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/CCLayerImpl.h"
31
32 #include "GraphicsContext3D.h"
33 #include "LayerChromium.h" // FIXME: temporary and bad
34 #include "LayerRendererChromium.h"
35 #include "RenderSurfaceChromium.h"
36 #include <wtf/text/WTFString.h>
37
38 namespace {
toGLMatrix(float * flattened,const WebCore::TransformationMatrix & m)39 void toGLMatrix(float* flattened, const WebCore::TransformationMatrix& m)
40 {
41 flattened[0] = m.m11();
42 flattened[1] = m.m12();
43 flattened[2] = m.m13();
44 flattened[3] = m.m14();
45 flattened[4] = m.m21();
46 flattened[5] = m.m22();
47 flattened[6] = m.m23();
48 flattened[7] = m.m24();
49 flattened[8] = m.m31();
50 flattened[9] = m.m32();
51 flattened[10] = m.m33();
52 flattened[11] = m.m34();
53 flattened[12] = m.m41();
54 flattened[13] = m.m42();
55 flattened[14] = m.m43();
56 flattened[15] = m.m44();
57 }
58 }
59
60
61 namespace WebCore {
62
CCLayerImpl(LayerChromium * owner)63 CCLayerImpl::CCLayerImpl(LayerChromium* owner)
64 : m_owner(owner)
65 , m_anchorPoint(0.5, 0.5)
66 , m_anchorPointZ(0)
67 , m_doubleSided(true)
68 , m_masksToBounds(false)
69 , m_opacity(1.0)
70 , m_preserves3D(false)
71 #ifndef NDEBUG
72 , m_debugID(owner->debugID())
73 #endif
74 , m_targetRenderSurface(0)
75 , m_drawDepth(0)
76 , m_drawOpacity(0)
77 , m_debugBorderColor(0, 0, 0, 0)
78 , m_debugBorderWidth(0)
79 , m_renderSurface(0)
80 , m_layerRenderer(0)
81 {
82 }
83
~CCLayerImpl()84 CCLayerImpl::~CCLayerImpl()
85 {
86 }
87
88 // These are pseudo-structural hacks until we get real tree syncing up in this piece.
superlayer() const89 CCLayerImpl* CCLayerImpl::superlayer() const
90 {
91 return m_owner->superlayer() ? m_owner->superlayer()->ccLayerImpl() : 0;
92 }
93
maskLayer() const94 CCLayerImpl* CCLayerImpl::maskLayer() const
95 {
96 return m_owner->maskLayer() ? m_owner->maskLayer()->ccLayerImpl() : 0;
97 }
98
replicaLayer() const99 CCLayerImpl* CCLayerImpl::replicaLayer() const
100 {
101 return m_owner->replicaLayer() ? m_owner->replicaLayer()->ccLayerImpl() : 0;
102 }
103
setLayerRenderer(LayerRendererChromium * renderer)104 void CCLayerImpl::setLayerRenderer(LayerRendererChromium* renderer)
105 {
106 m_layerRenderer = renderer;
107 }
108
createRenderSurface()109 RenderSurfaceChromium* CCLayerImpl::createRenderSurface()
110 {
111 m_renderSurface = new RenderSurfaceChromium(this);
112 return m_renderSurface.get();
113 }
114
descendantsDrawsContent()115 bool CCLayerImpl::descendantsDrawsContent()
116 {
117 const Vector<RefPtr<LayerChromium> >& sublayers = m_owner->getSublayers();
118 for (size_t i = 0; i < sublayers.size(); ++i) {
119 sublayers[i]->createCCLayerImplIfNeeded();
120 if (sublayers[i]->ccLayerImpl()->drawsContent() || sublayers[i]->ccLayerImpl()->descendantsDrawsContent())
121 return true;
122 }
123 return false;
124 }
125
126 // These belong on CCLayerImpl, but should be overridden by each type and not defer to the LayerChromium subtypes.
drawsContent() const127 bool CCLayerImpl::drawsContent() const
128 {
129 return m_owner && m_owner->drawsContent();
130 }
131
draw(const IntRect & targetSurfaceRect)132 void CCLayerImpl::draw(const IntRect& targetSurfaceRect)
133 {
134 return m_owner->draw(targetSurfaceRect);
135 }
136
updateCompositorResources()137 void CCLayerImpl::updateCompositorResources()
138 {
139 return m_owner->updateCompositorResources();
140 }
141
unreserveContentsTexture()142 void CCLayerImpl::unreserveContentsTexture()
143 {
144 m_owner->unreserveContentsTexture();
145 }
146
bindContentsTexture()147 void CCLayerImpl::bindContentsTexture()
148 {
149 m_owner->bindContentsTexture();
150 }
151
cleanupResources()152 void CCLayerImpl::cleanupResources()
153 {
154 if (renderSurface())
155 renderSurface()->cleanupResources();
156 }
157
getDrawRect() const158 const IntRect CCLayerImpl::getDrawRect() const
159 {
160 // Form the matrix used by the shader to map the corners of the layer's
161 // bounds into the view space.
162 FloatRect layerRect(-0.5 * bounds().width(), -0.5 * bounds().height(), bounds().width(), bounds().height());
163 IntRect mappedRect = enclosingIntRect(drawTransform().mapRect(layerRect));
164 return mappedRect;
165 }
166
drawDebugBorder()167 void CCLayerImpl::drawDebugBorder()
168 {
169 static float glMatrix[16];
170 if (!debugBorderColor().alpha())
171 return;
172
173 ASSERT(layerRenderer());
174 const LayerChromium::BorderProgram* program = layerRenderer()->borderProgram();
175 ASSERT(program && program->initialized());
176 layerRenderer()->useShader(program->program());
177 TransformationMatrix renderMatrix = drawTransform();
178 renderMatrix.scale3d(bounds().width(), bounds().height(), 1);
179 toGLMatrix(&glMatrix[0], layerRenderer()->projectionMatrix() * renderMatrix);
180 GraphicsContext3D* context = layerRenderer()->context();
181 GLC(context, context->uniformMatrix4fv(program->vertexShader().matrixLocation(), false, &glMatrix[0], 1));
182
183 GLC(context, context->uniform4f(program->fragmentShader().colorLocation(), debugBorderColor().red() / 255.0, debugBorderColor().green() / 255.0, debugBorderColor().blue() / 255.0, 1));
184
185 GLC(context, context->lineWidth(debugBorderWidth()));
186
187 // The indices for the line are stored in the same array as the triangle indices.
188 GLC(context, context->drawElements(GraphicsContext3D::LINE_LOOP, 4, GraphicsContext3D::UNSIGNED_SHORT, 6 * sizeof(unsigned short)));
189 }
190
writeIndent(TextStream & ts,int indent)191 void CCLayerImpl::writeIndent(TextStream& ts, int indent)
192 {
193 for (int i = 0; i != indent; ++i)
194 ts << " ";
195 }
196
dumpLayerProperties(TextStream & ts,int indent) const197 void CCLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const
198 {
199 writeIndent(ts, indent);
200 ts << "bounds: " << bounds().width() << ", " << bounds().height() << "\n";
201
202 if (m_targetRenderSurface) {
203 writeIndent(ts, indent);
204 ts << "targetRenderSurface: " << m_targetRenderSurface->name() << "\n";
205 }
206
207 writeIndent(ts, indent);
208 ts << "drawTransform: ";
209 ts << m_drawTransform.m11() << ", " << m_drawTransform.m12() << ", " << m_drawTransform.m13() << ", " << m_drawTransform.m14() << ", ";
210 ts << m_drawTransform.m21() << ", " << m_drawTransform.m22() << ", " << m_drawTransform.m23() << ", " << m_drawTransform.m24() << ", ";
211 ts << m_drawTransform.m31() << ", " << m_drawTransform.m32() << ", " << m_drawTransform.m33() << ", " << m_drawTransform.m34() << ", ";
212 ts << m_drawTransform.m41() << ", " << m_drawTransform.m42() << ", " << m_drawTransform.m43() << ", " << m_drawTransform.m44() << "\n";
213 }
214
215 }
216
217 #endif // USE(ACCELERATED_COMPOSITING)
218