1 /*
2  * Copyright 2011 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 GrGpu_DEFINED
9 #define GrGpu_DEFINED
10 
11 #include "include/core/SkPath.h"
12 #include "include/core/SkSurface.h"
13 #include "include/gpu/GrTypes.h"
14 #include "include/private/SkTArray.h"
15 #include "src/core/SkSpan.h"
16 #include "src/core/SkTInternalLList.h"
17 #include "src/gpu/GrAttachment.h"
18 #include "src/gpu/GrCaps.h"
19 #include "src/gpu/GrOpsRenderPass.h"
20 #include "src/gpu/GrSamplePatternDictionary.h"
21 #include "src/gpu/GrSwizzle.h"
22 #include "src/gpu/GrTextureProducer.h"
23 #include "src/gpu/GrXferProcessor.h"
24 
25 class GrBackendRenderTarget;
26 class GrBackendSemaphore;
27 class GrDirectContext;
28 class GrGpuBuffer;
29 struct GrContextOptions;
30 class GrGLContext;
31 class GrPath;
32 class GrPathRenderer;
33 class GrPathRendererChain;
34 class GrPathRendering;
35 class GrPipeline;
36 class GrPrimitiveProcessor;
37 class GrRenderTarget;
38 class GrRingBuffer;
39 class GrSemaphore;
40 class GrStagingBufferManager;
41 class GrAttachment;
42 class GrStencilSettings;
43 class GrSurface;
44 class GrTexture;
45 class SkJSONWriter;
46 
47 class GrGpu : public SkRefCnt {
48 public:
49     GrGpu(GrDirectContext* direct);
50     ~GrGpu() override;
51 
getContext()52     GrDirectContext* getContext() { return fContext; }
getContext()53     const GrDirectContext* getContext() const { return fContext; }
54 
55     /**
56      * Gets the capabilities of the draw target.
57      */
caps()58     const GrCaps* caps() const { return fCaps.get(); }
refCaps()59     sk_sp<const GrCaps> refCaps() const { return fCaps; }
60 
pathRendering()61     GrPathRendering* pathRendering() { return fPathRendering.get();  }
62 
stagingBufferManager()63     virtual GrStagingBufferManager* stagingBufferManager() { return nullptr; }
64 
uniformsRingBuffer()65     virtual GrRingBuffer* uniformsRingBuffer() { return nullptr; }
66 
67     enum class DisconnectType {
68         // No cleanup should be attempted, immediately cease making backend API calls
69         kAbandon,
70         // Free allocated resources (not known by GrResourceCache) before returning and
71         // ensure no backend backend 3D API calls will be made after disconnect() returns.
72         kCleanup,
73     };
74 
75     // Called by context when the underlying backend context is already or will be destroyed
76     // before GrDirectContext.
77     virtual void disconnect(DisconnectType);
78 
79     // Called by GrDirectContext::isContextLost. Returns true if the backend Gpu object has gotten
80     // into an unrecoverable, lost state.
isDeviceLost()81     virtual bool isDeviceLost() const { return false; }
82 
83     /**
84      * The GrGpu object normally assumes that no outsider is setting state
85      * within the underlying 3D API's context/device/whatever. This call informs
86      * the GrGpu that the state was modified and it shouldn't make assumptions
87      * about the state.
88      */
89     void markContextDirty(uint32_t state = kAll_GrBackendState) { fResetBits |= state; }
90 
91     /**
92      * Creates a texture object. If renderable is kYes then the returned texture can
93      * be used as a render target by calling GrTexture::asRenderTarget(). Not all
94      * pixel configs can be used as render targets. Support for configs as textures
95      * or render targets can be checked using GrCaps.
96      *
97      * @param dimensions     dimensions of the texture to be created.
98      * @param format         the format for the texture (not currently used).
99      * @param renderable     should the resulting texture be renderable
100      * @param renderTargetSampleCnt The number of samples to use for rendering if renderable is
101      *                       kYes. If renderable is kNo then this must be 1.
102      * @param budgeted       does this texture count against the resource cache budget?
103      * @param isProtected    should the texture be created as protected.
104      * @param texels         array of mipmap levels containing texel data to load.
105      *                       If level i has pixels then it is assumed that its dimensions are
106      *                       max(1, floor(dimensions.fWidth / 2)) by
107      *                       max(1, floor(dimensions.fHeight / 2)).
108      *                       If texels[i].fPixels == nullptr for all i <= mipLevelCount or
109      *                       mipLevelCount is 0 then the texture's contents are uninitialized.
110      *                       If a level has non-null pixels, its row bytes must be a multiple of the
111      *                       config's bytes-per-pixel. The row bytes must be tight to the
112      *                       level width if !caps->writePixelsRowBytesSupport().
113      *                       If mipLevelCount > 1 and texels[i].fPixels != nullptr for any i > 0
114      *                       then all levels must have non-null pixels. All levels must have
115      *                       non-null pixels if GrCaps::createTextureMustSpecifyAllLevels() is true.
116      * @param textureColorType The color type interpretation of the texture for the purpose of
117      *                       of uploading texel data.
118      * @param srcColorType   The color type of data in texels[].
119      * @param texelLevelCount the number of levels in 'texels'. May be 0, 1, or
120      *                       floor(max((log2(dimensions.fWidth), log2(dimensions.fHeight)))). It
121      *                       must be the latter if GrCaps::createTextureMustSpecifyAllLevels() is
122      *                       true.
123      * @return  The texture object if successful, otherwise nullptr.
124      */
125     sk_sp<GrTexture> createTexture(SkISize dimensions,
126                                    const GrBackendFormat& format,
127                                    GrRenderable renderable,
128                                    int renderTargetSampleCnt,
129                                    SkBudgeted budgeted,
130                                    GrProtected isProtected,
131                                    GrColorType textureColorType,
132                                    GrColorType srcColorType,
133                                    const GrMipLevel texels[],
134                                    int texelLevelCount);
135 
136     /**
137      * Simplified createTexture() interface for when there is no initial texel data to upload.
138      */
139     sk_sp<GrTexture> createTexture(SkISize dimensions,
140                                    const GrBackendFormat& format,
141                                    GrRenderable renderable,
142                                    int renderTargetSampleCnt,
143                                    GrMipmapped mipMapped,
144                                    SkBudgeted budgeted,
145                                    GrProtected isProtected);
146 
147     sk_sp<GrTexture> createCompressedTexture(SkISize dimensions,
148                                              const GrBackendFormat& format,
149                                              SkBudgeted budgeted,
150                                              GrMipmapped mipMapped,
151                                              GrProtected isProtected,
152                                              const void* data, size_t dataSize);
153 
154     /**
155      * Implements GrResourceProvider::wrapBackendTexture
156      */
157     sk_sp<GrTexture> wrapBackendTexture(const GrBackendTexture&,
158                                         GrWrapOwnership,
159                                         GrWrapCacheable,
160                                         GrIOType);
161 
162     sk_sp<GrTexture> wrapCompressedBackendTexture(const GrBackendTexture&,
163                                                   GrWrapOwnership,
164                                                   GrWrapCacheable);
165 
166     /**
167      * Implements GrResourceProvider::wrapRenderableBackendTexture
168      */
169     sk_sp<GrTexture> wrapRenderableBackendTexture(const GrBackendTexture&,
170                                                   int sampleCnt,
171                                                   GrWrapOwnership,
172                                                   GrWrapCacheable);
173 
174     /**
175      * Implements GrResourceProvider::wrapBackendRenderTarget
176      */
177     sk_sp<GrRenderTarget> wrapBackendRenderTarget(const GrBackendRenderTarget&);
178 
179     /**
180      * Implements GrResourceProvider::wrapVulkanSecondaryCBAsRenderTarget
181      */
182     sk_sp<GrRenderTarget> wrapVulkanSecondaryCBAsRenderTarget(const SkImageInfo&,
183                                                               const GrVkDrawableInfo&);
184 
185     /**
186      * Creates a buffer in GPU memory. For a client-side buffer use GrBuffer::CreateCPUBacked.
187      *
188      * @param size            size of buffer to create.
189      * @param intendedType    hint to the graphics subsystem about what the buffer will be used for.
190      * @param accessPattern   hint to the graphics subsystem about how the data will be accessed.
191      * @param data            optional data with which to initialize the buffer.
192      *
193      * @return the buffer if successful, otherwise nullptr.
194      */
195     sk_sp<GrGpuBuffer> createBuffer(size_t size, GrGpuBufferType intendedType,
196                                     GrAccessPattern accessPattern, const void* data = nullptr);
197 
198     /**
199      * Resolves MSAA. The resolveRect must already be in the native destination space.
200      */
201     void resolveRenderTarget(GrRenderTarget*, const SkIRect& resolveRect);
202 
203     /**
204      * Uses the base of the texture to recompute the contents of the other levels.
205      */
206     bool regenerateMipMapLevels(GrTexture*);
207 
208     /**
209      * If the backend API has stateful texture bindings, this resets them back to defaults.
210      */
211     void resetTextureBindings();
212 
213     /**
214      * Reads a rectangle of pixels from a render target. No sRGB/linear conversions are performed.
215      *
216      * @param surface           The surface to read from
217      * @param left              left edge of the rectangle to read (inclusive)
218      * @param top               top edge of the rectangle to read (inclusive)
219      * @param width             width of rectangle to read in pixels.
220      * @param height            height of rectangle to read in pixels.
221      * @param surfaceColorType  the color type for this use of the surface.
222      * @param dstColorType      the color type of the destination buffer.
223      * @param buffer            memory to read the rectangle into.
224      * @param rowBytes          the number of bytes between consecutive rows. Must be a multiple of
225      *                          dstColorType's bytes-per-pixel. Must be tight to width if
226      *                          !caps->readPixelsRowBytesSupport().
227      *
228      * @return true if the read succeeded, false if not. The read can fail
229      *              because of the surface doesn't support reading, the color type
230      *              is not allowed for the format of the surface or if the rectangle
231      *              read is not contained in the surface.
232      */
233     bool readPixels(GrSurface* surface, int left, int top, int width, int height,
234                     GrColorType surfaceColorType, GrColorType dstColorType, void* buffer,
235                     size_t rowBytes);
236 
237     /**
238      * Updates the pixels in a rectangle of a surface.  No sRGB/linear conversions are performed.
239      *
240      * @param surface            The surface to write to.
241      * @param left               left edge of the rectangle to write (inclusive)
242      * @param top                top edge of the rectangle to write (inclusive)
243      * @param width              width of rectangle to write in pixels.
244      * @param height             height of rectangle to write in pixels.
245      * @param surfaceColorType   the color type for this use of the surface.
246      * @param srcColorType       the color type of the source buffer.
247      * @param texels             array of mipmap levels containing texture data. Row bytes must be a
248      *                           multiple of srcColorType's bytes-per-pixel. Must be tight to level
249      *                           width if !caps->writePixelsRowBytesSupport().
250      * @param mipLevelCount      number of levels in 'texels'
251      * @param prepForTexSampling After doing write pixels should the surface be prepared for texture
252      *                           sampling. This is currently only used by Vulkan for inline uploads
253      *                           to set that layout back to sampled after doing the upload. Inline
254      *                           uploads currently can happen between draws in a single op so it is
255      *                           not trivial to break up the GrOpsTask into two tasks when we see
256      *                           an inline upload. However, once we are able to support doing that
257      *                           we can remove this parameter.
258      *
259      * @return true if the write succeeded, false if not. The read can fail
260      *              because of the surface doesn't support writing (e.g. read only),
261      *              the color type is not allowed for the format of the surface or
262      *              if the rectangle written is not contained in the surface.
263      */
264     bool writePixels(GrSurface* surface, int left, int top, int width, int height,
265                      GrColorType surfaceColorType, GrColorType srcColorType,
266                      const GrMipLevel texels[], int mipLevelCount, bool prepForTexSampling = false);
267 
268     /**
269      * Helper for the case of a single level.
270      */
271     bool writePixels(GrSurface* surface, int left, int top, int width, int height,
272                      GrColorType surfaceColorType, GrColorType srcColorType, const void* buffer,
273                      size_t rowBytes, bool prepForTexSampling = false) {
274         GrMipLevel mipLevel = {buffer, rowBytes};
275         return this->writePixels(surface, left, top, width, height, surfaceColorType, srcColorType,
276                                  &mipLevel, 1, prepForTexSampling);
277     }
278 
279     /**
280      * Updates the pixels in a rectangle of a texture using a buffer. If the texture is MIP mapped,
281      * the base level is written to.
282      *
283      * @param texture          The texture to write to.
284      * @param left             left edge of the rectangle to write (inclusive)
285      * @param top              top edge of the rectangle to write (inclusive)
286      * @param width            width of rectangle to write in pixels.
287      * @param height           height of rectangle to write in pixels.
288      * @param textureColorType the color type for this use of the surface.
289      * @param bufferColorType  the color type of the transfer buffer's pixel data
290      * @param transferBuffer   GrBuffer to read pixels from (type must be "kXferCpuToGpu")
291      * @param offset           offset from the start of the buffer
292      * @param rowBytes         number of bytes between consecutive rows in the buffer. Must be a
293      *                         multiple of bufferColorType's bytes-per-pixel. Must be tight to width
294      *                         if !caps->writePixelsRowBytesSupport().
295      */
296     bool transferPixelsTo(GrTexture* texture, int left, int top, int width, int height,
297                           GrColorType textureColorType, GrColorType bufferColorType,
298                           GrGpuBuffer* transferBuffer, size_t offset, size_t rowBytes);
299 
300     /**
301      * Reads the pixels from a rectangle of a surface into a buffer. Use
302      * GrCaps::SupportedRead::fOffsetAlignmentForTransferBuffer to determine the requirements for
303      * the buffer offset alignment. If the surface is a MIP mapped texture, the base level is read.
304      *
305      * If successful the row bytes in the buffer is always:
306      *   GrColorTypeBytesPerPixel(bufferColorType) * width
307      *
308      * Asserts that the caller has passed a properly aligned offset and that the buffer is
309      * large enough to hold the result
310      *
311      * @param surface          The surface to read from.
312      * @param left             left edge of the rectangle to read (inclusive)
313      * @param top              top edge of the rectangle to read (inclusive)
314      * @param width            width of rectangle to read in pixels.
315      * @param height           height of rectangle to read in pixels.
316      * @param surfaceColorType the color type for this use of the surface.
317      * @param bufferColorType  the color type of the transfer buffer's pixel data
318      * @param transferBuffer   GrBuffer to write pixels to (type must be "kXferGpuToCpu")
319      * @param offset           offset from the start of the buffer
320      */
321     bool transferPixelsFrom(GrSurface* surface, int left, int top, int width, int height,
322                             GrColorType surfaceColorType, GrColorType bufferColorType,
323                             GrGpuBuffer* transferBuffer, size_t offset);
324 
325     // Called to perform a surface to surface copy. Fallbacks to issuing a draw from the src to dst
326     // take place at higher levels and this function implement faster copy paths. The rect
327     // and point are pre-clipped. The src rect and implied dst rect are guaranteed to be within the
328     // src/dst bounds and non-empty. They must also be in their exact device space coords, including
329     // already being transformed for origin if need be. If canDiscardOutsideDstRect is set to true
330     // then we don't need to preserve any data on the dst surface outside of the copy.
331     bool copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
332                      const SkIPoint& dstPoint);
333 
334     // Queries the per-pixel HW sample locations for the given render target, and then finds or
335     // assigns a key that uniquely identifies the sample pattern. The actual sample locations can be
336     // retrieved with retrieveSampleLocations().
337     int findOrAssignSamplePatternKey(GrRenderTarget*);
338 
339     // Retrieves the per-pixel HW sample locations for the given sample pattern key, and, as a
340     // by-product, the actual number of samples in use. (This may differ from the number of samples
341     // requested by the render target.) Sample locations are returned as 0..1 offsets relative to
342     // the top-left corner of the pixel.
retrieveSampleLocations(int samplePatternKey)343     const SkTArray<SkPoint>& retrieveSampleLocations(int samplePatternKey) const {
344         return fSamplePatternDictionary.retrieveSampleLocations(samplePatternKey);
345     }
346 
347     // Returns a GrOpsRenderPass which GrOpsTasks send draw commands to instead of directly
348     // to the Gpu object. The 'bounds' rect is the content rect of the renderTarget.
349     // If a 'stencil' is provided it will be the one bound to 'renderTarget'. If one is not
350     // provided but 'renderTarget' has a stencil buffer then that is a signal that the
351     // render target's stencil buffer should be ignored.
352     GrOpsRenderPass* getOpsRenderPass(GrRenderTarget* renderTarget,
353                                       GrAttachment* stencil,
354                                       GrSurfaceOrigin,
355                                       const SkIRect& bounds,
356                                       const GrOpsRenderPass::LoadAndStoreInfo&,
357                                       const GrOpsRenderPass::StencilLoadAndStoreInfo&,
358                                       const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
359                                       GrXferBarrierFlags renderPassXferBarriers);
360 
361     // Called by GrDrawingManager when flushing.
362     // Provides a hook for post-flush actions (e.g. Vulkan command buffer submits). This will also
363     // insert any numSemaphore semaphores on the gpu and set the backendSemaphores to match the
364     // inserted semaphores.
365     void executeFlushInfo(SkSpan<GrSurfaceProxy*>,
366                           SkSurface::BackendSurfaceAccess access,
367                           const GrFlushInfo&,
368                           const GrBackendSurfaceMutableState* newState);
369 
370     bool submitToGpu(bool syncCpu);
371 
372     virtual void submit(GrOpsRenderPass*) = 0;
373 
374     virtual GrFence SK_WARN_UNUSED_RESULT insertFence() = 0;
375     virtual bool waitFence(GrFence) = 0;
376     virtual void deleteFence(GrFence) const = 0;
377 
378     virtual std::unique_ptr<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(
379             bool isOwned = true) = 0;
380     virtual std::unique_ptr<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
381             GrResourceProvider::SemaphoreWrapType wrapType, GrWrapOwnership ownership) = 0;
382     virtual void insertSemaphore(GrSemaphore* semaphore) = 0;
383     virtual void waitSemaphore(GrSemaphore* semaphore) = 0;
384 
385     virtual void addFinishedProc(GrGpuFinishedProc finishedProc,
386                                  GrGpuFinishedContext finishedContext) = 0;
387     virtual void checkFinishProcs() = 0;
388 
takeOwnershipOfBuffer(sk_sp<GrGpuBuffer>)389     virtual void takeOwnershipOfBuffer(sk_sp<GrGpuBuffer>) {}
390 
391     /**
392      * Checks if we detected an OOM from the underlying 3D API and if so returns true and resets
393      * the internal OOM state to false. Otherwise, returns false.
394      */
395     bool checkAndResetOOMed();
396 
397     /**
398      *  Put this texture in a safe and known state for use across multiple contexts. Depending on
399      *  the backend, this may return a GrSemaphore. If so, other contexts should wait on that
400      *  semaphore before using this texture.
401      */
402     virtual std::unique_ptr<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) = 0;
403 
404     ///////////////////////////////////////////////////////////////////////////
405     // Debugging and Stats
406 
407     class Stats {
408     public:
409         enum class ProgramCacheResult {
410             kHit,       // the program was found in the cache
411             kMiss,      // the program was not found in the cache (and was, thus, compiled)
412             kPartial,   // a precompiled version was found in the persistent cache
413 
414             kLast = kPartial
415         };
416 
417         static const int kNumProgramCacheResults = (int)ProgramCacheResult::kLast + 1;
418 
419 #if GR_GPU_STATS
420         Stats() = default;
421 
reset()422         void reset() { *this = {}; }
423 
renderTargetBinds()424         int renderTargetBinds() const { return fRenderTargetBinds; }
incRenderTargetBinds()425         void incRenderTargetBinds() { fRenderTargetBinds++; }
426 
shaderCompilations()427         int shaderCompilations() const { return fShaderCompilations; }
incShaderCompilations()428         void incShaderCompilations() { fShaderCompilations++; }
429 
textureCreates()430         int textureCreates() const { return fTextureCreates; }
incTextureCreates()431         void incTextureCreates() { fTextureCreates++; }
432 
textureUploads()433         int textureUploads() const { return fTextureUploads; }
incTextureUploads()434         void incTextureUploads() { fTextureUploads++; }
435 
transfersToTexture()436         int transfersToTexture() const { return fTransfersToTexture; }
incTransfersToTexture()437         void incTransfersToTexture() { fTransfersToTexture++; }
438 
transfersFromSurface()439         int transfersFromSurface() const { return fTransfersFromSurface; }
incTransfersFromSurface()440         void incTransfersFromSurface() { fTransfersFromSurface++; }
441 
stencilAttachmentCreates()442         int stencilAttachmentCreates() const { return fStencilAttachmentCreates; }
incStencilAttachmentCreates()443         void incStencilAttachmentCreates() { fStencilAttachmentCreates++; }
444 
msaaAttachmentCreates()445         int msaaAttachmentCreates() const { return fMSAAAttachmentCreates; }
incMSAAAttachmentCreates()446         void incMSAAAttachmentCreates() { fMSAAAttachmentCreates++; }
447 
numDraws()448         int numDraws() const { return fNumDraws; }
incNumDraws()449         void incNumDraws() { fNumDraws++; }
450 
numFailedDraws()451         int numFailedDraws() const { return fNumFailedDraws; }
incNumFailedDraws()452         void incNumFailedDraws() { ++fNumFailedDraws; }
453 
numSubmitToGpus()454         int numSubmitToGpus() const { return fNumSubmitToGpus; }
incNumSubmitToGpus()455         void incNumSubmitToGpus() { ++fNumSubmitToGpus; }
456 
numScratchTexturesReused()457         int numScratchTexturesReused() const { return fNumScratchTexturesReused; }
incNumScratchTexturesReused()458         void incNumScratchTexturesReused() { ++fNumScratchTexturesReused; }
459 
numScratchMSAAAttachmentsReused()460         int numScratchMSAAAttachmentsReused() const { return fNumScratchMSAAAttachmentsReused; }
incNumScratchMSAAAttachmentsReused()461         void incNumScratchMSAAAttachmentsReused() { ++fNumScratchMSAAAttachmentsReused; }
462 
numInlineCompilationFailures()463         int numInlineCompilationFailures() const { return fNumInlineCompilationFailures; }
incNumInlineCompilationFailures()464         void incNumInlineCompilationFailures() { ++fNumInlineCompilationFailures; }
465 
numInlineProgramCacheResult(ProgramCacheResult stat)466         int numInlineProgramCacheResult(ProgramCacheResult stat) const {
467             return fInlineProgramCacheStats[(int) stat];
468         }
incNumInlineProgramCacheResult(ProgramCacheResult stat)469         void incNumInlineProgramCacheResult(ProgramCacheResult stat) {
470             ++fInlineProgramCacheStats[(int) stat];
471         }
472 
numPreCompilationFailures()473         int numPreCompilationFailures() const { return fNumPreCompilationFailures; }
incNumPreCompilationFailures()474         void incNumPreCompilationFailures() { ++fNumPreCompilationFailures; }
475 
numPreProgramCacheResult(ProgramCacheResult stat)476         int numPreProgramCacheResult(ProgramCacheResult stat) const {
477             return fPreProgramCacheStats[(int) stat];
478         }
incNumPreProgramCacheResult(ProgramCacheResult stat)479         void incNumPreProgramCacheResult(ProgramCacheResult stat) {
480             ++fPreProgramCacheStats[(int) stat];
481         }
482 
numCompilationFailures()483         int numCompilationFailures() const { return fNumCompilationFailures; }
incNumCompilationFailures()484         void incNumCompilationFailures() { ++fNumCompilationFailures; }
485 
numPartialCompilationSuccesses()486         int numPartialCompilationSuccesses() const { return fNumPartialCompilationSuccesses; }
incNumPartialCompilationSuccesses()487         void incNumPartialCompilationSuccesses() { ++fNumPartialCompilationSuccesses; }
488 
numCompilationSuccesses()489         int numCompilationSuccesses() const { return fNumCompilationSuccesses; }
incNumCompilationSuccesses()490         void incNumCompilationSuccesses() { ++fNumCompilationSuccesses; }
491 
492 #if GR_TEST_UTILS
493         void dump(SkString*);
494         void dumpKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values);
495 #endif
496     private:
497         int fRenderTargetBinds = 0;
498         int fShaderCompilations = 0;
499         int fTextureCreates = 0;
500         int fTextureUploads = 0;
501         int fTransfersToTexture = 0;
502         int fTransfersFromSurface = 0;
503         int fStencilAttachmentCreates = 0;
504         int fMSAAAttachmentCreates = 0;
505         int fNumDraws = 0;
506         int fNumFailedDraws = 0;
507         int fNumSubmitToGpus = 0;
508         int fNumScratchTexturesReused = 0;
509         int fNumScratchMSAAAttachmentsReused = 0;
510 
511         int fNumInlineCompilationFailures = 0;
512         int fInlineProgramCacheStats[kNumProgramCacheResults] = { 0 };
513 
514         int fNumPreCompilationFailures = 0;
515         int fPreProgramCacheStats[kNumProgramCacheResults] = { 0 };
516 
517         int fNumCompilationFailures = 0;
518         int fNumPartialCompilationSuccesses = 0;
519         int fNumCompilationSuccesses = 0;
520 
521 #else
522 
523 #if GR_TEST_UTILS
dump(SkString *)524         void dump(SkString*) {}
dumpKeyValuePairs(SkTArray<SkString> *,SkTArray<double> *)525         void dumpKeyValuePairs(SkTArray<SkString>*, SkTArray<double>*) {}
526 #endif
incRenderTargetBinds()527         void incRenderTargetBinds() {}
incShaderCompilations()528         void incShaderCompilations() {}
incTextureCreates()529         void incTextureCreates() {}
incTextureUploads()530         void incTextureUploads() {}
incTransfersToTexture()531         void incTransfersToTexture() {}
incTransfersFromSurface()532         void incTransfersFromSurface() {}
incStencilAttachmentCreates()533         void incStencilAttachmentCreates() {}
incMSAAAttachmentCreates()534         void incMSAAAttachmentCreates() {}
incNumDraws()535         void incNumDraws() {}
incNumFailedDraws()536         void incNumFailedDraws() {}
incNumSubmitToGpus()537         void incNumSubmitToGpus() {}
incNumScratchTexturesReused()538         void incNumScratchTexturesReused() {}
incNumScratchMSAAAttachmentsReused()539         void incNumScratchMSAAAttachmentsReused() {}
incNumInlineCompilationFailures()540         void incNumInlineCompilationFailures() {}
incNumInlineProgramCacheResult(ProgramCacheResult stat)541         void incNumInlineProgramCacheResult(ProgramCacheResult stat) {}
incNumPreCompilationFailures()542         void incNumPreCompilationFailures() {}
incNumPreProgramCacheResult(ProgramCacheResult stat)543         void incNumPreProgramCacheResult(ProgramCacheResult stat) {}
incNumCompilationFailures()544         void incNumCompilationFailures() {}
incNumPartialCompilationSuccesses()545         void incNumPartialCompilationSuccesses() {}
incNumCompilationSuccesses()546         void incNumCompilationSuccesses() {}
547 #endif
548     };
549 
stats()550     Stats* stats() { return &fStats; }
551     void dumpJSON(SkJSONWriter*) const;
552 
553     /** Used to initialize a backend texture with either a constant color, pixmaps or
554      *  compressed data.
555      */
556     class BackendTextureData {
557     public:
558         enum class Type { kColor, kPixmaps, kCompressed };
559         BackendTextureData() = default;
BackendTextureData(const SkColor4f & color)560         BackendTextureData(const SkColor4f& color) : fType(Type::kColor), fColor(color) {}
BackendTextureData(const SkPixmap pixmaps[])561         BackendTextureData(const SkPixmap pixmaps[]) : fType(Type::kPixmaps), fPixmaps(pixmaps) {
562             SkASSERT(pixmaps);
563         }
BackendTextureData(const void * data,size_t size)564         BackendTextureData(const void* data, size_t size) : fType(Type::kCompressed) {
565             SkASSERT(data);
566             fCompressed.fData = data;
567             fCompressed.fSize = size;
568         }
569 
type()570         Type type() const { return fType; }
color()571         SkColor4f color() const {
572             SkASSERT(this->type() == Type::kColor);
573             return fColor;
574         }
575 
pixmap(int i)576         const SkPixmap& pixmap(int i) const {
577             SkASSERT(this->type() == Type::kPixmaps);
578             return fPixmaps[i];
579         }
pixmaps()580         const SkPixmap* pixmaps() const {
581             SkASSERT(this->type() == Type::kPixmaps);
582             return fPixmaps;
583         }
584 
compressedData()585         const void* compressedData() const {
586             SkASSERT(this->type() == Type::kCompressed);
587             return fCompressed.fData;
588         }
compressedSize()589         size_t compressedSize() const {
590             SkASSERT(this->type() == Type::kCompressed);
591             return fCompressed.fSize;
592         }
593 
594 
595     private:
596         Type fType = Type::kColor;
597         union {
598             SkColor4f fColor = {0, 0, 0, 0};
599             const SkPixmap* fPixmaps;
600             struct {
601                 const void*  fData;
602                 size_t       fSize;
603             } fCompressed;
604         };
605     };
606 
607     /**
608      * Creates a texture directly in the backend API without wrapping it in a GrTexture.
609      * Must be matched with a call to deleteBackendTexture().
610      *
611      * If data is null the texture is uninitialized.
612      *
613      * If data represents a color then all texture levels are cleared to that color.
614      *
615      * If data represents pixmaps then it must have a either one pixmap or, if mipmapping
616      * is specified, a complete MIP hierarchy of pixmaps. Additionally, if provided, the mip
617      * levels must be sized correctly according to the MIP sizes implied by dimensions. They
618      * must all have the same color type and that color type must be compatible with the
619      * texture format.
620      */
621     GrBackendTexture createBackendTexture(SkISize dimensions,
622                                           const GrBackendFormat&,
623                                           GrRenderable,
624                                           GrMipmapped,
625                                           GrProtected);
626 
627     bool updateBackendTexture(const GrBackendTexture&,
628                               sk_sp<GrRefCntedCallback> finishedCallback,
629                               const BackendTextureData*);
630 
631     /**
632      * Same as the createBackendTexture case except compressed backend textures can
633      * never be renderable.
634      */
635     GrBackendTexture createCompressedBackendTexture(SkISize dimensions,
636                                                     const GrBackendFormat&,
637                                                     GrMipmapped,
638                                                     GrProtected);
639 
640     bool updateCompressedBackendTexture(const GrBackendTexture&,
641                                         sk_sp<GrRefCntedCallback> finishedCallback,
642                                         const BackendTextureData*);
643 
setBackendTextureState(const GrBackendTexture &,const GrBackendSurfaceMutableState &,GrBackendSurfaceMutableState * previousState,sk_sp<GrRefCntedCallback> finishedCallback)644     virtual bool setBackendTextureState(const GrBackendTexture&,
645                                         const GrBackendSurfaceMutableState&,
646                                         GrBackendSurfaceMutableState* previousState,
647                                         sk_sp<GrRefCntedCallback> finishedCallback) {
648         return false;
649     }
650 
setBackendRenderTargetState(const GrBackendRenderTarget &,const GrBackendSurfaceMutableState &,GrBackendSurfaceMutableState * previousState,sk_sp<GrRefCntedCallback> finishedCallback)651     virtual bool setBackendRenderTargetState(const GrBackendRenderTarget&,
652                                              const GrBackendSurfaceMutableState&,
653                                              GrBackendSurfaceMutableState* previousState,
654                                              sk_sp<GrRefCntedCallback> finishedCallback) {
655         return false;
656     }
657 
658     /**
659      * Frees a texture created by createBackendTexture(). If ownership of the backend
660      * texture has been transferred to a context using adopt semantics this should not be called.
661      */
662     virtual void deleteBackendTexture(const GrBackendTexture&) = 0;
663 
664     /**
665      * In this case we have a program descriptor and a program info but no render target.
666      */
667     virtual bool compile(const GrProgramDesc&, const GrProgramInfo&) = 0;
668 
precompileShader(const SkData & key,const SkData & data)669     virtual bool precompileShader(const SkData& key, const SkData& data) { return false; }
670 
671 #if GR_TEST_UTILS
672     /** Check a handle represents an actual texture in the backend API that has not been freed. */
673     virtual bool isTestingOnlyBackendTexture(const GrBackendTexture&) const = 0;
674 
675     /**
676      * Creates a GrBackendRenderTarget that can be wrapped using
677      * SkSurface::MakeFromBackendRenderTarget. Ideally this is a non-textureable allocation to
678      * differentiate from testing with SkSurface::MakeFromBackendTexture. When sampleCnt > 1 this
679      * is used to test client wrapped allocations with MSAA where Skia does not allocate a separate
680      * buffer for resolving. If the color is non-null the backing store should be cleared to the
681      * passed in color.
682      */
683     virtual GrBackendRenderTarget createTestingOnlyBackendRenderTarget(
684             SkISize dimensions,
685             GrColorType,
686             int sampleCount = 1,
687             GrProtected = GrProtected::kNo) = 0;
688 
689     /**
690      * Deletes a GrBackendRenderTarget allocated with the above. Synchronization to make this safe
691      * is up to the caller.
692      */
693     virtual void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) = 0;
694 
695     // This is only to be used in GL-specific tests.
glContextForTesting()696     virtual const GrGLContext* glContextForTesting() const { return nullptr; }
697 
698     // This is only to be used by testing code
resetShaderCacheForTesting()699     virtual void resetShaderCacheForTesting() const {}
700 
701     /**
702      * Flushes all work to the gpu and forces the GPU to wait until all the gpu work has completed.
703      * This is for testing purposes only.
704      */
705     virtual void testingOnly_flushGpuAndSync() = 0;
706 
707     /**
708      * Inserted as a pair around a block of code to do a GPU frame capture.
709      * Currently only works with the Metal backend.
710      */
testingOnly_startCapture()711     virtual void testingOnly_startCapture() {}
testingOnly_endCapture()712     virtual void testingOnly_endCapture() {}
713 #endif
714 
715     // width and height may be larger than rt (if underlying API allows it).
716     // Returns nullptr if compatible sb could not be created, otherwise the caller owns the ref on
717     // the GrAttachment.
718     virtual sk_sp<GrAttachment> makeStencilAttachmentForRenderTarget(const GrRenderTarget*,
719                                                                      SkISize dimensions,
720                                                                      int numStencilSamples) = 0;
721 
722     virtual GrBackendFormat getPreferredStencilFormat(const GrBackendFormat&) = 0;
723 
724     // Creates an MSAA surface to be used as an MSAA attachment on a framebuffer.
725     virtual sk_sp<GrAttachment> makeMSAAAttachment(SkISize dimensions,
726                                                    const GrBackendFormat& format,
727                                                    int numSamples,
728                                                    GrProtected isProtected) = 0;
729 
handleDirtyContext()730     void handleDirtyContext() {
731         if (fResetBits) {
732             this->resetContext();
733         }
734     }
735 
storeVkPipelineCacheData()736     virtual void storeVkPipelineCacheData() {}
737 
738     // http://skbug.com/9739
insertManualFramebufferBarrier()739     virtual void insertManualFramebufferBarrier() {
740         SkASSERT(!this->caps()->requiresManualFBBarrierAfterTessellatedStencilDraw());
741         SK_ABORT("Manual framebuffer barrier not supported.");
742     }
743 
744     // Called before certain draws in order to guarantee coherent results from dst reads.
745     virtual void xferBarrier(GrRenderTarget*, GrXferBarrierType) = 0;
746 
747 protected:
748     static bool MipMapsAreCorrect(SkISize dimensions, GrMipmapped, const BackendTextureData*);
749     static bool CompressedDataIsCorrect(SkISize dimensions, SkImage::CompressionType,
750                                         GrMipmapped, const BackendTextureData*);
751 
752     // Handles cases where a surface will be updated without a call to flushRenderTarget.
753     void didWriteToSurface(GrSurface* surface, GrSurfaceOrigin origin, const SkIRect* bounds,
754                            uint32_t mipLevels = 1) const;
755 
setOOMed()756     void setOOMed() { fOOMed = true; }
757 
758     Stats                            fStats;
759     std::unique_ptr<GrPathRendering> fPathRendering;
760     // Subclass must initialize this in its constructor.
761     sk_sp<const GrCaps>              fCaps;
762 
763 private:
764     virtual GrBackendTexture onCreateBackendTexture(SkISize dimensions,
765                                                     const GrBackendFormat&,
766                                                     GrRenderable,
767                                                     GrMipmapped,
768                                                     GrProtected) = 0;
769 
770     virtual GrBackendTexture onCreateCompressedBackendTexture(
771             SkISize dimensions, const GrBackendFormat&, GrMipmapped, GrProtected) = 0;
772 
773     virtual bool onUpdateBackendTexture(const GrBackendTexture&,
774                                         sk_sp<GrRefCntedCallback> finishedCallback,
775                                         const BackendTextureData*) = 0;
776 
777     virtual bool onUpdateCompressedBackendTexture(const GrBackendTexture&,
778                                                   sk_sp<GrRefCntedCallback> finishedCallback,
779                                                   const BackendTextureData*) = 0;
780 
781     // called when the 3D context state is unknown. Subclass should emit any
782     // assumed 3D context state and dirty any state cache.
783     virtual void onResetContext(uint32_t resetBits) = 0;
784 
785     // Implementation of resetTextureBindings.
onResetTextureBindings()786     virtual void onResetTextureBindings() {}
787 
788     // Queries the effective number of samples in use by the hardware for the given render target,
789     // and queries the individual sample locations.
790     virtual void querySampleLocations(GrRenderTarget*, SkTArray<SkPoint>*) = 0;
791 
792     // overridden by backend-specific derived class to create objects.
793     // Texture size, renderablility, format support, sample count will have already been validated
794     // in base class before onCreateTexture is called.
795     // If the ith bit is set in levelClearMask then the ith MIP level should be cleared.
796     virtual sk_sp<GrTexture> onCreateTexture(SkISize dimensions,
797                                              const GrBackendFormat&,
798                                              GrRenderable,
799                                              int renderTargetSampleCnt,
800                                              SkBudgeted,
801                                              GrProtected,
802                                              int mipLevelCoont,
803                                              uint32_t levelClearMask) = 0;
804     virtual sk_sp<GrTexture> onCreateCompressedTexture(SkISize dimensions,
805                                                        const GrBackendFormat&,
806                                                        SkBudgeted,
807                                                        GrMipmapped,
808                                                        GrProtected,
809                                                        const void* data, size_t dataSize) = 0;
810     virtual sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&,
811                                                   GrWrapOwnership,
812                                                   GrWrapCacheable,
813                                                   GrIOType) = 0;
814 
815     virtual sk_sp<GrTexture> onWrapCompressedBackendTexture(const GrBackendTexture&,
816                                                             GrWrapOwnership,
817                                                             GrWrapCacheable) = 0;
818 
819     virtual sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&,
820                                                             int sampleCnt,
821                                                             GrWrapOwnership,
822                                                             GrWrapCacheable) = 0;
823     virtual sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&) = 0;
824     virtual sk_sp<GrRenderTarget> onWrapVulkanSecondaryCBAsRenderTarget(const SkImageInfo&,
825                                                                         const GrVkDrawableInfo&);
826 
827     virtual sk_sp<GrGpuBuffer> onCreateBuffer(size_t size, GrGpuBufferType intendedType,
828                                               GrAccessPattern, const void* data) = 0;
829 
830     // overridden by backend-specific derived class to perform the surface read
831     virtual bool onReadPixels(GrSurface*, int left, int top, int width, int height,
832                               GrColorType surfaceColorType, GrColorType dstColorType, void* buffer,
833                               size_t rowBytes) = 0;
834 
835     // overridden by backend-specific derived class to perform the surface write
836     virtual bool onWritePixels(GrSurface*, int left, int top, int width, int height,
837                                GrColorType surfaceColorType, GrColorType srcColorType,
838                                const GrMipLevel texels[], int mipLevelCount,
839                                bool prepForTexSampling) = 0;
840 
841     // overridden by backend-specific derived class to perform the texture transfer
842     virtual bool onTransferPixelsTo(GrTexture*, int left, int top, int width, int height,
843                                     GrColorType textiueColorType, GrColorType bufferColorType,
844                                     GrGpuBuffer* transferBuffer, size_t offset,
845                                     size_t rowBytes) = 0;
846     // overridden by backend-specific derived class to perform the surface transfer
847     virtual bool onTransferPixelsFrom(GrSurface*, int left, int top, int width, int height,
848                                       GrColorType surfaceColorType, GrColorType bufferColorType,
849                                       GrGpuBuffer* transferBuffer, size_t offset) = 0;
850 
851     // overridden by backend-specific derived class to perform the resolve
852     virtual void onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resolveRect) = 0;
853 
854     // overridden by backend specific derived class to perform mip map level regeneration.
855     virtual bool onRegenerateMipMapLevels(GrTexture*) = 0;
856 
857     // overridden by backend specific derived class to perform the copy surface
858     virtual bool onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
859                                const SkIPoint& dstPoint) = 0;
860 
861     virtual GrOpsRenderPass* onGetOpsRenderPass(
862             GrRenderTarget* renderTarget,
863             GrAttachment* stencil,
864             GrSurfaceOrigin,
865             const SkIRect& bounds,
866             const GrOpsRenderPass::LoadAndStoreInfo&,
867             const GrOpsRenderPass::StencilLoadAndStoreInfo&,
868             const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
869             GrXferBarrierFlags renderPassXferBarriers) = 0;
870 
prepareSurfacesForBackendAccessAndStateUpdates(SkSpan<GrSurfaceProxy * > proxies,SkSurface::BackendSurfaceAccess access,const GrBackendSurfaceMutableState * newState)871     virtual void prepareSurfacesForBackendAccessAndStateUpdates(
872             SkSpan<GrSurfaceProxy*> proxies,
873             SkSurface::BackendSurfaceAccess access,
874             const GrBackendSurfaceMutableState* newState) {}
875 
876     virtual bool onSubmitToGpu(bool syncCpu) = 0;
877 
878 #ifdef SK_ENABLE_DUMP_GPU
onDumpJSON(SkJSONWriter *)879     virtual void onDumpJSON(SkJSONWriter*) const {}
880 #endif
881 
882     sk_sp<GrTexture> createTextureCommon(SkISize,
883                                          const GrBackendFormat&,
884                                          GrRenderable,
885                                          int renderTargetSampleCnt,
886                                          SkBudgeted,
887                                          GrProtected,
888                                          int mipLevelCnt,
889                                          uint32_t levelClearMask);
890 
resetContext()891     void resetContext() {
892         this->onResetContext(fResetBits);
893         fResetBits = 0;
894     }
895 
896     void callSubmittedProcs(bool success);
897 
898     uint32_t fResetBits;
899     // The context owns us, not vice-versa, so this ptr is not ref'ed by Gpu.
900     GrDirectContext* fContext;
901     GrSamplePatternDictionary fSamplePatternDictionary;
902 
903     struct SubmittedProc {
SubmittedProcSubmittedProc904         SubmittedProc(GrGpuSubmittedProc proc, GrGpuSubmittedContext context)
905                 : fProc(proc), fContext(context) {}
906 
907         GrGpuSubmittedProc fProc;
908         GrGpuSubmittedContext fContext;
909     };
910     SkSTArray<4, SubmittedProc> fSubmittedProcs;
911 
912     bool fOOMed = false;
913 
914 #if SK_HISTOGRAMS_ENABLED
915     int fCurrentSubmitRenderPassCount = 0;
916 #endif
917 
918     friend class GrPathRendering;
919     using INHERITED = SkRefCnt;
920 };
921 
922 #endif
923