| 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/callback_helpers.h" |
| 9 #include "base/location.h" | 9 #include "base/location.h" |
| 10 #include "base/synchronization/lock.h" | 10 #include "base/synchronization/lock.h" |
| 11 #include "cc/layers/texture_layer_client.h" | 11 #include "cc/layers/texture_layer_client.h" |
| 12 #include "cc/layers/texture_layer_impl.h" | 12 #include "cc/layers/texture_layer_impl.h" |
| 13 #include "cc/resources/single_release_callback.h" | 13 #include "cc/resources/single_release_callback.h" |
| 14 #include "cc/trees/blocking_task_runner.h" | 14 #include "cc/trees/blocking_task_runner.h" |
| 15 #include "cc/trees/layer_tree_host.h" | 15 #include "cc/trees/layer_tree_host.h" |
| 16 | 16 |
| 17 namespace cc { | 17 namespace cc { |
| 18 | 18 |
| 19 scoped_refptr<TextureLayer> TextureLayer::Create(TextureLayerClient* client) { | 19 scoped_refptr<TextureLayer> TextureLayer::CreateForMailbox( |
| 20 return scoped_refptr<TextureLayer>(new TextureLayer(client, false)); | 20 TextureLayerClient* client) { |
| 21 return scoped_refptr<TextureLayer>(new TextureLayer(client)); |
| 21 } | 22 } |
| 22 | 23 |
| 23 scoped_refptr<TextureLayer> TextureLayer::CreateForMailbox( | 24 TextureLayer::TextureLayer(TextureLayerClient* client) |
| 24 TextureLayerClient* client) { | |
| 25 return scoped_refptr<TextureLayer>(new TextureLayer(client, true)); | |
| 26 } | |
| 27 | |
| 28 TextureLayer::TextureLayer(TextureLayerClient* client, bool uses_mailbox) | |
| 29 : Layer(), | 25 : Layer(), |
| 30 client_(client), | 26 client_(client), |
| 31 uses_mailbox_(uses_mailbox), | |
| 32 flipped_(true), | 27 flipped_(true), |
| 33 uv_top_left_(0.f, 0.f), | 28 uv_top_left_(0.f, 0.f), |
| 34 uv_bottom_right_(1.f, 1.f), | 29 uv_bottom_right_(1.f, 1.f), |
| 35 premultiplied_alpha_(true), | 30 premultiplied_alpha_(true), |
| 36 blend_background_color_(false), | 31 blend_background_color_(false), |
| 37 rate_limit_context_(false), | 32 rate_limit_context_(false), |
| 38 impl_may_draw_client_data_(false), | |
| 39 texture_id_(0), | |
| 40 needs_set_mailbox_(false) { | 33 needs_set_mailbox_(false) { |
| 41 vertex_opacity_[0] = 1.0f; | 34 vertex_opacity_[0] = 1.0f; |
| 42 vertex_opacity_[1] = 1.0f; | 35 vertex_opacity_[1] = 1.0f; |
| 43 vertex_opacity_[2] = 1.0f; | 36 vertex_opacity_[2] = 1.0f; |
| 44 vertex_opacity_[3] = 1.0f; | 37 vertex_opacity_[3] = 1.0f; |
| 45 } | 38 } |
| 46 | 39 |
| 47 TextureLayer::~TextureLayer() { | 40 TextureLayer::~TextureLayer() { |
| 48 } | 41 } |
| 49 | 42 |
| 50 void TextureLayer::ClearClient() { | 43 void TextureLayer::ClearClient() { |
| 51 if (rate_limit_context_ && client_ && layer_tree_host()) | 44 if (rate_limit_context_ && client_ && layer_tree_host()) |
| 52 layer_tree_host()->StopRateLimiter(); | 45 layer_tree_host()->StopRateLimiter(); |
| 53 client_ = NULL; | 46 client_ = NULL; |
| 54 ClearTexture(); | 47 ClearTexture(); |
| 55 } | 48 } |
| 56 | 49 |
| 57 void TextureLayer::ClearTexture() { | 50 void TextureLayer::ClearTexture() { |
| 58 if (uses_mailbox_) { | 51 SetTextureMailbox(TextureMailbox(), scoped_ptr<SingleReleaseCallback>()); |
| 59 SetTextureMailbox(TextureMailbox(), scoped_ptr<SingleReleaseCallback>()); | |
| 60 } else if (texture_id_) { | |
| 61 if (impl_may_draw_client_data_) { | |
| 62 DCHECK(layer_tree_host()); | |
| 63 layer_tree_host()->AcquireLayerTextures(); | |
| 64 impl_may_draw_client_data_ = false; | |
| 65 } | |
| 66 texture_id_ = 0; | |
| 67 SetNeedsCommit(); | |
| 68 // The texture id needs to be removed from the active tree before the | |
| 69 // commit is called complete. | |
| 70 SetNextCommitWaitsForActivation(); | |
| 71 } | |
| 72 } | 52 } |
| 73 | 53 |
| 74 scoped_ptr<LayerImpl> TextureLayer::CreateLayerImpl(LayerTreeImpl* tree_impl) { | 54 scoped_ptr<LayerImpl> TextureLayer::CreateLayerImpl(LayerTreeImpl* tree_impl) { |
| 75 return TextureLayerImpl::Create(tree_impl, id(), uses_mailbox_). | 55 return TextureLayerImpl::Create(tree_impl, id()).PassAs<LayerImpl>(); |
| 76 PassAs<LayerImpl>(); | |
| 77 } | 56 } |
| 78 | 57 |
| 79 void TextureLayer::SetFlipped(bool flipped) { | 58 void TextureLayer::SetFlipped(bool flipped) { |
| 80 if (flipped_ == flipped) | 59 if (flipped_ == flipped) |
| 81 return; | 60 return; |
| 82 flipped_ = flipped; | 61 flipped_ = flipped; |
| 83 SetNeedsCommit(); | 62 SetNeedsCommit(); |
| 84 } | 63 } |
| 85 | 64 |
| 86 void TextureLayer::SetUV(const gfx::PointF& top_left, | 65 void TextureLayer::SetUV(const gfx::PointF& top_left, |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 layer_tree_host()->StopRateLimiter(); | 110 layer_tree_host()->StopRateLimiter(); |
| 132 | 111 |
| 133 rate_limit_context_ = rate_limit; | 112 rate_limit_context_ = rate_limit; |
| 134 } | 113 } |
| 135 | 114 |
| 136 void TextureLayer::SetTextureMailboxInternal( | 115 void TextureLayer::SetTextureMailboxInternal( |
| 137 const TextureMailbox& mailbox, | 116 const TextureMailbox& mailbox, |
| 138 scoped_ptr<SingleReleaseCallback> release_callback, | 117 scoped_ptr<SingleReleaseCallback> release_callback, |
| 139 bool requires_commit, | 118 bool requires_commit, |
| 140 bool allow_mailbox_reuse) { | 119 bool allow_mailbox_reuse) { |
| 141 DCHECK(uses_mailbox_); | |
| 142 DCHECK(!mailbox.IsValid() || !holder_ref_ || | 120 DCHECK(!mailbox.IsValid() || !holder_ref_ || |
| 143 !mailbox.Equals(holder_ref_->holder()->mailbox()) || | 121 !mailbox.Equals(holder_ref_->holder()->mailbox()) || |
| 144 allow_mailbox_reuse); | 122 allow_mailbox_reuse); |
| 145 DCHECK_EQ(mailbox.IsValid(), !!release_callback); | 123 DCHECK_EQ(mailbox.IsValid(), !!release_callback); |
| 146 | 124 |
| 147 // If we never commited the mailbox, we need to release it here. | 125 // If we never commited the mailbox, we need to release it here. |
| 148 if (mailbox.IsValid()) { | 126 if (mailbox.IsValid()) { |
| 149 holder_ref_ = | 127 holder_ref_ = |
| 150 TextureMailboxHolder::Create(mailbox, release_callback.Pass()); | 128 TextureMailboxHolder::Create(mailbox, release_callback.Pass()); |
| 151 } else { | 129 } else { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 layer_tree_host()->StartRateLimiter(); | 176 layer_tree_host()->StartRateLimiter(); |
| 199 } | 177 } |
| 200 | 178 |
| 201 void TextureLayer::SetLayerTreeHost(LayerTreeHost* host) { | 179 void TextureLayer::SetLayerTreeHost(LayerTreeHost* host) { |
| 202 if (layer_tree_host() == host) { | 180 if (layer_tree_host() == host) { |
| 203 Layer::SetLayerTreeHost(host); | 181 Layer::SetLayerTreeHost(host); |
| 204 return; | 182 return; |
| 205 } | 183 } |
| 206 | 184 |
| 207 if (layer_tree_host()) { | 185 if (layer_tree_host()) { |
| 208 if (impl_may_draw_client_data_) { | |
| 209 layer_tree_host()->AcquireLayerTextures(); | |
| 210 // The texture id needs to be removed from the active tree before the | |
| 211 // commit is called complete. | |
| 212 SetNextCommitWaitsForActivation(); | |
| 213 impl_may_draw_client_data_ = false; | |
| 214 } | |
| 215 if (rate_limit_context_ && client_) | 186 if (rate_limit_context_ && client_) |
| 216 layer_tree_host()->StopRateLimiter(); | 187 layer_tree_host()->StopRateLimiter(); |
| 217 } | 188 } |
| 218 // If we're removed from the tree, the TextureLayerImpl will be destroyed, and | 189 // If we're removed from the tree, the TextureLayerImpl will be destroyed, and |
| 219 // we will need to set the mailbox again on a new TextureLayerImpl the next | 190 // we will need to set the mailbox again on a new TextureLayerImpl the next |
| 220 // time we push. | 191 // time we push. |
| 221 if (!host && uses_mailbox_ && holder_ref_) { | 192 if (!host && holder_ref_) { |
| 222 needs_set_mailbox_ = true; | 193 needs_set_mailbox_ = true; |
| 223 // The active frame needs to be replaced and the mailbox returned before the | 194 // The active frame needs to be replaced and the mailbox returned before the |
| 224 // commit is called complete. | 195 // commit is called complete. |
| 225 SetNextCommitWaitsForActivation(); | 196 SetNextCommitWaitsForActivation(); |
| 226 } | 197 } |
| 227 Layer::SetLayerTreeHost(host); | 198 Layer::SetLayerTreeHost(host); |
| 228 } | 199 } |
| 229 | 200 |
| 230 bool TextureLayer::DrawsContent() const { | 201 bool TextureLayer::DrawsContent() const { |
| 231 return (client_ || texture_id_ || holder_ref_) && Layer::DrawsContent(); | 202 return (client_ || holder_ref_) && Layer::DrawsContent(); |
| 232 } | 203 } |
| 233 | 204 |
| 234 bool TextureLayer::Update(ResourceUpdateQueue* queue, | 205 bool TextureLayer::Update(ResourceUpdateQueue* queue, |
| 235 const OcclusionTracker<Layer>* occlusion) { | 206 const OcclusionTracker<Layer>* occlusion) { |
| 236 bool updated = Layer::Update(queue, occlusion); | 207 bool updated = Layer::Update(queue, occlusion); |
| 237 if (client_) { | 208 if (client_) { |
| 238 if (uses_mailbox_) { | 209 TextureMailbox mailbox; |
| 239 TextureMailbox mailbox; | 210 scoped_ptr<SingleReleaseCallback> release_callback; |
| 240 scoped_ptr<SingleReleaseCallback> release_callback; | 211 if (client_->PrepareTextureMailbox( |
| 241 if (client_->PrepareTextureMailbox( | 212 &mailbox, |
| 242 &mailbox, | 213 &release_callback, |
| 243 &release_callback, | 214 layer_tree_host()->UsingSharedMemoryResources())) { |
| 244 layer_tree_host()->UsingSharedMemoryResources())) { | 215 // Already within a commit, no need to do another one immediately. |
| 245 // Already within a commit, no need to do another one immediately. | 216 bool requires_commit = false; |
| 246 bool requires_commit = false; | 217 bool allow_mailbox_reuse = false; |
| 247 bool allow_mailbox_reuse = false; | 218 SetTextureMailboxInternal(mailbox, |
| 248 SetTextureMailboxInternal(mailbox, | 219 release_callback.Pass(), |
| 249 release_callback.Pass(), | 220 requires_commit, |
| 250 requires_commit, | 221 allow_mailbox_reuse); |
| 251 allow_mailbox_reuse); | |
| 252 updated = true; | |
| 253 } | |
| 254 } else { | |
| 255 texture_id_ = client_->PrepareTexture(); | |
| 256 updated = true; | 222 updated = true; |
| 257 SetNeedsPushProperties(); | |
| 258 // The texture id needs to be removed from the active tree before the | |
| 259 // commit is called complete. | |
| 260 SetNextCommitWaitsForActivation(); | |
| 261 } | 223 } |
| 262 } | 224 } |
| 263 | 225 |
| 264 // SetTextureMailbox could be called externally and the same mailbox used for | 226 // SetTextureMailbox could be called externally and the same mailbox used for |
| 265 // different textures. Such callers notify this layer that the texture has | 227 // different textures. Such callers notify this layer that the texture has |
| 266 // changed by calling SetNeedsDisplay, so check for that here. | 228 // changed by calling SetNeedsDisplay, so check for that here. |
| 267 return updated || !update_rect_.IsEmpty(); | 229 return updated || !update_rect_.IsEmpty(); |
| 268 } | 230 } |
| 269 | 231 |
| 270 void TextureLayer::PushPropertiesTo(LayerImpl* layer) { | 232 void TextureLayer::PushPropertiesTo(LayerImpl* layer) { |
| 271 Layer::PushPropertiesTo(layer); | 233 Layer::PushPropertiesTo(layer); |
| 272 | 234 |
| 273 TextureLayerImpl* texture_layer = static_cast<TextureLayerImpl*>(layer); | 235 TextureLayerImpl* texture_layer = static_cast<TextureLayerImpl*>(layer); |
| 274 texture_layer->SetFlipped(flipped_); | 236 texture_layer->SetFlipped(flipped_); |
| 275 texture_layer->SetUVTopLeft(uv_top_left_); | 237 texture_layer->SetUVTopLeft(uv_top_left_); |
| 276 texture_layer->SetUVBottomRight(uv_bottom_right_); | 238 texture_layer->SetUVBottomRight(uv_bottom_right_); |
| 277 texture_layer->SetVertexOpacity(vertex_opacity_); | 239 texture_layer->SetVertexOpacity(vertex_opacity_); |
| 278 texture_layer->SetPremultipliedAlpha(premultiplied_alpha_); | 240 texture_layer->SetPremultipliedAlpha(premultiplied_alpha_); |
| 279 texture_layer->SetBlendBackgroundColor(blend_background_color_); | 241 texture_layer->SetBlendBackgroundColor(blend_background_color_); |
| 280 if (uses_mailbox_ && needs_set_mailbox_) { | 242 if (needs_set_mailbox_) { |
| 281 TextureMailbox texture_mailbox; | 243 TextureMailbox texture_mailbox; |
| 282 scoped_ptr<SingleReleaseCallback> release_callback; | 244 scoped_ptr<SingleReleaseCallback> release_callback; |
| 283 if (holder_ref_) { | 245 if (holder_ref_) { |
| 284 TextureMailboxHolder* holder = holder_ref_->holder(); | 246 TextureMailboxHolder* holder = holder_ref_->holder(); |
| 285 texture_mailbox = holder->mailbox(); | 247 texture_mailbox = holder->mailbox(); |
| 286 release_callback = holder->GetCallbackForImplThread(); | 248 release_callback = holder->GetCallbackForImplThread(); |
| 287 } | 249 } |
| 288 texture_layer->SetTextureMailbox(texture_mailbox, release_callback.Pass()); | 250 texture_layer->SetTextureMailbox(texture_mailbox, release_callback.Pass()); |
| 289 needs_set_mailbox_ = false; | 251 needs_set_mailbox_ = false; |
| 290 } else { | |
| 291 texture_layer->SetTextureId(texture_id_); | |
| 292 impl_may_draw_client_data_ = texture_id_ && Layer::DrawsContent(); | |
| 293 } | 252 } |
| 294 } | 253 } |
| 295 | 254 |
| 296 Region TextureLayer::VisibleContentOpaqueRegion() const { | 255 Region TextureLayer::VisibleContentOpaqueRegion() const { |
| 297 if (contents_opaque()) | 256 if (contents_opaque()) |
| 298 return visible_content_rect(); | 257 return visible_content_rect(); |
| 299 | 258 |
| 300 if (blend_background_color_ && (SkColorGetA(background_color()) == 0xFF)) | 259 if (blend_background_color_ && (SkColorGetA(background_color()) == 0xFF)) |
| 301 return visible_content_rect(); | 260 return visible_content_rect(); |
| 302 | 261 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 | 327 |
| 369 void TextureLayer::TextureMailboxHolder::ReturnAndReleaseOnImplThread( | 328 void TextureLayer::TextureMailboxHolder::ReturnAndReleaseOnImplThread( |
| 370 uint32 sync_point, | 329 uint32 sync_point, |
| 371 bool is_lost) { | 330 bool is_lost) { |
| 372 Return(sync_point, is_lost); | 331 Return(sync_point, is_lost); |
| 373 message_loop_->PostTask( | 332 message_loop_->PostTask( |
| 374 FROM_HERE, base::Bind(&TextureMailboxHolder::InternalRelease, this)); | 333 FROM_HERE, base::Bind(&TextureMailboxHolder::InternalRelease, this)); |
| 375 } | 334 } |
| 376 | 335 |
| 377 } // namespace cc | 336 } // namespace cc |
| OLD | NEW |