OLD | NEW |
---|---|
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_client.h" | 7 #include "android_webview/browser/browser_view_renderer_client.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/lazy_instance.h" | |
9 #include "base/location.h" | 10 #include "base/location.h" |
10 | 11 |
11 namespace android_webview { | 12 namespace android_webview { |
12 | 13 |
14 namespace internal { | |
15 | |
16 class RequestDrawGLTracker { | |
17 public: | |
18 RequestDrawGLTracker(); | |
19 bool ShouldRequestOnNoneUiThread(SharedRendererState* state); | |
20 bool ShouldRequestOnUiThread(SharedRendererState* state); | |
21 void DidRequestOnUiThread(); | |
22 void DidDrawGLProcess(); | |
23 | |
24 private: | |
25 base::Lock lock_; | |
26 SharedRendererState* pending_ui_; | |
27 SharedRendererState* pending_non_ui_; | |
28 }; | |
29 | |
30 RequestDrawGLTracker::RequestDrawGLTracker() | |
31 : pending_ui_(NULL), pending_non_ui_(NULL) { | |
32 } | |
33 | |
34 bool RequestDrawGLTracker::ShouldRequestOnNoneUiThread( | |
35 SharedRendererState* state) { | |
36 base::AutoLock lock(lock_); | |
37 if (pending_ui_ || pending_non_ui_) | |
38 return false; | |
39 pending_non_ui_ = state; | |
40 return true; | |
41 } | |
42 | |
43 bool RequestDrawGLTracker::ShouldRequestOnUiThread(SharedRendererState* state) { | |
44 base::AutoLock lock(lock_); | |
45 if (pending_non_ui_) { | |
46 pending_non_ui_->ResetRequestDrawGLCallback(); | |
47 pending_non_ui_ = NULL; | |
48 } | |
49 if (pending_ui_) | |
50 return false; | |
51 pending_ui_ = state; | |
52 return true; | |
53 } | |
54 | |
55 void RequestDrawGLTracker::DidDrawGLProcess() { | |
56 base::AutoLock lock(lock_); | |
57 pending_non_ui_ = NULL; | |
58 pending_ui_ = NULL; | |
59 } | |
60 | |
61 } // namespace internal | |
62 | |
63 namespace { | |
64 base::LazyInstance<internal::RequestDrawGLTracker> g_request_draw_gl_tracker = | |
65 LAZY_INSTANCE_INITIALIZER; | |
66 } | |
67 | |
13 DrawGLInput::DrawGLInput() : width(0), height(0) { | 68 DrawGLInput::DrawGLInput() : width(0), height(0) { |
14 } | 69 } |
15 | 70 |
16 DrawGLInput::~DrawGLInput() { | 71 DrawGLInput::~DrawGLInput() { |
17 } | 72 } |
18 | 73 |
19 SharedRendererState::SharedRendererState( | 74 SharedRendererState::SharedRendererState( |
20 scoped_refptr<base::MessageLoopProxy> ui_loop, | 75 scoped_refptr<base::MessageLoopProxy> ui_loop, |
21 BrowserViewRendererClient* client) | 76 BrowserViewRendererClient* client) |
22 : ui_loop_(ui_loop), | 77 : ui_loop_(ui_loop), |
23 client_on_ui_(client), | 78 client_on_ui_(client), |
24 weak_factory_on_ui_thread_(this), | 79 weak_factory_on_ui_thread_(this), |
25 ui_thread_weak_ptr_(weak_factory_on_ui_thread_.GetWeakPtr()), | 80 ui_thread_weak_ptr_(weak_factory_on_ui_thread_.GetWeakPtr()), |
26 inside_hardware_release_(false), | 81 inside_hardware_release_(false), |
27 share_context_(NULL) { | 82 share_context_(NULL) { |
28 DCHECK(ui_loop_->BelongsToCurrentThread()); | 83 DCHECK(ui_loop_->BelongsToCurrentThread()); |
29 DCHECK(client_on_ui_); | 84 DCHECK(client_on_ui_); |
85 ResetRequestDrawGLCallback(); | |
30 } | 86 } |
31 | 87 |
32 SharedRendererState::~SharedRendererState() { | 88 SharedRendererState::~SharedRendererState() { |
33 DCHECK(ui_loop_->BelongsToCurrentThread()); | 89 DCHECK(ui_loop_->BelongsToCurrentThread()); |
34 } | 90 } |
35 | 91 |
36 bool SharedRendererState::CurrentlyOnUIThread() { | 92 bool SharedRendererState::CurrentlyOnUIThread() { |
37 return ui_loop_->BelongsToCurrentThread(); | 93 return ui_loop_->BelongsToCurrentThread(); |
38 } | 94 } |
39 | 95 |
40 void SharedRendererState::ClientRequestDrawGL() { | 96 void SharedRendererState::ClientRequestDrawGL() { |
41 if (ui_loop_->BelongsToCurrentThread()) { | 97 if (ui_loop_->BelongsToCurrentThread()) { |
98 if (!g_request_draw_gl_tracker.Get().ShouldRequestOnUiThread(this)) | |
99 return; | |
42 ClientRequestDrawGLOnUIThread(); | 100 ClientRequestDrawGLOnUIThread(); |
43 } else { | 101 } else { |
44 ui_loop_->PostTask( | 102 if (!g_request_draw_gl_tracker.Get().ShouldRequestOnNoneUiThread(this)) |
45 FROM_HERE, | 103 return; |
46 base::Bind(&SharedRendererState::ClientRequestDrawGLOnUIThread, | 104 base::Closure callback; |
47 ui_thread_weak_ptr_)); | 105 { |
106 base::AutoLock lock(lock_); | |
107 callback = request_draw_gl_closure_; | |
108 } | |
109 ui_loop_->PostTask(FROM_HERE, callback); | |
48 } | 110 } |
49 } | 111 } |
50 | 112 |
113 void SharedRendererState::DidDrawGLProcess() { | |
114 g_request_draw_gl_tracker.Get().DidDrawGLProcess(); | |
115 } | |
116 | |
117 void SharedRendererState::ResetRequestDrawGLCallback() { | |
118 DCHECK(ui_loop_->BelongsToCurrentThread()); | |
119 base::AutoLock lock(lock_); | |
120 request_draw_gl_cancelable_closure_.Reset( | |
121 base::Bind(&SharedRendererState::ClientRequestDrawGLOnUIThread, | |
122 base::Unretained(this))); | |
123 request_draw_gl_closure_ = request_draw_gl_cancelable_closure_.callback(); | |
124 } | |
125 | |
51 void SharedRendererState::ClientRequestDrawGLOnUIThread() { | 126 void SharedRendererState::ClientRequestDrawGLOnUIThread() { |
52 DCHECK(ui_loop_->BelongsToCurrentThread()); | 127 DCHECK(ui_loop_->BelongsToCurrentThread()); |
128 ResetRequestDrawGLCallback(); | |
53 if (!client_on_ui_->RequestDrawGL(NULL, false)) { | 129 if (!client_on_ui_->RequestDrawGL(NULL, false)) { |
130 g_request_draw_gl_tracker.Get().DidDrawGLProcess(); | |
hush (inactive)
2014/08/07 22:31:18
Could you use a better name than "DidDrawGLProcess
boliu
2014/08/07 23:28:08
ResetPending?
hush (inactive)
2014/08/07 23:39:43
sounds good.
On 2014/08/07 23:28:08, boliu wrote:
| |
54 LOG(ERROR) << "Failed to request GL process. Deadlock likely"; | 131 LOG(ERROR) << "Failed to request GL process. Deadlock likely"; |
55 } | 132 } |
56 } | 133 } |
57 | 134 |
58 void SharedRendererState::UpdateParentDrawConstraintsOnUIThread() { | 135 void SharedRendererState::UpdateParentDrawConstraintsOnUIThread() { |
59 DCHECK(ui_loop_->BelongsToCurrentThread()); | 136 DCHECK(ui_loop_->BelongsToCurrentThread()); |
60 client_on_ui_->UpdateParentDrawConstraints(); | 137 client_on_ui_->UpdateParentDrawConstraints(); |
61 } | 138 } |
62 | 139 |
63 void SharedRendererState::SetDrawGLInput(scoped_ptr<DrawGLInput> input) { | 140 void SharedRendererState::SetDrawGLInput(scoped_ptr<DrawGLInput> input) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
137 : shared_renderer_state_(shared_renderer_state) { | 214 : shared_renderer_state_(shared_renderer_state) { |
138 DCHECK(!shared_renderer_state_->IsInsideHardwareRelease()); | 215 DCHECK(!shared_renderer_state_->IsInsideHardwareRelease()); |
139 shared_renderer_state_->SetInsideHardwareRelease(true); | 216 shared_renderer_state_->SetInsideHardwareRelease(true); |
140 } | 217 } |
141 | 218 |
142 InsideHardwareReleaseReset::~InsideHardwareReleaseReset() { | 219 InsideHardwareReleaseReset::~InsideHardwareReleaseReset() { |
143 shared_renderer_state_->SetInsideHardwareRelease(false); | 220 shared_renderer_state_->SetInsideHardwareRelease(false); |
144 } | 221 } |
145 | 222 |
146 } // namespace android_webview | 223 } // namespace android_webview |
OLD | NEW |