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(); |
| 146 |
142 needs_set_mailbox_ = true; | 147 needs_set_mailbox_ = true; |
| 148 |
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() { |
150 if (layer_tree_host() && (DrawsContent() || content_committed_)) { | 156 if (layer_tree_host() && (DrawsContent() || content_committed_)) { |
151 layer_tree_host()->AcquireLayerTextures(); | 157 layer_tree_host()->AcquireLayerTextures(); |
152 content_committed_ = false; | 158 content_committed_ = false; |
(...skipping 38 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 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 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, ScopedReleaseCallback release_callback) |
276 : message_loop_(BlockingTaskRunner::current()), | 286 : message_loop_(BlockingTaskRunner::current()), |
277 internal_references_(0), | 287 internal_references_(0), |
278 mailbox_(mailbox), | 288 mailbox_(mailbox), |
| 289 release_callback_(release_callback.Pass()), |
279 sync_point_(mailbox.sync_point()), | 290 sync_point_(mailbox.sync_point()), |
280 is_lost_(false) { | 291 is_lost_(false) { |
281 } | 292 } |
282 | 293 |
283 TextureLayer::MailboxHolder::~MailboxHolder() { | 294 TextureLayer::MailboxHolder::~MailboxHolder() { |
284 DCHECK_EQ(0u, internal_references_); | 295 DCHECK_EQ(0u, internal_references_); |
285 } | 296 } |
286 | 297 |
287 scoped_ptr<TextureLayer::MailboxHolder::MainThreadReference> | 298 scoped_ptr<TextureLayer::MailboxHolder::MainThreadReference> |
288 TextureLayer::MailboxHolder::Create(const TextureMailbox& mailbox) { | 299 TextureLayer::MailboxHolder::Create(const TextureMailbox& mailbox, |
| 300 ScopedReleaseCallback release_callback) { |
289 return scoped_ptr<MainThreadReference>(new MainThreadReference( | 301 return scoped_ptr<MainThreadReference>(new MainThreadReference( |
290 new MailboxHolder(mailbox))); | 302 new MailboxHolder(mailbox, release_callback.Pass()))); |
291 } | 303 } |
292 | 304 |
293 void TextureLayer::MailboxHolder::Return(unsigned sync_point, bool is_lost) { | 305 void TextureLayer::MailboxHolder::Return(unsigned sync_point, bool is_lost) { |
294 base::AutoLock lock(arguments_lock_); | 306 base::AutoLock lock(arguments_lock_); |
295 sync_point_ = sync_point; | 307 sync_point_ = sync_point; |
296 is_lost_ = is_lost; | 308 is_lost_ = is_lost; |
297 } | 309 } |
298 | 310 |
299 TextureMailbox::ReleaseCallback | 311 ScopedReleaseCallback TextureLayer::MailboxHolder::GetCallbackForImplThread() { |
300 TextureLayer::MailboxHolder::GetCallbackForImplThread() { | |
301 // We can't call GetCallbackForImplThread if we released the main thread | 312 // We can't call GetCallbackForImplThread if we released the main thread |
302 // reference. | 313 // reference. |
303 DCHECK_GT(internal_references_, 0u); | 314 DCHECK_GT(internal_references_, 0u); |
304 InternalAddRef(); | 315 InternalAddRef(); |
305 return base::Bind(&MailboxHolder::ReturnAndReleaseOnImplThread, this); | 316 return ScopedReleaseCallback( |
| 317 base::Bind(&MailboxHolder::ReturnAndReleaseOnImplThread, this)); |
306 } | 318 } |
307 | 319 |
308 void TextureLayer::MailboxHolder::InternalAddRef() { | 320 void TextureLayer::MailboxHolder::InternalAddRef() { |
309 ++internal_references_; | 321 ++internal_references_; |
310 } | 322 } |
311 | 323 |
312 void TextureLayer::MailboxHolder::InternalRelease() { | 324 void TextureLayer::MailboxHolder::InternalRelease() { |
313 DCHECK(message_loop_->BelongsToCurrentThread()); | 325 DCHECK(message_loop_->BelongsToCurrentThread()); |
314 if (!--internal_references_) { | 326 if (!--internal_references_) { |
315 mailbox_.RunReleaseCallback(sync_point_, is_lost_); | 327 release_callback_.RunAndReset(sync_point_, is_lost_); |
316 DCHECK(mailbox_.callback().is_null()); | |
317 } | 328 } |
318 } | 329 } |
319 | 330 |
320 void TextureLayer::MailboxHolder::ReturnAndReleaseOnImplThread( | 331 void TextureLayer::MailboxHolder::ReturnAndReleaseOnImplThread( |
321 unsigned sync_point, bool is_lost) { | 332 unsigned sync_point, bool is_lost) { |
322 Return(sync_point, is_lost); | 333 Return(sync_point, is_lost); |
323 message_loop_->PostTask(FROM_HERE, | 334 message_loop_->PostTask(FROM_HERE, |
324 base::Bind(&MailboxHolder::InternalRelease, this)); | 335 base::Bind(&MailboxHolder::InternalRelease, this)); |
325 } | 336 } |
326 | 337 |
327 } // namespace cc | 338 } // namespace cc |
OLD | NEW |