Coverage Report

Created: 2024-05-20 07:14

/src/skia/include/gpu/graphite/Context.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2021 Google LLC
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 skgpu_graphite_Context_DEFINED
9
#define skgpu_graphite_Context_DEFINED
10
11
#include "include/core/SkImage.h"
12
#include "include/core/SkRefCnt.h"
13
#include "include/core/SkShader.h"
14
#include "include/gpu/graphite/ContextOptions.h"
15
#include "include/gpu/graphite/GraphiteTypes.h"
16
#include "include/gpu/graphite/Recorder.h"
17
#include "include/private/base/SingleOwner.h"
18
19
#include <chrono>
20
#include <functional>
21
#include <memory>
22
23
class SkColorSpace;
24
class SkRuntimeEffect;
25
class SkTraceMemoryDump;
26
27
namespace skgpu::graphite {
28
29
class BackendTexture;
30
class Buffer;
31
class ClientMappedBufferManager;
32
class Context;
33
class ContextPriv;
34
class GlobalCache;
35
class PaintOptions;
36
class PlotUploadTracker;
37
class QueueManager;
38
class Recording;
39
class ResourceProvider;
40
class SharedContext;
41
class TextureProxy;
42
43
class SK_API Context final {
44
public:
45
    Context(const Context&) = delete;
46
    Context(Context&&) = delete;
47
    Context& operator=(const Context&) = delete;
48
    Context& operator=(Context&&) = delete;
49
50
    ~Context();
51
52
    BackendApi backend() const;
53
54
    std::unique_ptr<Recorder> makeRecorder(const RecorderOptions& = {});
55
56
    bool insertRecording(const InsertRecordingInfo&);
57
    bool submit(SyncToCpu = SyncToCpu::kNo);
58
59
    /** Returns true if there is work that was submitted to the GPU that has not finished. */
60
    bool hasUnfinishedGpuWork() const;
61
62
    void asyncRescaleAndReadPixels(const SkImage* image,
63
                                   const SkImageInfo& dstImageInfo,
64
                                   const SkIRect& srcRect,
65
                                   SkImage::RescaleGamma rescaleGamma,
66
                                   SkImage::RescaleMode rescaleMode,
67
                                   SkImage::ReadPixelsCallback callback,
68
                                   SkImage::ReadPixelsContext context);
69
70
    void asyncRescaleAndReadPixels(const SkSurface* surface,
71
                                   const SkImageInfo& dstImageInfo,
72
                                   const SkIRect& srcRect,
73
                                   SkImage::RescaleGamma rescaleGamma,
74
                                   SkImage::RescaleMode rescaleMode,
75
                                   SkImage::ReadPixelsCallback callback,
76
                                   SkImage::ReadPixelsContext context);
77
78
    void asyncRescaleAndReadPixelsYUV420(const SkImage*,
79
                                         SkYUVColorSpace yuvColorSpace,
80
                                         sk_sp<SkColorSpace> dstColorSpace,
81
                                         const SkIRect& srcRect,
82
                                         const SkISize& dstSize,
83
                                         SkImage::RescaleGamma rescaleGamma,
84
                                         SkImage::RescaleMode rescaleMode,
85
                                         SkImage::ReadPixelsCallback callback,
86
                                         SkImage::ReadPixelsContext context);
87
88
    void asyncRescaleAndReadPixelsYUV420(const SkSurface*,
89
                                         SkYUVColorSpace yuvColorSpace,
90
                                         sk_sp<SkColorSpace> dstColorSpace,
91
                                         const SkIRect& srcRect,
92
                                         const SkISize& dstSize,
93
                                         SkImage::RescaleGamma rescaleGamma,
94
                                         SkImage::RescaleMode rescaleMode,
95
                                         SkImage::ReadPixelsCallback callback,
96
                                         SkImage::ReadPixelsContext context);
97
98
    void asyncRescaleAndReadPixelsYUVA420(const SkImage*,
99
                                          SkYUVColorSpace yuvColorSpace,
100
                                          sk_sp<SkColorSpace> dstColorSpace,
101
                                          const SkIRect& srcRect,
102
                                          const SkISize& dstSize,
103
                                          SkImage::RescaleGamma rescaleGamma,
104
                                          SkImage::RescaleMode rescaleMode,
105
                                          SkImage::ReadPixelsCallback callback,
106
                                          SkImage::ReadPixelsContext context);
107
108
    void asyncRescaleAndReadPixelsYUVA420(const SkSurface*,
109
                                          SkYUVColorSpace yuvColorSpace,
110
                                          sk_sp<SkColorSpace> dstColorSpace,
111
                                          const SkIRect& srcRect,
112
                                          const SkISize& dstSize,
113
                                          SkImage::RescaleGamma rescaleGamma,
114
                                          SkImage::RescaleMode rescaleMode,
115
                                          SkImage::ReadPixelsCallback callback,
116
                                          SkImage::ReadPixelsContext context);
117
118
    /**
119
     * Checks whether any asynchronous work is complete and if so calls related callbacks.
120
     */
121
    void checkAsyncWorkCompletion();
122
123
    /**
124
     * Called to delete the passed in BackendTexture. This should only be called if the
125
     * BackendTexture was created by calling Recorder::createBackendTexture on a Recorder created
126
     * from this Context. If the BackendTexture is not valid or does not match the BackendApi of the
127
     * Context then nothing happens.
128
     *
129
     * Otherwise this will delete/release the backend object that is wrapped in the BackendTexture.
130
     * The BackendTexture will be reset to an invalid state and should not be used again.
131
     */
132
    void deleteBackendTexture(const BackendTexture&);
133
134
    /**
135
     * Frees GPU resources created and held by the Context. Can be called to reduce GPU memory
136
     * pressure. Any resources that are still in use (e.g. being used by work submitted to the GPU)
137
     * will not be deleted by this call. If the caller wants to make sure all resources are freed,
138
     * then they should first make sure to submit and wait on any outstanding work.
139
     */
140
    void freeGpuResources();
141
142
    /**
143
     * Purge GPU resources on the Context that haven't been used in the past 'msNotUsed'
144
     * milliseconds or are otherwise marked for deletion, regardless of whether the context is under
145
     * budget.
146
     */
147
    void performDeferredCleanup(std::chrono::milliseconds msNotUsed);
148
149
    /**
150
     * Returns the number of bytes of the Context's gpu memory cache budget that are currently in
151
     * use.
152
     */
153
    size_t currentBudgetedBytes() const;
154
155
    /**
156
     * Returns the size of Context's gpu memory cache budget in bytes.
157
     */
158
    size_t maxBudgetedBytes() const;
159
160
    /**
161
     * Enumerates all cached GPU resources owned by the Context and dumps their memory to
162
     * traceMemoryDump.
163
     */
164
    void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const;
165
166
    /**
167
     * Returns true if the backend-specific context has gotten into an unrecoverarble, lost state
168
     * (e.g. if we've gotten a VK_ERROR_DEVICE_LOST in the Vulkan backend).
169
     */
170
    bool isDeviceLost() const;
171
172
    /**
173
     * Returns the maximum texture dimension supported by the underlying backend.
174
     */
175
    int maxTextureSize() const;
176
177
    /*
178
     * Does this context support protected content?
179
     */
180
    bool supportsProtectedContent() const;
181
182
    // Provides access to functions that aren't part of the public API.
183
    ContextPriv priv();
184
    const ContextPriv priv() const;  // NOLINT(readability-const-return-type)
185
186
    class ContextID {
187
    public:
188
        static Context::ContextID Next();
189
190
0
        ContextID() : fID(SK_InvalidUniqueID) {}
191
192
0
        bool operator==(const ContextID& that) const { return fID == that.fID; }
193
0
        bool operator!=(const ContextID& that) const { return !(*this == that); }
194
195
0
        void makeInvalid() { fID = SK_InvalidUniqueID; }
196
0
        bool isValid() const { return fID != SK_InvalidUniqueID; }
197
198
    private:
199
0
        constexpr ContextID(uint32_t id) : fID(id) {}
200
        uint32_t fID;
201
    };
202
203
0
    ContextID contextID() const { return fContextID; }
204
205
protected:
206
    Context(sk_sp<SharedContext>, std::unique_ptr<QueueManager>, const ContextOptions&);
207
208
private:
209
    friend class ContextPriv;
210
    friend class ContextCtorAccessor;
211
212
    struct PixelTransferResult {
213
        using ConversionFn = void(void* dst, const void* mappedBuffer);
214
        // If null then the transfer could not be performed. Otherwise this buffer will contain
215
        // the pixel data when the transfer is complete.
216
        sk_sp<Buffer> fTransferBuffer;
217
        // Size of the read.
218
        SkISize fSize;
219
        // RowBytes for transfer buffer data
220
        size_t fRowBytes;
221
        // If this is null then the transfer buffer will contain the data in the requested
222
        // color type. Otherwise, when the transfer is done this must be called to convert
223
        // from the transfer buffer's color type to the requested color type.
224
        std::function<ConversionFn> fPixelConverter;
225
    };
226
227
0
    SingleOwner* singleOwner() const { return &fSingleOwner; }
228
229
    // Must be called in Make() to handle one-time GPU setup operations that can possibly fail and
230
    // require Context::Make() to return a nullptr.
231
    bool finishInitialization();
232
233
    void checkForFinishedWork(SyncToCpu);
234
235
    void asyncRescaleAndReadPixelsYUV420Impl(const SkImage*,
236
                                             SkYUVColorSpace yuvColorSpace,
237
                                             bool readAlpha,
238
                                             sk_sp<SkColorSpace> dstColorSpace,
239
                                             const SkIRect& srcRect,
240
                                             const SkISize& dstSize,
241
                                             SkImage::RescaleGamma rescaleGamma,
242
                                             SkImage::RescaleMode rescaleMode,
243
                                             SkImage::ReadPixelsCallback callback,
244
                                             SkImage::ReadPixelsContext context);
245
246
    void asyncReadPixels(const TextureProxy* textureProxy,
247
                         const SkImageInfo& srcImageInfo,
248
                         const SkColorInfo& dstColorInfo,
249
                         const SkIRect& srcRect,
250
                         SkImage::ReadPixelsCallback callback,
251
                         SkImage::ReadPixelsContext context);
252
253
    void asyncReadPixelsYUV420(Recorder*,
254
                               const SkImage*,
255
                               SkYUVColorSpace yuvColorSpace,
256
                               bool readAlpha,
257
                               const SkIRect& srcRect,
258
                               SkImage::ReadPixelsCallback callback,
259
                               SkImage::ReadPixelsContext context);
260
261
    void finalizeAsyncReadPixels(SkSpan<PixelTransferResult>,
262
                                 SkImage::ReadPixelsCallback callback,
263
                                 SkImage::ReadPixelsContext callbackContext);
264
265
    // Inserts a texture to buffer transfer task, used by asyncReadPixels methods
266
    PixelTransferResult transferPixels(const TextureProxy*,
267
                                       const SkImageInfo& srcImageInfo,
268
                                       const SkColorInfo& dstColorInfo,
269
                                       const SkIRect& srcRect);
270
271
    sk_sp<SharedContext> fSharedContext;
272
    std::unique_ptr<ResourceProvider> fResourceProvider;
273
    std::unique_ptr<QueueManager> fQueueManager;
274
    std::unique_ptr<ClientMappedBufferManager> fMappedBufferManager;
275
276
    // In debug builds we guard against improper thread handling. This guard is passed to the
277
    // ResourceCache for the Context.
278
    mutable SingleOwner fSingleOwner;
279
280
#if defined(GRAPHITE_TEST_UTILS)
281
    // In test builds a Recorder may track the Context that was used to create it.
282
    bool fStoreContextRefInRecorder = false;
283
    // If this tracking is on, to allow the client to safely delete this Context or its Recorders
284
    // in any order we must also track the Recorders created here.
285
    std::vector<Recorder*> fTrackedRecorders;
286
#endif
287
288
    // Needed for MessageBox handling
289
    const ContextID fContextID;
290
};
291
292
} // namespace skgpu::graphite
293
294
#endif // skgpu_graphite_Context_DEFINED