• 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/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     sk_sp<GrTexture> onCreateCompressedTexture(SkISize dimensions,
332                                                const GrBackendFormat&,
333                                                skgpu::Budgeted,
334                                                skgpu::Mipmapped,
335                                                GrProtected,
336                                                OH_NativeBuffer* nativeBuffer,
337                                                size_t bufferSize) override;
338 
339     sk_sp<GrGpuBuffer> onCreateBuffer(size_t size, GrGpuBufferType, GrAccessPattern) override;
340 
341     sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&,
342                                           GrWrapOwnership,
343                                           GrWrapCacheable,
344                                           GrIOType) override;
345     sk_sp<GrTexture> onWrapCompressedBackendTexture(const GrBackendTexture&,
346                                                     GrWrapOwnership,
347                                                     GrWrapCacheable) override;
348     sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&,
349                                                     int sampleCnt,
350                                                     GrWrapOwnership,
351                                                     GrWrapCacheable) override;
352     sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&) override;
353 
354     // Given a GL format return the index into the stencil format array on GrGLCaps to a
355     // compatible stencil format, or negative if there is no compatible stencil format.
356     int getCompatibleStencilIndex(GrGLFormat format);
357 
getPreferredStencilFormat(const GrBackendFormat & format)358     GrBackendFormat getPreferredStencilFormat(const GrBackendFormat& format) override {
359         int idx = this->getCompatibleStencilIndex(GrBackendFormats::AsGLFormat(format));
360         if (idx < 0) {
361             return {};
362         }
363         return GrBackendFormats::MakeGL(GrGLFormatToEnum(this->glCaps().stencilFormats()[idx]),
364                                         GR_GL_TEXTURE_NONE);
365     }
366 
367     void onFBOChanged();
368 
369     // Returns whether the texture is successfully created. On success, a non-zero texture ID is
370     // returned. On failure, zero is returned.
371     // The texture is populated with |texels|, if it is non-null.
372     // The texture parameters are cached in |initialTexParams|.
373     GrGLuint createTexture(SkISize dimensions,
374                            GrGLFormat,
375                            GrGLenum target,
376                            GrRenderable,
377                            GrGLTextureParameters::SamplerOverriddenState*,
378                            int mipLevelCount,
379                            GrProtected isProtected,
380                            std::string_view label);
381 
382     GrGLuint createCompressedTexture2D(SkISize dimensions,
383                                        SkTextureCompressionType compression,
384                                        GrGLFormat,
385                                        skgpu::Mipmapped,
386                                        GrProtected,
387                                        GrGLTextureParameters::SamplerOverriddenState*);
388 
389     bool onReadPixels(GrSurface*,
390                       SkIRect,
391                       GrColorType surfaceColorType,
392                       GrColorType dstColorType,
393                       void*,
394                       size_t rowBytes) override;
395 
396     bool onWritePixels(GrSurface*,
397                        SkIRect,
398                        GrColorType surfaceColorType,
399                        GrColorType srcColorType,
400                        const GrMipLevel[],
401                        int mipLevelCount,
402                        bool prepForTexSampling) override;
403 
404     bool onTransferFromBufferToBuffer(sk_sp<GrGpuBuffer> src,
405                                       size_t srcOffset,
406                                       sk_sp<GrGpuBuffer> dst,
407                                       size_t dstOffset,
408                                       size_t size) override;
409 
410     bool onTransferPixelsTo(GrTexture*,
411                             SkIRect,
412                             GrColorType textureColorType,
413                             GrColorType bufferColorType,
414                             sk_sp<GrGpuBuffer>,
415                             size_t offset,
416                             size_t rowBytes) override;
417 
418     bool onTransferPixelsFrom(GrSurface*,
419                               SkIRect,
420                               GrColorType surfaceColorType,
421                               GrColorType bufferColorType,
422                               sk_sp<GrGpuBuffer>,
423                               size_t offset) override;
424 
425     bool readOrTransferPixelsFrom(GrSurface*,
426                                   SkIRect rect,
427                                   GrColorType surfaceColorType,
428                                   GrColorType dstColorType,
429                                   void* offsetOrPtr,
430                                   int rowWidthInPixels);
431 
432     // Unbinds xfer buffers from GL for operations that don't need them.
433     // Before calling any variation of TexImage, TexSubImage, etc..., call this with
434     // GrGpuBufferType::kXferCpuToGpu to ensure that the PIXEL_UNPACK_BUFFER is unbound.
435     // Before calling ReadPixels and reading back into cpu memory call this with
436     // GrGpuBufferType::kXferGpuToCpu to ensure that the PIXEL_PACK_BUFFER is unbound.
437     void unbindXferBuffer(GrGpuBufferType type);
438 
439     void onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resolveRect) override;
440 
441     bool onRegenerateMipMapLevels(GrTexture*) override;
442 
443     bool onCopySurface(GrSurface* dst, const SkIRect& dstRect,
444                        GrSurface* src, const SkIRect& srcRect,
445                        GrSamplerState::Filter) override;
446 
447     // binds texture unit in GL
448     void setTextureUnit(int unitIdx);
449 
450     void flushBlendAndColorWrite(const skgpu::BlendInfo&, const skgpu::Swizzle&);
451 
452     void addFinishedCallback(skgpu::AutoCallback callback, std::optional<GrTimerQuery>) override;
453 
454     GrOpsRenderPass* onGetOpsRenderPass(
455             GrRenderTarget*,
456             bool useMultisampleFBO,
457             GrAttachment*,
458             GrSurfaceOrigin,
459             const SkIRect&,
460             const GrOpsRenderPass::LoadAndStoreInfo&,
461             const GrOpsRenderPass::StencilLoadAndStoreInfo&,
462             const skia_private::TArray<GrSurfaceProxy*, true>& sampledProxies,
463             GrXferBarrierFlags renderPassXferBarriers) override;
464 
465     bool onSubmitToGpu(const GrSubmitInfo& info) override;
466 
467     bool copySurfaceAsDraw(GrSurface* dst, bool drawToMultisampleFBO, GrSurface* src,
468                            const SkIRect& srcRect, const SkIRect& dstRect, GrSamplerState::Filter);
469     void copySurfaceAsCopyTexSubImage(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
470                                       const SkIPoint& dstPoint);
471     bool copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
472                                       const SkIRect& dstRect, GrSamplerState::Filter);
473 
474     class ProgramCache : public GrThreadSafePipelineBuilder {
475     public:
476         ProgramCache(int runtimeProgramCacheSize);
477         ~ProgramCache() override;
478 
479         void abandon();
480         void reset();
481         sk_sp<GrGLProgram> findOrCreateProgram(GrDirectContext*,
482                                                const GrProgramInfo&);
483         sk_sp<GrGLProgram> findOrCreateProgram(GrDirectContext*,
484                                                const GrProgramDesc&,
485                                                const GrProgramInfo&,
486                                                Stats::ProgramCacheResult*);
487         bool precompileShader(GrDirectContext*, const SkData& key, const SkData& data);
488 
489     private:
490         struct Entry;
491 
492         sk_sp<GrGLProgram> findOrCreateProgramImpl(GrDirectContext*,
493                                                    const GrProgramDesc&,
494                                                    const GrProgramInfo&,
495                                                    Stats::ProgramCacheResult*);
496 
497         struct DescHash {
operatorDescHash498             uint32_t operator()(const GrProgramDesc& desc) const {
499                 return SkChecksum::Hash32(desc.asKey(), desc.keyLength());
500             }
501         };
502 
503         SkLRUCache<GrProgramDesc, std::unique_ptr<Entry>, DescHash> fMap;
504     };
505 
506     void flushColorWrite(bool writeColor);
507     void flushClearColor(std::array<float, 4>);
508 
509     // flushes the scissor. see the note on flushBoundTextureAndParams about
510     // flushing the scissor after that function is called.
flushScissor(const GrScissorState & scissorState,int rtHeight,GrSurfaceOrigin rtOrigin)511     void flushScissor(const GrScissorState& scissorState, int rtHeight, GrSurfaceOrigin rtOrigin) {
512         this->flushScissorTest(GrScissorTest(scissorState.enabled()));
513         if (scissorState.enabled()) {
514             this->flushScissorRect(scissorState.rect(), rtHeight, rtOrigin);
515         }
516     }
517     void flushScissorTest(GrScissorTest);
518 
519     void flushWindowRectangles(const GrWindowRectsState&, const GrGLRenderTarget*, GrSurfaceOrigin);
520     void disableWindowRectangles();
521 
numTextureUnits()522     int numTextureUnits() const { return this->caps()->shaderCaps()->fMaxFragmentSamplers; }
523 
524     // Binds a texture to a target on the "scratch" texture unit to use for texture operations
525     // other than usual draw flow (i.e. a GrGLProgram derived from a GrPipeline used to draw). It
526     // ensures that such operations don't negatively interact with draws. The active texture unit
527     // and the binding for 'target' will change.
528     void bindTextureToScratchUnit(GrGLenum target, GrGLint textureID);
529 
530     void flushRenderTarget(GrGLRenderTarget*, bool useMultisampleFBO);
531 
532     void flushStencil(const GrStencilSettings&, GrSurfaceOrigin);
533     void disableStencil();
534 
535     void flushConservativeRasterState(bool enable);
536 
537     void flushWireframeState(bool enable);
538 
539     void flushFramebufferSRGB(bool enable);
540 
541     // Uploads src data of a color type to the currently bound texture on the active texture unit.
542     // The caller specifies color type that the texture is being used with, which may be different
543     // than the src color type. This fails if the combination of texture format, texture color type,
544     // and src data color type are not valid. No conversion is performed on the data before passing
545     // it to GL. 'dstRect' must be the texture bounds if mipLevelCount is greater than 1.
546     bool uploadColorTypeTexData(GrGLFormat textureFormat,
547                                 GrColorType textureColorType,
548                                 SkISize texDims,
549                                 GrGLenum target,
550                                 SkIRect dstRect,
551                                 GrColorType srcColorType,
552                                 const GrMipLevel texels[],
553                                 int mipLevelCount);
554 
555     // Uploads a constant color to a texture using the "default" format and color type. Overwrites
556     // entire levels. Bit n in 'levelMask' indicates whether level n should be written. This
557     // function doesn't know if MIP levels have been allocated, thus levelMask should not have bits
558     // beyond the low bit set if the texture is not MIP mapped.
559     bool uploadColorToTex(GrGLFormat textureFormat,
560                           SkISize texDims,
561                           GrGLenum target,
562                           std::array<float, 4> color,
563                           uint32_t levelMask);
564 
565     // Pushes data to the currently bound texture to the currently active unit. 'dstRect' must be
566     // the texture bounds if mipLevelCount is greater than 1.
567     void uploadTexData(SkISize dimensions,
568                        GrGLenum target,
569                        SkIRect dstRect,
570                        GrGLenum externalFormat,
571                        GrGLenum externalType,
572                        size_t bpp,
573                        const GrMipLevel texels[],
574                        int mipLevelCount);
575 
576     // Helper for onCreateCompressedTexture. Compressed textures are read-only so we only use this
577     // to populate a new texture. Returns false if we failed to create and upload the texture.
578     bool uploadCompressedTexData(SkTextureCompressionType compressionType,
579                                  GrGLFormat,
580                                  SkISize dimensions,
581                                  skgpu::Mipmapped,
582                                  GrGLenum target,
583                                  const void* data,
584                                  size_t dataSize);
585 
586     // Calls one of various versions of renderBufferStorageMultisample.
587     bool renderbufferStorageMSAA(const GrGLContext& ctx, int sampleCount, GrGLenum format,
588                                  int width, int height);
589 
590     bool createRenderTargetObjects(const GrGLTexture::Desc&,
591                                    int sampleCount,
592                                    GrGLRenderTarget::IDs*);
593     enum TempFBOTarget {
594         kSrc_TempFBOTarget,
595         kDst_TempFBOTarget
596     };
597 
598     // Binds a surface as a FBO for copying, reading, or clearing. If the surface already owns an
599     // FBO ID then that ID is bound. If not the surface is temporarily bound to a FBO and that FBO
600     // is bound. This must be paired with a call to unbindSurfaceFBOForPixelOps().
601     void bindSurfaceFBOForPixelOps(GrSurface* surface, int mipLevel, GrGLenum fboTarget,
602                                    TempFBOTarget tempFBOTarget);
603 
604     // Must be called if bindSurfaceFBOForPixelOps was used to bind a surface for copying.
605     void unbindSurfaceFBOForPixelOps(GrSurface* surface, int mipLevel, GrGLenum fboTarget);
606 
607 #ifdef SK_ENABLE_DUMP_GPU
608     void onDumpJSON(SkJSONWriter*) const override;
609 #endif
610 
611     bool createCopyProgram(GrTexture* srcTexture);
612     bool createMipmapProgram(int progIdx);
613 
614     std::unique_ptr<GrGLContext> fGLContext;
615 
616     // GL program-related state
617     sk_sp<ProgramCache>         fProgramCache;
618 
619     ///////////////////////////////////////////////////////////////////////////
620     ///@name Caching of GL State
621     ///@{
622     int                         fHWActiveTextureUnitIdx;
623 
624     GrGLuint                    fHWProgramID;
625     sk_sp<GrGLProgram>          fHWProgram;
626 
627     enum TriState {
628         kNo_TriState,
629         kYes_TriState,
630         kUnknown_TriState
631     };
632 
633     GrGLuint                    fTempSrcFBOID;
634     GrGLuint                    fTempDstFBOID;
635 
636     GrGLuint                    fStencilClearFBOID;
637 
638     // last scissor / viewport scissor state seen by the GL.
639     struct {
640         TriState fEnabled;
641         GrNativeRect fRect;
invalidate__anone4bd88b50108642         void invalidate() {
643             fEnabled = kUnknown_TriState;
644             fRect.invalidate();
645         }
646     } fHWScissorSettings;
647 
648     class HWWindowRectsState {
649     public:
valid()650         bool valid() const { return kInvalidSurfaceOrigin != fRTOrigin; }
invalidate()651         void invalidate() { fRTOrigin = kInvalidSurfaceOrigin; }
knownDisabled()652         bool knownDisabled() const { return this->valid() && !fWindowState.enabled(); }
setDisabled()653         void setDisabled() {
654             fRTOrigin = kTopLeft_GrSurfaceOrigin;
655             fWindowState.setDisabled();
656         }
657 
set(GrSurfaceOrigin rtOrigin,int width,int height,const GrWindowRectsState & windowState)658         void set(GrSurfaceOrigin rtOrigin, int width, int height,
659                  const GrWindowRectsState& windowState) {
660             fRTOrigin = rtOrigin;
661             fWidth = width;
662             fHeight = height;
663             fWindowState = windowState;
664         }
665 
knownEqualTo(GrSurfaceOrigin rtOrigin,int width,int height,const GrWindowRectsState & windowState)666         bool knownEqualTo(GrSurfaceOrigin rtOrigin, int width, int height,
667                           const GrWindowRectsState& windowState) const {
668             if (!this->valid()) {
669                 return false;
670             }
671             if (fWindowState.numWindows() &&
672                 (fRTOrigin != rtOrigin || fWidth != width || fHeight != height)) {
673                 return false;
674             }
675             return fWindowState == windowState;
676         }
677 
678     private:
679         static constexpr int kInvalidSurfaceOrigin = -1;
680 
681         int                  fRTOrigin;
682         int                  fWidth;
683         int                  fHeight;
684         GrWindowRectsState   fWindowState;
685     };
686     HWWindowRectsState fHWWindowRectsState;
687 
688     GrNativeRect fHWViewport;
689 
690     /**
691      * Tracks vertex attrib array state.
692      */
693     class HWVertexArrayState {
694     public:
HWVertexArrayState()695         HWVertexArrayState() : fCoreProfileVertexArray(nullptr) { this->invalidate(); }
696 
~HWVertexArrayState()697         ~HWVertexArrayState() { delete fCoreProfileVertexArray; }
698 
invalidate()699         void invalidate() {
700             fBoundVertexArrayIDIsValid = false;
701             fDefaultVertexArrayAttribState.invalidate();
702             if (fCoreProfileVertexArray) {
703                 fCoreProfileVertexArray->invalidateCachedState();
704             }
705         }
706 
notifyVertexArrayDelete(GrGLuint id)707         void notifyVertexArrayDelete(GrGLuint id) {
708             if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) {
709                 // Does implicit bind to 0
710                 fBoundVertexArrayID = 0;
711             }
712         }
713 
setVertexArrayID(GrGLGpu * gpu,GrGLuint arrayID)714         void setVertexArrayID(GrGLGpu* gpu, GrGLuint arrayID) {
715             if (!gpu->glCaps().vertexArrayObjectSupport()) {
716                 SkASSERT(0 == arrayID);
717                 return;
718             }
719             if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) {
720                 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID));
721                 fBoundVertexArrayIDIsValid = true;
722                 fBoundVertexArrayID = arrayID;
723             }
724         }
725 
726         /**
727          * Binds the vertex array that should be used for internal draws, and returns its attrib
728          * state. This binds the default VAO (ID=zero) unless we are on a core profile, in which
729          * case we use a placeholder array instead.
730          *
731          * If an index buffer is provided, it will be bound to the vertex array. Otherwise the
732          * index buffer binding will be left unchanged.
733          *
734          * The returned GrGLAttribArrayState should be used to set vertex attribute arrays.
735          */
736         GrGLAttribArrayState* bindInternalVertexArray(GrGLGpu*, const GrBuffer* ibuff = nullptr);
737 
738     private:
739         GrGLuint             fBoundVertexArrayID;
740         bool                 fBoundVertexArrayIDIsValid;
741 
742         // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0
743         // is bound. However, this class is internal to GrGLGpu and this object never leaks out of
744         // GrGLGpu.
745         GrGLAttribArrayState fDefaultVertexArrayAttribState;
746 
747         // This is used when we're using a core profile.
748         GrGLVertexArray*     fCoreProfileVertexArray;
749     } fHWVertexArrayState;
750 
751     struct {
752         GrGLenum                fGLTarget;
753         GrGpuResource::UniqueID fBoundBufferUniqueID;
754         bool                    fBufferZeroKnownBound;
755 
invalidate__anone4bd88b50208756         void invalidate() {
757             fBoundBufferUniqueID.makeInvalid();
758             fBufferZeroKnownBound = false;
759         }
760     }                                       fHWBufferState[kGrGpuBufferTypeCount];
761 
hwBufferState(GrGpuBufferType type)762     auto* hwBufferState(GrGpuBufferType type) {
763         unsigned typeAsUInt = static_cast<unsigned>(type);
764         SkASSERT(typeAsUInt < std::size(fHWBufferState));
765         SkASSERT(type != GrGpuBufferType::kUniform);
766         return &fHWBufferState[typeAsUInt];
767     }
768 
769     enum class FlushType {
770         kIfRequired,
771         kForce,
772     };
773 
774     // This calls glFlush if it is required for previous operations or kForce is passed.
775     void flush(FlushType flushType = FlushType::kIfRequired);
776 
setNeedsFlush()777     void setNeedsFlush() { fNeedsGLFlush = true; }
778 
779     struct {
780         skgpu::BlendEquation fEquation;
781         skgpu::BlendCoeff    fSrcCoeff;
782         skgpu::BlendCoeff    fDstCoeff;
783         SkPMColor4f          fConstColor;
784         bool                 fConstColorValid;
785         TriState             fEnabled;
786 
invalidate__anone4bd88b50308787         void invalidate() {
788             fEquation = skgpu::BlendEquation::kIllegal;
789             fSrcCoeff = skgpu::BlendCoeff::kIllegal;
790             fDstCoeff = skgpu::BlendCoeff::kIllegal;
791             fConstColorValid = false;
792             fEnabled = kUnknown_TriState;
793         }
794     }                                       fHWBlendState;
795 
796     TriState                                fHWConservativeRasterEnabled;
797 
798     TriState                                fHWWireframeEnabled;
799 
800     GrStencilSettings                       fHWStencilSettings;
801     GrSurfaceOrigin                         fHWStencilOrigin;
802     TriState                                fHWStencilTestEnabled;
803 
804     TriState                                fHWWriteToColor;
805     GrGpuResource::UniqueID                 fHWBoundRenderTargetUniqueID;
806     bool                                    fHWBoundFramebufferIsMSAA;
807     TriState                                fHWSRGBFramebuffer;
808 
809     class TextureUnitBindings {
810     public:
811         TextureUnitBindings() = default;
812         TextureUnitBindings(const TextureUnitBindings&) = delete;
813         TextureUnitBindings& operator=(const TextureUnitBindings&) = delete;
814 
815         GrGpuResource::UniqueID boundID(GrGLenum target) const;
816         bool hasBeenModified(GrGLenum target) const;
817         void setBoundID(GrGLenum target, GrGpuResource::UniqueID);
818         void invalidateForScratchUse(GrGLenum target);
819         void invalidateAllTargets(bool markUnmodified);
820 
821     private:
822         struct TargetBinding {
823             GrGpuResource::UniqueID fBoundResourceID;
824             bool fHasBeenModified = false;
825         };
826         TargetBinding fTargetBindings[3];
827     };
828     skia_private::AutoTArray<TextureUnitBindings> fHWTextureUnitBindings;
829 
830     GrGLfloat fHWClearColor[4];
831 
832     GrGLuint fBoundDrawFramebuffer = 0;
833 
834     /** IDs for copy surface program. (3 sampler types) */
835     struct {
836         GrGLuint    fProgram = 0;
837         GrGLint     fTextureUniform = 0;
838         GrGLint     fTexCoordXformUniform = 0;
839         GrGLint     fPosXformUniform = 0;
840     }                                       fCopyPrograms[3];
841     sk_sp<GrGLBuffer>                       fCopyProgramArrayBuffer;
842 
843     /** IDs for texture mipmap program. (4 filter configurations) */
844     struct {
845         GrGLuint    fProgram = 0;
846         GrGLint     fTextureUniform = 0;
847         GrGLint     fTexCoordXformUniform = 0;
848     }                                       fMipmapPrograms[4];
849     sk_sp<GrGLBuffer>                       fMipmapProgramArrayBuffer;
850 
851     static int TextureToCopyProgramIdx(GrTexture* texture);
852 
TextureSizeToMipmapProgramIdx(int width,int height)853     static int TextureSizeToMipmapProgramIdx(int width, int height) {
854         const bool wide = (width > 1) && SkToBool(width & 0x1);
855         const bool tall = (height > 1) && SkToBool(height & 0x1);
856         return (wide ? 0x2 : 0x0) | (tall ? 0x1 : 0x0);
857     }
858 
859     GrPrimitiveType fLastPrimitiveType;
860 
861     GrGLTextureParameters::ResetTimestamp fResetTimestampForTextureParameters = 0;
862 
863     class SamplerObjectCache;
864     std::unique_ptr<SamplerObjectCache> fSamplerObjectCache;
865 
866     std::unique_ptr<GrGLOpsRenderPass> fCachedOpsRenderPass;
867 
868     std::unique_ptr<GrStagingBufferManager> fStagingBufferManager;
869 
870     GrGLFinishCallbacks fFinishCallbacks;
871 
872     // If we've called a command that requires us to call glFlush than this will be set to true
873     // since we defer calling flush until submit time. When we call submitToGpu if this is true then
874     // we call glFlush and reset this to false.
875     bool fNeedsGLFlush = false;
876 
877     SkDEBUGCODE(bool fIsExecutingCommandBuffer_DebugOnly = false;)
878 
879     friend class GrGLPathRendering; // For accessing setTextureUnit.
880 
881     using INHERITED = GrGpu;
882 };
883 
884 #endif
885