Revert "Update DDL test harness to use backendTextures to back tiles"

This reverts commit 7ae9d2fca6.

Reason for revert: Triggering Vulkan Debug layer errors

Original change's description:
> Update DDL test harness to use backendTextures to back tiles
> 
> This better matches Chrome's use of DDLs.
> 
> With path, image, and text draws stripped out, here is the perf impact of this change:
> 
>            before CL   after CL
> w/ DDLs      7.792      1.038
> w/o DDLs     0.800      0.876
> 
> This perf improvement (in the DDL case) is from backend texture wrapping SkSurfaces being created w/o initialization. The prior method of SkSurface creation was resulting in double clearing of all the surfaces.
> 
> This perf improvement won't be seen by Chrome since they've always being using wrapped backend texture SkSurfaces.
> 
> TBR=bsalomon@google.com
> Change-Id: Ice3993ca125fce37804e58c353c265cf659dbe2f
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/283456
> Reviewed-by: Brian Salomon <bsalomon@google.com>
> Commit-Queue: Robert Phillips <robertphillips@google.com>

TBR=egdaniel@google.com,bsalomon@google.com,robertphillips@google.com

Change-Id: Ife023ede0774ec2cce4c0d6e7708c036347ebf54
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/283648
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Robert Phillips 2020-04-15 16:22:06 +00:00 committed by Skia Commit-Bot
parent 7ae9d2fca6
commit 9ff1d841f6
5 changed files with 25 additions and 138 deletions

View File

@ -1662,8 +1662,6 @@ Result GPUDDLSink::ddlDraw(const Src& src,
constexpr int kNumDivisions = 3; constexpr int kNumDivisions = 3;
DDLTileHelper tiles(dstSurface, dstCharacterization, viewport, kNumDivisions); DDLTileHelper tiles(dstSurface, dstCharacterization, viewport, kNumDivisions);
tiles.createBackendTextures(gpuTaskGroup, gpuThreadCtx);
// Reinflate the compressed picture individually for each thread. // Reinflate the compressed picture individually for each thread.
tiles.createSKPPerTile(compressedPictureData.get(), promiseImageHelper); tiles.createSKPPerTile(compressedPictureData.get(), promiseImageHelper);
@ -1679,8 +1677,6 @@ Result GPUDDLSink::ddlDraw(const Src& src,
// It is simpler to also delete them at this point on the gpuThread. // It is simpler to also delete them at this point on the gpuThread.
promiseImageHelper.deleteAllFromGPU(gpuTaskGroup, gpuThreadCtx); promiseImageHelper.deleteAllFromGPU(gpuTaskGroup, gpuThreadCtx);
tiles.deleteBackendTextures(gpuTaskGroup, gpuThreadCtx);
// A flush has already been scheduled on the gpu thread along with the clean up of the backend // A flush has already been scheduled on the gpu thread along with the clean up of the backend
// textures so it is safe to schedule making 'mainCtx' not current on the gpuThread. // textures so it is safe to schedule making 'mainCtx' not current on the gpuThread.
gpuTaskGroup->add([gpuTestCtx] { gpuTestCtx->makeNotCurrent(); }); gpuTaskGroup->add([gpuTestCtx] { gpuTestCtx->makeNotCurrent(); });
@ -2102,8 +2098,6 @@ Result ViaDDL::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkStrin
// First, create all the tiles (including their individual dest surfaces) // First, create all the tiles (including their individual dest surfaces)
DDLTileHelper tiles(dstSurface, dstCharacterization, viewport, fNumDivisions); DDLTileHelper tiles(dstSurface, dstCharacterization, viewport, fNumDivisions);
tiles.createBackendTextures(nullptr, context);
// Second, reinflate the compressed picture individually for each thread // Second, reinflate the compressed picture individually for each thread
// This recreates the promise SkImages on each replay iteration. We are currently // This recreates the promise SkImages on each replay iteration. We are currently
// relying on this to test using a SkPromiseImageTexture to fulfill different // relying on this to test using a SkPromiseImageTexture to fulfill different
@ -2127,10 +2121,8 @@ Result ViaDDL::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkStrin
// Finally, compose the drawn tiles into the result // Finally, compose the drawn tiles into the result
// Note: the separation between the tiles and the final composition better // Note: the separation between the tiles and the final composition better
// matches Chrome but costs us a copy // matches Chrome but costs us a copy
tiles.composeAllTiles(context); tiles.composeAllTiles();
context->flush(); context->flush();
tiles.deleteBackendTextures(nullptr, context);
} }
return Result::Ok(); return Result::Ok();
}; };

