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"
15 static void runCallbackOnMainThread(const TextureMailbox::ReleaseCallback
& callback
, unsigned syncPoint
)
17 callback
.Run(syncPoint
);
20 static void postCallbackToMainThread(Thread
*mainThread
, const TextureMailbox::ReleaseCallback
& 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
)
38 , m_usesMailbox(usesMailbox
)
40 , m_uvTopLeft(0.f
, 0.f
)
41 , m_uvBottomRight(1.f
, 1.f
)
42 , m_premultipliedAlpha(true)
43 , m_rateLimitContext(false)
44 , m_contextLost(false)
46 , m_contentCommitted(false)
48 m_vertexOpacity
[0] = 1.0f
;
49 m_vertexOpacity
[1] = 1.0f
;
50 m_vertexOpacity
[2] = 1.0f
;
51 m_vertexOpacity
[3] = 1.0f
;
54 TextureLayer::~TextureLayer()
56 if (layerTreeHost()) {
58 layerTreeHost()->acquireLayerTextures();
59 if (m_rateLimitContext
&& m_client
)
60 layerTreeHost()->stopRateLimiter(m_client
->context());
62 if (!m_contentCommitted
)
63 m_textureMailbox
.RunReleaseCallback(m_textureMailbox
.sync_point());
66 scoped_ptr
<LayerImpl
> TextureLayer::createLayerImpl(LayerTreeImpl
* treeImpl
)
68 return TextureLayerImpl::create(treeImpl
, m_layerId
, m_usesMailbox
).PassAs
<LayerImpl
>();
71 void TextureLayer::setFlipped(bool flipped
)
77 void TextureLayer::setUV(gfx::PointF topLeft
, gfx::PointF bottomRight
)
79 m_uvTopLeft
= topLeft
;
80 m_uvBottomRight
= bottomRight
;
84 void TextureLayer::setVertexOpacity(float bottomLeft
,
88 // Indexing according to the quad vertex generation:
92 m_vertexOpacity
[0] = bottomLeft
;
93 m_vertexOpacity
[1] = topLeft
;
94 m_vertexOpacity
[2] = topRight
;
95 m_vertexOpacity
[3] = bottomRight
;
99 void TextureLayer::setPremultipliedAlpha(bool premultipliedAlpha
)
101 m_premultipliedAlpha
= premultipliedAlpha
;
105 void TextureLayer::setRateLimitContext(bool rateLimit
)
107 if (!rateLimit
&& m_rateLimitContext
&& m_client
&& layerTreeHost())
108 layerTreeHost()->stopRateLimiter(m_client
->context());
110 m_rateLimitContext
= rateLimit
;
113 void TextureLayer::setTextureId(unsigned id
)
115 DCHECK(!m_usesMailbox
);
116 if (m_textureId
== id
)
118 if (m_textureId
&& layerTreeHost())
119 layerTreeHost()->acquireLayerTextures();
124 void TextureLayer::setTextureMailbox(const TextureMailbox
& mailbox
)
126 DCHECK(m_usesMailbox
);
127 if (m_textureMailbox
.Equals(mailbox
))
129 // If we never commited the mailbox, we need to release it here
130 if (!m_contentCommitted
)
131 m_textureMailbox
.RunReleaseCallback(m_textureMailbox
.sync_point());
132 m_textureMailbox
= mailbox
;
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_textureMailbox
.IsEmpty()) && !m_contextLost
&& Layer::drawsContent();
165 void TextureLayer::update(ResourceUpdateQueue
& queue
, const OcclusionTracker
*, RenderingStats
*)
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
->setUVTopLeft(m_uvTopLeft
);
182 textureLayer
->setUVBottomRight(m_uvBottomRight
);
183 textureLayer
->setVertexOpacity(m_vertexOpacity
);
184 textureLayer
->setPremultipliedAlpha(m_premultipliedAlpha
);
186 Thread
* mainThread
= layerTreeHost()->proxy()->mainThread();
187 TextureMailbox::ReleaseCallback callback
;
188 if (!m_textureMailbox
.IsEmpty())
189 callback
= base::Bind(&postCallbackToMainThread
, mainThread
, m_textureMailbox
.callback());
190 textureLayer
->setTextureMailbox(TextureMailbox(m_textureMailbox
.name(), callback
, m_textureMailbox
.sync_point()));
192 textureLayer
->setTextureId(m_textureId
);
194 m_contentCommitted
= drawsContent();
197 bool TextureLayer::blocksPendingCommit() const
199 // Double-buffered texture layers need to be blocked until they can be made
200 // triple-buffered. Single-buffered layers already prevent draws, so
201 // can block too for simplicity.
202 return drawsContent();
205 bool TextureLayer::canClipSelf() const