OLD | NEW |
1 // Copyright 2010 The Chromium Authors. All rights reserved. | 1 // Copyright 2010 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 "cc/layers/texture_layer.h" | 5 #include "cc/layers/texture_layer.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback_helpers.h" |
8 #include "base/location.h" | 9 #include "base/location.h" |
9 #include "base/synchronization/lock.h" | 10 #include "base/synchronization/lock.h" |
10 #include "cc/layers/texture_layer_client.h" | 11 #include "cc/layers/texture_layer_client.h" |
11 #include "cc/layers/texture_layer_impl.h" | 12 #include "cc/layers/texture_layer_impl.h" |
12 #include "cc/trees/blocking_task_runner.h" | 13 #include "cc/trees/blocking_task_runner.h" |
13 #include "cc/trees/layer_tree_host.h" | 14 #include "cc/trees/layer_tree_host.h" |
14 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" | 15 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" |
15 | 16 |
16 namespace cc { | 17 namespace cc { |
17 | 18 |
(...skipping 26 matching lines...) Expand all Loading... |
44 } | 45 } |
45 | 46 |
46 TextureLayer::~TextureLayer() { | 47 TextureLayer::~TextureLayer() { |
47 } | 48 } |
48 | 49 |
49 void TextureLayer::ClearClient() { | 50 void TextureLayer::ClearClient() { |
50 if (rate_limit_context_ && client_ && layer_tree_host()) | 51 if (rate_limit_context_ && client_ && layer_tree_host()) |
51 layer_tree_host()->StopRateLimiter(client_->Context3d()); | 52 layer_tree_host()->StopRateLimiter(client_->Context3d()); |
52 client_ = NULL; | 53 client_ = NULL; |
53 if (uses_mailbox_) | 54 if (uses_mailbox_) |
54 SetTextureMailbox(TextureMailbox()); | 55 SetTextureMailbox(TextureMailbox(), ScopedReleaseCallback()); |
55 else | 56 else |
56 SetTextureId(0); | 57 SetTextureId(0); |
57 } | 58 } |
58 | 59 |
59 scoped_ptr<LayerImpl> TextureLayer::CreateLayerImpl(LayerTreeImpl* tree_impl) { | 60 scoped_ptr<LayerImpl> TextureLayer::CreateLayerImpl(LayerTreeImpl* tree_impl) { |
60 return TextureLayerImpl::Create(tree_impl, id(), uses_mailbox_). | 61 return TextureLayerImpl::Create(tree_impl, id(), uses_mailbox_). |
61 PassAs<LayerImpl>(); | 62 PassAs<LayerImpl>(); |
62 } | 63 } |
63 | 64 |
64 void TextureLayer::SetFlipped(bool flipped) { | 65 void TextureLayer::SetFlipped(bool flipped) { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 return; | 124 return; |
124 if (texture_id_ && layer_tree_host()) | 125 if (texture_id_ && layer_tree_host()) |
125 layer_tree_host()->AcquireLayerTextures(); | 126 layer_tree_host()->AcquireLayerTextures(); |
126 texture_id_ = id; | 127 texture_id_ = id; |
127 SetNeedsCommit(); | 128 SetNeedsCommit(); |
128 // The texture id needs to be removed from the active tree before the | 129 // The texture id needs to be removed from the active tree before the |
129 // commit is called complete. | 130 // commit is called complete. |
130 SetNextCommitWaitsForActivation(); | 131 SetNextCommitWaitsForActivation(); |
131 } | 132 } |
132 | 133 |
133 void TextureLayer::SetTextureMailbox(const TextureMailbox& mailbox) { | 134 void TextureLayer::SetTextureMailbox(const TextureMailbox& mailbox, |
| 135 ScopedReleaseCallback release_callback) { |
134 DCHECK(uses_mailbox_); | 136 DCHECK(uses_mailbox_); |
135 DCHECK(!mailbox.IsValid() || !holder_ref_ || | 137 DCHECK(!mailbox.IsValid() || !holder_ref_ || |
136 !mailbox.Equals(holder_ref_->holder()->mailbox())); | 138 !mailbox.Equals(holder_ref_->holder()->mailbox())); |
| 139 DCHECK_EQ(mailbox.IsValid(), !release_callback.IsEmpty()); |
| 140 |
137 // If we never commited the mailbox, we need to release it here. | 141 // If we never commited the mailbox, we need to release it here. |
138 if (mailbox.IsValid()) | 142 if (mailbox.IsValid()) |
139 holder_ref_ = MailboxHolder::Create(mailbox); | 143 holder_ref_ = MailboxHolder::Create(mailbox, release_callback.Pass()); |
140 else | 144 else |
141 holder_ref_.reset(); | 145 holder_ref_.reset(); |
142 needs_set_mailbox_ = true; | 146 needs_set_mailbox_ = true; |
143 SetNeedsCommit(); | 147 SetNeedsCommit(); |
144 // The active frame needs to be replaced and the mailbox returned before the | 148 // The active frame needs to be replaced and the mailbox returned before the |
145 // commit is called complete. | 149 // commit is called complete. |
146 SetNextCommitWaitsForActivation(); | 150 SetNextCommitWaitsForActivation(); |
147 } | 151 } |
148 | 152 |
149 void TextureLayer::WillModifyTexture() { | 153 void TextureLayer::WillModifyTexture() { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 bool TextureLayer::DrawsContent() const { | 195 bool TextureLayer::DrawsContent() const { |
192 return (client_ || texture_id_ || holder_ref_) && Layer::DrawsContent(); | 196 return (client_ || texture_id_ || holder_ref_) && Layer::DrawsContent(); |
193 } | 197 } |
194 | 198 |
195 bool TextureLayer::Update(ResourceUpdateQueue* queue, | 199 bool TextureLayer::Update(ResourceUpdateQueue* queue, |
196 const OcclusionTracker* occlusion) { | 200 const OcclusionTracker* occlusion) { |
197 bool updated = Layer::Update(queue, occlusion); | 201 bool updated = Layer::Update(queue, occlusion); |
198 if (client_) { | 202 if (client_) { |
199 if (uses_mailbox_) { | 203 if (uses_mailbox_) { |
200 TextureMailbox mailbox; | 204 TextureMailbox mailbox; |
| 205 ScopedReleaseCallback release_callback; |
201 if (client_->PrepareTextureMailbox( | 206 if (client_->PrepareTextureMailbox( |
202 &mailbox, layer_tree_host()->UsingSharedMemoryResources())) { | 207 &mailbox, |
203 SetTextureMailbox(mailbox); | 208 &release_callback, |
| 209 layer_tree_host()->UsingSharedMemoryResources())) { |
| 210 SetTextureMailbox(mailbox, release_callback.Pass()); |
204 updated = true; | 211 updated = true; |
205 } | 212 } |
206 } else { | 213 } else { |
207 texture_id_ = client_->PrepareTexture(); | 214 texture_id_ = client_->PrepareTexture(); |
208 DCHECK_EQ(!!texture_id_, !!client_->Context3d()); | 215 DCHECK_EQ(!!texture_id_, !!client_->Context3d()); |
209 if (client_->Context3d() && | 216 if (client_->Context3d() && |
210 client_->Context3d()->getGraphicsResetStatusARB() != GL_NO_ERROR) | 217 client_->Context3d()->getGraphicsResetStatusARB() != GL_NO_ERROR) |
211 texture_id_ = 0; | 218 texture_id_ = 0; |
212 updated = true; | 219 updated = true; |
213 // The texture id needs to be removed from the active tree before the | 220 // The texture id needs to be removed from the active tree before the |
(...skipping 13 matching lines...) Expand all Loading... |
227 | 234 |
228 TextureLayerImpl* texture_layer = static_cast<TextureLayerImpl*>(layer); | 235 TextureLayerImpl* texture_layer = static_cast<TextureLayerImpl*>(layer); |
229 texture_layer->set_flipped(flipped_); | 236 texture_layer->set_flipped(flipped_); |
230 texture_layer->set_uv_top_left(uv_top_left_); | 237 texture_layer->set_uv_top_left(uv_top_left_); |
231 texture_layer->set_uv_bottom_right(uv_bottom_right_); | 238 texture_layer->set_uv_bottom_right(uv_bottom_right_); |
232 texture_layer->set_vertex_opacity(vertex_opacity_); | 239 texture_layer->set_vertex_opacity(vertex_opacity_); |
233 texture_layer->set_premultiplied_alpha(premultiplied_alpha_); | 240 texture_layer->set_premultiplied_alpha(premultiplied_alpha_); |
234 texture_layer->set_blend_background_color(blend_background_color_); | 241 texture_layer->set_blend_background_color(blend_background_color_); |
235 if (uses_mailbox_ && needs_set_mailbox_) { | 242 if (uses_mailbox_ && needs_set_mailbox_) { |
236 TextureMailbox texture_mailbox; | 243 TextureMailbox texture_mailbox; |
| 244 ScopedReleaseCallback release_callback; |
237 if (holder_ref_) { | 245 if (holder_ref_) { |
238 MailboxHolder* holder = holder_ref_->holder(); | 246 MailboxHolder* holder = holder_ref_->holder(); |
239 TextureMailbox::ReleaseCallback callback = | 247 texture_mailbox = holder->mailbox(); |
240 holder->GetCallbackForImplThread(); | 248 release_callback = holder->GetCallbackForImplThread(); |
241 texture_mailbox = holder->mailbox().CopyWithNewCallback(callback); | |
242 } | 249 } |
243 texture_layer->SetTextureMailbox(texture_mailbox); | 250 texture_layer->SetTextureMailbox(texture_mailbox, release_callback.Pass()); |
244 needs_set_mailbox_ = false; | 251 needs_set_mailbox_ = false; |
245 } else { | 252 } else { |
246 texture_layer->set_texture_id(texture_id_); | 253 texture_layer->set_texture_id(texture_id_); |
247 } | 254 } |
248 content_committed_ = DrawsContent(); | 255 content_committed_ = DrawsContent(); |
249 } | 256 } |
250 | 257 |
251 Region TextureLayer::VisibleContentOpaqueRegion() const { | 258 Region TextureLayer::VisibleContentOpaqueRegion() const { |
252 if (contents_opaque()) | 259 if (contents_opaque()) |
253 return visible_content_rect(); | 260 return visible_content_rect(); |
(...skipping 11 matching lines...) Expand all Loading... |
265 TextureLayer::MailboxHolder::MainThreadReference::MainThreadReference( | 272 TextureLayer::MailboxHolder::MainThreadReference::MainThreadReference( |
266 MailboxHolder* holder) | 273 MailboxHolder* holder) |
267 : holder_(holder) { | 274 : holder_(holder) { |
268 holder_->InternalAddRef(); | 275 holder_->InternalAddRef(); |
269 } | 276 } |
270 | 277 |
271 TextureLayer::MailboxHolder::MainThreadReference::~MainThreadReference() { | 278 TextureLayer::MailboxHolder::MainThreadReference::~MainThreadReference() { |
272 holder_->InternalRelease(); | 279 holder_->InternalRelease(); |
273 } | 280 } |
274 | 281 |
275 TextureLayer::MailboxHolder::MailboxHolder(const TextureMailbox& mailbox) | 282 TextureLayer::MailboxHolder::MailboxHolder( |
| 283 const TextureMailbox& mailbox, ScopedReleaseCallback release_callback) |
276 : message_loop_(BlockingTaskRunner::current()), | 284 : message_loop_(BlockingTaskRunner::current()), |
277 internal_references_(0), | 285 internal_references_(0), |
278 mailbox_(mailbox), | 286 mailbox_(mailbox), |
| 287 release_callback_(release_callback.Pass()), |
279 sync_point_(mailbox.sync_point()), | 288 sync_point_(mailbox.sync_point()), |
280 is_lost_(false) { | 289 is_lost_(false) { |
281 } | 290 } |
282 | 291 |
283 TextureLayer::MailboxHolder::~MailboxHolder() { | 292 TextureLayer::MailboxHolder::~MailboxHolder() { |
284 DCHECK_EQ(0u, internal_references_); | 293 DCHECK_EQ(0u, internal_references_); |
285 } | 294 } |
286 | 295 |
287 scoped_ptr<TextureLayer::MailboxHolder::MainThreadReference> | 296 scoped_ptr<TextureLayer::MailboxHolder::MainThreadReference> |
288 TextureLayer::MailboxHolder::Create(const TextureMailbox& mailbox) { | 297 TextureLayer::MailboxHolder::Create(const TextureMailbox& mailbox, |
| 298 ScopedReleaseCallback release_callback) { |
289 return scoped_ptr<MainThreadReference>(new MainThreadReference( | 299 return scoped_ptr<MainThreadReference>(new MainThreadReference( |
290 new MailboxHolder(mailbox))); | 300 new MailboxHolder(mailbox, release_callback.Pass()))); |
291 } | 301 } |
292 | 302 |
293 void TextureLayer::MailboxHolder::Return(unsigned sync_point, bool is_lost) { | 303 void TextureLayer::MailboxHolder::Return(unsigned sync_point, bool is_lost) { |
294 base::AutoLock lock(arguments_lock_); | 304 base::AutoLock lock(arguments_lock_); |
295 sync_point_ = sync_point; | 305 sync_point_ = sync_point; |
296 is_lost_ = is_lost; | 306 is_lost_ = is_lost; |
297 } | 307 } |
298 | 308 |
299 TextureMailbox::ReleaseCallback | 309 ScopedReleaseCallback TextureLayer::MailboxHolder::GetCallbackForImplThread() { |
300 TextureLayer::MailboxHolder::GetCallbackForImplThread() { | |
301 // We can't call GetCallbackForImplThread if we released the main thread | 310 // We can't call GetCallbackForImplThread if we released the main thread |
302 // reference. | 311 // reference. |
303 DCHECK_GT(internal_references_, 0u); | 312 DCHECK_GT(internal_references_, 0u); |
304 InternalAddRef(); | 313 InternalAddRef(); |
305 return base::Bind(&MailboxHolder::ReturnAndReleaseOnImplThread, this); | 314 return ScopedReleaseCallback( |
| 315 base::Bind(&MailboxHolder::ReturnAndReleaseOnImplThread, this)); |
306 } | 316 } |
307 | 317 |
308 void TextureLayer::MailboxHolder::InternalAddRef() { | 318 void TextureLayer::MailboxHolder::InternalAddRef() { |
309 ++internal_references_; | 319 ++internal_references_; |
310 } | 320 } |
311 | 321 |
312 void TextureLayer::MailboxHolder::InternalRelease() { | 322 void TextureLayer::MailboxHolder::InternalRelease() { |
313 DCHECK(message_loop_->BelongsToCurrentThread()); | 323 DCHECK(message_loop_->BelongsToCurrentThread()); |
314 if (!--internal_references_) { | 324 if (!--internal_references_) { |
315 mailbox_.RunReleaseCallback(sync_point_, is_lost_); | 325 release_callback_.RunAndReset(sync_point_, is_lost_); |
316 DCHECK(mailbox_.callback().is_null()); | 326 mailbox_ = TextureMailbox(); |
317 } | 327 } |
318 } | 328 } |
319 | 329 |
320 void TextureLayer::MailboxHolder::ReturnAndReleaseOnImplThread( | 330 void TextureLayer::MailboxHolder::ReturnAndReleaseOnImplThread( |
321 unsigned sync_point, bool is_lost) { | 331 unsigned sync_point, bool is_lost) { |
322 Return(sync_point, is_lost); | 332 Return(sync_point, is_lost); |
323 message_loop_->PostTask(FROM_HERE, | 333 message_loop_->PostTask(FROM_HERE, |
324 base::Bind(&MailboxHolder::InternalRelease, this)); | 334 base::Bind(&MailboxHolder::InternalRelease, this)); |
325 } | 335 } |
326 | 336 |
327 } // namespace cc | 337 } // namespace cc |
OLD | NEW |