1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2018 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #ifndef DDLTileHelper_DEFINED 9*c8dee2aaSAndroid Build Coastguard Worker #define DDLTileHelper_DEFINED 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSpan.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTemplates.h" 15*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/chromium/GrDeferredDisplayList.h" 16*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/chromium/GrSurfaceCharacterization.h" 17*c8dee2aaSAndroid Build Coastguard Worker 18*c8dee2aaSAndroid Build Coastguard Worker class DDLPromiseImageHelper; 19*c8dee2aaSAndroid Build Coastguard Worker class PromiseImageCallbackContext; 20*c8dee2aaSAndroid Build Coastguard Worker class SkCanvas; 21*c8dee2aaSAndroid Build Coastguard Worker class SkData; 22*c8dee2aaSAndroid Build Coastguard Worker class GrDeferredDisplayListRecorder; 23*c8dee2aaSAndroid Build Coastguard Worker class SkImage; 24*c8dee2aaSAndroid Build Coastguard Worker class SkPicture; 25*c8dee2aaSAndroid Build Coastguard Worker class SkSurface; 26*c8dee2aaSAndroid Build Coastguard Worker class GrSurfaceCharacterization; 27*c8dee2aaSAndroid Build Coastguard Worker class SkTaskGroup; 28*c8dee2aaSAndroid Build Coastguard Worker 29*c8dee2aaSAndroid Build Coastguard Worker class DDLTileHelper { 30*c8dee2aaSAndroid Build Coastguard Worker public: 31*c8dee2aaSAndroid Build Coastguard Worker // The TileData class encapsulates the information and behavior of a single tile when 32*c8dee2aaSAndroid Build Coastguard Worker // rendering with DDLs. 33*c8dee2aaSAndroid Build Coastguard Worker class TileData { 34*c8dee2aaSAndroid Build Coastguard Worker public: 35*c8dee2aaSAndroid Build Coastguard Worker TileData(); 36*c8dee2aaSAndroid Build Coastguard Worker ~TileData(); 37*c8dee2aaSAndroid Build Coastguard Worker initialized()38*c8dee2aaSAndroid Build Coastguard Worker bool initialized() const { return fID != -1; } 39*c8dee2aaSAndroid Build Coastguard Worker 40*c8dee2aaSAndroid Build Coastguard Worker void init(int id, 41*c8dee2aaSAndroid Build Coastguard Worker GrDirectContext*, 42*c8dee2aaSAndroid Build Coastguard Worker const GrSurfaceCharacterization& dstChar, 43*c8dee2aaSAndroid Build Coastguard Worker const SkIRect& clip, 44*c8dee2aaSAndroid Build Coastguard Worker const SkIRect& paddingOutsets); 45*c8dee2aaSAndroid Build Coastguard Worker 46*c8dee2aaSAndroid Build Coastguard Worker // Create the DDL for this tile (i.e., fill in 'fDisplayList'). 47*c8dee2aaSAndroid Build Coastguard Worker void createDDL(const SkPicture*); 48*c8dee2aaSAndroid Build Coastguard Worker dropDDL()49*c8dee2aaSAndroid Build Coastguard Worker void dropDDL() { fDisplayList.reset(); } 50*c8dee2aaSAndroid Build Coastguard Worker 51*c8dee2aaSAndroid Build Coastguard Worker // Precompile all the programs required to draw this tile's DDL 52*c8dee2aaSAndroid Build Coastguard Worker void precompile(GrDirectContext*); 53*c8dee2aaSAndroid Build Coastguard Worker 54*c8dee2aaSAndroid Build Coastguard Worker // Just draw the re-inflated per-tile SKP directly into this tile w/o going through a DDL 55*c8dee2aaSAndroid Build Coastguard Worker // first. This is used for determining the overhead of using DDLs (i.e., it replaces 56*c8dee2aaSAndroid Build Coastguard Worker // a 'createDDL' and 'draw' pair. 57*c8dee2aaSAndroid Build Coastguard Worker void drawSKPDirectly(GrDirectContext*, const SkPicture*); 58*c8dee2aaSAndroid Build Coastguard Worker 59*c8dee2aaSAndroid Build Coastguard Worker // Replay the recorded DDL into the tile surface - filling in 'fBackendTexture'. 60*c8dee2aaSAndroid Build Coastguard Worker void draw(GrDirectContext*); 61*c8dee2aaSAndroid Build Coastguard Worker 62*c8dee2aaSAndroid Build Coastguard Worker void reset(); 63*c8dee2aaSAndroid Build Coastguard Worker id()64*c8dee2aaSAndroid Build Coastguard Worker int id() const { return fID; } clipRect()65*c8dee2aaSAndroid Build Coastguard Worker SkIRect clipRect() const { return fClip; } paddedRectSize()66*c8dee2aaSAndroid Build Coastguard Worker SkISize paddedRectSize() const { 67*c8dee2aaSAndroid Build Coastguard Worker return { fClip.width() + fPaddingOutsets.fLeft + fPaddingOutsets.fRight, 68*c8dee2aaSAndroid Build Coastguard Worker fClip.height() + fPaddingOutsets.fTop + fPaddingOutsets.fBottom }; 69*c8dee2aaSAndroid Build Coastguard Worker } padOffset()70*c8dee2aaSAndroid Build Coastguard Worker SkIVector padOffset() const { return { fPaddingOutsets.fLeft, fPaddingOutsets.fTop }; } 71*c8dee2aaSAndroid Build Coastguard Worker ddl()72*c8dee2aaSAndroid Build Coastguard Worker GrDeferredDisplayList* ddl() { return fDisplayList.get(); } 73*c8dee2aaSAndroid Build Coastguard Worker 74*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> makePromiseImageForDst(sk_sp<GrContextThreadSafeProxy>); dropCallbackContext()75*c8dee2aaSAndroid Build Coastguard Worker void dropCallbackContext() { fCallbackContext.reset(); } 76*c8dee2aaSAndroid Build Coastguard Worker 77*c8dee2aaSAndroid Build Coastguard Worker static void CreateBackendTexture(GrDirectContext*, TileData*); 78*c8dee2aaSAndroid Build Coastguard Worker static void DeleteBackendTexture(GrDirectContext*, TileData*); 79*c8dee2aaSAndroid Build Coastguard Worker 80*c8dee2aaSAndroid Build Coastguard Worker private: 81*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> makeWrappedTileDest(GrRecordingContext* context); 82*c8dee2aaSAndroid Build Coastguard Worker refCallbackContext()83*c8dee2aaSAndroid Build Coastguard Worker sk_sp<PromiseImageCallbackContext> refCallbackContext() { return fCallbackContext; } 84*c8dee2aaSAndroid Build Coastguard Worker 85*c8dee2aaSAndroid Build Coastguard Worker int fID = -1; 86*c8dee2aaSAndroid Build Coastguard Worker SkIRect fClip; // in the device space of the final SkSurface 87*c8dee2aaSAndroid Build Coastguard Worker SkIRect fPaddingOutsets; // random padding for the output surface 88*c8dee2aaSAndroid Build Coastguard Worker GrSurfaceCharacterization fPlaybackChar; // characterization for the tile's dst surface 89*c8dee2aaSAndroid Build Coastguard Worker 90*c8dee2aaSAndroid Build Coastguard Worker // The callback context holds (via its GrPromiseImageTexture) the backend texture 91*c8dee2aaSAndroid Build Coastguard Worker // that is both wrapped in 'fTileSurface' and backs this tile's promise image 92*c8dee2aaSAndroid Build Coastguard Worker // (i.e., the one returned by 'makePromiseImage'). 93*c8dee2aaSAndroid Build Coastguard Worker sk_sp<PromiseImageCallbackContext> fCallbackContext; 94*c8dee2aaSAndroid Build Coastguard Worker // 'fTileSurface' wraps the backend texture in 'fCallbackContext' and must exist until 95*c8dee2aaSAndroid Build Coastguard Worker // after 'fDisplayList' has been flushed (bc it owns the proxy the DDL's destination 96*c8dee2aaSAndroid Build Coastguard Worker // trampoline points at). 97*c8dee2aaSAndroid Build Coastguard Worker // TODO: fix the ref-order so we don't need 'fTileSurface' here 98*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> fTileSurface; 99*c8dee2aaSAndroid Build Coastguard Worker 100*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrDeferredDisplayList> fDisplayList; 101*c8dee2aaSAndroid Build Coastguard Worker }; 102*c8dee2aaSAndroid Build Coastguard Worker 103*c8dee2aaSAndroid Build Coastguard Worker DDLTileHelper(GrDirectContext*, 104*c8dee2aaSAndroid Build Coastguard Worker const GrSurfaceCharacterization& dstChar, 105*c8dee2aaSAndroid Build Coastguard Worker const SkIRect& viewport, 106*c8dee2aaSAndroid Build Coastguard Worker int numXDivisions, int numYDivisions, 107*c8dee2aaSAndroid Build Coastguard Worker bool addRandomPaddingToDst); 108*c8dee2aaSAndroid Build Coastguard Worker 109*c8dee2aaSAndroid Build Coastguard Worker void kickOffThreadedWork(SkTaskGroup* recordingTaskGroup, 110*c8dee2aaSAndroid Build Coastguard Worker SkTaskGroup* gpuTaskGroup, 111*c8dee2aaSAndroid Build Coastguard Worker GrDirectContext*, 112*c8dee2aaSAndroid Build Coastguard Worker SkPicture*); 113*c8dee2aaSAndroid Build Coastguard Worker 114*c8dee2aaSAndroid Build Coastguard Worker void createDDLsInParallel(SkPicture*); 115*c8dee2aaSAndroid Build Coastguard Worker 116*c8dee2aaSAndroid Build Coastguard Worker // Create the DDL that will compose all the tile images into a final result. 117*c8dee2aaSAndroid Build Coastguard Worker void createComposeDDL(); composeDDL()118*c8dee2aaSAndroid Build Coastguard Worker const sk_sp<GrDeferredDisplayList>& composeDDL() const { return fComposeDDL; } 119*c8dee2aaSAndroid Build Coastguard Worker 120*c8dee2aaSAndroid Build Coastguard Worker // For each tile, create its DDL and then draw it - all on a single thread. This is to allow 121*c8dee2aaSAndroid Build Coastguard Worker // comparison w/ just drawing the SKP directly (i.e., drawAllTilesDirectly). The 122*c8dee2aaSAndroid Build Coastguard Worker // DDL creations and draws are interleaved to prevent starvation of the GPU. 123*c8dee2aaSAndroid Build Coastguard Worker // Note: this is somewhat of a misuse/pessimistic-use of DDLs since they are supposed to 124*c8dee2aaSAndroid Build Coastguard Worker // be created on a separate thread. 125*c8dee2aaSAndroid Build Coastguard Worker void interleaveDDLCreationAndDraw(GrDirectContext*, SkPicture*); 126*c8dee2aaSAndroid Build Coastguard Worker 127*c8dee2aaSAndroid Build Coastguard Worker // This draws all the per-tile SKPs directly into all of the tiles w/o converting them to 128*c8dee2aaSAndroid Build Coastguard Worker // DDLs first - all on a single thread. 129*c8dee2aaSAndroid Build Coastguard Worker void drawAllTilesDirectly(GrDirectContext*, SkPicture*); 130*c8dee2aaSAndroid Build Coastguard Worker 131*c8dee2aaSAndroid Build Coastguard Worker void dropCallbackContexts(); 132*c8dee2aaSAndroid Build Coastguard Worker void resetAllTiles(); 133*c8dee2aaSAndroid Build Coastguard Worker numTiles()134*c8dee2aaSAndroid Build Coastguard Worker int numTiles() const { return fNumXDivisions * fNumYDivisions; } 135*c8dee2aaSAndroid Build Coastguard Worker 136*c8dee2aaSAndroid Build Coastguard Worker void createBackendTextures(SkTaskGroup*, GrDirectContext*); 137*c8dee2aaSAndroid Build Coastguard Worker void deleteBackendTextures(SkTaskGroup*, GrDirectContext*); 138*c8dee2aaSAndroid Build Coastguard Worker 139*c8dee2aaSAndroid Build Coastguard Worker private: 140*c8dee2aaSAndroid Build Coastguard Worker int fNumXDivisions; // number of tiles horizontally 141*c8dee2aaSAndroid Build Coastguard Worker int fNumYDivisions; // number of tiles vertically 142*c8dee2aaSAndroid Build Coastguard Worker skia_private::AutoTArray<TileData> fTiles; // 'fNumXDivisions' x 143*c8dee2aaSAndroid Build Coastguard Worker // 'fNumYDivisions' 144*c8dee2aaSAndroid Build Coastguard Worker 145*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrDeferredDisplayList> fComposeDDL; 146*c8dee2aaSAndroid Build Coastguard Worker 147*c8dee2aaSAndroid Build Coastguard Worker const GrSurfaceCharacterization fDstCharacterization; 148*c8dee2aaSAndroid Build Coastguard Worker }; 149*c8dee2aaSAndroid Build Coastguard Worker 150*c8dee2aaSAndroid Build Coastguard Worker #endif 151