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