Index: tools/VisualBench/WrappedBenchmark.h |
diff --git a/tools/VisualBench/WrappedBenchmark.h b/tools/VisualBench/WrappedBenchmark.h |
index ffa0da342a8b314d496e41887e4079c0486f18b4..dba6134f76cf6109bf3c224f989dd4a6613b3636 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,8 @@ public: |
void onDelayedSetup() override { fBench->delayedSetup(); } |
void onPerCanvasPreDraw(SkCanvas* canvas) override { |
- fOffScreen.reset(this->setupOffScreen(canvas)); |
+ this->setupOffScreen(canvas); |
+ fOffScreen->getCanvas()->clear(SK_ColorWHITE); |
fBench->perCanvasPreDraw(fOffScreen->getCanvas()); |
} |
void onPreDraw(SkCanvas* canvas) override { |
@@ -47,14 +51,21 @@ 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; |
+ |
+ void blitToScreen(SkCanvas* canvas) { |
+ int w = SkTMin(fBench->getSize().fX, fOffScreen->width()); |
+ int h = SkTMin(fBench->getSize().fY, fOffScreen->width()); |
+ this->onBlitToScreen(canvas, w, h); |
+ } |
+ |
+ virtual void onBlitToScreen(SkCanvas* canvas, int w, int h) = 0; |
SkSurfaceProps fSurfaceProps; |
SkAutoTUnref<SkSurface> fOffScreen; |
@@ -68,8 +79,16 @@ 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())); |
+ } |
+ |
+ void onBlitToScreen(SkCanvas* canvas, int w, int h) override { |
+ SkAutoTUnref<SkImage> image(fOffScreen->newImageSnapshot()); |
+ SkPaint blitPaint; |
+ blitPaint.setXfermodeMode(SkXfermode::kSrc_Mode); |
+ canvas->drawImageRect(image, SkIRect::MakeWH(w, h), |
+ SkRect::MakeWH(SkIntToScalar(w), SkIntToScalar(h)), &blitPaint); |
} |
typedef WrappedBenchmark INHERITED; |
@@ -84,12 +103,36 @@ 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())); |
+ } |
+ |
+ void onBlitToScreen(SkCanvas* canvas, int w, int h) override { |
+ // We call copySurface directly on the underlying GPU surfaces for a more efficient blit. |
+ GrRenderTarget* dst, *src; |
+ |
+ SkCanvas::LayerIter canvasIter(canvas, false); |
+ SkAssertResult((dst = canvasIter.device()->accessRenderTarget())); |
+ |
+ SkCanvas::LayerIter offscreenIter(fOffScreen->getCanvas(), false); |
+ SkAssertResult((src = offscreenIter.device()->accessRenderTarget())); |
+ |
+ SkASSERT(dst->getContext() == src->getContext()); |
+ |
+ 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; |