blob: 58c54253f443409f29285f6f0676b889135335c1 [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]dc462d782012-11-21 21:43:01113void SoftwareRenderer::ensureScissorTestEnabled()
114{
115 // Nothing to do here. Current implementation of software rendering has no
116 // notion of enabling/disabling the feature.
117}
118
119void SoftwareRenderer::ensureScissorTestDisabled()
120{
121 // There is no explicit notion of enabling/disabling scissoring in software
122 // rendering, but the underlying effect we want is to clear any existing
123 // clipRect on the current SkCanvas. This is done by setting clipRect to
124 // the viewport's dimensions.
125 SkISize canvasSize = m_skCurrentCanvas->getDeviceSize();
126 SkRect canvasRect = SkRect::MakeXYWH(0, 0, canvasSize.width(), canvasSize.height());
127 m_skCurrentCanvas->clipRect(canvasRect, SkRegion::kReplace_Op);
128}
129
[email protected]96baf3e2012-10-22 23:09:55130void SoftwareRenderer::finish()
[email protected]d61675de42012-09-24 21:32:57131{
132}
133
[email protected]96baf3e2012-10-22 23:09:55134void SoftwareRenderer::bindFramebufferToOutputSurface(DrawingFrame& frame)
[email protected]d61675de42012-09-24 21:32:57135{
[email protected]0704caf2012-10-16 03:39:47136 m_currentFramebufferLock.reset();
[email protected]75fe7f822012-09-28 17:54:14137 m_skCurrentCanvas = m_skRootCanvas.get();
[email protected]d61675de42012-09-24 21:32:57138}
139
[email protected]f7685bc2012-11-08 17:32:33140bool SoftwareRenderer::bindFramebufferToTexture(DrawingFrame& frame, const ScopedResource* texture, const gfx::Rect& framebufferRect)
[email protected]d61675de42012-09-24 21:32:57141{
[email protected]96baf3e2012-10-22 23:09:55142 m_currentFramebufferLock = make_scoped_ptr(new ResourceProvider::ScopedWriteLockSoftware(m_resourceProvider, texture->id()));
[email protected]d61675de42012-09-24 21:32:57143 m_skCurrentCanvas = m_currentFramebufferLock->skCanvas();
144 initializeMatrices(frame, framebufferRect, false);
145 setDrawViewportSize(framebufferRect.size());
146
147 return true;
148}
149
[email protected]7ead0932012-11-08 07:46:52150void SoftwareRenderer::setScissorTestRect(const gfx::Rect& scissorRect)
[email protected]d61675de42012-09-24 21:32:57151{
[email protected]79fbdab02012-11-14 07:28:11152 m_skCurrentCanvas->clipRect(gfx::RectToSkRect(scissorRect), SkRegion::kReplace_Op);
[email protected]d61675de42012-09-24 21:32:57153}
154
[email protected]96baf3e2012-10-22 23:09:55155void SoftwareRenderer::clearFramebuffer(DrawingFrame& frame)
[email protected]d61675de42012-09-24 21:32:57156{
[email protected]f57bbc02012-11-21 07:02:15157 if (frame.currentRenderPass->has_transparent_background) {
[email protected]0b056ee2012-10-15 21:31:21158 m_skCurrentCanvas->clear(SkColorSetARGB(0, 0, 0, 0));
159 } else {
160#ifndef NDEBUG
161 // On DEBUG builds, opaque render passes are cleared to blue to easily see regions that were not drawn on the screen.
162 m_skCurrentCanvas->clear(SkColorSetARGB(255, 0, 0, 255));
163#endif
164 }
[email protected]d61675de42012-09-24 21:32:57165}
166
[email protected]96baf3e2012-10-22 23:09:55167void SoftwareRenderer::setDrawViewportSize(const gfx::Size& viewportSize)
[email protected]d61675de42012-09-24 21:32:57168{
169}
170
[email protected]96baf3e2012-10-22 23:09:55171bool SoftwareRenderer::isSoftwareResource(ResourceProvider::ResourceId id) const
[email protected]d61675de42012-09-24 21:32:57172{
173 switch (m_resourceProvider->resourceType(id)) {
[email protected]96baf3e2012-10-22 23:09:55174 case ResourceProvider::GLTexture:
[email protected]d61675de42012-09-24 21:32:57175 return false;
[email protected]96baf3e2012-10-22 23:09:55176 case ResourceProvider::Bitmap:
[email protected]d61675de42012-09-24 21:32:57177 return true;
178 }
179
[email protected]6eb6bb62012-11-10 06:30:59180 LOG(FATAL) << "Invalid resource type.";
[email protected]d61675de42012-09-24 21:32:57181 return false;
182}
183
[email protected]96baf3e2012-10-22 23:09:55184void SoftwareRenderer::drawQuad(DrawingFrame& frame, const DrawQuad* quad)
[email protected]d61675de42012-09-24 21:32:57185{
[email protected]ffbfdc492012-11-15 03:35:32186 TRACE_EVENT0("cc", "SoftwareRenderer::drawQuad");
[email protected]d61675de42012-09-24 21:32:57187 WebTransformationMatrix quadRectMatrix;
[email protected]1bc93f62012-11-17 19:29:50188 quadRectTransform(&quadRectMatrix, quad->quadTransform(), quad->rect);
[email protected]0b056ee2012-10-15 21:31:21189 WebTransformationMatrix contentsDeviceTransform = (frame.windowMatrix * frame.projectionMatrix * quadRectMatrix).to2dTransform();
190 SkMatrix skDeviceMatrix;
191 toSkMatrix(&skDeviceMatrix, contentsDeviceTransform);
192 m_skCurrentCanvas->setMatrix(skDeviceMatrix);
[email protected]d61675de42012-09-24 21:32:57193
194 m_skCurrentPaint.reset();
[email protected]276508a2012-10-16 00:56:34195 if (!isScaleAndTranslate(skDeviceMatrix)) {
196 m_skCurrentPaint.setAntiAlias(true);
197 m_skCurrentPaint.setFilterBitmap(true);
198 }
[email protected]9cd20a32012-11-17 14:11:27199
200 if (quad->ShouldDrawWithBlending()) {
[email protected]d61675de42012-09-24 21:32:57201 m_skCurrentPaint.setAlpha(quad->opacity() * 255);
[email protected]0b056ee2012-10-15 21:31:21202 m_skCurrentPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
203 } else {
[email protected]d61675de42012-09-24 21:32:57204 m_skCurrentPaint.setXfermodeMode(SkXfermode::kSrc_Mode);
[email protected]0b056ee2012-10-15 21:31:21205 }
[email protected]d61675de42012-09-24 21:32:57206
[email protected]1bc93f62012-11-17 19:29:50207 switch (quad->material) {
[email protected]e48727e2012-11-16 22:10:02208 case DrawQuad::DEBUG_BORDER:
[email protected]c22418b2012-11-20 23:06:26209 drawDebugBorderQuad(frame, DebugBorderDrawQuad::MaterialCast(quad));
[email protected]d61675de42012-09-24 21:32:57210 break;
[email protected]e48727e2012-11-16 22:10:02211 case DrawQuad::SOLID_COLOR:
[email protected]c22418b2012-11-20 23:06:26212 drawSolidColorQuad(frame, SolidColorDrawQuad::MaterialCast(quad));
[email protected]d61675de42012-09-24 21:32:57213 break;
[email protected]e48727e2012-11-16 22:10:02214 case DrawQuad::TEXTURE_CONTENT:
[email protected]c22418b2012-11-20 23:06:26215 drawTextureQuad(frame, TextureDrawQuad::MaterialCast(quad));
[email protected]d61675de42012-09-24 21:32:57216 break;
[email protected]e48727e2012-11-16 22:10:02217 case DrawQuad::TILED_CONTENT:
[email protected]c22418b2012-11-20 23:06:26218 drawTileQuad(frame, TileDrawQuad::MaterialCast(quad));
[email protected]d61675de42012-09-24 21:32:57219 break;
[email protected]e48727e2012-11-16 22:10:02220 case DrawQuad::RENDER_PASS:
[email protected]c22418b2012-11-20 23:06:26221 drawRenderPassQuad(frame, RenderPassDrawQuad::MaterialCast(quad));
[email protected]0b056ee2012-10-15 21:31:21222 break;
[email protected]d61675de42012-09-24 21:32:57223 default:
224 drawUnsupportedQuad(frame, quad);
225 break;
226 }
227
228 m_skCurrentCanvas->resetMatrix();
229}
230
[email protected]96baf3e2012-10-22 23:09:55231void SoftwareRenderer::drawDebugBorderQuad(const DrawingFrame& frame, const DebugBorderDrawQuad* quad)
[email protected]d61675de42012-09-24 21:32:57232{
233 // We need to apply the matrix manually to have pixel-sized stroke width.
234 SkPoint vertices[4];
[email protected]79fbdab02012-11-14 07:28:11235 gfx::RectFToSkRect(quadVertexRect()).toQuad(vertices);
[email protected]d61675de42012-09-24 21:32:57236 SkPoint transformedVertices[4];
237 m_skCurrentCanvas->getTotalMatrix().mapPoints(transformedVertices, vertices, 4);
238 m_skCurrentCanvas->resetMatrix();
239
[email protected]c22418b2012-11-20 23:06:26240 m_skCurrentPaint.setColor(quad->color);
241 m_skCurrentPaint.setAlpha(quad->opacity() * SkColorGetA(quad->color));
[email protected]d61675de42012-09-24 21:32:57242 m_skCurrentPaint.setStyle(SkPaint::kStroke_Style);
[email protected]c22418b2012-11-20 23:06:26243 m_skCurrentPaint.setStrokeWidth(quad->width);
[email protected]d61675de42012-09-24 21:32:57244 m_skCurrentCanvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, transformedVertices, m_skCurrentPaint);
245}
246
[email protected]96baf3e2012-10-22 23:09:55247void SoftwareRenderer::drawSolidColorQuad(const DrawingFrame& frame, const SolidColorDrawQuad* quad)
[email protected]d61675de42012-09-24 21:32:57248{
[email protected]c22418b2012-11-20 23:06:26249 m_skCurrentPaint.setColor(quad->color);
250 m_skCurrentPaint.setAlpha(quad->opacity() * SkColorGetA(quad->color));
[email protected]79fbdab02012-11-14 07:28:11251 m_skCurrentCanvas->drawRect(gfx::RectFToSkRect(quadVertexRect()), m_skCurrentPaint);
[email protected]d61675de42012-09-24 21:32:57252}
253
[email protected]96baf3e2012-10-22 23:09:55254void SoftwareRenderer::drawTextureQuad(const DrawingFrame& frame, const TextureDrawQuad* quad)
[email protected]d61675de42012-09-24 21:32:57255{
[email protected]c22418b2012-11-20 23:06:26256 if (!isSoftwareResource(quad->resource_id)) {
[email protected]d61675de42012-09-24 21:32:57257 drawUnsupportedQuad(frame, quad);
258 return;
259 }
260
261 // FIXME: Add support for non-premultiplied alpha.
[email protected]c22418b2012-11-20 23:06:26262 ResourceProvider::ScopedReadLockSoftware lock(m_resourceProvider, quad->resource_id);
[email protected]058a724a2012-10-30 18:37:02263 const SkBitmap* bitmap = lock.skBitmap();
[email protected]c22418b2012-11-20 23:06:26264 gfx::RectF uvRect = gfx::ScaleRect(quad->uv_rect, bitmap->width(), bitmap->height());
[email protected]79fbdab02012-11-14 07:28:11265 SkRect skUvRect = gfx::RectFToSkRect(uvRect);
[email protected]c22418b2012-11-20 23:06:26266 if (quad->flipped)
[email protected]d61675de42012-09-24 21:32:57267 m_skCurrentCanvas->scale(1, -1);
[email protected]66dce292012-11-06 09:12:00268 m_skCurrentCanvas->drawBitmapRectToRect(*bitmap, &skUvRect,
[email protected]79fbdab02012-11-14 07:28:11269 gfx::RectFToSkRect(quadVertexRect()),
[email protected]66dce292012-11-06 09:12:00270 &m_skCurrentPaint);
[email protected]d61675de42012-09-24 21:32:57271}
272
[email protected]96baf3e2012-10-22 23:09:55273void SoftwareRenderer::drawTileQuad(const DrawingFrame& frame, const TileDrawQuad* quad)
[email protected]d61675de42012-09-24 21:32:57274{
[email protected]c22418b2012-11-20 23:06:26275 DCHECK(isSoftwareResource(quad->resource_id));
276 ResourceProvider::ScopedReadLockSoftware lock(m_resourceProvider, quad->resource_id);
[email protected]d61675de42012-09-24 21:32:57277
[email protected]c22418b2012-11-20 23:06:26278 SkRect uvRect = gfx::RectFToSkRect(quad->tex_coord_rect);
[email protected]0457b7502012-11-13 21:48:42279 m_skCurrentPaint.setFilterBitmap(true);
[email protected]66dce292012-11-06 09:12:00280 m_skCurrentCanvas->drawBitmapRectToRect(*lock.skBitmap(), &uvRect,
[email protected]79fbdab02012-11-14 07:28:11281 gfx::RectFToSkRect(quadVertexRect()),
[email protected]66dce292012-11-06 09:12:00282 &m_skCurrentPaint);
[email protected]d61675de42012-09-24 21:32:57283}
284
[email protected]96baf3e2012-10-22 23:09:55285void SoftwareRenderer::drawRenderPassQuad(const DrawingFrame& frame, const RenderPassDrawQuad* quad)
[email protected]0b056ee2012-10-15 21:31:21286{
[email protected]c22418b2012-11-20 23:06:26287 CachedResource* contentTexture = m_renderPassTextures.get(quad->render_pass_id);
[email protected]058a724a2012-10-30 18:37:02288 if (!contentTexture || !contentTexture->id())
[email protected]0b056ee2012-10-15 21:31:21289 return;
290
[email protected]c22418b2012-11-20 23:06:26291 const RenderPass* renderPass = frame.renderPassesById->get(quad->render_pass_id);
[email protected]632bd7662012-11-14 21:21:54292 DCHECK(renderPass);
293 if (!renderPass)
294 return;
295
[email protected]058a724a2012-10-30 18:37:02296 DCHECK(isSoftwareResource(contentTexture->id()));
297 ResourceProvider::ScopedReadLockSoftware lock(m_resourceProvider, contentTexture->id());
[email protected]0b056ee2012-10-15 21:31:21298
[email protected]79fbdab02012-11-14 07:28:11299 SkRect destRect = gfx::RectFToSkRect(quadVertexRect());
[email protected]0b056ee2012-10-15 21:31:21300
[email protected]058a724a2012-10-30 18:37:02301 const SkBitmap* content = lock.skBitmap();
[email protected]0b056ee2012-10-15 21:31:21302
[email protected]058a724a2012-10-30 18:37:02303 SkRect contentRect;
304 content->getBounds(&contentRect);
305
306 SkMatrix contentMat;
307 contentMat.setRectToRect(contentRect, destRect, SkMatrix::kFill_ScaleToFit);
308
309 SkAutoTUnref<SkShader> shader(SkShader::CreateBitmapShader(*content,
[email protected]0b056ee2012-10-15 21:31:21310 SkShader::kClamp_TileMode,
311 SkShader::kClamp_TileMode));
[email protected]058a724a2012-10-30 18:37:02312 shader->setLocalMatrix(contentMat);
[email protected]0b056ee2012-10-15 21:31:21313 m_skCurrentPaint.setShader(shader);
314
[email protected]f57bbc02012-11-21 07:02:15315 SkImageFilter* filter = renderPass->filter;
[email protected]632bd7662012-11-14 21:21:54316 if (filter)
317 m_skCurrentPaint.setImageFilter(filter);
318
[email protected]c22418b2012-11-20 23:06:26319 if (quad->mask_resource_id) {
320 ResourceProvider::ScopedReadLockSoftware maskLock(m_resourceProvider, quad->mask_resource_id);
[email protected]058a724a2012-10-30 18:37:02321
322 const SkBitmap* mask = maskLock.skBitmap();
323
324 SkRect maskRect = SkRect::MakeXYWH(
[email protected]c22418b2012-11-20 23:06:26325 quad->mask_tex_coord_offset_x * mask->width(),
326 quad->mask_tex_coord_offset_y * mask->height(),
327 quad->mask_tex_coord_scale_x * mask->width(),
328 quad->mask_tex_coord_scale_y * mask->height());
[email protected]0b056ee2012-10-15 21:31:21329
330 SkMatrix maskMat;
[email protected]058a724a2012-10-30 18:37:02331 maskMat.setRectToRect(maskRect, destRect, SkMatrix::kFill_ScaleToFit);
[email protected]0b056ee2012-10-15 21:31:21332
[email protected]058a724a2012-10-30 18:37:02333 SkAutoTUnref<SkShader> maskShader(SkShader::CreateBitmapShader(*mask,
[email protected]0b056ee2012-10-15 21:31:21334 SkShader::kClamp_TileMode,
335 SkShader::kClamp_TileMode));
336 maskShader->setLocalMatrix(maskMat);
337
338 SkPaint maskPaint;
339 maskPaint.setShader(maskShader);
340
341 SkAutoTUnref<SkLayerRasterizer> maskRasterizer(new SkLayerRasterizer);
342 maskRasterizer->addLayer(maskPaint);
343
344 m_skCurrentPaint.setRasterizer(maskRasterizer);
345 m_skCurrentCanvas->drawRect(destRect, m_skCurrentPaint);
346 } else {
[email protected]058a724a2012-10-30 18:37:02347 // FIXME: Apply background filters and blend with content
[email protected]0b056ee2012-10-15 21:31:21348 m_skCurrentCanvas->drawRect(destRect, m_skCurrentPaint);
349 }
350}
351
[email protected]96baf3e2012-10-22 23:09:55352void SoftwareRenderer::drawUnsupportedQuad(const DrawingFrame& frame, const DrawQuad* quad)
[email protected]d61675de42012-09-24 21:32:57353{
354 m_skCurrentPaint.setColor(SK_ColorMAGENTA);
355 m_skCurrentPaint.setAlpha(quad->opacity() * 255);
[email protected]79fbdab02012-11-14 07:28:11356 m_skCurrentCanvas->drawRect(gfx::RectFToSkRect(quadVertexRect()), m_skCurrentPaint);
[email protected]d61675de42012-09-24 21:32:57357}
358
[email protected]96baf3e2012-10-22 23:09:55359bool SoftwareRenderer::swapBuffers()
[email protected]d61675de42012-09-24 21:32:57360{
[email protected]61de5812012-11-08 07:03:44361 if (m_client->hasImplThread())
[email protected]d61675de42012-09-24 21:32:57362 m_client->onSwapBuffersComplete();
363 return true;
364}
365
[email protected]aad0a0072012-11-01 18:15:58366void SoftwareRenderer::getFramebufferPixels(void *pixels, const gfx::Rect& rect)
[email protected]d61675de42012-09-24 21:32:57367{
[email protected]ffbfdc492012-11-15 03:35:32368 TRACE_EVENT0("cc", "SoftwareRenderer::getFramebufferPixels");
[email protected]d61675de42012-09-24 21:32:57369 SkBitmap fullBitmap = m_outputDevice->lock(false)->getSkBitmap();
370 SkBitmap subsetBitmap;
[email protected]aad0a0072012-11-01 18:15:58371 SkIRect invertRect = SkIRect::MakeXYWH(rect.x(), viewportSize().height() - rect.bottom(), rect.width(), rect.height());
[email protected]d61675de42012-09-24 21:32:57372 fullBitmap.extractSubset(&subsetBitmap, invertRect);
373 subsetBitmap.copyPixelsTo(pixels, rect.width() * rect.height() * 4, rect.width() * 4);
374 m_outputDevice->unlock();
375}
376
[email protected]96baf3e2012-10-22 23:09:55377void SoftwareRenderer::setVisible(bool visible)
[email protected]d61675de42012-09-24 21:32:57378{
379 if (m_visible == visible)
380 return;
381 m_visible = visible;
382}
383
[email protected]bc5e77c2012-11-05 20:00:49384} // namespace cc