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 SetNeedsPushProperties(); | 222 SetNeedsPushProperties(); |
(...skipping 14 matching lines...) Expand all Loading... |
228 | 237 |
229 TextureLayerImpl* texture_layer = static_cast<TextureLayerImpl*>(layer); | 238 TextureLayerImpl* texture_layer = static_cast<TextureLayerImpl*>(layer); |
230 texture_layer->set_flipped(flipped_); | 239 texture_layer->set_flipped(flipped_); |
231 texture_layer->set_uv_top_left(uv_top_left_); | 240 texture_layer->set_uv_top_left(uv_top_left_); |
232 texture_layer->set_uv_bottom_right(uv_bottom_right_); | 241 texture_layer->set_uv_bottom_right(uv_bottom_right_); |
233 texture_layer->set_vertex_opacity(vertex_opacity_); | 242 texture_layer->set_vertex_opacity(vertex_opacity_); |
234 texture_layer->set_premultiplied_alpha(premultiplied_alpha_); | 243 texture_layer->set_premultiplied_alpha(premultiplied_alpha_); |
235 texture_layer->set_blend_background_color(blend_background_color_); | 244 texture_layer->set_blend_background_color(blend_background_color_); |
236 if (uses_mailbox_ && needs_set_mailbox_) { | 245 if (uses_mailbox_ && needs_set_mailbox_) { |
237 TextureMailbox texture_mailbox; | 246 TextureMailbox texture_mailbox; |
| 247 scoped_ptr<ScopedReleaseCallback> release_callback; |
238 if (holder_ref_) { | 248 if (holder_ref_) { |
239 MailboxHolder* holder = holder_ref_->holder(); | 249 MailboxHolder* holder = holder_ref_->holder(); |
240 TextureMailbox::ReleaseCallback callback = | 250 texture_mailbox = holder->mailbox(); |
241 holder->GetCallbackForImplThread(); | 251 release_callback = holder->GetCallbackForImplThread(); |
242 texture_mailbox = holder->mailbox().CopyWithNewCallback(callback); | |
243 } | 252 } |
244 texture_layer->SetTextureMailbox(texture_mailbox); | 253 texture_layer->SetTextureMailbox(texture_mailbox, release_callback.Pass()); |
245 needs_set_mailbox_ = false; | 254 needs_set_mailbox_ = false; |
246 } else { | 255 } else { |
247 texture_layer->set_texture_id(texture_id_); | 256 texture_layer->set_texture_id(texture_id_); |
248 } | 257 } |
249 content_committed_ = DrawsContent(); | 258 content_committed_ = DrawsContent(); |
250 } | 259 } |
251 | 260 |
252 Region TextureLayer::VisibleContentOpaqueRegion() const { | 261 Region TextureLayer::VisibleContentOpaqueRegion() const { |
253 if (contents_opaque()) | 262 if (contents_opaque()) |
254 return visible_content_rect(); | 263 return visible_content_rect(); |
(...skipping 11 matching lines...) Expand all Loading... |
266 TextureLayer::MailboxHolder::MainThreadReference::MainThreadReference( | 275 TextureLayer::MailboxHolder::MainThreadReference::MainThreadReference( |
267 MailboxHolder* holder) | 276 MailboxHolder* holder) |
268 : holder_(holder) { | 277 : holder_(holder) { |
269 holder_->InternalAddRef(); | 278 holder_->InternalAddRef(); |
270 } | 279 } |
271 | 280 |
272 TextureLayer::MailboxHolder::MainThreadReference::~MainThreadReference() { | 281 TextureLayer::MailboxHolder::MainThreadReference::~MainThreadReference() { |
273 holder_->InternalRelease(); | 282 holder_->InternalRelease(); |
274 } | 283 } |
275 | 284 |
276 TextureLayer::MailboxHolder::MailboxHolder(const TextureMailbox& mailbox) | 285 TextureLayer::MailboxHolder::MailboxHolder( |
| 286 const TextureMailbox& mailbox, |
| 287 scoped_ptr<ScopedReleaseCallback> release_callback) |
277 : message_loop_(BlockingTaskRunner::current()), | 288 : message_loop_(BlockingTaskRunner::current()), |
278 internal_references_(0), | 289 internal_references_(0), |
279 mailbox_(mailbox), | 290 mailbox_(mailbox), |
| 291 release_callback_(release_callback.Pass()), |
280 sync_point_(mailbox.sync_point()), | 292 sync_point_(mailbox.sync_point()), |
281 is_lost_(false) { | 293 is_lost_(false) { |
282 } | 294 } |
283 | 295 |
284 TextureLayer::MailboxHolder::~MailboxHolder() { | 296 TextureLayer::MailboxHolder::~MailboxHolder() { |
285 DCHECK_EQ(0u, internal_references_); | 297 DCHECK_EQ(0u, internal_references_); |
286 } | 298 } |
287 | 299 |
288 scoped_ptr<TextureLayer::MailboxHolder::MainThreadReference> | 300 scoped_ptr<TextureLayer::MailboxHolder::MainThreadReference> |
289 TextureLayer::MailboxHolder::Create(const TextureMailbox& mailbox) { | 301 TextureLayer::MailboxHolder::Create( |
| 302 const TextureMailbox& mailbox, |
| 303 scoped_ptr<ScopedReleaseCallback> release_callback) { |
290 return scoped_ptr<MainThreadReference>(new MainThreadReference( | 304 return scoped_ptr<MainThreadReference>(new MainThreadReference( |
291 new MailboxHolder(mailbox))); | 305 new MailboxHolder(mailbox, release_callback.Pass()))); |
292 } | 306 } |
293 | 307 |
294 void TextureLayer::MailboxHolder::Return(unsigned sync_point, bool is_lost) { | 308 void TextureLayer::MailboxHolder::Return(unsigned sync_point, bool is_lost) { |
295 base::AutoLock lock(arguments_lock_); | 309 base::AutoLock lock(arguments_lock_); |
296 sync_point_ = sync_point; | 310 sync_point_ = sync_point; |
297 is_lost_ = is_lost; | 311 is_lost_ = is_lost; |
298 } | 312 } |
299 | 313 |
300 TextureMailbox::ReleaseCallback | 314 scoped_ptr<ScopedReleaseCallback> |
301 TextureLayer::MailboxHolder::GetCallbackForImplThread() { | 315 TextureLayer::MailboxHolder::GetCallbackForImplThread() { |
302 // We can't call GetCallbackForImplThread if we released the main thread | 316 // We can't call GetCallbackForImplThread if we released the main thread |
303 // reference. | 317 // reference. |
304 DCHECK_GT(internal_references_, 0u); | 318 DCHECK_GT(internal_references_, 0u); |
305 InternalAddRef(); | 319 InternalAddRef(); |
306 return base::Bind(&MailboxHolder::ReturnAndReleaseOnImplThread, this); | 320 return ScopedReleaseCallback::Create( |
| 321 base::Bind(&MailboxHolder::ReturnAndReleaseOnImplThread, this)); |
307 } | 322 } |
308 | 323 |
309 void TextureLayer::MailboxHolder::InternalAddRef() { | 324 void TextureLayer::MailboxHolder::InternalAddRef() { |
310 ++internal_references_; | 325 ++internal_references_; |
311 } | 326 } |
312 | 327 |
313 void TextureLayer::MailboxHolder::InternalRelease() { | 328 void TextureLayer::MailboxHolder::InternalRelease() { |
314 DCHECK(message_loop_->BelongsToCurrentThread()); | 329 DCHECK(message_loop_->BelongsToCurrentThread()); |
315 if (!--internal_references_) { | 330 if (!--internal_references_) { |
316 mailbox_.RunReleaseCallback(sync_point_, is_lost_); | 331 release_callback_->Run(sync_point_, is_lost_); |
317 DCHECK(mailbox_.callback().is_null()); | 332 mailbox_ = TextureMailbox(); |
| 333 release_callback_.reset(); |
318 } | 334 } |
319 } | 335 } |
320 | 336 |
321 void TextureLayer::MailboxHolder::ReturnAndReleaseOnImplThread( | 337 void TextureLayer::MailboxHolder::ReturnAndReleaseOnImplThread( |
322 unsigned sync_point, bool is_lost) { | 338 unsigned sync_point, bool is_lost) { |
323 Return(sync_point, is_lost); | 339 Return(sync_point, is_lost); |
324 message_loop_->PostTask(FROM_HERE, | 340 message_loop_->PostTask(FROM_HERE, |
325 base::Bind(&MailboxHolder::InternalRelease, this)); | 341 base::Bind(&MailboxHolder::InternalRelease, this)); |
326 } | 342 } |
327 | 343 |
328 } // namespace cc | 344 } // namespace cc |
OLD | NEW |