blob: d16556cb1c3b7460c722123d00eacd2b3d550b69 [file] [log] [blame]
joshualittc9dd93c2015-10-15 09:49:31 -07001/*
2 * Copyright 2015 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 WrappedBenchmark_DEFINED
9#define WrappedBenchmark_DEFINED
10
11#include "Benchmark.h"
cdalton0f6cca82015-11-24 08:54:29 -080012#include "SkDevice.h"
joshualittc9dd93c2015-10-15 09:49:31 -070013#include "SkSurface.h"
cdalton0f6cca82015-11-24 08:54:29 -080014#include "GrContext.h"
15#include "GrRenderTarget.h"
joshualittc9dd93c2015-10-15 09:49:31 -070016
17// Wrap some other benchmark to allow specialization to either
18// cpu or gpu backends. The derived class will override 'setupOffScreen'
19// to create an offscreen surface in which the actual rendering will occur.
20class WrappedBenchmark : public Benchmark {
21public:
22 // Takes ownership of caller's ref on `bench`.
cdaltonc70483f2015-10-26 13:14:36 -070023 explicit WrappedBenchmark(const SkSurfaceProps& surfaceProps, Benchmark* bench)
24 : fSurfaceProps(surfaceProps)
25 , fBench(bench) {}
26
27 const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; }
joshualittc9dd93c2015-10-15 09:49:31 -070028
29 const char* onGetName() override { return fBench->getName(); }
30 const char* onGetUniqueName() override { return fBench->getUniqueName(); }
31
32 void onDelayedSetup() override { fBench->delayedSetup(); }
33 void onPerCanvasPreDraw(SkCanvas* canvas) override {
cdalton0f6cca82015-11-24 08:54:29 -080034 this->setupOffScreen(canvas);
35 fOffScreen->getCanvas()->clear(SK_ColorWHITE);
joshualittc9dd93c2015-10-15 09:49:31 -070036 fBench->perCanvasPreDraw(fOffScreen->getCanvas());
37 }
38 void onPreDraw(SkCanvas* canvas) override {
39 SkASSERT(fOffScreen.get());
40 fBench->preDraw(fOffScreen->getCanvas());
41 }
42 void onPostDraw(SkCanvas* canvas) override {
43 SkASSERT(fOffScreen.get());
44 fBench->postDraw(fOffScreen->getCanvas());
45 }
46 void onPerCanvasPostDraw(SkCanvas* canvas) override {
47 SkASSERT(fOffScreen.get());
48 fBench->perCanvasPostDraw(fOffScreen->getCanvas());
49 }
50
51 void onDraw(int loops, SkCanvas* canvas) override {
52 SkASSERT(fOffScreen.get());
53 fBench->draw(loops, fOffScreen->getCanvas());
cdalton0f6cca82015-11-24 08:54:29 -080054 this->blitToScreen(canvas);
joshualittc9dd93c2015-10-15 09:49:31 -070055 }
56
57 virtual SkIPoint onGetSize() override { return fBench->getSize(); }
58
cdalton0f6cca82015-11-24 08:54:29 -080059protected:
60 virtual void setupOffScreen(SkCanvas*)=0;
61
62 void blitToScreen(SkCanvas* canvas) {
63 int w = SkTMin(fBench->getSize().fX, fOffScreen->width());
64 int h = SkTMin(fBench->getSize().fY, fOffScreen->width());
65 this->onBlitToScreen(canvas, w, h);
66 }
67
68 virtual void onBlitToScreen(SkCanvas* canvas, int w, int h) = 0;
joshualittc9dd93c2015-10-15 09:49:31 -070069
cdaltonc70483f2015-10-26 13:14:36 -070070 SkSurfaceProps fSurfaceProps;
joshualittc9dd93c2015-10-15 09:49:31 -070071 SkAutoTUnref<SkSurface> fOffScreen;
72 SkAutoTUnref<Benchmark> fBench;
73};
74
75// Create a raster surface for off screen rendering
76class CpuWrappedBenchmark : public WrappedBenchmark {
77public:
cdaltonc70483f2015-10-26 13:14:36 -070078 explicit CpuWrappedBenchmark(const SkSurfaceProps& surfaceProps, Benchmark* bench)
79 : INHERITED(surfaceProps, bench) {}
joshualittc9dd93c2015-10-15 09:49:31 -070080
81private:
cdalton0f6cca82015-11-24 08:54:29 -080082 void setupOffScreen(SkCanvas* canvas) override {
83 fOffScreen.reset(SkSurface::NewRaster(canvas->imageInfo(), &this->surfaceProps()));
84 }
85
86 void onBlitToScreen(SkCanvas* canvas, int w, int h) override {
87 SkAutoTUnref<SkImage> image(fOffScreen->newImageSnapshot());
88 SkPaint blitPaint;
89 blitPaint.setXfermodeMode(SkXfermode::kSrc_Mode);
90 canvas->drawImageRect(image, SkIRect::MakeWH(w, h),
91 SkRect::MakeWH(SkIntToScalar(w), SkIntToScalar(h)), &blitPaint);
joshualittc9dd93c2015-10-15 09:49:31 -070092 }
93
94 typedef WrappedBenchmark INHERITED;
95};
96
97// Create an MSAA & NVPR-enabled GPU backend
cdaltonbaf8fcb2015-11-24 09:20:24 -080098class GpuWrappedBenchmark : public WrappedBenchmark {
joshualittc9dd93c2015-10-15 09:49:31 -070099public:
cdaltonbaf8fcb2015-11-24 09:20:24 -0800100 explicit GpuWrappedBenchmark(const SkSurfaceProps& surfaceProps, Benchmark* bench,
101 int numSamples)
cdaltonc70483f2015-10-26 13:14:36 -0700102 : INHERITED(surfaceProps, bench)
joshualittc9dd93c2015-10-15 09:49:31 -0700103 , fNumSamples(numSamples) {}
104
105private:
cdalton0f6cca82015-11-24 08:54:29 -0800106 void setupOffScreen(SkCanvas* canvas) override {
107 fOffScreen.reset(SkSurface::NewRenderTarget(canvas->getGrContext(),
108 SkSurface::kNo_Budgeted,
109 canvas->imageInfo(),
110 fNumSamples,
111 &this->surfaceProps()));
112 }
113
114 void onBlitToScreen(SkCanvas* canvas, int w, int h) override {
115 // We call copySurface directly on the underlying GPU surfaces for a more efficient blit.
116 GrRenderTarget* dst, *src;
117
118 SkCanvas::LayerIter canvasIter(canvas, false);
119 SkAssertResult((dst = canvasIter.device()->accessRenderTarget()));
120
121 SkCanvas::LayerIter offscreenIter(fOffScreen->getCanvas(), false);
122 SkAssertResult((src = offscreenIter.device()->accessRenderTarget()));
123
124 SkASSERT(dst->getContext() == src->getContext());
125
126 dst->getContext()->copySurface(dst, src, SkIRect::MakeWH(w, h), SkIPoint::Make(0, 0));
127
128#ifdef SK_DEBUG
129 // This method should not be called while layers are saved.
130 canvasIter.next();
131 SkASSERT(canvasIter.done());
132
133 offscreenIter.next();
134 SkASSERT(offscreenIter.done());
135#endif
joshualittc9dd93c2015-10-15 09:49:31 -0700136 }
137
138 int fNumSamples;
139 typedef WrappedBenchmark INHERITED;
140};
141
142#endif //WrappedBenchmark_DEFINED