12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2010 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/texture_layer.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
77d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/bind.h"
8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/callback_helpers.h"
97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/location.h"
10424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/synchronization/lock.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/texture_layer_client.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/texture_layer_impl.h"
13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "cc/resources/single_release_callback.h"
14424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "cc/trees/blocking_task_runner.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/layer_tree_host.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_refptr<TextureLayer> TextureLayer::CreateForMailbox(
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TextureLayerClient* client) {
21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return scoped_refptr<TextureLayer>(new TextureLayer(client));
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTextureLayer::TextureLayer(TextureLayerClient* client)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : Layer(),
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      client_(client),
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      flipped_(true),
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      uv_top_left_(0.f, 0.f),
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      uv_bottom_right_(1.f, 1.f),
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      premultiplied_alpha_(true),
317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      blend_background_color_(false),
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      rate_limit_context_(false),
337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      needs_set_mailbox_(false) {
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  vertex_opacity_[0] = 1.0f;
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  vertex_opacity_[1] = 1.0f;
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  vertex_opacity_[2] = 1.0f;
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  vertex_opacity_[3] = 1.0f;
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TextureLayer::~TextureLayer() {
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TextureLayer::ClearClient() {
447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (rate_limit_context_ && client_ && layer_tree_host())
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    layer_tree_host()->StopRateLimiter();
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  client_ = NULL;
47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ClearTexture();
48c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
49c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
50c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid TextureLayer::ClearTexture() {
51c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  SetTextureMailbox(TextureMailbox(), scoped_ptr<SingleReleaseCallback>());
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<LayerImpl> TextureLayer::CreateLayerImpl(LayerTreeImpl* tree_impl) {
55c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return TextureLayerImpl::Create(tree_impl, id()).PassAs<LayerImpl>();
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TextureLayer::SetFlipped(bool flipped) {
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (flipped_ == flipped)
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  flipped_ = flipped;
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetNeedsCommit();
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void TextureLayer::SetUV(const gfx::PointF& top_left,
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         const gfx::PointF& bottom_right) {
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (uv_top_left_ == top_left && uv_bottom_right_ == bottom_right)
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uv_top_left_ = top_left;
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uv_bottom_right_ = bottom_right;
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetNeedsCommit();
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TextureLayer::SetVertexOpacity(float bottom_left,
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    float top_left,
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    float top_right,
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    float bottom_right) {
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Indexing according to the quad vertex generation:
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 1--2
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |  |
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 0--3
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (vertex_opacity_[0] == bottom_left &&
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      vertex_opacity_[1] == top_left &&
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      vertex_opacity_[2] == top_right &&
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      vertex_opacity_[3] == bottom_right)
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  vertex_opacity_[0] = bottom_left;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  vertex_opacity_[1] = top_left;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  vertex_opacity_[2] = top_right;
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  vertex_opacity_[3] = bottom_right;
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetNeedsCommit();
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TextureLayer::SetPremultipliedAlpha(bool premultiplied_alpha) {
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (premultiplied_alpha_ == premultiplied_alpha)
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  premultiplied_alpha_ = premultiplied_alpha;
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetNeedsCommit();
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid TextureLayer::SetBlendBackgroundColor(bool blend) {
1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (blend_background_color_ == blend)
1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  blend_background_color_ = blend;
1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SetNeedsCommit();
1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TextureLayer::SetRateLimitContext(bool rate_limit) {
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!rate_limit && rate_limit_context_ && client_ && layer_tree_host())
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    layer_tree_host()->StopRateLimiter();
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rate_limit_context_ = rate_limit;
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void TextureLayer::SetTextureMailboxInternal(
116d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const TextureMailbox& mailbox,
1171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    scoped_ptr<SingleReleaseCallback> release_callback,
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool requires_commit,
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool allow_mailbox_reuse) {
1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(!mailbox.IsValid() || !holder_ref_ ||
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         !mailbox.Equals(holder_ref_->holder()->mailbox()) ||
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         allow_mailbox_reuse);
123d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK_EQ(mailbox.IsValid(), !!release_callback);
124d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // If we never commited the mailbox, we need to release it here.
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (mailbox.IsValid()) {
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    holder_ref_ =
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        TextureMailboxHolder::Create(mailbox, release_callback.Pass());
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    holder_ref_.reset();
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  needs_set_mailbox_ = true;
1331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // If we are within a commit, no need to do it again immediately after.
1341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (requires_commit)
1351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    SetNeedsCommit();
1361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  else
1371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    SetNeedsPushProperties();
1381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
139424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // The active frame needs to be replaced and the mailbox returned before the
140424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // commit is called complete.
141424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SetNextCommitWaitsForActivation();
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void TextureLayer::SetTextureMailbox(
1451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const TextureMailbox& mailbox,
1461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    scoped_ptr<SingleReleaseCallback> release_callback) {
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool requires_commit = true;
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool allow_mailbox_reuse = false;
1491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  SetTextureMailboxInternal(
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      mailbox, release_callback.Pass(), requires_commit, allow_mailbox_reuse);
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static void IgnoreReleaseCallback(uint32 sync_point, bool lost) {}
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TextureLayer::SetTextureMailboxWithoutReleaseCallback(
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const TextureMailbox& mailbox) {
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // We allow reuse of the mailbox if there is a new sync point signalling new
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // content, and the release callback goes nowhere since we'll be calling it
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // multiple times for the same mailbox.
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!mailbox.IsValid() || !holder_ref_ ||
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         !mailbox.Equals(holder_ref_->holder()->mailbox()) ||
162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         mailbox.sync_point() != holder_ref_->holder()->mailbox().sync_point());
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<SingleReleaseCallback> release;
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool requires_commit = true;
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool allow_mailbox_reuse = true;
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (mailbox.IsValid())
167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    release = SingleReleaseCallback::Create(base::Bind(&IgnoreReleaseCallback));
168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SetTextureMailboxInternal(
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      mailbox, release.Pass(), requires_commit, allow_mailbox_reuse);
1701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TextureLayer::SetNeedsDisplayRect(const gfx::RectF& dirty_rect) {
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Layer::SetNeedsDisplayRect(dirty_rect);
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rate_limit_context_ && client_ && layer_tree_host() && DrawsContent())
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    layer_tree_host()->StartRateLimiter();
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TextureLayer::SetLayerTreeHost(LayerTreeHost* host) {
1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (layer_tree_host() == host) {
1817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    Layer::SetLayerTreeHost(host);
1827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
1837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (layer_tree_host()) {
1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (rate_limit_context_ && client_)
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      layer_tree_host()->StopRateLimiter();
1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
1897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // If we're removed from the tree, the TextureLayerImpl will be destroyed, and
1907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // we will need to set the mailbox again on a new TextureLayerImpl the next
1917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // time we push.
192c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!host && holder_ref_) {
1937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    needs_set_mailbox_ = true;
194424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // The active frame needs to be replaced and the mailbox returned before the
195424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // commit is called complete.
196424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    SetNextCommitWaitsForActivation();
197424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Layer::SetLayerTreeHost(host);
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TextureLayer::DrawsContent() const {
202c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return (client_ || holder_ref_) && Layer::DrawsContent();
2037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool TextureLayer::Update(ResourceUpdateQueue* queue,
206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                          const OcclusionTracker<Layer>* occlusion) {
207a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool updated = Layer::Update(queue, occlusion);
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (client_) {
209c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    TextureMailbox mailbox;
210c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    scoped_ptr<SingleReleaseCallback> release_callback;
211c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if (client_->PrepareTextureMailbox(
212c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch            &mailbox,
213c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch            &release_callback,
214c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch            layer_tree_host()->UsingSharedMemoryResources())) {
215c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      // Already within a commit, no need to do another one immediately.
216c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      bool requires_commit = false;
217c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      bool allow_mailbox_reuse = false;
218c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      SetTextureMailboxInternal(mailbox,
219c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                release_callback.Pass(),
220c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                requires_commit,
221c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                allow_mailbox_reuse);
2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      updated = true;
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // SetTextureMailbox could be called externally and the same mailbox used for
2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // different textures.  Such callers notify this layer that the texture has
2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // changed by calling SetNeedsDisplay, so check for that here.
2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return updated || !update_rect_.IsEmpty();
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TextureLayer::PushPropertiesTo(LayerImpl* layer) {
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Layer::PushPropertiesTo(layer);
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TextureLayerImpl* texture_layer = static_cast<TextureLayerImpl*>(layer);
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  texture_layer->SetFlipped(flipped_);
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  texture_layer->SetUVTopLeft(uv_top_left_);
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  texture_layer->SetUVBottomRight(uv_bottom_right_);
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  texture_layer->SetVertexOpacity(vertex_opacity_);
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  texture_layer->SetPremultipliedAlpha(premultiplied_alpha_);
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  texture_layer->SetBlendBackgroundColor(blend_background_color_);
242c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (needs_set_mailbox_) {
2437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    TextureMailbox texture_mailbox;
244d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    scoped_ptr<SingleReleaseCallback> release_callback;
2457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (holder_ref_) {
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      TextureMailboxHolder* holder = holder_ref_->holder();
247d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      texture_mailbox = holder->mailbox();
248d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      release_callback = holder->GetCallbackForImplThread();
2497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
250d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    texture_layer->SetTextureMailbox(texture_mailbox, release_callback.Pass());
2517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    needs_set_mailbox_ = false;
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
255a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)Region TextureLayer::VisibleContentOpaqueRegion() const {
256a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (contents_opaque())
257a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return visible_content_rect();
258a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
259a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (blend_background_color_ && (SkColorGetA(background_color()) == 0xFF))
260a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return visible_content_rect();
261a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
262a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return Region();
263a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
264a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TextureLayer::TextureMailboxHolder::MainThreadReference::MainThreadReference(
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    TextureMailboxHolder* holder)
2677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    : holder_(holder) {
2687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  holder_->InternalAddRef();
2697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
2707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TextureLayer::TextureMailboxHolder::MainThreadReference::
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ~MainThreadReference() {
2737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  holder_->InternalRelease();
2747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
2757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TextureLayer::TextureMailboxHolder::TextureMailboxHolder(
277d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const TextureMailbox& mailbox,
278d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    scoped_ptr<SingleReleaseCallback> release_callback)
279424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    : message_loop_(BlockingTaskRunner::current()),
2807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      internal_references_(0),
2817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      mailbox_(mailbox),
282d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      release_callback_(release_callback.Pass()),
2837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      sync_point_(mailbox.sync_point()),
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      is_lost_(false) {}
2857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TextureLayer::TextureMailboxHolder::~TextureMailboxHolder() {
2877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK_EQ(0u, internal_references_);
2887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
2897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)scoped_ptr<TextureLayer::TextureMailboxHolder::MainThreadReference>
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TextureLayer::TextureMailboxHolder::Create(
292d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const TextureMailbox& mailbox,
293d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    scoped_ptr<SingleReleaseCallback> release_callback) {
2947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return scoped_ptr<MainThreadReference>(new MainThreadReference(
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new TextureMailboxHolder(mailbox, release_callback.Pass())));
2967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
2977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void TextureLayer::TextureMailboxHolder::Return(uint32 sync_point,
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                bool is_lost) {
300424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  base::AutoLock lock(arguments_lock_);
3017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  sync_point_ = sync_point;
3027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  is_lost_ = is_lost;
3037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
305d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)scoped_ptr<SingleReleaseCallback>
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TextureLayer::TextureMailboxHolder::GetCallbackForImplThread() {
3077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // We can't call GetCallbackForImplThread if we released the main thread
3087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // reference.
3097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK_GT(internal_references_, 0u);
3107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  InternalAddRef();
311d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return SingleReleaseCallback::Create(
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&TextureMailboxHolder::ReturnAndReleaseOnImplThread, this));
3137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void TextureLayer::TextureMailboxHolder::InternalAddRef() {
3167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ++internal_references_;
3177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void TextureLayer::TextureMailboxHolder::InternalRelease() {
3207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(message_loop_->BelongsToCurrentThread());
3217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!--internal_references_) {
322d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    release_callback_->Run(sync_point_, is_lost_);
323d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    mailbox_ = TextureMailbox();
324d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    release_callback_.reset();
3257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void TextureLayer::TextureMailboxHolder::ReturnAndReleaseOnImplThread(
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    uint32 sync_point,
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool is_lost) {
331424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  Return(sync_point, is_lost);
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  message_loop_->PostTask(
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FROM_HERE, base::Bind(&TextureMailboxHolder::InternalRelease, this));
3347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
337