Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(387)

Side by Side Diff: tools/PictureRenderer.h

Issue 1486153002: Revert of Make NVPR a GL context option instead of a GL context (Closed) Base URL: https://skia.googlesource.com/skia.git@commandbuffer-as-api-02-other-tests-refactor
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tests/GrContextFactoryTest.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
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
8 #ifndef PictureRenderer_DEFINED
9 #define PictureRenderer_DEFINED
10
11 #include "SkCanvas.h"
12 #include "SkDrawFilter.h"
13 #include "SkJSONCPP.h"
14 #include "SkMath.h"
15 #include "SkPaint.h"
16 #include "SkPicture.h"
17 #include "SkPictureRecorder.h"
18 #include "SkRect.h"
19 #include "SkRefCnt.h"
20 #include "SkString.h"
21 #include "SkTDArray.h"
22 #include "SkTypes.h"
23
24 #if SK_SUPPORT_GPU
25 #include "GrContextFactory.h"
26 #include "GrContext.h"
27 #endif
28
29 struct GrContextOptions;
30 class SkBitmap;
31 class SkCanvas;
32 class SkGLContext;
33 class SkThread;
34
35 namespace sk_tools {
36
37 class TiledPictureRenderer;
38
39 class PictureRenderer : public SkRefCnt {
40
41 public:
42 enum SkDeviceTypes {
43 #if SK_ANGLE
44 kAngle_DeviceType,
45 #endif
46 #if SK_COMMAND_BUFFER
47 kCommandBuffer_DeviceType,
48 #endif
49 #if SK_MESA
50 kMesa_DeviceType,
51 #endif
52 kBitmap_DeviceType,
53 #if SK_SUPPORT_GPU
54 kGPU_DeviceType,
55 kNVPR_DeviceType,
56 #endif
57 };
58
59 enum BBoxHierarchyType {
60 kNone_BBoxHierarchyType = 0,
61 kRTree_BBoxHierarchyType,
62
63 kLast_BBoxHierarchyType = kRTree_BBoxHierarchyType,
64 };
65
66 // this uses SkPaint::Flags as a base and adds additional flags
67 enum DrawFilterFlags {
68 kNone_DrawFilterFlag = 0,
69 kHinting_DrawFilterFlag = 0x10000, // toggles between no hinting and nor mal hinting
70 kSlightHinting_DrawFilterFlag = 0x20000, // toggles between slight and n ormal hinting
71 kAAClip_DrawFilterFlag = 0x40000, // toggles between soft and hard clip
72 kMaskFilter_DrawFilterFlag = 0x80000, // toggles on/off mask filters (e. g., blurs)
73 };
74
75 static_assert(!(kMaskFilter_DrawFilterFlag & SkPaint::kAllFlags),
76 "maskfilter_flag_must_be_greater");
77 static_assert(!(kHinting_DrawFilterFlag & SkPaint::kAllFlags),
78 "hinting_flag_must_be_greater");
79 static_assert(!(kSlightHinting_DrawFilterFlag & SkPaint::kAllFlags),
80 "slight_hinting_flag_must_be_greater");
81
82 /**
83 * Called with each new SkPicture to render.
84 *
85 * @param pict The SkPicture to render.
86 * @param writePath The output directory within which this renderer should w rite all images,
87 * or nullptr if this renderer should not write all images.
88 * @param mismatchPath The output directory within which this renderer shoul d write any images
89 * which do not match expectations, or nullptr if this renderer should n ot write mismatches.
90 * @param inputFilename The name of the input file we are rendering.
91 * @param useChecksumBasedFilenames Whether to use checksum-based filenames when writing
92 * bitmap images to disk.
93 * @param useMultiPictureDraw true if MultiPictureDraw should be used for re ndering
94 */
95 virtual void init(const SkPicture* pict,
96 const SkString* writePath,
97 const SkString* mismatchPath,
98 const SkString* inputFilename,
99 bool useChecksumBasedFilenames,
100 bool useMultiPictureDraw);
101
102 /**
103 * Set the viewport so that only the portion listed gets drawn.
104 */
105 void setViewport(SkISize size) { fViewport = size; }
106
107 /**
108 * Set the scale factor at which draw the picture.
109 */
110 void setScaleFactor(SkScalar scale) { fScaleFactor = scale; }
111
112 /**
113 * Perform any setup that should done prior to each iteration of render() wh ich should not be
114 * timed.
115 */
116 virtual void setup() {}
117
118 /**
119 * Perform the work. If this is being called within the context of bench_pi ctures,
120 * this is the step that will be timed.
121 *
122 * Typically "the work" is rendering an SkPicture into a bitmap, but in some subclasses
123 * it is recording the source SkPicture into another SkPicture.
124 *
125 * If fWritePath has been specified, the result of the work will be written to that dir.
126 * If fMismatchPath has been specified, and the actual image result differs from its
127 * expectation, the result of the work will be written to that dir.
128 *
129 * @param out If non-null, the implementing subclass MAY allocate an SkBitma p, copy the
130 * output image into it, and return it here. (Some subclasses ig nore this parameter)
131 * @return bool True if rendering succeeded and, if fWritePath had been spec ified, the output
132 * was successfully written to a file.
133 */
134 virtual bool render(SkBitmap** out = nullptr) = 0;
135
136 /**
137 * Called once finished with a particular SkPicture, before calling init aga in, and before
138 * being done with this Renderer.
139 */
140 virtual void end();
141
142 /**
143 * If this PictureRenderer is actually a TiledPictureRender, return a pointe r to this as a
144 * TiledPictureRender so its methods can be called.
145 */
146 virtual TiledPictureRenderer* getTiledRenderer() { return nullptr; }
147
148 /**
149 * Resets the GPU's state. Does nothing if the backing is raster. For a GPU renderer, calls
150 * flush, swapBuffers and, if callFinish is true, finish.
151 * @param callFinish Whether to call finish.
152 */
153 void resetState(bool callFinish);
154
155 /**
156 * Remove all decoded textures from the CPU caches and all uploaded textures
157 * from the GPU.
158 */
159 void purgeTextures();
160
161 /**
162 * Set the backend type. Returns true on success and false on failure.
163 */
164 #if SK_SUPPORT_GPU
165 bool setDeviceType(SkDeviceTypes deviceType, GrGLStandard gpuAPI = kNone_GrG LStandard) {
166 #else
167 bool setDeviceType(SkDeviceTypes deviceType) {
168 #endif
169 fDeviceType = deviceType;
170 #if SK_SUPPORT_GPU
171 // In case this function is called more than once
172 fGrContext.reset();
173 fGLContext.reset();
174
175 // Set to Native so it will have an initial value.
176 GrContextFactory::GLContextType glContextType = GrContextFactory::kNativ e_GLContextType;
177 GrContextFactory::GLContextType glContextOptions = GrContextFactory::kNo ne_GLContextOptions;
178 #endif
179 switch(deviceType) {
180 case kBitmap_DeviceType:
181 return true;
182 #if SK_SUPPORT_GPU
183 case kGPU_DeviceType:
184 // Already set to GrContextFactory::kNative_GLContextType, above .
185 break;
186 case kNVPR_DeviceType:
187 // Already set to GrContextFactory::kNative_GLContextType, above .
188 glContextOptions = GrContextFactory::kEnableNVPR_GLContextOption s;
189 break;
190 #if SK_ANGLE
191 case kAngle_DeviceType:
192 glContextType = GrContextFactory::kANGLE_GLContextType;
193 break;
194 #endif
195 #if SK_COMMAND_BUFFER
196 case kCommandBuffer_DeviceType:
197 glContextType = GrContextFactory::kCommandBuffer_GLContextType;
198 break;
199 #endif
200 #if SK_MESA
201 case kMesa_DeviceType:
202 glContextType = GrContextFactory::kMESA_GLContextType;
203 break;
204 #endif
205 #endif
206 default:
207 // Invalid device type.
208 return false;
209 }
210 #if SK_SUPPORT_GPU
211 GrContextFactory::ContextInfo* contextInfo = fGrContextFactory.getContex tInfo(glContextType, gpuAPI, glContextOptions);
212 if (contextInfo) {
213 fGrContext.reset(SkRef(contextInfo->fGrContext));
214 fGLContext.reset(SkRef(contextInfo->fGLContext));
215 return true;
216 }
217 return false;
218 #endif
219 }
220
221 #if SK_SUPPORT_GPU
222 void setSampleCount(int sampleCount) {
223 fSampleCount = sampleCount;
224 }
225
226 void setUseDFText(bool useDFText) {
227 fUseDFText = useDFText;
228 }
229 #endif
230
231 void setDrawFilters(DrawFilterFlags const * const filters, const SkString& c onfigName) {
232 fHasDrawFilters = false;
233 fDrawFiltersConfig = configName;
234
235 for (size_t i = 0; i < SK_ARRAY_COUNT(fDrawFilters); ++i) {
236 fDrawFilters[i] = filters[i];
237 fHasDrawFilters |= SkToBool(filters[i]);
238 }
239 }
240
241 void setBBoxHierarchyType(BBoxHierarchyType bbhType) {
242 fBBoxHierarchyType = bbhType;
243 }
244
245 BBoxHierarchyType getBBoxHierarchyType() { return fBBoxHierarchyType; }
246
247 bool isUsingBitmapDevice() {
248 return kBitmap_DeviceType == fDeviceType;
249 }
250
251 virtual SkString getPerIterTimeFormat() { return SkString("%.2f"); }
252
253 virtual SkString getNormalTimeFormat() { return SkString("%6.2f"); }
254
255 /**
256 * Reports the configuration of this PictureRenderer.
257 */
258 SkString getConfigName() {
259 SkString config = this->getConfigNameInternal();
260 if (!fViewport.isEmpty()) {
261 config.appendf("_viewport_%ix%i", fViewport.width(), fViewport.heigh t());
262 }
263 if (fScaleFactor != SK_Scalar1) {
264 config.appendf("_scalar_%f", SkScalarToFloat(fScaleFactor));
265 }
266 if (kRTree_BBoxHierarchyType == fBBoxHierarchyType) {
267 config.append("_rtree");
268 }
269 #if SK_SUPPORT_GPU
270 switch (fDeviceType) {
271 case kGPU_DeviceType:
272 if (fSampleCount) {
273 config.appendf("_msaa%d", fSampleCount);
274 } else if (fUseDFText) {
275 config.append("_gpudft");
276 } else {
277 config.append("_gpu");
278 }
279 break;
280 case kNVPR_DeviceType:
281 config.appendf("_nvprmsaa%d", fSampleCount);
282 break;
283 #if SK_ANGLE
284 case kAngle_DeviceType:
285 config.append("_angle");
286 break;
287 #endif
288 #if SK_COMMAND_BUFFER
289 case kCommandBuffer_DeviceType:
290 config.append("_commandbuffer");
291 break;
292 #endif
293 #if SK_MESA
294 case kMesa_DeviceType:
295 config.append("_mesa");
296 break;
297 #endif
298 default:
299 // Assume that no extra info means bitmap.
300 break;
301 }
302 #endif
303 config.append(fDrawFiltersConfig.c_str());
304 return config;
305 }
306
307 Json::Value getJSONConfig() {
308 Json::Value result;
309
310 result["mode"] = this->getConfigNameInternal().c_str();
311 result["scale"] = 1.0f;
312 if (SK_Scalar1 != fScaleFactor) {
313 result["scale"] = SkScalarToFloat(fScaleFactor);
314 }
315 if (kRTree_BBoxHierarchyType == fBBoxHierarchyType) {
316 result["bbh"] = "rtree";
317 }
318 #if SK_SUPPORT_GPU
319 SkString tmp;
320 switch (fDeviceType) {
321 case kGPU_DeviceType:
322 if (0 != fSampleCount) {
323 tmp = "msaa";
324 tmp.appendS32(fSampleCount);
325 result["config"] = tmp.c_str();
326 } else if (fUseDFText) {
327 result["config"] = "gpudft";
328 } else {
329 result["config"] = "gpu";
330 }
331 break;
332 case kNVPR_DeviceType:
333 tmp = "nvprmsaa";
334 tmp.appendS32(fSampleCount);
335 result["config"] = tmp.c_str();
336 break;
337 #if SK_ANGLE
338 case kAngle_DeviceType:
339 result["config"] = "angle";
340 break;
341 #endif
342 #if SK_COMMAND_BUFFER
343 case kCommandBuffer_DeviceType:
344 result["config"] = "commandbuffer";
345 break;
346 #endif
347 #if SK_MESA
348 case kMesa_DeviceType:
349 result["config"] = "mesa";
350 break;
351 #endif
352 default:
353 // Assume that no extra info means bitmap.
354 break;
355 }
356 #endif
357 return result;
358 }
359
360 #if SK_SUPPORT_GPU
361 bool isUsingGpuDevice() {
362 switch (fDeviceType) {
363 case kGPU_DeviceType:
364 case kNVPR_DeviceType:
365 // fall through
366 #if SK_ANGLE
367 case kAngle_DeviceType:
368 // fall through
369 #endif
370 #if SK_COMMAND_BUFFER
371 case kCommandBuffer_DeviceType:
372 // fall through
373 #endif
374 #if SK_MESA
375 case kMesa_DeviceType:
376 #endif
377 return true;
378 default:
379 return false;
380 }
381 }
382
383 SkGLContext* getGLContext() {
384 return fGLContext;
385 }
386
387 GrContext* getGrContext() {
388 return fGrContext;
389 }
390
391 const GrContextOptions& getGrContextOptions() {
392 return fGrContextFactory.getGlobalOptions();
393 }
394 #endif
395
396 SkCanvas* getCanvas() {
397 return fCanvas;
398 }
399
400 const SkPicture* getPicture() {
401 return fPicture;
402 }
403
404 #if SK_SUPPORT_GPU
405 explicit PictureRenderer(const GrContextOptions &opts)
406 #else
407 PictureRenderer()
408 #endif
409 : fDeviceType(kBitmap_DeviceType)
410 , fBBoxHierarchyType(kNone_BBoxHierarchyType)
411 , fHasDrawFilters(false)
412 , fScaleFactor(SK_Scalar1)
413 #if SK_SUPPORT_GPU
414 , fGrContextFactory(opts)
415 , fSampleCount(0)
416 , fUseDFText(false)
417 #endif
418 {
419 sk_bzero(fDrawFilters, sizeof(fDrawFilters));
420 fViewport.set(0, 0);
421 }
422
423 protected:
424 SkAutoTUnref<SkCanvas> fCanvas;
425 SkAutoTUnref<const SkPicture> fPicture;
426 bool fUseChecksumBasedFilenames;
427 bool fUseMultiPictureDraw;
428 SkDeviceTypes fDeviceType;
429 BBoxHierarchyType fBBoxHierarchyType;
430 bool fHasDrawFilters;
431 DrawFilterFlags fDrawFilters[SkDrawFilter::kTypeCount];
432 SkString fDrawFiltersConfig;
433 SkString fWritePath;
434 SkString fMismatchPath;
435 SkString fInputFilename;
436
437 void buildBBoxHierarchy();
438
439 /**
440 * Return the total width that should be drawn. If the viewport width has be en set greater than
441 * 0, this will be the minimum of the current SkPicture's width and the view port's width.
442 */
443 int getViewWidth();
444
445 /**
446 * Return the total height that should be drawn. If the viewport height has been set greater
447 * than 0, this will be the minimum of the current SkPicture's height and th e viewport's height.
448 */
449 int getViewHeight();
450
451 /**
452 * Scales the provided canvas to the scale factor set by setScaleFactor.
453 */
454 void scaleToScaleFactor(SkCanvas*);
455
456 SkBBHFactory* getFactory();
457 uint32_t recordFlags() const { return 0; }
458 SkCanvas* setupCanvas();
459 virtual SkCanvas* setupCanvas(int width, int height);
460
461 /**
462 * Copy src to dest; if src==nullptr, set dest to empty string.
463 */
464 static void CopyString(SkString* dest, const SkString* src);
465
466 private:
467 SkISize fViewport;
468 SkScalar fScaleFactor;
469 #if SK_SUPPORT_GPU
470 GrContextFactory fGrContextFactory;
471 SkAutoTUnref<GrContext> fGrContext;
472 SkAutoTUnref<SkGLContext> fGLContext;
473 int fSampleCount;
474 bool fUseDFText;
475 #endif
476
477 virtual SkString getConfigNameInternal() = 0;
478
479 typedef SkRefCnt INHERITED;
480 };
481
482 /**
483 * This class does not do any rendering, but its render function executes record ing, which we want
484 * to time.
485 */
486 class RecordPictureRenderer : public PictureRenderer {
487 public:
488 #if SK_SUPPORT_GPU
489 RecordPictureRenderer(const GrContextOptions &opts) : INHERITED(opts) { }
490 #endif
491
492 bool render(SkBitmap** out = nullptr) override;
493
494 SkString getPerIterTimeFormat() override { return SkString("%.4f"); }
495
496 SkString getNormalTimeFormat() override { return SkString("%6.4f"); }
497
498 protected:
499 SkCanvas* setupCanvas(int width, int height) override;
500
501 private:
502 SkString getConfigNameInternal() override;
503
504 typedef PictureRenderer INHERITED;
505 };
506
507 class PipePictureRenderer : public PictureRenderer {
508 public:
509 #if SK_SUPPORT_GPU
510 PipePictureRenderer(const GrContextOptions &opts) : INHERITED(opts) { }
511 #endif
512
513 bool render(SkBitmap** out = nullptr) override;
514
515 private:
516 SkString getConfigNameInternal() override;
517
518 typedef PictureRenderer INHERITED;
519 };
520
521 class SimplePictureRenderer : public PictureRenderer {
522 public:
523 #if SK_SUPPORT_GPU
524 SimplePictureRenderer(const GrContextOptions &opts) : INHERITED(opts) { }
525 #endif
526
527 virtual void init(const SkPicture* pict,
528 const SkString* writePath,
529 const SkString* mismatchPath,
530 const SkString* inputFilename,
531 bool useChecksumBasedFilenames,
532 bool useMultiPictureDraw) override;
533
534 bool render(SkBitmap** out = nullptr) override;
535
536 private:
537 SkString getConfigNameInternal() override;
538
539 typedef PictureRenderer INHERITED;
540 };
541
542 class TiledPictureRenderer : public PictureRenderer {
543 public:
544 #if SK_SUPPORT_GPU
545 TiledPictureRenderer(const GrContextOptions &opts);
546 #else
547 TiledPictureRenderer();
548 #endif
549
550 virtual void init(const SkPicture* pict,
551 const SkString* writePath,
552 const SkString* mismatchPath,
553 const SkString* inputFilename,
554 bool useChecksumBasedFilenames,
555 bool useMultiPictureDraw) override;
556
557 /**
558 * Renders to tiles, rather than a single canvas.
559 * If fWritePath was provided, a separate file is
560 * created for each tile, named "path0.png", "path1.png", etc.
561 */
562 bool render(SkBitmap** out = nullptr) override;
563
564 void end() override;
565
566 void setTileWidth(int width) {
567 fTileWidth = width;
568 }
569
570 int getTileWidth() const {
571 return fTileWidth;
572 }
573
574 void setTileHeight(int height) {
575 fTileHeight = height;
576 }
577
578 int getTileHeight() const {
579 return fTileHeight;
580 }
581
582 void setTileWidthPercentage(double percentage) {
583 fTileWidthPercentage = percentage;
584 }
585
586 double getTileWidthPercentage() const {
587 return fTileWidthPercentage;
588 }
589
590 void setTileHeightPercentage(double percentage) {
591 fTileHeightPercentage = percentage;
592 }
593
594 double getTileHeightPercentage() const {
595 return fTileHeightPercentage;
596 }
597
598 void setTileMinPowerOf2Width(int width) {
599 SkASSERT(SkIsPow2(width) && width > 0);
600 if (!SkIsPow2(width) || width <= 0) {
601 return;
602 }
603
604 fTileMinPowerOf2Width = width;
605 }
606
607 int getTileMinPowerOf2Width() const {
608 return fTileMinPowerOf2Width;
609 }
610
611 TiledPictureRenderer* getTiledRenderer() override { return this; }
612
613 virtual bool supportsTimingIndividualTiles() { return true; }
614
615 /**
616 * Report the number of tiles in the x and y directions. Must not be called before init.
617 * @param x Output parameter identifying the number of tiles in the x direct ion.
618 * @param y Output parameter identifying the number of tiles in the y direct ion.
619 * @return True if the tiles have been set up, and x and y are meaningful. I f false, x and y are
620 * unmodified.
621 */
622 bool tileDimensions(int& x, int&y);
623
624 /**
625 * Move to the next tile and return its indices. Must be called before calli ng drawCurrentTile
626 * for the first time.
627 * @param i Output parameter identifying the column of the next tile to be d rawn on the next
628 * call to drawNextTile.
629 * @param j Output parameter identifying the row of the next tile to be dra wn on the next call
630 * to drawNextTile.
631 * @param True if the tiles have been created and the next tile to be drawn by drawCurrentTile
632 * is within the range of tiles. If false, i and j are unmodified.
633 */
634 bool nextTile(int& i, int& j);
635
636 /**
637 * Render one tile. This will draw the same tile each time it is called unti l nextTile is
638 * called. The tile rendered will depend on how many calls have been made to nextTile.
639 * It is an error to call this without first calling nextTile, or if nextTil e returns false.
640 */
641 void drawCurrentTile();
642
643 protected:
644 SkTDArray<SkIRect> fTileRects;
645
646 SkCanvas* setupCanvas(int width, int height) override;
647 SkString getConfigNameInternal() override;
648
649 private:
650 int fTileWidth;
651 int fTileHeight;
652 double fTileWidthPercentage;
653 double fTileHeightPercentage;
654 int fTileMinPowerOf2Width;
655
656 // These variables are only used for timing individual tiles.
657 // Next tile to draw in fTileRects.
658 int fCurrentTileOffset;
659 // Number of tiles in the x direction.
660 int fTilesX;
661 // Number of tiles in the y direction.
662 int fTilesY;
663
664 void setupTiles();
665 void setupPowerOf2Tiles();
666 bool postRender(SkCanvas*, const SkIRect& tileRect,
667 SkBitmap* tempBM, SkBitmap** out,
668 int tileNumber);
669
670 typedef PictureRenderer INHERITED;
671 };
672
673 /**
674 * This class does not do any rendering, but its render function executes turnin g an SkPictureRecord
675 * into an SkPicturePlayback, which we want to time.
676 */
677 class PlaybackCreationRenderer : public PictureRenderer {
678 public:
679 #if SK_SUPPORT_GPU
680 PlaybackCreationRenderer(const GrContextOptions &opts) : INHERITED(opts) { }
681 #endif
682
683 void setup() override;
684
685 bool render(SkBitmap** out = nullptr) override;
686
687 SkString getPerIterTimeFormat() override { return SkString("%.4f"); }
688
689 SkString getNormalTimeFormat() override { return SkString("%6.4f"); }
690
691 private:
692 SkAutoTDelete<SkPictureRecorder> fRecorder;
693
694 SkString getConfigNameInternal() override;
695
696 typedef PictureRenderer INHERITED;
697 };
698
699 #if SK_SUPPORT_GPU
700 extern PictureRenderer* CreateGatherPixelRefsRenderer(const GrContextOptions& op ts);
701 #else
702 extern PictureRenderer* CreateGatherPixelRefsRenderer();
703 #endif
704
705 }
706
707 #endif // PictureRenderer_DEFINED
OLDNEW
« no previous file with comments | « tests/GrContextFactoryTest.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698