| 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 |