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

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

Issue 1904453004: Transfer DrawGLFunctor ownership from AwContents to AwGLFunctor (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 months 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/render_thread_manager.h" 5 #include "android_webview/browser/render_thread_manager.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "android_webview/browser/child_frame.h" 9 #include "android_webview/browser/child_frame.h"
10 #include "android_webview/browser/deferred_gpu_command_service.h" 10 #include "android_webview/browser/deferred_gpu_command_service.h"
11 #include "android_webview/browser/hardware_renderer.h" 11 #include "android_webview/browser/hardware_renderer.h"
12 #include "android_webview/browser/render_thread_manager_client.h" 12 #include "android_webview/browser/render_thread_manager_client.h"
13 #include "android_webview/browser/scoped_app_gl_state_restore.h" 13 #include "android_webview/browser/scoped_app_gl_state_restore.h"
14 #include "android_webview/public/browser/draw_gl.h" 14 #include "android_webview/public/browser/draw_gl.h"
15 #include "base/bind.h" 15 #include "base/bind.h"
16 #include "base/lazy_instance.h" 16 #include "base/lazy_instance.h"
17 #include "base/location.h" 17 #include "base/location.h"
18 #include "base/time/time.h" 18 #include "base/time/time.h"
19 #include "base/trace_event/trace_event_argument.h" 19 #include "base/trace_event/trace_event_argument.h"
20 20
21 namespace android_webview { 21 namespace android_webview {
22 22
23 namespace internal { 23 namespace internal {
24 24
25 class RequestDrawGLTracker { 25 class RequestInvokeGLTracker {
26 public: 26 public:
27 RequestDrawGLTracker(); 27 RequestInvokeGLTracker();
28 bool ShouldRequestOnNonUiThread(RenderThreadManager* state); 28 bool ShouldRequestOnNonUiThread(RenderThreadManager* state);
29 bool ShouldRequestOnUiThread(RenderThreadManager* state); 29 bool ShouldRequestOnUiThread(RenderThreadManager* state);
30 void ResetPending(); 30 void ResetPending();
31 void SetQueuedFunctorOnUi(RenderThreadManager* state); 31 void SetQueuedFunctorOnUi(RenderThreadManager* state);
32 32
33 private: 33 private:
34 base::Lock lock_; 34 base::Lock lock_;
35 RenderThreadManager* pending_ui_; 35 RenderThreadManager* pending_ui_;
36 RenderThreadManager* pending_non_ui_; 36 RenderThreadManager* pending_non_ui_;
37 }; 37 };
38 38
39 RequestDrawGLTracker::RequestDrawGLTracker() 39 RequestInvokeGLTracker::RequestInvokeGLTracker()
40 : pending_ui_(NULL), pending_non_ui_(NULL) { 40 : pending_ui_(NULL), pending_non_ui_(NULL) {}
41 }
42 41
43 bool RequestDrawGLTracker::ShouldRequestOnNonUiThread( 42 bool RequestInvokeGLTracker::ShouldRequestOnNonUiThread(
44 RenderThreadManager* state) { 43 RenderThreadManager* state) {
45 base::AutoLock lock(lock_); 44 base::AutoLock lock(lock_);
46 if (pending_ui_ || pending_non_ui_) 45 if (pending_ui_ || pending_non_ui_)
47 return false; 46 return false;
48 pending_non_ui_ = state; 47 pending_non_ui_ = state;
49 return true; 48 return true;
50 } 49 }
51 50
52 bool RequestDrawGLTracker::ShouldRequestOnUiThread(RenderThreadManager* state) { 51 bool RequestInvokeGLTracker::ShouldRequestOnUiThread(
52 RenderThreadManager* state) {
53 base::AutoLock lock(lock_); 53 base::AutoLock lock(lock_);
54 if (pending_non_ui_) { 54 if (pending_non_ui_) {
55 pending_non_ui_->ResetRequestDrawGLCallback(); 55 pending_non_ui_->ResetRequestInvokeGLCallback();
56 pending_non_ui_ = NULL; 56 pending_non_ui_ = NULL;
57 } 57 }
58 // At this time, we could have already called RequestDrawGL on the UI thread, 58 // At this time, we could have already called RequestInvokeGL on the UI
59 // thread,
59 // but the corresponding GL mode process hasn't happened yet. In this case, 60 // but the corresponding GL mode process hasn't happened yet. In this case,
60 // don't schedule another requestDrawGL on the UI thread. 61 // don't schedule another requestInvokeGL on the UI thread.
61 if (pending_ui_) 62 if (pending_ui_)
62 return false; 63 return false;
63 pending_ui_ = state; 64 pending_ui_ = state;
64 return true; 65 return true;
65 } 66 }
66 67
67 void RequestDrawGLTracker::ResetPending() { 68 void RequestInvokeGLTracker::ResetPending() {
68 base::AutoLock lock(lock_); 69 base::AutoLock lock(lock_);
69 pending_non_ui_ = NULL; 70 pending_non_ui_ = NULL;
70 pending_ui_ = NULL; 71 pending_ui_ = NULL;
71 } 72 }
72 73
73 void RequestDrawGLTracker::SetQueuedFunctorOnUi(RenderThreadManager* state) { 74 void RequestInvokeGLTracker::SetQueuedFunctorOnUi(RenderThreadManager* state) {
74 base::AutoLock lock(lock_); 75 base::AutoLock lock(lock_);
75 DCHECK(state); 76 DCHECK(state);
76 pending_ui_ = state; 77 pending_ui_ = state;
77 pending_non_ui_ = NULL; 78 pending_non_ui_ = NULL;
78 } 79 }
79 80
80 } // namespace internal 81 } // namespace internal
81 82
82 namespace { 83 namespace {
83 84
84 base::LazyInstance<internal::RequestDrawGLTracker> g_request_draw_gl_tracker = 85 base::LazyInstance<internal::RequestInvokeGLTracker>
85 LAZY_INSTANCE_INITIALIZER; 86 g_request_invoke_gl_tracker = LAZY_INSTANCE_INITIALIZER;
86
87 } 87 }
88 88
89 RenderThreadManager::RenderThreadManager( 89 RenderThreadManager::RenderThreadManager(
90 RenderThreadManagerClient* client, 90 RenderThreadManagerClient* client,
91 const scoped_refptr<base::SingleThreadTaskRunner>& ui_loop) 91 const scoped_refptr<base::SingleThreadTaskRunner>& ui_loop)
92 : ui_loop_(ui_loop), 92 : ui_loop_(ui_loop),
93 client_(client), 93 client_(client),
94 renderer_manager_key_(GLViewRendererManager::GetInstance()->NullKey()), 94 renderer_manager_key_(GLViewRendererManager::GetInstance()->NullKey()),
95 hardware_renderer_has_frame_(false), 95 hardware_renderer_has_frame_(false),
96 inside_hardware_release_(false), 96 inside_hardware_release_(false),
97 weak_factory_on_ui_thread_(this) { 97 weak_factory_on_ui_thread_(this) {
98 DCHECK(ui_loop_->BelongsToCurrentThread()); 98 DCHECK(ui_loop_->BelongsToCurrentThread());
99 DCHECK(client_); 99 DCHECK(client_);
100 ui_thread_weak_ptr_ = weak_factory_on_ui_thread_.GetWeakPtr(); 100 ui_thread_weak_ptr_ = weak_factory_on_ui_thread_.GetWeakPtr();
101 ResetRequestDrawGLCallback(); 101 ResetRequestInvokeGLCallback();
102 } 102 }
103 103
104 RenderThreadManager::~RenderThreadManager() { 104 RenderThreadManager::~RenderThreadManager() {
105 DCHECK(ui_loop_->BelongsToCurrentThread()); 105 DCHECK(ui_loop_->BelongsToCurrentThread());
106 DCHECK(!hardware_renderer_.get()); 106 DCHECK(!hardware_renderer_.get());
107 } 107 }
108 108
109 void RenderThreadManager::ClientRequestDrawGL(bool for_idle) { 109 void RenderThreadManager::ClientRequestInvokeGL(bool for_idle) {
110 if (ui_loop_->BelongsToCurrentThread()) { 110 if (ui_loop_->BelongsToCurrentThread()) {
111 if (!g_request_draw_gl_tracker.Get().ShouldRequestOnUiThread(this)) 111 if (!g_request_invoke_gl_tracker.Get().ShouldRequestOnUiThread(this))
112 return; 112 return;
113 ClientRequestDrawGLOnUI(); 113 ClientRequestInvokeGLOnUI();
114 } else { 114 } else {
115 if (!g_request_draw_gl_tracker.Get().ShouldRequestOnNonUiThread(this)) 115 if (!g_request_invoke_gl_tracker.Get().ShouldRequestOnNonUiThread(this))
116 return; 116 return;
117 base::Closure callback; 117 base::Closure callback;
118 { 118 {
119 base::AutoLock lock(lock_); 119 base::AutoLock lock(lock_);
120 callback = request_draw_gl_closure_; 120 callback = request_draw_gl_closure_;
121 } 121 }
122 // 17ms is slightly longer than a frame, hoping that it will come 122 // 17ms is slightly longer than a frame, hoping that it will come
123 // after the next frame so that the idle work is taken care off by 123 // after the next frame so that the idle work is taken care off by
124 // the next frame instead. 124 // the next frame instead.
125 ui_loop_->PostDelayedTask( 125 ui_loop_->PostDelayedTask(
126 FROM_HERE, callback, 126 FROM_HERE, callback,
127 for_idle ? base::TimeDelta::FromMilliseconds(17) : base::TimeDelta()); 127 for_idle ? base::TimeDelta::FromMilliseconds(17) : base::TimeDelta());
128 } 128 }
129 } 129 }
130 130
131 void RenderThreadManager::DidDrawGLProcess() { 131 void RenderThreadManager::DidInvokeGLProcess() {
132 g_request_draw_gl_tracker.Get().ResetPending(); 132 g_request_invoke_gl_tracker.Get().ResetPending();
133 } 133 }
134 134
135 void RenderThreadManager::ResetRequestDrawGLCallback() { 135 void RenderThreadManager::ResetRequestInvokeGLCallback() {
136 DCHECK(ui_loop_->BelongsToCurrentThread()); 136 DCHECK(ui_loop_->BelongsToCurrentThread());
137 base::AutoLock lock(lock_); 137 base::AutoLock lock(lock_);
138 request_draw_gl_cancelable_closure_.Reset(base::Bind( 138 request_draw_gl_cancelable_closure_.Reset(base::Bind(
139 &RenderThreadManager::ClientRequestDrawGLOnUI, base::Unretained(this))); 139 &RenderThreadManager::ClientRequestInvokeGLOnUI, base::Unretained(this)));
140 request_draw_gl_closure_ = request_draw_gl_cancelable_closure_.callback(); 140 request_draw_gl_closure_ = request_draw_gl_cancelable_closure_.callback();
141 } 141 }
142 142
143 void RenderThreadManager::ClientRequestDrawGLOnUI() { 143 void RenderThreadManager::ClientRequestInvokeGLOnUI() {
144 DCHECK(ui_loop_->BelongsToCurrentThread()); 144 DCHECK(ui_loop_->BelongsToCurrentThread());
145 ResetRequestDrawGLCallback(); 145 ResetRequestInvokeGLCallback();
146 g_request_draw_gl_tracker.Get().SetQueuedFunctorOnUi(this); 146 g_request_invoke_gl_tracker.Get().SetQueuedFunctorOnUi(this);
147 if (!client_->RequestDrawGL(false)) { 147 if (!client_->RequestInvokeGL(false)) {
148 g_request_draw_gl_tracker.Get().ResetPending(); 148 g_request_invoke_gl_tracker.Get().ResetPending();
149 LOG(ERROR) << "Failed to request GL process. Deadlock likely"; 149 LOG(ERROR) << "Failed to request GL process. Deadlock likely";
150 } 150 }
151 } 151 }
152 152
153 void RenderThreadManager::UpdateParentDrawConstraintsOnUI() { 153 void RenderThreadManager::UpdateParentDrawConstraintsOnUI() {
154 DCHECK(ui_loop_->BelongsToCurrentThread()); 154 DCHECK(ui_loop_->BelongsToCurrentThread());
155 client_->OnParentDrawConstraintsUpdated(); 155 client_->OnParentDrawConstraintsUpdated();
156 } 156 }
157 157
158 void RenderThreadManager::SetScrollOffsetOnUI(gfx::Vector2d scroll_offset) { 158 void RenderThreadManager::SetScrollOffsetOnUI(gfx::Vector2d scroll_offset) {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 return; 255 return;
256 } 256 }
257 257
258 // kModeProcessNoContext should never happen because we tear down hardware 258 // kModeProcessNoContext should never happen because we tear down hardware
259 // in onTrimMemory. However that guarantee is maintained outside of chromium 259 // in onTrimMemory. However that guarantee is maintained outside of chromium
260 // code. Not notifying shared state in kModeProcessNoContext can lead to 260 // code. Not notifying shared state in kModeProcessNoContext can lead to
261 // immediate deadlock, which is slightly more catastrophic than leaks or 261 // immediate deadlock, which is slightly more catastrophic than leaks or
262 // corruption. 262 // corruption.
263 if (draw_info->mode == AwDrawGLInfo::kModeProcess || 263 if (draw_info->mode == AwDrawGLInfo::kModeProcess ||
264 draw_info->mode == AwDrawGLInfo::kModeProcessNoContext) { 264 draw_info->mode == AwDrawGLInfo::kModeProcessNoContext) {
265 DidDrawGLProcess(); 265 DidInvokeGLProcess();
266 } 266 }
267 267
268 { 268 {
269 GLViewRendererManager* manager = GLViewRendererManager::GetInstance(); 269 GLViewRendererManager* manager = GLViewRendererManager::GetInstance();
270 base::AutoLock lock(lock_); 270 base::AutoLock lock(lock_);
271 if (renderer_manager_key_ != manager->NullKey()) { 271 if (renderer_manager_key_ != manager->NullKey()) {
272 manager->DidDrawGL(renderer_manager_key_); 272 manager->DidDrawGL(renderer_manager_key_);
273 } 273 }
274 } 274 }
275 275
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 } 317 }
318 318
319 void RenderThreadManager::DeleteHardwareRendererOnUI() { 319 void RenderThreadManager::DeleteHardwareRendererOnUI() {
320 DCHECK(ui_loop_->BelongsToCurrentThread()); 320 DCHECK(ui_loop_->BelongsToCurrentThread());
321 321
322 InsideHardwareReleaseReset auto_inside_hardware_release_reset(this); 322 InsideHardwareReleaseReset auto_inside_hardware_release_reset(this);
323 323
324 client_->DetachFunctorFromView(); 324 client_->DetachFunctorFromView();
325 325
326 // If the WebView gets onTrimMemory >= MODERATE twice in a row, the 2nd 326 // If the WebView gets onTrimMemory >= MODERATE twice in a row, the 2nd
327 // onTrimMemory will result in an unnecessary Render Thread DrawGL call. 327 // onTrimMemory will result in an unnecessary Render Thread InvokeGL call.
328 bool hardware_initialized = HasFrameOnUI(); 328 bool hardware_initialized = HasFrameOnUI();
329 if (hardware_initialized) { 329 if (hardware_initialized) {
330 bool draw_functor_succeeded = client_->RequestDrawGL(true); 330 bool draw_functor_succeeded = client_->RequestInvokeGL(true);
331 if (!draw_functor_succeeded) { 331 if (!draw_functor_succeeded) {
332 LOG(ERROR) << "Unable to free GL resources. Has the Window leaked?"; 332 LOG(ERROR) << "Unable to free GL resources. Has the Window leaked?";
333 // Calling release on wrong thread intentionally. 333 // Calling release on wrong thread intentionally.
334 AwDrawGLInfo info; 334 AwDrawGLInfo info;
335 info.mode = AwDrawGLInfo::kModeProcess; 335 info.mode = AwDrawGLInfo::kModeProcess;
336 DrawGL(&info); 336 DrawGL(&info);
337 } 337 }
338 } 338 }
339 339
340 GLViewRendererManager* manager = GLViewRendererManager::GetInstance(); 340 GLViewRendererManager* manager = GLViewRendererManager::GetInstance();
341 341
342 { 342 {
343 base::AutoLock lock(lock_); 343 base::AutoLock lock(lock_);
344 if (renderer_manager_key_ != manager->NullKey()) { 344 if (renderer_manager_key_ != manager->NullKey()) {
345 manager->Remove(renderer_manager_key_); 345 manager->Remove(renderer_manager_key_);
346 renderer_manager_key_ = manager->NullKey(); 346 renderer_manager_key_ = manager->NullKey();
347 } 347 }
348 } 348 }
349 349
350 if (hardware_initialized) { 350 if (hardware_initialized) {
351 // Flush any invoke functors that's caused by ReleaseHardware. 351 // Flush any invoke functors that's caused by ReleaseHardware.
352 client_->RequestDrawGL(true); 352 client_->RequestInvokeGL(true);
353 } 353 }
354 } 354 }
355 355
356 bool RenderThreadManager::HasFrameOnUI() const { 356 bool RenderThreadManager::HasFrameOnUI() const {
357 base::AutoLock lock(lock_); 357 base::AutoLock lock(lock_);
358 return hardware_renderer_has_frame_ || child_frame_.get(); 358 return hardware_renderer_has_frame_ || child_frame_.get();
359 } 359 }
360 360
361 bool RenderThreadManager::HasFrameForHardwareRendererOnRT() const { 361 bool RenderThreadManager::HasFrameForHardwareRendererOnRT() const {
362 base::AutoLock lock(lock_); 362 base::AutoLock lock(lock_);
(...skipping 15 matching lines...) Expand all
378 : render_thread_manager_(render_thread_manager) { 378 : render_thread_manager_(render_thread_manager) {
379 DCHECK(!render_thread_manager_->IsInsideHardwareRelease()); 379 DCHECK(!render_thread_manager_->IsInsideHardwareRelease());
380 render_thread_manager_->SetInsideHardwareRelease(true); 380 render_thread_manager_->SetInsideHardwareRelease(true);
381 } 381 }
382 382
383 RenderThreadManager::InsideHardwareReleaseReset::~InsideHardwareReleaseReset() { 383 RenderThreadManager::InsideHardwareReleaseReset::~InsideHardwareReleaseReset() {
384 render_thread_manager_->SetInsideHardwareRelease(false); 384 render_thread_manager_->SetInsideHardwareRelease(false);
385 } 385 }
386 386
387 } // namespace android_webview 387 } // namespace android_webview
OLDNEW
« no previous file with comments | « android_webview/browser/render_thread_manager.h ('k') | android_webview/browser/render_thread_manager_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698