View File

@ -72,11 +72,7 @@ private:
public: public:
// Upon being replayed - this field will be filled in (by the DrawingManager) with the // Upon being replayed - this field will be filled in (by the DrawingManager) with the
// proxy backing the destination SkSurface. Note that, since there is no good place to // proxy backing the destination SkSurface. Note that, since there is no good place to
// clear it, it can become a dangling pointer. Additionally, since the renderTargetProxy // clear it, it can become a dangling pointer.
// doesn't get a ref here, the SkSurface that owns it must remain alive until the DDL
// is flushed.
// TODO: the drawing manager could ref the renderTargetProxy for the DDL and then add
// a renderingTask to unref it after the DDL's ops have been executed.
GrRenderTargetProxy* fReplayDest = nullptr; GrRenderTargetProxy* fReplayDest = nullptr;
#endif #endif
}; };

View File

@ -28,7 +28,6 @@ void DDLTileHelper::TileData::init(int id,
fCharacterization = dstSurfaceCharacterization.createResized(clip.width(), clip.height()); fCharacterization = dstSurfaceCharacterization.createResized(clip.width(), clip.height());
SkASSERT(fCharacterization.isValid()); SkASSERT(fCharacterization.isValid());
SkASSERT(!fBackendTexture.isValid());
} }
DDLTileHelper::TileData::~TileData() {} DDLTileHelper::TileData::~TileData() {}
@ -92,100 +91,51 @@ void DDLTileHelper::TileData::precompile(GrContext* context) {
} }
} }
sk_sp<SkSurface> DDLTileHelper::TileData::makeWrappedTileDest(GrContext* context) {
if (!fBackendTexture.isValid()) {
return nullptr;
}
return SkSurface::MakeFromBackendTexture(context,
fBackendTexture,
fCharacterization.origin(),
fCharacterization.sampleCount(),
fCharacterization.colorType(),
fCharacterization.refColorSpace(),
&fCharacterization.surfaceProps());
}
void DDLTileHelper::TileData::drawSKPDirectly(GrContext* context) { void DDLTileHelper::TileData::drawSKPDirectly(GrContext* context) {
SkASSERT(!fDisplayList && !fTileSurface && fReconstitutedPicture); SkASSERT(!fDisplayList && !fImage && fReconstitutedPicture);
fTileSurface = this->makeWrappedTileDest(context); sk_sp<SkSurface> tileSurface = SkSurface::MakeRenderTarget(context, fCharacterization,
if (fTileSurface) { SkBudgeted::kYes);
SkCanvas* tileCanvas = fTileSurface->getCanvas(); if (tileSurface) {
SkCanvas* tileCanvas = tileSurface->getCanvas();
tileCanvas->clipRect(SkRect::MakeWH(fClip.width(), fClip.height())); tileCanvas->clipRect(SkRect::MakeWH(fClip.width(), fClip.height()));
tileCanvas->translate(-fClip.fLeft, -fClip.fTop); tileCanvas->translate(-fClip.fLeft, -fClip.fTop);
tileCanvas->drawPicture(fReconstitutedPicture); tileCanvas->drawPicture(fReconstitutedPicture);
// We can't snap an image here bc, since we're using wrapped backend textures for the fImage = tileSurface->makeImageSnapshot();
// surfaces, that would incur a copy.
} }
} }
void DDLTileHelper::TileData::draw(GrContext* context) { void DDLTileHelper::TileData::draw(GrContext* context) {
SkASSERT(fDisplayList && !fTileSurface); SkASSERT(fDisplayList && !fImage);
// The tile's surface needs to be held until after the DDL is flushed sk_sp<SkSurface> tileSurface = SkSurface::MakeRenderTarget(context, fCharacterization,
fTileSurface = this->makeWrappedTileDest(context); SkBudgeted::kYes);
if (fTileSurface) { if (tileSurface) {
fTileSurface->draw(fDisplayList.get()); tileSurface->draw(fDisplayList.get());
// We can't snap an image here bc, since we're using wrapped backend textures for the fImage = tileSurface->makeImageSnapshot();
// surfaces, that would incur a copy.
} }
} }
// TODO: We should create a single DDL for the composition step and just add replaying it // TODO: We should create a single DDL for the composition step and just add replaying it
// as the last GPU task // as the last GPU task
void DDLTileHelper::TileData::compose(GrContext* context) { void DDLTileHelper::TileData::compose() {
SkASSERT(context->priv().asDirectContext()); SkASSERT(fDstSurface && fImage);
SkASSERT(fDstSurface);
if (!fBackendTexture.isValid()) {
return;
}
// Here we are, unfortunately, aliasing 'fBackendTexture'. It is backing both 'fTileSurface'
// and 'tmp'.
sk_sp<SkImage> tmp = SkImage::MakeFromTexture(context,
fBackendTexture,
fCharacterization.origin(),
fCharacterization.colorType(),
kPremul_SkAlphaType,
fCharacterization.refColorSpace());
SkCanvas* canvas = fDstSurface->getCanvas(); SkCanvas* canvas = fDstSurface->getCanvas();
canvas->save(); canvas->save();
canvas->clipRect(SkRect::Make(fClip)); canvas->clipRect(SkRect::Make(fClip));
canvas->drawImage(tmp, fClip.fLeft, fClip.fTop); canvas->drawImage(fImage, fClip.fLeft, fClip.fTop);
canvas->restore(); canvas->restore();
} }
void DDLTileHelper::TileData::reset() { void DDLTileHelper::TileData::reset() {
// TODO: when DDLs are re-renderable we don't need to do this // TODO: when DDLs are re-renderable we don't need to do this
fDisplayList = nullptr; fDisplayList = nullptr;
fTileSurface = nullptr; fImage = nullptr;
}
void DDLTileHelper::TileData::CreateBackendTexture(GrContext* context, TileData* tile) {
SkASSERT(context->priv().asDirectContext());
SkASSERT(!tile->fBackendTexture.isValid());
tile->fBackendTexture = context->createBackendTexture(tile->fCharacterization);
// TODO: it seems that, on the Linux bots, backend texture creation is failing
// a lot (skbug.com/10142)
//SkASSERT(tile->fBackendTexture.isValid());
}
void DDLTileHelper::TileData::DeleteBackendTexture(GrContext* context, TileData* tile) {
SkASSERT(context->priv().asDirectContext());
// TODO: it seems that, on the Linux bots, backend texture creation is failing
// a lot (skbug.com/10142)
//SkASSERT(tile->fBackendTexture.isValid());
tile->fTileSurface = nullptr;
context->deleteBackendTexture(tile->fBackendTexture);
} }
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
@ -249,7 +199,7 @@ static void do_gpu_stuff(GrContext* context, DDLTileHelper::TileData* tile) {
// TODO: we should actually have a separate DDL that does // TODO: we should actually have a separate DDL that does
// the final composition draw // the final composition draw
tile->compose(context); tile->compose();
} }
// We expect to have more than one recording thread but just one gpu thread // We expect to have more than one recording thread but just one gpu thread
@ -296,9 +246,9 @@ void DDLTileHelper::drawAllTilesDirectly(GrContext* context) {
} }
} }
void DDLTileHelper::composeAllTiles(GrContext* context) { void DDLTileHelper::composeAllTiles() {
for (int i = 0; i < this->numTiles(); ++i) { for (int i = 0; i < this->numTiles(); ++i) {
fTiles[i].compose(context); fTiles[i].compose();
} }
} }
@ -307,35 +257,3 @@ void DDLTileHelper::resetAllTiles() {
fTiles[i].reset(); fTiles[i].reset();
} }
} }
void DDLTileHelper::createBackendTextures(SkTaskGroup* taskGroup, GrContext* context) {
SkASSERT(context->priv().asDirectContext());
if (taskGroup) {
for (int i = 0; i < this->numTiles(); ++i) {
TileData* tile = &fTiles[i];
taskGroup->add([context, tile]() { TileData::CreateBackendTexture(context, tile); });
}
} else {
for (int i = 0; i < this->numTiles(); ++i) {
TileData::CreateBackendTexture(context, &fTiles[i]);
}
}
}
void DDLTileHelper::deleteBackendTextures(SkTaskGroup* taskGroup, GrContext* context) {
SkASSERT(context->priv().asDirectContext());
if (taskGroup) {
for (int i = 0; i < this->numTiles(); ++i) {
TileData* tile = &fTiles[i];
taskGroup->add([context, tile]() { TileData::DeleteBackendTexture(context, tile); });
}
} else {
for (int i = 0; i < this->numTiles(); ++i) {
TileData::DeleteBackendTexture(context, &fTiles[i]);
}
}
}

