blob: 2ec35d0a3932fc9b934c101d3f61f20535d17dee [file] [log] [blame]
[email protected]d61675de42012-09-24 21:32:571// 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
[email protected]c4040a522012-10-21 15:01:405#include "cc/software_renderer.h"
[email protected]d61675de42012-09-24 21:32:576
[email protected]ffbfdc492012-11-15 03:35:327#include "base/debug/trace_event.h"
[email protected]aa0a9d32012-10-24 01:58:108#include "cc/debug_border_draw_quad.h"
[email protected]55a124d02012-10-22 03:07:139#include "cc/render_pass_draw_quad.h"
[email protected]4456eee22012-10-19 18:16:3810#include "cc/solid_color_draw_quad.h"
11#include "cc/texture_draw_quad.h"
[email protected]da2c9122012-10-20 23:13:0612#include "cc/tile_draw_quad.h"
[email protected]0b056ee2012-10-15 21:31:2113#include "third_party/skia/include/core/SkCanvas.h"
14#include "third_party/skia/include/core/SkColor.h"
15#include "third_party/skia/include/core/SkMatrix.h"
16#include "third_party/skia/include/core/SkShader.h"
17#include "third_party/skia/include/effects/SkLayerRasterizer.h"
[email protected]1fea8142012-10-20 04:12:4118#include "ui/gfx/rect_conversions.h"
[email protected]79fbdab02012-11-14 07:28:1119#include "ui/gfx/skia_util.h"
[email protected]59cb7b352012-10-30 06:45:4820#include <public/WebCompositorSoftwareOutputDevice.h>
[email protected]d61675de42012-09-24 21:32:5721#include <public/WebImage.h>
22#include <public/WebSize.h>
23#include <public/WebTransformationMatrix.h>
24
25using WebKit::WebCompositorSoftwareOutputDevice;
[email protected]d61675de42012-09-24 21:32:5726using WebKit::WebSize;
27using WebKit::WebTransformationMatrix;
28
29namespace cc {
30
31namespace {
32
[email protected]d61675de42012-09-24 21:32:5733void toSkMatrix(SkMatrix* flattened, const WebTransformationMatrix& m)
34{
35 // Convert from 4x4 to 3x3 by dropping the third row and column.
[email protected]79fbdab02012-11-14 07:28:1136 flattened->set(0, SkDoubleToScalar(m.m11()));
37 flattened->set(1, SkDoubleToScalar(m.m21()));
38 flattened->set(2, SkDoubleToScalar(m.m41()));
39 flattened->set(3, SkDoubleToScalar(m.m12()));
40 flattened->set(4, SkDoubleToScalar(m.m22()));
41 flattened->set(5, SkDoubleToScalar(m.m42()));
42 flattened->set(6, SkDoubleToScalar(m.m14()));
43 flattened->set(7, SkDoubleToScalar(m.m24()));
44 flattened->set(8, SkDoubleToScalar(m.m44()));
[email protected]d61675de42012-09-24 21:32:5745}
46
[email protected]276508a2012-10-16 00:56:3447bool isScaleAndTranslate(const SkMatrix& matrix)
48{
49 return SkScalarNearlyZero(matrix[SkMatrix::kMSkewX]) &&
50 SkScalarNearlyZero(matrix[SkMatrix::kMSkewY]) &&
51 SkScalarNearlyZero(matrix[SkMatrix::kMPersp0]) &&
52 SkScalarNearlyZero(matrix[SkMatrix::kMPersp1]) &&
53 SkScalarNearlyZero(matrix[SkMatrix::kMPersp2] - 1.0f);
54}
55
[email protected]d61675de42012-09-24 21:32:5756} // anonymous namespace
57
[email protected]96baf3e2012-10-22 23:09:5558scoped_ptr<SoftwareRenderer> SoftwareRenderer::create(RendererClient* client, ResourceProvider* resourceProvider, WebCompositorSoftwareOutputDevice* outputDevice)
[email protected]d61675de42012-09-24 21:32:5759{
[email protected]96baf3e2012-10-22 23:09:5560 return make_scoped_ptr(new SoftwareRenderer(client, resourceProvider, outputDevice));
[email protected]d61675de42012-09-24 21:32:5761}
62
[email protected]96baf3e2012-10-22 23:09:5563SoftwareRenderer::SoftwareRenderer(RendererClient* client, ResourceProvider* resourceProvider, WebCompositorSoftwareOutputDevice* outputDevice)
64 : DirectRenderer(client, resourceProvider)
[email protected]d61675de42012-09-24 21:32:5765 , m_visible(true)
66 , m_outputDevice(outputDevice)
[email protected]d61675de42012-09-24 21:32:5767 , m_skCurrentCanvas(0)
68{
[email protected]96baf3e2012-10-22 23:09:5569 m_resourceProvider->setDefaultResourceType(ResourceProvider::Bitmap);
[email protected]d61675de42012-09-24 21:32:5770
71 m_capabilities.maxTextureSize = INT_MAX;
[email protected]d9c28522012-10-18 23:35:4372 m_capabilities.bestTextureFormat = GL_RGBA;
[email protected]d61675de42012-09-24 21:32:5773 m_capabilities.contextHasCachedFrontBuffer = true;
74 m_capabilities.usingSetVisibility = true;
75
76 viewportChanged();
77}
78
[email protected]96baf3e2012-10-22 23:09:5579SoftwareRenderer::~SoftwareRenderer()
[email protected]d61675de42012-09-24 21:32:5780{
81}
82
[email protected]96baf3e2012-10-22 23:09:5583const RendererCapabilities& SoftwareRenderer::capabilities() const
[email protected]d61675de42012-09-24 21:32:5784{
85 return m_capabilities;
86}
87
[email protected]96baf3e2012-10-22 23:09:5588void SoftwareRenderer::viewportChanged()
[email protected]d61675de42012-09-24 21:32:5789{
90 m_outputDevice->didChangeViewportSize(WebSize(viewportSize().width(), viewportSize().height()));
91}
92
[email protected]96baf3e2012-10-22 23:09:5593void SoftwareRenderer::beginDrawingFrame(DrawingFrame& frame)
[email protected]d61675de42012-09-24 21:32:5794{
[email protected]ffbfdc492012-11-15 03:35:3295 TRACE_EVENT0("cc", "SoftwareRenderer::beginDrawingFrame");
[email protected]0704caf2012-10-16 03:39:4796 m_skRootCanvas = make_scoped_ptr(new SkCanvas(m_outputDevice->lock(true)->getSkBitmap()));
[email protected]d61675de42012-09-24 21:32:5797}
98
[email protected]96baf3e2012-10-22 23:09:5599void SoftwareRenderer::finishDrawingFrame(DrawingFrame& frame)
[email protected]d61675de42012-09-24 21:32:57100{
[email protected]ffbfdc492012-11-15 03:35:32101 TRACE_EVENT0("cc", "SoftwareRenderer::finishDrawingFrame");
[email protected]0704caf2012-10-16 03:39:47102 m_currentFramebufferLock.reset();
[email protected]d61675de42012-09-24 21:32:57103 m_skCurrentCanvas = 0;
[email protected]0704caf2012-10-16 03:39:47104 m_skRootCanvas.reset();
[email protected]d61675de42012-09-24 21:32:57105 m_outputDevice->unlock();
106}
107
[email protected]96baf3e2012-10-22 23:09:55108bool SoftwareRenderer::flippedFramebuffer() const
[email protected]d61675de42012-09-24 21:32:57109{
110 return false;
111}
112
[email protected]96baf3e2012-10-22 23:09:55113void SoftwareRenderer::finish()
[email protected]d61675de42012-09-24 21:32:57114{
115}
116
[email protected]96baf3e2012-10-22 23:09:55117void SoftwareRenderer::bindFramebufferToOutputSurface(DrawingFrame& frame)
[email protected]d61675de42012-09-24 21:32:57118{
[email protected]0704caf2012-10-16 03:39:47119 m_currentFramebufferLock.reset();
[email protected]75fe7f822012-09-28 17:54:14120 m_skCurrentCanvas = m_skRootCanvas.get();
[email protected]d61675de42012-09-24 21:32:57121}
122
[email protected]f7685bc2012-11-08 17:32:33123bool SoftwareRenderer::bindFramebufferToTexture(DrawingFrame& frame, const ScopedResource* texture, const gfx::Rect& framebufferRect)
[email protected]d61675de42012-09-24 21:32:57124{
[email protected]96baf3e2012-10-22 23:09:55125 m_currentFramebufferLock = make_scoped_ptr(new ResourceProvider::ScopedWriteLockSoftware(m_resourceProvider, texture->id()));
[email protected]d61675de42012-09-24 21:32:57126 m_skCurrentCanvas = m_currentFramebufferLock->skCanvas();
127 initializeMatrices(frame, framebufferRect, false);
128 setDrawViewportSize(framebufferRect.size());
129
130 return true;
131}
132
[email protected]7ead0932012-11-08 07:46:52133void SoftwareRenderer::setScissorTestRect(const gfx::Rect& scissorRect)
[email protected]d61675de42012-09-24 21:32:57134{
[email protected]79fbdab02012-11-14 07:28:11135 m_skCurrentCanvas->clipRect(gfx::RectToSkRect(scissorRect), SkRegion::kReplace_Op);
[email protected]d61675de42012-09-24 21:32:57136}
137
[email protected]96baf3e2012-10-22 23:09:55138void SoftwareRenderer::clearFramebuffer(DrawingFrame& frame)
[email protected]d61675de42012-09-24 21:32:57139{
[email protected]0b056ee2012-10-15 21:31:21140 if (frame.currentRenderPass->hasTransparentBackground()) {
141 m_skCurrentCanvas->clear(SkColorSetARGB(0, 0, 0, 0));
142 } else {
143#ifndef NDEBUG
144 // On DEBUG builds, opaque render passes are cleared to blue to easily see regions that were not drawn on the screen.
145 m_skCurrentCanvas->clear(SkColorSetARGB(255, 0, 0, 255));
146#endif
147 }
[email protected]d61675de42012-09-24 21:32:57148}
149
[email protected]96baf3e2012-10-22 23:09:55150void SoftwareRenderer::setDrawViewportSize(const gfx::Size& viewportSize)
[email protected]d61675de42012-09-24 21:32:57151{
152}
153
[email protected]96baf3e2012-10-22 23:09:55154bool SoftwareRenderer::isSoftwareResource(ResourceProvider::ResourceId id) const
[email protected]d61675de42012-09-24 21:32:57155{
156 switch (m_resourceProvider->resourceType(id)) {
[email protected]96baf3e2012-10-22 23:09:55157 case ResourceProvider::GLTexture:
[email protected]d61675de42012-09-24 21:32:57158 return false;
[email protected]96baf3e2012-10-22 23:09:55159 case ResourceProvider::Bitmap:
[email protected]d61675de42012-09-24 21:32:57160 return true;
161 }
162
[email protected]6eb6bb62012-11-10 06:30:59163 LOG(FATAL) << "Invalid resource type.";
[email protected]d61675de42012-09-24 21:32:57164 return false;
165}
166
[email protected]96baf3e2012-10-22 23:09:55167void SoftwareRenderer::drawQuad(DrawingFrame& frame, const DrawQuad* quad)
[email protected]d61675de42012-09-24 21:32:57168{
[email protected]ffbfdc492012-11-15 03:35:32169 TRACE_EVENT0("cc", "SoftwareRenderer::drawQuad");
[email protected]d61675de42012-09-24 21:32:57170 WebTransformationMatrix quadRectMatrix;
[email protected]9cd20a32012-11-17 14:11:27171 quadRectTransform(&quadRectMatrix, quad->quadTransform(), quad->rect());
[email protected]0b056ee2012-10-15 21:31:21172 WebTransformationMatrix contentsDeviceTransform = (frame.windowMatrix * frame.projectionMatrix * quadRectMatrix).to2dTransform();
173 SkMatrix skDeviceMatrix;
174 toSkMatrix(&skDeviceMatrix, contentsDeviceTransform);
175 m_skCurrentCanvas->setMatrix(skDeviceMatrix);
[email protected]d61675de42012-09-24 21:32:57176
177 m_skCurrentPaint.reset();
[email protected]276508a2012-10-16 00:56:34178 if (!isScaleAndTranslate(skDeviceMatrix)) {
179 m_skCurrentPaint.setAntiAlias(true);
180 m_skCurrentPaint.setFilterBitmap(true);
181 }
[email protected]9cd20a32012-11-17 14:11:27182
183 if (quad->ShouldDrawWithBlending()) {
[email protected]d61675de42012-09-24 21:32:57184 m_skCurrentPaint.setAlpha(quad->opacity() * 255);
[email protected]0b056ee2012-10-15 21:31:21185 m_skCurrentPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
186 } else {
[email protected]d61675de42012-09-24 21:32:57187 m_skCurrentPaint.setXfermodeMode(SkXfermode::kSrc_Mode);
[email protected]0b056ee2012-10-15 21:31:21188 }
[email protected]d61675de42012-09-24 21:32:57189
190 switch (quad->material()) {
[email protected]e48727e2012-11-16 22:10:02191 case DrawQuad::DEBUG_BORDER:
[email protected]96baf3e2012-10-22 23:09:55192 drawDebugBorderQuad(frame, DebugBorderDrawQuad::materialCast(quad));
[email protected]d61675de42012-09-24 21:32:57193 break;
[email protected]e48727e2012-11-16 22:10:02194 case DrawQuad::SOLID_COLOR:
[email protected]96baf3e2012-10-22 23:09:55195 drawSolidColorQuad(frame, SolidColorDrawQuad::materialCast(quad));
[email protected]d61675de42012-09-24 21:32:57196 break;
[email protected]e48727e2012-11-16 22:10:02197 case DrawQuad::TEXTURE_CONTENT:
[email protected]96baf3e2012-10-22 23:09:55198 drawTextureQuad(frame, TextureDrawQuad::materialCast(quad));
[email protected]d61675de42012-09-24 21:32:57199 break;
[email protected]e48727e2012-11-16 22:10:02200 case DrawQuad::TILED_CONTENT:
[email protected]96baf3e2012-10-22 23:09:55201 drawTileQuad(frame, TileDrawQuad::materialCast(quad));
[email protected]d61675de42012-09-24 21:32:57202 break;
[email protected]e48727e2012-11-16 22:10:02203 case DrawQuad::RENDER_PASS:
[email protected]96baf3e2012-10-22 23:09:55204 drawRenderPassQuad(frame, RenderPassDrawQuad::materialCast(quad));
[email protected]0b056ee2012-10-15 21:31:21205 break;
[email protected]d61675de42012-09-24 21:32:57206 default:
207 drawUnsupportedQuad(frame, quad);
208 break;
209 }
210
211 m_skCurrentCanvas->resetMatrix();
212}
213
[email protected]96baf3e2012-10-22 23:09:55214void SoftwareRenderer::drawDebugBorderQuad(const DrawingFrame& frame, const DebugBorderDrawQuad* quad)
[email protected]d61675de42012-09-24 21:32:57215{
216 // We need to apply the matrix manually to have pixel-sized stroke width.
217 SkPoint vertices[4];
[email protected]79fbdab02012-11-14 07:28:11218 gfx::RectFToSkRect(quadVertexRect()).toQuad(vertices);
[email protected]d61675de42012-09-24 21:32:57219 SkPoint transformedVertices[4];
220 m_skCurrentCanvas->getTotalMatrix().mapPoints(transformedVertices, vertices, 4);
221 m_skCurrentCanvas->resetMatrix();
222
223 m_skCurrentPaint.setColor(quad->color());
224 m_skCurrentPaint.setAlpha(quad->opacity() * SkColorGetA(quad->color()));
225 m_skCurrentPaint.setStyle(SkPaint::kStroke_Style);
226 m_skCurrentPaint.setStrokeWidth(quad->width());
227 m_skCurrentCanvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, transformedVertices, m_skCurrentPaint);
228}
229
[email protected]96baf3e2012-10-22 23:09:55230void SoftwareRenderer::drawSolidColorQuad(const DrawingFrame& frame, const SolidColorDrawQuad* quad)
[email protected]d61675de42012-09-24 21:32:57231{
232 m_skCurrentPaint.setColor(quad->color());
233 m_skCurrentPaint.setAlpha(quad->opacity() * SkColorGetA(quad->color()));
[email protected]79fbdab02012-11-14 07:28:11234 m_skCurrentCanvas->drawRect(gfx::RectFToSkRect(quadVertexRect()), m_skCurrentPaint);
[email protected]d61675de42012-09-24 21:32:57235}
236
[email protected]96baf3e2012-10-22 23:09:55237void SoftwareRenderer::drawTextureQuad(const DrawingFrame& frame, const TextureDrawQuad* quad)
[email protected]d61675de42012-09-24 21:32:57238{
239 if (!isSoftwareResource(quad->resourceId())) {
240 drawUnsupportedQuad(frame, quad);
241 return;
242 }
243
244 // FIXME: Add support for non-premultiplied alpha.
[email protected]058a724a2012-10-30 18:37:02245 ResourceProvider::ScopedReadLockSoftware lock(m_resourceProvider, quad->resourceId());
246 const SkBitmap* bitmap = lock.skBitmap();
[email protected]59cb7b352012-10-30 06:45:48247 gfx::RectF uvRect = gfx::ScaleRect(quad->uvRect(), bitmap->width(), bitmap->height());
[email protected]79fbdab02012-11-14 07:28:11248 SkRect skUvRect = gfx::RectFToSkRect(uvRect);
[email protected]d61675de42012-09-24 21:32:57249 if (quad->flipped())
250 m_skCurrentCanvas->scale(1, -1);
[email protected]66dce292012-11-06 09:12:00251 m_skCurrentCanvas->drawBitmapRectToRect(*bitmap, &skUvRect,
[email protected]79fbdab02012-11-14 07:28:11252 gfx::RectFToSkRect(quadVertexRect()),
[email protected]66dce292012-11-06 09:12:00253 &m_skCurrentPaint);
[email protected]d61675de42012-09-24 21:32:57254}
255
[email protected]96baf3e2012-10-22 23:09:55256void SoftwareRenderer::drawTileQuad(const DrawingFrame& frame, const TileDrawQuad* quad)
[email protected]d61675de42012-09-24 21:32:57257{
[email protected]1d993172012-10-18 18:15:04258 DCHECK(isSoftwareResource(quad->resourceId()));
[email protected]058a724a2012-10-30 18:37:02259 ResourceProvider::ScopedReadLockSoftware lock(m_resourceProvider, quad->resourceId());
[email protected]d61675de42012-09-24 21:32:57260
[email protected]66dce292012-11-06 09:12:00261 SkRect uvRect = SkRect::MakeXYWH(
262 quad->textureOffset().x(), quad->textureOffset().y(),
[email protected]9cd20a32012-11-17 14:11:27263 quad->rect().width(), quad->rect().height());
[email protected]0457b7502012-11-13 21:48:42264 m_skCurrentPaint.setFilterBitmap(true);
[email protected]66dce292012-11-06 09:12:00265 m_skCurrentCanvas->drawBitmapRectToRect(*lock.skBitmap(), &uvRect,
[email protected]79fbdab02012-11-14 07:28:11266 gfx::RectFToSkRect(quadVertexRect()),
[email protected]66dce292012-11-06 09:12:00267 &m_skCurrentPaint);
[email protected]d61675de42012-09-24 21:32:57268}
269
[email protected]96baf3e2012-10-22 23:09:55270void SoftwareRenderer::drawRenderPassQuad(const DrawingFrame& frame, const RenderPassDrawQuad* quad)
[email protected]0b056ee2012-10-15 21:31:21271{
[email protected]f7685bc2012-11-08 17:32:33272 CachedResource* contentTexture = m_renderPassTextures.get(quad->renderPassId());
[email protected]058a724a2012-10-30 18:37:02273 if (!contentTexture || !contentTexture->id())
[email protected]0b056ee2012-10-15 21:31:21274 return;
275
[email protected]632bd7662012-11-14 21:21:54276 const RenderPass* renderPass = frame.renderPassesById->get(quad->renderPassId());
277 DCHECK(renderPass);
278 if (!renderPass)
279 return;
280
[email protected]058a724a2012-10-30 18:37:02281 DCHECK(isSoftwareResource(contentTexture->id()));
282 ResourceProvider::ScopedReadLockSoftware lock(m_resourceProvider, contentTexture->id());
[email protected]0b056ee2012-10-15 21:31:21283
[email protected]79fbdab02012-11-14 07:28:11284 SkRect destRect = gfx::RectFToSkRect(quadVertexRect());
[email protected]0b056ee2012-10-15 21:31:21285
[email protected]058a724a2012-10-30 18:37:02286 const SkBitmap* content = lock.skBitmap();
[email protected]0b056ee2012-10-15 21:31:21287
[email protected]058a724a2012-10-30 18:37:02288 SkRect contentRect;
289 content->getBounds(&contentRect);
290
291 SkMatrix contentMat;
292 contentMat.setRectToRect(contentRect, destRect, SkMatrix::kFill_ScaleToFit);
293
294 SkAutoTUnref<SkShader> shader(SkShader::CreateBitmapShader(*content,
[email protected]0b056ee2012-10-15 21:31:21295 SkShader::kClamp_TileMode,
296 SkShader::kClamp_TileMode));
[email protected]058a724a2012-10-30 18:37:02297 shader->setLocalMatrix(contentMat);
[email protected]0b056ee2012-10-15 21:31:21298 m_skCurrentPaint.setShader(shader);
299
[email protected]632bd7662012-11-14 21:21:54300 SkImageFilter* filter = renderPass->filter();
301 if (filter)
302 m_skCurrentPaint.setImageFilter(filter);
303
[email protected]0b056ee2012-10-15 21:31:21304 if (quad->maskResourceId()) {
[email protected]058a724a2012-10-30 18:37:02305 ResourceProvider::ScopedReadLockSoftware maskLock(m_resourceProvider, quad->maskResourceId());
306
307 const SkBitmap* mask = maskLock.skBitmap();
308
309 SkRect maskRect = SkRect::MakeXYWH(
310 quad->maskTexCoordOffsetX() * mask->width(),
311 quad->maskTexCoordOffsetY() * mask->height(),
312 quad->maskTexCoordScaleX() * mask->width(),
313 quad->maskTexCoordScaleY() * mask->height());
[email protected]0b056ee2012-10-15 21:31:21314
315 SkMatrix maskMat;
[email protected]058a724a2012-10-30 18:37:02316 maskMat.setRectToRect(maskRect, destRect, SkMatrix::kFill_ScaleToFit);
[email protected]0b056ee2012-10-15 21:31:21317
[email protected]058a724a2012-10-30 18:37:02318 SkAutoTUnref<SkShader> maskShader(SkShader::CreateBitmapShader(*mask,
[email protected]0b056ee2012-10-15 21:31:21319 SkShader::kClamp_TileMode,
320 SkShader::kClamp_TileMode));
321 maskShader->setLocalMatrix(maskMat);
322
323 SkPaint maskPaint;
324 maskPaint.setShader(maskShader);
325
326 SkAutoTUnref<SkLayerRasterizer> maskRasterizer(new SkLayerRasterizer);
327 maskRasterizer->addLayer(maskPaint);
328
329 m_skCurrentPaint.setRasterizer(maskRasterizer);
330 m_skCurrentCanvas->drawRect(destRect, m_skCurrentPaint);
331 } else {
[email protected]058a724a2012-10-30 18:37:02332 // FIXME: Apply background filters and blend with content
[email protected]0b056ee2012-10-15 21:31:21333 m_skCurrentCanvas->drawRect(destRect, m_skCurrentPaint);
334 }
335}
336
[email protected]96baf3e2012-10-22 23:09:55337void SoftwareRenderer::drawUnsupportedQuad(const DrawingFrame& frame, const DrawQuad* quad)
[email protected]d61675de42012-09-24 21:32:57338{
339 m_skCurrentPaint.setColor(SK_ColorMAGENTA);
340 m_skCurrentPaint.setAlpha(quad->opacity() * 255);
[email protected]79fbdab02012-11-14 07:28:11341 m_skCurrentCanvas->drawRect(gfx::RectFToSkRect(quadVertexRect()), m_skCurrentPaint);
[email protected]d61675de42012-09-24 21:32:57342}
343
[email protected]96baf3e2012-10-22 23:09:55344bool SoftwareRenderer::swapBuffers()
[email protected]d61675de42012-09-24 21:32:57345{
[email protected]61de5812012-11-08 07:03:44346 if (m_client->hasImplThread())
[email protected]d61675de42012-09-24 21:32:57347 m_client->onSwapBuffersComplete();
348 return true;
349}
350
[email protected]aad0a0072012-11-01 18:15:58351void SoftwareRenderer::getFramebufferPixels(void *pixels, const gfx::Rect& rect)
[email protected]d61675de42012-09-24 21:32:57352{
[email protected]ffbfdc492012-11-15 03:35:32353 TRACE_EVENT0("cc", "SoftwareRenderer::getFramebufferPixels");
[email protected]d61675de42012-09-24 21:32:57354 SkBitmap fullBitmap = m_outputDevice->lock(false)->getSkBitmap();
355 SkBitmap subsetBitmap;
[email protected]aad0a0072012-11-01 18:15:58356 SkIRect invertRect = SkIRect::MakeXYWH(rect.x(), viewportSize().height() - rect.bottom(), rect.width(), rect.height());
[email protected]d61675de42012-09-24 21:32:57357 fullBitmap.extractSubset(&subsetBitmap, invertRect);
358 subsetBitmap.copyPixelsTo(pixels, rect.width() * rect.height() * 4, rect.width() * 4);
359 m_outputDevice->unlock();
360}
361
[email protected]96baf3e2012-10-22 23:09:55362void SoftwareRenderer::setVisible(bool visible)
[email protected]d61675de42012-09-24 21:32:57363{
364 if (m_visible == visible)
365 return;
366 m_visible = visible;
367}
368
[email protected]bc5e77c2012-11-05 20:00:49369} // namespace cc