blob: c550b6eefb2634af94891e5500f04c21c11c0162 [file] [log] [blame]
keyar@chromium.orgb3fb7c12012-08-20 21:02:49 +00001/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
keyar@chromium.org451bb9f2012-07-26 17:27:57 +00008#include "PictureRenderer.h"
scroggo@google.com58b4ead2012-08-31 16:15:22 +00009#include "picture_utils.h"
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000010#include "SamplePipeControllers.h"
commit-bot@chromium.orga3f882c2013-12-13 20:52:36 +000011#include "SkBitmapHasher.h"
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000012#include "SkCanvas.h"
scroggo@google.com1b1bcc32013-05-21 20:31:23 +000013#include "SkData.h"
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000014#include "SkDevice.h"
robertphillips@google.com94d8f1e2013-12-18 17:25:33 +000015#include "SkDiscardableMemoryPool.h"
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000016#include "SkGPipe.h"
scroggo@google.com58b4ead2012-08-31 16:15:22 +000017#if SK_SUPPORT_GPU
robertphillips@google.comfe1b5362013-02-07 19:45:46 +000018#include "gl/GrGLDefines.h"
scroggo@google.com58b4ead2012-08-31 16:15:22 +000019#include "SkGpuDevice.h"
20#endif
21#include "SkGraphics.h"
22#include "SkImageEncoder.h"
caryclark@google.coma3622372012-11-06 21:26:13 +000023#include "SkMaskFilter.h"
keyar@chromium.orgea826952012-08-23 15:24:13 +000024#include "SkMatrix.h"
robertphillips78c71272014-10-09 04:59:19 -070025#include "SkMultiPictureDraw.h"
commit-bot@chromium.org24c568c2014-04-10 15:39:02 +000026#include "SkOSFile.h"
fmalita50420202015-06-15 11:48:16 -070027#include "SkPaintFilterCanvas.h"
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000028#include "SkPicture.h"
robertphillips@google.com770963f2014-04-18 18:04:41 +000029#include "SkPictureRecorder.h"
scroggo@google.com1b1bcc32013-05-21 20:31:23 +000030#include "SkPictureUtils.h"
31#include "SkPixelRef.h"
scroggo895c43b2014-12-11 10:53:58 -080032#include "SkPixelSerializer.h"
keyar@chromium.orgea826952012-08-23 15:24:13 +000033#include "SkScalar.h"
scroggo@google.coma9e3a362012-11-07 17:52:48 +000034#include "SkStream.h"
keyar@chromium.org9299ede2012-08-21 19:05:08 +000035#include "SkString.h"
robertphillips78c71272014-10-09 04:59:19 -070036#include "SkSurface.h"
scroggo@google.com58b4ead2012-08-31 16:15:22 +000037#include "SkTemplates.h"
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000038#include "SkTDArray.h"
scroggo@google.com58b4ead2012-08-31 16:15:22 +000039#include "SkThreadUtils.h"
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000040#include "SkTypes.h"
robertphillips3e5c2b12015-03-23 05:46:51 -070041#include "sk_tool_utils.h"
keyar@chromium.org4ea96c52012-08-20 15:03:29 +000042
reed@google.come15b2f52013-12-18 04:59:26 +000043static inline SkScalar scalar_log2(SkScalar x) {
reed80ea19c2015-05-12 10:37:34 -070044 static const SkScalar log2_conversion_factor = SkScalarInvert(SkScalarLog(2));
skia.committer@gmail.com3b85deb2013-12-18 07:01:56 +000045
reed@google.come15b2f52013-12-18 04:59:26 +000046 return SkScalarLog(x) * log2_conversion_factor;
47}
48
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000049namespace sk_tools {
50
51enum {
52 kDefaultTileWidth = 256,
53 kDefaultTileHeight = 256
54};
55
mtklein2a65a232014-08-26 14:07:04 -070056void PictureRenderer::init(const SkPicture* pict,
57 const SkString* writePath,
robertphillipsce4dd3d2014-07-07 13:46:35 -070058 const SkString* mismatchPath,
mtklein2a65a232014-08-26 14:07:04 -070059 const SkString* inputFilename,
robertphillips78c71272014-10-09 04:59:19 -070060 bool useChecksumBasedFilenames,
61 bool useMultiPictureDraw) {
commit-bot@chromium.org3f045172014-05-15 15:10:48 +000062 this->CopyString(&fWritePath, writePath);
63 this->CopyString(&fMismatchPath, mismatchPath);
commit-bot@chromium.orgf5e315c2014-03-19 17:26:07 +000064 this->CopyString(&fInputFilename, inputFilename);
65 fUseChecksumBasedFilenames = useChecksumBasedFilenames;
robertphillips78c71272014-10-09 04:59:19 -070066 fUseMultiPictureDraw = useMultiPictureDraw;
commit-bot@chromium.orgf5e315c2014-03-19 17:26:07 +000067
halcanary96fcdcc2015-08-27 07:41:13 -070068 SkASSERT(nullptr == fPicture);
69 SkASSERT(nullptr == fCanvas.get());
bsalomon49f085d2014-09-05 13:34:00 -070070 if (fPicture || fCanvas.get()) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +000071 return;
72 }
73
halcanary96fcdcc2015-08-27 07:41:13 -070074 SkASSERT(pict != nullptr);
75 if (nullptr == pict) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +000076 return;
77 }
78
bungeman77a53de2015-10-01 12:28:49 -070079 fPicture.reset(SkRef(pict));
keyar@chromium.orga474ce32012-08-20 15:03:57 +000080 fCanvas.reset(this->setupCanvas());
81}
82
commit-bot@chromium.orgf5e315c2014-03-19 17:26:07 +000083void PictureRenderer::CopyString(SkString* dest, const SkString* src) {
bsalomon49f085d2014-09-05 13:34:00 -070084 if (src) {
commit-bot@chromium.orgf5e315c2014-03-19 17:26:07 +000085 dest->set(*src);
86 } else {
87 dest->reset();
88 }
89}
90
fmalita50420202015-06-15 11:48:16 -070091class FlagsFilterCanvas : public SkPaintFilterCanvas {
caryclark@google.coma3622372012-11-06 21:26:13 +000092public:
fmalita50420202015-06-15 11:48:16 -070093 FlagsFilterCanvas(SkCanvas* canvas, PictureRenderer::DrawFilterFlags* flags)
94 : INHERITED(canvas->imageInfo().width(), canvas->imageInfo().height())
95 , fFlags(flags) {
96 this->addCanvas(canvas);
97 }
caryclark@google.coma3622372012-11-06 21:26:13 +000098
fmalita50420202015-06-15 11:48:16 -070099protected:
100 void onFilterPaint(SkPaint* paint, Type t) const override {
caryclark@google.coma3622372012-11-06 21:26:13 +0000101 paint->setFlags(paint->getFlags() & ~fFlags[t] & SkPaint::kAllFlags);
robertphillips@google.com49149312013-07-03 15:34:35 +0000102 if (PictureRenderer::kMaskFilter_DrawFilterFlag & fFlags[t]) {
caryclark@google.coma3622372012-11-06 21:26:13 +0000103 SkMaskFilter* maskFilter = paint->getMaskFilter();
bsalomon49f085d2014-09-05 13:34:00 -0700104 if (maskFilter) {
halcanary96fcdcc2015-08-27 07:41:13 -0700105 paint->setMaskFilter(nullptr);
caryclark@google.coma3622372012-11-06 21:26:13 +0000106 }
107 }
108 if (PictureRenderer::kHinting_DrawFilterFlag & fFlags[t]) {
109 paint->setHinting(SkPaint::kNo_Hinting);
110 } else if (PictureRenderer::kSlightHinting_DrawFilterFlag & fFlags[t]) {
111 paint->setHinting(SkPaint::kSlight_Hinting);
112 }
113 }
114
115private:
fmalita50420202015-06-15 11:48:16 -0700116 const PictureRenderer::DrawFilterFlags* fFlags;
caryclark@google.coma3622372012-11-06 21:26:13 +0000117
fmalita50420202015-06-15 11:48:16 -0700118 typedef SkPaintFilterCanvas INHERITED;
119};
caryclark@google.coma3622372012-11-06 21:26:13 +0000120
keyar@chromium.orga474ce32012-08-20 15:03:57 +0000121SkCanvas* PictureRenderer::setupCanvas() {
scroggo@google.comc0d5e542012-12-13 21:40:48 +0000122 const int width = this->getViewWidth();
123 const int height = this->getViewHeight();
124 return this->setupCanvas(width, height);
keyar@chromium.orga474ce32012-08-20 15:03:57 +0000125}
126
127SkCanvas* PictureRenderer::setupCanvas(int width, int height) {
fmalita50420202015-06-15 11:48:16 -0700128 SkAutoTUnref<SkCanvas> canvas;
129
keyar@chromium.org4ea96c52012-08-20 15:03:29 +0000130 switch(fDeviceType) {
131 case kBitmap_DeviceType: {
132 SkBitmap bitmap;
keyar@chromium.orga474ce32012-08-20 15:03:57 +0000133 sk_tools::setup_bitmap(&bitmap, width, height);
halcanary385fe4d2015-08-26 13:07:48 -0700134 canvas.reset(new SkCanvas(bitmap));
keyar@chromium.org4ea96c52012-08-20 15:03:29 +0000135 }
scroggo@google.com82ec0b02012-12-17 19:25:54 +0000136 break;
keyar@chromium.org4ea96c52012-08-20 15:03:29 +0000137#if SK_SUPPORT_GPU
scroggo@google.com0556ea02013-02-08 19:38:21 +0000138#if SK_ANGLE
139 case kAngle_DeviceType:
140 // fall through
141#endif
hendrikw885bf092015-08-27 10:38:39 -0700142#if SK_COMMAND_BUFFER
143 case kCommandBuffer_DeviceType:
144 // fall through
145#endif
rmistry@google.com6ab96732014-01-06 18:37:24 +0000146#if SK_MESA
147 case kMesa_DeviceType:
148 // fall through
149#endif
commit-bot@chromium.org0fd52702014-03-07 18:41:14 +0000150 case kGPU_DeviceType:
151 case kNVPR_DeviceType: {
commit-bot@chromium.orgae403b92013-04-10 17:27:30 +0000152 SkAutoTUnref<GrSurface> target;
scroggo@google.com0556ea02013-02-08 19:38:21 +0000153 if (fGrContext) {
154 // create a render target to back the device
bsalomonf2703d82014-10-28 14:33:06 -0700155 GrSurfaceDesc desc;
scroggo@google.com0556ea02013-02-08 19:38:21 +0000156 desc.fConfig = kSkia8888_GrPixelConfig;
bsalomonf2703d82014-10-28 14:33:06 -0700157 desc.fFlags = kRenderTarget_GrSurfaceFlag;
scroggo@google.com0556ea02013-02-08 19:38:21 +0000158 desc.fWidth = width;
159 desc.fHeight = height;
jvanverth@google.comf6a90332013-05-02 12:39:37 +0000160 desc.fSampleCnt = fSampleCount;
halcanary96fcdcc2015-08-27 07:41:13 -0700161 target.reset(fGrContext->textureProvider()->createTexture(desc, false, nullptr, 0));
scroggo@google.com0556ea02013-02-08 19:38:21 +0000162 }
bsalomonafe30052015-01-16 07:32:33 -0800163
bsalomonafcd7cd2015-08-31 12:39:41 -0700164 uint32_t flags = fUseDFText ? SkSurfaceProps::kUseDeviceIndependentFonts_Flag : 0;
bsalomonafe30052015-01-16 07:32:33 -0800165 SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType);
bsalomon74f681d2015-06-23 14:38:48 -0700166 SkAutoTUnref<SkGpuDevice> device(
167 SkGpuDevice::Create(target->asRenderTarget(), &props,
168 SkGpuDevice::kUninit_InitContents));
bsalomonafe30052015-01-16 07:32:33 -0800169 if (!device) {
halcanary96fcdcc2015-08-27 07:41:13 -0700170 return nullptr;
scroggo@google.com0556ea02013-02-08 19:38:21 +0000171 }
halcanary385fe4d2015-08-26 13:07:48 -0700172 canvas.reset(new SkCanvas(device));
scroggo@google.com0556ea02013-02-08 19:38:21 +0000173 break;
keyar@chromium.org4ea96c52012-08-20 15:03:29 +0000174 }
175#endif
176 default:
177 SkASSERT(0);
halcanary96fcdcc2015-08-27 07:41:13 -0700178 return nullptr;
keyar@chromium.org4ea96c52012-08-20 15:03:29 +0000179 }
fmalita50420202015-06-15 11:48:16 -0700180
181 if (fHasDrawFilters) {
182 if (fDrawFilters[0] & PictureRenderer::kAAClip_DrawFilterFlag) {
183 canvas->setAllowSoftClip(false);
184 }
185
halcanary385fe4d2015-08-26 13:07:48 -0700186 canvas.reset(new FlagsFilterCanvas(canvas.get(), fDrawFilters));
fmalita50420202015-06-15 11:48:16 -0700187 }
188
scroggo@google.com82ec0b02012-12-17 19:25:54 +0000189 this->scaleToScaleFactor(canvas);
commit-bot@chromium.org17cc3ea2014-01-15 14:51:25 +0000190
191 // Pictures often lie about their extent (i.e., claim to be 100x100 but
192 // only ever draw to 90x100). Clear here so the undrawn portion will have
193 // a consistent color
194 canvas->clear(SK_ColorTRANSPARENT);
fmalita50420202015-06-15 11:48:16 -0700195 return canvas.detach();
scroggo@google.com82ec0b02012-12-17 19:25:54 +0000196}
keyar@chromium.orga474ce32012-08-20 15:03:57 +0000197
scroggo@google.com82ec0b02012-12-17 19:25:54 +0000198void PictureRenderer::scaleToScaleFactor(SkCanvas* canvas) {
halcanary96fcdcc2015-08-27 07:41:13 -0700199 SkASSERT(canvas != nullptr);
scroggo@google.com82ec0b02012-12-17 19:25:54 +0000200 if (fScaleFactor != SK_Scalar1) {
201 canvas->scale(fScaleFactor, fScaleFactor);
202 }
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000203}
204
205void PictureRenderer::end() {
scroggo@google.com08085f82013-01-28 20:40:24 +0000206 this->resetState(true);
halcanary96fcdcc2015-08-27 07:41:13 -0700207 fPicture.reset(nullptr);
208 fCanvas.reset(nullptr);
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000209}
210
scroggo@google.comc0d5e542012-12-13 21:40:48 +0000211int PictureRenderer::getViewWidth() {
halcanary96fcdcc2015-08-27 07:41:13 -0700212 SkASSERT(fPicture != nullptr);
robertphillipsa8d7f0b2014-08-29 08:03:56 -0700213 int width = SkScalarCeilToInt(fPicture->cullRect().width() * fScaleFactor);
scroggo@google.comc0d5e542012-12-13 21:40:48 +0000214 if (fViewport.width() > 0) {
215 width = SkMin32(width, fViewport.width());
216 }
217 return width;
218}
219
220int PictureRenderer::getViewHeight() {
halcanary96fcdcc2015-08-27 07:41:13 -0700221 SkASSERT(fPicture != nullptr);
robertphillipsa8d7f0b2014-08-29 08:03:56 -0700222 int height = SkScalarCeilToInt(fPicture->cullRect().height() * fScaleFactor);
scroggo@google.comc0d5e542012-12-13 21:40:48 +0000223 if (fViewport.height() > 0) {
224 height = SkMin32(height, fViewport.height());
225 }
226 return height;
227}
228
junov@chromium.org9313ca42012-11-02 18:11:49 +0000229/** Converts fPicture to a picture that uses a BBoxHierarchy.
230 * PictureRenderer subclasses that are used to test picture playback
231 * should call this method during init.
232 */
233void PictureRenderer::buildBBoxHierarchy() {
bsalomon49f085d2014-09-05 13:34:00 -0700234 SkASSERT(fPicture);
235 if (kNone_BBoxHierarchyType != fBBoxHierarchyType && fPicture) {
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +0000236 SkAutoTDelete<SkBBHFactory> factory(this->getFactory());
237 SkPictureRecorder recorder;
robertphillips81f71b62014-11-11 04:54:49 -0800238 uint32_t flags = this->recordFlags();
239 if (fUseMultiPictureDraw) {
240 flags |= SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag;
241 }
mtklein703dd2e2015-01-09 06:41:48 -0800242 SkCanvas* canvas = recorder.beginRecording(fPicture->cullRect().width(),
robertphillipsa8d7f0b2014-08-29 08:03:56 -0700243 fPicture->cullRect().height(),
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +0000244 factory.get(),
robertphillips81f71b62014-11-11 04:54:49 -0800245 flags);
robertphillipsc5ba71d2014-09-04 08:42:50 -0700246 fPicture->playback(canvas);
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000247 fPicture.reset(recorder.endRecording());
junov@chromium.org9313ca42012-11-02 18:11:49 +0000248 }
249}
250
scroggo@google.com08085f82013-01-28 20:40:24 +0000251void PictureRenderer::resetState(bool callFinish) {
keyar@chromium.org28136b32012-08-20 15:04:15 +0000252#if SK_SUPPORT_GPU
kkinnunen9e61bb72014-10-09 05:24:15 -0700253 SkGLContext* glContext = this->getGLContext();
halcanary96fcdcc2015-08-27 07:41:13 -0700254 if (nullptr == glContext) {
scroggo@google.com0556ea02013-02-08 19:38:21 +0000255 SkASSERT(kBitmap_DeviceType == fDeviceType);
256 return;
257 }
keyar@chromium.org28136b32012-08-20 15:04:15 +0000258
scroggo@google.com0556ea02013-02-08 19:38:21 +0000259 fGrContext->flush();
commit-bot@chromium.org51c040e2014-03-11 22:58:00 +0000260 glContext->swapBuffers();
scroggo@google.com0556ea02013-02-08 19:38:21 +0000261 if (callFinish) {
262 SK_GL(*glContext, Finish());
keyar@chromium.org77a55222012-08-20 15:03:47 +0000263 }
keyar@chromium.orga40c20d2012-08-20 15:04:12 +0000264#endif
keyar@chromium.org77a55222012-08-20 15:03:47 +0000265}
266
robertphillips@google.com94d8f1e2013-12-18 17:25:33 +0000267void PictureRenderer::purgeTextures() {
268 SkDiscardableMemoryPool* pool = SkGetGlobalDiscardableMemoryPool();
269
270 pool->dumpPool();
271
272#if SK_SUPPORT_GPU
kkinnunen9e61bb72014-10-09 05:24:15 -0700273 SkGLContext* glContext = this->getGLContext();
halcanary96fcdcc2015-08-27 07:41:13 -0700274 if (nullptr == glContext) {
robertphillips@google.com94d8f1e2013-12-18 17:25:33 +0000275 SkASSERT(kBitmap_DeviceType == fDeviceType);
276 return;
277 }
278
279 // resetState should've already done this
280 fGrContext->flush();
281
282 fGrContext->purgeAllUnlockedResources();
283#endif
284}
285
scroggo@google.comacfb30e2012-09-18 14:32:35 +0000286///////////////////////////////////////////////////////////////////////////////////////////////
287
djsollen@google.comfd9720c2012-11-06 16:54:40 +0000288SkCanvas* RecordPictureRenderer::setupCanvas(int width, int height) {
289 // defer the canvas setup until the render step
halcanary96fcdcc2015-08-27 07:41:13 -0700290 return nullptr;
djsollen@google.comfd9720c2012-11-06 16:54:40 +0000291}
292
commit-bot@chromium.orgf5e315c2014-03-19 17:26:07 +0000293bool RecordPictureRenderer::render(SkBitmap** out) {
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +0000294 SkAutoTDelete<SkBBHFactory> factory(this->getFactory());
295 SkPictureRecorder recorder;
mtklein703dd2e2015-01-09 06:41:48 -0800296 SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(this->getViewWidth()),
robertphillipsa8d7f0b2014-08-29 08:03:56 -0700297 SkIntToScalar(this->getViewHeight()),
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +0000298 factory.get(),
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000299 this->recordFlags());
300 this->scaleToScaleFactor(canvas);
robertphillipsc5ba71d2014-09-04 08:42:50 -0700301 fPicture->playback(canvas);
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000302 SkAutoTUnref<SkPicture> picture(recorder.endRecording());
commit-bot@chromium.org3f045172014-05-15 15:10:48 +0000303 if (!fWritePath.isEmpty()) {
scroggo@google.coma9e3a362012-11-07 17:52:48 +0000304 // Record the new picture as a new SKP with PNG encoded bitmaps.
tfarinaa8e2e152014-07-28 19:26:58 -0700305 SkString skpPath = SkOSPath::Join(fWritePath.c_str(), fInputFilename.c_str());
scroggo@google.coma9e3a362012-11-07 17:52:48 +0000306 SkFILEWStream stream(skpPath.c_str());
robertphillips3e5c2b12015-03-23 05:46:51 -0700307 sk_tool_utils::PngPixelSerializer serializer;
scroggo895c43b2014-12-11 10:53:58 -0800308 picture->serialize(&stream, &serializer);
scroggo@google.coma9e3a362012-11-07 17:52:48 +0000309 return true;
310 }
scroggo@google.com81f9d2e2012-09-20 14:54:21 +0000311 return false;
scroggo@google.com9a412522012-09-07 15:21:18 +0000312}
313
scroggo@google.com0a049b82012-11-02 22:01:26 +0000314SkString RecordPictureRenderer::getConfigNameInternal() {
315 return SkString("record");
316}
317
scroggo@google.comacfb30e2012-09-18 14:32:35 +0000318///////////////////////////////////////////////////////////////////////////////////////////////
319
commit-bot@chromium.orgf5e315c2014-03-19 17:26:07 +0000320bool PipePictureRenderer::render(SkBitmap** out) {
halcanary96fcdcc2015-08-27 07:41:13 -0700321 SkASSERT(fCanvas.get() != nullptr);
322 SkASSERT(fPicture != nullptr);
323 if (nullptr == fCanvas.get() || nullptr == fPicture) {
scroggo@google.com81f9d2e2012-09-20 14:54:21 +0000324 return false;
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000325 }
326
327 PipeController pipeController(fCanvas.get());
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000328 SkGPipeWriter writer;
329 SkCanvas* pipeCanvas = writer.startRecording(&pipeController);
robertphillips9b14f262014-06-04 05:40:44 -0700330 pipeCanvas->drawPicture(fPicture);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000331 writer.endRecording();
scroggo@google.com9a412522012-09-07 15:21:18 +0000332 fCanvas->flush();
bsalomon49f085d2014-09-05 13:34:00 -0700333 if (out) {
halcanary385fe4d2015-08-26 13:07:48 -0700334 *out = new SkBitmap;
mtklein703dd2e2015-01-09 06:41:48 -0800335 setup_bitmap(*out, SkScalarCeilToInt(fPicture->cullRect().width()),
robertphillipsa8d7f0b2014-08-29 08:03:56 -0700336 SkScalarCeilToInt(fPicture->cullRect().height()));
edisonn@google.com84f548c2012-12-18 22:24:03 +0000337 fCanvas->readPixels(*out, 0, 0);
skia.committer@gmail.coma7d8e3e2012-12-19 02:01:38 +0000338 }
mtklein0c768a22015-10-20 14:29:10 -0700339 return true;
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000340}
341
scroggo@google.com0a049b82012-11-02 22:01:26 +0000342SkString PipePictureRenderer::getConfigNameInternal() {
343 return SkString("pipe");
344}
345
scroggo@google.comacfb30e2012-09-18 14:32:35 +0000346///////////////////////////////////////////////////////////////////////////////////////////////
347
robertphillipsce4dd3d2014-07-07 13:46:35 -0700348void SimplePictureRenderer::init(const SkPicture* picture, const SkString* writePath,
commit-bot@chromium.org3f045172014-05-15 15:10:48 +0000349 const SkString* mismatchPath, const SkString* inputFilename,
robertphillips78c71272014-10-09 04:59:19 -0700350 bool useChecksumBasedFilenames, bool useMultiPictureDraw) {
mtklein703dd2e2015-01-09 06:41:48 -0800351 INHERITED::init(picture, writePath, mismatchPath, inputFilename,
robertphillips78c71272014-10-09 04:59:19 -0700352 useChecksumBasedFilenames, useMultiPictureDraw);
junov@chromium.org9313ca42012-11-02 18:11:49 +0000353 this->buildBBoxHierarchy();
354}
355
commit-bot@chromium.orgf5e315c2014-03-19 17:26:07 +0000356bool SimplePictureRenderer::render(SkBitmap** out) {
halcanary96fcdcc2015-08-27 07:41:13 -0700357 SkASSERT(fCanvas.get() != nullptr);
bsalomon49f085d2014-09-05 13:34:00 -0700358 SkASSERT(fPicture);
halcanary96fcdcc2015-08-27 07:41:13 -0700359 if (nullptr == fCanvas.get() || nullptr == fPicture) {
scroggo@google.com81f9d2e2012-09-20 14:54:21 +0000360 return false;
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000361 }
362
robertphillips78c71272014-10-09 04:59:19 -0700363 if (fUseMultiPictureDraw) {
364 SkMultiPictureDraw mpd;
365
366 mpd.add(fCanvas, fPicture);
367
368 mpd.draw();
369 } else {
370 fCanvas->drawPicture(fPicture);
371 }
scroggo@google.com9a412522012-09-07 15:21:18 +0000372 fCanvas->flush();
bsalomon49f085d2014-09-05 13:34:00 -0700373 if (out) {
halcanary385fe4d2015-08-26 13:07:48 -0700374 *out = new SkBitmap;
mtklein703dd2e2015-01-09 06:41:48 -0800375 setup_bitmap(*out, SkScalarCeilToInt(fPicture->cullRect().width()),
robertphillipsa8d7f0b2014-08-29 08:03:56 -0700376 SkScalarCeilToInt(fPicture->cullRect().height()));
edisonn@google.com84f548c2012-12-18 22:24:03 +0000377 fCanvas->readPixels(*out, 0, 0);
378 }
mtklein0c768a22015-10-20 14:29:10 -0700379 return true;
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000380}
381
scroggo@google.com0a049b82012-11-02 22:01:26 +0000382SkString SimplePictureRenderer::getConfigNameInternal() {
383 return SkString("simple");
384}
385
scroggo@google.comacfb30e2012-09-18 14:32:35 +0000386///////////////////////////////////////////////////////////////////////////////////////////////
387
krajcevskib1aded82014-08-18 07:52:17 -0700388#if SK_SUPPORT_GPU
bsalomon682c2692015-05-22 14:01:46 -0700389TiledPictureRenderer::TiledPictureRenderer(const GrContextOptions& opts)
mtklein2a65a232014-08-26 14:07:04 -0700390 : INHERITED(opts)
krajcevskib1aded82014-08-18 07:52:17 -0700391 , fTileWidth(kDefaultTileWidth)
392#else
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000393TiledPictureRenderer::TiledPictureRenderer()
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000394 : fTileWidth(kDefaultTileWidth)
krajcevskib1aded82014-08-18 07:52:17 -0700395#endif
rileya@google.comb947b912012-08-29 17:35:07 +0000396 , fTileHeight(kDefaultTileHeight)
rileya@google.coma04dc022012-09-10 19:01:38 +0000397 , fTileWidthPercentage(0.0)
rileya@google.comb947b912012-08-29 17:35:07 +0000398 , fTileHeightPercentage(0.0)
scroggo@google.comcbcef702012-12-13 22:09:28 +0000399 , fTileMinPowerOf2Width(0)
400 , fCurrentTileOffset(-1)
401 , fTilesX(0)
402 , fTilesY(0) { }
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000403
robertphillipsce4dd3d2014-07-07 13:46:35 -0700404void TiledPictureRenderer::init(const SkPicture* pict, const SkString* writePath,
commit-bot@chromium.org3f045172014-05-15 15:10:48 +0000405 const SkString* mismatchPath, const SkString* inputFilename,
robertphillips78c71272014-10-09 04:59:19 -0700406 bool useChecksumBasedFilenames, bool useMultiPictureDraw) {
bsalomon49f085d2014-09-05 13:34:00 -0700407 SkASSERT(pict);
scroggo@google.comacfb30e2012-09-18 14:32:35 +0000408 SkASSERT(0 == fTileRects.count());
halcanary96fcdcc2015-08-27 07:41:13 -0700409 if (nullptr == pict || fTileRects.count() != 0) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000410 return;
411 }
412
scroggo@google.comacfb30e2012-09-18 14:32:35 +0000413 // Do not call INHERITED::init(), which would create a (potentially large) canvas which is not
414 // used by bench_pictures.
bungeman77a53de2015-10-01 12:28:49 -0700415 fPicture.reset(SkRef(pict));
commit-bot@chromium.org3f045172014-05-15 15:10:48 +0000416 this->CopyString(&fWritePath, writePath);
417 this->CopyString(&fMismatchPath, mismatchPath);
commit-bot@chromium.orgf5e315c2014-03-19 17:26:07 +0000418 this->CopyString(&fInputFilename, inputFilename);
419 fUseChecksumBasedFilenames = useChecksumBasedFilenames;
robertphillips78c71272014-10-09 04:59:19 -0700420 fUseMultiPictureDraw = useMultiPictureDraw;
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000421 this->buildBBoxHierarchy();
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000422
423 if (fTileWidthPercentage > 0) {
robertphillipsa8d7f0b2014-08-29 08:03:56 -0700424 fTileWidth = SkScalarCeilToInt(float(fTileWidthPercentage * fPicture->cullRect().width() / 100));
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000425 }
426 if (fTileHeightPercentage > 0) {
robertphillipsa8d7f0b2014-08-29 08:03:56 -0700427 fTileHeight = SkScalarCeilToInt(float(fTileHeightPercentage * fPicture->cullRect().height() / 100));
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000428 }
429
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000430 if (fTileMinPowerOf2Width > 0) {
431 this->setupPowerOf2Tiles();
432 } else {
433 this->setupTiles();
434 }
scroggo@google.comcbcef702012-12-13 22:09:28 +0000435 fCanvas.reset(this->setupCanvas(fTileWidth, fTileHeight));
436 // Initialize to -1 so that the first call to nextTile will set this up to draw tile 0 on the
437 // first call to drawCurrentTile.
438 fCurrentTileOffset = -1;
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000439}
440
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000441void TiledPictureRenderer::end() {
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000442 fTileRects.reset();
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000443 this->INHERITED::end();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000444}
445
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000446void TiledPictureRenderer::setupTiles() {
scroggo@google.comc0d5e542012-12-13 21:40:48 +0000447 // Only use enough tiles to cover the viewport
448 const int width = this->getViewWidth();
449 const int height = this->getViewHeight();
450
scroggo@google.comcbcef702012-12-13 22:09:28 +0000451 fTilesX = fTilesY = 0;
scroggo@google.comc0d5e542012-12-13 21:40:48 +0000452 for (int tile_y_start = 0; tile_y_start < height; tile_y_start += fTileHeight) {
scroggo@google.comcbcef702012-12-13 22:09:28 +0000453 fTilesY++;
scroggo@google.comc0d5e542012-12-13 21:40:48 +0000454 for (int tile_x_start = 0; tile_x_start < width; tile_x_start += fTileWidth) {
scroggo@google.comcbcef702012-12-13 22:09:28 +0000455 if (0 == tile_y_start) {
456 // Only count tiles in the X direction on the first pass.
457 fTilesX++;
458 }
robertphillips78c71272014-10-09 04:59:19 -0700459 *fTileRects.append() = SkIRect::MakeXYWH(tile_x_start, tile_y_start,
460 fTileWidth, fTileHeight);
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000461 }
462 }
463}
464
scroggo@google.comcbcef702012-12-13 22:09:28 +0000465bool TiledPictureRenderer::tileDimensions(int &x, int &y) {
halcanary96fcdcc2015-08-27 07:41:13 -0700466 if (fTileRects.count() == 0 || nullptr == fPicture) {
scroggo@google.comcbcef702012-12-13 22:09:28 +0000467 return false;
468 }
469 x = fTilesX;
470 y = fTilesY;
471 return true;
472}
473
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000474// The goal of the powers of two tiles is to minimize the amount of wasted tile
475// space in the width-wise direction and then minimize the number of tiles. The
476// constraints are that every tile must have a pixel width that is a power of
477// two and also be of some minimal width (that is also a power of two).
478//
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000479// This is solved by first taking our picture size and rounding it up to the
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000480// multiple of the minimal width. The binary representation of this rounded
481// value gives us the tiles we need: a bit of value one means we need a tile of
482// that size.
483void TiledPictureRenderer::setupPowerOf2Tiles() {
scroggo@google.comc0d5e542012-12-13 21:40:48 +0000484 // Only use enough tiles to cover the viewport
485 const int width = this->getViewWidth();
486 const int height = this->getViewHeight();
487
488 int rounded_value = width;
489 if (width % fTileMinPowerOf2Width != 0) {
490 rounded_value = width - (width % fTileMinPowerOf2Width) + fTileMinPowerOf2Width;
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000491 }
492
reed@google.come15b2f52013-12-18 04:59:26 +0000493 int num_bits = SkScalarCeilToInt(scalar_log2(SkIntToScalar(width)));
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000494 int largest_possible_tile_size = 1 << num_bits;
495
scroggo@google.comcbcef702012-12-13 22:09:28 +0000496 fTilesX = fTilesY = 0;
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000497 // The tile height is constant for a particular picture.
scroggo@google.comc0d5e542012-12-13 21:40:48 +0000498 for (int tile_y_start = 0; tile_y_start < height; tile_y_start += fTileHeight) {
scroggo@google.comcbcef702012-12-13 22:09:28 +0000499 fTilesY++;
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000500 int tile_x_start = 0;
501 int current_width = largest_possible_tile_size;
scroggo@google.comacfb30e2012-09-18 14:32:35 +0000502 // Set fTileWidth to be the width of the widest tile, so that each canvas is large enough
503 // to draw each tile.
504 fTileWidth = current_width;
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000505
506 while (current_width >= fTileMinPowerOf2Width) {
507 // It is very important this is a bitwise AND.
508 if (current_width & rounded_value) {
scroggo@google.comcbcef702012-12-13 22:09:28 +0000509 if (0 == tile_y_start) {
510 // Only count tiles in the X direction on the first pass.
511 fTilesX++;
512 }
robertphillips78c71272014-10-09 04:59:19 -0700513 *fTileRects.append() = SkIRect::MakeXYWH(tile_x_start, tile_y_start,
514 current_width, fTileHeight);
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000515 tile_x_start += current_width;
516 }
517
518 current_width >>= 1;
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000519 }
520 }
521}
522
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000523/**
commit-bot@chromium.org145d1c02014-03-16 19:46:36 +0000524 * Draw the specified picture to the canvas translated to rectangle provided, so that this mini
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000525 * canvas represents the rectangle's portion of the overall picture.
526 * Saves and restores so that the initial clip and matrix return to their state before this function
527 * is called.
528 */
mtklein2a65a232014-08-26 14:07:04 -0700529static void draw_tile_to_canvas(SkCanvas* canvas,
robertphillips78c71272014-10-09 04:59:19 -0700530 const SkIRect& tileRect,
robertphillipsce4dd3d2014-07-07 13:46:35 -0700531 const SkPicture* picture) {
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000532 int saveCount = canvas->save();
scroggo@google.com82ec0b02012-12-17 19:25:54 +0000533 // Translate so that we draw the correct portion of the picture.
534 // Perform a postTranslate so that the scaleFactor does not interfere with the positioning.
535 SkMatrix mat(canvas->getTotalMatrix());
robertphillips78c71272014-10-09 04:59:19 -0700536 mat.postTranslate(-SkIntToScalar(tileRect.fLeft), -SkIntToScalar(tileRect.fTop));
scroggo@google.com82ec0b02012-12-17 19:25:54 +0000537 canvas->setMatrix(mat);
robertphillips43044dd2014-11-28 07:42:16 -0800538 canvas->clipRect(SkRect::Make(tileRect));
robertphillips4a36d9a2014-10-20 08:45:57 -0700539 canvas->clear(SK_ColorTRANSPARENT); // Not every picture covers the entirety of every tile
robertphillips9b14f262014-06-04 05:40:44 -0700540 canvas->drawPicture(picture);
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000541 canvas->restoreToCount(saveCount);
542 canvas->flush();
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000543}
544
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000545///////////////////////////////////////////////////////////////////////////////////////////////
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000546
commit-bot@chromium.orga3f882c2013-12-13 20:52:36 +0000547/**
548 * Copies the entirety of the src bitmap (typically a tile) into a portion of the dst bitmap.
549 * If the src bitmap is too large to fit within the dst bitmap after the x and y
550 * offsets have been applied, any excess will be ignored (so only the top-left portion of the
551 * src bitmap will be copied).
552 *
553 * @param src source bitmap
554 * @param dst destination bitmap
555 * @param xOffset x-offset within destination bitmap
556 * @param yOffset y-offset within destination bitmap
557 */
558static void bitmapCopyAtOffset(const SkBitmap& src, SkBitmap* dst,
559 int xOffset, int yOffset) {
560 for (int y = 0; y <src.height() && y + yOffset < dst->height() ; y++) {
561 for (int x = 0; x < src.width() && x + xOffset < dst->width() ; x++) {
562 *dst->getAddr32(xOffset + x, yOffset + y) = *src.getAddr32(x, y);
edisonn@google.com84f548c2012-12-18 22:24:03 +0000563 }
564 }
565}
566
scroggo@google.comcbcef702012-12-13 22:09:28 +0000567bool TiledPictureRenderer::nextTile(int &i, int &j) {
568 if (++fCurrentTileOffset < fTileRects.count()) {
569 i = fCurrentTileOffset % fTilesX;
570 j = fCurrentTileOffset / fTilesX;
571 return true;
572 }
573 return false;
574}
575
576void TiledPictureRenderer::drawCurrentTile() {
577 SkASSERT(fCurrentTileOffset >= 0 && fCurrentTileOffset < fTileRects.count());
commit-bot@chromium.org145d1c02014-03-16 19:46:36 +0000578 draw_tile_to_canvas(fCanvas, fTileRects[fCurrentTileOffset], fPicture);
scroggo@google.comcbcef702012-12-13 22:09:28 +0000579}
580
mtklein703dd2e2015-01-09 06:41:48 -0800581bool TiledPictureRenderer::postRender(SkCanvas* canvas, const SkIRect& tileRect,
robertphillips78c71272014-10-09 04:59:19 -0700582 SkBitmap* tempBM, SkBitmap** out,
583 int tileNumber) {
584 bool success = true;
585
robertphillips78c71272014-10-09 04:59:19 -0700586 if (out) {
587 if (canvas->readPixels(tempBM, 0, 0)) {
588 // Add this tile to the entire bitmap.
589 bitmapCopyAtOffset(*tempBM, *out, tileRect.left(), tileRect.top());
590 } else {
591 success = false;
592 }
593 }
594
595 return success;
596}
597
commit-bot@chromium.orgf5e315c2014-03-19 17:26:07 +0000598bool TiledPictureRenderer::render(SkBitmap** out) {
halcanary96fcdcc2015-08-27 07:41:13 -0700599 SkASSERT(fPicture != nullptr);
600 if (nullptr == fPicture) {
scroggo@google.com81f9d2e2012-09-20 14:54:21 +0000601 return false;
scroggo@google.comacfb30e2012-09-18 14:32:35 +0000602 }
603
edisonn@google.com84f548c2012-12-18 22:24:03 +0000604 SkBitmap bitmap;
robertphillips78c71272014-10-09 04:59:19 -0700605 if (out) {
halcanary385fe4d2015-08-26 13:07:48 -0700606 *out = new SkBitmap;
mtklein703dd2e2015-01-09 06:41:48 -0800607 setup_bitmap(*out, SkScalarCeilToInt(fPicture->cullRect().width()),
robertphillipsa8d7f0b2014-08-29 08:03:56 -0700608 SkScalarCeilToInt(fPicture->cullRect().height()));
edisonn@google.com84f548c2012-12-18 22:24:03 +0000609 setup_bitmap(&bitmap, fTileWidth, fTileHeight);
610 }
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000611 bool success = true;
robertphillips78c71272014-10-09 04:59:19 -0700612
613 if (fUseMultiPictureDraw) {
614 SkMultiPictureDraw mpd;
615 SkTDArray<SkSurface*> surfaces;
616 surfaces.setReserve(fTileRects.count());
617
618 // Create a separate SkSurface/SkCanvas for each tile along with a
619 // translated version of the skp (to mimic Chrome's behavior) and
620 // feed all such pairs to the MultiPictureDraw.
621 for (int i = 0; i < fTileRects.count(); ++i) {
622 SkImageInfo ii = fCanvas->imageInfo().makeWH(fTileRects[i].width(),
623 fTileRects[i].height());
624 *surfaces.append() = fCanvas->newSurface(ii);
625 surfaces[i]->getCanvas()->setMatrix(fCanvas->getTotalMatrix());
626
627 SkPictureRecorder recorder;
robertphillips81f71b62014-11-11 04:54:49 -0800628 SkRTreeFactory bbhFactory;
629
robertphillips78c71272014-10-09 04:59:19 -0700630 SkCanvas* c = recorder.beginRecording(SkIntToScalar(fTileRects[i].width()),
robertphillips81f71b62014-11-11 04:54:49 -0800631 SkIntToScalar(fTileRects[i].height()),
632 &bbhFactory,
633 SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag);
robertphillips78c71272014-10-09 04:59:19 -0700634 c->save();
635 SkMatrix mat;
636 mat.setTranslate(-SkIntToScalar(fTileRects[i].fLeft),
637 -SkIntToScalar(fTileRects[i].fTop));
638 c->setMatrix(mat);
639 c->drawPicture(fPicture);
640 c->restore();
641
642 SkAutoTUnref<SkPicture> xlatedPicture(recorder.endRecording());
643
644 mpd.add(surfaces[i]->getCanvas(), xlatedPicture);
commit-bot@chromium.org8991c672014-05-22 00:36:05 +0000645 }
robertphillips78c71272014-10-09 04:59:19 -0700646
647 // Render all the buffered SkCanvases/SkPictures
648 mpd.draw();
649
650 // Sort out the results and cleanup the allocated surfaces
651 for (int i = 0; i < fTileRects.count(); ++i) {
652 success &= this->postRender(surfaces[i]->getCanvas(), fTileRects[i], &bitmap, out, i);
653 surfaces[i]->unref();
654 }
655 } else {
656 for (int i = 0; i < fTileRects.count(); ++i) {
657 draw_tile_to_canvas(fCanvas, fTileRects[i], fPicture);
658 success &= this->postRender(fCanvas, fTileRects[i], &bitmap, out, i);
edisonn@google.com84f548c2012-12-18 22:24:03 +0000659 }
keyar@chromium.org163b5672012-08-01 17:53:29 +0000660 }
robertphillips78c71272014-10-09 04:59:19 -0700661
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000662 return success;
keyar@chromium.org163b5672012-08-01 17:53:29 +0000663}
664
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000665SkCanvas* TiledPictureRenderer::setupCanvas(int width, int height) {
666 SkCanvas* canvas = this->INHERITED::setupCanvas(width, height);
bsalomon49f085d2014-09-05 13:34:00 -0700667 SkASSERT(fPicture);
scroggo@google.com82ec0b02012-12-17 19:25:54 +0000668 // Clip the tile to an area that is completely inside both the SkPicture and the viewport. This
669 // is mostly important for tiles on the right and bottom edges as they may go over this area and
670 // the picture may have some commands that draw outside of this area and so should not actually
671 // be written.
672 // Uses a clipRegion so that it will be unaffected by the scale factor, which may have been set
673 // by INHERITED::setupCanvas.
674 SkRegion clipRegion;
675 clipRegion.setRect(0, 0, this->getViewWidth(), this->getViewHeight());
676 canvas->clipRegion(clipRegion);
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000677 return canvas;
678}
scroggo@google.com0a049b82012-11-02 22:01:26 +0000679
680SkString TiledPictureRenderer::getConfigNameInternal() {
681 SkString name;
682 if (fTileMinPowerOf2Width > 0) {
683 name.append("pow2tile_");
684 name.appendf("%i", fTileMinPowerOf2Width);
685 } else {
686 name.append("tile_");
687 if (fTileWidthPercentage > 0) {
688 name.appendf("%.f%%", fTileWidthPercentage);
689 } else {
690 name.appendf("%i", fTileWidth);
691 }
692 }
693 name.append("x");
694 if (fTileHeightPercentage > 0) {
695 name.appendf("%.f%%", fTileHeightPercentage);
696 } else {
697 name.appendf("%i", fTileHeight);
698 }
699 return name;
700}
701
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000702///////////////////////////////////////////////////////////////////////////////////////////////
703
scroggo@google.com9a412522012-09-07 15:21:18 +0000704void PlaybackCreationRenderer::setup() {
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +0000705 SkAutoTDelete<SkBBHFactory> factory(this->getFactory());
halcanary385fe4d2015-08-26 13:07:48 -0700706 fRecorder.reset(new SkPictureRecorder);
mtklein703dd2e2015-01-09 06:41:48 -0800707 SkCanvas* canvas = fRecorder->beginRecording(SkIntToScalar(this->getViewWidth()),
robertphillipsa8d7f0b2014-08-29 08:03:56 -0700708 SkIntToScalar(this->getViewHeight()),
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +0000709 factory.get(),
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000710 this->recordFlags());
711 this->scaleToScaleFactor(canvas);
robertphillips9b14f262014-06-04 05:40:44 -0700712 canvas->drawPicture(fPicture);
scroggo@google.com9a412522012-09-07 15:21:18 +0000713}
714
commit-bot@chromium.orgf5e315c2014-03-19 17:26:07 +0000715bool PlaybackCreationRenderer::render(SkBitmap** out) {
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000716 fPicture.reset(fRecorder->endRecording());
scroggo@google.com81f9d2e2012-09-20 14:54:21 +0000717 // Since this class does not actually render, return false.
718 return false;
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000719}
720
scroggo@google.com0a049b82012-11-02 22:01:26 +0000721SkString PlaybackCreationRenderer::getConfigNameInternal() {
722 return SkString("playback_creation");
723}
724
junov@chromium.org9313ca42012-11-02 18:11:49 +0000725///////////////////////////////////////////////////////////////////////////////////////////////
726// SkPicture variants for each BBoxHierarchy type
727
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +0000728SkBBHFactory* PictureRenderer::getFactory() {
junov@chromium.org9313ca42012-11-02 18:11:49 +0000729 switch (fBBoxHierarchyType) {
730 case kNone_BBoxHierarchyType:
halcanary96fcdcc2015-08-27 07:41:13 -0700731 return nullptr;
junov@chromium.org9313ca42012-11-02 18:11:49 +0000732 case kRTree_BBoxHierarchyType:
halcanary385fe4d2015-08-26 13:07:48 -0700733 return new SkRTreeFactory;
junov@chromium.org9313ca42012-11-02 18:11:49 +0000734 }
735 SkASSERT(0); // invalid bbhType
halcanary96fcdcc2015-08-27 07:41:13 -0700736 return nullptr;
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000737}
junov@chromium.org9313ca42012-11-02 18:11:49 +0000738
739} // namespace sk_tools