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 <list>
12 #include "include/core/SkTypes.h"
13 #include "include/private/SkTArray.h"
14 #include "src/core/SkLRUCache.h"
15 #include "src/gpu/GrGpu.h"
16 #include "src/gpu/GrMesh.h"
17 #include "src/gpu/GrNativeRect.h"
18 #include "src/gpu/GrWindowRectsState.h"
19 #include "src/gpu/GrXferProcessor.h"
20 #include "src/gpu/gl/GrGLContext.h"
21 #include "src/gpu/gl/GrGLPathRendering.h"
22 #include "src/gpu/gl/GrGLProgram.h"
23 #include "src/gpu/gl/GrGLRenderTarget.h"
24 #include "src/gpu/gl/GrGLStencilAttachment.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, private GrMesh::SendToGpuImpl {
34 public:
35     static sk_sp<GrGpu> Make(sk_sp<const GrGLInterface>, const GrContextOptions&, GrContext*);
36     ~GrGLGpu() override;
37 
38     void disconnect(DisconnectType) override;
39 
glContext()40     const GrGLContext& glContext() const { return *fGLContext; }
41 
glInterface()42     const GrGLInterface* glInterface() const { return fGLContext->interface(); }
ctxInfo()43     const GrGLContextInfo& ctxInfo() const { return *fGLContext; }
glStandard()44     GrGLStandard glStandard() const { return fGLContext->standard(); }
glVersion()45     GrGLVersion glVersion() const { return fGLContext->version(); }
glslGeneration()46     GrGLSLGeneration glslGeneration() const { return fGLContext->glslGeneration(); }
glCaps()47     const GrGLCaps& glCaps() const { return *fGLContext->caps(); }
48 
glPathRendering()49     GrGLPathRendering* glPathRendering() {
50         SkASSERT(glCaps().shaderCaps()->pathRenderingSupport());
51         return static_cast<GrGLPathRendering*>(pathRendering());
52     }
53 
54     // Used by GrGLProgram to configure OpenGL state.
55     void bindTexture(int unitIdx, GrSamplerState samplerState, const GrSwizzle&, GrGLTexture*);
56 
57     // These functions should be used to bind GL objects. They track the GL state and skip redundant
58     // bindings. Making the equivalent glBind calls directly will confuse the state tracking.
bindVertexArray(GrGLuint id)59     void bindVertexArray(GrGLuint id) {
60         fHWVertexArrayState.setVertexArrayID(this, id);
61     }
62 
63     // These callbacks update state tracking when GL objects are deleted. They are called from
64     // GrGLResource onRelease functions.
notifyVertexArrayDelete(GrGLuint id)65     void notifyVertexArrayDelete(GrGLuint id) {
66         fHWVertexArrayState.notifyVertexArrayDelete(id);
67     }
68 
69     // Binds a buffer to the GL target corresponding to 'type', updates internal state tracking, and
70     // returns the GL target the buffer was bound to.
71     // When 'type' is kIndex_GrBufferType, this function will also implicitly bind the default VAO.
72     // If the caller wishes to bind an index buffer to a specific VAO, it can call glBind directly.
73     GrGLenum bindBuffer(GrGpuBufferType type, const GrBuffer*);
74 
75     // The GrGLOpsRenderPass does not buffer up draws before submitting them to the gpu.
76     // Thus this is the implementation of the draw call for the corresponding passthrough function
77     // on GrGLOpsRenderPass.
78     void draw(GrRenderTarget*, const GrProgramInfo&, const GrMesh[], int meshCount);
79 
80     // GrMesh::SendToGpuImpl methods. These issue the actual GL draw calls.
81     // Marked final as a hint to the compiler to not use virtual dispatch.
82     void sendMeshToGpu(GrPrimitiveType, const GrBuffer* vertexBuffer, int vertexCount,
83                        int baseVertex) final;
84 
85     void sendIndexedMeshToGpu(GrPrimitiveType, const GrBuffer* indexBuffer, int indexCount,
86                               int baseIndex, uint16_t minIndexValue, uint16_t maxIndexValue,
87                               const GrBuffer* vertexBuffer, int baseVertex,
88                               GrPrimitiveRestart) final;
89 
90     void sendInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* vertexBuffer, int vertexCount,
91                                 int baseVertex, const GrBuffer* instanceBuffer, int instanceCount,
92                                 int baseInstance) final;
93 
94     void sendIndexedInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* indexBuffer, int indexCount,
95                                        int baseIndex, const GrBuffer* vertexBuffer, int baseVertex,
96                                        const GrBuffer* instanceBuffer, int instanceCount,
97                                        int baseInstance, GrPrimitiveRestart) final;
98 
99     // The GrGLOpsRenderPass does not buffer up draws before submitting them to the gpu.
100     // Thus this is the implementation of the clear call for the corresponding passthrough function
101     // on GrGLOpsRenderPass.
102     void clear(const GrFixedClip&, const SkPMColor4f&, GrRenderTarget*, GrSurfaceOrigin);
103 
104     // The GrGLOpsRenderPass does not buffer up draws before submitting them to the gpu.
105     // Thus this is the implementation of the clearStencil call for the corresponding passthrough
106     // function on GrGLOpsrenderPass.
107     void clearStencilClip(const GrFixedClip&, bool insideStencilMask,
108                           GrRenderTarget*, GrSurfaceOrigin);
109 
110     // FIXME (michaelludwig): Can this go away and just use clearStencilClip() + marking the
111     // stencil buffer as not dirty?
112     void clearStencil(GrRenderTarget*, int clearValue);
113 
114     void beginCommandBuffer(GrRenderTarget*, const SkIRect& bounds, GrSurfaceOrigin,
115                             const GrOpsRenderPass::LoadAndStoreInfo& colorLoadStore,
116                             const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilLoadStore);
117 
118     void endCommandBuffer(GrRenderTarget*, const GrOpsRenderPass::LoadAndStoreInfo& colorLoadStore,
119                           const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilLoadStore);
120 
121     GrOpsRenderPass* getOpsRenderPass(
122             GrRenderTarget*, GrSurfaceOrigin, const SkIRect&,
123             const GrOpsRenderPass::LoadAndStoreInfo&,
124             const GrOpsRenderPass::StencilLoadAndStoreInfo&,
125             const SkTArray<GrTextureProxy*, true>& sampledProxies) override;
126 
invalidateBoundRenderTarget()127     void invalidateBoundRenderTarget() {
128         fHWBoundRenderTargetUniqueID.makeInvalid();
129     }
130 
131     GrStencilAttachment* createStencilAttachmentForRenderTarget(
132             const GrRenderTarget* rt, int width, int height, int numStencilSamples) override;
133     void deleteBackendTexture(const GrBackendTexture&) override;
134 
precompileShader(const SkData & key,const SkData & data)135     bool precompileShader(const SkData& key, const SkData& data) override {
136         return fProgramCache->precompileShader(key, data);
137     }
138 
139 #if GR_TEST_UTILS
140     bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override;
141 
142     GrBackendRenderTarget createTestingOnlyBackendRenderTarget(int w, int h, GrColorType) override;
143     void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override;
144 
glContextForTesting()145     const GrGLContext* glContextForTesting() const override { return &this->glContext(); }
146 
resetShaderCacheForTesting()147     void resetShaderCacheForTesting() const override { fProgramCache->reset(); }
148 
149     void testingOnly_flushGpuAndSync() override;
150 #endif
151 
152     void submit(GrOpsRenderPass* renderPass) override;
153 
154     GrFence SK_WARN_UNUSED_RESULT insertFence() override;
155     bool waitFence(GrFence, uint64_t timeout) override;
156     void deleteFence(GrFence) const override;
157 
158     sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned) override;
159     sk_sp<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
160                                             GrResourceProvider::SemaphoreWrapType wrapType,
161                                             GrWrapOwnership ownership) override;
162     void insertSemaphore(sk_sp<GrSemaphore> semaphore) override;
163     void waitSemaphore(sk_sp<GrSemaphore> semaphore) override;
164 
165     void checkFinishProcs() override;
166 
167     sk_sp<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override;
168 
169     void deleteSync(GrGLsync) const;
170 
171     void insertEventMarker(const char*);
172 
173     void bindFramebuffer(GrGLenum fboTarget, GrGLuint fboid);
174     void deleteFramebuffer(GrGLuint fboid);
175 
176 private:
177     GrGLGpu(std::unique_ptr<GrGLContext>, GrContext*);
178 
179     // GrGpu overrides
180     GrBackendTexture onCreateBackendTexture(int w, int h, const GrBackendFormat&,
181                                             GrMipMapped, GrRenderable,
182                                             const SkPixmap srcData[], int numMipLevels,
183                                             const SkColor4f* color, GrProtected) override;
184 
185     void onResetContext(uint32_t resetBits) override;
186 
187     void onResetTextureBindings() override;
188 
189     void querySampleLocations(GrRenderTarget*, SkTArray<SkPoint>*) override;
190 
191     void xferBarrier(GrRenderTarget*, GrXferBarrierType) override;
192 
193     sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc&,
194                                      const GrBackendFormat&,
195                                      GrRenderable,
196                                      int renderTargetSampleCnt,
197                                      SkBudgeted,
198                                      GrProtected,
199                                      int mipLevelCount,
200                                      uint32_t levelClearMask) override;
201     sk_sp<GrTexture> onCreateCompressedTexture(int width, int height, const GrBackendFormat&,
202                                                SkImage::CompressionType compression, SkBudgeted,
203                                                const void* data) override;
204 
205     sk_sp<GrGpuBuffer> onCreateBuffer(size_t size, GrGpuBufferType intendedType, GrAccessPattern,
206                                       const void* data) override;
207 
208     sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrColorType, GrWrapOwnership,
209                                           GrWrapCacheable, GrIOType) override;
210     sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&, int sampleCnt,
211                                                     GrColorType, GrWrapOwnership,
212                                                     GrWrapCacheable) override;
213     sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&,
214                                                     GrColorType) override;
215     sk_sp<GrRenderTarget> onWrapBackendTextureAsRenderTarget(const GrBackendTexture&,
216                                                              int sampleCnt, GrColorType) override;
217 
218     // Given a GL format return the index into the stencil format array on GrGLCaps to a
219     // compatible stencil format, or negative if there is no compatible stencil format.
220     int getCompatibleStencilIndex(GrGLFormat format);
221 
222     void onFBOChanged();
223 
224     // Returns whether the texture is successfully created. On success, a non-zero texture ID is
225     // returned. On failure, zero is returned.
226     // The texture is populated with |texels|, if it is non-null.
227     // The texture parameters are cached in |initialTexParams|.
228     GrGLuint createTexture2D(const SkISize& size,
229                              GrGLFormat format,
230                              GrRenderable,
231                              GrGLTextureParameters::SamplerOverriddenState* initialState,
232                              int mipLevelCount);
233 
234     GrGLuint createCompressedTexture2D(const SkISize& size, GrGLFormat format,
235                                        SkImage::CompressionType compression,
236                                        GrGLTextureParameters::SamplerOverriddenState* initialState,
237                                        const void* data);
238 
239     bool onReadPixels(GrSurface*, int left, int top, int width, int height,
240                       GrColorType surfaceColorType, GrColorType dstColorType, void* buffer,
241                       size_t rowBytes) override;
242 
243     bool onWritePixels(GrSurface*, int left, int top, int width, int height,
244                        GrColorType surfaceColorType, GrColorType srcColorType,
245                        const GrMipLevel texels[], int mipLevelCount,
246                        bool prepForTexSampling) override;
247 
248     bool onTransferPixelsTo(GrTexture*, int left, int top, int width, int height,
249                             GrColorType textureColorType, GrColorType bufferColorType,
250                             GrGpuBuffer* transferBuffer, size_t offset, size_t rowBytes) override;
251     bool onTransferPixelsFrom(GrSurface*, int left, int top, int width, int height,
252                               GrColorType surfaceColorType, GrColorType bufferColorType,
253                               GrGpuBuffer* transferBuffer, size_t offset) override;
254     bool readOrTransferPixelsFrom(GrSurface*, int left, int top, int width, int height,
255                                   GrColorType surfaceColorType, GrColorType dstColorType,
256                                   void* offsetOrPtr, int rowWidthInPixels);
257 
258     // Before calling any variation of TexImage, TexSubImage, etc..., call this to ensure that the
259     // PIXEL_UNPACK_BUFFER is unbound.
260     void unbindCpuToGpuXferBuffer();
261 
262     void onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resolveRect,
263                                GrSurfaceOrigin resolveOrigin, ForExternalIO) override;
264 
265     bool onRegenerateMipMapLevels(GrTexture*) override;
266 
267     bool onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
268                        const SkIPoint& dstPoint) override;
269 
270     // binds texture unit in GL
271     void setTextureUnit(int unitIdx);
272 
273     // Flushes state from GrPipeline to GL. Returns false if the state couldn't be set.
274     // willDrawPoints must be true if point primitives will be rendered after setting the GL state.
275     // If DynamicStateArrays is not null then dynamicStateArraysLength is the number of dynamic
276     // state entries in each array.
277     bool flushGLState(GrRenderTarget*, const GrProgramInfo&, GrPrimitiveType);
278 
279     void flushProgram(sk_sp<GrGLProgram>);
280 
281     // Version for programs that aren't GrGLProgram.
282     void flushProgram(GrGLuint);
283 
284     // Sets up vertex/instance attribute pointers and strides.
285     void setupGeometry(const GrBuffer* indexBuffer,
286                        const GrBuffer* vertexBuffer,
287                        int baseVertex,
288                        const GrBuffer* instanceBuffer,
289                        int baseInstance,
290                        GrPrimitiveRestart);
291 
292     void flushBlendAndColorWrite(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle&);
293 
294     void onFinishFlush(GrSurfaceProxy*[], int n, SkSurface::BackendSurfaceAccess access,
295                        const GrFlushInfo&, const GrPrepareForExternalIORequests&) override;
296 
297     bool waitSync(GrGLsync, uint64_t timeout, bool flush);
298 
299     bool copySurfaceAsDraw(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
300                            const SkIPoint& dstPoint);
301     void copySurfaceAsCopyTexSubImage(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
302                                       const SkIPoint& dstPoint);
303     bool copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
304                                       const SkIPoint& dstPoint);
305 
306     static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
307 
308     class ProgramCache : public ::SkNoncopyable {
309     public:
310         ProgramCache(GrGLGpu* gpu);
311         ~ProgramCache();
312 
313         void abandon();
314         void reset();
315         GrGLProgram* refProgram(GrGLGpu*, GrRenderTarget*, const GrProgramInfo&, GrPrimitiveType);
316         bool precompileShader(const SkData& key, const SkData& data);
317 
318     private:
319         struct Entry;
320 
321         struct DescHash {
operatorDescHash322             uint32_t operator()(const GrProgramDesc& desc) const {
323                 return SkOpts::hash_fn(desc.asKey(), desc.keyLength(), 0);
324             }
325         };
326 
327         SkLRUCache<GrProgramDesc, std::unique_ptr<Entry>, DescHash> fMap;
328 
329         GrGLGpu* fGpu;
330     };
331 
332     void flushColorWrite(bool writeColor);
333     void flushClearColor(const SkPMColor4f&);
334 
335     // flushes the scissor. see the note on flushBoundTextureAndParams about
336     // flushing the scissor after that function is called.
337     void flushScissor(const GrScissorState&, int rtWidth, int rtHeight, GrSurfaceOrigin rtOrigin);
338 
339     // disables the scissor
340     void disableScissor();
341 
342     void flushWindowRectangles(const GrWindowRectsState&, const GrGLRenderTarget*, GrSurfaceOrigin);
343     void disableWindowRectangles();
344 
numTextureUnits()345     int numTextureUnits() const { return this->caps()->shaderCaps()->maxFragmentSamplers(); }
346 
347     // Binds a texture to a target on the "scratch" texture unit to use for texture operations
348     // other than usual draw flow (i.e. a GrGLProgram derived from a GrPipeline used to draw
349     // GrMesh). It ensures that such operations don't negatively interact with draws.
350     // The active texture unit and the binding for 'target' will change.
351     void bindTextureToScratchUnit(GrGLenum target, GrGLint textureID);
352 
353     // The passed bounds contains the render target's color values that will subsequently be
354     // written.
355     void flushRenderTarget(GrGLRenderTarget*, GrSurfaceOrigin, const SkIRect& bounds);
356     // This version has an implicit bounds of the entire render target.
357     void flushRenderTarget(GrGLRenderTarget*);
358     // This version can be used when the render target's colors will not be written.
359     void flushRenderTargetNoColorWrites(GrGLRenderTarget*);
360 
361     // Need not be called if flushRenderTarget is used.
362     void flushViewport(int width, int height);
363 
364     void flushStencil(const GrStencilSettings&, GrSurfaceOrigin);
365     void disableStencil();
366 
367     // rt is used only if useHWAA is true.
368     void flushHWAAState(GrRenderTarget* rt, bool useHWAA);
369 
370     void flushFramebufferSRGB(bool enable);
371 
372     bool uploadTexData(GrGLFormat textureFormat, GrColorType textureColorType, int texWidth,
373                        int texHeight, GrGLenum target, int left, int top, int width, int height,
374                        GrColorType srcColorType, const GrMipLevel texels[], int mipLevelCount,
375                        GrMipMapsStatus* mipMapsStatus = nullptr);
376 
377     // Helper for onCreateCompressedTexture. Compressed textures are read-only so we only use this
378     // to populate a new texture. Returns false if we failed to create and upload the texture.
379     bool uploadCompressedTexData(GrGLFormat,
380                                  SkImage::CompressionType,
381                                  const SkISize& size,
382                                  GrGLenum target,
383                                  const void* data);
384 
385     bool createRenderTargetObjects(const GrGLTexture::Desc&,
386                                    int sampleCount,
387                                    GrGLRenderTarget::IDs*);
388 
389     enum TempFBOTarget {
390         kSrc_TempFBOTarget,
391         kDst_TempFBOTarget
392     };
393 
394     // Binds a surface as a FBO for copying, reading, or clearing. If the surface already owns an
395     // FBO ID then that ID is bound. If not the surface is temporarily bound to a FBO and that FBO
396     // is bound. This must be paired with a call to unbindSurfaceFBOForPixelOps().
397     void bindSurfaceFBOForPixelOps(GrSurface* surface, int mipLevel, GrGLenum fboTarget,
398                                    TempFBOTarget tempFBOTarget);
399 
400     // Must be called if bindSurfaceFBOForPixelOps was used to bind a surface for copying.
401     void unbindSurfaceFBOForPixelOps(GrSurface* surface, int mipLevel, GrGLenum fboTarget);
402 
403 #ifdef SK_ENABLE_DUMP_GPU
404     void onDumpJSON(SkJSONWriter*) const override;
405 #endif
406 
407     bool createCopyProgram(GrTexture* srcTexture);
408     bool createMipmapProgram(int progIdx);
409 
410     std::unique_ptr<GrGLContext> fGLContext;
411 
412     // GL program-related state
413     ProgramCache*               fProgramCache;
414 
415     ///////////////////////////////////////////////////////////////////////////
416     ///@name Caching of GL State
417     ///@{
418     int                         fHWActiveTextureUnitIdx;
419 
420     GrGLuint                    fHWProgramID;
421     sk_sp<GrGLProgram>          fHWProgram;
422 
423     enum TriState {
424         kNo_TriState,
425         kYes_TriState,
426         kUnknown_TriState
427     };
428 
429     GrGLuint                    fTempSrcFBOID;
430     GrGLuint                    fTempDstFBOID;
431 
432     GrGLuint                    fStencilClearFBOID;
433 
434     // last scissor / viewport scissor state seen by the GL.
435     struct {
436         TriState fEnabled;
437         GrNativeRect fRect;
invalidate__anon6ffece3a0108438         void invalidate() {
439             fEnabled = kUnknown_TriState;
440             fRect.invalidate();
441         }
442     } fHWScissorSettings;
443 
444     class {
445     public:
valid()446         bool valid() const { return kInvalidSurfaceOrigin != fRTOrigin; }
invalidate()447         void invalidate() { fRTOrigin = kInvalidSurfaceOrigin; }
knownDisabled()448         bool knownDisabled() const { return this->valid() && !fWindowState.enabled(); }
setDisabled()449         void setDisabled() {
450             fRTOrigin = kTopLeft_GrSurfaceOrigin;
451             fWindowState.setDisabled();
452         }
453 
set(GrSurfaceOrigin rtOrigin,int width,int height,const GrWindowRectsState & windowState)454         void set(GrSurfaceOrigin rtOrigin, int width, int height,
455                  const GrWindowRectsState& windowState) {
456             fRTOrigin = rtOrigin;
457             fWidth = width;
458             fHeight = height;
459             fWindowState = windowState;
460         }
461 
knownEqualTo(GrSurfaceOrigin rtOrigin,int width,int height,const GrWindowRectsState & windowState)462         bool knownEqualTo(GrSurfaceOrigin rtOrigin, int width, int height,
463                           const GrWindowRectsState& windowState) const {
464             if (!this->valid()) {
465                 return false;
466             }
467             if (fWindowState.numWindows() &&
468                 (fRTOrigin != rtOrigin || fWidth != width || fHeight != height)) {
469                 return false;
470             }
471             return fWindowState == windowState;
472         }
473 
474     private:
475         enum { kInvalidSurfaceOrigin = -1 };
476 
477         int                  fRTOrigin;
478         int                  fWidth;
479         int                  fHeight;
480         GrWindowRectsState   fWindowState;
481     } fHWWindowRectsState;
482 
483     GrNativeRect fHWViewport;
484 
485     /**
486      * Tracks vertex attrib array state.
487      */
488     class HWVertexArrayState {
489     public:
HWVertexArrayState()490         HWVertexArrayState() : fCoreProfileVertexArray(nullptr) { this->invalidate(); }
491 
~HWVertexArrayState()492         ~HWVertexArrayState() { delete fCoreProfileVertexArray; }
493 
invalidate()494         void invalidate() {
495             fBoundVertexArrayIDIsValid = false;
496             fDefaultVertexArrayAttribState.invalidate();
497             if (fCoreProfileVertexArray) {
498                 fCoreProfileVertexArray->invalidateCachedState();
499             }
500         }
501 
notifyVertexArrayDelete(GrGLuint id)502         void notifyVertexArrayDelete(GrGLuint id) {
503             if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) {
504                 // Does implicit bind to 0
505                 fBoundVertexArrayID = 0;
506             }
507         }
508 
setVertexArrayID(GrGLGpu * gpu,GrGLuint arrayID)509         void setVertexArrayID(GrGLGpu* gpu, GrGLuint arrayID) {
510             if (!gpu->glCaps().vertexArrayObjectSupport()) {
511                 SkASSERT(0 == arrayID);
512                 return;
513             }
514             if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) {
515                 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID));
516                 fBoundVertexArrayIDIsValid = true;
517                 fBoundVertexArrayID = arrayID;
518             }
519         }
520 
521         /**
522          * Binds the vertex array that should be used for internal draws, and returns its attrib
523          * state. This binds the default VAO (ID=zero) unless we are on a core profile, in which
524          * case we use a dummy array instead.
525          *
526          * If an index buffer is privided, it will be bound to the vertex array. Otherwise the
527          * index buffer binding will be left unchanged.
528          *
529          * The returned GrGLAttribArrayState should be used to set vertex attribute arrays.
530          */
531         GrGLAttribArrayState* bindInternalVertexArray(GrGLGpu*, const GrBuffer* ibuff = nullptr);
532 
533     private:
534         GrGLuint             fBoundVertexArrayID;
535         bool                 fBoundVertexArrayIDIsValid;
536 
537         // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0
538         // is bound. However, this class is internal to GrGLGpu and this object never leaks out of
539         // GrGLGpu.
540         GrGLAttribArrayState fDefaultVertexArrayAttribState;
541 
542         // This is used when we're using a core profile.
543         GrGLVertexArray*     fCoreProfileVertexArray;
544     }                                       fHWVertexArrayState;
545 
546     struct {
547         GrGLenum                fGLTarget;
548         GrGpuResource::UniqueID fBoundBufferUniqueID;
549         bool                    fBufferZeroKnownBound;
550 
invalidate__anon6ffece3a0308551         void invalidate() {
552             fBoundBufferUniqueID.makeInvalid();
553             fBufferZeroKnownBound = false;
554         }
555     }                                       fHWBufferState[kGrGpuBufferTypeCount];
556 
hwBufferState(GrGpuBufferType type)557     auto* hwBufferState(GrGpuBufferType type) {
558         unsigned typeAsUInt = static_cast<unsigned>(type);
559         SkASSERT(typeAsUInt < SK_ARRAY_COUNT(fHWBufferState));
560         return &fHWBufferState[typeAsUInt];
561     }
562 
563     struct {
564         GrBlendEquation fEquation;
565         GrBlendCoeff    fSrcCoeff;
566         GrBlendCoeff    fDstCoeff;
567         SkPMColor4f     fConstColor;
568         bool            fConstColorValid;
569         TriState        fEnabled;
570 
invalidate__anon6ffece3a0408571         void invalidate() {
572             fEquation = kIllegal_GrBlendEquation;
573             fSrcCoeff = kIllegal_GrBlendCoeff;
574             fDstCoeff = kIllegal_GrBlendCoeff;
575             fConstColorValid = false;
576             fEnabled = kUnknown_TriState;
577         }
578     }                                       fHWBlendState;
579 
580     TriState                                fMSAAEnabled;
581 
582     GrStencilSettings                       fHWStencilSettings;
583     GrSurfaceOrigin                         fHWStencilOrigin;
584     TriState                                fHWStencilTestEnabled;
585 
586 
587     TriState                                fHWWriteToColor;
588     GrGpuResource::UniqueID                 fHWBoundRenderTargetUniqueID;
589     TriState                                fHWSRGBFramebuffer;
590 
591     class TextureUnitBindings {
592     public:
593         TextureUnitBindings() = default;
594         TextureUnitBindings(const TextureUnitBindings&) = delete;
595         TextureUnitBindings& operator=(const TextureUnitBindings&) = delete;
596 
597         GrGpuResource::UniqueID boundID(GrGLenum target) const;
598         bool hasBeenModified(GrGLenum target) const;
599         void setBoundID(GrGLenum target, GrGpuResource::UniqueID);
600         void invalidateForScratchUse(GrGLenum target);
601         void invalidateAllTargets(bool markUnmodified);
602 
603     private:
604         struct TargetBinding {
605             GrGpuResource::UniqueID fBoundResourceID;
606             bool fHasBeenModified = false;
607         };
608         TargetBinding fTargetBindings[3];
609     };
610     SkAutoTArray<TextureUnitBindings> fHWTextureUnitBindings;
611 
612     GrGLfloat fHWClearColor[4];
613 
614     GrGLuint fBoundDrawFramebuffer = 0;
615 
616     /** IDs for copy surface program. (3 sampler types) */
617     struct {
618         GrGLuint    fProgram = 0;
619         GrGLint     fTextureUniform = 0;
620         GrGLint     fTexCoordXformUniform = 0;
621         GrGLint     fPosXformUniform = 0;
622     }                                       fCopyPrograms[3];
623     sk_sp<GrGLBuffer>                       fCopyProgramArrayBuffer;
624 
625     /** IDs for texture mipmap program. (4 filter configurations) */
626     struct {
627         GrGLuint    fProgram = 0;
628         GrGLint     fTextureUniform = 0;
629         GrGLint     fTexCoordXformUniform = 0;
630     }                                       fMipmapPrograms[4];
631     sk_sp<GrGLBuffer>                       fMipmapProgramArrayBuffer;
632 
633     static int TextureToCopyProgramIdx(GrTexture* texture);
634 
TextureSizeToMipmapProgramIdx(int width,int height)635     static int TextureSizeToMipmapProgramIdx(int width, int height) {
636         const bool wide = (width > 1) && SkToBool(width & 0x1);
637         const bool tall = (height > 1) && SkToBool(height & 0x1);
638         return (wide ? 0x2 : 0x0) | (tall ? 0x1 : 0x0);
639     }
640 
641     GrPrimitiveType fLastPrimitiveType;
642 
643     GrGLTextureParameters::ResetTimestamp fResetTimestampForTextureParameters = 0;
644 
645     class SamplerObjectCache;
646     std::unique_ptr<SamplerObjectCache> fSamplerObjectCache;
647 
648     std::unique_ptr<GrGLOpsRenderPass> fCachedOpsRenderPass;
649 
650     struct FinishCallback {
651         GrGpuFinishedProc fCallback;
652         GrGpuFinishedContext fContext;
653         GrGLsync fSync;
654     };
655     std::list<FinishCallback> fFinishCallbacks;
656 
657     SkDEBUGCODE(bool fIsExecutingCommandBuffer_DebugOnly = false);
658 
659     friend class GrGLPathRendering; // For accessing setTextureUnit.
660 
661     typedef GrGpu INHERITED;
662 };
663 
664 #endif
665