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