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 8a137a8e7883f0ee76c8b59fa1e01e51fdf0a211..93f6c16ed2bdd2115766278de20cf39892bb9f00 100644 |
--- a/android_webview/browser/deferred_gpu_command_service.cc |
+++ b/android_webview/browser/deferred_gpu_command_service.cc |
@@ -6,6 +6,7 @@ |
#include "android_webview/browser/gl_view_renderer_manager.h" |
#include "android_webview/browser/shared_renderer_state.h" |
+#include "base/debug/trace_event.h" |
#include "base/synchronization/lock.h" |
#include "content/public/browser/android/synchronous_compositor.h" |
#include "gpu/command_buffer/service/shader_translator_cache.h" |
@@ -20,6 +21,7 @@ class ThreadSafeBool { |
ThreadSafeBool(); |
void Set(bool boolean); |
bool Get(); |
+ bool GetAndSet(); |
private: |
base::Lock lock_; |
@@ -35,6 +37,13 @@ void ThreadSafeBool::Set(bool boolean) { |
boolean_ = boolean; |
} |
+bool ThreadSafeBool::GetAndSet() { |
+ base::AutoLock lock(lock_); |
+ bool rv = boolean_; |
+ boolean_ = true; |
+ return rv; |
+} |
+ |
bool ThreadSafeBool::Get() { |
base::AutoLock lock(lock_); |
return boolean_; |
@@ -43,6 +52,11 @@ bool ThreadSafeBool::Get() { |
base::LazyInstance<ThreadSafeBool> g_request_pending = |
LAZY_INSTANCE_INITIALIZER; |
+// Because request is posted to UI thread, have to treat requests on UI thread |
+// specifically because UI can immediately block waiting for the request. |
+base::LazyInstance<ThreadSafeBool> g_request_pending_on_ui = |
+ LAZY_INSTANCE_INITIALIZER; |
+ |
base::LazyInstance<scoped_refptr<DeferredGpuCommandService> > |
g_service = LAZY_INSTANCE_INITIALIZER; |
} // namespace |
@@ -65,6 +79,7 @@ ScopedAllowGL::ScopedAllowGL() { |
ScopedAllowGL::~ScopedAllowGL() { |
allow_gl.Get().Set(false); |
g_request_pending.Get().Set(false); |
+ g_request_pending_on_ui.Get().Set(false); |
DeferredGpuCommandService* service = g_service.Get(); |
if (service) { |
@@ -83,6 +98,7 @@ void DeferredGpuCommandService::SetInstance() { |
// Initialize global booleans. |
g_request_pending.Get().Set(false); |
+ g_request_pending_on_ui.Get().Set(false); |
} |
} |
@@ -109,7 +125,10 @@ void DeferredGpuCommandService::RequestProcessGL() { |
return; |
} |
- if (!g_request_pending.Get().Get()) { |
+ bool on_ui_thread = renderer_state->CurrentlyOnUIThread(); |
+ bool need_request = on_ui_thread ? !g_request_pending_on_ui.Get().GetAndSet() |
+ : !g_request_pending.Get().GetAndSet(); |
+ if (need_request) { |
g_request_pending.Get().Set(true); |
renderer_state->ClientRequestDrawGL(); |
} |
@@ -143,6 +162,10 @@ void DeferredGpuCommandService::ScheduleIdleWork( |
} |
void DeferredGpuCommandService::PerformIdleWork(bool is_idle) { |
+ TRACE_EVENT1("android_webview", |
+ "DeferredGpuCommandService::PerformIdleWork", |
+ "is_idle", |
+ is_idle); |
DCHECK(ScopedAllowGL::IsAllowed()); |
static const base::TimeDelta kMaxIdleAge = |
base::TimeDelta::FromMilliseconds(16); |