Chromium Code Reviews| Index: android_webview/browser/shared_renderer_state.cc |
| diff --git a/android_webview/browser/shared_renderer_state.cc b/android_webview/browser/shared_renderer_state.cc |
| index 7c7238e7d2053442c97e3462e9e5c23424724482..1389e043377f90b61e64c62a98c59a8cd7354e09 100644 |
| --- a/android_webview/browser/shared_renderer_state.cc |
| +++ b/android_webview/browser/shared_renderer_state.cc |
| @@ -6,10 +6,65 @@ |
| #include "android_webview/browser/browser_view_renderer_client.h" |
| #include "base/bind.h" |
| +#include "base/lazy_instance.h" |
| #include "base/location.h" |
| namespace android_webview { |
| +namespace internal { |
| + |
| +class RequestDrawGLTracker { |
| + public: |
| + RequestDrawGLTracker(); |
| + bool ShouldRequestOnNoneUiThread(SharedRendererState* state); |
| + bool ShouldRequestOnUiThread(SharedRendererState* state); |
| + void DidRequestOnUiThread(); |
| + void DidDrawGLProcess(); |
| + |
| + private: |
| + base::Lock lock_; |
| + SharedRendererState* pending_ui_; |
| + SharedRendererState* pending_non_ui_; |
| +}; |
| + |
| +RequestDrawGLTracker::RequestDrawGLTracker() |
| + : pending_ui_(NULL), pending_non_ui_(NULL) { |
| +} |
| + |
| +bool RequestDrawGLTracker::ShouldRequestOnNoneUiThread( |
| + SharedRendererState* state) { |
| + base::AutoLock lock(lock_); |
| + if (pending_ui_ || pending_non_ui_) |
|
hush (inactive)
2014/08/07 22:14:27
this means there should be only at most one pendin
boliu
2014/08/07 22:21:35
That's the goal. But it's not quite true.
Right n
|
| + return false; |
| + pending_non_ui_ = state; |
| + return true; |
| +} |
| + |
| +bool RequestDrawGLTracker::ShouldRequestOnUiThread(SharedRendererState* state) { |
| + base::AutoLock lock(lock_); |
| + if (pending_non_ui_) { |
| + pending_non_ui_->ResetRequestDrawGLCallback(); |
| + pending_non_ui_ = NULL; |
| + } |
| + if (pending_ui_) |
| + return false; |
| + pending_ui_ = state; |
| + return true; |
| +} |
| + |
| +void RequestDrawGLTracker::DidDrawGLProcess() { |
| + base::AutoLock lock(lock_); |
| + pending_non_ui_ = NULL; |
| + pending_ui_ = NULL; |
| +} |
| + |
| +} // namespace internal |
| + |
| +namespace { |
|
hush (inactive)
2014/08/07 22:14:27
an empty line after this line?
|
| +base::LazyInstance<internal::RequestDrawGLTracker> g_request_draw_gl_tracker = |
| + LAZY_INSTANCE_INITIALIZER; |
| +} |
| + |
| DrawGLInput::DrawGLInput() : width(0), height(0) { |
| } |
| @@ -27,6 +82,7 @@ SharedRendererState::SharedRendererState( |
| share_context_(NULL) { |
| DCHECK(ui_loop_->BelongsToCurrentThread()); |
| DCHECK(client_on_ui_); |
| + ResetRequestDrawGLCallback(); |
| } |
| SharedRendererState::~SharedRendererState() { |
| @@ -39,17 +95,37 @@ bool SharedRendererState::CurrentlyOnUIThread() { |
| void SharedRendererState::ClientRequestDrawGL() { |
| if (ui_loop_->BelongsToCurrentThread()) { |
| + if (!g_request_draw_gl_tracker.Get().ShouldRequestOnUiThread(this)) |
| + return; |
| ClientRequestDrawGLOnUIThread(); |
| } else { |
| - ui_loop_->PostTask( |
| - FROM_HERE, |
| - base::Bind(&SharedRendererState::ClientRequestDrawGLOnUIThread, |
| - ui_thread_weak_ptr_)); |
| + if (!g_request_draw_gl_tracker.Get().ShouldRequestOnNoneUiThread(this)) |
| + return; |
| + base::Closure callback; |
| + { |
| + base::AutoLock lock(lock_); |
| + callback = request_draw_gl_closure_; |
| + } |
| + ui_loop_->PostTask(FROM_HERE, callback); |
| } |
| } |
| +void SharedRendererState::DidDrawGLProcess() { |
| + g_request_draw_gl_tracker.Get().DidDrawGLProcess(); |
| +} |
| + |
| +void SharedRendererState::ResetRequestDrawGLCallback() { |
| + DCHECK(ui_loop_->BelongsToCurrentThread()); |
| + base::AutoLock lock(lock_); |
| + request_draw_gl_cancelable_closure_.Reset( |
| + base::Bind(&SharedRendererState::ClientRequestDrawGLOnUIThread, |
| + base::Unretained(this))); |
| + request_draw_gl_closure_ = request_draw_gl_cancelable_closure_.callback(); |
| +} |
| + |
| void SharedRendererState::ClientRequestDrawGLOnUIThread() { |
| DCHECK(ui_loop_->BelongsToCurrentThread()); |
| + ResetRequestDrawGLCallback(); |
| if (!client_on_ui_->RequestDrawGL(NULL, false)) { |
| LOG(ERROR) << "Failed to request GL process. Deadlock likely"; |
| } |