1c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt/* 2c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt * Copyright 2015 Google Inc. 3c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt * 4c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt * Use of this source code is governed by a BSD-style license that can be 5c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt * found in the LICENSE file. 6c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt */ 7c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt 8c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt#ifndef WrappedBenchmark_DEFINED 9c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt#define WrappedBenchmark_DEFINED 10c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt 11c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt#include "Benchmark.h" 120f6cca8a2070b974368652ec04b6003e9205a8a3cdalton#include "SkDevice.h" 13c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt#include "SkSurface.h" 140f6cca8a2070b974368652ec04b6003e9205a8a3cdalton#include "GrContext.h" 150f6cca8a2070b974368652ec04b6003e9205a8a3cdalton#include "GrRenderTarget.h" 16c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt 17c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt// Wrap some other benchmark to allow specialization to either 18c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt// cpu or gpu backends. The derived class will override 'setupOffScreen' 19c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt// to create an offscreen surface in which the actual rendering will occur. 20c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualittclass WrappedBenchmark : public Benchmark { 21c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualittpublic: 22c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt // Takes ownership of caller's ref on `bench`. 23c70483f5ab83aaa29c0697398aeca3432f3591b6cdalton explicit WrappedBenchmark(const SkSurfaceProps& surfaceProps, Benchmark* bench) 24c70483f5ab83aaa29c0697398aeca3432f3591b6cdalton : fSurfaceProps(surfaceProps) 25c70483f5ab83aaa29c0697398aeca3432f3591b6cdalton , fBench(bench) {} 26c70483f5ab83aaa29c0697398aeca3432f3591b6cdalton 27c70483f5ab83aaa29c0697398aeca3432f3591b6cdalton const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; } 28c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt 29c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt const char* onGetName() override { return fBench->getName(); } 30c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt const char* onGetUniqueName() override { return fBench->getUniqueName(); } 31c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt 32c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt void onDelayedSetup() override { fBench->delayedSetup(); } 33c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt void onPerCanvasPreDraw(SkCanvas* canvas) override { 340f6cca8a2070b974368652ec04b6003e9205a8a3cdalton this->setupOffScreen(canvas); 350f6cca8a2070b974368652ec04b6003e9205a8a3cdalton fOffScreen->getCanvas()->clear(SK_ColorWHITE); 36c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt fBench->perCanvasPreDraw(fOffScreen->getCanvas()); 37c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt } 38c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt void onPreDraw(SkCanvas* canvas) override { 39c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt SkASSERT(fOffScreen.get()); 40c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt fBench->preDraw(fOffScreen->getCanvas()); 41c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt } 42c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt void onPostDraw(SkCanvas* canvas) override { 43c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt SkASSERT(fOffScreen.get()); 44c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt fBench->postDraw(fOffScreen->getCanvas()); 45c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt } 46c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt void onPerCanvasPostDraw(SkCanvas* canvas) override { 47c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt SkASSERT(fOffScreen.get()); 48c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt fBench->perCanvasPostDraw(fOffScreen->getCanvas()); 49c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt } 50c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt 51c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt void onDraw(int loops, SkCanvas* canvas) override { 52c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt SkASSERT(fOffScreen.get()); 53c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt fBench->draw(loops, fOffScreen->getCanvas()); 540f6cca8a2070b974368652ec04b6003e9205a8a3cdalton this->blitToScreen(canvas); 55c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt } 56c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt 57c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt virtual SkIPoint onGetSize() override { return fBench->getSize(); } 58c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt 590f6cca8a2070b974368652ec04b6003e9205a8a3cdaltonprotected: 600f6cca8a2070b974368652ec04b6003e9205a8a3cdalton virtual void setupOffScreen(SkCanvas*)=0; 610f6cca8a2070b974368652ec04b6003e9205a8a3cdalton 620f6cca8a2070b974368652ec04b6003e9205a8a3cdalton void blitToScreen(SkCanvas* canvas) { 630f6cca8a2070b974368652ec04b6003e9205a8a3cdalton int w = SkTMin(fBench->getSize().fX, fOffScreen->width()); 640f6cca8a2070b974368652ec04b6003e9205a8a3cdalton int h = SkTMin(fBench->getSize().fY, fOffScreen->width()); 650f6cca8a2070b974368652ec04b6003e9205a8a3cdalton this->onBlitToScreen(canvas, w, h); 660f6cca8a2070b974368652ec04b6003e9205a8a3cdalton } 670f6cca8a2070b974368652ec04b6003e9205a8a3cdalton 680f6cca8a2070b974368652ec04b6003e9205a8a3cdalton virtual void onBlitToScreen(SkCanvas* canvas, int w, int h) = 0; 69c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt 70c70483f5ab83aaa29c0697398aeca3432f3591b6cdalton SkSurfaceProps fSurfaceProps; 71c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt SkAutoTUnref<SkSurface> fOffScreen; 72c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt SkAutoTUnref<Benchmark> fBench; 73c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt}; 74c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt 75c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt// Create a raster surface for off screen rendering 76c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualittclass CpuWrappedBenchmark : public WrappedBenchmark { 77c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualittpublic: 78c70483f5ab83aaa29c0697398aeca3432f3591b6cdalton explicit CpuWrappedBenchmark(const SkSurfaceProps& surfaceProps, Benchmark* bench) 79c70483f5ab83aaa29c0697398aeca3432f3591b6cdalton : INHERITED(surfaceProps, bench) {} 80c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt 81c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualittprivate: 820f6cca8a2070b974368652ec04b6003e9205a8a3cdalton void setupOffScreen(SkCanvas* canvas) override { 830f6cca8a2070b974368652ec04b6003e9205a8a3cdalton fOffScreen.reset(SkSurface::NewRaster(canvas->imageInfo(), &this->surfaceProps())); 840f6cca8a2070b974368652ec04b6003e9205a8a3cdalton } 850f6cca8a2070b974368652ec04b6003e9205a8a3cdalton 860f6cca8a2070b974368652ec04b6003e9205a8a3cdalton void onBlitToScreen(SkCanvas* canvas, int w, int h) override { 870f6cca8a2070b974368652ec04b6003e9205a8a3cdalton SkAutoTUnref<SkImage> image(fOffScreen->newImageSnapshot()); 880f6cca8a2070b974368652ec04b6003e9205a8a3cdalton SkPaint blitPaint; 890f6cca8a2070b974368652ec04b6003e9205a8a3cdalton blitPaint.setXfermodeMode(SkXfermode::kSrc_Mode); 900f6cca8a2070b974368652ec04b6003e9205a8a3cdalton canvas->drawImageRect(image, SkIRect::MakeWH(w, h), 910f6cca8a2070b974368652ec04b6003e9205a8a3cdalton SkRect::MakeWH(SkIntToScalar(w), SkIntToScalar(h)), &blitPaint); 92c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt } 93c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt 94c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt typedef WrappedBenchmark INHERITED; 95c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt}; 96c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt 97c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt// Create an MSAA & NVPR-enabled GPU backend 98baf8fcbb1b7eb89d5190df804bbda33c2622eb88cdaltonclass GpuWrappedBenchmark : public WrappedBenchmark { 99c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualittpublic: 100baf8fcbb1b7eb89d5190df804bbda33c2622eb88cdalton explicit GpuWrappedBenchmark(const SkSurfaceProps& surfaceProps, Benchmark* bench, 101baf8fcbb1b7eb89d5190df804bbda33c2622eb88cdalton int numSamples) 102c70483f5ab83aaa29c0697398aeca3432f3591b6cdalton : INHERITED(surfaceProps, bench) 103c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt , fNumSamples(numSamples) {} 104c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt 105c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualittprivate: 1060f6cca8a2070b974368652ec04b6003e9205a8a3cdalton void setupOffScreen(SkCanvas* canvas) override { 1070f6cca8a2070b974368652ec04b6003e9205a8a3cdalton fOffScreen.reset(SkSurface::NewRenderTarget(canvas->getGrContext(), 1085ec26ae9bfca635ccc98283aad5deda11519d826bsalomon SkBudgeted::kNo, 1090f6cca8a2070b974368652ec04b6003e9205a8a3cdalton canvas->imageInfo(), 1100f6cca8a2070b974368652ec04b6003e9205a8a3cdalton fNumSamples, 1110f6cca8a2070b974368652ec04b6003e9205a8a3cdalton &this->surfaceProps())); 1120f6cca8a2070b974368652ec04b6003e9205a8a3cdalton } 1130f6cca8a2070b974368652ec04b6003e9205a8a3cdalton 1140f6cca8a2070b974368652ec04b6003e9205a8a3cdalton void onBlitToScreen(SkCanvas* canvas, int w, int h) override { 1150f6cca8a2070b974368652ec04b6003e9205a8a3cdalton // We call copySurface directly on the underlying GPU surfaces for a more efficient blit. 1160f6cca8a2070b974368652ec04b6003e9205a8a3cdalton GrRenderTarget* dst, *src; 1170f6cca8a2070b974368652ec04b6003e9205a8a3cdalton 1180f6cca8a2070b974368652ec04b6003e9205a8a3cdalton SkCanvas::LayerIter canvasIter(canvas, false); 1190f6cca8a2070b974368652ec04b6003e9205a8a3cdalton SkAssertResult((dst = canvasIter.device()->accessRenderTarget())); 1200f6cca8a2070b974368652ec04b6003e9205a8a3cdalton 1210f6cca8a2070b974368652ec04b6003e9205a8a3cdalton SkCanvas::LayerIter offscreenIter(fOffScreen->getCanvas(), false); 1220f6cca8a2070b974368652ec04b6003e9205a8a3cdalton SkAssertResult((src = offscreenIter.device()->accessRenderTarget())); 1230f6cca8a2070b974368652ec04b6003e9205a8a3cdalton 1240f6cca8a2070b974368652ec04b6003e9205a8a3cdalton SkASSERT(dst->getContext() == src->getContext()); 1250f6cca8a2070b974368652ec04b6003e9205a8a3cdalton 1260f6cca8a2070b974368652ec04b6003e9205a8a3cdalton dst->getContext()->copySurface(dst, src, SkIRect::MakeWH(w, h), SkIPoint::Make(0, 0)); 1270f6cca8a2070b974368652ec04b6003e9205a8a3cdalton 1280f6cca8a2070b974368652ec04b6003e9205a8a3cdalton#ifdef SK_DEBUG 1290f6cca8a2070b974368652ec04b6003e9205a8a3cdalton // This method should not be called while layers are saved. 1300f6cca8a2070b974368652ec04b6003e9205a8a3cdalton canvasIter.next(); 1310f6cca8a2070b974368652ec04b6003e9205a8a3cdalton SkASSERT(canvasIter.done()); 1320f6cca8a2070b974368652ec04b6003e9205a8a3cdalton 1330f6cca8a2070b974368652ec04b6003e9205a8a3cdalton offscreenIter.next(); 1340f6cca8a2070b974368652ec04b6003e9205a8a3cdalton SkASSERT(offscreenIter.done()); 1350f6cca8a2070b974368652ec04b6003e9205a8a3cdalton#endif 136c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt } 137c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt 138c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt int fNumSamples; 139c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt typedef WrappedBenchmark INHERITED; 140c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt}; 141c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt 142c9dd93cd5bf72a236a14693b04f5e5c983e32ba4joshualitt#endif //WrappedBenchmark_DEFINED 143