skia2/tools/DDLTileHelper.h
Adlai Holler 55aaefe687 Reland "Support sharing promise images between DDLs"
This reverts commit 38b9a4bc3e.

Reason for revert: Fixed ASAN, TSAN, and other bugs via other CLs.

Original change's description:
> Revert "Support sharing promise images between DDLs"
>
> This reverts commit 07e11d48cb.
>
> Reason for revert: Broke DDL3_ASAN and DDL3_TSAN
>
> Original change's description:
> > Support sharing promise images between DDLs
> >
> > - Migrate our code to SkImage::MakePromiseTexture
> > - Have DDLTileHelper share one SKP and one set of promise images across all tiles.
> > - Disallow on-the-fly allocation of mips for promise textures.
> >
> > Bug: skia:10286
> > Change-Id: Ie35976958454fc520f3c9d860e6285441260c9f7
> > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/291938
> > Commit-Queue: Adlai Holler <adlai@google.com>
> > Reviewed-by: Robert Phillips <robertphillips@google.com>
>
> TBR=robertphillips@google.com,adlai@google.com
>
> Change-Id: I939b14875d1a20e4a92eab94680adcfe9596ad81
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: skia:10286
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/375738
> Reviewed-by: Adlai Holler <adlai@google.com>
> Commit-Queue: Adlai Holler <adlai@google.com>


Bug: skia:10286
Change-Id: Ibfd7dfcd72f10a4e29a87fa8c610f2dfd018e0db
Cq-Include-Trybots: luci.skia.skia.primary:Test-Ubuntu18-Clang-Golo-GPU-QuadroP400-x86_64-Debug-All-DDL3_ASAN,Test-Ubuntu18-Clang-Golo-GPU-QuadroP400-x86_64-Release-All-DDL3_TSAN
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/375739
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Adlai Holler <adlai@google.com>
2021-03-04 13:10:37 +00:00

156 lines
6.2 KiB
C++

/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef DDLTileHelper_DEFINED
#define DDLTileHelper_DEFINED
#include "include/core/SkDeferredDisplayList.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSurfaceCharacterization.h"
#include "src/core/SkSpan.h"
class DDLPromiseImageHelper;
class PromiseImageCallbackContext;
class SkCanvas;
class SkData;
class SkDeferredDisplayListRecorder;
class SkPicture;
class SkSurface;
class SkSurfaceCharacterization;
class SkTaskGroup;
class DDLTileHelper {
public:
// The TileData class encapsulates the information and behavior of a single tile when
// rendering with DDLs.
class TileData {
public:
TileData();
~TileData();
bool initialized() const { return fID != -1; }
void init(int id,
GrDirectContext*,
const SkSurfaceCharacterization& dstChar,
const SkIRect& clip,
const SkIRect& paddingOutsets);
// Create the DDL for this tile (i.e., fill in 'fDisplayList').
void createDDL(const SkPicture*);
void dropDDL() { fDisplayList.reset(); }
// Precompile all the programs required to draw this tile's DDL
void precompile(GrDirectContext*);
// Just draw the re-inflated per-tile SKP directly into this tile w/o going through a DDL
// first. This is used for determining the overhead of using DDLs (i.e., it replaces
// a 'createDDL' and 'draw' pair.
void drawSKPDirectly(GrDirectContext*, const SkPicture*);
// Replay the recorded DDL into the tile surface - filling in 'fBackendTexture'.
void draw(GrDirectContext*);
void reset();
int id() const { return fID; }
SkIRect clipRect() const { return fClip; }
SkISize paddedRectSize() const {
return { fClip.width() + fPaddingOutsets.fLeft + fPaddingOutsets.fRight,
fClip.height() + fPaddingOutsets.fTop + fPaddingOutsets.fBottom };
}
SkIVector padOffset() const { return { fPaddingOutsets.fLeft, fPaddingOutsets.fTop }; }
SkDeferredDisplayList* ddl() { return fDisplayList.get(); }
sk_sp<SkImage> makePromiseImageForDst(sk_sp<GrContextThreadSafeProxy>);
void dropCallbackContext() { fCallbackContext.reset(); }
static void CreateBackendTexture(GrDirectContext*, TileData*);
static void DeleteBackendTexture(GrDirectContext*, TileData*);
private:
sk_sp<SkSurface> makeWrappedTileDest(GrRecordingContext* context);
sk_sp<PromiseImageCallbackContext> refCallbackContext() { return fCallbackContext; }
int fID = -1;
SkIRect fClip; // in the device space of the final SkSurface
SkIRect fPaddingOutsets; // random padding for the output surface
SkSurfaceCharacterization fPlaybackChar; // characterization for the tile's dst surface
// The callback context holds (via its SkPromiseImageTexture) the backend texture
// that is both wrapped in 'fTileSurface' and backs this tile's promise image
// (i.e., the one returned by 'makePromiseImage').
sk_sp<PromiseImageCallbackContext> fCallbackContext;
// 'fTileSurface' wraps the backend texture in 'fCallbackContext' and must exist until
// after 'fDisplayList' has been flushed (bc it owns the proxy the DDL's destination
// trampoline points at).
// TODO: fix the ref-order so we don't need 'fTileSurface' here
sk_sp<SkSurface> fTileSurface;
sk_sp<SkDeferredDisplayList> fDisplayList;
};
DDLTileHelper(GrDirectContext*,
const SkSurfaceCharacterization& dstChar,
const SkIRect& viewport,
int numXDivisions, int numYDivisions,
bool addRandomPaddingToDst);
// TODO: Move this to PromiseImageHelper and have one method that does all the work and
// returns the shared SkP.
void createSKP(sk_sp<GrContextThreadSafeProxy>,
SkData* compressedPictureData,
const DDLPromiseImageHelper&);
void kickOffThreadedWork(SkTaskGroup* recordingTaskGroup,
SkTaskGroup* gpuTaskGroup,
GrDirectContext*);
void createDDLsInParallel();
// Create the DDL that will compose all the tile images into a final result.
void createComposeDDL();
const sk_sp<SkDeferredDisplayList>& composeDDL() const { return fComposeDDL; }
// For each tile, create its DDL and then draw it - all on a single thread. This is to allow
// comparison w/ just drawing the SKP directly (i.e., drawAllTilesDirectly). The
// DDL creations and draws are interleaved to prevent starvation of the GPU.
// Note: this is somewhat of a misuse/pessimistic-use of DDLs since they are supposed to
// be created on a separate thread.
void interleaveDDLCreationAndDraw(GrDirectContext*);
// This draws all the per-tile SKPs directly into all of the tiles w/o converting them to
// DDLs first - all on a single thread.
void drawAllTilesDirectly(GrDirectContext*);
void dropCallbackContexts();
void resetAllTiles();
int numTiles() const { return fNumXDivisions * fNumYDivisions; }
void createBackendTextures(SkTaskGroup*, GrDirectContext*);
void deleteBackendTextures(SkTaskGroup*, GrDirectContext*);
private:
int fNumXDivisions; // number of tiles horizontally
int fNumYDivisions; // number of tiles vertically
SkAutoTArray<TileData> fTiles; // 'fNumXDivisions' x 'fNumYDivisions'
sk_sp<SkDeferredDisplayList> fComposeDDL;
const SkSurfaceCharacterization fDstCharacterization;
sk_sp<SkPicture> fReconstitutedPicture;
SkTArray<sk_sp<SkImage>> fPromiseImages; // All the promise images in the
// reconstituted picture
};
#endif