View File

@ -55,7 +55,7 @@ public:
// Draw the result of replaying the DDL (i.e., 'fImage') into the // Draw the result of replaying the DDL (i.e., 'fImage') into the
// final destination surface ('fDstSurface'). // final destination surface ('fDstSurface').
void compose(GrContext*); void compose();
void reset(); void reset();
@ -63,22 +63,13 @@ public:
SkDeferredDisplayList* ddl() { return fDisplayList.get(); } SkDeferredDisplayList* ddl() { return fDisplayList.get(); }
static void CreateBackendTexture(GrContext*, TileData*);
static void DeleteBackendTexture(GrContext*, TileData*);
private: private:
sk_sp<SkSurface> makeWrappedTileDest(GrContext* context);
int fID = -1; int fID = -1;
sk_sp<SkSurface> fDstSurface; // the ultimate target for composition sk_sp<SkSurface> fDstSurface; // the ultimate target for composition
GrBackendTexture fBackendTexture; // destination for this tile's content
SkSurfaceCharacterization fCharacterization; // characterization for the tile's surface SkSurfaceCharacterization fCharacterization; // characterization for the tile's surface
SkIRect fClip; // in the device space of the 'fDstSurface' SkIRect fClip; // in the device space of the 'fDstSurface'
// 'fTileSurface' wraps 'fBackendTexture' and must exist until after 'fDisplayList' sk_sp<SkImage> fImage; // the result of replaying the DDL
// has been flushed.
sk_sp<SkSurface> fTileSurface;
sk_sp<SkPicture> fReconstitutedPicture; sk_sp<SkPicture> fReconstitutedPicture;
SkTArray<sk_sp<SkImage>> fPromiseImages; // All the promise images in the SkTArray<sk_sp<SkImage>> fPromiseImages; // All the promise images in the
// reconstituted picture // reconstituted picture
@ -114,15 +105,12 @@ public:
// DDLs first - all on a single thread. // DDLs first - all on a single thread.
void drawAllTilesDirectly(GrContext*); void drawAllTilesDirectly(GrContext*);
void composeAllTiles(GrContext*); void composeAllTiles();
void resetAllTiles(); void resetAllTiles();
int numTiles() const { return fNumDivisions * fNumDivisions; } int numTiles() const { return fNumDivisions * fNumDivisions; }
void createBackendTextures(SkTaskGroup*, GrContext*);
void deleteBackendTextures(SkTaskGroup*, GrContext*);
private: private:
int fNumDivisions; // number of tiles along a side int fNumDivisions; // number of tiles along a side
TileData* fTiles; // 'fNumDivisions' x 'fNumDivisions' TileData* fTiles; // 'fNumDivisions' x 'fNumDivisions'

