blob: e935f401700abd590c2f92bb10c12772e1c9f1df [file] [log] [blame]
caryclark@google.com411bb722012-11-06 21:29:16 +00001/*
keyar@chromium.org451bb9f2012-07-26 17:27:57 +00002 * 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
8#ifndef PictureRenderer_DEFINED
9#define PictureRenderer_DEFINED
scroggo@google.coma62da2f2012-11-02 21:28:12 +000010
scroggo@google.com161e1ba2013-03-04 16:41:06 +000011#include "SkCanvas.h"
caryclark@google.coma3622372012-11-06 21:26:13 +000012#include "SkDrawFilter.h"
kelvinly4d1a3642014-06-26 11:26:40 -070013#include "SkJSONCPP.h"
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +000014#include "SkMath.h"
reed@google.comea6a3062012-11-06 22:14:54 +000015#include "SkPaint.h"
scroggo@google.com9a412522012-09-07 15:21:18 +000016#include "SkPicture.h"
robertphillips@google.com770963f2014-04-18 18:04:41 +000017#include "SkPictureRecorder.h"
scroggo@google.comacfb30e2012-09-18 14:32:35 +000018#include "SkRect.h"
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000019#include "SkRefCnt.h"
scroggo@google.com9a412522012-09-07 15:21:18 +000020#include "SkString.h"
scroggo@google.coma62da2f2012-11-02 21:28:12 +000021#include "SkTDArray.h"
scroggo@google.coma62da2f2012-11-02 21:28:12 +000022#include "SkTypes.h"
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000023
keyar@chromium.org06125642012-08-20 15:03:33 +000024#if SK_SUPPORT_GPU
25#include "GrContextFactory.h"
26#include "GrContext.h"
27#endif
28
commit-bot@chromium.org90c0fbd2014-05-09 03:18:41 +000029#include "image_expectations.h"
30
bsalomon682c2692015-05-22 14:01:46 -070031struct GrContextOptions;
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000032class SkBitmap;
33class SkCanvas;
kkinnunen9e61bb72014-10-09 05:24:15 -070034class SkGLContext;
scroggo@google.coma62da2f2012-11-02 21:28:12 +000035class SkThread;
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000036
37namespace sk_tools {
38
scroggo@google.comcbcef702012-12-13 22:09:28 +000039class TiledPictureRenderer;
40
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000041class PictureRenderer : public SkRefCnt {
scroggo@google.comcbcef702012-12-13 22:09:28 +000042
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000043public:
keyar@chromium.orgc81686c2012-08-20 15:04:04 +000044 enum SkDeviceTypes {
scroggo@google.com0556ea02013-02-08 19:38:21 +000045#if SK_ANGLE
46 kAngle_DeviceType,
47#endif
hendrikw885bf092015-08-27 10:38:39 -070048#if SK_COMMAND_BUFFER
49 kCommandBuffer_DeviceType,
50#endif
rmistry@google.com6ab96732014-01-06 18:37:24 +000051#if SK_MESA
52 kMesa_DeviceType,
53#endif
keyar@chromium.orgc81686c2012-08-20 15:04:04 +000054 kBitmap_DeviceType,
55#if SK_SUPPORT_GPU
scroggo@google.com0556ea02013-02-08 19:38:21 +000056 kGPU_DeviceType,
commit-bot@chromium.org0fd52702014-03-07 18:41:14 +000057 kNVPR_DeviceType,
keyar@chromium.orgc81686c2012-08-20 15:04:04 +000058#endif
59 };
60
junov@chromium.org9313ca42012-11-02 18:11:49 +000061 enum BBoxHierarchyType {
62 kNone_BBoxHierarchyType = 0,
63 kRTree_BBoxHierarchyType,
commit-bot@chromium.orgcdd0f922014-03-11 17:27:07 +000064
mtklein703dd2e2015-01-09 06:41:48 -080065 kLast_BBoxHierarchyType = kRTree_BBoxHierarchyType,
junov@chromium.org9313ca42012-11-02 18:11:49 +000066 };
67
caryclark@google.coma3622372012-11-06 21:26:13 +000068 // this uses SkPaint::Flags as a base and adds additional flags
69 enum DrawFilterFlags {
70 kNone_DrawFilterFlag = 0,
reed@google.com881b10b2013-05-22 14:03:45 +000071 kHinting_DrawFilterFlag = 0x10000, // toggles between no hinting and normal hinting
72 kSlightHinting_DrawFilterFlag = 0x20000, // toggles between slight and normal hinting
73 kAAClip_DrawFilterFlag = 0x40000, // toggles between soft and hard clip
humper@google.com387db0a2013-07-09 14:13:04 +000074 kMaskFilter_DrawFilterFlag = 0x80000, // toggles on/off mask filters (e.g., blurs)
caryclark@google.coma3622372012-11-06 21:26:13 +000075 };
76
bungeman99fe8222015-08-20 07:57:51 -070077 static_assert(!(kMaskFilter_DrawFilterFlag & SkPaint::kAllFlags),
78 "maskfilter_flag_must_be_greater");
79 static_assert(!(kHinting_DrawFilterFlag & SkPaint::kAllFlags),
80 "hinting_flag_must_be_greater");
81 static_assert(!(kSlightHinting_DrawFilterFlag & SkPaint::kAllFlags),
82 "slight_hinting_flag_must_be_greater");
caryclark@google.coma3622372012-11-06 21:26:13 +000083
scroggo@google.coma62da2f2012-11-02 21:28:12 +000084 /**
85 * Called with each new SkPicture to render.
commit-bot@chromium.orgf5e315c2014-03-19 17:26:07 +000086 *
87 * @param pict The SkPicture to render.
commit-bot@chromium.org3f045172014-05-15 15:10:48 +000088 * @param writePath The output directory within which this renderer should write all images,
halcanary96fcdcc2015-08-27 07:41:13 -070089 * or nullptr if this renderer should not write all images.
commit-bot@chromium.org3f045172014-05-15 15:10:48 +000090 * @param mismatchPath The output directory within which this renderer should write any images
halcanary96fcdcc2015-08-27 07:41:13 -070091 * which do not match expectations, or nullptr if this renderer should not write mismatches.
commit-bot@chromium.orgf5e315c2014-03-19 17:26:07 +000092 * @param inputFilename The name of the input file we are rendering.
93 * @param useChecksumBasedFilenames Whether to use checksum-based filenames when writing
94 * bitmap images to disk.
robertphillips78c71272014-10-09 04:59:19 -070095 * @param useMultiPictureDraw true if MultiPictureDraw should be used for rendering
scroggo@google.coma62da2f2012-11-02 21:28:12 +000096 */
mtklein2a65a232014-08-26 14:07:04 -070097 virtual void init(const SkPicture* pict,
98 const SkString* writePath,
robertphillipsce4dd3d2014-07-07 13:46:35 -070099 const SkString* mismatchPath,
mtklein2a65a232014-08-26 14:07:04 -0700100 const SkString* inputFilename,
robertphillips78c71272014-10-09 04:59:19 -0700101 bool useChecksumBasedFilenames,
102 bool useMultiPictureDraw);
scroggo@google.com9a412522012-09-07 15:21:18 +0000103
104 /**
commit-bot@chromium.org8991c672014-05-22 00:36:05 +0000105 * TODO(epoger): Temporary hack, while we work on http://skbug.com/2584 ('bench_pictures is
106 * timing reading pixels and writing json files'), such that:
107 * - render_pictures can call this method and continue to work
108 * - any other callers (bench_pictures) will skip calls to write() by default
109 */
110 void enableWrites() { fEnableWrites = true; }
111
112 /**
scroggo@google.comc0d5e542012-12-13 21:40:48 +0000113 * Set the viewport so that only the portion listed gets drawn.
114 */
115 void setViewport(SkISize size) { fViewport = size; }
116
117 /**
scroggo@google.com82ec0b02012-12-17 19:25:54 +0000118 * Set the scale factor at which draw the picture.
119 */
120 void setScaleFactor(SkScalar scale) { fScaleFactor = scale; }
121
122 /**
scroggo@google.com9a412522012-09-07 15:21:18 +0000123 * Perform any setup that should done prior to each iteration of render() which should not be
124 * timed.
125 */
126 virtual void setup() {}
127
128 /**
commit-bot@chromium.orgf5e315c2014-03-19 17:26:07 +0000129 * Perform the work. If this is being called within the context of bench_pictures,
130 * this is the step that will be timed.
131 *
132 * Typically "the work" is rendering an SkPicture into a bitmap, but in some subclasses
133 * it is recording the source SkPicture into another SkPicture.
134 *
commit-bot@chromium.org3f045172014-05-15 15:10:48 +0000135 * If fWritePath has been specified, the result of the work will be written to that dir.
136 * If fMismatchPath has been specified, and the actual image result differs from its
137 * expectation, the result of the work will be written to that dir.
commit-bot@chromium.orgf5e315c2014-03-19 17:26:07 +0000138 *
139 * @param out If non-null, the implementing subclass MAY allocate an SkBitmap, copy the
140 * output image into it, and return it here. (Some subclasses ignore this parameter)
commit-bot@chromium.org3f045172014-05-15 15:10:48 +0000141 * @return bool True if rendering succeeded and, if fWritePath had been specified, the output
commit-bot@chromium.orgf5e315c2014-03-19 17:26:07 +0000142 * was successfully written to a file.
scroggo@google.com9a412522012-09-07 15:21:18 +0000143 */
halcanary96fcdcc2015-08-27 07:41:13 -0700144 virtual bool render(SkBitmap** out = nullptr) = 0;
scroggo@google.com9a412522012-09-07 15:21:18 +0000145
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000146 /**
147 * Called once finished with a particular SkPicture, before calling init again, and before
148 * being done with this Renderer.
149 */
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000150 virtual void end();
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000151
scroggo@google.comcbcef702012-12-13 22:09:28 +0000152 /**
153 * If this PictureRenderer is actually a TiledPictureRender, return a pointer to this as a
154 * TiledPictureRender so its methods can be called.
155 */
halcanary96fcdcc2015-08-27 07:41:13 -0700156 virtual TiledPictureRenderer* getTiledRenderer() { return nullptr; }
scroggo@google.comcbcef702012-12-13 22:09:28 +0000157
scroggo@google.com08085f82013-01-28 20:40:24 +0000158 /**
159 * Resets the GPU's state. Does nothing if the backing is raster. For a GPU renderer, calls
commit-bot@chromium.org51c040e2014-03-11 22:58:00 +0000160 * flush, swapBuffers and, if callFinish is true, finish.
scroggo@google.com08085f82013-01-28 20:40:24 +0000161 * @param callFinish Whether to call finish.
162 */
163 void resetState(bool callFinish);
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000164
scroggo@google.com0556ea02013-02-08 19:38:21 +0000165 /**
robertphillips@google.com94d8f1e2013-12-18 17:25:33 +0000166 * Remove all decoded textures from the CPU caches and all uploaded textures
167 * from the GPU.
168 */
169 void purgeTextures();
170
171 /**
scroggo@google.com0556ea02013-02-08 19:38:21 +0000172 * Set the backend type. Returns true on success and false on failure.
173 */
kkinnunen80549fc2014-06-30 06:36:31 -0700174#if SK_SUPPORT_GPU
175 bool setDeviceType(SkDeviceTypes deviceType, GrGLStandard gpuAPI = kNone_GrGLStandard) {
176#else
scroggo@google.com0556ea02013-02-08 19:38:21 +0000177 bool setDeviceType(SkDeviceTypes deviceType) {
kkinnunen80549fc2014-06-30 06:36:31 -0700178#endif
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000179 fDeviceType = deviceType;
scroggo@google.com0556ea02013-02-08 19:38:21 +0000180#if SK_SUPPORT_GPU
181 // In case this function is called more than once
182 SkSafeUnref(fGrContext);
halcanary96fcdcc2015-08-27 07:41:13 -0700183 fGrContext = nullptr;
scroggo@google.com0556ea02013-02-08 19:38:21 +0000184 // Set to Native so it will have an initial value.
185 GrContextFactory::GLContextType glContextType = GrContextFactory::kNative_GLContextType;
186#endif
187 switch(deviceType) {
188 case kBitmap_DeviceType:
189 return true;
190#if SK_SUPPORT_GPU
191 case kGPU_DeviceType:
192 // Already set to GrContextFactory::kNative_GLContextType, above.
193 break;
commit-bot@chromium.org0fd52702014-03-07 18:41:14 +0000194 case kNVPR_DeviceType:
195 glContextType = GrContextFactory::kNVPR_GLContextType;
196 break;
scroggo@google.com0556ea02013-02-08 19:38:21 +0000197#if SK_ANGLE
198 case kAngle_DeviceType:
199 glContextType = GrContextFactory::kANGLE_GLContextType;
200 break;
201#endif
hendrikw885bf092015-08-27 10:38:39 -0700202#if SK_COMMAND_BUFFER
203 case kCommandBuffer_DeviceType:
204 glContextType = GrContextFactory::kCommandBuffer_GLContextType;
205 break;
206#endif
rmistry@google.com6ab96732014-01-06 18:37:24 +0000207#if SK_MESA
208 case kMesa_DeviceType:
209 glContextType = GrContextFactory::kMESA_GLContextType;
210 break;
211#endif
scroggo@google.com0556ea02013-02-08 19:38:21 +0000212#endif
213 default:
214 // Invalid device type.
215 return false;
216 }
217#if SK_SUPPORT_GPU
kkinnunen80549fc2014-06-30 06:36:31 -0700218 fGrContext = fGrContextFactory.get(glContextType, gpuAPI);
halcanary96fcdcc2015-08-27 07:41:13 -0700219 if (nullptr == fGrContext) {
scroggo@google.com0556ea02013-02-08 19:38:21 +0000220 return false;
221 } else {
222 fGrContext->ref();
223 return true;
224 }
225#endif
keyar@chromium.orgfe6391a2012-08-20 15:03:41 +0000226 }
227
jvanverth@google.comf6a90332013-05-02 12:39:37 +0000228#if SK_SUPPORT_GPU
229 void setSampleCount(int sampleCount) {
230 fSampleCount = sampleCount;
231 }
jvanverth4736e142014-11-07 07:12:46 -0800232
233 void setUseDFText(bool useDFText) {
234 fUseDFText = useDFText;
235 }
jvanverth@google.comf6a90332013-05-02 12:39:37 +0000236#endif
237
caryclark@google.come3e940c2012-11-07 16:42:17 +0000238 void setDrawFilters(DrawFilterFlags const * const filters, const SkString& configName) {
fmalita50420202015-06-15 11:48:16 -0700239 fHasDrawFilters = false;
caryclark@google.coma3622372012-11-06 21:26:13 +0000240 fDrawFiltersConfig = configName;
fmalita50420202015-06-15 11:48:16 -0700241
242 for (size_t i = 0; i < SK_ARRAY_COUNT(fDrawFilters); ++i) {
243 fDrawFilters[i] = filters[i];
244 fHasDrawFilters |= SkToBool(filters[i]);
245 }
caryclark@google.coma3622372012-11-06 21:26:13 +0000246 }
247
junov@chromium.org9313ca42012-11-02 18:11:49 +0000248 void setBBoxHierarchyType(BBoxHierarchyType bbhType) {
249 fBBoxHierarchyType = bbhType;
250 }
251
junov@chromium.orge286e842013-03-13 17:27:16 +0000252 BBoxHierarchyType getBBoxHierarchyType() { return fBBoxHierarchyType; }
253
commit-bot@chromium.org205ce482014-05-12 15:37:20 +0000254 void setJsonSummaryPtr(ImageResultsAndExpectations* jsonSummaryPtr) {
commit-bot@chromium.orga3f882c2013-12-13 20:52:36 +0000255 fJsonSummaryPtr = jsonSummaryPtr;
256 }
257
keyar@chromium.orgfe6391a2012-08-20 15:03:41 +0000258 bool isUsingBitmapDevice() {
keyar@chromium.org78a35c52012-08-20 15:03:44 +0000259 return kBitmap_DeviceType == fDeviceType;
keyar@chromium.org4ea96c52012-08-20 15:03:29 +0000260 }
261
scroggo@google.com9a412522012-09-07 15:21:18 +0000262 virtual SkString getPerIterTimeFormat() { return SkString("%.2f"); }
263
264 virtual SkString getNormalTimeFormat() { return SkString("%6.2f"); }
265
scroggo@google.com0a049b82012-11-02 22:01:26 +0000266 /**
267 * Reports the configuration of this PictureRenderer.
268 */
269 SkString getConfigName() {
270 SkString config = this->getConfigNameInternal();
scroggo@google.comc4013c12012-12-13 22:07:08 +0000271 if (!fViewport.isEmpty()) {
272 config.appendf("_viewport_%ix%i", fViewport.width(), fViewport.height());
273 }
commit-bot@chromium.org9de35eb2013-12-20 21:49:33 +0000274 if (fScaleFactor != SK_Scalar1) {
275 config.appendf("_scalar_%f", SkScalarToFloat(fScaleFactor));
276 }
scroggo@google.com0a049b82012-11-02 22:01:26 +0000277 if (kRTree_BBoxHierarchyType == fBBoxHierarchyType) {
278 config.append("_rtree");
279 }
280#if SK_SUPPORT_GPU
robertphillips@google.come8fe4bc2013-02-13 13:26:13 +0000281 switch (fDeviceType) {
scroggo@google.com0556ea02013-02-08 19:38:21 +0000282 case kGPU_DeviceType:
jvanverth@google.comf6a90332013-05-02 12:39:37 +0000283 if (fSampleCount) {
284 config.appendf("_msaa%d", fSampleCount);
jvanverth4736e142014-11-07 07:12:46 -0800285 } else if (fUseDFText) {
286 config.append("_gpudft");
jvanverth@google.comf6a90332013-05-02 12:39:37 +0000287 } else {
288 config.append("_gpu");
289 }
scroggo@google.com0556ea02013-02-08 19:38:21 +0000290 break;
commit-bot@chromium.org0fd52702014-03-07 18:41:14 +0000291 case kNVPR_DeviceType:
292 config.appendf("_nvprmsaa%d", fSampleCount);
293 break;
scroggo@google.com0556ea02013-02-08 19:38:21 +0000294#if SK_ANGLE
295 case kAngle_DeviceType:
296 config.append("_angle");
297 break;
scroggo@google.com0a049b82012-11-02 22:01:26 +0000298#endif
hendrikw885bf092015-08-27 10:38:39 -0700299#if SK_COMMAND_BUFFER
300 case kCommandBuffer_DeviceType:
301 config.append("_commandbuffer");
302 break;
303#endif
rmistry@google.com6ab96732014-01-06 18:37:24 +0000304#if SK_MESA
305 case kMesa_DeviceType:
306 config.append("_mesa");
307 break;
308#endif
scroggo@google.com0556ea02013-02-08 19:38:21 +0000309 default:
310 // Assume that no extra info means bitmap.
311 break;
312 }
robertphillips@google.come8fe4bc2013-02-13 13:26:13 +0000313#endif
caryclark@google.coma3622372012-11-06 21:26:13 +0000314 config.append(fDrawFiltersConfig.c_str());
scroggo@google.com0a049b82012-11-02 22:01:26 +0000315 return config;
316 }
317
kelvinly4d1a3642014-06-26 11:26:40 -0700318 Json::Value getJSONConfig() {
319 Json::Value result;
320
321 result["mode"] = this->getConfigNameInternal().c_str();
322 result["scale"] = 1.0f;
323 if (SK_Scalar1 != fScaleFactor) {
324 result["scale"] = SkScalarToFloat(fScaleFactor);
325 }
326 if (kRTree_BBoxHierarchyType == fBBoxHierarchyType) {
327 result["bbh"] = "rtree";
kelvinly4d1a3642014-06-26 11:26:40 -0700328 }
329#if SK_SUPPORT_GPU
330 SkString tmp;
331 switch (fDeviceType) {
332 case kGPU_DeviceType:
333 if (0 != fSampleCount) {
334 tmp = "msaa";
335 tmp.appendS32(fSampleCount);
336 result["config"] = tmp.c_str();
jvanverth4736e142014-11-07 07:12:46 -0800337 } else if (fUseDFText) {
338 result["config"] = "gpudft";
kelvinly4d1a3642014-06-26 11:26:40 -0700339 } else {
340 result["config"] = "gpu";
341 }
342 break;
343 case kNVPR_DeviceType:
344 tmp = "nvprmsaa";
345 tmp.appendS32(fSampleCount);
346 result["config"] = tmp.c_str();
347 break;
348#if SK_ANGLE
349 case kAngle_DeviceType:
350 result["config"] = "angle";
351 break;
352#endif
hendrikw885bf092015-08-27 10:38:39 -0700353#if SK_COMMAND_BUFFER
354 case kCommandBuffer_DeviceType:
355 result["config"] = "commandbuffer";
356 break;
357#endif
kelvinly4d1a3642014-06-26 11:26:40 -0700358#if SK_MESA
359 case kMesa_DeviceType:
360 result["config"] = "mesa";
361 break;
362#endif
363 default:
364 // Assume that no extra info means bitmap.
365 break;
366 }
367#endif
368 return result;
369 }
370
keyar@chromium.org4ea96c52012-08-20 15:03:29 +0000371#if SK_SUPPORT_GPU
keyar@chromium.orgfe6391a2012-08-20 15:03:41 +0000372 bool isUsingGpuDevice() {
scroggo@google.com0556ea02013-02-08 19:38:21 +0000373 switch (fDeviceType) {
374 case kGPU_DeviceType:
commit-bot@chromium.org0fd52702014-03-07 18:41:14 +0000375 case kNVPR_DeviceType:
scroggo@google.com0556ea02013-02-08 19:38:21 +0000376 // fall through
377#if SK_ANGLE
378 case kAngle_DeviceType:
rmistry@google.com6ab96732014-01-06 18:37:24 +0000379 // fall through
380#endif
hendrikw885bf092015-08-27 10:38:39 -0700381#if SK_COMMAND_BUFFER
382 case kCommandBuffer_DeviceType:
383 // fall through
384#endif
rmistry@google.com6ab96732014-01-06 18:37:24 +0000385#if SK_MESA
386 case kMesa_DeviceType:
scroggo@google.com0556ea02013-02-08 19:38:21 +0000387#endif
388 return true;
389 default:
390 return false;
391 }
keyar@chromium.orgfe6391a2012-08-20 15:03:41 +0000392 }
keyar@chromium.org77a55222012-08-20 15:03:47 +0000393
kkinnunen9e61bb72014-10-09 05:24:15 -0700394 SkGLContext* getGLContext() {
scroggo@google.com0556ea02013-02-08 19:38:21 +0000395 GrContextFactory::GLContextType glContextType
396 = GrContextFactory::kNull_GLContextType;
397 switch(fDeviceType) {
398 case kGPU_DeviceType:
399 glContextType = GrContextFactory::kNative_GLContextType;
400 break;
commit-bot@chromium.org0fd52702014-03-07 18:41:14 +0000401 case kNVPR_DeviceType:
402 glContextType = GrContextFactory::kNVPR_GLContextType;
403 break;
scroggo@google.com0556ea02013-02-08 19:38:21 +0000404#if SK_ANGLE
405 case kAngle_DeviceType:
406 glContextType = GrContextFactory::kANGLE_GLContextType;
407 break;
408#endif
hendrikw885bf092015-08-27 10:38:39 -0700409#if SK_COMMAND_BUFFER
410 case kCommandBuffer_DeviceType:
411 glContextType = GrContextFactory::kCommandBuffer_GLContextType;
412 break;
413#endif
rmistry@google.com6ab96732014-01-06 18:37:24 +0000414#if SK_MESA
415 case kMesa_DeviceType:
416 glContextType = GrContextFactory::kMESA_GLContextType;
417 break;
418#endif
scroggo@google.com0556ea02013-02-08 19:38:21 +0000419 default:
halcanary96fcdcc2015-08-27 07:41:13 -0700420 return nullptr;
keyar@chromium.org77a55222012-08-20 15:03:47 +0000421 }
scroggo@google.com0556ea02013-02-08 19:38:21 +0000422 return fGrContextFactory.getGLContext(glContextType);
keyar@chromium.org77a55222012-08-20 15:03:47 +0000423 }
robertphillips@google.com163c84b2012-09-13 15:40:37 +0000424
425 GrContext* getGrContext() {
426 return fGrContext;
427 }
krajcevskib1aded82014-08-18 07:52:17 -0700428
bsalomon682c2692015-05-22 14:01:46 -0700429 const GrContextOptions& getGrContextOptions() {
krajcevskib1aded82014-08-18 07:52:17 -0700430 return fGrContextFactory.getGlobalOptions();
431 }
keyar@chromium.org4ea96c52012-08-20 15:03:29 +0000432#endif
433
commit-bot@chromium.org145d1c02014-03-16 19:46:36 +0000434 SkCanvas* getCanvas() {
435 return fCanvas;
436 }
437
robertphillipsce4dd3d2014-07-07 13:46:35 -0700438 const SkPicture* getPicture() {
commit-bot@chromium.org8ddc26b2014-03-31 17:55:12 +0000439 return fPicture;
440 }
mtklein2a65a232014-08-26 14:07:04 -0700441
krajcevskib1aded82014-08-18 07:52:17 -0700442#if SK_SUPPORT_GPU
bsalomon682c2692015-05-22 14:01:46 -0700443 explicit PictureRenderer(const GrContextOptions &opts)
krajcevskib1aded82014-08-18 07:52:17 -0700444#else
keyar@chromium.org02dfb122012-08-20 15:03:36 +0000445 PictureRenderer()
krajcevskib1aded82014-08-18 07:52:17 -0700446#endif
halcanary96fcdcc2015-08-27 07:41:13 -0700447 : fJsonSummaryPtr(nullptr)
keyar@chromium.org06125642012-08-20 15:03:33 +0000448 , fDeviceType(kBitmap_DeviceType)
commit-bot@chromium.org8991c672014-05-22 00:36:05 +0000449 , fEnableWrites(false)
junov@chromium.org50ff9bd2012-11-02 19:16:22 +0000450 , fBBoxHierarchyType(kNone_BBoxHierarchyType)
fmalita50420202015-06-15 11:48:16 -0700451 , fHasDrawFilters(false)
scroggo@google.com06d6ac62013-02-08 21:16:19 +0000452 , fScaleFactor(SK_Scalar1)
keyar@chromium.org06125642012-08-20 15:03:33 +0000453#if SK_SUPPORT_GPU
krajcevskib1aded82014-08-18 07:52:17 -0700454 , fGrContextFactory(opts)
halcanary96fcdcc2015-08-27 07:41:13 -0700455 , fGrContext(nullptr)
jvanverth@google.comf6a90332013-05-02 12:39:37 +0000456 , fSampleCount(0)
jvanverth4736e142014-11-07 07:12:46 -0800457 , fUseDFText(false)
keyar@chromium.org06125642012-08-20 15:03:33 +0000458#endif
caryclark@google.come3e940c2012-11-07 16:42:17 +0000459 {
460 sk_bzero(fDrawFilters, sizeof(fDrawFilters));
scroggo@google.comc0d5e542012-12-13 21:40:48 +0000461 fViewport.set(0, 0);
caryclark@google.come3e940c2012-11-07 16:42:17 +0000462 }
keyar@chromium.org06125642012-08-20 15:03:33 +0000463
scroggo@google.com0556ea02013-02-08 19:38:21 +0000464#if SK_SUPPORT_GPU
465 virtual ~PictureRenderer() {
466 SkSafeUnref(fGrContext);
467 }
468#endif
469
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000470protected:
471 SkAutoTUnref<SkCanvas> fCanvas;
robertphillipsce4dd3d2014-07-07 13:46:35 -0700472 SkAutoTUnref<const SkPicture> fPicture;
commit-bot@chromium.orgf5e315c2014-03-19 17:26:07 +0000473 bool fUseChecksumBasedFilenames;
robertphillips78c71272014-10-09 04:59:19 -0700474 bool fUseMultiPictureDraw;
commit-bot@chromium.org205ce482014-05-12 15:37:20 +0000475 ImageResultsAndExpectations* fJsonSummaryPtr;
scroggo@google.comc0d5e542012-12-13 21:40:48 +0000476 SkDeviceTypes fDeviceType;
commit-bot@chromium.org8991c672014-05-22 00:36:05 +0000477 bool fEnableWrites;
scroggo@google.comc0d5e542012-12-13 21:40:48 +0000478 BBoxHierarchyType fBBoxHierarchyType;
fmalita50420202015-06-15 11:48:16 -0700479 bool fHasDrawFilters;
scroggo@google.comc0d5e542012-12-13 21:40:48 +0000480 DrawFilterFlags fDrawFilters[SkDrawFilter::kTypeCount];
481 SkString fDrawFiltersConfig;
commit-bot@chromium.org3f045172014-05-15 15:10:48 +0000482 SkString fWritePath;
483 SkString fMismatchPath;
commit-bot@chromium.orgf5e315c2014-03-19 17:26:07 +0000484 SkString fInputFilename;
keyar@chromium.org06125642012-08-20 15:03:33 +0000485
scroggo@google.comc0d5e542012-12-13 21:40:48 +0000486 void buildBBoxHierarchy();
487
488 /**
489 * Return the total width that should be drawn. If the viewport width has been set greater than
490 * 0, this will be the minimum of the current SkPicture's width and the viewport's width.
491 */
492 int getViewWidth();
493
494 /**
495 * Return the total height that should be drawn. If the viewport height has been set greater
496 * than 0, this will be the minimum of the current SkPicture's height and the viewport's height.
497 */
498 int getViewHeight();
499
scroggo@google.com82ec0b02012-12-17 19:25:54 +0000500 /**
501 * Scales the provided canvas to the scale factor set by setScaleFactor.
502 */
503 void scaleToScaleFactor(SkCanvas*);
504
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +0000505 SkBBHFactory* getFactory();
robertphillips9f1c2412014-06-09 06:25:34 -0700506 uint32_t recordFlags() const { return 0; }
scroggo@google.comc0d5e542012-12-13 21:40:48 +0000507 SkCanvas* setupCanvas();
508 virtual SkCanvas* setupCanvas(int width, int height);
509
commit-bot@chromium.orgf5e315c2014-03-19 17:26:07 +0000510 /**
halcanary96fcdcc2015-08-27 07:41:13 -0700511 * Copy src to dest; if src==nullptr, set dest to empty string.
commit-bot@chromium.orgf5e315c2014-03-19 17:26:07 +0000512 */
513 static void CopyString(SkString* dest, const SkString* src);
514
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000515private:
scroggo@google.comc0d5e542012-12-13 21:40:48 +0000516 SkISize fViewport;
scroggo@google.com82ec0b02012-12-17 19:25:54 +0000517 SkScalar fScaleFactor;
scroggo@google.com0556ea02013-02-08 19:38:21 +0000518#if SK_SUPPORT_GPU
519 GrContextFactory fGrContextFactory;
520 GrContext* fGrContext;
jvanverth@google.comf6a90332013-05-02 12:39:37 +0000521 int fSampleCount;
jvanverth4736e142014-11-07 07:12:46 -0800522 bool fUseDFText;
scroggo@google.com0556ea02013-02-08 19:38:21 +0000523#endif
scroggo@google.comc0d5e542012-12-13 21:40:48 +0000524
scroggo@google.com0a049b82012-11-02 22:01:26 +0000525 virtual SkString getConfigNameInternal() = 0;
526
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000527 typedef SkRefCnt INHERITED;
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000528};
529
scroggo@google.com9a412522012-09-07 15:21:18 +0000530/**
531 * This class does not do any rendering, but its render function executes recording, which we want
532 * to time.
533 */
534class RecordPictureRenderer : public PictureRenderer {
krajcevskib1aded82014-08-18 07:52:17 -0700535public:
536#if SK_SUPPORT_GPU
bsalomon682c2692015-05-22 14:01:46 -0700537 RecordPictureRenderer(const GrContextOptions &opts) : INHERITED(opts) { }
krajcevskib1aded82014-08-18 07:52:17 -0700538#endif
539
halcanary96fcdcc2015-08-27 07:41:13 -0700540 bool render(SkBitmap** out = nullptr) override;
scroggo@google.com9a412522012-09-07 15:21:18 +0000541
mtklein36352bf2015-03-25 18:17:31 -0700542 SkString getPerIterTimeFormat() override { return SkString("%.4f"); }
scroggo@google.com9a412522012-09-07 15:21:18 +0000543
mtklein36352bf2015-03-25 18:17:31 -0700544 SkString getNormalTimeFormat() override { return SkString("%6.4f"); }
scroggo@google.com0a049b82012-11-02 22:01:26 +0000545
djsollen@google.comfd9720c2012-11-06 16:54:40 +0000546protected:
mtklein36352bf2015-03-25 18:17:31 -0700547 SkCanvas* setupCanvas(int width, int height) override;
djsollen@google.comfd9720c2012-11-06 16:54:40 +0000548
scroggo@google.com0a049b82012-11-02 22:01:26 +0000549private:
mtklein36352bf2015-03-25 18:17:31 -0700550 SkString getConfigNameInternal() override;
krajcevskib1aded82014-08-18 07:52:17 -0700551
552 typedef PictureRenderer INHERITED;
scroggo@google.com9a412522012-09-07 15:21:18 +0000553};
554
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000555class PipePictureRenderer : public PictureRenderer {
keyar@chromium.org163b5672012-08-01 17:53:29 +0000556public:
krajcevskib1aded82014-08-18 07:52:17 -0700557#if SK_SUPPORT_GPU
bsalomon682c2692015-05-22 14:01:46 -0700558 PipePictureRenderer(const GrContextOptions &opts) : INHERITED(opts) { }
krajcevskib1aded82014-08-18 07:52:17 -0700559#endif
560
halcanary96fcdcc2015-08-27 07:41:13 -0700561 bool render(SkBitmap** out = nullptr) override;
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000562
563private:
mtklein36352bf2015-03-25 18:17:31 -0700564 SkString getConfigNameInternal() override;
scroggo@google.com0a049b82012-11-02 22:01:26 +0000565
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000566 typedef PictureRenderer INHERITED;
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000567};
568
569class SimplePictureRenderer : public PictureRenderer {
keyar@chromium.org163b5672012-08-01 17:53:29 +0000570public:
krajcevskib1aded82014-08-18 07:52:17 -0700571#if SK_SUPPORT_GPU
bsalomon682c2692015-05-22 14:01:46 -0700572 SimplePictureRenderer(const GrContextOptions &opts) : INHERITED(opts) { }
krajcevskib1aded82014-08-18 07:52:17 -0700573#endif
574
robertphillipsce4dd3d2014-07-07 13:46:35 -0700575 virtual void init(const SkPicture* pict,
mtklein2a65a232014-08-26 14:07:04 -0700576 const SkString* writePath,
robertphillipsce4dd3d2014-07-07 13:46:35 -0700577 const SkString* mismatchPath,
mtklein2a65a232014-08-26 14:07:04 -0700578 const SkString* inputFilename,
robertphillips78c71272014-10-09 04:59:19 -0700579 bool useChecksumBasedFilenames,
mtklein36352bf2015-03-25 18:17:31 -0700580 bool useMultiPictureDraw) override;
junov@chromium.org9313ca42012-11-02 18:11:49 +0000581
halcanary96fcdcc2015-08-27 07:41:13 -0700582 bool render(SkBitmap** out = nullptr) override;
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000583
584private:
mtklein36352bf2015-03-25 18:17:31 -0700585 SkString getConfigNameInternal() override;
scroggo@google.com0a049b82012-11-02 22:01:26 +0000586
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000587 typedef PictureRenderer INHERITED;
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000588};
589
590class TiledPictureRenderer : public PictureRenderer {
591public:
krajcevskib1aded82014-08-18 07:52:17 -0700592#if SK_SUPPORT_GPU
bsalomon682c2692015-05-22 14:01:46 -0700593 TiledPictureRenderer(const GrContextOptions &opts);
krajcevskib1aded82014-08-18 07:52:17 -0700594#else
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000595 TiledPictureRenderer();
krajcevskib1aded82014-08-18 07:52:17 -0700596#endif
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000597
mtklein2a65a232014-08-26 14:07:04 -0700598 virtual void init(const SkPicture* pict,
599 const SkString* writePath,
robertphillipsce4dd3d2014-07-07 13:46:35 -0700600 const SkString* mismatchPath,
mtklein2a65a232014-08-26 14:07:04 -0700601 const SkString* inputFilename,
robertphillips78c71272014-10-09 04:59:19 -0700602 bool useChecksumBasedFilenames,
mtklein36352bf2015-03-25 18:17:31 -0700603 bool useMultiPictureDraw) override;
scroggo@google.com81f9d2e2012-09-20 14:54:21 +0000604
scroggo@google.com81f9d2e2012-09-20 14:54:21 +0000605 /**
commit-bot@chromium.orgf5e315c2014-03-19 17:26:07 +0000606 * Renders to tiles, rather than a single canvas.
commit-bot@chromium.org3f045172014-05-15 15:10:48 +0000607 * If fWritePath was provided, a separate file is
scroggo@google.com81f9d2e2012-09-20 14:54:21 +0000608 * created for each tile, named "path0.png", "path1.png", etc.
scroggo@google.com81f9d2e2012-09-20 14:54:21 +0000609 */
halcanary96fcdcc2015-08-27 07:41:13 -0700610 bool render(SkBitmap** out = nullptr) override;
scroggo@google.com81f9d2e2012-09-20 14:54:21 +0000611
mtklein36352bf2015-03-25 18:17:31 -0700612 void end() override;
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000613
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000614 void setTileWidth(int width) {
615 fTileWidth = width;
616 }
617
618 int getTileWidth() const {
619 return fTileWidth;
620 }
621
622 void setTileHeight(int height) {
623 fTileHeight = height;
624 }
625
626 int getTileHeight() const {
627 return fTileHeight;
628 }
629
630 void setTileWidthPercentage(double percentage) {
631 fTileWidthPercentage = percentage;
632 }
633
keyar@chromium.org163b5672012-08-01 17:53:29 +0000634 double getTileWidthPercentage() const {
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000635 return fTileWidthPercentage;
636 }
637
638 void setTileHeightPercentage(double percentage) {
639 fTileHeightPercentage = percentage;
640 }
641
keyar@chromium.org163b5672012-08-01 17:53:29 +0000642 double getTileHeightPercentage() const {
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000643 return fTileHeightPercentage;
644 }
645
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000646 void setTileMinPowerOf2Width(int width) {
647 SkASSERT(SkIsPow2(width) && width > 0);
648 if (!SkIsPow2(width) || width <= 0) {
649 return;
650 }
651
652 fTileMinPowerOf2Width = width;
653 }
654
655 int getTileMinPowerOf2Width() const {
656 return fTileMinPowerOf2Width;
657 }
658
mtklein36352bf2015-03-25 18:17:31 -0700659 TiledPictureRenderer* getTiledRenderer() override { return this; }
scroggo@google.comcbcef702012-12-13 22:09:28 +0000660
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000661 virtual bool supportsTimingIndividualTiles() { return true; }
662
scroggo@google.comcbcef702012-12-13 22:09:28 +0000663 /**
664 * Report the number of tiles in the x and y directions. Must not be called before init.
665 * @param x Output parameter identifying the number of tiles in the x direction.
666 * @param y Output parameter identifying the number of tiles in the y direction.
667 * @return True if the tiles have been set up, and x and y are meaningful. If false, x and y are
668 * unmodified.
669 */
670 bool tileDimensions(int& x, int&y);
671
672 /**
673 * Move to the next tile and return its indices. Must be called before calling drawCurrentTile
674 * for the first time.
675 * @param i Output parameter identifying the column of the next tile to be drawn on the next
676 * call to drawNextTile.
677 * @param j Output parameter identifying the row of the next tile to be drawn on the next call
678 * to drawNextTile.
679 * @param True if the tiles have been created and the next tile to be drawn by drawCurrentTile
680 * is within the range of tiles. If false, i and j are unmodified.
681 */
682 bool nextTile(int& i, int& j);
683
684 /**
685 * Render one tile. This will draw the same tile each time it is called until nextTile is
686 * called. The tile rendered will depend on how many calls have been made to nextTile.
687 * It is an error to call this without first calling nextTile, or if nextTile returns false.
688 */
689 void drawCurrentTile();
690
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000691protected:
robertphillips78c71272014-10-09 04:59:19 -0700692 SkTDArray<SkIRect> fTileRects;
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000693
mtklein36352bf2015-03-25 18:17:31 -0700694 SkCanvas* setupCanvas(int width, int height) override;
695 SkString getConfigNameInternal() override;
scroggo@google.com0a049b82012-11-02 22:01:26 +0000696
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000697private:
scroggo@google.comcbcef702012-12-13 22:09:28 +0000698 int fTileWidth;
699 int fTileHeight;
700 double fTileWidthPercentage;
701 double fTileHeightPercentage;
702 int fTileMinPowerOf2Width;
703
704 // These variables are only used for timing individual tiles.
705 // Next tile to draw in fTileRects.
706 int fCurrentTileOffset;
707 // Number of tiles in the x direction.
708 int fTilesX;
709 // Number of tiles in the y direction.
710 int fTilesY;
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000711
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000712 void setupTiles();
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000713 void setupPowerOf2Tiles();
mtklein703dd2e2015-01-09 06:41:48 -0800714 bool postRender(SkCanvas*, const SkIRect& tileRect,
robertphillips78c71272014-10-09 04:59:19 -0700715 SkBitmap* tempBM, SkBitmap** out,
716 int tileNumber);
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000717
718 typedef PictureRenderer INHERITED;
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000719};
720
scroggo@google.com9a412522012-09-07 15:21:18 +0000721/**
722 * This class does not do any rendering, but its render function executes turning an SkPictureRecord
723 * into an SkPicturePlayback, which we want to time.
724 */
725class PlaybackCreationRenderer : public PictureRenderer {
726public:
krajcevskib1aded82014-08-18 07:52:17 -0700727#if SK_SUPPORT_GPU
bsalomon682c2692015-05-22 14:01:46 -0700728 PlaybackCreationRenderer(const GrContextOptions &opts) : INHERITED(opts) { }
krajcevskib1aded82014-08-18 07:52:17 -0700729#endif
730
mtklein36352bf2015-03-25 18:17:31 -0700731 void setup() override;
scroggo@google.com9a412522012-09-07 15:21:18 +0000732
halcanary96fcdcc2015-08-27 07:41:13 -0700733 bool render(SkBitmap** out = nullptr) override;
scroggo@google.com9a412522012-09-07 15:21:18 +0000734
mtklein36352bf2015-03-25 18:17:31 -0700735 SkString getPerIterTimeFormat() override { return SkString("%.4f"); }
scroggo@google.com9a412522012-09-07 15:21:18 +0000736
mtklein36352bf2015-03-25 18:17:31 -0700737 SkString getNormalTimeFormat() override { return SkString("%6.4f"); }
scroggo@google.com9a412522012-09-07 15:21:18 +0000738
739private:
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000740 SkAutoTDelete<SkPictureRecorder> fRecorder;
scroggo@google.com0a049b82012-11-02 22:01:26 +0000741
mtklein36352bf2015-03-25 18:17:31 -0700742 SkString getConfigNameInternal() override;
scroggo@google.com0a049b82012-11-02 22:01:26 +0000743
scroggo@google.com9a412522012-09-07 15:21:18 +0000744 typedef PictureRenderer INHERITED;
745};
746
krajcevskib1aded82014-08-18 07:52:17 -0700747#if SK_SUPPORT_GPU
bsalomon682c2692015-05-22 14:01:46 -0700748extern PictureRenderer* CreateGatherPixelRefsRenderer(const GrContextOptions& opts);
krajcevskib1aded82014-08-18 07:52:17 -0700749#else
reed@google.comfe7b1ed2012-11-29 21:00:39 +0000750extern PictureRenderer* CreateGatherPixelRefsRenderer();
krajcevskib1aded82014-08-18 07:52:17 -0700751#endif
reed@google.comfe7b1ed2012-11-29 21:00:39 +0000752
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000753}
754
755#endif // PictureRenderer_DEFINED