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 576a8a0cd83920acf0a34a16cff124e506d0d799..fc8fd2c4186771c3e5617f483e134bd950581856 100644 |
| --- a/android_webview/browser/shared_renderer_state.cc |
| +++ b/android_webview/browser/shared_renderer_state.cc |
| @@ -51,7 +51,11 @@ bool RequestDrawGLTracker::ShouldRequestOnUiThread(SharedRendererState* state) { |
| pending_non_ui_->ResetRequestDrawGLCallback(); |
| pending_non_ui_ = NULL; |
| } |
| - if (pending_ui_) |
| + // 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_ || state->has_queued_functor_on_ui_) |
| return false; |
| pending_ui_ = state; |
| return true; |
| @@ -77,6 +81,7 @@ SharedRendererState::SharedRendererState( |
| BrowserViewRenderer* browser_view_renderer) |
| : ui_loop_(ui_loop), |
| browser_view_renderer_(browser_view_renderer), |
| + has_queued_functor_on_ui_(false), |
| renderer_manager_key_(GLViewRendererManager::GetInstance()->NullKey()), |
| force_commit_(false), |
| inside_hardware_release_(false), |
| @@ -112,6 +117,7 @@ void SharedRendererState::ClientRequestDrawGL() { |
| void SharedRendererState::DidDrawGLProcess() { |
| g_request_draw_gl_tracker.Get().ResetPending(); |
| + has_queued_functor_on_ui_ = false; |
| } |
| void SharedRendererState::ResetRequestDrawGLCallback() { |
| @@ -125,6 +131,7 @@ void SharedRendererState::ResetRequestDrawGLCallback() { |
| void SharedRendererState::ClientRequestDrawGLOnUI() { |
| DCHECK(ui_loop_->BelongsToCurrentThread()); |
| ResetRequestDrawGLCallback(); |
| + has_queued_functor_on_ui_ = true; |
| if (!browser_view_renderer_->RequestDrawGL(false)) { |
| g_request_draw_gl_tracker.Get().ResetPending(); |
| LOG(ERROR) << "Failed to request GL process. Deadlock likely"; |
| @@ -259,6 +266,16 @@ bool SharedRendererState::ReturnedResourcesEmptyOnUI() const { |
| void SharedRendererState::DrawGL(AwDrawGLInfo* draw_info) { |
| TRACE_EVENT0("android_webview", "DrawFunctor"); |
| + // 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 || |
|
boliu
2014/12/13 01:03:15
nit: put it after the kModeSync check
hush (inactive)
2014/12/13 01:17:23
Done.
|
| + draw_info->mode == AwDrawGLInfo::kModeProcessNoContext) { |
| + DidDrawGLProcess(); |
| + } |
| + |
| if (draw_info->mode == AwDrawGLInfo::kModeSync) { |
| TRACE_EVENT_INSTANT0("android_webview", "kModeSync", |
| TRACE_EVENT_SCOPE_THREAD); |
| @@ -285,16 +302,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. |