View File

@ -258,8 +258,6 @@ static void run_ddl_benchmark(GrContext* context, sk_sp<SkSurface> surface,
DDLTileHelper tiles(surface, dstCharacterization, viewport, FLAGS_ddlTilingWidthHeight); DDLTileHelper tiles(surface, dstCharacterization, viewport, FLAGS_ddlTilingWidthHeight);
tiles.createBackendTextures(nullptr, context);
tiles.createSKPPerTile(compressedPictureData.get(), promiseImageHelper); tiles.createSKPPerTile(compressedPictureData.get(), promiseImageHelper);
SkTaskGroup::Enabler enabled(FLAGS_ddlNumAdditionalThreads); SkTaskGroup::Enabler enabled(FLAGS_ddlNumAdditionalThreads);
@ -285,7 +283,7 @@ static void run_ddl_benchmark(GrContext* context, sk_sp<SkSurface> surface,
if (!FLAGS_png.isEmpty()) { if (!FLAGS_png.isEmpty()) {
// The user wants to see the final result // The user wants to see the final result
tiles.composeAllTiles(context); tiles.composeAllTiles();
} }
tiles.resetAllTiles(); tiles.resetAllTiles();
@ -295,11 +293,6 @@ static void run_ddl_benchmark(GrContext* context, sk_sp<SkSurface> surface,
GrFlushInfo flushInfo; GrFlushInfo flushInfo;
flushInfo.fFlags = kSyncCpu_GrFlushFlag; flushInfo.fFlags = kSyncCpu_GrFlushFlag;
context->flush(flushInfo); context->flush(flushInfo);
promiseImageHelper.deleteAllFromGPU(nullptr, context);
tiles.deleteBackendTextures(nullptr, context);
} }
static void run_benchmark(GrContext* context, SkSurface* surface, SkpProducer* skpp, static void run_benchmark(GrContext* context, SkSurface* surface, SkpProducer* skpp,