Remove uses of SkCanvas::flush

afaict the perf surprises associated with:

https://skia-review.googlesource.com/c/skia/+/334417 (Remove SkBaseDevice::flush)

were bc Ganesh resolves MSAA buffers for SkCanvas::flush but doesn't do so for GrDirectContext::flush.

Where possible this CL switches SkCanvas::flush to SkSurface::flush (which will also resolve MSAA buffers) so that when https://skia-review.googlesource.com/c/skia/+/334417 relands there should not be any performance surprises.

Change-Id: I705ad6219f0f625a88cf3f9e8b2418a3182d298c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/335866
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Adlai Holler <adlai@google.com>
This commit is contained in:
Robert Phillips 2020-11-20 13:49:37 -05:00 committed by Skia Commit-Bot
parent c4e958bff3
commit 2c21a11923
10 changed files with 51 additions and 28 deletions

View File

@ -12,6 +12,7 @@
#include "include/core/SkCanvas.h"
#include "include/core/SkImage.h"
#include "include/core/SkSurface.h"
#include "include/gpu/GrDirectContext.h"
#include "include/private/SkTemplates.h"
#include "include/utils/SkRandom.h"
@ -216,7 +217,10 @@ protected:
}
}
// Prevent any batching between composited "frames".
canvas->flush();
auto surface = canvas->getSurface();
if (surface) {
surface->flush();
}
}
canvas->restore();
}

View File

@ -122,6 +122,8 @@ protected:
}
void onDraw(int loops, SkCanvas* canvas) override {
auto dContext = GrAsDirectContext(canvas->recordingContext());
for (int i = 0; i < loops; ++i) {
for (int frame = 0; frame < kSimulatedFrames; ++frame) {
for (int j = 0; j < kImagesToDraw; ++j) {
@ -134,7 +136,9 @@ protected:
draw_image(canvas, fImages[idx].get());
}
// Simulate a frame boundary by flushing. This should notify GrResourceCache.
canvas->flush();
if (dContext) {
dContext->flush();
}
}
}
}
@ -217,6 +221,8 @@ protected:
}
void onDraw(int loops, SkCanvas* canvas) override {
auto dContext = GrAsDirectContext(canvas->recordingContext());
int delta = 0;
switch (fMode) {
case Mode::kPingPong:
@ -238,7 +244,9 @@ protected:
imgsToDraw += 2 * delta;
}
// Simulate a frame boundary by flushing. This should notify GrResourceCache.
canvas->flush();
if (dContext) {
dContext->flush();
}
}
}
}

View File

@ -35,7 +35,7 @@ void SKPAnimationBench::drawPicture() {
}
for (int j = 0; j < this->tileRects().count(); ++j) {
this->surfaces()[j]->getCanvas()->flush();
this->surfaces()[j]->flush();
}
}

View File

