/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 |