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/compositor_proxy.h" |
6 | 6 |
7 #include "android_webview/browser/browser_view_renderer_client.h" | 7 #include "android_webview/browser/aw_gl_methods.h" |
| 8 #include "android_webview/browser/browser_view_renderer.h" |
8 #include "base/bind.h" | 9 #include "base/bind.h" |
9 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
10 #include "base/location.h" | 11 #include "base/location.h" |
11 | 12 |
12 namespace android_webview { | 13 namespace android_webview { |
13 | 14 |
14 namespace internal { | 15 namespace internal { |
15 | 16 |
16 class RequestDrawGLTracker { | 17 class RequestDrawGLTracker { |
17 public: | 18 public: |
18 RequestDrawGLTracker(); | 19 RequestDrawGLTracker(); |
19 bool ShouldRequestOnNoneUiThread(SharedRendererState* state); | 20 bool ShouldRequestOnNonUiThread(CompositorProxy* proxy); |
20 bool ShouldRequestOnUiThread(SharedRendererState* state); | 21 bool ShouldRequestOnUiThread(CompositorProxy* proxy); |
21 void DidRequestOnUiThread(); | 22 void DidRequestOnUiThread(); |
22 void ResetPending(); | 23 void ResetPending(); |
23 | 24 |
24 private: | 25 private: |
25 base::Lock lock_; | 26 base::Lock lock_; |
26 SharedRendererState* pending_ui_; | 27 CompositorProxy* pending_ui_; |
27 SharedRendererState* pending_non_ui_; | 28 CompositorProxy* pending_non_ui_; |
28 }; | 29 }; |
29 | 30 |
30 RequestDrawGLTracker::RequestDrawGLTracker() | 31 RequestDrawGLTracker::RequestDrawGLTracker() |
31 : pending_ui_(NULL), pending_non_ui_(NULL) { | 32 : pending_ui_(NULL), pending_non_ui_(NULL) { |
32 } | 33 } |
33 | 34 |
34 bool RequestDrawGLTracker::ShouldRequestOnNoneUiThread( | 35 bool RequestDrawGLTracker::ShouldRequestOnNonUiThread(CompositorProxy* proxy) { |
35 SharedRendererState* state) { | |
36 base::AutoLock lock(lock_); | 36 base::AutoLock lock(lock_); |
37 if (pending_ui_ || pending_non_ui_) | 37 if (pending_ui_ || pending_non_ui_) |
38 return false; | 38 return false; |
39 pending_non_ui_ = state; | 39 pending_non_ui_ = proxy; |
40 return true; | 40 return true; |
41 } | 41 } |
42 | 42 |
43 bool RequestDrawGLTracker::ShouldRequestOnUiThread(SharedRendererState* state) { | 43 bool RequestDrawGLTracker::ShouldRequestOnUiThread(CompositorProxy* proxy) { |
44 base::AutoLock lock(lock_); | 44 base::AutoLock lock(lock_); |
45 if (pending_non_ui_) { | 45 if (pending_non_ui_) { |
46 pending_non_ui_->ResetRequestDrawGLCallback(); | 46 pending_non_ui_->ResetRequestDrawGLCallback(); |
47 pending_non_ui_ = NULL; | 47 pending_non_ui_ = NULL; |
48 } | 48 } |
49 if (pending_ui_) | 49 if (pending_ui_) |
50 return false; | 50 return false; |
51 pending_ui_ = state; | 51 pending_ui_ = proxy; |
52 return true; | 52 return true; |
53 } | 53 } |
54 | 54 |
55 void RequestDrawGLTracker::ResetPending() { | 55 void RequestDrawGLTracker::ResetPending() { |
56 base::AutoLock lock(lock_); | 56 base::AutoLock lock(lock_); |
57 pending_non_ui_ = NULL; | 57 pending_non_ui_ = NULL; |
58 pending_ui_ = NULL; | 58 pending_ui_ = NULL; |
59 } | 59 } |
60 | 60 |
61 } // namespace internal | 61 } // namespace internal |
62 | 62 |
63 namespace { | 63 namespace { |
64 | 64 |
65 base::LazyInstance<internal::RequestDrawGLTracker> g_request_draw_gl_tracker = | 65 base::LazyInstance<internal::RequestDrawGLTracker> g_request_draw_gl_tracker = |
66 LAZY_INSTANCE_INITIALIZER; | 66 LAZY_INSTANCE_INITIALIZER; |
67 | |
68 } | 67 } |
69 | 68 |
70 SharedRendererState::SharedRendererState( | 69 CompositorProxy::CompositorProxy(scoped_refptr<base::MessageLoopProxy> ui_loop, |
71 scoped_refptr<base::MessageLoopProxy> ui_loop, | 70 AwGLMethods* gl_methods) |
72 BrowserViewRendererClient* client) | |
73 : ui_loop_(ui_loop), | 71 : ui_loop_(ui_loop), |
74 client_on_ui_(client), | 72 gl_methods_on_ui_(gl_methods), |
75 force_commit_(false), | 73 force_commit_(false), |
76 inside_hardware_release_(false), | 74 inside_hardware_release_(false), |
77 needs_force_invalidate_on_next_draw_gl_(false), | 75 needs_force_invalidate_on_next_draw_gl_(false), |
78 weak_factory_on_ui_thread_(this) { | 76 weak_factory_on_ui_thread_(this) { |
79 DCHECK(ui_loop_->BelongsToCurrentThread()); | 77 DCHECK(ui_loop_->BelongsToCurrentThread()); |
80 DCHECK(client_on_ui_); | 78 DCHECK(gl_methods_on_ui_); |
81 ui_thread_weak_ptr_ = weak_factory_on_ui_thread_.GetWeakPtr(); | 79 ui_thread_weak_ptr_ = weak_factory_on_ui_thread_.GetWeakPtr(); |
82 ResetRequestDrawGLCallback(); | 80 ResetRequestDrawGLCallback(); |
83 } | 81 } |
84 | 82 |
85 SharedRendererState::~SharedRendererState() { | 83 CompositorProxy::~CompositorProxy() { |
86 DCHECK(ui_loop_->BelongsToCurrentThread()); | 84 DCHECK(ui_loop_->BelongsToCurrentThread()); |
87 } | 85 } |
88 | 86 |
89 void SharedRendererState::ClientRequestDrawGL() { | 87 void CompositorProxy::ClientRequestDrawGL() { |
90 if (ui_loop_->BelongsToCurrentThread()) { | 88 if (ui_loop_->BelongsToCurrentThread()) { |
91 if (!g_request_draw_gl_tracker.Get().ShouldRequestOnUiThread(this)) | 89 if (!g_request_draw_gl_tracker.Get().ShouldRequestOnUiThread(this)) |
92 return; | 90 return; |
93 ClientRequestDrawGLOnUIThread(); | 91 ClientRequestDrawGLOnUIThread(); |
94 } else { | 92 } else { |
95 if (!g_request_draw_gl_tracker.Get().ShouldRequestOnNoneUiThread(this)) | 93 if (!g_request_draw_gl_tracker.Get().ShouldRequestOnNonUiThread(this)) |
96 return; | 94 return; |
97 base::Closure callback; | 95 base::Closure callback; |
98 { | 96 { |
99 base::AutoLock lock(lock_); | 97 base::AutoLock lock(lock_); |
100 callback = request_draw_gl_closure_; | 98 callback = request_draw_gl_closure_; |
101 } | 99 } |
102 ui_loop_->PostTask(FROM_HERE, callback); | 100 ui_loop_->PostTask(FROM_HERE, callback); |
103 } | 101 } |
104 } | 102 } |
105 | 103 |
106 void SharedRendererState::DidDrawGLProcess() { | 104 void CompositorProxy::DidDrawGLProcess() { |
107 g_request_draw_gl_tracker.Get().ResetPending(); | 105 g_request_draw_gl_tracker.Get().ResetPending(); |
108 } | 106 } |
109 | 107 |
110 void SharedRendererState::ResetRequestDrawGLCallback() { | 108 void CompositorProxy::ResetRequestDrawGLCallback() { |
111 DCHECK(ui_loop_->BelongsToCurrentThread()); | 109 DCHECK(ui_loop_->BelongsToCurrentThread()); |
112 base::AutoLock lock(lock_); | 110 base::AutoLock lock(lock_); |
113 request_draw_gl_cancelable_closure_.Reset( | 111 request_draw_gl_cancelable_closure_.Reset(base::Bind( |
114 base::Bind(&SharedRendererState::ClientRequestDrawGLOnUIThread, | 112 &CompositorProxy::ClientRequestDrawGLOnUIThread, base::Unretained(this))); |
115 base::Unretained(this))); | |
116 request_draw_gl_closure_ = request_draw_gl_cancelable_closure_.callback(); | 113 request_draw_gl_closure_ = request_draw_gl_cancelable_closure_.callback(); |
117 } | 114 } |
118 | 115 |
119 void SharedRendererState::ClientRequestDrawGLOnUIThread() { | 116 void CompositorProxy::ClientRequestDrawGLOnUIThread() { |
120 DCHECK(ui_loop_->BelongsToCurrentThread()); | 117 DCHECK(ui_loop_->BelongsToCurrentThread()); |
121 ResetRequestDrawGLCallback(); | 118 ResetRequestDrawGLCallback(); |
122 if (!client_on_ui_->RequestDrawGL(NULL, false)) { | 119 if (!gl_methods_on_ui_->RequestDrawGL(NULL, false)) { |
123 g_request_draw_gl_tracker.Get().ResetPending(); | 120 g_request_draw_gl_tracker.Get().ResetPending(); |
124 LOG(ERROR) << "Failed to request GL process. Deadlock likely"; | 121 LOG(ERROR) << "Failed to request GL process. Deadlock likely"; |
125 } | 122 } |
126 } | 123 } |
127 | 124 |
128 void SharedRendererState::UpdateParentDrawConstraintsOnUIThread() { | 125 void CompositorProxy::SetParentDrawConstraintsOnUIThread() { |
129 DCHECK(ui_loop_->BelongsToCurrentThread()); | 126 DCHECK(ui_loop_->BelongsToCurrentThread()); |
130 client_on_ui_->UpdateParentDrawConstraints(); | 127 browser_view_renderer_->SetParentDrawConstraints(); |
131 } | 128 } |
132 | 129 |
133 void SharedRendererState::SetScrollOffset(gfx::Vector2d scroll_offset) { | 130 void CompositorProxy::SetScrollOffset(gfx::Vector2d scroll_offset) { |
134 base::AutoLock lock(lock_); | 131 base::AutoLock lock(lock_); |
135 scroll_offset_ = scroll_offset; | 132 scroll_offset_ = scroll_offset; |
136 } | 133 } |
137 | 134 |
138 gfx::Vector2d SharedRendererState::GetScrollOffset() { | 135 gfx::Vector2d CompositorProxy::GetScrollOffset() { |
139 base::AutoLock lock(lock_); | 136 base::AutoLock lock(lock_); |
140 return scroll_offset_; | 137 return scroll_offset_; |
141 } | 138 } |
142 | 139 |
143 bool SharedRendererState::HasCompositorFrame() const { | 140 bool CompositorProxy::HasCompositorFrame() const { |
144 base::AutoLock lock(lock_); | 141 base::AutoLock lock(lock_); |
145 return compositor_frame_.get(); | 142 return compositor_frame_.get(); |
146 } | 143 } |
147 | 144 |
148 void SharedRendererState::SetCompositorFrame( | 145 void CompositorProxy::SetCompositorFrame(scoped_ptr<cc::CompositorFrame> frame, |
149 scoped_ptr<cc::CompositorFrame> frame, bool force_commit) { | 146 bool force_commit) { |
| 147 ReturnUnusedResources(); |
| 148 |
150 base::AutoLock lock(lock_); | 149 base::AutoLock lock(lock_); |
151 DCHECK(!compositor_frame_.get()); | |
152 compositor_frame_ = frame.Pass(); | 150 compositor_frame_ = frame.Pass(); |
153 force_commit_ = force_commit; | 151 force_commit_ = force_commit; |
154 } | 152 } |
155 | 153 |
156 scoped_ptr<cc::CompositorFrame> SharedRendererState::PassCompositorFrame() { | 154 scoped_ptr<cc::CompositorFrame> CompositorProxy::PassCompositorFrame() { |
157 base::AutoLock lock(lock_); | 155 base::AutoLock lock(lock_); |
158 return compositor_frame_.Pass(); | 156 return compositor_frame_.Pass(); |
159 } | 157 } |
160 | 158 |
161 bool SharedRendererState::ForceCommit() const { | 159 bool CompositorProxy::ForceCommit() const { |
162 base::AutoLock lock(lock_); | 160 base::AutoLock lock(lock_); |
163 return force_commit_; | 161 return force_commit_; |
164 } | 162 } |
165 | 163 |
166 bool SharedRendererState::UpdateDrawConstraints( | 164 bool CompositorProxy::SetParentCompositorDrawConstraints( |
167 const ParentCompositorDrawConstraints& parent_draw_constraints) { | 165 const ParentCompositorDrawConstraints& parent_draw_constraints) { |
168 base::AutoLock lock(lock_); | 166 base::AutoLock lock(lock_); |
169 if (needs_force_invalidate_on_next_draw_gl_ || | 167 if (needs_force_invalidate_on_next_draw_gl_ || |
170 !parent_draw_constraints_.Equals(parent_draw_constraints)) { | 168 !parent_draw_constraints_.Equals(parent_draw_constraints)) { |
171 parent_draw_constraints_ = parent_draw_constraints; | 169 parent_draw_constraints_ = parent_draw_constraints; |
172 return true; | 170 return true; |
173 } | 171 } |
174 | 172 |
175 return false; | 173 return false; |
176 } | 174 } |
177 | 175 |
178 void SharedRendererState::PostExternalDrawConstraintsToChildCompositor( | 176 void CompositorProxy::PostExternalDrawConstraintsToChildCompositor( |
179 const ParentCompositorDrawConstraints& parent_draw_constraints) { | 177 const ParentCompositorDrawConstraints& parent_draw_constraints) { |
180 if (UpdateDrawConstraints(parent_draw_constraints)) { | 178 if (SetParentCompositorDrawConstraints(parent_draw_constraints)) { |
181 // No need to hold the lock_ during the post task. | 179 // No need to hold the lock_ during the post task. |
182 ui_loop_->PostTask( | 180 ui_loop_->PostTask( |
183 FROM_HERE, | 181 FROM_HERE, |
184 base::Bind(&SharedRendererState::UpdateParentDrawConstraintsOnUIThread, | 182 base::Bind(&CompositorProxy::SetParentDrawConstraintsOnUIThread, |
185 ui_thread_weak_ptr_)); | 183 ui_thread_weak_ptr_)); |
186 } | 184 } |
187 } | 185 } |
188 | 186 |
189 void SharedRendererState::DidSkipCommitFrame() { | 187 void CompositorProxy::DidSkipCommitFrame() { |
190 ui_loop_->PostTask( | 188 ui_loop_->PostTask(FROM_HERE, |
191 FROM_HERE, | 189 base::Bind(&CompositorProxy::DidSkipCommitFrameOnUIThread, |
192 base::Bind(&SharedRendererState::DidSkipCommitFrameOnUIThread, | 190 ui_thread_weak_ptr_)); |
193 ui_thread_weak_ptr_)); | |
194 } | 191 } |
195 | 192 |
196 void SharedRendererState::DidSkipCommitFrameOnUIThread() { | 193 void CompositorProxy::DidSkipCommitFrameOnUIThread() { |
197 DCHECK(ui_loop_->BelongsToCurrentThread()); | 194 DCHECK(ui_loop_->BelongsToCurrentThread()); |
198 client_on_ui_->DidSkipCommitFrame(); | 195 DCHECK(browser_view_renderer_); |
| 196 browser_view_renderer_->DidSkipCommitFrame(); |
199 } | 197 } |
200 | 198 |
201 const ParentCompositorDrawConstraints | 199 const ParentCompositorDrawConstraints |
202 SharedRendererState::ParentDrawConstraints() const { | 200 CompositorProxy::GetParentDrawConstraints() const { |
203 base::AutoLock lock(lock_); | 201 base::AutoLock lock(lock_); |
204 return parent_draw_constraints_; | 202 return parent_draw_constraints_; |
205 } | 203 } |
206 | 204 |
207 void SharedRendererState::SetForceInvalidateOnNextDrawGL( | 205 void CompositorProxy::SetForceInvalidateOnNextDrawGL( |
208 bool needs_force_invalidate_on_next_draw_gl) { | 206 bool needs_force_invalidate_on_next_draw_gl) { |
209 base::AutoLock lock(lock_); | 207 base::AutoLock lock(lock_); |
210 needs_force_invalidate_on_next_draw_gl_ = | 208 needs_force_invalidate_on_next_draw_gl_ = |
211 needs_force_invalidate_on_next_draw_gl; | 209 needs_force_invalidate_on_next_draw_gl; |
212 } | 210 } |
213 | 211 |
214 bool SharedRendererState::NeedsForceInvalidateOnNextDrawGL() const { | 212 bool CompositorProxy::NeedsForceInvalidateOnNextDrawGL() const { |
215 base::AutoLock lock(lock_); | 213 base::AutoLock lock(lock_); |
216 return needs_force_invalidate_on_next_draw_gl_; | 214 return needs_force_invalidate_on_next_draw_gl_; |
217 } | 215 } |
218 | 216 |
219 void SharedRendererState::SetInsideHardwareRelease(bool inside) { | 217 void CompositorProxy::SetInsideHardwareRelease(bool inside) { |
220 base::AutoLock lock(lock_); | 218 base::AutoLock lock(lock_); |
221 inside_hardware_release_ = inside; | 219 inside_hardware_release_ = inside; |
222 } | 220 } |
223 | 221 |
224 bool SharedRendererState::IsInsideHardwareRelease() const { | 222 void CompositorProxy::ReturnUnusedResources() { |
| 223 DCHECK(ui_loop_->BelongsToCurrentThread()); |
| 224 |
| 225 if (scoped_ptr<cc::CompositorFrame> frame = PassCompositorFrame()) { |
| 226 cc::ReturnedResourceArray resources; |
| 227 cc::TransferableResource::ReturnResources( |
| 228 frame->delegated_frame_data->resource_list, &resources); |
| 229 InsertReturnedResources(resources); |
| 230 } |
| 231 } |
| 232 |
| 233 bool CompositorProxy::IsInsideHardwareRelease() const { |
225 base::AutoLock lock(lock_); | 234 base::AutoLock lock(lock_); |
226 return inside_hardware_release_; | 235 return inside_hardware_release_; |
227 } | 236 } |
228 | 237 |
229 void SharedRendererState::InsertReturnedResources( | 238 void CompositorProxy::InsertReturnedResources( |
230 const cc::ReturnedResourceArray& resources) { | 239 const cc::ReturnedResourceArray& resources) { |
231 base::AutoLock lock(lock_); | 240 base::AutoLock lock(lock_); |
232 returned_resources_.insert( | 241 returned_resources_.insert( |
233 returned_resources_.end(), resources.begin(), resources.end()); | 242 returned_resources_.end(), resources.begin(), resources.end()); |
234 } | 243 } |
235 | 244 |
236 void SharedRendererState::SwapReturnedResources( | 245 void CompositorProxy::SwapReturnedResources( |
237 cc::ReturnedResourceArray* resources) { | 246 cc::ReturnedResourceArray* resources) { |
238 DCHECK(resources->empty()); | 247 DCHECK(resources->empty()); |
239 base::AutoLock lock(lock_); | 248 base::AutoLock lock(lock_); |
240 resources->swap(returned_resources_); | 249 resources->swap(returned_resources_); |
241 } | 250 } |
242 | 251 |
243 bool SharedRendererState::ReturnedResourcesEmpty() const { | 252 void CompositorProxy::SetBrowserViewRenderer( |
| 253 BrowserViewRenderer* browser_view_renderer) { |
244 base::AutoLock lock(lock_); | 254 base::AutoLock lock(lock_); |
245 return returned_resources_.empty(); | 255 browser_view_renderer_ = browser_view_renderer; |
246 } | 256 } |
247 | 257 |
248 InsideHardwareReleaseReset::InsideHardwareReleaseReset( | 258 InsideHardwareReleaseReset::InsideHardwareReleaseReset( |
249 SharedRendererState* shared_renderer_state) | 259 CompositorProxy* compositor_proxy) |
250 : shared_renderer_state_(shared_renderer_state) { | 260 : compositor_proxy_(compositor_proxy) { |
251 DCHECK(!shared_renderer_state_->IsInsideHardwareRelease()); | 261 DCHECK(!compositor_proxy_->IsInsideHardwareRelease()); |
252 shared_renderer_state_->SetInsideHardwareRelease(true); | 262 compositor_proxy_->SetInsideHardwareRelease(true); |
253 } | 263 } |
254 | 264 |
255 InsideHardwareReleaseReset::~InsideHardwareReleaseReset() { | 265 InsideHardwareReleaseReset::~InsideHardwareReleaseReset() { |
256 shared_renderer_state_->SetInsideHardwareRelease(false); | 266 compositor_proxy_->SetInsideHardwareRelease(false); |
257 } | 267 } |
258 | 268 |
259 } // namespace android_webview | 269 } // namespace android_webview |
OLD | NEW |