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(); |
} |
} |