• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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"
12 #include "SkDevice.h"
13 #include "SkSurface.h"
14 #include "GrContext.h"
15 #include "GrRenderTarget.h"
16 
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.
20 class WrappedBenchmark : public Benchmark {
21 public:
22     // Takes ownership of caller's ref on `bench`.
WrappedBenchmark(const SkSurfaceProps & surfaceProps,Benchmark * bench)23     explicit WrappedBenchmark(const SkSurfaceProps& surfaceProps, Benchmark* bench)
24         : fSurfaceProps(surfaceProps)
25         , fBench(bench) {}
26 
surfaceProps()27     const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; }
28 
onGetName()29     const char* onGetName()       override { return fBench->getName(); }
onGetUniqueName()30     const char* onGetUniqueName() override { return fBench->getUniqueName(); }
31 
onDelayedSetup()32     void onDelayedSetup() override { fBench->delayedSetup(); }
onPerCanvasPreDraw(SkCanvas * canvas)33     void onPerCanvasPreDraw(SkCanvas* canvas) override {
34         this->setupOffScreen(canvas);
35         fOffScreen->getCanvas()->clear(SK_ColorWHITE);
36         fBench->perCanvasPreDraw(fOffScreen->getCanvas());
37     }
onPreDraw(SkCanvas * canvas)38     void onPreDraw(SkCanvas* canvas) override {
39         SkASSERT(fOffScreen.get());
40         fBench->preDraw(fOffScreen->getCanvas());
41     }
onPostDraw(SkCanvas * canvas)42     void onPostDraw(SkCanvas* canvas) override {
43         SkASSERT(fOffScreen.get());
44         fBench->postDraw(fOffScreen->getCanvas());
45     }
onPerCanvasPostDraw(SkCanvas * canvas)46     void onPerCanvasPostDraw(SkCanvas* canvas) override {
47         SkASSERT(fOffScreen.get());
48         fBench->perCanvasPostDraw(fOffScreen->getCanvas());
49     }
50 
onDraw(int loops,SkCanvas * canvas)51     void onDraw(int loops, SkCanvas* canvas) override {
52         SkASSERT(fOffScreen.get());
53         fBench->draw(loops, fOffScreen->getCanvas());
54         this->blitToScreen(canvas);
55     }
56 
onGetSize()57     virtual SkIPoint onGetSize() override { return fBench->getSize(); }
58 
59 protected:
60     virtual void setupOffScreen(SkCanvas*)=0;
61 
blitToScreen(SkCanvas * canvas)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;
69 
70     SkSurfaceProps          fSurfaceProps;
71     SkAutoTUnref<SkSurface> fOffScreen;
72     SkAutoTUnref<Benchmark> fBench;
73 };
74 
75 // Create a raster surface for off screen rendering
76 class CpuWrappedBenchmark : public WrappedBenchmark {
77 public:
CpuWrappedBenchmark(const SkSurfaceProps & surfaceProps,Benchmark * bench)78     explicit CpuWrappedBenchmark(const SkSurfaceProps& surfaceProps, Benchmark* bench)
79         : INHERITED(surfaceProps, bench) {}
80 
81 private:
setupOffScreen(SkCanvas * canvas)82     void setupOffScreen(SkCanvas* canvas) override {
83         fOffScreen.reset(SkSurface::NewRaster(canvas->imageInfo(), &this->surfaceProps()));
84     }
85 
onBlitToScreen(SkCanvas * canvas,int w,int h)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);
92     }
93 
94     typedef WrappedBenchmark INHERITED;
95 };
96 
97 // Create an MSAA & NVPR-enabled GPU backend
98 class GpuWrappedBenchmark : public WrappedBenchmark {
99 public:
GpuWrappedBenchmark(const SkSurfaceProps & surfaceProps,Benchmark * bench,int numSamples)100     explicit GpuWrappedBenchmark(const SkSurfaceProps& surfaceProps, Benchmark* bench,
101                                  int numSamples)
102         : INHERITED(surfaceProps, bench)
103         , fNumSamples(numSamples) {}
104 
105 private:
setupOffScreen(SkCanvas * canvas)106     void setupOffScreen(SkCanvas* canvas) override {
107         fOffScreen.reset(SkSurface::NewRenderTarget(canvas->getGrContext(),
108                                                     SkBudgeted::kNo,
109                                                     canvas->imageInfo(),
110                                                     fNumSamples,
111                                                     &this->surfaceProps()));
112     }
113 
onBlitToScreen(SkCanvas * canvas,int w,int h)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
136     }
137 
138     int fNumSamples;
139     typedef WrappedBenchmark INHERITED;
140 };
141 
142 #endif //WrappedBenchmark_DEFINED
143