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:
parent
c4e958bff3
commit
2c21a11923
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user