 Chromium Code Reviews
 Chromium Code Reviews Issue 2257533006:
  Free worker context resources on idle.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@fix-cleanup2
    
  
    Issue 2257533006:
  Free worker context resources on idle.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@fix-cleanup2| 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 1c5cd13e9936d3bf84bbdef6f53e225ee353cefb..6ea86583fbd62ffe2453c2216d1a5070998470ab 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) | 
| @@ -292,6 +300,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 | 
| @@ -446,6 +456,18 @@ void GLES2Implementation::SetAggressivelyFreeResources( | 
| } | 
| } | 
| +void GLES2Implementation::TrimResources() { | 
| + TRACE_EVENT0("gpu", "GLES2Implementation::TrimResources"); | 
| + | 
| + bool initial_state = aggressively_free_resources_; | 
| + | 
| + SetAggressivelyFreeResources(true); | 
| + | 
| + if (!initial_state) { | 
| + SetAggressivelyFreeResources(false); | 
| + } | 
| +} | 
| + | 
| bool GLES2Implementation::OnMemoryDump( | 
| const base::trace_event::MemoryDumpArgs& args, | 
| base::trace_event::ProcessMemoryDump* pmd) { | 
| @@ -5895,6 +5917,46 @@ bool GLES2Implementation::AnyClientsVisible() const { | 
| return num_visible_clients_ > 0; | 
| } | 
| +std::unique_ptr<ContextSupport::ScopedBusy> | 
| +GLES2Implementation::ClientBecameBusy() { | 
| + DCHECK(is_idle_); | 
| + is_idle_ = false; | 
| + | 
| + if (idle_callback_) { | 
| + // We can only modify |pending_idle_callback_| from the provided callback | 
| 
danakj
2016/08/23 01:26:25
Its kinda awk if you end up running the cancel rig
 
ericrk
2016/08/24 18:32:21
It's actually a little bit tricky to avoid races l
 | 
| + // thread due to CancellableCallback constraints. Move to that thread. | 
| + idle_callback_task_runner_->PostTask( | 
| + FROM_HERE, base::Bind(&GLES2Implementation::CancelIdleCallback, | 
| + weak_ptr_factory_.GetWeakPtr())); | 
| + } | 
| + | 
| + return base::MakeUnique<ScopedBusyImpl>(this); | 
| +} | 
| + | 
| +void GLES2Implementation::ClientBecameNotBusy( | 
| + std::unique_ptr<ScopedBusy> busy) { | 
| + DCHECK(busy); | 
| + DCHECK(!is_idle_); | 
| + is_idle_ = true; | 
| + | 
| + if (idle_callback_) { | 
| + // We can only modify |pending_idle_callback_| from the provided callback | 
| + // thread due to CancellableCallback constraints. Move to that thread. | 
| + idle_callback_task_runner_->PostTask( | 
| + FROM_HERE, base::Bind(&GLES2Implementation::ScheduleIdleCallback, | 
| + weak_ptr_factory_.GetWeakPtr())); | 
| + } | 
| + | 
| + static_cast<ScopedBusyImpl*>(busy.get())->Release(this); | 
| +} | 
| + | 
| +void GLES2Implementation::SetIdleCallback( | 
| + const base::Closure& callback, | 
| + scoped_refptr<base::SingleThreadTaskRunner> callback_task_runner) { | 
| + idle_callback_ = callback; | 
| + idle_callback_task_runner_ = std::move(callback_task_runner); | 
| +} | 
| + | 
| void GLES2Implementation::SetLostContextCallback( | 
| const base::Closure& callback) { | 
| lost_context_callback_ = callback; | 
| @@ -6929,6 +6991,22 @@ void GLES2Implementation::InvalidateCachedExtensions() { | 
| cached_extensions_.clear(); | 
| } | 
| +void GLES2Implementation::ScheduleIdleCallback() { | 
| + if (!idle_callback_) | 
| + return; | 
| + if (!pending_idle_callback_) | 
| + pending_idle_callback_.reset(new base::CancelableClosure()); | 
| + | 
| + pending_idle_callback_->Reset(idle_callback_); | 
| + idle_callback_task_runner_->PostDelayedTask( | 
| + FROM_HERE, pending_idle_callback_->callback(), kIdleCallbackDelay); | 
| +} | 
| + | 
| +void GLES2Implementation::CancelIdleCallback() { | 
| + if (pending_idle_callback_) | 
| + pending_idle_callback_->Cancel(); | 
| +} | 
| + | 
| // 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. |