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