| Index: gpu/command_buffer/client/gles2_implementation.cc
|
| diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
|
| index c4c77e6bf9ba518a4338522754153839a8146680..db2bda0b60c85447992547634b9d01085deeb325 100644
|
| --- a/gpu/command_buffer/client/gles2_implementation.cc
|
| +++ b/gpu/command_buffer/client/gles2_implementation.cc
|
| @@ -53,11 +53,13 @@ namespace gles2 {
|
| namespace {
|
|
|
| // Class that DCHECKs if it is destructed without first having Release called.
|
| -class ScopedVisibilityImpl : public ContextSupport::ScopedVisibility {
|
| +template <typename T>
|
| +class ScopedContextSupportToken : public T {
|
| public:
|
| - explicit ScopedVisibilityImpl(ContextSupport* context_support)
|
| + explicit ScopedContextSupportToken(ContextSupport* context_support)
|
| : initial_context_support_(context_support) {}
|
| - ~ScopedVisibilityImpl() { DCHECK(!initial_context_support_); }
|
| +
|
| + ~ScopedContextSupportToken() { DCHECK(!initial_context_support_); }
|
|
|
| void Release(ContextSupport* context_support) {
|
| DCHECK_EQ(initial_context_support_, context_support);
|
| @@ -68,6 +70,10 @@ class ScopedVisibilityImpl : public ContextSupport::ScopedVisibility {
|
| const ContextSupport* initial_context_support_;
|
| };
|
|
|
| +using ScopedVisibilityImpl =
|
| + ScopedContextSupportToken<ContextSupport::ScopedVisibility>;
|
| +using ScopedBusyImpl = ScopedContextSupportToken<ContextSupport::ScopedBusy>;
|
| +
|
| void CopyRectToBuffer(const void* pixels,
|
| uint32_t height,
|
| uint32_t unpadded_row_size,
|
| @@ -101,6 +107,8 @@ uint32_t GenerateNextFlushId() {
|
| return static_cast<uint32_t>(g_flush_id.GetNext());
|
| }
|
|
|
| +const base::TimeDelta kIdleCallbackDelay = base::TimeDelta::FromSeconds(1);
|
| +
|
| } // anonymous namespace
|
|
|
| #if !defined(_MSC_VER)
|
| @@ -181,6 +189,7 @@ GLES2Implementation::GLES2Implementation(
|
| #endif
|
| current_trace_stack_(0),
|
| gpu_control_(gpu_control),
|
| + task_runner_(std::move(task_runner)),
|
| capabilities_(gpu_control->GetCapabilities()),
|
| cached_extension_string_(nullptr),
|
| weak_ptr_factory_(this) {
|
| @@ -293,6 +302,8 @@ GLES2Implementation::~GLES2Implementation() {
|
| base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
|
| this);
|
|
|
| + CancelIdleCallback();
|
| +
|
| // Make sure the queries are finished otherwise we'll delete the
|
| // shared memory (mapped_memory_) which will free the memory used
|
| // by the queries. The GPU process when validating that memory is still
|
| @@ -5903,6 +5914,41 @@ bool GLES2Implementation::AnyClientsVisible() const {
|
| return num_visible_clients_ > 0;
|
| }
|
|
|
| +std::unique_ptr<ContextSupport::ScopedBusy>
|
| +GLES2Implementation::ClientBecameBusy() {
|
| + base::AutoLock hold(idle_lock_);
|
| + DCHECK(is_idle_);
|
| + is_idle_ = false;
|
| + // Increment the idle callback generation to cancel any pending callbacks.
|
| + ++current_idle_callback_generation_;
|
| +
|
| + return base::MakeUnique<ScopedBusyImpl>(this);
|
| +}
|
| +
|
| +void GLES2Implementation::ClientBecameNotBusy(
|
| + std::unique_ptr<ScopedBusy> busy) {
|
| + DCHECK(busy);
|
| +
|
| + base::AutoLock hold(idle_lock_);
|
| + DCHECK(!is_idle_);
|
| + is_idle_ = true;
|
| +
|
| + if (idle_callback_ && task_runner_) {
|
| + task_runner_->PostDelayedTask(
|
| + FROM_HERE, base::Bind(&GLES2Implementation::RunIdleCallback,
|
| + weak_ptr_factory_.GetWeakPtr(),
|
| + current_idle_callback_generation_),
|
| + kIdleCallbackDelay);
|
| + }
|
| +
|
| + static_cast<ScopedBusyImpl*>(busy.get())->Release(this);
|
| +}
|
| +
|
| +void GLES2Implementation::SetIdleCallback(const base::Closure& callback) {
|
| + base::AutoLock hold(idle_lock_);
|
| + idle_callback_ = callback;
|
| +}
|
| +
|
| void GLES2Implementation::SetLostContextCallback(
|
| const base::Closure& callback) {
|
| lost_context_callback_ = callback;
|
| @@ -6937,6 +6983,22 @@ void GLES2Implementation::InvalidateCachedExtensions() {
|
| cached_extensions_.clear();
|
| }
|
|
|
| +void GLES2Implementation::RunIdleCallback(uint32_t callback_generation) const {
|
| + base::AutoLock hold(idle_lock_);
|
| +
|
| + if (!idle_callback_)
|
| + return;
|
| + if (callback_generation != current_idle_callback_generation_)
|
| + return;
|
| +
|
| + idle_callback_.Run();
|
| +}
|
| +
|
| +void GLES2Implementation::CancelIdleCallback() {
|
| + base::AutoLock hold(idle_lock_);
|
| + ++current_idle_callback_generation_;
|
| +}
|
| +
|
| // Include the auto-generated part of this file. We split this because it means
|
| // we can easily edit the non-auto generated parts right here in this file
|
| // instead of having to edit some template or the code generator.
|
|
|