tzh
2024-08-22 c7d0944258c7d0943aa7b2211498fd612971ce27
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/*
 * Copyright 2015 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
 
#ifndef GrDrawingManager_DEFINED
#define GrDrawingManager_DEFINED
 
#include "GrDeferredUpload.h"
#include "GrPathRenderer.h"
#include "GrPathRendererChain.h"
#include "GrResourceCache.h"
#include "SkTArray.h"
#include "text/GrTextContext.h"
 
class GrContext;
class GrCoverageCountingPathRenderer;
class GrOnFlushCallbackObject;
class GrOpFlushState;
class GrRenderTargetContext;
class GrRenderTargetProxy;
class GrSingleOWner;
class GrRenderTargetOpList;
class GrSoftwarePathRenderer;
class GrTextureContext;
class GrTextureOpList;
class SkDeferredDisplayList;
 
// The GrDrawingManager allocates a new GrRenderTargetContext for each GrRenderTarget
// but all of them still land in the same GrOpList!
//
// In the future this class will allocate a new GrRenderTargetContext for
// each GrRenderTarget/GrOpList and manage the DAG.
class GrDrawingManager {
public:
    ~GrDrawingManager();
 
    bool wasAbandoned() const { return fAbandoned; }
    void freeGpuResources();
 
    sk_sp<GrRenderTargetContext> makeRenderTargetContext(sk_sp<GrSurfaceProxy>,
                                                         sk_sp<SkColorSpace>,
                                                         const SkSurfaceProps*,
                                                         bool managedOpList = true);
    sk_sp<GrTextureContext> makeTextureContext(sk_sp<GrSurfaceProxy>, sk_sp<SkColorSpace>);
 
    // The caller automatically gets a ref on the returned opList. It must
    // be balanced by an unref call.
    // A managed opList is controlled by the drawing manager (i.e., sorted & flushed with the
    // other). An unmanaged one is created and used by the onFlushCallback.
    sk_sp<GrRenderTargetOpList> newRTOpList(GrRenderTargetProxy* rtp, bool managedOpList);
    sk_sp<GrTextureOpList> newTextureOpList(GrTextureProxy* textureProxy);
 
    GrContext* getContext() { return fContext; }
 
    GrTextContext* getTextContext();
 
    GrPathRenderer* getPathRenderer(const GrPathRenderer::CanDrawPathArgs& args,
                                    bool allowSW,
                                    GrPathRendererChain::DrawType drawType,
                                    GrPathRenderer::StencilSupport* stencilSupport = nullptr);
 
    GrPathRenderer* getSoftwarePathRenderer();
 
    // Returns a direct pointer to the coverage counting path renderer, or null if it is not
    // supported and turned on.
    GrCoverageCountingPathRenderer* getCoverageCountingPathRenderer();
 
    void flushIfNecessary();
 
    static bool ProgramUnitTest(GrContext* context, int maxStages, int maxLevels);
 
    GrSemaphoresSubmitted prepareSurfaceForExternalIO(GrSurfaceProxy*,
                                                      int numSemaphores,
                                                      GrBackendSemaphore backendSemaphores[]);
 
    void addOnFlushCallbackObject(GrOnFlushCallbackObject*);
    void testingOnly_removeOnFlushCallbackObject(GrOnFlushCallbackObject*);
 
    void moveOpListsToDDL(SkDeferredDisplayList* ddl);
    void copyOpListsFromDDL(const SkDeferredDisplayList*, GrRenderTargetProxy* newDest);
 
private:
    // This class encapsulates maintenance and manipulation of the drawing manager's DAG of opLists.
    class OpListDAG {
    public:
        OpListDAG(bool explicitlyAllocating, GrContextOptions::Enable sortOpLists);
        ~OpListDAG();
 
        // Currently, when explicitly allocating resources, this call will topologically sort the
        // opLists.
        // MDB TODO: remove once incremental opList sorting is enabled
        void prepForFlush();
 
        void closeAll(const GrCaps* caps);
 
        // A yucky combination of closeAll and reset
        void cleanup(const GrCaps* caps);
 
        void gatherIDs(SkSTArray<8, uint32_t, true>* idArray) const;
 
        void reset();
 
        // These calls forceably remove an opList from the DAG. They are problematic bc they just
        // remove the opList but don't cleanup any refering pointers (i.e., dependency pointers
        // in the DAG). They work right now bc they are only called at flush time, after the
        // topological sort is complete (so the dangling pointers aren't used).
        void removeOpList(int index);
        void removeOpLists(int startIndex, int stopIndex);
 
        bool empty() const { return fOpLists.empty(); }
        int numOpLists() const { return fOpLists.count(); }
 
        GrOpList* opList(int index) { return fOpLists[index].get(); }
        const GrOpList* opList(int index) const { return fOpLists[index].get(); }
 
        GrOpList* back() { return fOpLists.back().get(); }
        const GrOpList* back() const { return fOpLists.back().get(); }
 
        void add(sk_sp<GrOpList>);
        void add(const SkTArray<sk_sp<GrOpList>>&);
 
        void swap(SkTArray<sk_sp<GrOpList>>* opLists);
 
        bool sortingOpLists() const { return fSortOpLists; }
 
    private:
        SkTArray<sk_sp<GrOpList>> fOpLists;
        bool                      fSortOpLists;
    };
 
    GrDrawingManager(GrContext*, const GrPathRendererChain::Options&,
                     const GrTextContext::Options&, GrSingleOwner*,
                     bool explicitlyAllocating, GrContextOptions::Enable sortRenderTargets,
                     GrContextOptions::Enable reduceOpListSplitting);
 
    void abandon();
    void cleanup();
 
    // return true if any opLists were actually executed; false otherwise
    bool executeOpLists(int startIndex, int stopIndex, GrOpFlushState*, int* numOpListsExecuted);
 
    GrSemaphoresSubmitted flush(GrSurfaceProxy* proxy,
                                int numSemaphores = 0,
                                GrBackendSemaphore backendSemaphores[] = nullptr);
 
    SkDEBUGCODE(void validate() const);
 
    friend class GrContext;  // for access to: ctor, abandon, reset & flush
    friend class GrContextPriv; // access to: flush
    friend class GrOnFlushResourceProvider; // this is just a shallow wrapper around this class
 
    static const int kNumPixelGeometries = 5; // The different pixel geometries
    static const int kNumDFTOptions = 2;      // DFT or no DFT
 
    GrContext*                        fContext;
    GrPathRendererChain::Options      fOptionsForPathRendererChain;
    GrTextContext::Options            fOptionsForTextContext;
 
    std::unique_ptr<char[]>           fVertexBufferSpace;
    std::unique_ptr<char[]>           fIndexBufferSpace;
    // In debug builds we guard against improper thread handling
    GrSingleOwner*                    fSingleOwner;
 
    bool                              fAbandoned;
    OpListDAG                         fDAG;
    GrOpList*                         fActiveOpList = nullptr;
    // These are the IDs of the opLists currently being flushed (in internalFlush)
    SkSTArray<8, uint32_t, true>      fFlushingOpListIDs;
    // These are the new opLists generated by the onFlush CBs
    SkSTArray<8, sk_sp<GrOpList>>     fOnFlushCBOpLists;
 
    std::unique_ptr<GrTextContext>    fTextContext;
 
    std::unique_ptr<GrPathRendererChain> fPathRendererChain;
    sk_sp<GrSoftwarePathRenderer>     fSoftwarePathRenderer;
 
    GrTokenTracker                    fTokenTracker;
    bool                              fFlushing;
    bool                              fReduceOpListSplitting;
 
    SkTArray<GrOnFlushCallbackObject*> fOnFlushCBObjects;
};
 
#endif