Chromium Code Reviews| Index: android_webview/browser/deferred_gpu_command_service.cc |
| diff --git a/android_webview/browser/deferred_gpu_command_service.cc b/android_webview/browser/deferred_gpu_command_service.cc |
| index a680c7be01fa4c719d68481ec78d182ce10ce1f0..b051056f8c3553191d89fd3c338e1ce5e797bbf0 100644 |
| --- a/android_webview/browser/deferred_gpu_command_service.cc |
| +++ b/android_webview/browser/deferred_gpu_command_service.cc |
| @@ -6,12 +6,44 @@ |
| #include "android_webview/browser/gl_view_renderer_manager.h" |
| #include "android_webview/browser/shared_renderer_state.h" |
| +#include "base/synchronization/lock.h" |
| #include "content/public/browser/android/synchronous_compositor.h" |
| #include "gpu/command_buffer/service/shader_translator_cache.h" |
| namespace android_webview { |
| namespace { |
| + |
| +// TODO(boliu): Consider using base/atomicops.h. |
| +class ThreadSafeBool { |
| + public: |
| + ThreadSafeBool(); |
| + void set(bool boolean); |
|
no sievers
2014/05/27 20:12:48
nit: caps Set()/Get()
|
| + bool get(); |
| + |
| + private: |
| + base::Lock lock_; |
| + bool boolean_; |
| + DISALLOW_COPY_AND_ASSIGN(ThreadSafeBool); |
| +}; |
| + |
| +ThreadSafeBool::ThreadSafeBool() : boolean_(false) { |
| +} |
| + |
| +void ThreadSafeBool::set(bool boolean) { |
| + base::AutoLock lock(lock_); |
| + boolean_ = boolean; |
| +} |
| + |
| +bool ThreadSafeBool::get() { |
| + base::AutoLock lock(lock_); |
| + return boolean_; |
| +} |
| + |
| +base::LazyInstance<ThreadSafeBool> g_need_schedule = LAZY_INSTANCE_INITIALIZER; |
| +base::LazyInstance<ThreadSafeBool> g_request_pending = |
|
no sievers
2014/05/27 20:12:48
Does it work pretty much as good if you combine th
|
| + LAZY_INSTANCE_INITIALIZER; |
| + |
| base::LazyInstance<scoped_refptr<DeferredGpuCommandService> > |
| g_service = LAZY_INSTANCE_INITIALIZER; |
| } // namespace |
| @@ -23,21 +55,37 @@ bool ScopedAllowGL::IsAllowed() { |
| return allow_gl.Get().Get(); |
| } |
| +// static |
| +bool ScopedAllowGL::NeedSchedule() { |
| + return g_need_schedule.Get().get(); |
| +} |
| + |
| ScopedAllowGL::ScopedAllowGL() { |
| DCHECK(!allow_gl.Get().Get()); |
| allow_gl.Get().Set(true); |
| + g_need_schedule.Get().set(false); |
| + g_request_pending.Get().set(false); |
| if (g_service.Get()) |
| g_service.Get()->RunTasks(); |
| } |
| -ScopedAllowGL::~ScopedAllowGL() { allow_gl.Get().Set(false); } |
| +ScopedAllowGL::~ScopedAllowGL() { |
| + allow_gl.Get().Set(false); |
| + g_need_schedule.Get().set(true); |
| + |
| + if (g_service.Get()) |
| + g_service.Get()->RunTasks(); |
| +} |
| // static |
| void DeferredGpuCommandService::SetInstance() { |
| if (!g_service.Get()) { |
| g_service.Get() = new DeferredGpuCommandService; |
| content::SynchronousCompositor::SetGpuService(g_service.Get()); |
| + // Initialize global booleans. |
| + g_request_pending.Get().set(false); |
| + g_need_schedule.Get().set(true); |
| } |
| } |
| @@ -63,7 +111,11 @@ void DeferredGpuCommandService::RequestProcessGL() { |
| LOG(ERROR) << "No hardware renderer. Deadlock likely"; |
| return; |
| } |
| - renderer_state->ClientRequestDrawGL(); |
| + |
| + if (!g_request_pending.Get().get()) { |
| + g_request_pending.Get().set(true); |
| + renderer_state->ClientRequestDrawGL(); |
| + } |
| } |
| // Called from different threads! |
| @@ -74,8 +126,7 @@ void DeferredGpuCommandService::ScheduleTask(const base::Closure& task) { |
| } |
| if (ScopedAllowGL::IsAllowed()) { |
| RunTasks(); |
| - } else { |
| - // TODO(boliu): Improve this to avoid PostTask storm. |
| + } else if (ScopedAllowGL::NeedSchedule()) { |
| RequestProcessGL(); |
| } |
| } |