Chromium Code Reviews| 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 |