@ -130,21 +130,24 @@ void SKPBench::drawPicture() {
}
for (int j = 0; j < fTileRects.count(); ++j) {
fSurfaces[j]->getCanvas()->flush();
fSurfaces[j]->flush();
}
}
#include "src/gpu/GrGpu.h"
static void draw_pic_for_stats(SkCanvas* canvas, GrDirectContext* context, const SkPicture* picture,
SkTArray<SkString>* keys, SkTArray<double>* values) {
context->priv().resetGpuStats();
context->priv().resetContextStats();
static void draw_pic_for_stats(SkCanvas* canvas,
GrDirectContext* dContext,
const SkPicture* picture,
SkTArray<SkString>* keys,
SkTArray<double>* values) {
dContext->priv().resetGpuStats();
dContext->priv().resetContextStats();
canvas->drawPicture(picture);
canvas->flush();
dContext->flush();
context->priv().dumpGpuStatsKeyValuePairs(keys, values);
context->priv().dumpCacheStatsKeyValuePairs(keys, values);
context->priv().dumpContextStatsKeyValuePairs(keys, values);
dContext->priv().dumpGpuStatsKeyValuePairs(keys, values);
dContext->priv().dumpCacheStatsKeyValuePairs(keys, values);
dContext->priv().dumpContextStatsKeyValuePairs(keys, values);
}
void SKPBench::getGpuStats(SkCanvas* canvas, SkTArray<SkString>* keys, SkTArray<double>* values) {

View File

@ -119,12 +119,12 @@ class SkpDebugPlayer {
canvas->clear(SK_ColorTRANSPARENT);
if (fInspectedLayer >= 0) {
// when it's a layer event we're viewing, we use the layer manager to render it.
fLayerManager->drawLayerEventTo(canvas, fInspectedLayer, fp);
fLayerManager->drawLayerEventTo(surface, fInspectedLayer, fp);
} else {
// otherwise, its a frame at the top level.
frames[fp]->drawTo(surface->getCanvas(), index);
}
surface->getCanvas()->flush();
surface->flush();
}
// Draws to the end of the current frame.

View File

@ -25,7 +25,6 @@ static void test_basic(skiatest::Reporter* reporter) {
SkPaint paint;
paint.setColor(SK_ColorBLUE);
canvas->drawOval(SkRect::MakeLTRB(1,1,99,99), paint);
canvas->flush();
auto picture1 = rec.finishRecordingAsPicture();
SkIRect dirtyRectFull = SkIRect::MakeLTRB(0, 0, layerWidth, layerHeight);
@ -34,7 +33,6 @@ static void test_basic(skiatest::Reporter* reporter) {
canvas = rec2.beginRecording(layerWidth, layerHeight);
paint.setColor(SK_ColorGREEN);
canvas->drawOval(SkRect::MakeLTRB(40,40,60,60), paint);
canvas->flush();
auto picture2 = rec2.finishRecordingAsPicture();
SkIRect dirtyRectPartial = SkIRect::MakeLTRB(40,40,60,60);

View File

@ -10,6 +10,7 @@
#include "include/core/SkPicture.h"
#include "include/core/SkPoint.h"
#include "include/core/SkTextBlob.h"
#include "include/gpu/GrDirectContext.h"
#include "include/utils/SkPaintFilterCanvas.h"
#include "src/core/SkCanvasPriv.h"
#include "src/core/SkClipOpPriv.h"
@ -140,6 +141,8 @@ void DebugCanvas::drawTo(SkCanvas* originalCanvas, int index, int m) {
DebugPaintFilterCanvas filterCanvas(originalCanvas);
SkCanvas* finalCanvas = fOverdrawViz ? &filterCanvas : originalCanvas;
auto dContext = GrAsDirectContext(finalCanvas->recordingContext());
// If we have a GPU backend we can also visualize the op information
GrAuditTrail* at = nullptr;
if (fDrawGpuOpBounds || m != -1) {
@ -153,7 +156,9 @@ void DebugCanvas::drawTo(SkCanvas* originalCanvas, int index, int m) {
// We need to flush any pending operations, or they might combine with commands below.
// Previous operations were not registered with the audit trail when they were
// created, so if we allow them to combine, the audit trail will fail to find them.
finalCanvas->flush();
if (dContext) {
dContext->flush();
}
acb = new GrAuditTrail::AutoCollectOps(at, i);
}
if (fCommandVector[i]->isVisible()) {
@ -196,7 +201,9 @@ void DebugCanvas::drawTo(SkCanvas* originalCanvas, int index, int m) {
// just in case there is global reordering, we flush the canvas before querying
// GrAuditTrail
GrAuditTrail::AutoEnable ae(at);
finalCanvas->flush();
if (dContext) {
dContext->flush();
}
// we pick three colorblind-safe colors, 75% alpha
static const SkColor kTotalBounds = SkColorSetARGB(0xC0, 0x6A, 0x3D, 0x9A);
@ -278,7 +285,11 @@ void DebugCanvas::drawAndCollectOps(SkCanvas* canvas) {
// in case there is some kind of global reordering
{
GrAuditTrail::AutoEnable ae(at);
canvas->flush();
auto dContext = GrAsDirectContext(canvas->recordingContext());
if (dContext) {
dContext->flush();
}
}
}
}

View File

@ -66,10 +66,10 @@ void DebugLayerManager::storeSkPicture(int nodeId, int frame, sk_sp<SkPicture> p
keys.push_back(k);
}
void DebugLayerManager::drawLayerEventTo(SkCanvas* canvas, const int nodeId, const int frame) {
void DebugLayerManager::drawLayerEventTo(SkSurface* surface, const int nodeId, const int frame) {
auto& evt = fDraws[{frame, nodeId}];
evt.debugCanvas->drawTo(canvas, evt.command);
canvas->flush();
evt.debugCanvas->drawTo(surface->getCanvas(), evt.command);
surface->flush();
}
sk_sp<SkImage> DebugLayerManager::getLayerAsImage(const int nodeId, const int frame) {
@ -105,9 +105,8 @@ sk_sp<SkImage> DebugLayerManager::getLayerAsImage(const int nodeId, const int fr
// draw everything from the last full redraw up to the current frame.
// other frames drawn are partial, meaning they were clipped to not completely cover the layer.
// count back up with i
auto* canvas = surface->getCanvas();
for (; i<relevantFrames.size() && relevantFrames[i]<=frameN; i++) {
drawLayerEventTo(canvas, nodeId, relevantFrames[i]);
drawLayerEventTo(surface.get(), nodeId, relevantFrames[i]);
}
drawEvent.image = surface->makeImageSnapshot();
return drawEvent.image;

View File

@ -46,7 +46,7 @@ public:
// Set's the command playback head for a given picture/draw event.
void setCommand(int nodeId, int frame, int command);
void drawLayerEventTo(SkCanvas* canvas, const int nodeId, const int frame);
void drawLayerEventTo(SkSurface*, const int nodeId, const int frame);
// getLayerAsImage draws the given layer as it would have looked on frame and returns an image.
// Though each picture can be played back in as many ways as there are commands, we will let

View File

@ -186,7 +186,7 @@ bool Request::enableGPU(bool enable) {
// TODO understand what is actually happening here
if (fDebugCanvas) {
fDebugCanvas->drawTo(this->getCanvas(), this->getLastOp());
this->getCanvas()->flush();
fSurface->flush();
}
return true;
@ -216,7 +216,7 @@ bool Request::initPictureFromStream(SkStream* stream) {
// for some reason we need to 'flush' the debug canvas by drawing all of the ops
fDebugCanvas->drawTo(this->getCanvas(), this->getLastOp());
this->getCanvas()->flush();
fSurface->flush();
return true;
}