Coverage Report

Created: 2024-05-20 07:14

/src/skia/include/gpu/GrBackendSurface.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2017 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 GrBackendSurface_DEFINED
9
#define GrBackendSurface_DEFINED
10
11
#include "include/core/SkRefCnt.h"
12
#include "include/core/SkSize.h"
13
#include "include/gpu/GpuTypes.h"
14
#include "include/gpu/GrTypes.h"
15
#include "include/gpu/mock/GrMockTypes.h"
16
#include "include/private/base/SkAPI.h"
17
#include "include/private/base/SkAnySubclass.h"
18
#include "include/private/base/SkDebug.h"
19
#include "include/private/gpu/ganesh/GrTypesPriv.h"
20
21
enum class SkTextureCompressionType;
22
class GrBackendFormatData;
23
class GrBackendTextureData;
24
class GrBackendRenderTargetData;
25
26
namespace skgpu {
27
class MutableTextureState;
28
}
29
30
#ifdef SK_DIRECT3D
31
#include "include/private/gpu/ganesh/GrD3DTypesMinimal.h"
32
class GrD3DResourceState;
33
#endif
34
35
#if defined(SK_DEBUG) || defined(GR_TEST_UTILS)
36
class SkString;
37
#endif
38
39
#include <cstddef>
40
#include <cstdint>
41
#include <string>
42
#include <string_view>
43
44
class SK_API GrBackendFormat {
45
public:
46
    // Creates an invalid backend format.
47
    GrBackendFormat();
48
    GrBackendFormat(const GrBackendFormat&);
49
    GrBackendFormat& operator=(const GrBackendFormat&);
50
    ~GrBackendFormat();
51
52
#ifdef SK_DIRECT3D
53
    static GrBackendFormat MakeDxgi(DXGI_FORMAT format) {
54
        return GrBackendFormat(format);
55
    }
56
#endif
57
58
    static GrBackendFormat MakeMock(GrColorType colorType,
59
                                    SkTextureCompressionType compression,
60
                                    bool isStencilFormat = false);
61
62
    bool operator==(const GrBackendFormat& that) const;
63
38.6k
    bool operator!=(const GrBackendFormat& that) const { return !(*this == that); }
64
65
1.00M
    GrBackendApi backend() const { return fBackend; }
66
569k
    GrTextureType textureType() const { return fTextureType; }
67
68
    /**
69
     * Gets the channels present in the format as a bitfield of SkColorChannelFlag values.
70
     * Luminance channels are reported as kGray_SkColorChannelFlag.
71
     */
72
    uint32_t channelMask() const;
73
74
    GrColorFormatDesc desc() const;
75
76
#ifdef SK_DIRECT3D
77
    /**
78
     * If the backend API is Direct3D this gets the format as a DXGI_FORMAT and returns true.
79
     * Otherwise, returns false.
80
     */
81
    bool asDxgiFormat(DXGI_FORMAT*) const;
82
#endif
83
84
    /**
85
     * If the backend API is not Mock these three calls will return kUnknown, kNone or false,
86
     * respectively. Otherwise, only one of the following can be true. The GrColorType is not
87
     * kUnknown, the compression type is not kNone, or this is a mock stencil format.
88
     */
89
    GrColorType asMockColorType() const;
90
    SkTextureCompressionType asMockCompressionType() const;
91
    bool isMockStencilFormat() const;
92
93
    // If possible, copies the GrBackendFormat and forces the texture type to be Texture2D. If the
94
    // GrBackendFormat was for Vulkan and it originally had a GrVkYcbcrConversionInfo, we will
95
    // remove the conversion and set the format to be VK_FORMAT_R8G8B8A8_UNORM.
96
    GrBackendFormat makeTexture2D() const;
97
98
    // Returns true if the backend format has been initialized.
99
4.33M
    bool isValid() const { return fValid; }
100
101
#if defined(SK_DEBUG) || defined(GR_TEST_UTILS)
102
    SkString toStr() const;
103
#endif
104
105
private:
106
    // Size determined by looking at the GrBackendFormatData subclasses, then guessing-and-checking.
107
    // Compiler will complain if this is too small - in that case, just increase the number.
108
    inline constexpr static size_t kMaxSubclassSize = 80;
109
    using AnyFormatData = SkAnySubclass<GrBackendFormatData, kMaxSubclassSize>;
110
111
    friend class GrBackendSurfacePriv;
112
    friend class GrBackendFormatData;
113
114
    // Used by internal factories. Should not be used externally. Use factories like
115
    // GrBackendFormats::MakeGL instead.
116
    template <typename FormatData>
117
    GrBackendFormat(GrTextureType textureType, GrBackendApi api, const FormatData& formatData)
118
0
            : fBackend(api), fValid(true), fTextureType(textureType) {
119
0
        fFormatData.emplace<FormatData>(formatData);
120
0
    }
121
122
#ifdef SK_DIRECT3D
123
    GrBackendFormat(DXGI_FORMAT dxgiFormat);
124
#endif
125
126
    GrBackendFormat(GrColorType, SkTextureCompressionType, bool isStencilFormat);
127
128
#ifdef SK_DEBUG
129
    bool validateMock() const;
130
#endif
131
132
    GrBackendApi fBackend = GrBackendApi::kMock;
133
    bool fValid = false;
134
    AnyFormatData fFormatData;
135
136
    union {
137
#ifdef SK_DIRECT3D
138
        DXGI_FORMAT fDxgiFormat;
139
#endif
140
        struct {
141
            GrColorType fColorType;
142
            SkTextureCompressionType fCompressionType;
143
            bool fIsStencilFormat;
144
        } fMock;
145
    };
146
    GrTextureType fTextureType = GrTextureType::kNone;
147
};
148
149
class SK_API GrBackendTexture {
150
public:
151
    // Creates an invalid backend texture.
152
    GrBackendTexture();
153
154
#ifdef SK_DIRECT3D
155
    GrBackendTexture(int width,
156
                     int height,
157
                     const GrD3DTextureResourceInfo& d3dInfo,
158
                     std::string_view label = {});
159
#endif
160
161
    GrBackendTexture(int width,
162
                     int height,
163
                     skgpu::Mipmapped,
164
                     const GrMockTextureInfo& mockInfo,
165
                     std::string_view label = {});
166
167
    GrBackendTexture(const GrBackendTexture& that);
168
169
    ~GrBackendTexture();
170
171
    GrBackendTexture& operator=(const GrBackendTexture& that);
172
173
0
    SkISize dimensions() const { return {fWidth, fHeight}; }
174
0
    int width() const { return fWidth; }
175
0
    int height() const { return fHeight; }
176
0
    std::string_view getLabel() const { return fLabel; }
177
0
    skgpu::Mipmapped mipmapped() const { return fMipmapped; }
178
0
    bool hasMipmaps() const { return fMipmapped == skgpu::Mipmapped::kYes; }
179
0
    GrBackendApi backend() const {return fBackend; }
180
0
    GrTextureType textureType() const { return fTextureType; }
181
182
#ifdef SK_DIRECT3D
183
    // If the backend API is Direct3D, copies a snapshot of the GrD3DTextureResourceInfo struct into
184
    // the passed in pointer and returns true. This snapshot will set the fResourceState to the
185
    // current resource state. Otherwise returns false if the backend API is not D3D.
186
    bool getD3DTextureResourceInfo(GrD3DTextureResourceInfo*) const;
187
188
    // Anytime the client changes the D3D12_RESOURCE_STATES of the D3D12_RESOURCE captured by this
189
    // GrBackendTexture, they must call this function to notify Skia of the changed layout.
190
    void setD3DResourceState(GrD3DResourceStateEnum);
191
#endif
192
193
    // Get the GrBackendFormat for this texture (or an invalid format if this is not valid).
194
    GrBackendFormat getBackendFormat() const;
195
196
    // If the backend API is Mock, copies a snapshot of the GrMockTextureInfo struct into the passed
197
    // in pointer and returns true. Otherwise returns false if the backend API is not Mock.
198
    bool getMockTextureInfo(GrMockTextureInfo*) const;
199
200
    // If the client changes any of the mutable backend of the GrBackendTexture they should call
201
    // this function to inform Skia that those values have changed. The backend API specific state
202
    // that can be set from this function are:
203
    //
204
    // Vulkan: VkImageLayout and QueueFamilyIndex
205
    void setMutableState(const skgpu::MutableTextureState&);
206
207
    // Returns true if we are working with protected content.
208
    bool isProtected() const;
209
210
    // Returns true if the backend texture has been initialized.
211
0
    bool isValid() const { return fIsValid; }
212
213
    // Returns true if both textures are valid and refer to the same API texture.
214
    bool isSameTexture(const GrBackendTexture&);
215
216
#if defined(GR_TEST_UTILS)
217
    static bool TestingOnly_Equals(const GrBackendTexture&, const GrBackendTexture&);
218
#endif
219
220
private:
221
    // Size determined by looking at the GrBackendTextureData subclasses, then guessing-and-checking.
222
    // Compiler will complain if this is too small - in that case, just increase the number.
223
    inline constexpr static size_t kMaxSubclassSize = 176;
224
    using AnyTextureData = SkAnySubclass<GrBackendTextureData, kMaxSubclassSize>;
225
226
    friend class GrBackendSurfacePriv;
227
    friend class GrBackendTextureData;
228
229
    // Used by internal factories. Should not be used externally. Use factories like
230
    // GrBackendTextures::MakeGL instead.
231
    template <typename TextureData>
232
    GrBackendTexture(int width,
233
                     int height,
234
                     std::string_view label,
235
                     skgpu::Mipmapped mipped,
236
                     GrBackendApi backend,
237
                     GrTextureType texture,
238
                     const TextureData& textureData)
239
            : fIsValid(true)
240
            , fWidth(width)
241
            , fHeight(height)
242
            , fLabel(label)
243
            , fMipmapped(mipped)
244
            , fBackend(backend)
245
0
            , fTextureType(texture) {
246
0
        fTextureData.emplace<TextureData>(textureData);
247
0
    }
248
249
    friend class GrVkGpu;  // for getMutableState
250
    sk_sp<skgpu::MutableTextureState> getMutableState() const;
251
252
#ifdef SK_DIRECT3D
253
    friend class GrD3DTexture;
254
    friend class GrD3DGpu;     // for getGrD3DResourceState
255
    GrBackendTexture(int width,
256
                     int height,
257
                     const GrD3DTextureResourceInfo& vkInfo,
258
                     sk_sp<GrD3DResourceState> state,
259
                     std::string_view label = {});
260
    sk_sp<GrD3DResourceState> getGrD3DResourceState() const;
261
#endif
262
263
    // Free and release and resources being held by the GrBackendTexture.
264
    void cleanup();
265
266
    bool fIsValid;
267
    int fWidth;         //<! width in pixels
268
    int fHeight;        //<! height in pixels
269
    const std::string fLabel;
270
    skgpu::Mipmapped fMipmapped;
271
    GrBackendApi fBackend;
272
    GrTextureType fTextureType;
273
    AnyTextureData fTextureData;
274
275
    union {
276
        GrMockTextureInfo fMockInfo;
277
#ifdef SK_DIRECT3D
278
        GrD3DBackendSurfaceInfo fD3DInfo;
279
#endif
280
    };
281
};
282
283
class SK_API GrBackendRenderTarget {
284
public:
285
    // Creates an invalid backend texture.
286
    GrBackendRenderTarget();
287
288
#ifdef SK_DIRECT3D
289
    GrBackendRenderTarget(int width,
290
                          int height,
291
                          const GrD3DTextureResourceInfo& d3dInfo);
292
#endif
293
294
    GrBackendRenderTarget(int width,
295
                          int height,
296
                          int sampleCnt,
297
                          int stencilBits,
298
                          const GrMockRenderTargetInfo& mockInfo);
299
300
    ~GrBackendRenderTarget();
301
302
    GrBackendRenderTarget(const GrBackendRenderTarget& that);
303
    GrBackendRenderTarget& operator=(const GrBackendRenderTarget&);
304
305
0
    SkISize dimensions() const { return {fWidth, fHeight}; }
306
0
    int width() const { return fWidth; }
307
0
    int height() const { return fHeight; }
308
0
    int sampleCnt() const { return fSampleCnt; }
309
0
    int stencilBits() const { return fStencilBits; }
310
0
    GrBackendApi backend() const {return fBackend; }
311
0
    bool isFramebufferOnly() const { return fFramebufferOnly; }
312
313
#ifdef SK_DIRECT3D
314
    // If the backend API is Direct3D, copies a snapshot of the GrMtlTextureInfo struct into the
315
    // passed in pointer and returns true. Otherwise returns false if the backend API is not D3D.
316
    bool getD3DTextureResourceInfo(GrD3DTextureResourceInfo*) const;
317
318
    // Anytime the client changes the D3D12_RESOURCE_STATES of the D3D12_RESOURCE captured by this
319
    // GrBackendTexture, they must call this function to notify Skia of the changed layout.
320
    void setD3DResourceState(GrD3DResourceStateEnum);
321
#endif
322
323
    // Get the GrBackendFormat for this render target (or an invalid format if this is not valid).
324
    GrBackendFormat getBackendFormat() const;
325
326
    // If the backend API is Mock, copies a snapshot of the GrMockTextureInfo struct into the passed
327
    // in pointer and returns true. Otherwise returns false if the backend API is not Mock.
328
    bool getMockRenderTargetInfo(GrMockRenderTargetInfo*) const;
329
330
    // If the client changes any of the mutable backend of the GrBackendTexture they should call
331
    // this function to inform Skia that those values have changed. The backend API specific state
332
    // that can be set from this function are:
333
    //
334
    // Vulkan: VkImageLayout and QueueFamilyIndex
335
    void setMutableState(const skgpu::MutableTextureState&);
336
337
    // Returns true if we are working with protected content.
338
    bool isProtected() const;
339
340
    // Returns true if the backend texture has been initialized.
341
0
    bool isValid() const { return fIsValid; }
342
343
#if defined(GR_TEST_UTILS)
344
    static bool TestingOnly_Equals(const GrBackendRenderTarget&, const GrBackendRenderTarget&);
345
#endif
346
347
private:
348
    // Size determined by looking at the GrBackendRenderTargetData subclasses, then
349
    // guessing-and-checking. Compiler will complain if this is too small - in that case, just
350
    // increase the number.
351
    inline constexpr static size_t kMaxSubclassSize = 176;
352
    using AnyRenderTargetData = SkAnySubclass<GrBackendRenderTargetData, kMaxSubclassSize>;
353
354
    friend class GrBackendSurfacePriv;
355
    friend class GrBackendRenderTargetData;
356
357
    // Used by internal factories. Should not be used externally. Use factories like
358
    // GrBackendRenderTargets::MakeGL instead.
359
    template <typename RenderTargetData>
360
    GrBackendRenderTarget(int width,
361
                          int height,
362
                          int sampleCnt,
363
                          int stencilBits,
364
                          GrBackendApi backend,
365
                          bool framebufferOnly,
366
                          const RenderTargetData& rtData)
367
            : fIsValid(true)
368
            , fFramebufferOnly(framebufferOnly)
369
            , fWidth(width)
370
            , fHeight(height)
371
            , fSampleCnt(sampleCnt)
372
            , fStencilBits(stencilBits)
373
0
            , fBackend(backend) {
374
0
        fRTData.emplace<RenderTargetData>(rtData);
375
0
    }
376
377
    friend class GrVkGpu; // for getMutableState
378
    sk_sp<skgpu::MutableTextureState> getMutableState() const;
379
380
#ifdef SK_DIRECT3D
381
    friend class GrD3DGpu;
382
    friend class GrD3DRenderTarget;
383
    GrBackendRenderTarget(int width,
384
                          int height,
385
                          const GrD3DTextureResourceInfo& d3dInfo,
386
                          sk_sp<GrD3DResourceState> state);
387
    sk_sp<GrD3DResourceState> getGrD3DResourceState() const;
388
#endif
389
390
    // Free and release and resources being held by the GrBackendTexture.
391
    void cleanup();
392
393
    bool fIsValid;
394
    bool fFramebufferOnly = false;
395
    int fWidth;         //<! width in pixels
396
    int fHeight;        //<! height in pixels
397
398
    int fSampleCnt;
399
    int fStencilBits;
400
401
    GrBackendApi fBackend;
402
    AnyRenderTargetData fRTData;
403
404
    union {
405
        GrMockRenderTargetInfo fMockInfo;
406
#ifdef SK_DIRECT3D
407
        GrD3DBackendSurfaceInfo fD3DInfo;
408
#endif
409
    };
410
};
411
412
#endif