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