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