Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: cc/layers/texture_layer.cc

Issue 16888015: Reland r206537 - cc: Don't return mailboxes if the TextureLayer is removed from the tree. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Safer semantics Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « cc/layers/texture_layer.h ('k') | cc/layers/texture_layer_impl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
8 #include "base/location.h"
9 #include "base/message_loop/message_loop_proxy.h"
7 #include "cc/base/thread.h" 10 #include "cc/base/thread.h"
8 #include "cc/layers/texture_layer_client.h" 11 #include "cc/layers/texture_layer_client.h"
9 #include "cc/layers/texture_layer_impl.h" 12 #include "cc/layers/texture_layer_impl.h"
10 #include "cc/trees/layer_tree_host.h" 13 #include "cc/trees/layer_tree_host.h"
11 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" 14 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
12 15
13 namespace cc { 16 namespace cc {
14 17
15 namespace {
16
17 void RunCallback(
18 const TextureMailbox::ReleaseCallback& callback,
19 unsigned sync_point,
20 bool lost_resource) {
21 callback.Run(sync_point, lost_resource);
22 }
23
24 void PostCallbackToThread(
25 Thread* thread,
26 const TextureMailbox::ReleaseCallback& callback,
27 unsigned sync_point,
28 bool lost_resource) {
29 if (!callback.is_null()) {
30 thread->PostTask(base::Bind(&RunCallback, callback,
31 sync_point, lost_resource));
32 }
33 }
34
35 } // namespace
36
37 scoped_refptr<TextureLayer> TextureLayer::Create(TextureLayerClient* client) { 18 scoped_refptr<TextureLayer> TextureLayer::Create(TextureLayerClient* client) {
38 return scoped_refptr<TextureLayer>(new TextureLayer(client, false)); 19 return scoped_refptr<TextureLayer>(new TextureLayer(client, false));
39 } 20 }
40 21
41 scoped_refptr<TextureLayer> TextureLayer::CreateForMailbox( 22 scoped_refptr<TextureLayer> TextureLayer::CreateForMailbox(
42 TextureLayerClient* client) { 23 TextureLayerClient* client) {
43 return scoped_refptr<TextureLayer>(new TextureLayer(client, true)); 24 return scoped_refptr<TextureLayer>(new TextureLayer(client, true));
44 } 25 }
45 26
46 TextureLayer::TextureLayer(TextureLayerClient* client, bool uses_mailbox) 27 TextureLayer::TextureLayer(TextureLayerClient* client, bool uses_mailbox)
47 : Layer(), 28 : Layer(),
48 client_(client), 29 client_(client),
49 uses_mailbox_(uses_mailbox), 30 uses_mailbox_(uses_mailbox),
50 flipped_(true), 31 flipped_(true),
51 uv_top_left_(0.f, 0.f), 32 uv_top_left_(0.f, 0.f),
52 uv_bottom_right_(1.f, 1.f), 33 uv_bottom_right_(1.f, 1.f),
53 premultiplied_alpha_(true), 34 premultiplied_alpha_(true),
54 rate_limit_context_(false), 35 rate_limit_context_(false),
55 context_lost_(false), 36 context_lost_(false),
56 content_committed_(false), 37 content_committed_(false),
57 texture_id_(0), 38 texture_id_(0),
58 own_mailbox_(false) { 39 needs_set_mailbox_(false) {
59 vertex_opacity_[0] = 1.0f; 40 vertex_opacity_[0] = 1.0f;
60 vertex_opacity_[1] = 1.0f; 41 vertex_opacity_[1] = 1.0f;
61 vertex_opacity_[2] = 1.0f; 42 vertex_opacity_[2] = 1.0f;
62 vertex_opacity_[3] = 1.0f; 43 vertex_opacity_[3] = 1.0f;
63 } 44 }
64 45
65 TextureLayer::~TextureLayer() { 46 TextureLayer::~TextureLayer() {
66 if (layer_tree_host()) { 47 if (layer_tree_host()) {
67 if (texture_id_) 48 if (texture_id_)
68 layer_tree_host()->AcquireLayerTextures(); 49 layer_tree_host()->AcquireLayerTextures();
69 if (rate_limit_context_ && client_) 50 if (rate_limit_context_ && client_)
70 layer_tree_host()->StopRateLimiter(client_->Context3d()); 51 layer_tree_host()->StopRateLimiter(client_->Context3d());
71 } 52 }
72 if (own_mailbox_)
73 texture_mailbox_.RunReleaseCallback(texture_mailbox_.sync_point(), false);
74 } 53 }
75 54
76 void TextureLayer::ClearClient() { 55 void TextureLayer::ClearClient() {
77 client_ = NULL; 56 client_ = NULL;
78 if (uses_mailbox_) 57 if (uses_mailbox_)
79 SetTextureMailbox(TextureMailbox()); 58 SetTextureMailbox(TextureMailbox());
80 else 59 else
81 SetTextureId(0); 60 SetTextureId(0);
82 } 61 }
83 62
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 if (texture_id_ == id) 119 if (texture_id_ == id)
141 return; 120 return;
142 if (texture_id_ && layer_tree_host()) 121 if (texture_id_ && layer_tree_host())
143 layer_tree_host()->AcquireLayerTextures(); 122 layer_tree_host()->AcquireLayerTextures();
144 texture_id_ = id; 123 texture_id_ = id;
145 SetNeedsCommit(); 124 SetNeedsCommit();
146 } 125 }
147 126
148 void TextureLayer::SetTextureMailbox(const TextureMailbox& mailbox) { 127 void TextureLayer::SetTextureMailbox(const TextureMailbox& mailbox) {
149 DCHECK(uses_mailbox_); 128 DCHECK(uses_mailbox_);
150 if (own_mailbox_) 129 DCHECK(!mailbox.IsValid() || !holder_ref_ ||
151 DCHECK(!mailbox.IsValid() || !mailbox.Equals(texture_mailbox_)); 130 !mailbox.Equals(holder_ref_->holder()->mailbox()));
152 // If we never commited the mailbox, we need to release it here 131 // If we never commited the mailbox, we need to release it here.
153 if (own_mailbox_) 132 if (mailbox.IsValid())
154 texture_mailbox_.RunReleaseCallback(texture_mailbox_.sync_point(), false); 133 holder_ref_ = MailboxHolder::Create(mailbox);
155 texture_mailbox_ = mailbox; 134 else
156 own_mailbox_ = true; 135 holder_ref_.reset();
136 needs_set_mailbox_ = true;
157 SetNeedsCommit(); 137 SetNeedsCommit();
158 } 138 }
159 139
160 void TextureLayer::WillModifyTexture() { 140 void TextureLayer::WillModifyTexture() {
161 if (layer_tree_host() && (DrawsContent() || content_committed_)) { 141 if (layer_tree_host() && (DrawsContent() || content_committed_)) {
162 layer_tree_host()->AcquireLayerTextures(); 142 layer_tree_host()->AcquireLayerTextures();
163 content_committed_ = false; 143 content_committed_ = false;
164 } 144 }
165 } 145 }
166 146
167 void TextureLayer::SetNeedsDisplayRect(const gfx::RectF& dirty_rect) { 147 void TextureLayer::SetNeedsDisplayRect(const gfx::RectF& dirty_rect) {
168 Layer::SetNeedsDisplayRect(dirty_rect); 148 Layer::SetNeedsDisplayRect(dirty_rect);
169 149
170 if (rate_limit_context_ && client_ && layer_tree_host() && DrawsContent()) 150 if (rate_limit_context_ && client_ && layer_tree_host() && DrawsContent())
171 layer_tree_host()->StartRateLimiter(client_->Context3d()); 151 layer_tree_host()->StartRateLimiter(client_->Context3d());
172 } 152 }
173 153
174 void TextureLayer::SetLayerTreeHost(LayerTreeHost* host) { 154 void TextureLayer::SetLayerTreeHost(LayerTreeHost* host) {
175 if (texture_id_ && layer_tree_host() && host != layer_tree_host()) 155 if (texture_id_ && layer_tree_host() && host != layer_tree_host())
176 layer_tree_host()->AcquireLayerTextures(); 156 layer_tree_host()->AcquireLayerTextures();
157 // If we're removed from the tree, the TextureLayerImpl will be destroyed, and
158 // we will need to set the mailbox again on a new TextureLayerImpl the next
159 // time we push.
160 if (!host && uses_mailbox_ && holder_ref_.get())
danakj 2013/06/18 02:20:20 nit: don't need .get() for scoped_ptr
piman 2013/06/18 02:53:01 Done.
161 needs_set_mailbox_ = true;
177 Layer::SetLayerTreeHost(host); 162 Layer::SetLayerTreeHost(host);
178 } 163 }
179 164
180 bool TextureLayer::DrawsContent() const { 165 bool TextureLayer::DrawsContent() const {
181 return (client_ || texture_id_ || texture_mailbox_.IsValid()) && 166 return (client_ || texture_id_ || holder_ref_.get()) &&
danakj 2013/06/18 02:20:20 nit: don't need .get() for scoped_ptr
piman 2013/06/18 02:53:01 Done.
182 !context_lost_ && Layer::DrawsContent(); 167 !context_lost_ && Layer::DrawsContent();
183 } 168 }
184 169
185 void TextureLayer::Update(ResourceUpdateQueue* queue, 170 void TextureLayer::Update(ResourceUpdateQueue* queue,
186 const OcclusionTracker* occlusion, 171 const OcclusionTracker* occlusion,
187 RenderingStats* stats) { 172 RenderingStats* stats) {
188 if (client_) { 173 if (client_) {
189 if (uses_mailbox_) { 174 if (uses_mailbox_) {
190 TextureMailbox mailbox; 175 TextureMailbox mailbox;
191 if (client_->PrepareTextureMailbox(&mailbox)) { 176 if (client_->PrepareTextureMailbox(&mailbox)) {
(...skipping 14 matching lines...) Expand all
206 191
207 void TextureLayer::PushPropertiesTo(LayerImpl* layer) { 192 void TextureLayer::PushPropertiesTo(LayerImpl* layer) {
208 Layer::PushPropertiesTo(layer); 193 Layer::PushPropertiesTo(layer);
209 194
210 TextureLayerImpl* texture_layer = static_cast<TextureLayerImpl*>(layer); 195 TextureLayerImpl* texture_layer = static_cast<TextureLayerImpl*>(layer);
211 texture_layer->set_flipped(flipped_); 196 texture_layer->set_flipped(flipped_);
212 texture_layer->set_uv_top_left(uv_top_left_); 197 texture_layer->set_uv_top_left(uv_top_left_);
213 texture_layer->set_uv_bottom_right(uv_bottom_right_); 198 texture_layer->set_uv_bottom_right(uv_bottom_right_);
214 texture_layer->set_vertex_opacity(vertex_opacity_); 199 texture_layer->set_vertex_opacity(vertex_opacity_);
215 texture_layer->set_premultiplied_alpha(premultiplied_alpha_); 200 texture_layer->set_premultiplied_alpha(premultiplied_alpha_);
216 if (uses_mailbox_ && own_mailbox_) { 201 if (uses_mailbox_ && needs_set_mailbox_) {
217 Thread* main_thread = layer_tree_host()->proxy()->MainThread(); 202 TextureMailbox texture_mailbox;
218 TextureMailbox::ReleaseCallback callback = base::Bind( 203 if (holder_ref_) {
219 &PostCallbackToThread, main_thread, texture_mailbox_.callback()); 204 MailboxHolder* holder = holder_ref_->holder();
220 texture_layer->SetTextureMailbox( 205 TextureMailbox::ReleaseCallback callback =
221 texture_mailbox_.CopyWithNewCallback(callback)); 206 holder->GetCallbackForImplThread();
222 own_mailbox_ = false; 207 texture_mailbox = holder->mailbox().CopyWithNewCallback(callback);
208 }
209 texture_layer->SetTextureMailbox(texture_mailbox);
210 needs_set_mailbox_ = false;
223 } else { 211 } else {
224 texture_layer->set_texture_id(texture_id_); 212 texture_layer->set_texture_id(texture_id_);
225 } 213 }
226 content_committed_ = DrawsContent(); 214 content_committed_ = DrawsContent();
227 } 215 }
228 216
229 bool TextureLayer::BlocksPendingCommit() const { 217 bool TextureLayer::BlocksPendingCommit() const {
230 // Double-buffered texture layers need to be blocked until they can be made 218 // Double-buffered texture layers need to be blocked until they can be made
231 // triple-buffered. Single-buffered layers already prevent draws, so 219 // triple-buffered. Single-buffered layers already prevent draws, so
232 // can block too for simplicity. 220 // can block too for simplicity.
233 return DrawsContent(); 221 return DrawsContent();
234 } 222 }
235 223
236 bool TextureLayer::CanClipSelf() const { 224 bool TextureLayer::CanClipSelf() const {
237 return true; 225 return true;
238 } 226 }
239 227
228 TextureLayer::MailboxHolder::MainThreadReference::MainThreadReference(
229 MailboxHolder* holder)
230 : holder_(holder) {
231 }
232
233 TextureLayer::MailboxHolder::MainThreadReference::~MainThreadReference() {
234 holder_->InternalRelease();
235 }
236
237 TextureLayer::MailboxHolder::MailboxHolder(const TextureMailbox& mailbox)
238 : message_loop_(base::MessageLoopProxy::current()),
239 internal_references_(1),
danakj 2013/06/18 02:20:20 nit: start with 0 here, and have MainThreadRef con
piman 2013/06/18 02:53:01 Done.
240 mailbox_(mailbox),
241 sync_point_(mailbox.sync_point()),
242 is_lost_(false) {
243 }
244
245 TextureLayer::MailboxHolder::~MailboxHolder() {
246 DCHECK_EQ(0u, internal_references_);
247 }
248
249 scoped_ptr<TextureLayer::MailboxHolder::MainThreadReference>
250 TextureLayer::MailboxHolder::Create(const TextureMailbox& mailbox) {
251 return scoped_ptr<MainThreadReference>(new MainThreadReference(
252 new MailboxHolder(mailbox)));
253 }
254
255 void TextureLayer::MailboxHolder::Return(unsigned sync_point, bool is_lost) {
256 sync_point_ = sync_point;
257 is_lost_ = is_lost;
258 }
259
260 TextureMailbox::ReleaseCallback
261 TextureLayer::MailboxHolder::GetCallbackForImplThread() {
262 // We can't call GetCallbackForImplThread if we released the main thread
263 // reference.
264 DCHECK(internal_references_);
danakj 2013/06/18 02:20:20 nit: DCHECK_GT or DCHECK_NE 0?
piman 2013/06/18 02:53:01 Done.
265 InternalAddRef();
266 return base::Bind(&MailboxHolder::ReturnAndReleaseOnImplThread, this);
267 }
268
269 void TextureLayer::MailboxHolder::InternalAddRef() {
270 ++internal_references_;
271 }
272
273 void TextureLayer::MailboxHolder::InternalRelease() {
274 DCHECK(message_loop_->BelongsToCurrentThread());
275 if (!--internal_references_) {
276 mailbox_.RunReleaseCallback(sync_point_, is_lost_);
277 mailbox_ = TextureMailbox();
278 }
279 }
280
281 void TextureLayer::MailboxHolder::ReturnAndReleaseOnMainThread(
282 unsigned sync_point, bool is_lost) {
283 DCHECK(message_loop_->BelongsToCurrentThread());
284 Return(sync_point, is_lost);
285 InternalRelease();
286 }
287
288 void TextureLayer::MailboxHolder::ReturnAndReleaseOnImplThread(
289 unsigned sync_point, bool is_lost) {
290 message_loop_->PostTask(FROM_HERE, base::Bind(
291 &MailboxHolder::ReturnAndReleaseOnMainThread,
292 this, sync_point, is_lost));
293 }
294
240 } // namespace cc 295 } // namespace cc
OLDNEW
« no previous file with comments | « cc/layers/texture_layer.h ('k') | cc/layers/texture_layer_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698