Index: tools/VisualBench/WrappedBenchmark.h |
diff --git a/tools/VisualBench/WrappedBenchmark.h b/tools/VisualBench/WrappedBenchmark.h |
index ffa0da342a8b314d496e41887e4079c0486f18b4..3d5d895773015cb9da4baa7b7da2cf7c9bef1e50 100644 |
--- a/tools/VisualBench/WrappedBenchmark.h |
+++ b/tools/VisualBench/WrappedBenchmark.h |
@@ -9,7 +9,10 @@ |
#define WrappedBenchmark_DEFINED |
#include "Benchmark.h" |
+#include "SkDevice.h" |
#include "SkSurface.h" |
+#include "GrContext.h" |
+#include "GrRenderTarget.h" |
// Wrap some other benchmark to allow specialization to either |
// cpu or gpu backends. The derived class will override 'setupOffScreen' |
@@ -28,7 +31,7 @@ public: |
void onDelayedSetup() override { fBench->delayedSetup(); } |
void onPerCanvasPreDraw(SkCanvas* canvas) override { |
- fOffScreen.reset(this->setupOffScreen(canvas)); |
+ this->setupOffScreen(canvas); |
fBench->perCanvasPreDraw(fOffScreen->getCanvas()); |
} |
void onPreDraw(SkCanvas* canvas) override { |
@@ -47,14 +50,18 @@ public: |
void onDraw(int loops, SkCanvas* canvas) override { |
SkASSERT(fOffScreen.get()); |
fBench->draw(loops, fOffScreen->getCanvas()); |
- SkAutoTUnref<SkImage> image(fOffScreen->newImageSnapshot()); |
- canvas->drawImage(image, 0,0); |
+ this->blitToScreen(canvas); |
} |
virtual SkIPoint onGetSize() override { return fBench->getSize(); } |
-private: |
- virtual SkSurface* setupOffScreen(SkCanvas*)=0; |
+protected: |
+ virtual void setupOffScreen(SkCanvas*)=0; |
+ |
+ virtual void blitToScreen(SkCanvas* canvas) { |
+ SkAutoTUnref<SkImage> image(fOffScreen->newImageSnapshot()); |
+ canvas->drawImage(image, 0,0); |
+ } |
SkSurfaceProps fSurfaceProps; |
SkAutoTUnref<SkSurface> fOffScreen; |
@@ -68,8 +75,8 @@ public: |
: INHERITED(surfaceProps, bench) {} |
private: |
- SkSurface* setupOffScreen(SkCanvas* canvas) override { |
- return SkSurface::NewRaster(canvas->imageInfo(), &this->surfaceProps()); |
+ void setupOffScreen(SkCanvas* canvas) override { |
+ fOffScreen.reset(SkSurface::NewRaster(canvas->imageInfo(), &this->surfaceProps())); |
} |
typedef WrappedBenchmark INHERITED; |
@@ -84,12 +91,44 @@ public: |
, fNumSamples(numSamples) {} |
private: |
- SkSurface* setupOffScreen(SkCanvas* canvas) override { |
- return SkSurface::NewRenderTarget(canvas->getGrContext(), |
- SkSurface::kNo_Budgeted, |
- canvas->imageInfo(), |
- fNumSamples, |
- &this->surfaceProps()); |
+ void setupOffScreen(SkCanvas* canvas) override { |
+ fOffScreen.reset(SkSurface::NewRenderTarget(canvas->getGrContext(), |
+ SkSurface::kNo_Budgeted, |
+ canvas->imageInfo(), |
+ fNumSamples, |
+ &this->surfaceProps())); |
+ fOffScreen->getCanvas()->clear(SK_ColorWHITE); |
+ } |
+ |
+ void blitToScreen(SkCanvas* canvas) override { |
+ // We call copySurface directly on the underlying GPU surfaces for a more efficient blit. |
+ SkCanvas::LayerIter canvasIter(canvas, false); |
Chris Dalton
2015/11/16 18:30:35
I'd rather call getTopDevice() than use the LayerI
bsalomon
2015/11/16 21:14:59
I think this is the best we can do right now.
|
+ GrRenderTarget* dst = canvasIter.device()->accessRenderTarget(); |
+ |
+ SkCanvas::LayerIter offscreenIter(fOffScreen->getCanvas(), false); |
+ GrRenderTarget* src = offscreenIter.device()->accessRenderTarget(); |
+ |
+ if (!src || src->width() != fOffScreen->width() || src->height() != fOffScreen->height() || |
+ !dst || canvas->imageInfo().dimensions() != SkISize::Make(dst->width(),dst->height())) { |
Chris Dalton
2015/11/16 18:30:35
I added the check of RT size because I understand
bsalomon
2015/11/16 21:14:59
I think the RT is always the size of the screen. J
Chris Dalton
2015/11/16 21:23:17
Oh that's right, unless running in windowed mode (
joshualitt
2015/11/18 17:02:03
just print not supported in that case.
|
+ SkDebugf("warning : blitToScreen() falling back on slow path for nvpr."); |
+ INHERITED::blitToScreen(canvas); |
+ return; |
+ } |
+ |
+ SkASSERT(dst->getContext() == src->getContext()); |
+ |
+ int w = SkTMin(fBench->getSize().fX, SkTMin(dst->width(), src->width())); |
+ int h = SkTMin(fBench->getSize().fY, SkTMin(dst->height(), src->height())); |
+ dst->getContext()->copySurface(dst, src, SkIRect::MakeWH(w, h), SkIPoint::Make(0, 0)); |
+ |
+#ifdef SK_DEBUG |
+ // This method should not be called while layers are saved. |
+ canvasIter.next(); |
+ SkASSERT(canvasIter.done()); |
+ |
+ offscreenIter.next(); |
+ SkASSERT(offscreenIter.done()); |
+#endif |
} |
int fNumSamples; |