| 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.
|
|
|