Coverage Report

Created: 2024-05-20 07:14

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