Use Default PasswordStore with Ozone.
[chromium-blink-merge.git] / cc / layers / texture_layer.cc
blob195d05ddaba5721f1407a99a24912c69fecab392
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
3 // found in the LICENSE file.
5 #include "cc/layers/texture_layer.h"
7 #include "base/bind.h"
8 #include "base/callback_helpers.h"
9 #include "base/location.h"
10 #include "base/synchronization/lock.h"
11 #include "cc/layers/texture_layer_client.h"
12 #include "cc/layers/texture_layer_impl.h"
13 #include "cc/resources/single_release_callback.h"
14 #include "cc/trees/blocking_task_runner.h"
15 #include "cc/trees/layer_tree_host.h"
17 namespace cc {
19 scoped_refptr<TextureLayer> TextureLayer::Create(TextureLayerClient* client) {
20 return scoped_refptr<TextureLayer>(new TextureLayer(client, false));
23 scoped_refptr<TextureLayer> TextureLayer::CreateForMailbox(
24 TextureLayerClient* client) {
25 return scoped_refptr<TextureLayer>(new TextureLayer(client, true));
28 TextureLayer::TextureLayer(TextureLayerClient* client, bool uses_mailbox)
29 : Layer(),
30 client_(client),
31 uses_mailbox_(uses_mailbox),
32 flipped_(true),
33 uv_top_left_(0.f, 0.f),
34 uv_bottom_right_(1.f, 1.f),
35 premultiplied_alpha_(true),
36 blend_background_color_(false),
37 rate_limit_context_(false),
38 content_committed_(false),
39 texture_id_(0),
40 needs_set_mailbox_(false) {
41 vertex_opacity_[0] = 1.0f;
42 vertex_opacity_[1] = 1.0f;
43 vertex_opacity_[2] = 1.0f;
44 vertex_opacity_[3] = 1.0f;
47 TextureLayer::~TextureLayer() {
50 void TextureLayer::ClearClient() {
51 if (rate_limit_context_ && client_ && layer_tree_host())
52 layer_tree_host()->StopRateLimiter();
53 client_ = NULL;
54 if (uses_mailbox_)
55 SetTextureMailbox(TextureMailbox(), scoped_ptr<SingleReleaseCallback>());
56 else
57 SetTextureId(0);
60 scoped_ptr<LayerImpl> TextureLayer::CreateLayerImpl(LayerTreeImpl* tree_impl) {
61 return TextureLayerImpl::Create(tree_impl, id(), uses_mailbox_).
62 PassAs<LayerImpl>();
65 void TextureLayer::SetFlipped(bool flipped) {
66 if (flipped_ == flipped)
67 return;
68 flipped_ = flipped;
69 SetNeedsCommit();
72 void TextureLayer::SetUV(gfx::PointF top_left, gfx::PointF bottom_right) {
73 if (uv_top_left_ == top_left && uv_bottom_right_ == bottom_right)
74 return;
75 uv_top_left_ = top_left;
76 uv_bottom_right_ = bottom_right;
77 SetNeedsCommit();
80 void TextureLayer::SetVertexOpacity(float bottom_left,
81 float top_left,
82 float top_right,
83 float bottom_right) {
84 // Indexing according to the quad vertex generation:
85 // 1--2
86 // | |
87 // 0--3
88 if (vertex_opacity_[0] == bottom_left &&
89 vertex_opacity_[1] == top_left &&
90 vertex_opacity_[2] == top_right &&
91 vertex_opacity_[3] == bottom_right)
92 return;
93 vertex_opacity_[0] = bottom_left;
94 vertex_opacity_[1] = top_left;
95 vertex_opacity_[2] = top_right;
96 vertex_opacity_[3] = bottom_right;
97 SetNeedsCommit();
100 void TextureLayer::SetPremultipliedAlpha(bool premultiplied_alpha) {
101 if (premultiplied_alpha_ == premultiplied_alpha)
102 return;
103 premultiplied_alpha_ = premultiplied_alpha;
104 SetNeedsCommit();
107 void TextureLayer::SetBlendBackgroundColor(bool blend) {
108 if (blend_background_color_ == blend)
109 return;
110 blend_background_color_ = blend;
111 SetNeedsCommit();
114 void TextureLayer::SetRateLimitContext(bool rate_limit) {
115 if (!rate_limit && rate_limit_context_ && client_ && layer_tree_host())
116 layer_tree_host()->StopRateLimiter();
118 rate_limit_context_ = rate_limit;
121 void TextureLayer::SetTextureId(unsigned id) {
122 DCHECK(!uses_mailbox_);
123 if (texture_id_ == id)
124 return;
125 if (texture_id_ && layer_tree_host())
126 layer_tree_host()->AcquireLayerTextures();
127 texture_id_ = id;
128 SetNeedsCommit();
129 // The texture id needs to be removed from the active tree before the
130 // commit is called complete.
131 SetNextCommitWaitsForActivation();
134 void TextureLayer::SetTextureMailboxInternal(
135 const TextureMailbox& mailbox,
136 scoped_ptr<SingleReleaseCallback> release_callback,
137 bool requires_commit) {
138 DCHECK(uses_mailbox_);
139 DCHECK(!mailbox.IsValid() || !holder_ref_ ||
140 !mailbox.Equals(holder_ref_->holder()->mailbox()));
141 DCHECK_EQ(mailbox.IsValid(), !!release_callback);
143 // If we never commited the mailbox, we need to release it here.
144 if (mailbox.IsValid())
145 holder_ref_ = MailboxHolder::Create(mailbox, release_callback.Pass());
146 else
147 holder_ref_.reset();
148 needs_set_mailbox_ = true;
149 // If we are within a commit, no need to do it again immediately after.
150 if (requires_commit)
151 SetNeedsCommit();
152 else
153 SetNeedsPushProperties();
155 // The active frame needs to be replaced and the mailbox returned before the
156 // commit is called complete.
157 SetNextCommitWaitsForActivation();
160 void TextureLayer::SetTextureMailbox(
161 const TextureMailbox& mailbox,
162 scoped_ptr<SingleReleaseCallback> release_callback) {
163 SetTextureMailboxInternal(
164 mailbox,
165 release_callback.Pass(),
166 true /* requires_commit */);
169 void TextureLayer::WillModifyTexture() {
170 if (!uses_mailbox_ && layer_tree_host() && (DrawsContent() ||
171 content_committed_)) {
172 layer_tree_host()->AcquireLayerTextures();
173 content_committed_ = false;
177 void TextureLayer::SetNeedsDisplayRect(const gfx::RectF& dirty_rect) {
178 Layer::SetNeedsDisplayRect(dirty_rect);
180 if (rate_limit_context_ && client_ && layer_tree_host() && DrawsContent())
181 layer_tree_host()->StartRateLimiter();
184 void TextureLayer::SetLayerTreeHost(LayerTreeHost* host) {
185 if (layer_tree_host() == host) {
186 Layer::SetLayerTreeHost(host);
187 return;
190 if (layer_tree_host()) {
191 if (texture_id_) {
192 layer_tree_host()->AcquireLayerTextures();
193 // The texture id needs to be removed from the active tree before the
194 // commit is called complete.
195 SetNextCommitWaitsForActivation();
197 if (rate_limit_context_ && client_)
198 layer_tree_host()->StopRateLimiter();
200 // If we're removed from the tree, the TextureLayerImpl will be destroyed, and
201 // we will need to set the mailbox again on a new TextureLayerImpl the next
202 // time we push.
203 if (!host && uses_mailbox_ && holder_ref_) {
204 needs_set_mailbox_ = true;
205 // The active frame needs to be replaced and the mailbox returned before the
206 // commit is called complete.
207 SetNextCommitWaitsForActivation();
209 Layer::SetLayerTreeHost(host);
212 bool TextureLayer::DrawsContent() const {
213 return (client_ || texture_id_ || holder_ref_) && Layer::DrawsContent();
216 bool TextureLayer::Update(ResourceUpdateQueue* queue,
217 const OcclusionTracker* occlusion) {
218 bool updated = Layer::Update(queue, occlusion);
219 if (client_) {
220 if (uses_mailbox_) {
221 TextureMailbox mailbox;
222 scoped_ptr<SingleReleaseCallback> release_callback;
223 if (client_->PrepareTextureMailbox(
224 &mailbox,
225 &release_callback,
226 layer_tree_host()->UsingSharedMemoryResources())) {
227 // Already within a commit, no need to do another one immediately.
228 SetTextureMailboxInternal(
229 mailbox,
230 release_callback.Pass(),
231 false /* requires_commit */);
232 updated = true;
234 } else {
235 texture_id_ = client_->PrepareTexture();
236 updated = true;
237 SetNeedsPushProperties();
238 // The texture id needs to be removed from the active tree before the
239 // commit is called complete.
240 SetNextCommitWaitsForActivation();
244 // SetTextureMailbox could be called externally and the same mailbox used for
245 // different textures. Such callers notify this layer that the texture has
246 // changed by calling SetNeedsDisplay, so check for that here.
247 return updated || !update_rect_.IsEmpty();
250 void TextureLayer::PushPropertiesTo(LayerImpl* layer) {
251 Layer::PushPropertiesTo(layer);
253 TextureLayerImpl* texture_layer = static_cast<TextureLayerImpl*>(layer);
254 texture_layer->set_flipped(flipped_);
255 texture_layer->set_uv_top_left(uv_top_left_);
256 texture_layer->set_uv_bottom_right(uv_bottom_right_);
257 texture_layer->set_vertex_opacity(vertex_opacity_);
258 texture_layer->set_premultiplied_alpha(premultiplied_alpha_);
259 texture_layer->set_blend_background_color(blend_background_color_);
260 if (uses_mailbox_ && needs_set_mailbox_) {
261 TextureMailbox texture_mailbox;
262 scoped_ptr<SingleReleaseCallback> release_callback;
263 if (holder_ref_) {
264 MailboxHolder* holder = holder_ref_->holder();
265 texture_mailbox = holder->mailbox();
266 release_callback = holder->GetCallbackForImplThread();
268 texture_layer->SetTextureMailbox(texture_mailbox, release_callback.Pass());
269 needs_set_mailbox_ = false;
270 } else {
271 texture_layer->set_texture_id(texture_id_);
272 content_committed_ = DrawsContent();
276 Region TextureLayer::VisibleContentOpaqueRegion() const {
277 if (contents_opaque())
278 return visible_content_rect();
280 if (blend_background_color_ && (SkColorGetA(background_color()) == 0xFF))
281 return visible_content_rect();
283 return Region();
286 TextureLayer::MailboxHolder::MainThreadReference::MainThreadReference(
287 MailboxHolder* holder)
288 : holder_(holder) {
289 holder_->InternalAddRef();
292 TextureLayer::MailboxHolder::MainThreadReference::~MainThreadReference() {
293 holder_->InternalRelease();
296 TextureLayer::MailboxHolder::MailboxHolder(
297 const TextureMailbox& mailbox,
298 scoped_ptr<SingleReleaseCallback> release_callback)
299 : message_loop_(BlockingTaskRunner::current()),
300 internal_references_(0),
301 mailbox_(mailbox),
302 release_callback_(release_callback.Pass()),
303 sync_point_(mailbox.sync_point()),
304 is_lost_(false) {
307 TextureLayer::MailboxHolder::~MailboxHolder() {
308 DCHECK_EQ(0u, internal_references_);
311 scoped_ptr<TextureLayer::MailboxHolder::MainThreadReference>
312 TextureLayer::MailboxHolder::Create(
313 const TextureMailbox& mailbox,
314 scoped_ptr<SingleReleaseCallback> release_callback) {
315 return scoped_ptr<MainThreadReference>(new MainThreadReference(
316 new MailboxHolder(mailbox, release_callback.Pass())));
319 void TextureLayer::MailboxHolder::Return(unsigned sync_point, bool is_lost) {
320 base::AutoLock lock(arguments_lock_);
321 sync_point_ = sync_point;
322 is_lost_ = is_lost;
325 scoped_ptr<SingleReleaseCallback>
326 TextureLayer::MailboxHolder::GetCallbackForImplThread() {
327 // We can't call GetCallbackForImplThread if we released the main thread
328 // reference.
329 DCHECK_GT(internal_references_, 0u);
330 InternalAddRef();
331 return SingleReleaseCallback::Create(
332 base::Bind(&MailboxHolder::ReturnAndReleaseOnImplThread, this));
335 void TextureLayer::MailboxHolder::InternalAddRef() {
336 ++internal_references_;
339 void TextureLayer::MailboxHolder::InternalRelease() {
340 DCHECK(message_loop_->BelongsToCurrentThread());
341 if (!--internal_references_) {
342 release_callback_->Run(sync_point_, is_lost_);
343 mailbox_ = TextureMailbox();
344 release_callback_.reset();
348 void TextureLayer::MailboxHolder::ReturnAndReleaseOnImplThread(
349 unsigned sync_point, bool is_lost) {
350 Return(sync_point, is_lost);
351 message_loop_->PostTask(FROM_HERE,
352 base::Bind(&MailboxHolder::InternalRelease, this));
355 } // namespace cc