Mailbox support for texture layers.
[chromium-blink-merge.git] / cc / texture_layer.cc
blobddfa09797241a028f9052398a1bec59d446cbbd2
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/texture_layer.h"
7 #include "cc/layer_tree_host.h"
8 #include "cc/texture_layer_client.h"
9 #include "cc/texture_layer_impl.h"
10 #include "cc/thread.h"
11 #include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h"
13 namespace cc {
15 static void runCallbackOnMainThread(const TextureLayer::MailboxCallback& callback, unsigned syncPoint)
17 callback.Run(syncPoint);
20 static void postCallbackToMainThread(Thread *mainThread, const TextureLayer::MailboxCallback& callback, unsigned syncPoint)
22 mainThread->postTask(base::Bind(&runCallbackOnMainThread, callback, syncPoint));
25 scoped_refptr<TextureLayer> TextureLayer::create(TextureLayerClient* client)
27 return scoped_refptr<TextureLayer>(new TextureLayer(client, false));
30 scoped_refptr<TextureLayer> TextureLayer::createForMailbox()
32 return scoped_refptr<TextureLayer>(new TextureLayer(0, true));
35 TextureLayer::TextureLayer(TextureLayerClient* client, bool usesMailbox)
36 : Layer()
37 , m_client(client)
38 , m_usesMailbox(usesMailbox)
39 , m_flipped(true)
40 , m_uvRect(0, 0, 1, 1)
41 , m_premultipliedAlpha(true)
42 , m_rateLimitContext(false)
43 , m_contextLost(false)
44 , m_textureId(0)
45 , m_contentCommitted(false)
47 m_vertexOpacity[0] = 1.0f;
48 m_vertexOpacity[1] = 1.0f;
49 m_vertexOpacity[2] = 1.0f;
50 m_vertexOpacity[3] = 1.0f;
53 TextureLayer::~TextureLayer()
55 if (layerTreeHost()) {
56 if (m_textureId)
57 layerTreeHost()->acquireLayerTextures();
58 if (m_rateLimitContext && m_client)
59 layerTreeHost()->stopRateLimiter(m_client->context());
61 if (!m_contentCommitted && !m_mailboxName.empty())
62 m_mailboxReleaseCallback.Run(0);
65 scoped_ptr<LayerImpl> TextureLayer::createLayerImpl(LayerTreeImpl* treeImpl)
67 return TextureLayerImpl::create(treeImpl, m_layerId, m_usesMailbox).PassAs<LayerImpl>();
70 void TextureLayer::setFlipped(bool flipped)
72 m_flipped = flipped;
73 setNeedsCommit();
76 void TextureLayer::setUVRect(const gfx::RectF& rect)
78 m_uvRect = rect;
79 setNeedsCommit();
82 void TextureLayer::setVertexOpacity(float bottomLeft,
83 float topLeft,
84 float topRight,
85 float bottomRight) {
86 // Indexing according to the quad vertex generation:
87 // 1--2
88 // | |
89 // 0--3
90 m_vertexOpacity[0] = bottomLeft;
91 m_vertexOpacity[1] = topLeft;
92 m_vertexOpacity[2] = topRight;
93 m_vertexOpacity[3] = bottomRight;
94 setNeedsCommit();
97 void TextureLayer::setPremultipliedAlpha(bool premultipliedAlpha)
99 m_premultipliedAlpha = premultipliedAlpha;
100 setNeedsCommit();
103 void TextureLayer::setRateLimitContext(bool rateLimit)
105 if (!rateLimit && m_rateLimitContext && m_client && layerTreeHost())
106 layerTreeHost()->stopRateLimiter(m_client->context());
108 m_rateLimitContext = rateLimit;
111 void TextureLayer::setTextureId(unsigned id)
113 DCHECK(!m_usesMailbox);
114 if (m_textureId == id)
115 return;
116 if (m_textureId && layerTreeHost())
117 layerTreeHost()->acquireLayerTextures();
118 m_textureId = id;
119 setNeedsCommit();
122 void TextureLayer::setTextureMailbox(const std::string& mailboxName, const MailboxCallback& callback)
124 DCHECK(m_usesMailbox);
125 DCHECK(mailboxName.empty() == callback.is_null());
126 if (m_mailboxName.compare(mailboxName) == 0)
127 return;
128 // If we never commited the mailbox, we need to release it here
129 if (!m_contentCommitted && !m_mailboxName.empty())
130 m_mailboxReleaseCallback.Run(0);
131 m_mailboxReleaseCallback = callback;
132 m_mailboxName = mailboxName;
134 setNeedsCommit();
137 void TextureLayer::willModifyTexture()
139 if (layerTreeHost() && (drawsContent() || m_contentCommitted)) {
140 layerTreeHost()->acquireLayerTextures();
141 m_contentCommitted = false;
145 void TextureLayer::setNeedsDisplayRect(const gfx::RectF& dirtyRect)
147 Layer::setNeedsDisplayRect(dirtyRect);
149 if (m_rateLimitContext && m_client && layerTreeHost() && drawsContent())
150 layerTreeHost()->startRateLimiter(m_client->context());
153 void TextureLayer::setLayerTreeHost(LayerTreeHost* host)
155 if (m_textureId && layerTreeHost() && host != layerTreeHost())
156 layerTreeHost()->acquireLayerTextures();
157 Layer::setLayerTreeHost(host);
160 bool TextureLayer::drawsContent() const
162 return (m_client || m_textureId || !m_mailboxName.empty()) && !m_contextLost && Layer::drawsContent();
165 void TextureLayer::update(ResourceUpdateQueue& queue, const OcclusionTracker*, RenderingStats&)
167 if (m_client) {
168 m_textureId = m_client->prepareTexture(queue);
169 m_contextLost = m_client->context()->getGraphicsResetStatusARB() != GL_NO_ERROR;
172 m_needsDisplay = false;
175 void TextureLayer::pushPropertiesTo(LayerImpl* layer)
177 Layer::pushPropertiesTo(layer);
179 TextureLayerImpl* textureLayer = static_cast<TextureLayerImpl*>(layer);
180 textureLayer->setFlipped(m_flipped);
181 textureLayer->setUVRect(m_uvRect);
182 textureLayer->setVertexOpacity(m_vertexOpacity);
183 textureLayer->setPremultipliedAlpha(m_premultipliedAlpha);
184 if (m_usesMailbox) {
185 Thread* mainThread = layerTreeHost()->proxy()->mainThread();
186 textureLayer->setTextureMailbox(m_mailboxName, base::Bind(&postCallbackToMainThread, mainThread, m_mailboxReleaseCallback));
187 } else {
188 textureLayer->setTextureId(m_textureId);
190 m_contentCommitted = drawsContent();
193 bool TextureLayer::blocksPendingCommit() const
195 // Double-buffered texture layers need to be blocked until they can be made
196 // triple-buffered. Single-buffered layers already prevent draws, so
197 // can block too for simplicity.
198 return true;
201 } // namespace cc