blob: 785ed6b65d006c8bdd939552ddf503eb77a8b11a [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]c8686a02012-11-27 08:29:009#include "cc/math_util.h"
[email protected]55a124d02012-10-22 03:07:1310#include "cc/render_pass_draw_quad.h"
[email protected]a46f32932012-12-07 21:43:1611#include "cc/software_output_device.h"
[email protected]4456eee22012-10-19 18:16:3812#include "cc/solid_color_draw_quad.h"
13#include "cc/texture_draw_quad.h"
[email protected]da2c9122012-10-20 23:13:0614#include "cc/tile_draw_quad.h"
[email protected]920caa52012-12-18 22:39:5015#include "third_party/WebKit/Source/Platform/chromium/public/WebImage.h"
[email protected]0b056ee2012-10-15 21:31:2116#include "third_party/skia/include/core/SkCanvas.h"
17#include "third_party/skia/include/core/SkColor.h"
18#include "third_party/skia/include/core/SkMatrix.h"
19#include "third_party/skia/include/core/SkShader.h"
20#include "third_party/skia/include/effects/SkLayerRasterizer.h"
[email protected]1fea8142012-10-20 04:12:4121#include "ui/gfx/rect_conversions.h"
[email protected]79fbdab02012-11-14 07:28:1122#include "ui/gfx/skia_util.h"
[email protected]c8686a02012-11-27 08:29:0023#include "ui/gfx/transform.h"
[email protected]d61675de42012-09-24 21:32:5724
[email protected]d61675de42012-09-24 21:32:5725namespace cc {
26
27namespace {
28
[email protected]c8686a02012-11-27 08:29:0029void toSkMatrix(SkMatrix* flattened, const gfx::Transform& m)
[email protected]d61675de42012-09-24 21:32:5730{
31 // Convert from 4x4 to 3x3 by dropping the third row and column.
[email protected]c8686a02012-11-27 08:29:0032 flattened->set(0, SkDoubleToScalar(m.matrix().getDouble(0, 0)));
33 flattened->set(1, SkDoubleToScalar(m.matrix().getDouble(0, 1)));
34 flattened->set(2, SkDoubleToScalar(m.matrix().getDouble(0, 3)));
35 flattened->set(3, SkDoubleToScalar(m.matrix().getDouble(1, 0)));
36 flattened->set(4, SkDoubleToScalar(m.matrix().getDouble(1, 1)));
37 flattened->set(5, SkDoubleToScalar(m.matrix().getDouble(1, 3)));
38 flattened->set(6, SkDoubleToScalar(m.matrix().getDouble(3, 0)));
39 flattened->set(7, SkDoubleToScalar(m.matrix().getDouble(3, 1)));
40 flattened->set(8, SkDoubleToScalar(m.matrix().getDouble(3, 3)));
[email protected]d61675de42012-09-24 21:32:5741}
42
[email protected]276508a2012-10-16 00:56:3443bool isScaleAndTranslate(const SkMatrix& matrix)
44{
45 return SkScalarNearlyZero(matrix[SkMatrix::kMSkewX]) &&
46 SkScalarNearlyZero(matrix[SkMatrix::kMSkewY]) &&
47 SkScalarNearlyZero(matrix[SkMatrix::kMPersp0]) &&
48 SkScalarNearlyZero(matrix[SkMatrix::kMPersp1]) &&
49 SkScalarNearlyZero(matrix[SkMatrix::kMPersp2] - 1.0f);
50}
51
[email protected]d61675de42012-09-24 21:32:5752} // anonymous namespace
53
[email protected]a46f32932012-12-07 21:43:1654scoped_ptr<SoftwareRenderer> SoftwareRenderer::create(RendererClient* client, ResourceProvider* resourceProvider, SoftwareOutputDevice* outputDevice)
[email protected]d61675de42012-09-24 21:32:5755{
[email protected]96baf3e2012-10-22 23:09:5556 return make_scoped_ptr(new SoftwareRenderer(client, resourceProvider, outputDevice));
[email protected]d61675de42012-09-24 21:32:5757}
58
[email protected]a46f32932012-12-07 21:43:1659SoftwareRenderer::SoftwareRenderer(RendererClient* client, ResourceProvider* resourceProvider, SoftwareOutputDevice* outputDevice)
[email protected]96baf3e2012-10-22 23:09:5560 : DirectRenderer(client, resourceProvider)
[email protected]d61675de42012-09-24 21:32:5761 , m_visible(true)
62 , m_outputDevice(outputDevice)
[email protected]d61675de42012-09-24 21:32:5763 , m_skCurrentCanvas(0)
64{
[email protected]96baf3e2012-10-22 23:09:5565 m_resourceProvider->setDefaultResourceType(ResourceProvider::Bitmap);
[email protected]d61675de42012-09-24 21:32:5766
[email protected]ea9d8f22012-12-08 03:39:2967 m_capabilities.maxTextureSize = m_resourceProvider->maxTextureSize();
68 m_capabilities.bestTextureFormat = m_resourceProvider->bestTextureFormat();
[email protected]d61675de42012-09-24 21:32:5769 m_capabilities.usingSetVisibility = true;
[email protected]da983ab02012-12-06 02:32:4070 // The updater can access bitmaps while the SoftwareRenderer is using them.
71 m_capabilities.allowPartialTextureUpdates = true;
[email protected]d61675de42012-09-24 21:32:5772
73 viewportChanged();
74}
75
[email protected]96baf3e2012-10-22 23:09:5576SoftwareRenderer::~SoftwareRenderer()
[email protected]d61675de42012-09-24 21:32:5777{
78}
79
[email protected]96baf3e2012-10-22 23:09:5580const RendererCapabilities& SoftwareRenderer::capabilities() const
[email protected]d61675de42012-09-24 21:32:5781{
82 return m_capabilities;
83}
84
[email protected]96baf3e2012-10-22 23:09:5585void SoftwareRenderer::viewportChanged()
[email protected]d61675de42012-09-24 21:32:5786{
[email protected]a46f32932012-12-07 21:43:1687 m_outputDevice->DidChangeViewportSize(viewportSize());
[email protected]d61675de42012-09-24 21:32:5788}
89
[email protected]96baf3e2012-10-22 23:09:5590void SoftwareRenderer::beginDrawingFrame(DrawingFrame& frame)
[email protected]d61675de42012-09-24 21:32:5791{
[email protected]ffbfdc492012-11-15 03:35:3292 TRACE_EVENT0("cc", "SoftwareRenderer::beginDrawingFrame");
[email protected]a46f32932012-12-07 21:43:1693 m_skRootCanvas = make_scoped_ptr(new SkCanvas(m_outputDevice->Lock(true)->getSkBitmap()));
[email protected]d61675de42012-09-24 21:32:5794}
95
[email protected]96baf3e2012-10-22 23:09:5596void SoftwareRenderer::finishDrawingFrame(DrawingFrame& frame)
[email protected]d61675de42012-09-24 21:32:5797{
[email protected]ffbfdc492012-11-15 03:35:3298 TRACE_EVENT0("cc", "SoftwareRenderer::finishDrawingFrame");
[email protected]0704caf2012-10-16 03:39:4799 m_currentFramebufferLock.reset();
[email protected]d61675de42012-09-24 21:32:57100 m_skCurrentCanvas = 0;
[email protected]0704caf2012-10-16 03:39:47101 m_skRootCanvas.reset();
[email protected]a46f32932012-12-07 21:43:16102 m_outputDevice->Unlock();
[email protected]d61675de42012-09-24 21:32:57103}
104
[email protected]96baf3e2012-10-22 23:09:55105bool SoftwareRenderer::flippedFramebuffer() const
[email protected]d61675de42012-09-24 21:32:57106{
107 return false;
108}
109
[email protected]dc462d782012-11-21 21:43:01110void SoftwareRenderer::ensureScissorTestEnabled()
111{
112 // Nothing to do here. Current implementation of software rendering has no
113 // notion of enabling/disabling the feature.
114}
115
116void SoftwareRenderer::ensureScissorTestDisabled()
117{
118 // There is no explicit notion of enabling/disabling scissoring in software
119 // rendering, but the underlying effect we want is to clear any existing
120 // clipRect on the current SkCanvas. This is done by setting clipRect to
121 // the viewport's dimensions.
122 SkISize canvasSize = m_skCurrentCanvas->getDeviceSize();
123 SkRect canvasRect = SkRect::MakeXYWH(0, 0, canvasSize.width(), canvasSize.height());
124 m_skCurrentCanvas->clipRect(canvasRect, SkRegion::kReplace_Op);
125}
126
[email protected]96baf3e2012-10-22 23:09:55127void SoftwareRenderer::finish()
[email protected]d61675de42012-09-24 21:32:57128{
129}
130
[email protected]96baf3e2012-10-22 23:09:55131void SoftwareRenderer::bindFramebufferToOutputSurface(DrawingFrame& frame)
[email protected]d61675de42012-09-24 21:32:57132{
[email protected]0704caf2012-10-16 03:39:47133 m_currentFramebufferLock.reset();
[email protected]75fe7f822012-09-28 17:54:14134 m_skCurrentCanvas = m_skRootCanvas.get();
[email protected]d61675de42012-09-24 21:32:57135}
136
[email protected]f7685bc2012-11-08 17:32:33137bool SoftwareRenderer::bindFramebufferToTexture(DrawingFrame& frame, const ScopedResource* texture, const gfx::Rect& framebufferRect)
[email protected]d61675de42012-09-24 21:32:57138{
[email protected]96baf3e2012-10-22 23:09:55139 m_currentFramebufferLock = make_scoped_ptr(new ResourceProvider::ScopedWriteLockSoftware(m_resourceProvider, texture->id()));
[email protected]d61675de42012-09-24 21:32:57140 m_skCurrentCanvas = m_currentFramebufferLock->skCanvas();
141 initializeMatrices(frame, framebufferRect, false);
142 setDrawViewportSize(framebufferRect.size());
143
144 return true;
145}
146
[email protected]7ead0932012-11-08 07:46:52147void SoftwareRenderer::setScissorTestRect(const gfx::Rect& scissorRect)
[email protected]d61675de42012-09-24 21:32:57148{
[email protected]79fbdab02012-11-14 07:28:11149 m_skCurrentCanvas->clipRect(gfx::RectToSkRect(scissorRect), SkRegion::kReplace_Op);
[email protected]d61675de42012-09-24 21:32:57150}
151
[email protected]96baf3e2012-10-22 23:09:55152void SoftwareRenderer::clearFramebuffer(DrawingFrame& frame)
[email protected]d61675de42012-09-24 21:32:57153{
[email protected]f57bbc02012-11-21 07:02:15154 if (frame.currentRenderPass->has_transparent_background) {
[email protected]0b056ee2012-10-15 21:31:21155 m_skCurrentCanvas->clear(SkColorSetARGB(0, 0, 0, 0));
156 } else {
157#ifndef NDEBUG
158 // On DEBUG builds, opaque render passes are cleared to blue to easily see regions that were not drawn on the screen.
159 m_skCurrentCanvas->clear(SkColorSetARGB(255, 0, 0, 255));
160#endif
161 }
[email protected]d61675de42012-09-24 21:32:57162}
163
[email protected]96baf3e2012-10-22 23:09:55164void SoftwareRenderer::setDrawViewportSize(const gfx::Size& viewportSize)
[email protected]d61675de42012-09-24 21:32:57165{
166}
167
[email protected]96baf3e2012-10-22 23:09:55168bool SoftwareRenderer::isSoftwareResource(ResourceProvider::ResourceId id) const
[email protected]d61675de42012-09-24 21:32:57169{
170 switch (m_resourceProvider->resourceType(id)) {
[email protected]96baf3e2012-10-22 23:09:55171 case ResourceProvider::GLTexture:
[email protected]d61675de42012-09-24 21:32:57172 return false;
[email protected]96baf3e2012-10-22 23:09:55173 case ResourceProvider::Bitmap:
[email protected]d61675de42012-09-24 21:32:57174 return true;
175 }
176
[email protected]6eb6bb62012-11-10 06:30:59177 LOG(FATAL) << "Invalid resource type.";
[email protected]d61675de42012-09-24 21:32:57178 return false;
179}
180
[email protected]96baf3e2012-10-22 23:09:55181void SoftwareRenderer::drawQuad(DrawingFrame& frame, const DrawQuad* quad)
[email protected]d61675de42012-09-24 21:32:57182{
[email protected]ffbfdc492012-11-15 03:35:32183 TRACE_EVENT0("cc", "SoftwareRenderer::drawQuad");
[email protected]c8686a02012-11-27 08:29:00184 gfx::Transform quadRectMatrix;
[email protected]1bc93f62012-11-17 19:29:50185 quadRectTransform(&quadRectMatrix, quad->quadTransform(), quad->rect);
[email protected]78634b0c2013-01-15 07:49:40186 gfx::Transform contentsDeviceTransform = frame.windowMatrix * frame.projectionMatrix * quadRectMatrix;
187 contentsDeviceTransform.FlattenTo2d();
[email protected]0b056ee2012-10-15 21:31:21188 SkMatrix skDeviceMatrix;
189 toSkMatrix(&skDeviceMatrix, contentsDeviceTransform);
190 m_skCurrentCanvas->setMatrix(skDeviceMatrix);
[email protected]d61675de42012-09-24 21:32:57191
192 m_skCurrentPaint.reset();
[email protected]276508a2012-10-16 00:56:34193 if (!isScaleAndTranslate(skDeviceMatrix)) {
194 m_skCurrentPaint.setAntiAlias(true);
195 m_skCurrentPaint.setFilterBitmap(true);
196 }
[email protected]9cd20a32012-11-17 14:11:27197
198 if (quad->ShouldDrawWithBlending()) {
[email protected]d61675de42012-09-24 21:32:57199 m_skCurrentPaint.setAlpha(quad->opacity() * 255);
[email protected]0b056ee2012-10-15 21:31:21200 m_skCurrentPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
201 } else {
[email protected]d61675de42012-09-24 21:32:57202 m_skCurrentPaint.setXfermodeMode(SkXfermode::kSrc_Mode);
[email protected]0b056ee2012-10-15 21:31:21203 }
[email protected]d61675de42012-09-24 21:32:57204
[email protected]1bc93f62012-11-17 19:29:50205 switch (quad->material) {
[email protected]e48727e2012-11-16 22:10:02206 case DrawQuad::DEBUG_BORDER:
[email protected]c22418b2012-11-20 23:06:26207 drawDebugBorderQuad(frame, DebugBorderDrawQuad::MaterialCast(quad));
[email protected]d61675de42012-09-24 21:32:57208 break;
[email protected]e48727e2012-11-16 22:10:02209 case DrawQuad::SOLID_COLOR:
[email protected]c22418b2012-11-20 23:06:26210 drawSolidColorQuad(frame, SolidColorDrawQuad::MaterialCast(quad));
[email protected]d61675de42012-09-24 21:32:57211 break;
[email protected]e48727e2012-11-16 22:10:02212 case DrawQuad::TEXTURE_CONTENT:
[email protected]c22418b2012-11-20 23:06:26213 drawTextureQuad(frame, TextureDrawQuad::MaterialCast(quad));
[email protected]d61675de42012-09-24 21:32:57214 break;
[email protected]e48727e2012-11-16 22:10:02215 case DrawQuad::TILED_CONTENT:
[email protected]c22418b2012-11-20 23:06:26216 drawTileQuad(frame, TileDrawQuad::MaterialCast(quad));
[email protected]d61675de42012-09-24 21:32:57217 break;
[email protected]e48727e2012-11-16 22:10:02218 case DrawQuad::RENDER_PASS:
[email protected]c22418b2012-11-20 23:06:26219 drawRenderPassQuad(frame, RenderPassDrawQuad::MaterialCast(quad));
[email protected]0b056ee2012-10-15 21:31:21220 break;
[email protected]d61675de42012-09-24 21:32:57221 default:
222 drawUnsupportedQuad(frame, quad);
223 break;
224 }
225
226 m_skCurrentCanvas->resetMatrix();
227}
228
[email protected]96baf3e2012-10-22 23:09:55229void SoftwareRenderer::drawDebugBorderQuad(const DrawingFrame& frame, const DebugBorderDrawQuad* quad)
[email protected]d61675de42012-09-24 21:32:57230{
231 // We need to apply the matrix manually to have pixel-sized stroke width.
232 SkPoint vertices[4];
[email protected]79fbdab02012-11-14 07:28:11233 gfx::RectFToSkRect(quadVertexRect()).toQuad(vertices);
[email protected]d61675de42012-09-24 21:32:57234 SkPoint transformedVertices[4];
235 m_skCurrentCanvas->getTotalMatrix().mapPoints(transformedVertices, vertices, 4);
236 m_skCurrentCanvas->resetMatrix();
237
[email protected]c22418b2012-11-20 23:06:26238 m_skCurrentPaint.setColor(quad->color);
239 m_skCurrentPaint.setAlpha(quad->opacity() * SkColorGetA(quad->color));
[email protected]d61675de42012-09-24 21:32:57240 m_skCurrentPaint.setStyle(SkPaint::kStroke_Style);
[email protected]c22418b2012-11-20 23:06:26241 m_skCurrentPaint.setStrokeWidth(quad->width);
[email protected]d61675de42012-09-24 21:32:57242 m_skCurrentCanvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, transformedVertices, m_skCurrentPaint);
243}
244
[email protected]96baf3e2012-10-22 23:09:55245void SoftwareRenderer::drawSolidColorQuad(const DrawingFrame& frame, const SolidColorDrawQuad* quad)
[email protected]d61675de42012-09-24 21:32:57246{
[email protected]c22418b2012-11-20 23:06:26247 m_skCurrentPaint.setColor(quad->color);
248 m_skCurrentPaint.setAlpha(quad->opacity() * SkColorGetA(quad->color));
[email protected]79fbdab02012-11-14 07:28:11249 m_skCurrentCanvas->drawRect(gfx::RectFToSkRect(quadVertexRect()), m_skCurrentPaint);
[email protected]d61675de42012-09-24 21:32:57250}
251
[email protected]96baf3e2012-10-22 23:09:55252void SoftwareRenderer::drawTextureQuad(const DrawingFrame& frame, const TextureDrawQuad* quad)
[email protected]d61675de42012-09-24 21:32:57253{
[email protected]c22418b2012-11-20 23:06:26254 if (!isSoftwareResource(quad->resource_id)) {
[email protected]d61675de42012-09-24 21:32:57255 drawUnsupportedQuad(frame, quad);
256 return;
257 }
258
259 // FIXME: Add support for non-premultiplied alpha.
[email protected]c22418b2012-11-20 23:06:26260 ResourceProvider::ScopedReadLockSoftware lock(m_resourceProvider, quad->resource_id);
[email protected]058a724a2012-10-30 18:37:02261 const SkBitmap* bitmap = lock.skBitmap();
[email protected]c22418b2012-11-20 23:06:26262 gfx::RectF uvRect = gfx::ScaleRect(quad->uv_rect, bitmap->width(), bitmap->height());
[email protected]79fbdab02012-11-14 07:28:11263 SkRect skUvRect = gfx::RectFToSkRect(uvRect);
[email protected]c22418b2012-11-20 23:06:26264 if (quad->flipped)
[email protected]d61675de42012-09-24 21:32:57265 m_skCurrentCanvas->scale(1, -1);
[email protected]66dce292012-11-06 09:12:00266 m_skCurrentCanvas->drawBitmapRectToRect(*bitmap, &skUvRect,
[email protected]79fbdab02012-11-14 07:28:11267 gfx::RectFToSkRect(quadVertexRect()),
[email protected]66dce292012-11-06 09:12:00268 &m_skCurrentPaint);
[email protected]d61675de42012-09-24 21:32:57269}
270
[email protected]96baf3e2012-10-22 23:09:55271void SoftwareRenderer::drawTileQuad(const DrawingFrame& frame, const TileDrawQuad* quad)
[email protected]d61675de42012-09-24 21:32:57272{
[email protected]c22418b2012-11-20 23:06:26273 DCHECK(isSoftwareResource(quad->resource_id));
274 ResourceProvider::ScopedReadLockSoftware lock(m_resourceProvider, quad->resource_id);
[email protected]d61675de42012-09-24 21:32:57275
[email protected]c22418b2012-11-20 23:06:26276 SkRect uvRect = gfx::RectFToSkRect(quad->tex_coord_rect);
[email protected]0457b7502012-11-13 21:48:42277 m_skCurrentPaint.setFilterBitmap(true);
[email protected]66dce292012-11-06 09:12:00278 m_skCurrentCanvas->drawBitmapRectToRect(*lock.skBitmap(), &uvRect,
[email protected]79fbdab02012-11-14 07:28:11279 gfx::RectFToSkRect(quadVertexRect()),
[email protected]66dce292012-11-06 09:12:00280 &m_skCurrentPaint);
[email protected]d61675de42012-09-24 21:32:57281}
282
[email protected]96baf3e2012-10-22 23:09:55283void SoftwareRenderer::drawRenderPassQuad(const DrawingFrame& frame, const RenderPassDrawQuad* quad)
[email protected]0b056ee2012-10-15 21:31:21284{
[email protected]c22418b2012-11-20 23:06:26285 CachedResource* contentTexture = m_renderPassTextures.get(quad->render_pass_id);
[email protected]058a724a2012-10-30 18:37:02286 if (!contentTexture || !contentTexture->id())
[email protected]0b056ee2012-10-15 21:31:21287 return;
288
[email protected]058a724a2012-10-30 18:37:02289 DCHECK(isSoftwareResource(contentTexture->id()));
290 ResourceProvider::ScopedReadLockSoftware lock(m_resourceProvider, contentTexture->id());
[email protected]0b056ee2012-10-15 21:31:21291
[email protected]79fbdab02012-11-14 07:28:11292 SkRect destRect = gfx::RectFToSkRect(quadVertexRect());
[email protected]0b056ee2012-10-15 21:31:21293
[email protected]058a724a2012-10-30 18:37:02294 const SkBitmap* content = lock.skBitmap();
[email protected]0b056ee2012-10-15 21:31:21295
[email protected]058a724a2012-10-30 18:37:02296 SkRect contentRect;
297 content->getBounds(&contentRect);
298
299 SkMatrix contentMat;
300 contentMat.setRectToRect(contentRect, destRect, SkMatrix::kFill_ScaleToFit);
301
[email protected]1940c4e2012-12-04 05:08:15302 skia::RefPtr<SkShader> shader = skia::AdoptRef(
303 SkShader::CreateBitmapShader(*content,
304 SkShader::kClamp_TileMode,
305 SkShader::kClamp_TileMode));
[email protected]058a724a2012-10-30 18:37:02306 shader->setLocalMatrix(contentMat);
[email protected]1940c4e2012-12-04 05:08:15307 m_skCurrentPaint.setShader(shader.get());
[email protected]0b056ee2012-10-15 21:31:21308
[email protected]20062042012-12-21 22:16:36309 SkImageFilter* filter = quad->filter.get();
[email protected]632bd7662012-11-14 21:21:54310 if (filter)
311 m_skCurrentPaint.setImageFilter(filter);
312
[email protected]c22418b2012-11-20 23:06:26313 if (quad->mask_resource_id) {
314 ResourceProvider::ScopedReadLockSoftware maskLock(m_resourceProvider, quad->mask_resource_id);
[email protected]058a724a2012-10-30 18:37:02315
316 const SkBitmap* mask = maskLock.skBitmap();
317
318 SkRect maskRect = SkRect::MakeXYWH(
[email protected]458af1e2012-12-13 05:12:18319 quad->mask_uv_rect.x() * mask->width(),
320 quad->mask_uv_rect.y() * mask->height(),
321 quad->mask_uv_rect.width() * mask->width(),
322 quad->mask_uv_rect.height() * mask->height());
[email protected]0b056ee2012-10-15 21:31:21323
324 SkMatrix maskMat;
[email protected]058a724a2012-10-30 18:37:02325 maskMat.setRectToRect(maskRect, destRect, SkMatrix::kFill_ScaleToFit);
[email protected]0b056ee2012-10-15 21:31:21326
[email protected]1940c4e2012-12-04 05:08:15327 skia::RefPtr<SkShader> maskShader = skia::AdoptRef(
328 SkShader::CreateBitmapShader(*mask,
329 SkShader::kClamp_TileMode,
330 SkShader::kClamp_TileMode));
[email protected]0b056ee2012-10-15 21:31:21331 maskShader->setLocalMatrix(maskMat);
332
333 SkPaint maskPaint;
[email protected]1940c4e2012-12-04 05:08:15334 maskPaint.setShader(maskShader.get());
[email protected]0b056ee2012-10-15 21:31:21335
[email protected]1940c4e2012-12-04 05:08:15336 skia::RefPtr<SkLayerRasterizer> maskRasterizer = skia::AdoptRef(new SkLayerRasterizer);
[email protected]0b056ee2012-10-15 21:31:21337 maskRasterizer->addLayer(maskPaint);
338
[email protected]1940c4e2012-12-04 05:08:15339 m_skCurrentPaint.setRasterizer(maskRasterizer.get());
[email protected]0b056ee2012-10-15 21:31:21340 m_skCurrentCanvas->drawRect(destRect, m_skCurrentPaint);
341 } else {
[email protected]058a724a2012-10-30 18:37:02342 // FIXME: Apply background filters and blend with content
[email protected]0b056ee2012-10-15 21:31:21343 m_skCurrentCanvas->drawRect(destRect, m_skCurrentPaint);
344 }
345}
346
[email protected]96baf3e2012-10-22 23:09:55347void SoftwareRenderer::drawUnsupportedQuad(const DrawingFrame& frame, const DrawQuad* quad)
[email protected]d61675de42012-09-24 21:32:57348{
349 m_skCurrentPaint.setColor(SK_ColorMAGENTA);
350 m_skCurrentPaint.setAlpha(quad->opacity() * 255);
[email protected]79fbdab02012-11-14 07:28:11351 m_skCurrentCanvas->drawRect(gfx::RectFToSkRect(quadVertexRect()), m_skCurrentPaint);
[email protected]d61675de42012-09-24 21:32:57352}
353
[email protected]96baf3e2012-10-22 23:09:55354bool SoftwareRenderer::swapBuffers()
[email protected]d61675de42012-09-24 21:32:57355{
[email protected]61de5812012-11-08 07:03:44356 if (m_client->hasImplThread())
[email protected]d61675de42012-09-24 21:32:57357 m_client->onSwapBuffersComplete();
358 return true;
359}
360
[email protected]aad0a0072012-11-01 18:15:58361void SoftwareRenderer::getFramebufferPixels(void *pixels, const gfx::Rect& rect)
[email protected]d61675de42012-09-24 21:32:57362{
[email protected]ffbfdc492012-11-15 03:35:32363 TRACE_EVENT0("cc", "SoftwareRenderer::getFramebufferPixels");
[email protected]a46f32932012-12-07 21:43:16364 SkBitmap fullBitmap = m_outputDevice->Lock(false)->getSkBitmap();
[email protected]d61675de42012-09-24 21:32:57365 SkBitmap subsetBitmap;
[email protected]aad0a0072012-11-01 18:15:58366 SkIRect invertRect = SkIRect::MakeXYWH(rect.x(), viewportSize().height() - rect.bottom(), rect.width(), rect.height());
[email protected]d61675de42012-09-24 21:32:57367 fullBitmap.extractSubset(&subsetBitmap, invertRect);
368 subsetBitmap.copyPixelsTo(pixels, rect.width() * rect.height() * 4, rect.width() * 4);
[email protected]a46f32932012-12-07 21:43:16369 m_outputDevice->Unlock();
[email protected]d61675de42012-09-24 21:32:57370}
371
[email protected]96baf3e2012-10-22 23:09:55372void SoftwareRenderer::setVisible(bool visible)
[email protected]d61675de42012-09-24 21:32:57373{
374 if (m_visible == visible)
375 return;
376 m_visible = visible;
377}
378
[email protected]bc5e77c2012-11-05 20:00:49379} // namespace cc