943c53fbf0827e126a7b62ee18d86bf3d28f578c
[WebKit-https.git] / Source / WebCore / platform / graphics / chromium / cc / CCRenderSurface.cpp
1 /*
2  * Copyright (C) 2011 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27
28 #if USE(ACCELERATED_COMPOSITING)
29
30 #include "cc/CCRenderSurface.h"
31
32 #include "GraphicsContext3D.h"
33 #include "LayerChromium.h"
34 #include "LayerRendererChromium.h"
35 #include "ManagedTexture.h"
36 #include "TextStream.h"
37 #include "cc/CCDamageTracker.h"
38 #include "cc/CCDebugBorderDrawQuad.h"
39 #include "cc/CCLayerImpl.h"
40 #include "cc/CCQuadCuller.h"
41 #include "cc/CCRenderSurfaceDrawQuad.h"
42 #include "cc/CCSharedQuadState.h"
43 #include <wtf/text/CString.h>
44
45 namespace WebCore {
46
47 static const int debugSurfaceBorderWidth = 2;
48 static const int debugSurfaceBorderAlpha = 100;
49 static const int debugSurfaceBorderColorRed = 0;
50 static const int debugSurfaceBorderColorGreen = 0;
51 static const int debugSurfaceBorderColorBlue = 255;
52 static const int debugReplicaBorderColorRed = 160;
53 static const int debugReplicaBorderColorGreen = 0;
54 static const int debugReplicaBorderColorBlue = 255;
55
56 CCRenderSurface::CCRenderSurface(CCLayerImpl* owningLayer)
57     : m_owningLayer(owningLayer)
58     , m_surfacePropertyChanged(false)
59     , m_drawOpacity(1)
60     , m_drawOpacityIsAnimating(false)
61     , m_targetSurfaceTransformsAreAnimating(false)
62     , m_screenSpaceTransformsAreAnimating(false)
63     , m_nearestAncestorThatMovesPixels(0)
64     , m_targetRenderSurfaceLayerIndexHistory(0)
65     , m_currentLayerIndexHistory(0)
66 {
67     m_damageTracker = CCDamageTracker::create();
68 }
69
70 CCRenderSurface::~CCRenderSurface()
71 {
72 }
73
74 FloatRect CCRenderSurface::drawableContentRect() const
75 {
76     FloatRect localContentRect(-0.5 * m_contentRect.width(), -0.5 * m_contentRect.height(),
77                                m_contentRect.width(), m_contentRect.height());
78     FloatRect drawableContentRect = m_drawTransform.mapRect(localContentRect);
79     if (hasReplica())
80         drawableContentRect.unite(m_replicaDrawTransform.mapRect(localContentRect));
81
82     return drawableContentRect;
83 }
84
85 bool CCRenderSurface::prepareContentsTexture(LayerRendererChromium* layerRenderer)
86 {
87     TextureManager* textureManager = layerRenderer->renderSurfaceTextureManager();
88
89     if (!m_contentsTexture)
90         m_contentsTexture = ManagedTexture::create(textureManager);
91
92     if (m_contentsTexture->isReserved())
93         return true;
94
95     if (!m_contentsTexture->reserve(m_contentRect.size(), GraphicsContext3D::RGBA))
96         return false;
97
98     return true;
99 }
100
101 void CCRenderSurface::releaseContentsTexture()
102 {
103     if (!m_contentsTexture || !m_contentsTexture->isReserved())
104         return;
105     m_contentsTexture->unreserve();
106 }
107
108 bool CCRenderSurface::hasValidContentsTexture() const
109 {
110     return m_contentsTexture && m_contentsTexture->isReserved() && m_contentsTexture->isValid(m_contentRect.size(), GraphicsContext3D::RGBA);
111 }
112
113 bool CCRenderSurface::prepareBackgroundTexture(LayerRendererChromium* layerRenderer)
114 {
115     TextureManager* textureManager = layerRenderer->renderSurfaceTextureManager();
116
117     if (!m_backgroundTexture)
118         m_backgroundTexture = ManagedTexture::create(textureManager);
119
120     if (m_backgroundTexture->isReserved())
121         return true;
122
123     if (!m_backgroundTexture->reserve(m_contentRect.size(), GraphicsContext3D::RGBA))
124         return false;
125
126     return true;
127 }
128
129 void CCRenderSurface::releaseBackgroundTexture()
130 {
131     if (!m_backgroundTexture || !m_backgroundTexture->isReserved())
132         return;
133     m_backgroundTexture->unreserve();
134 }
135
136 bool CCRenderSurface::hasValidBackgroundTexture() const
137 {
138     return m_backgroundTexture && m_backgroundTexture->isReserved() && m_backgroundTexture->isValid(m_contentRect.size(), GraphicsContext3D::RGBA);
139 }
140
141 void CCRenderSurface::setScissorRect(LayerRendererChromium* layerRenderer, const FloatRect& surfaceDamageRect) const
142 {
143     if (m_owningLayer->parent() && m_owningLayer->parent()->usesLayerClipping() && layerRenderer->capabilities().usingPartialSwap) {
144         FloatRect clipAndDamageRect = m_clipRect;
145         clipAndDamageRect.intersect(surfaceDamageRect);
146         layerRenderer->setScissorToRect(enclosingIntRect(clipAndDamageRect));
147     } else if (layerRenderer->capabilities().usingPartialSwap)
148         layerRenderer->setScissorToRect(enclosingIntRect(surfaceDamageRect));
149     else if (m_owningLayer->parent() && m_owningLayer->parent()->usesLayerClipping())
150         layerRenderer->setScissorToRect(m_clipRect);
151     else
152         GLC(layerRenderer->context(), layerRenderer->context()->disable(GraphicsContext3D::SCISSOR_TEST));
153 }
154
155 String CCRenderSurface::name() const
156 {
157     return String::format("RenderSurface(id=%i,owner=%s)", m_owningLayer->id(), m_owningLayer->debugName().utf8().data());
158 }
159
160 static void writeIndent(TextStream& ts, int indent)
161 {
162     for (int i = 0; i != indent; ++i)
163         ts << "  ";
164 }
165
166 void CCRenderSurface::dumpSurface(TextStream& ts, int indent) const
167 {
168     writeIndent(ts, indent);
169     ts << name() << "\n";
170
171     writeIndent(ts, indent+1);
172     ts << "contentRect: (" << m_contentRect.x() << ", " << m_contentRect.y() << ", " << m_contentRect.width() << ", " << m_contentRect.height() << "\n";
173
174     writeIndent(ts, indent+1);
175     ts << "drawTransform: ";
176     ts << m_drawTransform.m11() << ", " << m_drawTransform.m12() << ", " << m_drawTransform.m13() << ", " << m_drawTransform.m14() << "  //  ";
177     ts << m_drawTransform.m21() << ", " << m_drawTransform.m22() << ", " << m_drawTransform.m23() << ", " << m_drawTransform.m24() << "  //  ";
178     ts << m_drawTransform.m31() << ", " << m_drawTransform.m32() << ", " << m_drawTransform.m33() << ", " << m_drawTransform.m34() << "  //  ";
179     ts << m_drawTransform.m41() << ", " << m_drawTransform.m42() << ", " << m_drawTransform.m43() << ", " << m_drawTransform.m44() << "\n";
180
181     writeIndent(ts, indent+1);
182     ts << "damageRect is pos(" << m_damageTracker->currentDamageRect().x() << "," << m_damageTracker->currentDamageRect().y() << "), ";
183     ts << "size(" << m_damageTracker->currentDamageRect().width() << "," << m_damageTracker->currentDamageRect().height() << ")\n";
184 }
185
186 int CCRenderSurface::owningLayerId() const
187 {
188     return m_owningLayer ? m_owningLayer->id() : 0;
189 }
190
191 CCRenderSurface* CCRenderSurface::targetRenderSurface() const
192 {
193     CCLayerImpl* parent = m_owningLayer->parent();
194     if (!parent)
195         return 0;
196     return parent->targetRenderSurface();
197 }
198
199 bool CCRenderSurface::hasReplica() const
200 {
201     return m_owningLayer->replicaLayer();
202 }
203
204 bool CCRenderSurface::hasMask() const
205 {
206     return m_owningLayer->maskLayer();
207 }
208
209 bool CCRenderSurface::replicaHasMask() const
210 {
211     return hasReplica() && (m_owningLayer->maskLayer() || m_owningLayer->replicaLayer()->maskLayer());
212 }
213
214 void CCRenderSurface::setClipRect(const IntRect& clipRect)
215 {
216     if (m_clipRect == clipRect)
217         return;
218
219     m_surfacePropertyChanged = true;
220     m_clipRect = clipRect;
221 }
222
223 void CCRenderSurface::setContentRect(const IntRect& contentRect)
224 {
225     if (m_contentRect == contentRect)
226         return;
227
228     m_surfacePropertyChanged = true;
229     m_contentRect = contentRect;
230 }
231
232 bool CCRenderSurface::surfacePropertyChanged() const
233 {
234     // Surface property changes are tracked as follows:
235     //
236     // - m_surfacePropertyChanged is flagged when the clipRect or contentRect change. As
237     //   of now, these are the only two properties that can be affected by descendant layers.
238     //
239     // - all other property changes come from the owning layer (or some ancestor layer
240     //   that propagates its change to the owning layer).
241     //
242     ASSERT(m_owningLayer);
243     return m_surfacePropertyChanged || m_owningLayer->layerPropertyChanged();
244 }
245
246 bool CCRenderSurface::surfacePropertyChangedOnlyFromDescendant() const
247 {
248     return m_surfacePropertyChanged && !m_owningLayer->layerPropertyChanged();
249 }
250
251 PassOwnPtr<CCSharedQuadState> CCRenderSurface::createSharedQuadState() const
252 {
253     bool isOpaque = false;
254     return CCSharedQuadState::create(originTransform(), drawTransform(), contentRect(), clipRect(), drawOpacity(), isOpaque);
255 }
256
257 PassOwnPtr<CCSharedQuadState> CCRenderSurface::createReplicaSharedQuadState() const
258 {
259     bool isOpaque = false;
260     return CCSharedQuadState::create(replicaOriginTransform(), replicaDrawTransform(), contentRect(), clipRect(), drawOpacity(), isOpaque);
261 }
262
263 void CCRenderSurface::appendQuads(CCQuadCuller& quadList, CCSharedQuadState* sharedQuadState, bool forReplica, const FloatRect& surfaceDamageRect)
264 {
265     ASSERT(!forReplica || hasReplica());
266
267     if (m_owningLayer->hasDebugBorders()) {
268         int red = forReplica ? debugReplicaBorderColorRed : debugSurfaceBorderColorRed;
269         int green = forReplica ?  debugReplicaBorderColorGreen : debugSurfaceBorderColorGreen;
270         int blue = forReplica ? debugReplicaBorderColorBlue : debugSurfaceBorderColorBlue;
271         Color color(red, green, blue, debugSurfaceBorderAlpha);
272         quadList.appendSurface(CCDebugBorderDrawQuad::create(sharedQuadState, contentRect(), color, debugSurfaceBorderWidth));
273     }
274
275     // FIXME: By using the same RenderSurface for both the content and its reflection,
276     // it's currently not possible to apply a separate mask to the reflection layer
277     // or correctly handle opacity in reflections (opacity must be applied after drawing
278     // both the layer and its reflection). The solution is to introduce yet another RenderSurface
279     // to draw the layer and its reflection in. For now we only apply a separate reflection
280     // mask if the contents don't have a mask of their own.
281     CCLayerImpl* maskLayer = m_owningLayer->maskLayer();
282     if (maskLayer && (!maskLayer->drawsContent() || maskLayer->bounds().isEmpty()))
283         maskLayer = 0;
284
285     if (!maskLayer && forReplica) {
286         maskLayer = m_owningLayer->replicaLayer()->maskLayer();
287         if (maskLayer && (!maskLayer->drawsContent() || maskLayer->bounds().isEmpty()))
288             maskLayer = 0;
289     }
290
291     int maskTextureId = maskLayer ? maskLayer->contentsTextureId() : 0;
292
293     quadList.appendSurface(CCRenderSurfaceDrawQuad::create(sharedQuadState, contentRect(), m_owningLayer, surfaceDamageRect, forReplica, filters(), backgroundFilters(), maskTextureId));
294 }
295
296 }
297 #endif // USE(ACCELERATED_COMPOSITING)