xref: /aosp_15_r20/external/skia/include/gpu/ganesh/GrBackendSurface.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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/ganesh/GrTypes.h"
15 #include "include/gpu/ganesh/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(GPU_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
MakeDxgi(DXGI_FORMAT format)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     bool operator!=(const GrBackendFormat& that) const { return !(*this == that); }
64 
backend()65     GrBackendApi backend() const { return fBackend; }
textureType()66     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 skgpu::VulkanYcbcrConversionInfo,
95     // we will 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.
isValid()99     bool isValid() const { return fValid; }
100 
101 #if defined(SK_DEBUG) || defined(GPU_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>
GrBackendFormat(GrTextureType textureType,GrBackendApi api,const FormatData & formatData)117     GrBackendFormat(GrTextureType textureType, GrBackendApi api, const FormatData& formatData)
118             : fBackend(api), fValid(true), fTextureType(textureType) {
119         fFormatData.emplace<FormatData>(formatData);
120     }
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 
dimensions()173     SkISize dimensions() const { return {fWidth, fHeight}; }
width()174     int width() const { return fWidth; }
height()175     int height() const { return fHeight; }
getLabel()176     std::string_view getLabel() const { return fLabel; }
mipmapped()177     skgpu::Mipmapped mipmapped() const { return fMipmapped; }
hasMipmaps()178     bool hasMipmaps() const { return fMipmapped == skgpu::Mipmapped::kYes; }
backend()179     GrBackendApi backend() const {return fBackend; }
textureType()180     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.
isValid()211     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(GPU_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>
GrBackendTexture(int width,int height,std::string_view label,skgpu::Mipmapped mipped,GrBackendApi backend,GrTextureType texture,const TextureData & 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             , fTextureType(texture) {
246         fTextureData.emplace<TextureData>(textureData);
247     }
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 
dimensions()305     SkISize dimensions() const { return {fWidth, fHeight}; }
width()306     int width() const { return fWidth; }
height()307     int height() const { return fHeight; }
sampleCnt()308     int sampleCnt() const { return fSampleCnt; }
stencilBits()309     int stencilBits() const { return fStencilBits; }
backend()310     GrBackendApi backend() const {return fBackend; }
isFramebufferOnly()311     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.
isValid()341     bool isValid() const { return fIsValid; }
342 
343 #if defined(GPU_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>
GrBackendRenderTarget(int width,int height,int sampleCnt,int stencilBits,GrBackendApi backend,bool framebufferOnly,const RenderTargetData & rtData)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             , fBackend(backend) {
374         fRTData.emplace<RenderTargetData>(rtData);
375     }
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
413