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