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