Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(106)

Side by Side Diff: android_webview/browser/shared_renderer_state.cc

Issue 801923003: Don't schedule more invokeFunctors than necessary. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "android_webview/browser/shared_renderer_state.h" 5 #include "android_webview/browser/shared_renderer_state.h"
6 6
7 #include "android_webview/browser/browser_view_renderer.h" 7 #include "android_webview/browser/browser_view_renderer.h"
8 #include "android_webview/browser/deferred_gpu_command_service.h" 8 #include "android_webview/browser/deferred_gpu_command_service.h"
9 #include "android_webview/browser/hardware_renderer.h" 9 #include "android_webview/browser/hardware_renderer.h"
10 #include "android_webview/browser/scoped_app_gl_state_restore.h" 10 #include "android_webview/browser/scoped_app_gl_state_restore.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 pending_non_ui_ = state; 44 pending_non_ui_ = state;
45 return true; 45 return true;
46 } 46 }
47 47
48 bool RequestDrawGLTracker::ShouldRequestOnUiThread(SharedRendererState* state) { 48 bool RequestDrawGLTracker::ShouldRequestOnUiThread(SharedRendererState* state) {
49 base::AutoLock lock(lock_); 49 base::AutoLock lock(lock_);
50 if (pending_non_ui_) { 50 if (pending_non_ui_) {
51 pending_non_ui_->ResetRequestDrawGLCallback(); 51 pending_non_ui_->ResetRequestDrawGLCallback();
52 pending_non_ui_ = NULL; 52 pending_non_ui_ = NULL;
53 } 53 }
54 if (pending_ui_) 54 // At this time, we could have already called RequestDrawGL on the UI thread,
55 // but the corresponding GL mode process hasn't happened yet. In this case,
56 // don't
57 // schedule another requestDrawGL on the UI thread.
58 if (pending_ui_ || state->has_queued_functor_on_ui_)
55 return false; 59 return false;
56 pending_ui_ = state; 60 pending_ui_ = state;
57 return true; 61 return true;
58 } 62 }
59 63
60 void RequestDrawGLTracker::ResetPending() { 64 void RequestDrawGLTracker::ResetPending() {
61 base::AutoLock lock(lock_); 65 base::AutoLock lock(lock_);
62 pending_non_ui_ = NULL; 66 pending_non_ui_ = NULL;
63 pending_ui_ = NULL; 67 pending_ui_ = NULL;
64 } 68 }
65 69
66 } // namespace internal 70 } // namespace internal
67 71
68 namespace { 72 namespace {
69 73
70 base::LazyInstance<internal::RequestDrawGLTracker> g_request_draw_gl_tracker = 74 base::LazyInstance<internal::RequestDrawGLTracker> g_request_draw_gl_tracker =
71 LAZY_INSTANCE_INITIALIZER; 75 LAZY_INSTANCE_INITIALIZER;
72 76
73 } 77 }
74 78
75 SharedRendererState::SharedRendererState( 79 SharedRendererState::SharedRendererState(
76 const scoped_refptr<base::SingleThreadTaskRunner>& ui_loop, 80 const scoped_refptr<base::SingleThreadTaskRunner>& ui_loop,
77 BrowserViewRenderer* browser_view_renderer) 81 BrowserViewRenderer* browser_view_renderer)
78 : ui_loop_(ui_loop), 82 : ui_loop_(ui_loop),
79 browser_view_renderer_(browser_view_renderer), 83 browser_view_renderer_(browser_view_renderer),
84 has_queued_functor_on_ui_(false),
80 renderer_manager_key_(GLViewRendererManager::GetInstance()->NullKey()), 85 renderer_manager_key_(GLViewRendererManager::GetInstance()->NullKey()),
81 force_commit_(false), 86 force_commit_(false),
82 inside_hardware_release_(false), 87 inside_hardware_release_(false),
83 needs_force_invalidate_on_next_draw_gl_(false), 88 needs_force_invalidate_on_next_draw_gl_(false),
84 weak_factory_on_ui_thread_(this) { 89 weak_factory_on_ui_thread_(this) {
85 DCHECK(ui_loop_->BelongsToCurrentThread()); 90 DCHECK(ui_loop_->BelongsToCurrentThread());
86 DCHECK(browser_view_renderer_); 91 DCHECK(browser_view_renderer_);
87 ui_thread_weak_ptr_ = weak_factory_on_ui_thread_.GetWeakPtr(); 92 ui_thread_weak_ptr_ = weak_factory_on_ui_thread_.GetWeakPtr();
88 ResetRequestDrawGLCallback(); 93 ResetRequestDrawGLCallback();
89 } 94 }
(...skipping 15 matching lines...) Expand all
105 { 110 {
106 base::AutoLock lock(lock_); 111 base::AutoLock lock(lock_);
107 callback = request_draw_gl_closure_; 112 callback = request_draw_gl_closure_;
108 } 113 }
109 ui_loop_->PostTask(FROM_HERE, callback); 114 ui_loop_->PostTask(FROM_HERE, callback);
110 } 115 }
111 } 116 }
112 117
113 void SharedRendererState::DidDrawGLProcess() { 118 void SharedRendererState::DidDrawGLProcess() {
114 g_request_draw_gl_tracker.Get().ResetPending(); 119 g_request_draw_gl_tracker.Get().ResetPending();
120 has_queued_functor_on_ui_ = false;
115 } 121 }
116 122
117 void SharedRendererState::ResetRequestDrawGLCallback() { 123 void SharedRendererState::ResetRequestDrawGLCallback() {
118 DCHECK(ui_loop_->BelongsToCurrentThread()); 124 DCHECK(ui_loop_->BelongsToCurrentThread());
119 base::AutoLock lock(lock_); 125 base::AutoLock lock(lock_);
120 request_draw_gl_cancelable_closure_.Reset(base::Bind( 126 request_draw_gl_cancelable_closure_.Reset(base::Bind(
121 &SharedRendererState::ClientRequestDrawGLOnUI, base::Unretained(this))); 127 &SharedRendererState::ClientRequestDrawGLOnUI, base::Unretained(this)));
122 request_draw_gl_closure_ = request_draw_gl_cancelable_closure_.callback(); 128 request_draw_gl_closure_ = request_draw_gl_cancelable_closure_.callback();
123 } 129 }
124 130
125 void SharedRendererState::ClientRequestDrawGLOnUI() { 131 void SharedRendererState::ClientRequestDrawGLOnUI() {
126 DCHECK(ui_loop_->BelongsToCurrentThread()); 132 DCHECK(ui_loop_->BelongsToCurrentThread());
127 ResetRequestDrawGLCallback(); 133 ResetRequestDrawGLCallback();
134 has_queued_functor_on_ui_ = true;
128 if (!browser_view_renderer_->RequestDrawGL(false)) { 135 if (!browser_view_renderer_->RequestDrawGL(false)) {
129 g_request_draw_gl_tracker.Get().ResetPending(); 136 g_request_draw_gl_tracker.Get().ResetPending();
130 LOG(ERROR) << "Failed to request GL process. Deadlock likely"; 137 LOG(ERROR) << "Failed to request GL process. Deadlock likely";
131 } 138 }
132 } 139 }
133 140
134 void SharedRendererState::UpdateParentDrawConstraintsOnUI() { 141 void SharedRendererState::UpdateParentDrawConstraintsOnUI() {
135 DCHECK(ui_loop_->BelongsToCurrentThread()); 142 DCHECK(ui_loop_->BelongsToCurrentThread());
136 browser_view_renderer_->UpdateParentDrawConstraints(); 143 browser_view_renderer_->UpdateParentDrawConstraints();
137 } 144 }
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 resources->swap(returned_resources_); 259 resources->swap(returned_resources_);
253 } 260 }
254 261
255 bool SharedRendererState::ReturnedResourcesEmptyOnUI() const { 262 bool SharedRendererState::ReturnedResourcesEmptyOnUI() const {
256 base::AutoLock lock(lock_); 263 base::AutoLock lock(lock_);
257 return returned_resources_.empty(); 264 return returned_resources_.empty();
258 } 265 }
259 266
260 void SharedRendererState::DrawGL(AwDrawGLInfo* draw_info) { 267 void SharedRendererState::DrawGL(AwDrawGLInfo* draw_info) {
261 TRACE_EVENT0("android_webview", "DrawFunctor"); 268 TRACE_EVENT0("android_webview", "DrawFunctor");
269 // kModeProcessNoContext should never happen because we tear down hardware
270 // in onTrimMemory. However that guarantee is maintained outside of chromium
271 // code. Not notifying shared state in kModeProcessNoContext can lead to
272 // immediate deadlock, which is slightly more catastrophic than leaks or
273 // corruption.
274 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.
275 draw_info->mode == AwDrawGLInfo::kModeProcessNoContext) {
276 DidDrawGLProcess();
277 }
278
262 if (draw_info->mode == AwDrawGLInfo::kModeSync) { 279 if (draw_info->mode == AwDrawGLInfo::kModeSync) {
263 TRACE_EVENT_INSTANT0("android_webview", "kModeSync", 280 TRACE_EVENT_INSTANT0("android_webview", "kModeSync",
264 TRACE_EVENT_SCOPE_THREAD); 281 TRACE_EVENT_SCOPE_THREAD);
265 if (hardware_renderer_) 282 if (hardware_renderer_)
266 hardware_renderer_->CommitFrame(); 283 hardware_renderer_->CommitFrame();
267 return; 284 return;
268 } 285 }
269 286
270 { 287 {
271 GLViewRendererManager* manager = GLViewRendererManager::GetInstance(); 288 GLViewRendererManager* manager = GLViewRendererManager::GetInstance();
272 base::AutoLock lock(lock_); 289 base::AutoLock lock(lock_);
273 if (renderer_manager_key_ != manager->NullKey()) { 290 if (renderer_manager_key_ != manager->NullKey()) {
274 manager->DidDrawGL(renderer_manager_key_); 291 manager->DidDrawGL(renderer_manager_key_);
275 } 292 }
276 } 293 }
277 294
278 ScopedAppGLStateRestore state_restore( 295 ScopedAppGLStateRestore state_restore(
279 draw_info->mode == AwDrawGLInfo::kModeDraw 296 draw_info->mode == AwDrawGLInfo::kModeDraw
280 ? ScopedAppGLStateRestore::MODE_DRAW 297 ? ScopedAppGLStateRestore::MODE_DRAW
281 : ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); 298 : ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT);
282 ScopedAllowGL allow_gl; 299 ScopedAllowGL allow_gl;
283 300
284 if (draw_info->mode == AwDrawGLInfo::kModeProcessNoContext) { 301 if (draw_info->mode == AwDrawGLInfo::kModeProcessNoContext) {
285 LOG(ERROR) << "Received unexpected kModeProcessNoContext"; 302 LOG(ERROR) << "Received unexpected kModeProcessNoContext";
286 } 303 }
287 304
288 // kModeProcessNoContext should never happen because we tear down hardware
289 // in onTrimMemory. However that guarantee is maintained outside of chromium
290 // code. Not notifying shared state in kModeProcessNoContext can lead to
291 // immediate deadlock, which is slightly more catastrophic than leaks or
292 // corruption.
293 if (draw_info->mode == AwDrawGLInfo::kModeProcess ||
294 draw_info->mode == AwDrawGLInfo::kModeProcessNoContext) {
295 DidDrawGLProcess();
296 }
297
298 if (IsInsideHardwareRelease()) { 305 if (IsInsideHardwareRelease()) {
299 hardware_renderer_.reset(); 306 hardware_renderer_.reset();
300 // Flush the idle queue in tear down. 307 // Flush the idle queue in tear down.
301 DeferredGpuCommandService::GetInstance()->PerformAllIdleWork(); 308 DeferredGpuCommandService::GetInstance()->PerformAllIdleWork();
302 return; 309 return;
303 } 310 }
304 311
305 if (draw_info->mode != AwDrawGLInfo::kModeDraw) { 312 if (draw_info->mode != AwDrawGLInfo::kModeDraw) {
306 if (draw_info->mode == AwDrawGLInfo::kModeProcess) { 313 if (draw_info->mode == AwDrawGLInfo::kModeProcess) {
307 DeferredGpuCommandService::GetInstance()->PerformIdleWork(true); 314 DeferredGpuCommandService::GetInstance()->PerformIdleWork(true);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 : shared_renderer_state_(shared_renderer_state) { 378 : shared_renderer_state_(shared_renderer_state) {
372 DCHECK(!shared_renderer_state_->IsInsideHardwareRelease()); 379 DCHECK(!shared_renderer_state_->IsInsideHardwareRelease());
373 shared_renderer_state_->SetInsideHardwareRelease(true); 380 shared_renderer_state_->SetInsideHardwareRelease(true);
374 } 381 }
375 382
376 SharedRendererState::InsideHardwareReleaseReset::~InsideHardwareReleaseReset() { 383 SharedRendererState::InsideHardwareReleaseReset::~InsideHardwareReleaseReset() {
377 shared_renderer_state_->SetInsideHardwareRelease(false); 384 shared_renderer_state_->SetInsideHardwareRelease(false);
378 } 385 }
379 386
380 } // namespace android_webview 387 } // namespace android_webview
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698