• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright 2013 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 #ifndef GrCaps_DEFINED
9 #define GrCaps_DEFINED
10 
11 #include "include/core/SkCapabilities.h"
12 #include "include/core/SkRefCnt.h"
13 #include "include/core/SkTypes.h"
14 #include "include/gpu/GrDriverBugWorkarounds.h"
15 #include "include/gpu/GrTypes.h"
16 #include "include/private/base/SkTo.h"
17 #include "include/private/gpu/ganesh/GrTypesPriv.h"
18 #include "src/gpu/Blend.h"
19 #include "src/gpu/Swizzle.h"
20 #include "src/gpu/ganesh/GrSamplerState.h"
21 #include "src/gpu/ganesh/GrShaderCaps.h"
22 #include "src/gpu/ganesh/GrSurfaceProxy.h"
23 
24 #include <algorithm>
25 #include <cstddef>
26 #include <cstdint>
27 #include <memory>
28 #include <string>
29 #include <string_view>
30 #include <tuple>
31 #include <vector>
32 
33 class GrBackendFormat;
34 class GrBackendRenderTarget;
35 class GrProgramDesc;
36 class GrProgramInfo;
37 class GrRenderTarget;
38 class GrRenderTargetProxy;
39 class GrSurface;
40 class SkJSONWriter;
41 enum class SkTextureCompressionType;
42 struct GrContextOptions;
43 struct SkIRect;
44 struct SkISize;
45 
46 namespace skgpu {
47     class KeyBuilder;
48     enum class Mipmapped : bool;
49 }
50 namespace GrTest {
51     struct TestFormatColorTypeCombination;
52 }
53 
54 /**
55  * Represents the capabilities of a GrContext.
56  */
57 class GrCaps : public SkCapabilities {
58 public:
59     GrCaps(const GrContextOptions&);
60 
61     void dumpJSON(SkJSONWriter*) const;
62 
shaderCaps()63     const GrShaderCaps* shaderCaps() const { return fShaderCaps.get(); }
64 
65 #if defined(GR_TEST_UTILS)
deviceName()66     std::string_view deviceName() const { return fDeviceName; }
67 #endif
68 
npotTextureTileSupport()69     bool npotTextureTileSupport() const { return fNPOTTextureTileSupport; }
70     /** To avoid as-yet-unnecessary complexity we don't allow any partial support of MIP Maps (e.g.
71         only for POT textures) */
mipmapSupport()72     bool mipmapSupport() const { return fMipmapSupport; }
73     /** Is anisotropic filtering supported. */
anisoSupport()74     bool anisoSupport() const { return fAnisoSupport; }
75 
gpuTracingSupport()76     bool gpuTracingSupport() const { return fGpuTracingSupport; }
oversizedStencilSupport()77     bool oversizedStencilSupport() const { return fOversizedStencilSupport; }
textureBarrierSupport()78     bool textureBarrierSupport() const { return fTextureBarrierSupport; }
sampleLocationsSupport()79     bool sampleLocationsSupport() const { return fSampleLocationsSupport; }
drawInstancedSupport()80     bool drawInstancedSupport() const { return fDrawInstancedSupport; }
81     // Is there hardware support for indirect draws? (Ganesh always supports indirect draws as long
82     // as it can polyfill them with instanced calls, but this cap tells us if they are supported
83     // natively.)
nativeDrawIndirectSupport()84     bool nativeDrawIndirectSupport() const { return fNativeDrawIndirectSupport; }
useClientSideIndirectBuffers()85     bool useClientSideIndirectBuffers() const {
86 #ifdef SK_DEBUG
87         if (!fNativeDrawIndirectSupport || fNativeDrawIndexedIndirectIsBroken) {
88             // We might implement indirect draws with a polyfill, so the commands need to reside in
89             // CPU memory.
90             SkASSERT(fUseClientSideIndirectBuffers);
91         }
92 #endif
93         return fUseClientSideIndirectBuffers;
94     }
conservativeRasterSupport()95     bool conservativeRasterSupport() const { return fConservativeRasterSupport; }
wireframeSupport()96     bool wireframeSupport() const { return fWireframeSupport; }
97     // This flag indicates that we never have to resolve MSAA. In practice, it means that we have
98     // an MSAA-render-to-texture extension: Any render target we create internally will use the
99     // extension, and any wrapped render target is the client's responsibility.
msaaResolvesAutomatically()100     bool msaaResolvesAutomatically() const { return fMSAAResolvesAutomatically; }
101     // If true then when doing MSAA draws, we will prefer to discard the msaa attachment on load
102     // and stores. The use of this feature for specific draws depends on the render target having a
103     // resolve attachment, and if we need to load previous data the resolve attachment must be
104     // usable as an input attachment/texture. Otherwise we will just write out and store the msaa
105     // attachment like normal.
106     // This flag is similar to enabling gl render to texture for msaa rendering.
preferDiscardableMSAAAttachment()107     bool preferDiscardableMSAAAttachment() const { return fPreferDiscardableMSAAAttachment; }
halfFloatVertexAttributeSupport()108     bool halfFloatVertexAttributeSupport() const { return fHalfFloatVertexAttributeSupport; }
109 
110     // Primitive restart functionality is core in ES 3.0, but using it will cause slowdowns on some
111     // systems. This cap is only set if primitive restart will improve performance.
usePrimitiveRestart()112     bool usePrimitiveRestart() const { return fUsePrimitiveRestart; }
113 
preferClientSideDynamicBuffers()114     bool preferClientSideDynamicBuffers() const { return fPreferClientSideDynamicBuffers; }
115 
116     // On tilers, an initial fullscreen clear is an OPTIMIZATION. It allows the hardware to
117     // initialize each tile with a constant value rather than loading each pixel from memory.
preferFullscreenClears()118     bool preferFullscreenClears() const { return fPreferFullscreenClears; }
119 
120     // Should we discard stencil values after a render pass? (Tilers get better performance if we
121     // always load stencil buffers with a "clear" op, and then discard the content when finished.)
discardStencilValuesAfterRenderPass()122     bool discardStencilValuesAfterRenderPass() const {
123         // b/160958008
124         return false;
125 #if 0
126         // This method is actually just a duplicate of preferFullscreenClears(), with a descriptive
127         // name for the sake of readability.
128         return this->preferFullscreenClears();
129 #endif
130     }
131 
132     // D3D does not allow the refs or masks to differ on a two-sided stencil draw.
twoSidedStencilRefsAndMasksMustMatch()133     bool twoSidedStencilRefsAndMasksMustMatch() const {
134         return fTwoSidedStencilRefsAndMasksMustMatch;
135     }
136 
preferVRAMUseOverFlushes()137     bool preferVRAMUseOverFlushes() const { return fPreferVRAMUseOverFlushes; }
138 
avoidStencilBuffers()139     bool avoidStencilBuffers() const { return fAvoidStencilBuffers; }
140 
avoidWritePixelsFastPath()141     bool avoidWritePixelsFastPath() const { return fAvoidWritePixelsFastPath; }
142 
143     // glDrawElementsIndirect fails GrMeshTest on every Win10 Intel bot.
nativeDrawIndexedIndirectIsBroken()144     bool nativeDrawIndexedIndirectIsBroken() const { return fNativeDrawIndexedIndirectIsBroken; }
145 
146     /**
147      * Indicates the capabilities of the fixed function blend unit.
148      */
149     enum BlendEquationSupport {
150         kBasic_BlendEquationSupport,             //<! Support to select the operator that
151                                                  //   combines src and dst terms.
152         kAdvanced_BlendEquationSupport,          //<! Additional fixed function support for specific
153                                                  //   SVG/PDF blend modes. Requires blend barriers.
154         kAdvancedCoherent_BlendEquationSupport,  //<! Advanced blend equation support that does not
155                                                  //   require blend barriers, and permits overlap.
156 
157         kLast_BlendEquationSupport = kAdvancedCoherent_BlendEquationSupport
158     };
159 
blendEquationSupport()160     BlendEquationSupport blendEquationSupport() const { return fBlendEquationSupport; }
161 
advancedBlendEquationSupport()162     bool advancedBlendEquationSupport() const {
163         return fBlendEquationSupport >= kAdvanced_BlendEquationSupport;
164     }
165 
advancedCoherentBlendEquationSupport()166     bool advancedCoherentBlendEquationSupport() const {
167         return kAdvancedCoherent_BlendEquationSupport == fBlendEquationSupport;
168     }
169 
isAdvancedBlendEquationDisabled(skgpu::BlendEquation equation)170     bool isAdvancedBlendEquationDisabled(skgpu::BlendEquation equation) const {
171         SkASSERT(skgpu::BlendEquationIsAdvanced(equation));
172         SkASSERT(this->advancedBlendEquationSupport());
173         return SkToBool(fAdvBlendEqDisableFlags & (1 << static_cast<int>(equation)));
174     }
175 
176     // On some GPUs it is a performance win to disable blending instead of doing src-over with a src
177     // alpha equal to 1. To disable blending we collapse src-over to src and the backends will
178     // handle the disabling of blending.
shouldCollapseSrcOverToSrcWhenAble()179     bool shouldCollapseSrcOverToSrcWhenAble() const {
180         return fShouldCollapseSrcOverToSrcWhenAble;
181     }
182 
183     // When abandoning the GrDirectContext do we need to sync the GPU before we start abandoning
184     // resources.
mustSyncGpuDuringAbandon()185     bool mustSyncGpuDuringAbandon() const {
186         return fMustSyncGpuDuringAbandon;
187     }
188 
189     // Shortcut for shaderCaps()->fReducedShaderMode.
reducedShaderMode()190     bool reducedShaderMode() const { return this->shaderCaps()->fReducedShaderMode; }
191 
192     /**
193      * Indicates whether GPU->CPU memory mapping for GPU resources such as vertex buffers and
194      * textures allows partial mappings or full mappings.
195      */
196     enum MapFlags {
197         kNone_MapFlags      = 0x0,   //<! Cannot map the resource.
198 
199         kCanMap_MapFlag     = 0x1,   //<! The resource can be mapped. Must be set for any of
200                                      //   the other flags to have meaning.
201         kSubset_MapFlag     = 0x2,   //<! The resource can be partially mapped.
202         kAsyncRead_MapFlag  = 0x4,   //<! Are maps for reading asynchronous WRT GrOpsRenderPass
203                                      //   submitted to GrGpu.
204     };
205 
206     // This returns the general mapping support for the GPU. However, even if this returns a flag
207     // that says buffers can be mapped, it does NOT mean that every buffer will be mappable. Thus
208     // calls of map should still check to see if a valid pointer was returned from the map call and
209     // handle fallbacks appropriately. If this does return kNone_MapFlags then all calls to map() on
210     // any buffer will fail.
mapBufferFlags()211     uint32_t mapBufferFlags() const { return fMapBufferFlags; }
212 
213     // Scratch textures not being reused means that those scratch textures
214     // that we upload to (i.e., don't have a render target) will not be
215     // recycled in the texture cache. This is to prevent ghosting by drivers
216     // (in particular for deferred architectures).
reuseScratchTextures()217     bool reuseScratchTextures() const { return fReuseScratchTextures; }
reuseScratchBuffers()218     bool reuseScratchBuffers() const { return fReuseScratchBuffers; }
219 
220     /// maximum number of attribute values per vertex
maxVertexAttributes()221     int maxVertexAttributes() const { return fMaxVertexAttributes; }
222 
maxRenderTargetSize()223     int maxRenderTargetSize() const { return fMaxRenderTargetSize; }
224 
225     /** This is the largest render target size that can be used without incurring extra perfomance
226         cost. It is usually the max RT size, unless larger render targets are known to be slower. */
maxPreferredRenderTargetSize()227     int maxPreferredRenderTargetSize() const { return fMaxPreferredRenderTargetSize; }
228 
maxTextureSize()229     int maxTextureSize() const { return fMaxTextureSize; }
230 
maxWindowRectangles()231     int maxWindowRectangles() const { return fMaxWindowRectangles; }
232 
233     // Returns whether window rectangles are supported for the given backend render target.
isWindowRectanglesSupportedForRT(const GrBackendRenderTarget & rt)234     bool isWindowRectanglesSupportedForRT(const GrBackendRenderTarget& rt) const {
235         return this->maxWindowRectangles() > 0 && this->onIsWindowRectanglesSupportedForRT(rt);
236     }
237 
maxPushConstantsSize()238     uint32_t maxPushConstantsSize() const { return fMaxPushConstantsSize; }
239 
240     // Alignment requirement for row bytes in buffer<->texture transfers.
transferBufferRowBytesAlignment()241     size_t transferBufferRowBytesAlignment() const { return fTransferBufferRowBytesAlignment; }
242 
243     // Alignment requirement for offsets and size in buffer->buffer transfers.
transferFromBufferToBufferAlignment()244     size_t transferFromBufferToBufferAlignment() const {
245         return fTransferFromBufferToBufferAlignment;
246     }
247 
248     // Alignment requirement for offset and size passed to in GrGpuBuffer::updateData when the
249     // preserve param is true.
bufferUpdateDataPreserveAlignment()250     size_t bufferUpdateDataPreserveAlignment() const {
251         return fBufferUpdateDataPreserveAlignment;
252     }
253 
254     virtual bool isFormatSRGB(const GrBackendFormat&) const = 0;
255 
256     bool isFormatCompressed(const GrBackendFormat& format) const;
257 
258     // Can a texture be made with the GrBackendFormat and texture type, and then be bound and
259     // sampled in a shader.
260     virtual bool isFormatTexturable(const GrBackendFormat&, GrTextureType) const = 0;
261 
262     // Returns whether a texture of the given format can be copied to a texture of the same format.
263     virtual bool isFormatCopyable(const GrBackendFormat&) const = 0;
264 
265     // Returns the maximum supported sample count for a format. 0 means the format is not renderable
266     // 1 means the format is renderable but doesn't support MSAA.
267     virtual int maxRenderTargetSampleCount(const GrBackendFormat&) const = 0;
268 
269     // Returns the number of samples to use when performing draws to the given config with internal
270     // MSAA. If 0, Ganesh should not attempt to use internal multisampling.
internalMultisampleCount(const GrBackendFormat & format)271     int internalMultisampleCount(const GrBackendFormat& format) const {
272         return std::min(fInternalMultisampleCount, this->maxRenderTargetSampleCount(format));
273     }
274 
275     virtual bool isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format,
276                                                int sampleCount = 1) const = 0;
277 
278     virtual bool isFormatRenderable(const GrBackendFormat& format, int sampleCount) const = 0;
279 
280     // Find a sample count greater than or equal to the requested count which is supported for a
281     // render target of the given format or 0 if no such sample count is supported. If the requested
282     // sample count is 1 then 1 will be returned if non-MSAA rendering is supported, otherwise 0.
283     // For historical reasons requestedCount==0 is handled identically to requestedCount==1.
284     virtual int getRenderTargetSampleCount(int requestedCount, const GrBackendFormat&) const = 0;
285 
286     /**
287      * Backends may have restrictions on what types of surfaces support GrGpu::writePixels().
288      * If this returns false then the caller should implement a fallback where a temporary texture
289      * is created, pixels are written to it, and then that is copied or drawn into the the surface.
290      */
291     bool surfaceSupportsWritePixels(const GrSurface*) const;
292 
293     /**
294      * Indicates whether surface supports GrGpu::readPixels, must be copied, or cannot be read.
295      */
296     enum class SurfaceReadPixelsSupport {
297         /** GrGpu::readPixels is supported by the surface. */
298         kSupported,
299         /**
300          * GrGpu::readPixels is not supported by this surface but this surface can be drawn
301          * or copied to a Ganesh-created GrTextureType::kTexture2D and then that surface will be
302          * readable.
303          */
304         kCopyToTexture2D,
305         /**
306          * Not supported
307          */
308         kUnsupported,
309     };
310     /**
311      * Backends may have restrictions on what types of surfaces support GrGpu::readPixels(). We may
312      * either be able to read directly from the surface, read from a copy of the surface, or not
313      * read at all.
314      */
315     virtual SurfaceReadPixelsSupport surfaceSupportsReadPixels(const GrSurface*) const = 0;
316 
317     struct SupportedWrite {
318         GrColorType fColorType;
319         // If the write is occurring using GrGpu::transferPixelsTo then this provides the
320         // minimum alignment of the offset into the transfer buffer.
321         size_t fOffsetAlignmentForTransferBuffer;
322     };
323 
324     /**
325      * Given a dst pixel config and a src color type what color type must the caller coax the
326      * the data into in order to use GrGpu::writePixels().
327      */
328     virtual SupportedWrite supportedWritePixelsColorType(GrColorType surfaceColorType,
329                                                          const GrBackendFormat& surfaceFormat,
330                                                          GrColorType srcColorType) const = 0;
331 
332     struct SupportedRead {
333         GrColorType fColorType;
334         // If the read is occurring using GrGpu::transferPixelsFrom then this provides the
335         // minimum alignment of the offset into the transfer buffer.
336         size_t fOffsetAlignmentForTransferBuffer;
337     };
338 
339     /**
340      * Given a src surface's color type and its backend format as well as a color type the caller
341      * would like read into, this provides a legal color type that the caller may pass to
342      * GrGpu::readPixels(). The returned color type may differ from the passed dstColorType, in
343      * which case the caller must convert the read pixel data (see GrConvertPixels). When converting
344      * to dstColorType the swizzle in the returned struct should be applied. The caller must check
345      * the returned color type for kUnknown.
346      */
347     SupportedRead supportedReadPixelsColorType(GrColorType srcColorType,
348                                                const GrBackendFormat& srcFormat,
349                                                GrColorType dstColorType) const;
350 
351     /**
352      * Does GrGpu::writePixels() support a src buffer where the row bytes is not equal to bpp * w?
353      */
writePixelsRowBytesSupport()354     bool writePixelsRowBytesSupport() const { return fWritePixelsRowBytesSupport; }
355 
356     /**
357      * Does GrGpu::transferPixelsTo() support a src buffer where the row bytes is not equal to
358      * bpp * w?
359      */
transferPixelsToRowBytesSupport()360     bool transferPixelsToRowBytesSupport() const { return fTransferPixelsToRowBytesSupport; }
361 
362     /**
363      * Does GrGpu::readPixels() support a dst buffer where the row bytes is not equal to bpp * w?
364      */
readPixelsRowBytesSupport()365     bool readPixelsRowBytesSupport() const { return fReadPixelsRowBytesSupport; }
366 
transferFromSurfaceToBufferSupport()367     bool transferFromSurfaceToBufferSupport() const { return fTransferFromSurfaceToBufferSupport; }
transferFromBufferToTextureSupport()368     bool transferFromBufferToTextureSupport() const { return fTransferFromBufferToTextureSupport; }
transferFromBufferToBufferSupport()369     bool transferFromBufferToBufferSupport()  const { return fTransferFromBufferToBufferSupport;  }
370 
suppressPrints()371     bool suppressPrints() const { return fSuppressPrints; }
372 
bufferMapThreshold()373     size_t bufferMapThreshold() const {
374         SkASSERT(fBufferMapThreshold >= 0);
375         return static_cast<size_t>(fBufferMapThreshold);
376     }
377 
378     /** True in environments that will issue errors if memory uploaded to buffers
379         is not initialized (even if not read by draw calls). */
mustClearUploadedBufferData()380     bool mustClearUploadedBufferData() const { return fMustClearUploadedBufferData; }
381 
382     /** For some environments, there is a performance or safety concern to not
383         initializing textures. For example, with WebGL and Firefox, there is a large
384         performance hit to not doing it.
385      */
shouldInitializeTextures()386     bool shouldInitializeTextures() const { return fShouldInitializeTextures; }
387 
388     /**
389      * When a new GrGpuBuffer is created is it known to contain all zero bytes?
390      */
buffersAreInitiallyZero()391     bool buffersAreInitiallyZero() const { return fBuffersAreInitiallyZero; }
392 
393     /** Returns true if the given backend supports importing AHardwareBuffers via the
394      * GrAHardwarebufferImageGenerator. This will only ever be supported on Android devices with API
395      * level >= 26.
396      * */
supportsAHardwareBufferImages()397     bool supportsAHardwareBufferImages() const { return fSupportsAHardwareBufferImages; }
398 
wireframeMode()399     bool wireframeMode() const { return fWireframeMode; }
400 
401     /** Supports using GrSemaphores. */
semaphoreSupport()402     bool semaphoreSupport() const { return fSemaphoreSupport; }
403 
404     /** Supports using GrBackendSemaphore as "signal" semaphores or for waiting. See also
405      *  GrFlushInfo and GrDirectContext. */
backendSemaphoreSupport()406     bool backendSemaphoreSupport() const { return fBackendSemaphoreSupport; }
407 
408     /** Supports async callback for finishedProcs */
finishedProcAsyncCallbackSupport()409     bool finishedProcAsyncCallbackSupport() const { return fFinishedProcAsyncCallbackSupport; }
410 
crossContextTextureSupport()411     bool crossContextTextureSupport() const { return fCrossContextTextureSupport; }
412     /**
413      * Returns whether or not we will be able to do a copy given the passed in params
414      */
415     bool canCopySurface(const GrSurfaceProxy* dst, const SkIRect& dstRect,
416                         const GrSurfaceProxy* src, const SkIRect& srcRect) const;
417 
dynamicStateArrayGeometryProcessorTextureSupport()418     bool dynamicStateArrayGeometryProcessorTextureSupport() const {
419         return fDynamicStateArrayGeometryProcessorTextureSupport;
420     }
421 
supportsProtectedContent()422     bool supportsProtectedContent() const { return fSupportsProtectedContent; }
423 
424     // Not all backends support clearing with a scissor test (e.g. Metal), this will always
425     // return true if performColorClearsAsDraws() returns true.
performPartialClearsAsDraws()426     bool performPartialClearsAsDraws() const {
427         return fPerformColorClearsAsDraws || fPerformPartialClearsAsDraws;
428     }
429 
430     // Many drivers have issues with color clears.
performColorClearsAsDraws()431     bool performColorClearsAsDraws() const { return fPerformColorClearsAsDraws; }
432 
avoidLargeIndexBufferDraws()433     bool avoidLargeIndexBufferDraws() const { return fAvoidLargeIndexBufferDraws; }
434 
435     /// Adreno 4xx devices experience an issue when there are a large number of stencil clip bit
436     /// clears. The minimal repro steps are not precisely known but drawing a rect with a stencil
437     /// op instead of using glClear seems to resolve the issue.
performStencilClearsAsDraws()438     bool performStencilClearsAsDraws() const { return fPerformStencilClearsAsDraws; }
439 
440     // Should we disable TessellationPathRenderer due to a faulty driver?
disableTessellationPathRenderer()441     bool disableTessellationPathRenderer() const { return fDisableTessellationPathRenderer; }
442 
443     // Returns how to sample the dst values for the passed in GrRenderTargetProxy.
444     GrDstSampleFlags getDstSampleFlagsForProxy(const GrRenderTargetProxy*, bool drawUsesMSAA) const;
445 
446     /**
447      * This is used to try to ensure a successful copy a dst in order to perform shader-based
448      * blending.
449      *
450      * fRectsMustMatch will be set to true if the copy operation must ensure that the src and dest
451      * rects are identical.
452      *
453      * fMustCopyWholeSrc will be set to true if copy rect must equal src's bounds.
454      *
455      * Caller will detect cases when copy cannot succeed and try copy-as-draw as a fallback.
456      */
457     struct DstCopyRestrictions {
458         GrSurfaceProxy::RectsMustMatch fRectsMustMatch = GrSurfaceProxy::RectsMustMatch::kNo;
459         bool fMustCopyWholeSrc = false;
460     };
getDstCopyRestrictions(const GrRenderTargetProxy * src,GrColorType ct)461     virtual DstCopyRestrictions getDstCopyRestrictions(const GrRenderTargetProxy* src,
462                                                        GrColorType ct) const {
463         return {};
464     }
465 
466     bool validateSurfaceParams(const SkISize&,
467                                const GrBackendFormat&,
468                                GrRenderable renderable,
469                                int renderTargetSampleCnt,
470                                skgpu::Mipmapped,
471                                GrTextureType) const;
472 
473     bool areColorTypeAndFormatCompatible(GrColorType grCT, const GrBackendFormat& format) const;
474 
475     /** These are used when creating a new texture internally. */
476     GrBackendFormat getDefaultBackendFormat(GrColorType, GrRenderable) const;
477 
478     virtual GrBackendFormat getBackendFormatFromCompressionType(SkTextureCompressionType) const = 0;
479 
480     /**
481      * The CLAMP_TO_BORDER wrap mode for texture coordinates was added to desktop GL in 1.3, and
482      * GLES 3.2, but is also available in extensions. Vulkan and Metal always have support.
483      */
clampToBorderSupport()484     bool clampToBorderSupport() const { return fClampToBorderSupport; }
485 
486     /**
487      * Returns the skgpu::Swizzle to use when sampling or reading back from a texture with the
488      * passed in GrBackendFormat and GrColorType.
489      */
490     skgpu::Swizzle getReadSwizzle(const GrBackendFormat& format, GrColorType colorType) const;
491 
492     /**
493      * Returns the skgpu::Swizzle to use when writing colors to a surface with the passed in
494      * GrBackendFormat and GrColorType.
495      */
496     virtual skgpu::Swizzle getWriteSwizzle(const GrBackendFormat&, GrColorType) const = 0;
497 
498     virtual uint64_t computeFormatKey(const GrBackendFormat&) const = 0;
499 
workarounds()500     const GrDriverBugWorkarounds& workarounds() const { return fDriverBugWorkarounds; }
501 
502     /**
503      * Adds fields to the key to represent the sampler that will be created for the passed
504      * in parameters. Currently this extra keying is only needed when building a vulkan pipeline
505      * with immutable samplers.
506      */
addExtraSamplerKey(skgpu::KeyBuilder *,GrSamplerState,const GrBackendFormat &)507     virtual void addExtraSamplerKey(skgpu::KeyBuilder*,
508                                     GrSamplerState,
509                                     const GrBackendFormat&) const {}
510 
511     enum class ProgramDescOverrideFlags {
512         kNone = 0,
513         // If using discardable msaa surfaces in vulkan, when we break up a render pass for an
514         // inline upload, we must do a load msaa subpass for the second render pass. However, if the
515         // original render pass did not have this load subpass (e.g. clear or discard load op), then
516         // all the GrProgramInfos for draws that end up in the second render pass will have been
517         // recorded thinking they will be in a render pass with only 1 subpass. Thus we add an
518         // override flag to the makeDesc call to force the actually VkPipeline that gets created to
519         // be created using a render pass with 2 subpasses. We do miss on the pre-compile with this
520         // approach, but inline uploads are very rare and already slow.
521         kVulkanHasResolveLoadSubpass = 0x1,
522     };
523     GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(ProgramDescOverrideFlags);
524 
525 
526     virtual GrProgramDesc makeDesc(
527             GrRenderTarget*, const GrProgramInfo&,
528             ProgramDescOverrideFlags overrideFlags = ProgramDescOverrideFlags::kNone) const = 0;
529 
530     // This method specifies, for each backend, the extra properties of a RT when Ganesh creates one
531     // internally. For example, for Vulkan, Ganesh always creates RTs that can be used as input
532     // attachments.
getExtraSurfaceFlagsForDeferredRT()533     virtual GrInternalSurfaceFlags getExtraSurfaceFlagsForDeferredRT() const {
534         return GrInternalSurfaceFlags::kNone;
535     }
536 
537     bool supportsDynamicMSAA(const GrRenderTargetProxy*) const;
538 
dmsaaResolveCanBeUsedAsTextureInSameRenderPass()539     virtual bool dmsaaResolveCanBeUsedAsTextureInSameRenderPass() const { return true; }
540 
541     // skbug.com/11935. Task reordering is disabled for some GPUs on GL due to driver bugs.
avoidReorderingRenderTasks()542     bool avoidReorderingRenderTasks() const {
543         return fAvoidReorderingRenderTasks;
544     }
545 
avoidDithering()546     bool avoidDithering() const {
547         return fAvoidDithering;
548     }
549 
disablePerspectiveSDFText()550     bool disablePerspectiveSDFText() const {
551         return fDisablePerspectiveSDFText;
552     }
553 
554     // anglebug.com/7796
avoidLineDraws()555     bool avoidLineDraws() const { return fAvoidLineDraws; }
556 
557     /**
558      * Checks whether the passed color type is renderable. If so, the same color type is passed
559      * back along with the default format used for the color type. If not, provides an alternative
560      * (perhaps lower bit depth and/or unorm instead of float) color type that is supported
561      * along with it's default format or kUnknown if there no renderable fallback format.
562      */
563     std::tuple<GrColorType, GrBackendFormat> getFallbackColorTypeAndFormat(GrColorType,
564                                                                            int sampleCount) const;
565 
566 #if defined(GR_TEST_UTILS)
567     virtual std::vector<GrTest::TestFormatColorTypeCombination> getTestingCombinations() const = 0;
568 #endif
569 
570 protected:
571     // Subclasses must call this at the end of their init method in order to do final processing on
572     // the caps (including overrides requested by the client).
573     // NOTE: this method will only reduce the caps, never expand them.
574     void finishInitialization(const GrContextOptions& options);
575 
576 #if defined(GR_TEST_UTILS)
setDeviceName(const char * n)577     void setDeviceName(const char* n) {
578         fDeviceName = n;
579     }
580 #endif
581 
onSupportsDynamicMSAA(const GrRenderTargetProxy *)582     virtual bool onSupportsDynamicMSAA(const GrRenderTargetProxy*) const { return false; }
583 
584     std::unique_ptr<GrShaderCaps> fShaderCaps;
585 
586     bool fNPOTTextureTileSupport                     : 1;
587     bool fMipmapSupport                              : 1;
588     bool fAnisoSupport                               : 1;
589     bool fReuseScratchTextures                       : 1;
590     bool fReuseScratchBuffers                        : 1;
591     bool fGpuTracingSupport                          : 1;
592     bool fOversizedStencilSupport                    : 1;
593     bool fTextureBarrierSupport                      : 1;
594     bool fSampleLocationsSupport                     : 1;
595     bool fDrawInstancedSupport                       : 1;
596     bool fNativeDrawIndirectSupport                  : 1;
597     bool fUseClientSideIndirectBuffers               : 1;
598     bool fConservativeRasterSupport                  : 1;
599     bool fWireframeSupport                           : 1;
600     bool fMSAAResolvesAutomatically                  : 1;
601     bool fPreferDiscardableMSAAAttachment            : 1;
602     bool fUsePrimitiveRestart                        : 1;
603     bool fPreferClientSideDynamicBuffers             : 1;
604     bool fPreferFullscreenClears                     : 1;
605     bool fTwoSidedStencilRefsAndMasksMustMatch       : 1;
606     bool fMustClearUploadedBufferData                : 1;
607     bool fBuffersAreInitiallyZero                    : 1;
608     bool fShouldInitializeTextures                   : 1;
609     bool fSupportsAHardwareBufferImages              : 1;
610     bool fHalfFloatVertexAttributeSupport            : 1;
611     bool fClampToBorderSupport                       : 1;
612     bool fPerformPartialClearsAsDraws                : 1;
613     bool fPerformColorClearsAsDraws                  : 1;
614     bool fAvoidLargeIndexBufferDraws                 : 1;
615     bool fPerformStencilClearsAsDraws                : 1;
616     bool fTransferFromBufferToTextureSupport         : 1;
617     bool fTransferFromSurfaceToBufferSupport         : 1;
618     bool fTransferFromBufferToBufferSupport          : 1;
619     bool fWritePixelsRowBytesSupport                 : 1;
620     bool fTransferPixelsToRowBytesSupport            : 1;
621     bool fReadPixelsRowBytesSupport                  : 1;
622     bool fShouldCollapseSrcOverToSrcWhenAble         : 1;
623     bool fMustSyncGpuDuringAbandon                   : 1;
624 
625     // Driver workaround
626     bool fDisableTessellationPathRenderer            : 1;
627     bool fAvoidStencilBuffers                        : 1;
628     bool fAvoidWritePixelsFastPath                   : 1;
629     bool fNativeDrawIndexedIndirectIsBroken          : 1;
630     bool fAvoidReorderingRenderTasks                 : 1;
631     bool fAvoidDithering                             : 1;
632     bool fDisablePerspectiveSDFText                  : 1;
633     bool fAvoidLineDraws                             : 1;
634 
635     // ANGLE performance workaround
636     bool fPreferVRAMUseOverFlushes                   : 1;
637 
638     bool fSemaphoreSupport                           : 1;
639     bool fBackendSemaphoreSupport                    : 1;
640     bool fFinishedProcAsyncCallbackSupport           : 1;
641 
642     // Requires fence sync support in GL.
643     bool fCrossContextTextureSupport                 : 1;
644 
645     // Not (yet) implemented in VK backend.
646     bool fDynamicStateArrayGeometryProcessorTextureSupport : 1;
647 
648     bool fSupportsProtectedContent                   : 1;
649 
650     BlendEquationSupport fBlendEquationSupport;
651     uint32_t fAdvBlendEqDisableFlags;
652     static_assert(static_cast<int>(skgpu::BlendEquation::kLast) < 32);
653 
654     uint32_t fMapBufferFlags;
655     int fBufferMapThreshold;
656 
657     int fMaxRenderTargetSize;
658     int fMaxPreferredRenderTargetSize;
659     int fMaxVertexAttributes;
660     int fMaxTextureSize;
661     int fMaxWindowRectangles;
662     int fInternalMultisampleCount;
663     uint32_t fMaxPushConstantsSize = 0;
664     size_t fTransferBufferRowBytesAlignment = 1;
665     size_t fTransferFromBufferToBufferAlignment = 1;
666     size_t fBufferUpdateDataPreserveAlignment = 1;
667 
668     GrDriverBugWorkarounds fDriverBugWorkarounds;
669 
670 #if defined(GR_TEST_UTILS)
671     std::string fDeviceName;
672 #endif
673 
674 private:
675     void applyOptionsOverrides(const GrContextOptions& options);
676 
onApplyOptionsOverrides(const GrContextOptions &)677     virtual void onApplyOptionsOverrides(const GrContextOptions&) {}
onDumpJSON(SkJSONWriter *)678     virtual void onDumpJSON(SkJSONWriter*) const {}
679     virtual bool onSurfaceSupportsWritePixels(const GrSurface*) const = 0;
680     virtual bool onCanCopySurface(const GrSurfaceProxy* dst, const SkIRect& dstRect,
681                                   const GrSurfaceProxy* src, const SkIRect& srcRect) const = 0;
682     virtual GrBackendFormat onGetDefaultBackendFormat(GrColorType) const = 0;
683 
684     // Backends should implement this if they have any extra requirements for use of window
685     // rectangles for a specific GrBackendRenderTarget outside of basic support.
onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget &)686     virtual bool onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget&) const {
687         return true;
688     }
689 
690     virtual bool onAreColorTypeAndFormatCompatible(GrColorType, const GrBackendFormat&) const = 0;
691 
692     virtual SupportedRead onSupportedReadPixelsColorType(GrColorType srcColorType,
693                                                          const GrBackendFormat& srcFormat,
694                                                          GrColorType dstColorType) const = 0;
695 
696     virtual skgpu::Swizzle onGetReadSwizzle(const GrBackendFormat&, GrColorType) const = 0;
697 
onGetDstSampleFlagsForProxy(const GrRenderTargetProxy *)698     virtual GrDstSampleFlags onGetDstSampleFlagsForProxy(const GrRenderTargetProxy*) const {
699         return GrDstSampleFlags::kNone;
700     }
701 
702     bool fSuppressPrints : 1;
703     bool fWireframeMode  : 1;
704 
705     using INHERITED = SkRefCnt;
706 };
707 
708 GR_MAKE_BITFIELD_CLASS_OPS(GrCaps::ProgramDescOverrideFlags)
709 
710 #endif
711