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 576a8a0cd83920acf0a34a16cff124e506d0d799..9a5b4794e95afb4314d328c930bbb9f2c12081ed 100644 |
--- a/android_webview/browser/shared_renderer_state.cc |
+++ b/android_webview/browser/shared_renderer_state.cc |
@@ -23,8 +23,8 @@ class RequestDrawGLTracker { |
RequestDrawGLTracker(); |
bool ShouldRequestOnNonUiThread(SharedRendererState* state); |
bool ShouldRequestOnUiThread(SharedRendererState* state); |
- void DidRequestOnUiThread(); |
void ResetPending(); |
+ void SetQueuedFunctorOnUi(SharedRendererState* state); |
private: |
base::Lock lock_; |
@@ -51,6 +51,9 @@ bool RequestDrawGLTracker::ShouldRequestOnUiThread(SharedRendererState* state) { |
pending_non_ui_->ResetRequestDrawGLCallback(); |
pending_non_ui_ = NULL; |
} |
+ // At this time, we could have already called RequestDrawGL on the UI thread, |
+ // but the corresponding GL mode process hasn't happened yet. In this case, |
+ // don't schedule another requestDrawGL on the UI thread. |
if (pending_ui_) |
return false; |
pending_ui_ = state; |
@@ -63,6 +66,14 @@ void RequestDrawGLTracker::ResetPending() { |
pending_ui_ = NULL; |
} |
+void RequestDrawGLTracker::SetQueuedFunctorOnUi(SharedRendererState* state) { |
+ base::AutoLock lock(lock_); |
+ DCHECK(state); |
+ DCHECK(pending_ui_ == state || pending_non_ui_ == state); |
+ pending_ui_ = state; |
+ pending_non_ui_ = NULL; |
+} |
+ |
} // namespace internal |
namespace { |
@@ -125,6 +136,7 @@ void SharedRendererState::ResetRequestDrawGLCallback() { |
void SharedRendererState::ClientRequestDrawGLOnUI() { |
DCHECK(ui_loop_->BelongsToCurrentThread()); |
ResetRequestDrawGLCallback(); |
+ g_request_draw_gl_tracker.Get().SetQueuedFunctorOnUi(this); |
if (!browser_view_renderer_->RequestDrawGL(false)) { |
g_request_draw_gl_tracker.Get().ResetPending(); |
LOG(ERROR) << "Failed to request GL process. Deadlock likely"; |
@@ -267,6 +279,16 @@ void SharedRendererState::DrawGL(AwDrawGLInfo* draw_info) { |
return; |
} |
+ // kModeProcessNoContext should never happen because we tear down hardware |
+ // in onTrimMemory. However that guarantee is maintained outside of chromium |
+ // code. Not notifying shared state in kModeProcessNoContext can lead to |
+ // immediate deadlock, which is slightly more catastrophic than leaks or |
+ // corruption. |
+ if (draw_info->mode == AwDrawGLInfo::kModeProcess || |
+ draw_info->mode == AwDrawGLInfo::kModeProcessNoContext) { |
+ DidDrawGLProcess(); |
+ } |
+ |
{ |
GLViewRendererManager* manager = GLViewRendererManager::GetInstance(); |
base::AutoLock lock(lock_); |
@@ -285,16 +307,6 @@ void SharedRendererState::DrawGL(AwDrawGLInfo* draw_info) { |
LOG(ERROR) << "Received unexpected kModeProcessNoContext"; |
} |
- // kModeProcessNoContext should never happen because we tear down hardware |
- // in onTrimMemory. However that guarantee is maintained outside of chromium |
- // code. Not notifying shared state in kModeProcessNoContext can lead to |
- // immediate deadlock, which is slightly more catastrophic than leaks or |
- // corruption. |
- if (draw_info->mode == AwDrawGLInfo::kModeProcess || |
- draw_info->mode == AwDrawGLInfo::kModeProcessNoContext) { |
- DidDrawGLProcess(); |
- } |
- |
if (IsInsideHardwareRelease()) { |
hardware_renderer_.reset(); |
// Flush the idle queue in tear down. |