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