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 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
)
38 , m_usesMailbox(usesMailbox
)
40 , m_uvRect(0, 0, 1, 1)
41 , m_premultipliedAlpha(true)
42 , m_rateLimitContext(false)
43 , m_contextLost(false)
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()) {
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
)
76 void TextureLayer::setUVRect(const gfx::RectF
& rect
)
82 void TextureLayer::setVertexOpacity(float bottomLeft
,
86 // Indexing according to the quad vertex generation:
90 m_vertexOpacity
[0] = bottomLeft
;
91 m_vertexOpacity
[1] = topLeft
;
92 m_vertexOpacity
[2] = topRight
;
93 m_vertexOpacity
[3] = bottomRight
;
97 void TextureLayer::setPremultipliedAlpha(bool premultipliedAlpha
)
99 m_premultipliedAlpha
= premultipliedAlpha
;
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
)
116 if (m_textureId
&& layerTreeHost())
117 layerTreeHost()->acquireLayerTextures();
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)
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
;
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
&)
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
);
185 Thread
* mainThread
= layerTreeHost()->proxy()->mainThread();
186 textureLayer
->setTextureMailbox(m_mailboxName
, base::Bind(&postCallbackToMainThread
, mainThread
, m_mailboxReleaseCallback
));
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.