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