blob: e1764c79a4c24b69c6ebb5bfcefb94f202b21054 [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"
[email protected]a22ac652013-02-01 03:02:4918#include "third_party/skia/include/core/SkDevice.h"
[email protected]0b056ee2012-10-15 21:31:2119#include "third_party/skia/include/core/SkMatrix.h"
20#include "third_party/skia/include/core/SkShader.h"
21#include "third_party/skia/include/effects/SkLayerRasterizer.h"
[email protected]1fea8142012-10-20 04:12:4122#include "ui/gfx/rect_conversions.h"
[email protected]79fbdab02012-11-14 07:28:1123#include "ui/gfx/skia_util.h"
[email protected]c8686a02012-11-27 08:29:0024#include "ui/gfx/transform.h"
[email protected]d61675de42012-09-24 21:32:5725
[email protected]d61675de42012-09-24 21:32:5726namespace cc {
27
28namespace {
29
[email protected]c8686a02012-11-27 08:29:0030void toSkMatrix(SkMatrix* flattened, const gfx::Transform& m)
[email protected]d61675de42012-09-24 21:32:5731{
32 // Convert from 4x4 to 3x3 by dropping the third row and column.
[email protected]c8686a02012-11-27 08:29:0033 flattened->set(0, SkDoubleToScalar(m.matrix().getDouble(0, 0)));
34 flattened->set(1, SkDoubleToScalar(m.matrix().getDouble(0, 1)));
35 flattened->set(2, SkDoubleToScalar(m.matrix().getDouble(0, 3)));
36 flattened->set(3, SkDoubleToScalar(m.matrix().getDouble(1, 0)));
37 flattened->set(4, SkDoubleToScalar(m.matrix().getDouble(1, 1)));
38 flattened->set(5, SkDoubleToScalar(m.matrix().getDouble(1, 3)));
39 flattened->set(6, SkDoubleToScalar(m.matrix().getDouble(3, 0)));
40 flattened->set(7, SkDoubleToScalar(m.matrix().getDouble(3, 1)));
41 flattened->set(8, SkDoubleToScalar(m.matrix().getDouble(3, 3)));
[email protected]d61675de42012-09-24 21:32:5742}
43
[email protected]276508a2012-10-16 00:56:3444bool isScaleAndTranslate(const SkMatrix& matrix)
45{
46 return SkScalarNearlyZero(matrix[SkMatrix::kMSkewX]) &&
47 SkScalarNearlyZero(matrix[SkMatrix::kMSkewY]) &&
48 SkScalarNearlyZero(matrix[SkMatrix::kMPersp0]) &&
49 SkScalarNearlyZero(matrix[SkMatrix::kMPersp1]) &&
50 SkScalarNearlyZero(matrix[SkMatrix::kMPersp2] - 1.0f);
51}
52
[email protected]d61675de42012-09-24 21:32:5753} // anonymous namespace
54
[email protected]a46f32932012-12-07 21:43:1655scoped_ptr<SoftwareRenderer> SoftwareRenderer::create(RendererClient* client, ResourceProvider* resourceProvider, SoftwareOutputDevice* outputDevice)
[email protected]d61675de42012-09-24 21:32:5756{
[email protected]96baf3e2012-10-22 23:09:5557 return make_scoped_ptr(new SoftwareRenderer(client, resourceProvider, outputDevice));
[email protected]d61675de42012-09-24 21:32:5758}
59
[email protected]a46f32932012-12-07 21:43:1660SoftwareRenderer::SoftwareRenderer(RendererClient* client, ResourceProvider* resourceProvider, SoftwareOutputDevice* outputDevice)
[email protected]96baf3e2012-10-22 23:09:5561 : DirectRenderer(client, resourceProvider)
[email protected]d61675de42012-09-24 21:32:5762 , m_visible(true)
[email protected]a22ac652013-02-01 03:02:4963 , m_isScissorEnabled(false)
[email protected]d61675de42012-09-24 21:32:5764 , m_outputDevice(outputDevice)
[email protected]d61675de42012-09-24 21:32:5765 , m_skCurrentCanvas(0)
66{
[email protected]96baf3e2012-10-22 23:09:5567 m_resourceProvider->setDefaultResourceType(ResourceProvider::Bitmap);
[email protected]d61675de42012-09-24 21:32:5768
[email protected]ea9d8f22012-12-08 03:39:2969 m_capabilities.maxTextureSize = m_resourceProvider->maxTextureSize();
70 m_capabilities.bestTextureFormat = m_resourceProvider->bestTextureFormat();
[email protected]d61675de42012-09-24 21:32:5771 m_capabilities.usingSetVisibility = true;
[email protected]da983ab02012-12-06 02:32:4072 // The updater can access bitmaps while the SoftwareRenderer is using them.
73 m_capabilities.allowPartialTextureUpdates = true;
[email protected]a22ac652013-02-01 03:02:4974 m_capabilities.usingPartialSwap = true;
[email protected]d61675de42012-09-24 21:32:5775
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{
[email protected]a46f32932012-12-07 21:43:1690 m_outputDevice->DidChangeViewportSize(viewportSize());
[email protected]d61675de42012-09-24 21:32:5791}
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]a46f32932012-12-07 21:43:1696 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]a46f32932012-12-07 21:43:16105 m_outputDevice->Unlock();
[email protected]d61675de42012-09-24 21:32:57106}
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{
[email protected]a22ac652013-02-01 03:02:49115 m_isScissorEnabled = true;
116 setClipRect(m_scissorRect);
[email protected]dc462d782012-11-21 21:43:01117}
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.
[email protected]a22ac652013-02-01 03:02:49125 m_isScissorEnabled = false;
126 SkDevice* device = m_skCurrentCanvas->getDevice();
127 setClipRect(gfx::Rect(device->width(), device->height()));
[email protected]dc462d782012-11-21 21:43:01128}
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]a22ac652013-02-01 03:02:49152 m_isScissorEnabled = true;
153 m_scissorRect = scissorRect;
154 setClipRect(scissorRect);
155}
156
157void SoftwareRenderer::setClipRect(const gfx::Rect& rect)
158{
159 // Skia applies the current matrix to clip rects so we reset it temporary.
160 SkMatrix currentMatrix = m_skCurrentCanvas->getTotalMatrix();
161 m_skCurrentCanvas->resetMatrix();
162 m_skCurrentCanvas->clipRect(gfx::RectToSkRect(rect), SkRegion::kReplace_Op);
163 m_skCurrentCanvas->setMatrix(currentMatrix);
164}
165
166void SoftwareRenderer::clearCanvas(SkColor color)
167{
168 // SkCanvas::clear doesn't respect the current clipping region
169 // so we SkCanvas::drawColor instead if scissoring is active.
170 if (m_isScissorEnabled)
171 m_skCurrentCanvas->drawColor(color, SkXfermode::kSrc_Mode);
172 else
173 m_skCurrentCanvas->clear(color);
[email protected]d61675de42012-09-24 21:32:57174}
175
[email protected]96baf3e2012-10-22 23:09:55176void SoftwareRenderer::clearFramebuffer(DrawingFrame& frame)
[email protected]d61675de42012-09-24 21:32:57177{
[email protected]f57bbc02012-11-21 07:02:15178 if (frame.currentRenderPass->has_transparent_background) {
[email protected]a22ac652013-02-01 03:02:49179 clearCanvas(SkColorSetARGB(0, 0, 0, 0));
[email protected]0b056ee2012-10-15 21:31:21180 } else {
181#ifndef NDEBUG
182 // On DEBUG builds, opaque render passes are cleared to blue to easily see regions that were not drawn on the screen.
[email protected]a22ac652013-02-01 03:02:49183 clearCanvas(SkColorSetARGB(255, 0, 0, 255));
[email protected]0b056ee2012-10-15 21:31:21184#endif
185 }
[email protected]d61675de42012-09-24 21:32:57186}
187
[email protected]96baf3e2012-10-22 23:09:55188void SoftwareRenderer::setDrawViewportSize(const gfx::Size& viewportSize)
[email protected]d61675de42012-09-24 21:32:57189{
190}
191
[email protected]96baf3e2012-10-22 23:09:55192bool SoftwareRenderer::isSoftwareResource(ResourceProvider::ResourceId id) const
[email protected]d61675de42012-09-24 21:32:57193{
194 switch (m_resourceProvider->resourceType(id)) {
[email protected]96baf3e2012-10-22 23:09:55195 case ResourceProvider::GLTexture:
[email protected]d61675de42012-09-24 21:32:57196 return false;
[email protected]96baf3e2012-10-22 23:09:55197 case ResourceProvider::Bitmap:
[email protected]d61675de42012-09-24 21:32:57198 return true;
199 }
200
[email protected]6eb6bb62012-11-10 06:30:59201 LOG(FATAL) << "Invalid resource type.";
[email protected]d61675de42012-09-24 21:32:57202 return false;
203}
204
[email protected]96baf3e2012-10-22 23:09:55205void SoftwareRenderer::drawQuad(DrawingFrame& frame, const DrawQuad* quad)
[email protected]d61675de42012-09-24 21:32:57206{
[email protected]ffbfdc492012-11-15 03:35:32207 TRACE_EVENT0("cc", "SoftwareRenderer::drawQuad");
[email protected]c8686a02012-11-27 08:29:00208 gfx::Transform quadRectMatrix;
[email protected]1bc93f62012-11-17 19:29:50209 quadRectTransform(&quadRectMatrix, quad->quadTransform(), quad->rect);
[email protected]78634b0c2013-01-15 07:49:40210 gfx::Transform contentsDeviceTransform = frame.windowMatrix * frame.projectionMatrix * quadRectMatrix;
211 contentsDeviceTransform.FlattenTo2d();
[email protected]0b056ee2012-10-15 21:31:21212 SkMatrix skDeviceMatrix;
213 toSkMatrix(&skDeviceMatrix, contentsDeviceTransform);
214 m_skCurrentCanvas->setMatrix(skDeviceMatrix);
[email protected]d61675de42012-09-24 21:32:57215
216 m_skCurrentPaint.reset();
[email protected]276508a2012-10-16 00:56:34217 if (!isScaleAndTranslate(skDeviceMatrix)) {
218 m_skCurrentPaint.setAntiAlias(true);
219 m_skCurrentPaint.setFilterBitmap(true);
220 }
[email protected]9cd20a32012-11-17 14:11:27221
222 if (quad->ShouldDrawWithBlending()) {
[email protected]d61675de42012-09-24 21:32:57223 m_skCurrentPaint.setAlpha(quad->opacity() * 255);
[email protected]0b056ee2012-10-15 21:31:21224 m_skCurrentPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
225 } else {
[email protected]d61675de42012-09-24 21:32:57226 m_skCurrentPaint.setXfermodeMode(SkXfermode::kSrc_Mode);
[email protected]0b056ee2012-10-15 21:31:21227 }
[email protected]d61675de42012-09-24 21:32:57228
[email protected]1bc93f62012-11-17 19:29:50229 switch (quad->material) {
[email protected]e48727e2012-11-16 22:10:02230 case DrawQuad::DEBUG_BORDER:
[email protected]c22418b2012-11-20 23:06:26231 drawDebugBorderQuad(frame, DebugBorderDrawQuad::MaterialCast(quad));
[email protected]d61675de42012-09-24 21:32:57232 break;
[email protected]e48727e2012-11-16 22:10:02233 case DrawQuad::SOLID_COLOR:
[email protected]c22418b2012-11-20 23:06:26234 drawSolidColorQuad(frame, SolidColorDrawQuad::MaterialCast(quad));
[email protected]d61675de42012-09-24 21:32:57235 break;
[email protected]e48727e2012-11-16 22:10:02236 case DrawQuad::TEXTURE_CONTENT:
[email protected]c22418b2012-11-20 23:06:26237 drawTextureQuad(frame, TextureDrawQuad::MaterialCast(quad));
[email protected]d61675de42012-09-24 21:32:57238 break;
[email protected]e48727e2012-11-16 22:10:02239 case DrawQuad::TILED_CONTENT:
[email protected]c22418b2012-11-20 23:06:26240 drawTileQuad(frame, TileDrawQuad::MaterialCast(quad));
[email protected]d61675de42012-09-24 21:32:57241 break;
[email protected]e48727e2012-11-16 22:10:02242 case DrawQuad::RENDER_PASS:
[email protected]c22418b2012-11-20 23:06:26243 drawRenderPassQuad(frame, RenderPassDrawQuad::MaterialCast(quad));
[email protected]0b056ee2012-10-15 21:31:21244 break;
[email protected]d61675de42012-09-24 21:32:57245 default:
246 drawUnsupportedQuad(frame, quad);
247 break;
248 }
249
250 m_skCurrentCanvas->resetMatrix();
251}
252
[email protected]96baf3e2012-10-22 23:09:55253void SoftwareRenderer::drawDebugBorderQuad(const DrawingFrame& frame, const DebugBorderDrawQuad* quad)
[email protected]d61675de42012-09-24 21:32:57254{
255 // We need to apply the matrix manually to have pixel-sized stroke width.
256 SkPoint vertices[4];
[email protected]79fbdab02012-11-14 07:28:11257 gfx::RectFToSkRect(quadVertexRect()).toQuad(vertices);
[email protected]d61675de42012-09-24 21:32:57258 SkPoint transformedVertices[4];
259 m_skCurrentCanvas->getTotalMatrix().mapPoints(transformedVertices, vertices, 4);
260 m_skCurrentCanvas->resetMatrix();
261
[email protected]c22418b2012-11-20 23:06:26262 m_skCurrentPaint.setColor(quad->color);
263 m_skCurrentPaint.setAlpha(quad->opacity() * SkColorGetA(quad->color));
[email protected]d61675de42012-09-24 21:32:57264 m_skCurrentPaint.setStyle(SkPaint::kStroke_Style);
[email protected]c22418b2012-11-20 23:06:26265 m_skCurrentPaint.setStrokeWidth(quad->width);
[email protected]d61675de42012-09-24 21:32:57266 m_skCurrentCanvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, transformedVertices, m_skCurrentPaint);
267}
268
[email protected]96baf3e2012-10-22 23:09:55269void SoftwareRenderer::drawSolidColorQuad(const DrawingFrame& frame, const SolidColorDrawQuad* quad)
[email protected]d61675de42012-09-24 21:32:57270{
[email protected]c22418b2012-11-20 23:06:26271 m_skCurrentPaint.setColor(quad->color);
272 m_skCurrentPaint.setAlpha(quad->opacity() * SkColorGetA(quad->color));
[email protected]79fbdab02012-11-14 07:28:11273 m_skCurrentCanvas->drawRect(gfx::RectFToSkRect(quadVertexRect()), m_skCurrentPaint);
[email protected]d61675de42012-09-24 21:32:57274}
275
[email protected]96baf3e2012-10-22 23:09:55276void SoftwareRenderer::drawTextureQuad(const DrawingFrame& frame, const TextureDrawQuad* quad)
[email protected]d61675de42012-09-24 21:32:57277{
[email protected]c22418b2012-11-20 23:06:26278 if (!isSoftwareResource(quad->resource_id)) {
[email protected]d61675de42012-09-24 21:32:57279 drawUnsupportedQuad(frame, quad);
280 return;
281 }
282
283 // FIXME: Add support for non-premultiplied alpha.
[email protected]c22418b2012-11-20 23:06:26284 ResourceProvider::ScopedReadLockSoftware lock(m_resourceProvider, quad->resource_id);
[email protected]058a724a2012-10-30 18:37:02285 const SkBitmap* bitmap = lock.skBitmap();
[email protected]1fd555b2013-01-18 00:13:21286 gfx::RectF uvRect = gfx::ScaleRect(gfx::BoundingRect(quad->uv_top_left, quad->uv_bottom_right),
287 bitmap->width(),
288 bitmap->height());
[email protected]79fbdab02012-11-14 07:28:11289 SkRect skUvRect = gfx::RectFToSkRect(uvRect);
[email protected]c22418b2012-11-20 23:06:26290 if (quad->flipped)
[email protected]d61675de42012-09-24 21:32:57291 m_skCurrentCanvas->scale(1, -1);
[email protected]66dce292012-11-06 09:12:00292 m_skCurrentCanvas->drawBitmapRectToRect(*bitmap, &skUvRect,
[email protected]79fbdab02012-11-14 07:28:11293 gfx::RectFToSkRect(quadVertexRect()),
[email protected]66dce292012-11-06 09:12:00294 &m_skCurrentPaint);
[email protected]d61675de42012-09-24 21:32:57295}
296
[email protected]96baf3e2012-10-22 23:09:55297void SoftwareRenderer::drawTileQuad(const DrawingFrame& frame, const TileDrawQuad* quad)
[email protected]d61675de42012-09-24 21:32:57298{
[email protected]c22418b2012-11-20 23:06:26299 DCHECK(isSoftwareResource(quad->resource_id));
300 ResourceProvider::ScopedReadLockSoftware lock(m_resourceProvider, quad->resource_id);
[email protected]d61675de42012-09-24 21:32:57301
[email protected]c22418b2012-11-20 23:06:26302 SkRect uvRect = gfx::RectFToSkRect(quad->tex_coord_rect);
[email protected]0457b7502012-11-13 21:48:42303 m_skCurrentPaint.setFilterBitmap(true);
[email protected]66dce292012-11-06 09:12:00304 m_skCurrentCanvas->drawBitmapRectToRect(*lock.skBitmap(), &uvRect,
[email protected]79fbdab02012-11-14 07:28:11305 gfx::RectFToSkRect(quadVertexRect()),
[email protected]66dce292012-11-06 09:12:00306 &m_skCurrentPaint);
[email protected]d61675de42012-09-24 21:32:57307}
308
[email protected]96baf3e2012-10-22 23:09:55309void SoftwareRenderer::drawRenderPassQuad(const DrawingFrame& frame, const RenderPassDrawQuad* quad)
[email protected]0b056ee2012-10-15 21:31:21310{
[email protected]c22418b2012-11-20 23:06:26311 CachedResource* contentTexture = m_renderPassTextures.get(quad->render_pass_id);
[email protected]058a724a2012-10-30 18:37:02312 if (!contentTexture || !contentTexture->id())
[email protected]0b056ee2012-10-15 21:31:21313 return;
314
[email protected]058a724a2012-10-30 18:37:02315 DCHECK(isSoftwareResource(contentTexture->id()));
316 ResourceProvider::ScopedReadLockSoftware lock(m_resourceProvider, contentTexture->id());
[email protected]0b056ee2012-10-15 21:31:21317
[email protected]79fbdab02012-11-14 07:28:11318 SkRect destRect = gfx::RectFToSkRect(quadVertexRect());
[email protected]a22ac652013-02-01 03:02:49319 SkRect contentRect = SkRect::MakeWH(quad->rect.width(), quad->rect.height());
[email protected]058a724a2012-10-30 18:37:02320
321 SkMatrix contentMat;
322 contentMat.setRectToRect(contentRect, destRect, SkMatrix::kFill_ScaleToFit);
323
[email protected]a22ac652013-02-01 03:02:49324 const SkBitmap* content = lock.skBitmap();
[email protected]1940c4e2012-12-04 05:08:15325 skia::RefPtr<SkShader> shader = skia::AdoptRef(
326 SkShader::CreateBitmapShader(*content,
327 SkShader::kClamp_TileMode,
328 SkShader::kClamp_TileMode));
[email protected]058a724a2012-10-30 18:37:02329 shader->setLocalMatrix(contentMat);
[email protected]1940c4e2012-12-04 05:08:15330 m_skCurrentPaint.setShader(shader.get());
[email protected]0b056ee2012-10-15 21:31:21331
[email protected]20062042012-12-21 22:16:36332 SkImageFilter* filter = quad->filter.get();
[email protected]632bd7662012-11-14 21:21:54333 if (filter)
334 m_skCurrentPaint.setImageFilter(filter);
335
[email protected]c22418b2012-11-20 23:06:26336 if (quad->mask_resource_id) {
337 ResourceProvider::ScopedReadLockSoftware maskLock(m_resourceProvider, quad->mask_resource_id);
[email protected]058a724a2012-10-30 18:37:02338
339 const SkBitmap* mask = maskLock.skBitmap();
340
341 SkRect maskRect = SkRect::MakeXYWH(
[email protected]458af1e2012-12-13 05:12:18342 quad->mask_uv_rect.x() * mask->width(),
343 quad->mask_uv_rect.y() * mask->height(),
344 quad->mask_uv_rect.width() * mask->width(),
345 quad->mask_uv_rect.height() * mask->height());
[email protected]0b056ee2012-10-15 21:31:21346
347 SkMatrix maskMat;
[email protected]058a724a2012-10-30 18:37:02348 maskMat.setRectToRect(maskRect, destRect, SkMatrix::kFill_ScaleToFit);
[email protected]0b056ee2012-10-15 21:31:21349
[email protected]1940c4e2012-12-04 05:08:15350 skia::RefPtr<SkShader> maskShader = skia::AdoptRef(
351 SkShader::CreateBitmapShader(*mask,
352 SkShader::kClamp_TileMode,
353 SkShader::kClamp_TileMode));
[email protected]0b056ee2012-10-15 21:31:21354 maskShader->setLocalMatrix(maskMat);
355
356 SkPaint maskPaint;
[email protected]1940c4e2012-12-04 05:08:15357 maskPaint.setShader(maskShader.get());
[email protected]0b056ee2012-10-15 21:31:21358
[email protected]1940c4e2012-12-04 05:08:15359 skia::RefPtr<SkLayerRasterizer> maskRasterizer = skia::AdoptRef(new SkLayerRasterizer);
[email protected]0b056ee2012-10-15 21:31:21360 maskRasterizer->addLayer(maskPaint);
361
[email protected]1940c4e2012-12-04 05:08:15362 m_skCurrentPaint.setRasterizer(maskRasterizer.get());
[email protected]0b056ee2012-10-15 21:31:21363 m_skCurrentCanvas->drawRect(destRect, m_skCurrentPaint);
364 } else {
[email protected]058a724a2012-10-30 18:37:02365 // FIXME: Apply background filters and blend with content
[email protected]0b056ee2012-10-15 21:31:21366 m_skCurrentCanvas->drawRect(destRect, m_skCurrentPaint);
367 }
368}
369
[email protected]96baf3e2012-10-22 23:09:55370void SoftwareRenderer::drawUnsupportedQuad(const DrawingFrame& frame, const DrawQuad* quad)
[email protected]d61675de42012-09-24 21:32:57371{
372 m_skCurrentPaint.setColor(SK_ColorMAGENTA);
373 m_skCurrentPaint.setAlpha(quad->opacity() * 255);
[email protected]79fbdab02012-11-14 07:28:11374 m_skCurrentCanvas->drawRect(gfx::RectFToSkRect(quadVertexRect()), m_skCurrentPaint);
[email protected]d61675de42012-09-24 21:32:57375}
376
[email protected]96baf3e2012-10-22 23:09:55377bool SoftwareRenderer::swapBuffers()
[email protected]d61675de42012-09-24 21:32:57378{
[email protected]61de5812012-11-08 07:03:44379 if (m_client->hasImplThread())
[email protected]d61675de42012-09-24 21:32:57380 m_client->onSwapBuffersComplete();
381 return true;
382}
383
[email protected]aad0a0072012-11-01 18:15:58384void SoftwareRenderer::getFramebufferPixels(void *pixels, const gfx::Rect& rect)
[email protected]d61675de42012-09-24 21:32:57385{
[email protected]ffbfdc492012-11-15 03:35:32386 TRACE_EVENT0("cc", "SoftwareRenderer::getFramebufferPixels");
[email protected]a46f32932012-12-07 21:43:16387 SkBitmap fullBitmap = m_outputDevice->Lock(false)->getSkBitmap();
[email protected]d61675de42012-09-24 21:32:57388 SkBitmap subsetBitmap;
[email protected]aad0a0072012-11-01 18:15:58389 SkIRect invertRect = SkIRect::MakeXYWH(rect.x(), viewportSize().height() - rect.bottom(), rect.width(), rect.height());
[email protected]d61675de42012-09-24 21:32:57390 fullBitmap.extractSubset(&subsetBitmap, invertRect);
391 subsetBitmap.copyPixelsTo(pixels, rect.width() * rect.height() * 4, rect.width() * 4);
[email protected]a46f32932012-12-07 21:43:16392 m_outputDevice->Unlock();
[email protected]d61675de42012-09-24 21:32:57393}
394
[email protected]96baf3e2012-10-22 23:09:55395void SoftwareRenderer::setVisible(bool visible)
[email protected]d61675de42012-09-24 21:32:57396{
397 if (m_visible == visible)
398 return;
399 m_visible = visible;
400}
401
[email protected]bc5e77c2012-11-05 20:00:49402} // namespace cc