• 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 GrGLGpu_DEFINED
9 #define GrGLGpu_DEFINED
10 
11 #include "include/core/SkRefCnt.h"
12 #include "include/core/SkSamplingOptions.h"
13 #include "include/core/SkTypes.h"
14 #include "include/gpu/GrBackendSurface.h"
15 #include "include/gpu/GrTypes.h"
16 #include "include/gpu/ganesh/gl/GrGLBackendSurface.h"
17 #include "include/gpu/gl/GrGLFunctions.h"
18 #include "include/gpu/gl/GrGLInterface.h"
19 #include "include/gpu/gl/GrGLTypes.h"
20 #include "include/private/SkColorData.h"
21 #include "include/private/base/SkDebug.h"
22 #include "include/private/base/SkTArray.h"
23 #include "include/private/base/SkTemplates.h"
24 #include "include/private/base/SkTo.h"
25 #include "include/private/gpu/ganesh/GrTypesPriv.h"
26 #include "src/core/SkChecksum.h"
27 #include "src/core/SkLRUCache.h"
28 #include "src/gpu/Blend.h"
29 #include "src/gpu/ganesh/GrCaps.h"
30 #include "src/gpu/ganesh/GrGpu.h"
31 #include "src/gpu/ganesh/GrGpuResource.h"
32 #include "src/gpu/ganesh/GrNativeRect.h"
33 #include "src/gpu/ganesh/GrOpsRenderPass.h"
34 #include "src/gpu/ganesh/GrProgramDesc.h"
35 #include "src/gpu/ganesh/GrSamplerState.h"
36 #include "src/gpu/ganesh/GrScissorState.h"
37 #include "src/gpu/ganesh/GrShaderCaps.h"
38 #include "src/gpu/ganesh/GrStencilSettings.h"
39 #include "src/gpu/ganesh/GrThreadSafePipelineBuilder.h"
40 #include "src/gpu/ganesh/GrWindowRectsState.h"
41 #include "src/gpu/ganesh/GrXferProcessor.h"
42 #include "src/gpu/ganesh/gl/GrGLCaps.h"
43 #include "src/gpu/ganesh/gl/GrGLContext.h"
44 #include "src/gpu/ganesh/gl/GrGLDefines.h"
45 #include "src/gpu/ganesh/gl/GrGLFinishCallbacks.h"
46 #include "src/gpu/ganesh/gl/GrGLRenderTarget.h"
47 #include "src/gpu/ganesh/gl/GrGLTexture.h"
48 #include "src/gpu/ganesh/gl/GrGLTypesPriv.h"
49 #include "src/gpu/ganesh/gl/GrGLUtil.h"
50 #include "src/gpu/ganesh/gl/GrGLVertexArray.h"
51 
52 #include <array>
53 #include <cstddef>
54 #include <cstdint>
55 #include <memory>
56 #include <string_view>
57 
58 class GrAttachment;
59 class GrBackendSemaphore;
60 class GrBuffer;
61 class GrDirectContext;
62 class GrGLBuffer;
63 class GrGLOpsRenderPass;
64 class GrGLProgram;
65 class GrGpuBuffer;
66 class GrProgramInfo;
67 class GrRenderTarget;
68 class GrSemaphore;
69 class GrStagingBufferManager;
70 class GrSurface;
71 class GrSurfaceProxy;
72 class GrTexture;
73 class SkData;
74 enum class SkTextureCompressionType;
75 struct GrContextOptions;
76 struct SkIPoint;
77 struct SkIRect;
78 struct SkISize;
79 
80 namespace SkSL { enum class GLSLGeneration; }
81 
82 namespace skgpu {
83 class RefCntedCallback;
84 class Swizzle;
85 enum class Budgeted : bool;
86 enum class Mipmapped : bool;
87 }
88 
89 class GrGLGpu final : public GrGpu {
90 public:
91     static std::unique_ptr<GrGpu> Make(sk_sp<const GrGLInterface>,
92                                        const GrContextOptions&,
93                                        GrDirectContext*);
94     ~GrGLGpu() override;
95 
96     void disconnect(DisconnectType) override;
97 
98     GrThreadSafePipelineBuilder* pipelineBuilder() override;
99     sk_sp<GrThreadSafePipelineBuilder> refPipelineBuilder() override;
100 
glContext()101     const GrGLContext& glContext() const { return *fGLContext; }
102 
glInterface()103     const GrGLInterface* glInterface() const { return fGLContext->glInterface(); }
ctxInfo()104     const GrGLContextInfo& ctxInfo() const { return *fGLContext; }
glStandard()105     GrGLStandard glStandard() const { return fGLContext->standard(); }
glVersion()106     GrGLVersion glVersion() const { return fGLContext->version(); }
glslGeneration()107     SkSL::GLSLGeneration glslGeneration() const { return fGLContext->glslGeneration(); }
glCaps()108     const GrGLCaps& glCaps() const { return *fGLContext->caps(); }
109 
stagingBufferManager()110     GrStagingBufferManager* stagingBufferManager() override { return fStagingBufferManager.get(); }
111 
112     // Used by GrGLProgram to configure OpenGL state.
113     void bindTexture(int unitIdx, GrSamplerState samplerState, const skgpu::Swizzle&, GrGLTexture*);
114 
115     // These functions should be used to bind GL objects. They track the GL state and skip redundant
116     // bindings. Making the equivalent glBind calls directly will confuse the state tracking.
bindVertexArray(GrGLuint id)117     void bindVertexArray(GrGLuint id) {
118         fHWVertexArrayState.setVertexArrayID(this, id);
119     }
120 
121     // These callbacks update state tracking when GL objects are deleted. They are called from
122     // GrGLResource onRelease functions.
notifyVertexArrayDelete(GrGLuint id)123     void notifyVertexArrayDelete(GrGLuint id) {
124         fHWVertexArrayState.notifyVertexArrayDelete(id);
125     }
126 
127     // Binds a buffer to the GL target corresponding to 'type', updates internal state tracking, and
128     // returns the GL target the buffer was bound to.
129     // When 'type' is kIndex_GrBufferType, this function will also implicitly bind the default VAO.
130     // If the caller wishes to bind an index buffer to a specific VAO, it can call glBind directly.
131     GrGLenum bindBuffer(GrGpuBufferType type, const GrBuffer*);
132 
133     // Flushes state from GrProgramInfo to GL. Returns false if the state couldn't be set.
134     bool flushGLState(GrRenderTarget*, bool useMultisampleFBO, const GrProgramInfo&);
135     void flushScissorRect(const SkIRect& scissor, int rtHeight, GrSurfaceOrigin);
136 
137     // The flushRenderTarget methods will all set the initial viewport to the full extent of the
138     // backing render target.
139     void flushViewport(const SkIRect& viewport, int rtHeight, GrSurfaceOrigin);
140 
141     // Returns the last program bound by flushGLState(), or nullptr if a different program has since
142     // been put into use via some other method (e.g., resetContext, copySurfaceAsDraw).
143     // The returned GrGLProgram can be used for binding textures and vertex attributes.
currentProgram()144     GrGLProgram* currentProgram() {
145         this->handleDirtyContext();
146         return fHWProgram.get();
147     }
148 
149     // Binds the vertex array that should be used for internal draws, enables 'numAttribs' vertex
150     // arrays, and flushes the desired primitive restart settings. If an index buffer is provided,
151     // it will be bound to the vertex array. Otherwise the index buffer binding will be left
152     // unchanged.
153     //
154     // NOTE: This binds the default VAO (ID=zero) unless we are on a core profile, in which case we
155     // use a placeholder array instead.
bindInternalVertexArray(const GrBuffer * indexBuffer,int numAttribs,GrPrimitiveRestart primitiveRestart)156     GrGLAttribArrayState* bindInternalVertexArray(const GrBuffer* indexBuffer, int numAttribs,
157                                                   GrPrimitiveRestart primitiveRestart) {
158         auto* attribState = fHWVertexArrayState.bindInternalVertexArray(this, indexBuffer);
159         attribState->enableVertexArrays(this, numAttribs, primitiveRestart);
160         return attribState;
161     }
162 
163     // Applies any necessary workarounds and returns the GL primitive type to use in draw calls.
164     GrGLenum prepareToDraw(GrPrimitiveType primitiveType);
165 
166     using ResolveDirection = GrGLRenderTarget::ResolveDirection;
167 
168     // Resolves the render target's single sample FBO into the MSAA, or vice versa.
169     // If glCaps.framebufferResolvesMustBeFullSize() is true, resolveRect must be equal the render
170     // target's bounds rect.
171     // If blitting single to MSAA, glCaps.canResolveSingleToMSAA() must be true.
172     void resolveRenderFBOs(GrGLRenderTarget*, const SkIRect& resolveRect, ResolveDirection,
173                            bool invalidateReadBufferAfterBlit = false);
174 
175     // For loading a dynamic MSAA framebuffer when glCaps.canResolveSingleToMSAA() is false.
176     // NOTE: If glCaps.framebufferResolvesMustBeFullSize() is also true, the drawBounds should be
177     // equal to the proxy bounds. This is because the render pass will have to do a full size
178     // resolve back into the single sample FBO when rendering is complete.
drawSingleIntoMSAAFBO(GrGLRenderTarget * rt,const SkIRect & drawBounds)179     void drawSingleIntoMSAAFBO(GrGLRenderTarget* rt, const SkIRect& drawBounds) {
180         this->copySurfaceAsDraw(rt, true/*drawToMultisampleFBO*/, rt, drawBounds, drawBounds,
181                                 GrSamplerState::Filter::kNearest);
182     }
183 
184     // The GrGLOpsRenderPass does not buffer up draws before submitting them to the gpu.
185     // Thus this is the implementation of the clear call for the corresponding passthrough function
186     // on GrGLOpsRenderPass.
187     void clear(const GrScissorState&, std::array<float, 4> color, GrRenderTarget*,
188                bool useMultisampleFBO, GrSurfaceOrigin);
189 
190     // The GrGLOpsRenderPass does not buffer up draws before submitting them to the gpu.
191     // Thus this is the implementation of the clearStencil call for the corresponding passthrough
192     // function on GrGLOpsrenderPass.
193     void clearStencilClip(const GrScissorState&, bool insideStencilMask,
194                           GrRenderTarget*, bool useMultisampleFBO, GrSurfaceOrigin);
195 
196     void beginCommandBuffer(GrGLRenderTarget*, bool useMultisampleFBO,
197                             const SkIRect& bounds, GrSurfaceOrigin,
198                             const GrOpsRenderPass::LoadAndStoreInfo& colorLoadStore,
199                             const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilLoadStore);
200 
201     void endCommandBuffer(GrGLRenderTarget*, bool useMultisampleFBO,
202                           const GrOpsRenderPass::LoadAndStoreInfo& colorLoadStore,
203                           const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilLoadStore);
204 
invalidateBoundRenderTarget()205     void invalidateBoundRenderTarget() {
206         fHWBoundRenderTargetUniqueID.makeInvalid();
207     }
208 
209     sk_sp<GrAttachment> makeStencilAttachment(const GrBackendFormat& colorFormat,
210                                               SkISize dimensions, int numStencilSamples) override;
211 
212     sk_sp<GrAttachment> makeMSAAAttachment(SkISize dimensions,
213                                            const GrBackendFormat& format,
214                                            int numSamples,
215                                            GrProtected isProtected,
216                                            GrMemoryless) override;
217 
218     void deleteBackendTexture(const GrBackendTexture&) override;
219 
220     bool compile(const GrProgramDesc&, const GrProgramInfo&) override;
221 
precompileShader(const SkData & key,const SkData & data)222     bool precompileShader(const SkData& key, const SkData& data) override {
223         return fProgramCache->precompileShader(this->getContext(), key, data);
224     }
225 
226 #if defined(GR_TEST_UTILS)
227     bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override;
228 
229     GrBackendRenderTarget createTestingOnlyBackendRenderTarget(SkISize dimensions,
230                                                                GrColorType,
231                                                                int sampleCnt,
232                                                                GrProtected) override;
233     void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override;
234 
glContextForTesting()235     const GrGLContext* glContextForTesting() const override { return &this->glContext(); }
236 
resetShaderCacheForTesting()237     void resetShaderCacheForTesting() const override { fProgramCache->reset(); }
238 #endif
239 
240     void willExecute() override;
241 
242     void submit(GrOpsRenderPass* renderPass) override;
243 
244     [[nodiscard]] GrGLsync insertFence();
245     bool waitFence(GrGLsync);
246     void deleteFence(GrGLsync);
247 
248     [[nodiscard]] std::unique_ptr<GrSemaphore> makeSemaphore(bool isOwned) override;
249     std::unique_ptr<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore&,
250                                                       GrSemaphoreWrapType,
251                                                       GrWrapOwnership) override;
252     void insertSemaphore(GrSemaphore* semaphore) override;
253     void waitSemaphore(GrSemaphore* semaphore) override;
254 
255     void checkFinishProcs() override;
256     void finishOutstandingGpuWork() override;
257 
258     // Calls glGetError() until no errors are reported. Also looks for OOMs.
259     void clearErrorsAndCheckForOOM();
260     // Calls glGetError() once and returns the result. Also looks for an OOM.
261     GrGLenum getErrorAndCheckForOOM();
262 
263     std::unique_ptr<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override;
264 
265     void deleteSync(GrGLsync);
266 
267     void bindFramebuffer(GrGLenum fboTarget, GrGLuint fboid);
268     void deleteFramebuffer(GrGLuint fboid);
269 
270     void flushProgram(sk_sp<GrGLProgram>);
271 
272     // Version for programs that aren't GrGLProgram.
273     void flushProgram(GrGLuint);
274 
275     // GrGLOpsRenderPass directly makes GL draws. GrGLGpu uses this notification to mark the
276     // destination surface dirty if color writes are enabled.
277     void didDrawTo(GrRenderTarget*);
278 
279 private:
280     GrGLGpu(std::unique_ptr<GrGLContext>, GrDirectContext*);
281 
282     // GrGpu overrides
283     GrBackendTexture onCreateBackendTexture(SkISize dimensions,
284                                             const GrBackendFormat&,
285                                             GrRenderable,
286                                             skgpu::Mipmapped,
287                                             GrProtected,
288                                             std::string_view label) override;
289 
290     GrBackendTexture onCreateCompressedBackendTexture(SkISize dimensions,
291                                                       const GrBackendFormat&,
292                                                       skgpu::Mipmapped,
293                                                       GrProtected) override;
294 
295     bool onClearBackendTexture(const GrBackendTexture&,
296                                sk_sp<skgpu::RefCntedCallback> finishedCallback,
297                                std::array<float, 4> color) override;
298 
299     bool onUpdateCompressedBackendTexture(const GrBackendTexture&,
300                                           sk_sp<skgpu::RefCntedCallback> finishedCallback,
301                                           const void* data,
302                                           size_t length) override;
303 
304     void onResetContext(uint32_t resetBits) override;
305 
306     void onResetTextureBindings() override;
307 
308     void xferBarrier(GrRenderTarget*, GrXferBarrierType) override;
309 
310     sk_sp<GrTexture> onCreateTexture(SkISize dimensions,
311                                      const GrBackendFormat&,
312                                      GrRenderable,
313                                      int renderTargetSampleCnt,
314                                      skgpu::Budgeted,
315                                      GrProtected,
316                                      int mipLevelCount,
317                                      uint32_t levelClearMask,
318                                      std::string_view label) override;
319     sk_sp<GrTexture> onCreateCompressedTexture(SkISize dimensions,
320                                                const GrBackendFormat&,
321                                                skgpu::Budgeted,
322                                                skgpu::Mipmapped,
323                                                GrProtected,
324                                                const void* data,
325                                                size_t dataSize) override;
326 
327     sk_sp<GrGpuBuffer> onCreateBuffer(size_t size, GrGpuBufferType, GrAccessPattern) override;
328 
329     sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&,
330                                           GrWrapOwnership,
331                                           GrWrapCacheable,
332                                           GrIOType) override;
333     sk_sp<GrTexture> onWrapCompressedBackendTexture(const GrBackendTexture&,
334                                                     GrWrapOwnership,
335                                                     GrWrapCacheable) override;
336     sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&,
337                                                     int sampleCnt,
338                                                     GrWrapOwnership,
339                                                     GrWrapCacheable) override;
340     sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&) override;
341 
342     // Given a GL format return the index into the stencil format array on GrGLCaps to a
343     // compatible stencil format, or negative if there is no compatible stencil format.
344     int getCompatibleStencilIndex(GrGLFormat format);
345 
getPreferredStencilFormat(const GrBackendFormat & format)346     GrBackendFormat getPreferredStencilFormat(const GrBackendFormat& format) override {
347         int idx = this->getCompatibleStencilIndex(GrBackendFormats::AsGLFormat(format));
348         if (idx < 0) {
349             return {};
350         }
351         return GrBackendFormats::MakeGL(GrGLFormatToEnum(this->glCaps().stencilFormats()[idx]),
352                                         GR_GL_TEXTURE_NONE);
353     }
354 
355     void onFBOChanged();
356 
357     // Returns whether the texture is successfully created. On success, a non-zero texture ID is
358     // returned. On failure, zero is returned.
359     // The texture is populated with |texels|, if it is non-null.
360     // The texture parameters are cached in |initialTexParams|.
361     GrGLuint createTexture(SkISize dimensions,
362                            GrGLFormat,
363                            GrGLenum target,
364                            GrRenderable,
365                            GrGLTextureParameters::SamplerOverriddenState*,
366                            int mipLevelCount,
367                            GrProtected isProtected,
368                            std::string_view label);
369 
370     GrGLuint createCompressedTexture2D(SkISize dimensions,
371                                        SkTextureCompressionType compression,
372                                        GrGLFormat,
373                                        skgpu::Mipmapped,
374                                        GrProtected,
375                                        GrGLTextureParameters::SamplerOverriddenState*);
376 
377     bool onReadPixels(GrSurface*,
378                       SkIRect,
379                       GrColorType surfaceColorType,
380                       GrColorType dstColorType,
381                       void*,
382                       size_t rowBytes) override;
383 
384     bool onWritePixels(GrSurface*,
385                        SkIRect,
386                        GrColorType surfaceColorType,
387                        GrColorType srcColorType,
388                        const GrMipLevel[],
389                        int mipLevelCount,
390                        bool prepForTexSampling) override;
391 
392     bool onTransferFromBufferToBuffer(sk_sp<GrGpuBuffer> src,
393                                       size_t srcOffset,
394                                       sk_sp<GrGpuBuffer> dst,
395                                       size_t dstOffset,
396                                       size_t size) override;
397 
398     bool onTransferPixelsTo(GrTexture*,
399                             SkIRect,
400                             GrColorType textureColorType,
401                             GrColorType bufferColorType,
402                             sk_sp<GrGpuBuffer>,
403                             size_t offset,
404                             size_t rowBytes) override;
405 
406     bool onTransferPixelsFrom(GrSurface*,
407                               SkIRect,
408                               GrColorType surfaceColorType,
409                               GrColorType bufferColorType,
410                               sk_sp<GrGpuBuffer>,
411                               size_t offset) override;
412 
413     bool readOrTransferPixelsFrom(GrSurface*,
414                                   SkIRect rect,
415                                   GrColorType surfaceColorType,
416                                   GrColorType dstColorType,
417                                   void* offsetOrPtr,
418                                   int rowWidthInPixels);
419 
420     // Unbinds xfer buffers from GL for operations that don't need them.
421     // Before calling any variation of TexImage, TexSubImage, etc..., call this with
422     // GrGpuBufferType::kXferCpuToGpu to ensure that the PIXEL_UNPACK_BUFFER is unbound.
423     // Before calling ReadPixels and reading back into cpu memory call this with
424     // GrGpuBufferType::kXferGpuToCpu to ensure that the PIXEL_PACK_BUFFER is unbound.
425     void unbindXferBuffer(GrGpuBufferType type);
426 
427     void onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resolveRect) override;
428 
429     bool onRegenerateMipMapLevels(GrTexture*) override;
430 
431     bool onCopySurface(GrSurface* dst, const SkIRect& dstRect,
432                        GrSurface* src, const SkIRect& srcRect,
433                        GrSamplerState::Filter) override;
434 
435     // binds texture unit in GL
436     void setTextureUnit(int unitIdx);
437 
438     void flushBlendAndColorWrite(const skgpu::BlendInfo&, const skgpu::Swizzle&);
439 
440     void addFinishedProc(GrGpuFinishedProc finishedProc,
441                          GrGpuFinishedContext finishedContext) override;
442 
443     GrOpsRenderPass* onGetOpsRenderPass(
444             GrRenderTarget*,
445             bool useMultisampleFBO,
446             GrAttachment*,
447             GrSurfaceOrigin,
448             const SkIRect&,
449             const GrOpsRenderPass::LoadAndStoreInfo&,
450             const GrOpsRenderPass::StencilLoadAndStoreInfo&,
451             const skia_private::TArray<GrSurfaceProxy*, true>& sampledProxies,
452             GrXferBarrierFlags renderPassXferBarriers) override;
453 
454     bool onSubmitToGpu(GrSyncCpu sync) override;
455 
456     bool waitSync(GrGLsync, uint64_t timeout, bool flush);
457 
458     bool copySurfaceAsDraw(GrSurface* dst, bool drawToMultisampleFBO, GrSurface* src,
459                            const SkIRect& srcRect, const SkIRect& dstRect, GrSamplerState::Filter);
460     void copySurfaceAsCopyTexSubImage(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
461                                       const SkIPoint& dstPoint);
462     bool copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
463                                       const SkIRect& dstRect, GrSamplerState::Filter);
464 
465     class ProgramCache : public GrThreadSafePipelineBuilder {
466     public:
467         ProgramCache(int runtimeProgramCacheSize);
468         ~ProgramCache() override;
469 
470         void abandon();
471         void reset();
472         sk_sp<GrGLProgram> findOrCreateProgram(GrDirectContext*,
473                                                const GrProgramInfo&);
474         sk_sp<GrGLProgram> findOrCreateProgram(GrDirectContext*,
475                                                const GrProgramDesc&,
476                                                const GrProgramInfo&,
477                                                Stats::ProgramCacheResult*);
478         bool precompileShader(GrDirectContext*, const SkData& key, const SkData& data);
479 
480     private:
481         struct Entry;
482 
483         sk_sp<GrGLProgram> findOrCreateProgramImpl(GrDirectContext*,
484                                                    const GrProgramDesc&,
485                                                    const GrProgramInfo&,
486                                                    Stats::ProgramCacheResult*);
487 
488         struct DescHash {
operatorDescHash489             uint32_t operator()(const GrProgramDesc& desc) const {
490                 return SkChecksum::Hash32(desc.asKey(), desc.keyLength());
491             }
492         };
493 
494         SkLRUCache<GrProgramDesc, std::unique_ptr<Entry>, DescHash> fMap;
495     };
496 
497     void flushColorWrite(bool writeColor);
498     void flushClearColor(std::array<float, 4>);
499 
500     // flushes the scissor. see the note on flushBoundTextureAndParams about
501     // flushing the scissor after that function is called.
flushScissor(const GrScissorState & scissorState,int rtHeight,GrSurfaceOrigin rtOrigin)502     void flushScissor(const GrScissorState& scissorState, int rtHeight, GrSurfaceOrigin rtOrigin) {
503         this->flushScissorTest(GrScissorTest(scissorState.enabled()));
504         if (scissorState.enabled()) {
505             this->flushScissorRect(scissorState.rect(), rtHeight, rtOrigin);
506         }
507     }
508     void flushScissorTest(GrScissorTest);
509 
510     void flushWindowRectangles(const GrWindowRectsState&, const GrGLRenderTarget*, GrSurfaceOrigin);
511     void disableWindowRectangles();
512 
numTextureUnits()513     int numTextureUnits() const { return this->caps()->shaderCaps()->fMaxFragmentSamplers; }
514 
515     // Binds a texture to a target on the "scratch" texture unit to use for texture operations
516     // other than usual draw flow (i.e. a GrGLProgram derived from a GrPipeline used to draw). It
517     // ensures that such operations don't negatively interact with draws. The active texture unit
518     // and the binding for 'target' will change.
519     void bindTextureToScratchUnit(GrGLenum target, GrGLint textureID);
520 
521     void flushRenderTarget(GrGLRenderTarget*, bool useMultisampleFBO);
522 
523     void flushStencil(const GrStencilSettings&, GrSurfaceOrigin);
524     void disableStencil();
525 
526     void flushConservativeRasterState(bool enable);
527 
528     void flushWireframeState(bool enable);
529 
530     void flushFramebufferSRGB(bool enable);
531 
532     // Uploads src data of a color type to the currently bound texture on the active texture unit.
533     // The caller specifies color type that the texture is being used with, which may be different
534     // than the src color type. This fails if the combination of texture format, texture color type,
535     // and src data color type are not valid. No conversion is performed on the data before passing
536     // it to GL. 'dstRect' must be the texture bounds if mipLevelCount is greater than 1.
537     bool uploadColorTypeTexData(GrGLFormat textureFormat,
538                                 GrColorType textureColorType,
539                                 SkISize texDims,
540                                 GrGLenum target,
541                                 SkIRect dstRect,
542                                 GrColorType srcColorType,
543                                 const GrMipLevel texels[],
544                                 int mipLevelCount);
545 
546     // Uploads a constant color to a texture using the "default" format and color type. Overwrites
547     // entire levels. Bit n in 'levelMask' indicates whether level n should be written. This
548     // function doesn't know if MIP levels have been allocated, thus levelMask should not have bits
549     // beyond the low bit set if the texture is not MIP mapped.
550     bool uploadColorToTex(GrGLFormat textureFormat,
551                           SkISize texDims,
552                           GrGLenum target,
553                           std::array<float, 4> color,
554                           uint32_t levelMask);
555 
556     // Pushes data to the currently bound texture to the currently active unit. 'dstRect' must be
557     // the texture bounds if mipLevelCount is greater than 1.
558     void uploadTexData(SkISize dimensions,
559                        GrGLenum target,
560                        SkIRect dstRect,
561                        GrGLenum externalFormat,
562                        GrGLenum externalType,
563                        size_t bpp,
564                        const GrMipLevel texels[],
565                        int mipLevelCount);
566 
567     // Helper for onCreateCompressedTexture. Compressed textures are read-only so we only use this
568     // to populate a new texture. Returns false if we failed to create and upload the texture.
569     bool uploadCompressedTexData(SkTextureCompressionType compressionType,
570                                  GrGLFormat,
571                                  SkISize dimensions,
572                                  skgpu::Mipmapped,
573                                  GrGLenum target,
574                                  const void* data,
575                                  size_t dataSize);
576 
577     // Calls one of various versions of renderBufferStorageMultisample.
578     bool renderbufferStorageMSAA(const GrGLContext& ctx, int sampleCount, GrGLenum format,
579                                  int width, int height);
580 
581     bool createRenderTargetObjects(const GrGLTexture::Desc&,
582                                    int sampleCount,
583                                    GrGLRenderTarget::IDs*);
584     enum TempFBOTarget {
585         kSrc_TempFBOTarget,
586         kDst_TempFBOTarget
587     };
588 
589     // Binds a surface as a FBO for copying, reading, or clearing. If the surface already owns an
590     // FBO ID then that ID is bound. If not the surface is temporarily bound to a FBO and that FBO
591     // is bound. This must be paired with a call to unbindSurfaceFBOForPixelOps().
592     void bindSurfaceFBOForPixelOps(GrSurface* surface, int mipLevel, GrGLenum fboTarget,
593                                    TempFBOTarget tempFBOTarget);
594 
595     // Must be called if bindSurfaceFBOForPixelOps was used to bind a surface for copying.
596     void unbindSurfaceFBOForPixelOps(GrSurface* surface, int mipLevel, GrGLenum fboTarget);
597 
598 #ifdef SK_ENABLE_DUMP_GPU
599     void onDumpJSON(SkJSONWriter*) const override;
600 #endif
601 
602     bool createCopyProgram(GrTexture* srcTexture);
603     bool createMipmapProgram(int progIdx);
604 
605     std::unique_ptr<GrGLContext> fGLContext;
606 
607     // GL program-related state
608     sk_sp<ProgramCache>         fProgramCache;
609 
610     ///////////////////////////////////////////////////////////////////////////
611     ///@name Caching of GL State
612     ///@{
613     int                         fHWActiveTextureUnitIdx;
614 
615     GrGLuint                    fHWProgramID;
616     sk_sp<GrGLProgram>          fHWProgram;
617 
618     enum TriState {
619         kNo_TriState,
620         kYes_TriState,
621         kUnknown_TriState
622     };
623 
624     GrGLuint                    fTempSrcFBOID;
625     GrGLuint                    fTempDstFBOID;
626 
627     GrGLuint                    fStencilClearFBOID;
628 
629     // last scissor / viewport scissor state seen by the GL.
630     struct {
631         TriState fEnabled;
632         GrNativeRect fRect;
invalidate__anon925186030108633         void invalidate() {
634             fEnabled = kUnknown_TriState;
635             fRect.invalidate();
636         }
637     } fHWScissorSettings;
638 
639     class {
640     public:
valid()641         bool valid() const { return kInvalidSurfaceOrigin != fRTOrigin; }
invalidate()642         void invalidate() { fRTOrigin = kInvalidSurfaceOrigin; }
knownDisabled()643         bool knownDisabled() const { return this->valid() && !fWindowState.enabled(); }
setDisabled()644         void setDisabled() {
645             fRTOrigin = kTopLeft_GrSurfaceOrigin;
646             fWindowState.setDisabled();
647         }
648 
set(GrSurfaceOrigin rtOrigin,int width,int height,const GrWindowRectsState & windowState)649         void set(GrSurfaceOrigin rtOrigin, int width, int height,
650                  const GrWindowRectsState& windowState) {
651             fRTOrigin = rtOrigin;
652             fWidth = width;
653             fHeight = height;
654             fWindowState = windowState;
655         }
656 
knownEqualTo(GrSurfaceOrigin rtOrigin,int width,int height,const GrWindowRectsState & windowState)657         bool knownEqualTo(GrSurfaceOrigin rtOrigin, int width, int height,
658                           const GrWindowRectsState& windowState) const {
659             if (!this->valid()) {
660                 return false;
661             }
662             if (fWindowState.numWindows() &&
663                 (fRTOrigin != rtOrigin || fWidth != width || fHeight != height)) {
664                 return false;
665             }
666             return fWindowState == windowState;
667         }
668 
669     private:
670         enum { kInvalidSurfaceOrigin = -1 };
671 
672         int                  fRTOrigin;
673         int                  fWidth;
674         int                  fHeight;
675         GrWindowRectsState   fWindowState;
676     } fHWWindowRectsState;
677 
678     GrNativeRect fHWViewport;
679 
680     /**
681      * Tracks vertex attrib array state.
682      */
683     class HWVertexArrayState {
684     public:
HWVertexArrayState()685         HWVertexArrayState() : fCoreProfileVertexArray(nullptr) { this->invalidate(); }
686 
~HWVertexArrayState()687         ~HWVertexArrayState() { delete fCoreProfileVertexArray; }
688 
invalidate()689         void invalidate() {
690             fBoundVertexArrayIDIsValid = false;
691             fDefaultVertexArrayAttribState.invalidate();
692             if (fCoreProfileVertexArray) {
693                 fCoreProfileVertexArray->invalidateCachedState();
694             }
695         }
696 
notifyVertexArrayDelete(GrGLuint id)697         void notifyVertexArrayDelete(GrGLuint id) {
698             if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) {
699                 // Does implicit bind to 0
700                 fBoundVertexArrayID = 0;
701             }
702         }
703 
setVertexArrayID(GrGLGpu * gpu,GrGLuint arrayID)704         void setVertexArrayID(GrGLGpu* gpu, GrGLuint arrayID) {
705             if (!gpu->glCaps().vertexArrayObjectSupport()) {
706                 SkASSERT(0 == arrayID);
707                 return;
708             }
709             if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) {
710                 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID));
711                 fBoundVertexArrayIDIsValid = true;
712                 fBoundVertexArrayID = arrayID;
713             }
714         }
715 
716         /**
717          * Binds the vertex array that should be used for internal draws, and returns its attrib
718          * state. This binds the default VAO (ID=zero) unless we are on a core profile, in which
719          * case we use a placeholder array instead.
720          *
721          * If an index buffer is provided, it will be bound to the vertex array. Otherwise the
722          * index buffer binding will be left unchanged.
723          *
724          * The returned GrGLAttribArrayState should be used to set vertex attribute arrays.
725          */
726         GrGLAttribArrayState* bindInternalVertexArray(GrGLGpu*, const GrBuffer* ibuff = nullptr);
727 
728     private:
729         GrGLuint             fBoundVertexArrayID;
730         bool                 fBoundVertexArrayIDIsValid;
731 
732         // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0
733         // is bound. However, this class is internal to GrGLGpu and this object never leaks out of
734         // GrGLGpu.
735         GrGLAttribArrayState fDefaultVertexArrayAttribState;
736 
737         // This is used when we're using a core profile.
738         GrGLVertexArray*     fCoreProfileVertexArray;
739     } fHWVertexArrayState;
740 
741     struct {
742         GrGLenum                fGLTarget;
743         GrGpuResource::UniqueID fBoundBufferUniqueID;
744         bool                    fBufferZeroKnownBound;
745 
invalidate__anon925186030308746         void invalidate() {
747             fBoundBufferUniqueID.makeInvalid();
748             fBufferZeroKnownBound = false;
749         }
750     }                                       fHWBufferState[kGrGpuBufferTypeCount];
751 
hwBufferState(GrGpuBufferType type)752     auto* hwBufferState(GrGpuBufferType type) {
753         unsigned typeAsUInt = static_cast<unsigned>(type);
754         SkASSERT(typeAsUInt < std::size(fHWBufferState));
755         SkASSERT(type != GrGpuBufferType::kUniform);
756         return &fHWBufferState[typeAsUInt];
757     }
758 
759     enum class FlushType {
760         kIfRequired,
761         kForce,
762     };
763 
764     // This calls glFlush if it is required for previous operations or kForce is passed.
765     void flush(FlushType flushType = FlushType::kIfRequired);
766 
setNeedsFlush()767     void setNeedsFlush() { fNeedsGLFlush = true; }
768 
769     struct {
770         skgpu::BlendEquation fEquation;
771         skgpu::BlendCoeff    fSrcCoeff;
772         skgpu::BlendCoeff    fDstCoeff;
773         SkPMColor4f          fConstColor;
774         bool                 fConstColorValid;
775         TriState             fEnabled;
776 
invalidate__anon925186030408777         void invalidate() {
778             fEquation = skgpu::BlendEquation::kIllegal;
779             fSrcCoeff = skgpu::BlendCoeff::kIllegal;
780             fDstCoeff = skgpu::BlendCoeff::kIllegal;
781             fConstColorValid = false;
782             fEnabled = kUnknown_TriState;
783         }
784     }                                       fHWBlendState;
785 
786     TriState                                fHWConservativeRasterEnabled;
787 
788     TriState                                fHWWireframeEnabled;
789 
790     GrStencilSettings                       fHWStencilSettings;
791     GrSurfaceOrigin                         fHWStencilOrigin;
792     TriState                                fHWStencilTestEnabled;
793 
794     TriState                                fHWWriteToColor;
795     GrGpuResource::UniqueID                 fHWBoundRenderTargetUniqueID;
796     bool                                    fHWBoundFramebufferIsMSAA;
797     TriState                                fHWSRGBFramebuffer;
798 
799     class TextureUnitBindings {
800     public:
801         TextureUnitBindings() = default;
802         TextureUnitBindings(const TextureUnitBindings&) = delete;
803         TextureUnitBindings& operator=(const TextureUnitBindings&) = delete;
804 
805         GrGpuResource::UniqueID boundID(GrGLenum target) const;
806         bool hasBeenModified(GrGLenum target) const;
807         void setBoundID(GrGLenum target, GrGpuResource::UniqueID);
808         void invalidateForScratchUse(GrGLenum target);
809         void invalidateAllTargets(bool markUnmodified);
810 
811     private:
812         struct TargetBinding {
813             GrGpuResource::UniqueID fBoundResourceID;
814             bool fHasBeenModified = false;
815         };
816         TargetBinding fTargetBindings[3];
817     };
818     skia_private::AutoTArray<TextureUnitBindings> fHWTextureUnitBindings;
819 
820     GrGLfloat fHWClearColor[4];
821 
822     GrGLuint fBoundDrawFramebuffer = 0;
823 
824     /** IDs for copy surface program. (3 sampler types) */
825     struct {
826         GrGLuint    fProgram = 0;
827         GrGLint     fTextureUniform = 0;
828         GrGLint     fTexCoordXformUniform = 0;
829         GrGLint     fPosXformUniform = 0;
830     }                                       fCopyPrograms[3];
831     sk_sp<GrGLBuffer>                       fCopyProgramArrayBuffer;
832 
833     /** IDs for texture mipmap program. (4 filter configurations) */
834     struct {
835         GrGLuint    fProgram = 0;
836         GrGLint     fTextureUniform = 0;
837         GrGLint     fTexCoordXformUniform = 0;
838     }                                       fMipmapPrograms[4];
839     sk_sp<GrGLBuffer>                       fMipmapProgramArrayBuffer;
840 
841     static int TextureToCopyProgramIdx(GrTexture* texture);
842 
TextureSizeToMipmapProgramIdx(int width,int height)843     static int TextureSizeToMipmapProgramIdx(int width, int height) {
844         const bool wide = (width > 1) && SkToBool(width & 0x1);
845         const bool tall = (height > 1) && SkToBool(height & 0x1);
846         return (wide ? 0x2 : 0x0) | (tall ? 0x1 : 0x0);
847     }
848 
849     GrPrimitiveType fLastPrimitiveType;
850 
851     GrGLTextureParameters::ResetTimestamp fResetTimestampForTextureParameters = 0;
852 
853     class SamplerObjectCache;
854     std::unique_ptr<SamplerObjectCache> fSamplerObjectCache;
855 
856     std::unique_ptr<GrGLOpsRenderPass> fCachedOpsRenderPass;
857 
858     std::unique_ptr<GrStagingBufferManager> fStagingBufferManager;
859 
860     GrGLFinishCallbacks fFinishCallbacks;
861 
862     // If we've called a command that requires us to call glFlush than this will be set to true
863     // since we defer calling flush until submit time. When we call submitToGpu if this is true then
864     // we call glFlush and reset this to false.
865     bool fNeedsGLFlush = false;
866 
867     SkDEBUGCODE(bool fIsExecutingCommandBuffer_DebugOnly = false;)
868 
869     friend class GrGLPathRendering; // For accessing setTextureUnit.
870 
871     using INHERITED = GrGpu;
872 };
873 
874 #endif
875