blob: 3217cd607a3cc2b258112739a4be3021f71ebfb9 [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/webgl/webgl_fast_call.h"
#include "base/check.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h"
namespace blink {
WebGLScopedFastCall::WebGLScopedFastCall(WebGLFastCallHelper* helper,
bool* deopt_flag)
: helper_(helper), deopt_flag_(deopt_flag) {
DCHECK(!helper_->in_fast_call_);
helper_->in_fast_call_ = true;
helper_->deopt_type_ = WebGLFastCallHelper::DeoptType::None;
}
WebGLScopedFastCall::~WebGLScopedFastCall() {
DCHECK(helper_->in_fast_call_);
helper_->in_fast_call_ = false;
if (helper_->deopt_type_ != WebGLFastCallHelper::DeoptType::None) {
CHECK(deopt_flag_);
*deopt_flag_ = true;
}
}
WebGLFastCallHelper::WebGLFastCallHelper() = default;
WebGLFastCallHelper::~WebGLFastCallHelper() = default;
void WebGLFastCallHelper::EagerDeopt() {
DCHECK(in_fast_call_);
DCHECK_EQ(deopt_type_, DeoptType::None);
deopt_type_ = DeoptType::Eager;
}
void WebGLFastCallHelper::AddDeferredConsoleWarning(const String& message) {
DCHECK(in_fast_call_);
DCHECK_NE(deopt_type_, DeoptType::Eager);
deopt_type_ = DeoptType::Deferred;
deferred_console_warnings_.push_back(message);
}
void WebGLFastCallHelper::AddDeferredErrorOrWarningNotification(
const String& message) {
AddDeferredNotification(Notification::WarningOrError, message);
}
void WebGLFastCallHelper::AddDeferredErrorNotification(
const String& error_type) {
AddDeferredNotification(Notification::Error, error_type);
}
void WebGLFastCallHelper::AddDeferredWarningNotification() {
AddDeferredNotification(Notification::Warning);
}
void WebGLFastCallHelper::AddDeferredNotification(Notification type,
const String& message) {
DCHECK(in_fast_call_);
DCHECK_NE(deopt_type_, DeoptType::Eager);
deopt_type_ = DeoptType::Deferred;
deferred_notifications_.emplace_back(type, message);
}
bool WebGLFastCallHelper::FlushDeferredEvents(
WebGLRenderingContextBase* context) {
DCHECK(!in_fast_call_);
bool any_events = false;
for (const auto& message : deferred_console_warnings_) {
any_events = true;
context->PrintWarningToConsole(message);
}
for (const auto& notification : deferred_notifications_) {
any_events = true;
switch (notification.first) {
case Notification::WarningOrError:
probe::DidFireWebGLErrorOrWarning(context->canvas(),
notification.second);
break;
case Notification::Error:
probe::DidFireWebGLError(context->canvas(), notification.second);
break;
case Notification::Warning:
probe::DidFireWebGLWarning(context->canvas());
break;
default:
NOTREACHED();
}
}
deferred_console_warnings_.clear();
deferred_notifications_.clear();
// If there were any deferred events, then we must have deopt'ed to defer
// logging.
DCHECK(!any_events || deopt_type_ == DeoptType::Deferred);
return any_events;
}
} // namespace blink