Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(587)

Side by Side Diff: cc/CCRendererSoftware.cpp

Issue 10918258: Add CC software renderer. (Closed) Base URL: http://git.chromium.org/chromium/src.git@gladapter
Patch Set: Change to OutputDevice API and remove "using namespace WebKit" Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 WebKit::WebCompositorSoftwareOutputDevice;
45 using WebKit::WebImage;
46 using WebKit::WebSize;
47 using WebKit::WebTransformationMatrix;
48
49 namespace cc {
50
51 namespace {
52
53 SkRect toSkRect(const FloatRect& rect)
54 {
55 return SkRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height());
56 }
57
58 SkIRect toSkIRect(const IntRect& rect)
59 {
60 return SkIRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height());
61 }
62
63 void toSkMatrix(SkMatrix* flattened, const WebTransformationMatrix& m)
64 {
65 // Convert from 4x4 to 3x3 by dropping the third row and column.
66 flattened->set(0, m.m11());
67 flattened->set(1, m.m21());
68 flattened->set(2, m.m41());
69 flattened->set(3, m.m12());
70 flattened->set(4, m.m22());
71 flattened->set(5, m.m42());
72 flattened->set(6, m.m14());
73 flattened->set(7, m.m24());
74 flattened->set(8, m.m44());
75 }
76
77 class SoftwareTextureCopier : public TextureCopier {
78 WTF_MAKE_NONCOPYABLE(SoftwareTextureCopier);
79 public:
80 static PassOwnPtr<SoftwareTextureCopier> create()
81 {
82 return adoptPtr(new SoftwareTextureCopier());
83 }
84 virtual void copyTexture(TextureCopier::Parameters) OVERRIDE { /* FIXME */ }
85 virtual void flush() OVERRIDE { }
86
87 private:
88 SoftwareTextureCopier() { }
89 };
90
91 } // anonymous namespace
92
93 PassOwnPtr<CCRendererSoftware> CCRendererSoftware::create(CCRendererClient* clie nt, CCResourceProvider* resourceProvider, WebCompositorSoftwareOutputDevice* out putDevice)
94 {
95 return adoptPtr(new CCRendererSoftware(client, resourceProvider, outputDevic e));
96 }
97
98 CCRendererSoftware::CCRendererSoftware(CCRendererClient* client, CCResourceProvi der* resourceProvider, WebCompositorSoftwareOutputDevice* outputDevice)
99 : CCDirectRenderer(client, resourceProvider)
100 , m_visible(true)
101 , m_textureCopier(SoftwareTextureCopier::create())
102 , m_textureUploader(UnthrottledTextureUploader::create())
103 , m_outputDevice(outputDevice)
104 , m_skRootCanvas(0)
105 , m_skCurrentCanvas(0)
106 {
107 m_resourceProvider->setDefaultResourceType(CCResourceProvider::Bitmap);
108
109 m_capabilities.maxTextureSize = INT_MAX;
110 m_capabilities.bestTextureFormat = GraphicsContext3D::RGBA;
111 m_capabilities.contextHasCachedFrontBuffer = true;
112 m_capabilities.usingSetVisibility = true;
113
114 viewportChanged();
115 }
116
117 CCRendererSoftware::~CCRendererSoftware()
118 {
119 }
120
121 void CCRendererSoftware::viewportChanged()
122 {
123 m_outputDevice->didChangeViewportSize(WebSize(viewportSize().width(), viewpo rtSize().height()));
danakj 2012/09/19 18:35:14 How come the software renderer needs a call like t
aelias_OOO_until_Jul13 2012/09/19 19:58:27 For the test harness and GL adapter, they need to
danakj 2012/09/19 20:06:18 I see, thanks.
124 }
125
126 void CCRendererSoftware::beginDrawingFrame(DrawingFrame& frame)
127 {
128 m_skRootCanvas.setBitmapDevice(m_outputDevice->lock(true)->getSkBitmap());
129 }
130
131 void CCRendererSoftware::finishDrawingFrame(DrawingFrame& frame)
132 {
133 m_currentFramebufferLock.clear();
134 m_skCurrentCanvas = 0;
135 m_skRootCanvas.setDevice(0);
136 m_outputDevice->unlock();
137 }
138
139 void CCRendererSoftware::finish()
140 {
141 }
142
143 void CCRendererSoftware::bindFramebufferToOutputSurface(DrawingFrame& frame)
144 {
145 m_currentFramebufferLock.clear();
146 m_skCurrentCanvas = &m_skRootCanvas;
147 }
148
149 bool CCRendererSoftware::bindFramebufferToTexture(DrawingFrame& frame, const CCS copedTexture* texture, const IntRect& framebufferRect)
150 {
151 m_currentFramebufferLock = adoptPtr(new CCResourceProvider::ScopedWriteLockS oftware(m_resourceProvider, texture->id()));
152 m_skCurrentCanvas = m_currentFramebufferLock->skCanvas();
153 initializeMatrices(frame, framebufferRect, false);
154 setDrawViewportSize(framebufferRect.size());
155
156 return true;
157 }
158
159 void CCRendererSoftware::enableScissorTestRect(const IntRect& scissorRect)
160 {
161 m_skCurrentCanvas->clipRect(toSkRect(scissorRect), SkRegion::kReplace_Op);
162 }
163
164 void CCRendererSoftware::disableScissorTest()
165 {
166 IntRect canvasRect(IntPoint(), viewportSize());
167 m_skCurrentCanvas->clipRect(toSkRect(canvasRect), SkRegion::kReplace_Op);
168 }
169
170 void CCRendererSoftware::clearFramebuffer(DrawingFrame& frame)
171 {
172 m_skCurrentCanvas->clear(SK_ColorGREEN);
173 }
174
175 void CCRendererSoftware::setDrawViewportSize(const IntSize& viewportSize)
176 {
177 }
178
179 bool CCRendererSoftware::isSoftwareResource(CCResourceProvider::ResourceId id) c onst
180 {
181 switch (m_resourceProvider->resourceType(id)) {
182 case CCResourceProvider::GLTexture:
183 return false;
184 case CCResourceProvider::Bitmap:
185 return true;
186 }
187
188 CRASH();
189 return false;
190 }
191
192 void CCRendererSoftware::drawQuad(DrawingFrame& frame, const CCDrawQuad* quad)
193 {
194 WebTransformationMatrix quadRectMatrix;
195 quadRectTransform(&quadRectMatrix, quad->quadTransform(), quad->quadRect());
196 WebTransformationMatrix windowMatrix = frame.windowMatrix * frame.projection Matrix * quadRectMatrix;
197 SkMatrix skWindowMatrix;
198 toSkMatrix(&skWindowMatrix, windowMatrix);
199 m_skCurrentCanvas->setMatrix(skWindowMatrix);
200
201 m_skCurrentPaint.reset();
202 if (quad->needsBlending())
203 m_skCurrentPaint.setAlpha(quad->opacity() * 255);
204 else
205 m_skCurrentPaint.setXfermodeMode(SkXfermode::kSrc_Mode);
206
207 switch (quad->material()) {
208 case CCDrawQuad::DebugBorder:
209 drawDebugBorderQuad(frame, CCDebugBorderDrawQuad::materialCast(quad));
210 break;
211 case CCDrawQuad::SolidColor:
212 drawSolidColorQuad(frame, CCSolidColorDrawQuad::materialCast(quad));
213 break;
214 case CCDrawQuad::TextureContent:
215 drawTextureQuad(frame, CCTextureDrawQuad::materialCast(quad));
216 break;
217 case CCDrawQuad::TiledContent:
218 drawTileQuad(frame, CCTileDrawQuad::materialCast(quad));
219 break;
220 default:
221 drawUnsupportedQuad(frame, quad);
222 break;
223 }
224
225 m_skCurrentCanvas->resetMatrix();
226 }
227
228 void CCRendererSoftware::drawDebugBorderQuad(const DrawingFrame& frame, const CC DebugBorderDrawQuad* quad)
229 {
230 // We need to apply the matrix manually to have pixel-sized stroke width.
231 SkPoint vertices[4];
232 toSkRect(quadVertexRect()).toQuad(vertices);
233 SkPoint transformedVertices[4];
234 m_skCurrentCanvas->getTotalMatrix().mapPoints(transformedVertices, vertices, 4);
235 m_skCurrentCanvas->resetMatrix();
236
237 m_skCurrentPaint.setColor(quad->color());
238 m_skCurrentPaint.setAlpha(quad->opacity() * SkColorGetA(quad->color()));
239 m_skCurrentPaint.setStyle(SkPaint::kStroke_Style);
240 m_skCurrentPaint.setStrokeWidth(quad->width());
241 m_skCurrentCanvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, transformedVe rtices, m_skCurrentPaint);
242 }
243
244 void CCRendererSoftware::drawSolidColorQuad(const DrawingFrame& frame, const CCS olidColorDrawQuad* quad)
245 {
246 m_skCurrentPaint.setColor(quad->color());
247 m_skCurrentPaint.setAlpha(quad->opacity() * SkColorGetA(quad->color()));
248 m_skCurrentCanvas->drawRect(toSkRect(quadVertexRect()), m_skCurrentPaint);
249 }
250
251 void CCRendererSoftware::drawTextureQuad(const DrawingFrame& frame, const CCText ureDrawQuad* quad)
252 {
253 if (!isSoftwareResource(quad->resourceId())) {
254 drawUnsupportedQuad(frame, quad);
255 return;
256 }
257
258 // FIXME: Add support for non-premultiplied alpha.
danakj 2012/09/19 18:35:14 Do you want an assert quad->premultipliedAlpha() o
259 CCResourceProvider::ScopedReadLockSoftware quadResourceLock(m_resourceProvid er, quad->resourceId());
260 FloatRect uvRect = quad->uvRect();
261 uvRect.scale(quad->quadRect().width(), quad->quadRect().height());
262 SkIRect skUvRect = toSkIRect(enclosingIntRect(uvRect));
263 if (quad->flipped())
264 m_skCurrentCanvas->scale(1, -1);
265 m_skCurrentCanvas->drawBitmapRect(*quadResourceLock.skBitmap(), &skUvRect, t oSkRect(quadVertexRect()), &m_skCurrentPaint);
266 }
267
268 void CCRendererSoftware::drawTileQuad(const DrawingFrame& frame, const CCTileDra wQuad* quad)
269 {
270 ASSERT(isSoftwareResource(quad->resourceId()));
271 CCResourceProvider::ScopedReadLockSoftware quadResourceLock(m_resourceProvid er, quad->resourceId());
272
273 SkIRect uvRect = toSkIRect(IntRect(quad->textureOffset(), quad->quadRect().s ize()));
274 m_skCurrentCanvas->drawBitmapRect(*quadResourceLock.skBitmap(), &uvRect, toS kRect(quadVertexRect()), &m_skCurrentPaint);
275 }
276
277 void CCRendererSoftware::drawUnsupportedQuad(const DrawingFrame& frame, const CC DrawQuad* quad)
278 {
279 m_skCurrentPaint.setColor(SK_ColorMAGENTA);
280 m_skCurrentPaint.setAlpha(quad->opacity() * 255);
281 m_skCurrentCanvas->drawRect(toSkRect(quadVertexRect()), m_skCurrentPaint);
282 }
283
284 bool CCRendererSoftware::swapBuffers()
285 {
286 if (CCProxy::hasImplThread())
287 m_client->onSwapBuffersComplete();
288 return true;
289 }
290
291 void CCRendererSoftware::getFramebufferPixels(void *pixels, const IntRect& rect)
292 {
293 SkBitmap fullBitmap = m_outputDevice->lock(false)->getSkBitmap();
294 SkBitmap subsetBitmap;
295 SkIRect invertRect = SkIRect::MakeXYWH(rect.x(), viewportSize().height() - r ect.maxY(), rect.width(), rect.height());
296 fullBitmap.extractSubset(&subsetBitmap, invertRect);
297 subsetBitmap.copyPixelsTo(pixels, rect.width() * rect.height() * 4, rect.wid th() * 4);
298 m_outputDevice->unlock();
299 }
300
301 void CCRendererSoftware::setVisible(bool visible)
302 {
303 if (m_visible == visible)
304 return;
305 m_visible = visible;
306 }
307
308 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698