OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright (C) 2012 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 #include "CCRendererSoftware.h" | |
29 | |
30 #include "CCDebugBorderDrawQuad.h" | |
31 #include "CCSolidColorDrawQuad.h" | |
32 #include "CCTextureDrawQuad.h" | |
33 #include "CCTileDrawQuad.h" | |
34 #include "SkCanvas.h" | |
35 #include "SkColor.h" | |
36 #include "SkMatrix.h" | |
37 #include "SkPixelRef.h" | |
38 #include "UnthrottledTextureUploader.h" | |
39 #include <GLES2/gl2.h> | |
40 #include <public/WebImage.h> | |
41 #include <public/WebSize.h> | |
42 #include <public/WebTransformationMatrix.h> | |
43 | |
44 using namespace WebKit; | |
jamesr
2012/09/17 20:57:24
I know we have various bits of code that do this b
aelias_OOO_until_Jul13
2012/09/17 21:42:01
Done.
| |
45 | |
46 namespace cc { | |
47 | |
48 namespace { | |
49 | |
50 SkRect toSkRect(const FloatRect& rect) | |
51 { | |
52 return SkRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height()); | |
53 } | |
54 | |
55 SkIRect toSkIRect(const IntRect& rect) | |
56 { | |
57 return SkIRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height()); | |
58 } | |
59 | |
60 void toSkMatrix(SkMatrix* flattened, const WebTransformationMatrix& m) | |
61 { | |
62 // Convert from 4x4 to 3x3 by dropping the third row and column. | |
63 flattened->set(0, m.m11()); | |
64 flattened->set(1, m.m21()); | |
65 flattened->set(2, m.m41()); | |
66 flattened->set(3, m.m12()); | |
67 flattened->set(4, m.m22()); | |
68 flattened->set(5, m.m42()); | |
69 flattened->set(6, m.m14()); | |
70 flattened->set(7, m.m24()); | |
71 flattened->set(8, m.m44()); | |
72 } | |
73 | |
74 class SoftwareTextureCopier : public TextureCopier { | |
75 WTF_MAKE_NONCOPYABLE(SoftwareTextureCopier); | |
76 public: | |
77 static PassOwnPtr<SoftwareTextureCopier> create() | |
78 { | |
79 return adoptPtr(new SoftwareTextureCopier()); | |
80 } | |
81 virtual void copyTexture(TextureCopier::Parameters) OVERRIDE { /* FIXME */ } | |
82 virtual void flush() OVERRIDE { } | |
83 | |
84 private: | |
85 SoftwareTextureCopier() { } | |
86 }; | |
87 | |
88 } // anonymous namespace | |
89 | |
90 PassOwnPtr<CCRendererSoftware> CCRendererSoftware::create(CCRendererClient* clie nt, CCResourceProvider* resourceProvider, WebCompositorOutputSurfaceSoftware* ou tputSurface) | |
91 { | |
92 return adoptPtr(new CCRendererSoftware(client, resourceProvider, outputSurfa ce)); | |
93 } | |
94 | |
95 CCRendererSoftware::CCRendererSoftware(CCRendererClient* client, CCResourceProvi der* resourceProvider, WebCompositorOutputSurfaceSoftware* outputSurface) | |
96 : CCDirectRenderer(client, resourceProvider) | |
97 , m_visible(true) | |
98 , m_textureCopier(SoftwareTextureCopier::create()) | |
99 , m_textureUploader(UnthrottledTextureUploader::create()) | |
100 , m_outputSurface(outputSurface) | |
101 , m_skRootCanvas(0) | |
102 , m_skCurrentCanvas(0) | |
103 { | |
104 m_resourceProvider->setDefaultResourceType(CCResourceProvider::Bitmap); | |
105 | |
106 m_capabilities.maxTextureSize = INT_MAX; | |
107 m_capabilities.bestTextureFormat = GraphicsContext3D::RGBA; | |
108 m_capabilities.contextHasCachedFrontBuffer = true; | |
109 m_capabilities.usingSetVisibility = true; | |
110 | |
111 viewportChanged(); | |
112 } | |
113 | |
114 CCRendererSoftware::~CCRendererSoftware() | |
115 { | |
116 } | |
117 | |
118 void CCRendererSoftware::viewportChanged() | |
119 { | |
120 m_outputSurface->viewportChanged(WebSize(viewportSize().width(), viewportSiz e().height())); | |
121 } | |
122 | |
123 void CCRendererSoftware::beginDrawingFrame(DrawingFrame& frame) | |
124 { | |
125 m_skRootCanvas.setBitmapDevice(m_outputSurface->lockForWrite()->getSkBitmap( )); | |
126 } | |
127 | |
128 void CCRendererSoftware::finishDrawingFrame(DrawingFrame& frame) | |
129 { | |
130 m_currentFramebufferLock.clear(); | |
131 m_skCurrentCanvas = 0; | |
132 m_skRootCanvas.setDevice(0); | |
133 m_outputSurface->unlockForWrite(); | |
134 } | |
135 | |
136 void CCRendererSoftware::finish() | |
137 { | |
138 } | |
139 | |
140 void CCRendererSoftware::bindFramebufferToOutputSurface(DrawingFrame& frame) | |
141 { | |
142 m_currentFramebufferLock.clear(); | |
143 m_skCurrentCanvas = &m_skRootCanvas; | |
144 } | |
145 | |
146 bool CCRendererSoftware::bindFramebufferToTexture(DrawingFrame& frame, const CCS copedTexture* texture, const IntRect& framebufferRect) | |
147 { | |
148 m_currentFramebufferLock = adoptPtr(new CCResourceProvider::ScopedWriteLockS oftware(m_resourceProvider, texture->id())); | |
149 m_skCurrentCanvas = m_currentFramebufferLock->skCanvas(); | |
150 initializeMatrices(frame, framebufferRect, false); | |
151 setDrawViewportSize(framebufferRect.size()); | |
152 | |
153 return true; | |
154 } | |
155 | |
156 void CCRendererSoftware::enableScissorTestRect(const IntRect& scissorRect) | |
157 { | |
158 m_skCurrentCanvas->clipRect(toSkRect(scissorRect), SkRegion::kReplace_Op); | |
159 } | |
160 | |
161 void CCRendererSoftware::disableScissorTest() | |
162 { | |
163 IntRect canvasRect(IntPoint(), viewportSize()); | |
164 m_skCurrentCanvas->clipRect(toSkRect(canvasRect), SkRegion::kReplace_Op); | |
165 } | |
166 | |
167 void CCRendererSoftware::clearFramebuffer(DrawingFrame& frame) | |
168 { | |
169 m_skCurrentCanvas->clear(SK_ColorGREEN); | |
jamesr
2012/09/17 20:57:24
this will have to be more advanced once you start
aelias_OOO_until_Jul13
2012/09/17 21:42:01
I'm not sure why this particular part would have t
| |
170 } | |
171 | |
172 void CCRendererSoftware::setDrawViewportSize(const IntSize& viewportSize) | |
173 { | |
174 } | |
175 | |
176 bool CCRendererSoftware::isSoftwareResource(CCResourceProvider::ResourceId id) c onst | |
177 { | |
178 switch (m_resourceProvider->resourceType(id)) { | |
179 case CCResourceProvider::GLTexture: | |
180 return false; | |
181 case CCResourceProvider::Bitmap: | |
182 return true; | |
183 } | |
184 | |
185 CRASH(); | |
186 return false; | |
187 } | |
188 | |
189 void CCRendererSoftware::drawQuad(DrawingFrame& frame, const CCDrawQuad* quad) | |
190 { | |
191 WebTransformationMatrix quadRectMatrix; | |
192 quadRectTransform(&quadRectMatrix, quad->quadTransform(), quad->quadRect()); | |
193 WebTransformationMatrix windowMatrix = frame.windowMatrix * frame.projection Matrix * quadRectMatrix; | |
194 SkMatrix skWindowMatrix; | |
195 toSkMatrix(&skWindowMatrix, windowMatrix); | |
196 m_skCurrentCanvas->setMatrix(skWindowMatrix); | |
197 | |
198 m_skCurrentPaint.reset(); | |
199 if (quad->needsBlending()) | |
200 m_skCurrentPaint.setAlpha(quad->opacity() * 255); | |
201 else | |
202 m_skCurrentPaint.setXfermodeMode(SkXfermode::kSrc_Mode); | |
203 | |
204 switch (quad->material()) { | |
205 case CCDrawQuad::DebugBorder: | |
206 drawDebugBorderQuad(frame, CCDebugBorderDrawQuad::materialCast(quad)); | |
207 break; | |
208 case CCDrawQuad::SolidColor: | |
209 drawSolidColorQuad(frame, CCSolidColorDrawQuad::materialCast(quad)); | |
210 break; | |
211 case CCDrawQuad::TextureContent: | |
212 drawTextureQuad(frame, CCTextureDrawQuad::materialCast(quad)); | |
213 break; | |
214 case CCDrawQuad::TiledContent: | |
215 drawTileQuad(frame, CCTileDrawQuad::materialCast(quad)); | |
216 break; | |
217 default: | |
218 drawUnsupportedQuad(frame, quad); | |
219 break; | |
220 } | |
221 | |
222 m_skCurrentCanvas->resetMatrix(); | |
223 } | |
224 | |
225 void CCRendererSoftware::drawDebugBorderQuad(const DrawingFrame& frame, const CC DebugBorderDrawQuad* quad) | |
226 { | |
227 // We need to apply the matrix manually to have pixel-sized stroke width. | |
228 SkPoint vertices[4]; | |
229 toSkRect(quadVertexRect()).toQuad(vertices); | |
230 SkPoint transformedVertices[4]; | |
231 m_skCurrentCanvas->getTotalMatrix().mapPoints(transformedVertices, vertices, 4); | |
232 m_skCurrentCanvas->resetMatrix(); | |
233 | |
234 m_skCurrentPaint.setColor(quad->color()); | |
235 m_skCurrentPaint.setAlpha(quad->opacity() * SkColorGetA(quad->color())); | |
236 m_skCurrentPaint.setStyle(SkPaint::kStroke_Style); | |
237 m_skCurrentPaint.setStrokeWidth(quad->width()); | |
238 m_skCurrentCanvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, transformedVe rtices, m_skCurrentPaint); | |
239 } | |
240 | |
241 void CCRendererSoftware::drawSolidColorQuad(const DrawingFrame& frame, const CCS olidColorDrawQuad* quad) | |
242 { | |
243 m_skCurrentPaint.setColor(quad->color()); | |
244 m_skCurrentPaint.setAlpha(quad->opacity() * SkColorGetA(quad->color())); | |
245 m_skCurrentCanvas->drawRect(toSkRect(quadVertexRect()), m_skCurrentPaint); | |
246 } | |
247 | |
248 void CCRendererSoftware::drawTextureQuad(const DrawingFrame& frame, const CCText ureDrawQuad* quad) | |
249 { | |
250 if (!isSoftwareResource(quad->resourceId())) { | |
251 drawUnsupportedQuad(frame, quad); | |
252 return; | |
253 } | |
254 | |
255 // FIXME: Add support for non-premultiplied alpha. | |
256 CCResourceProvider::ScopedReadLockSoftware quadResourceLock(m_resourceProvid er, quad->resourceId()); | |
257 FloatRect uvRect = quad->uvRect(); | |
258 uvRect.scale(quad->quadRect().width(), quad->quadRect().height()); | |
259 SkIRect skUvRect = toSkIRect(enclosingIntRect(uvRect)); | |
260 if (quad->flipped()) | |
261 m_skCurrentCanvas->scale(1, -1); | |
262 m_skCurrentCanvas->drawBitmapRect(*quadResourceLock.skBitmap(), &skUvRect, t oSkRect(quadVertexRect()), &m_skCurrentPaint); | |
263 } | |
264 | |
265 void CCRendererSoftware::drawTileQuad(const DrawingFrame& frame, const CCTileDra wQuad* quad) | |
266 { | |
267 ASSERT(isSoftwareResource(quad->resourceId())); | |
268 CCResourceProvider::ScopedReadLockSoftware quadResourceLock(m_resourceProvid er, quad->resourceId()); | |
269 | |
270 SkIRect uvRect = toSkIRect(IntRect(quad->textureOffset(), quad->quadRect().s ize())); | |
271 m_skCurrentCanvas->drawBitmapRect(*quadResourceLock.skBitmap(), &uvRect, toS kRect(quadVertexRect()), &m_skCurrentPaint); | |
272 } | |
273 | |
274 void CCRendererSoftware::drawUnsupportedQuad(const DrawingFrame& frame, const CC DrawQuad* quad) | |
275 { | |
276 m_skCurrentPaint.setColor(SK_ColorMAGENTA); | |
277 m_skCurrentPaint.setAlpha(quad->opacity() * 255); | |
278 m_skCurrentCanvas->drawRect(toSkRect(quadVertexRect()), m_skCurrentPaint); | |
279 } | |
280 | |
281 bool CCRendererSoftware::swapBuffers() | |
282 { | |
283 if (CCProxy::hasImplThread()) | |
284 m_client->onSwapBuffersComplete(); | |
285 return true; | |
286 } | |
287 | |
288 void CCRendererSoftware::getFramebufferPixels(void *pixels, const IntRect& rect) | |
289 { | |
290 SkBitmap fullBitmap = m_outputSurface->lockForRead()->getSkBitmap(); | |
291 SkBitmap subsetBitmap; | |
292 SkIRect invertRect = SkIRect::MakeXYWH(rect.x(), viewportSize().height() - r ect.maxY(), rect.width(), rect.height()); | |
293 fullBitmap.extractSubset(&subsetBitmap, invertRect); | |
294 subsetBitmap.copyPixelsTo(pixels, rect.width() * rect.height() * 4, rect.wid th() * 4); | |
295 m_outputSurface->unlockForRead(); | |
296 } | |
297 | |
298 void CCRendererSoftware::setVisible(bool visible) | |
299 { | |
300 if (m_visible == visible) | |
301 return; | |
302 m_visible = visible; | |
303 } | |
304 | |
305 } | |
OLD | NEW |