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