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