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

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: Just use pending_on_ui_ 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
11 #include "android_webview/public/browser/draw_gl.h" 11 #include "android_webview/public/browser/draw_gl.h"
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/debug/trace_event_argument.h" 13 #include "base/debug/trace_event_argument.h"
14 #include "base/lazy_instance.h" 14 #include "base/lazy_instance.h"
15 #include "base/location.h" 15 #include "base/location.h"
16 16
17 namespace android_webview { 17 namespace android_webview {
18 18
19 namespace internal { 19 namespace internal {
20 20
21 class RequestDrawGLTracker { 21 class RequestDrawGLTracker {
22 public: 22 public:
23 RequestDrawGLTracker(); 23 RequestDrawGLTracker();
24 bool ShouldRequestOnNonUiThread(SharedRendererState* state); 24 bool ShouldRequestOnNonUiThread(SharedRendererState* state);
25 bool ShouldRequestOnUiThread(SharedRendererState* state); 25 bool ShouldRequestOnUiThread(SharedRendererState* state);
26 void DidRequestOnUiThread();
27 void ResetPending(); 26 void ResetPending();
27 void SetQueuedFunctorOnUi(SharedRendererState* state);
28 28
29 private: 29 private:
30 base::Lock lock_; 30 base::Lock lock_;
31 SharedRendererState* pending_ui_; 31 SharedRendererState* pending_ui_;
32 SharedRendererState* pending_non_ui_; 32 SharedRendererState* pending_non_ui_;
33 }; 33 };
34 34
35 RequestDrawGLTracker::RequestDrawGLTracker() 35 RequestDrawGLTracker::RequestDrawGLTracker()
36 : pending_ui_(NULL), pending_non_ui_(NULL) { 36 : pending_ui_(NULL), pending_non_ui_(NULL) {
37 } 37 }
38 38
39 bool RequestDrawGLTracker::ShouldRequestOnNonUiThread( 39 bool RequestDrawGLTracker::ShouldRequestOnNonUiThread(
40 SharedRendererState* state) { 40 SharedRendererState* state) {
41 base::AutoLock lock(lock_); 41 base::AutoLock lock(lock_);
42 if (pending_ui_ || pending_non_ui_) 42 if (pending_ui_ || pending_non_ui_)
43 return false; 43 return false;
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 // 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 schedule another requestDrawGL on the UI thread.
54 if (pending_ui_) 57 if (pending_ui_)
55 return false; 58 return false;
56 pending_ui_ = state; 59 pending_ui_ = state;
57 return true; 60 return true;
58 } 61 }
59 62
60 void RequestDrawGLTracker::ResetPending() { 63 void RequestDrawGLTracker::ResetPending() {
61 base::AutoLock lock(lock_); 64 base::AutoLock lock(lock_);
62 pending_non_ui_ = NULL; 65 pending_non_ui_ = NULL;
63 pending_ui_ = NULL; 66 pending_ui_ = NULL;
64 } 67 }
65 68
69 void RequestDrawGLTracker::SetQueuedFunctorOnUi(SharedRendererState* state) {
70 base::AutoLock lock(lock_);
71 DCHECK(state);
72 DCHECK(pending_ui_ == state || pending_non_ui_ == state);
73 pending_ui_ = state;
74 pending_non_ui_ = NULL;
75 }
76
66 } // namespace internal 77 } // namespace internal
67 78
68 namespace { 79 namespace {
69 80
70 base::LazyInstance<internal::RequestDrawGLTracker> g_request_draw_gl_tracker = 81 base::LazyInstance<internal::RequestDrawGLTracker> g_request_draw_gl_tracker =
71 LAZY_INSTANCE_INITIALIZER; 82 LAZY_INSTANCE_INITIALIZER;
72 83
73 } 84 }
74 85
75 SharedRendererState::SharedRendererState( 86 SharedRendererState::SharedRendererState(
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 DCHECK(ui_loop_->BelongsToCurrentThread()); 129 DCHECK(ui_loop_->BelongsToCurrentThread());
119 base::AutoLock lock(lock_); 130 base::AutoLock lock(lock_);
120 request_draw_gl_cancelable_closure_.Reset(base::Bind( 131 request_draw_gl_cancelable_closure_.Reset(base::Bind(
121 &SharedRendererState::ClientRequestDrawGLOnUI, base::Unretained(this))); 132 &SharedRendererState::ClientRequestDrawGLOnUI, base::Unretained(this)));
122 request_draw_gl_closure_ = request_draw_gl_cancelable_closure_.callback(); 133 request_draw_gl_closure_ = request_draw_gl_cancelable_closure_.callback();
123 } 134 }
124 135
125 void SharedRendererState::ClientRequestDrawGLOnUI() { 136 void SharedRendererState::ClientRequestDrawGLOnUI() {
126 DCHECK(ui_loop_->BelongsToCurrentThread()); 137 DCHECK(ui_loop_->BelongsToCurrentThread());
127 ResetRequestDrawGLCallback(); 138 ResetRequestDrawGLCallback();
139 g_request_draw_gl_tracker.Get().SetQueuedFunctorOnUi(this);
128 if (!browser_view_renderer_->RequestDrawGL(false)) { 140 if (!browser_view_renderer_->RequestDrawGL(false)) {
129 g_request_draw_gl_tracker.Get().ResetPending(); 141 g_request_draw_gl_tracker.Get().ResetPending();
130 LOG(ERROR) << "Failed to request GL process. Deadlock likely"; 142 LOG(ERROR) << "Failed to request GL process. Deadlock likely";
131 } 143 }
132 } 144 }
133 145
134 void SharedRendererState::UpdateParentDrawConstraintsOnUI() { 146 void SharedRendererState::UpdateParentDrawConstraintsOnUI() {
135 DCHECK(ui_loop_->BelongsToCurrentThread()); 147 DCHECK(ui_loop_->BelongsToCurrentThread());
136 browser_view_renderer_->UpdateParentDrawConstraints(); 148 browser_view_renderer_->UpdateParentDrawConstraints();
137 } 149 }
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 void SharedRendererState::DrawGL(AwDrawGLInfo* draw_info) { 272 void SharedRendererState::DrawGL(AwDrawGLInfo* draw_info) {
261 TRACE_EVENT0("android_webview", "DrawFunctor"); 273 TRACE_EVENT0("android_webview", "DrawFunctor");
262 if (draw_info->mode == AwDrawGLInfo::kModeSync) { 274 if (draw_info->mode == AwDrawGLInfo::kModeSync) {
263 TRACE_EVENT_INSTANT0("android_webview", "kModeSync", 275 TRACE_EVENT_INSTANT0("android_webview", "kModeSync",
264 TRACE_EVENT_SCOPE_THREAD); 276 TRACE_EVENT_SCOPE_THREAD);
265 if (hardware_renderer_) 277 if (hardware_renderer_)
266 hardware_renderer_->CommitFrame(); 278 hardware_renderer_->CommitFrame();
267 return; 279 return;
268 } 280 }
269 281
282 // kModeProcessNoContext should never happen because we tear down hardware
283 // in onTrimMemory. However that guarantee is maintained outside of chromium
284 // code. Not notifying shared state in kModeProcessNoContext can lead to
285 // immediate deadlock, which is slightly more catastrophic than leaks or
286 // corruption.
287 if (draw_info->mode == AwDrawGLInfo::kModeProcess ||
288 draw_info->mode == AwDrawGLInfo::kModeProcessNoContext) {
289 DidDrawGLProcess();
290 }
291
270 { 292 {
271 GLViewRendererManager* manager = GLViewRendererManager::GetInstance(); 293 GLViewRendererManager* manager = GLViewRendererManager::GetInstance();
272 base::AutoLock lock(lock_); 294 base::AutoLock lock(lock_);
273 if (renderer_manager_key_ != manager->NullKey()) { 295 if (renderer_manager_key_ != manager->NullKey()) {
274 manager->DidDrawGL(renderer_manager_key_); 296 manager->DidDrawGL(renderer_manager_key_);
275 } 297 }
276 } 298 }
277 299
278 ScopedAppGLStateRestore state_restore( 300 ScopedAppGLStateRestore state_restore(
279 draw_info->mode == AwDrawGLInfo::kModeDraw 301 draw_info->mode == AwDrawGLInfo::kModeDraw
280 ? ScopedAppGLStateRestore::MODE_DRAW 302 ? ScopedAppGLStateRestore::MODE_DRAW
281 : ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); 303 : ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT);
282 ScopedAllowGL allow_gl; 304 ScopedAllowGL allow_gl;
283 305
284 if (draw_info->mode == AwDrawGLInfo::kModeProcessNoContext) { 306 if (draw_info->mode == AwDrawGLInfo::kModeProcessNoContext) {
285 LOG(ERROR) << "Received unexpected kModeProcessNoContext"; 307 LOG(ERROR) << "Received unexpected kModeProcessNoContext";
286 } 308 }
287 309
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()) { 310 if (IsInsideHardwareRelease()) {
299 hardware_renderer_.reset(); 311 hardware_renderer_.reset();
300 // Flush the idle queue in tear down. 312 // Flush the idle queue in tear down.
301 DeferredGpuCommandService::GetInstance()->PerformAllIdleWork(); 313 DeferredGpuCommandService::GetInstance()->PerformAllIdleWork();
302 return; 314 return;
303 } 315 }
304 316
305 if (draw_info->mode != AwDrawGLInfo::kModeDraw) { 317 if (draw_info->mode != AwDrawGLInfo::kModeDraw) {
306 if (draw_info->mode == AwDrawGLInfo::kModeProcess) { 318 if (draw_info->mode == AwDrawGLInfo::kModeProcess) {
307 DeferredGpuCommandService::GetInstance()->PerformIdleWork(true); 319 DeferredGpuCommandService::GetInstance()->PerformIdleWork(true);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 : shared_renderer_state_(shared_renderer_state) { 383 : shared_renderer_state_(shared_renderer_state) {
372 DCHECK(!shared_renderer_state_->IsInsideHardwareRelease()); 384 DCHECK(!shared_renderer_state_->IsInsideHardwareRelease());
373 shared_renderer_state_->SetInsideHardwareRelease(true); 385 shared_renderer_state_->SetInsideHardwareRelease(true);
374 } 386 }
375 387
376 SharedRendererState::InsideHardwareReleaseReset::~InsideHardwareReleaseReset() { 388 SharedRendererState::InsideHardwareReleaseReset::~InsideHardwareReleaseReset() {
377 shared_renderer_state_->SetInsideHardwareRelease(false); 389 shared_renderer_state_->SetInsideHardwareRelease(false);
378 } 390 }
379 391
380 } // namespace android_webview 392 } // namespace android_webview
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698