• 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 "GrGLContext.h"
12 #include "GrGLIRect.h"
13 #include "GrGLPathRendering.h"
14 #include "GrGLProgram.h"
15 #include "GrGLRenderTarget.h"
16 #include "GrGLStencilAttachment.h"
17 #include "GrGLTexture.h"
18 #include "GrGLVertexArray.h"
19 #include "GrGpu.h"
20 #include "GrMesh.h"
21 #include "GrWindowRectsState.h"
22 #include "GrXferProcessor.h"
23 #include "SkLRUCache.h"
24 #include "SkTArray.h"
25 #include "SkTypes.h"
26 
27 class GrGLBuffer;
28 class GrPipeline;
29 class GrSwizzle;
30 
31 #ifdef SK_DEBUG
32 #define PROGRAM_CACHE_STATS
33 #endif
34 
35 class GrGLGpu final : public GrGpu, private GrMesh::SendToGpuImpl {
36 public:
37     static sk_sp<GrGpu> Make(GrBackendContext backendContext, const GrContextOptions&, GrContext*);
38     static sk_sp<GrGpu> Make(sk_sp<const GrGLInterface>, const GrContextOptions&, GrContext*);
39     ~GrGLGpu() override;
40 
41     void disconnect(DisconnectType) override;
42 
glContext()43     const GrGLContext& glContext() const { return *fGLContext; }
44 
glInterface()45     const GrGLInterface* glInterface() const { return fGLContext->interface(); }
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 
glPathRendering()52     GrGLPathRendering* glPathRendering() {
53         SkASSERT(glCaps().shaderCaps()->pathRenderingSupport());
54         return static_cast<GrGLPathRendering*>(pathRendering());
55     }
56 
57     // Used by GrGLProgram to configure OpenGL state.
58     void bindTexture(int unitIdx, const GrSamplerState& samplerState, bool allowSRGBInputs,
59                      GrGLTexture* texture, GrSurfaceOrigin textureOrigin);
60 
61     void bindTexelBuffer(int unitIdx, GrPixelConfig, GrGLBuffer*);
62 
63     void generateMipmaps(const GrSamplerState& params, bool allowSRGBInputs, GrGLTexture* texture,
64                          GrSurfaceOrigin textureOrigin);
65 
66     bool onGetReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin,
67                              int readWidth, int readHeight, size_t rowBytes,
68                              GrPixelConfig readConfig, DrawPreference*,
69                              ReadPixelTempDrawInfo*) override;
70 
71     bool onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin,
72                               int width, int height,
73                               GrPixelConfig srcConfig, DrawPreference*,
74                               WritePixelTempDrawInfo*) override;
75 
76     // These functions should be used to bind GL objects. They track the GL state and skip redundant
77     // bindings. Making the equivalent glBind calls directly will confuse the state tracking.
bindVertexArray(GrGLuint id)78     void bindVertexArray(GrGLuint id) {
79         fHWVertexArrayState.setVertexArrayID(this, id);
80     }
81 
82     // These callbacks update state tracking when GL objects are deleted. They are called from
83     // GrGLResource onRelease functions.
notifyVertexArrayDelete(GrGLuint id)84     void notifyVertexArrayDelete(GrGLuint id) {
85         fHWVertexArrayState.notifyVertexArrayDelete(id);
86     }
87 
88     // Binds a buffer to the GL target corresponding to 'type', updates internal state tracking, and
89     // returns the GL target the buffer was bound to.
90     // When 'type' is kIndex_GrBufferType, this function will also implicitly bind the default VAO.
91     // If the caller wishes to bind an index buffer to a specific VAO, it can call glBind directly.
92     GrGLenum bindBuffer(GrBufferType type, const GrBuffer*);
93 
94     // Called by GrGLBuffer after its buffer object has been destroyed.
95     void notifyBufferReleased(const GrGLBuffer*);
96 
97     // The GrGLGpuRTCommandBuffer does not buffer up draws before submitting them to the gpu.
98     // Thus this is the implementation of the draw call for the corresponding passthrough function
99     // on GrGLRTGpuCommandBuffer.
100     void draw(const GrPipeline&,
101               const GrPrimitiveProcessor&,
102               const GrMesh[],
103               const GrPipeline::DynamicState[],
104               int meshCount);
105 
106 
107     // GrMesh::SendToGpuImpl methods. These issue the actual GL draw calls.
108     // Marked final as a hint to the compiler to not use virtual dispatch.
109     void sendMeshToGpu(const GrPrimitiveProcessor&, GrPrimitiveType,
110                        const GrBuffer* vertexBuffer, int vertexCount, int baseVertex) final;
111 
112     void sendIndexedMeshToGpu(const GrPrimitiveProcessor&, GrPrimitiveType,
113                               const GrBuffer* indexBuffer, int indexCount, int baseIndex,
114                               uint16_t minIndexValue, uint16_t maxIndexValue,
115                               const GrBuffer* vertexBuffer, int baseVertex) final;
116 
117     void sendInstancedMeshToGpu(const GrPrimitiveProcessor&, GrPrimitiveType,
118                                 const GrBuffer* vertexBuffer, int vertexCount, int baseVertex,
119                                 const GrBuffer* instanceBuffer, int instanceCount,
120                                 int baseInstance) final;
121 
122     void sendIndexedInstancedMeshToGpu(const GrPrimitiveProcessor&, GrPrimitiveType,
123                                        const GrBuffer* indexBuffer, int indexCount, int baseIndex,
124                                        const GrBuffer* vertexBuffer, int baseVertex,
125                                        const GrBuffer* instanceBuffer, int instanceCount,
126                                        int baseInstance) final;
127 
128     // The GrGLGpuRTCommandBuffer does not buffer up draws before submitting them to the gpu.
129     // Thus this is the implementation of the clear call for the corresponding passthrough function
130     // on GrGLGpuRTCommandBuffer.
131     void clear(const GrFixedClip&, GrColor, GrRenderTarget*, GrSurfaceOrigin);
132     void clearColorAsDraw(const GrFixedClip&, GrGLfloat r, GrGLfloat g, GrGLfloat b, GrGLfloat a,
133                           GrRenderTarget*, GrSurfaceOrigin);
134 
135     // The GrGLGpuRTCommandBuffer does not buffer up draws before submitting them to the gpu.
136     // Thus this is the implementation of the clearStencil call for the corresponding passthrough
137     // function on GrGLGpuRTCommandBuffer.
138     void clearStencilClip(const GrFixedClip&, bool insideStencilMask,
139                           GrRenderTarget*, GrSurfaceOrigin);
140 
glContextForTesting()141     const GrGLContext* glContextForTesting() const override {
142         return &this->glContext();
143     }
144 
145     void clearStencil(GrRenderTarget*, int clearValue) override;
146 
147     GrGpuRTCommandBuffer* createCommandBuffer(
148             GrRenderTarget*, GrSurfaceOrigin,
149             const GrGpuRTCommandBuffer::LoadAndStoreInfo&,
150             const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo&) override;
151 
152     GrGpuTextureCommandBuffer* createCommandBuffer(GrTexture*, GrSurfaceOrigin) override;
153 
invalidateBoundRenderTarget()154     void invalidateBoundRenderTarget() {
155         fHWBoundRenderTargetUniqueID.makeInvalid();
156     }
157 
158     GrStencilAttachment* createStencilAttachmentForRenderTarget(const GrRenderTarget* rt,
159                                                                 int width,
160                                                                 int height) override;
161 
162     GrBackendTexture createTestingOnlyBackendTexture(void* pixels, int w, int h,
163                                                      GrPixelConfig config,
164                                                      bool isRenderTarget,
165                                                      GrMipMapped mipMapped) override;
166     bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override;
167     void deleteTestingOnlyBackendTexture(GrBackendTexture*, bool abandonTexture = false) override;
168 
169     void resetShaderCacheForTesting() const override;
170 
171     void testingOnly_flushGpuAndSync() override;
172 
173     GrFence SK_WARN_UNUSED_RESULT insertFence() override;
174     bool waitFence(GrFence, uint64_t timeout) override;
175     void deleteFence(GrFence) const override;
176 
177     sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned) override;
178     sk_sp<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
179                                             GrResourceProvider::SemaphoreWrapType wrapType,
180                                             GrWrapOwnership ownership) override;
181     void insertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) override;
182     void waitSemaphore(sk_sp<GrSemaphore> semaphore) override;
183 
184     sk_sp<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override;
185 
186     void deleteSync(GrGLsync) const;
187 
188     void insertEventMarker(const char*);
189 
190 private:
191     GrGLGpu(std::unique_ptr<GrGLContext>, GrContext*);
192 
193     // GrGpu overrides
194     void onResetContext(uint32_t resetBits) override;
195 
196     void xferBarrier(GrRenderTarget*, GrXferBarrierType) override;
197 
198     sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
199                                      const GrMipLevel texels[],
200                                      int mipLevelCount) override;
201 
202     GrBuffer* onCreateBuffer(size_t size, GrBufferType intendedType, GrAccessPattern,
203                              const void* data) override;
204 
205     sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership) override;
206     sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&,
207                                                     int sampleCnt,
208                                                     GrWrapOwnership) override;
209     sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&) override;
210     sk_sp<GrRenderTarget> onWrapBackendTextureAsRenderTarget(const GrBackendTexture&,
211                                                              int sampleCnt) override;
212 
213     // Given a GrPixelConfig return the index into the stencil format array on GrGLCaps to a
214     // compatible stencil format, or negative if there is no compatible stencil format.
215     int getCompatibleStencilIndex(GrPixelConfig config);
216 
217 
218     // Returns whether the texture is successfully created. On success, the
219     // result is stored in |info|.
220     // The texture is populated with |texels|, if it exists.
221     // The texture parameters are cached in |initialTexParams|.
222     bool createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info,
223                            bool renderTarget, GrGLTexture::TexParams* initialTexParams,
224                            const GrMipLevel texels[], int mipLevelCount,
225                            GrMipMapsStatus* mipMapsStatus);
226 
227     bool onIsACopyNeededForTextureParams(GrTextureProxy*, const GrSamplerState&,
228                                          GrTextureProducer::CopyParams*,
229                                          SkScalar scaleAdjust[2]) const override;
230 
231     // Checks whether glReadPixels can be called to get pixel values in readConfig from the
232     // render target.
233     bool readPixelsSupported(GrRenderTarget* target, GrPixelConfig readConfig);
234 
235     // Checks whether glReadPixels can be called to get pixel values in readConfig from a
236     // render target that has renderTargetConfig. This may have to create a temporary
237     // render target and thus is less preferable than the variant that takes a render target.
238     bool readPixelsSupported(GrPixelConfig renderTargetConfig, GrPixelConfig readConfig);
239 
240     // Checks whether glReadPixels can be called to get pixel values in readConfig from a
241     // render target that has the same config as surfaceForConfig. Calls one of the the two
242     // variations above, depending on whether the surface is a render target or not.
243     bool readPixelsSupported(GrSurface* surfaceForConfig, GrPixelConfig readConfig);
244 
245     bool onReadPixels(GrSurface*, GrSurfaceOrigin,
246                       int left, int top,
247                       int width, int height,
248                       GrPixelConfig,
249                       void* buffer,
250                       size_t rowBytes) override;
251 
252     bool onWritePixels(GrSurface*, GrSurfaceOrigin,
253                        int left, int top, int width, int height,
254                        GrPixelConfig config,
255                        const GrMipLevel texels[], int mipLevelCount) override;
256 
257     bool onTransferPixels(GrTexture*,
258                           int left, int top, int width, int height,
259                           GrPixelConfig config, GrBuffer* transferBuffer,
260                           size_t offset, size_t rowBytes) override;
261 
262     // Before calling any variation of TexImage, TexSubImage, etc..., call this to ensure that the
263     // PIXEL_UNPACK_BUFFER is unbound.
264     void unbindCpuToGpuXferBuffer();
265 
266     void onResolveRenderTarget(GrRenderTarget* target, GrSurfaceOrigin) override;
267 
268     bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
269                        GrSurface* src, GrSurfaceOrigin srcOrigin,
270                        const SkIRect& srcRect, const SkIPoint& dstPoint,
271                        bool canDiscardOutsideDstRect) override;
272 
273     void onQueryMultisampleSpecs(GrRenderTarget*, GrSurfaceOrigin, const GrStencilSettings&,
274                                  int* effectiveSampleCnt, SamplePattern*) override;
275 
276     // binds texture unit in GL
277     void setTextureUnit(int unitIdx);
278 
279     void setTextureSwizzle(int unitIdx, GrGLenum target, const GrGLenum swizzle[]);
280 
281     // Flushes state from GrPipeline to GL. Returns false if the state couldn't be set.
282     // willDrawPoints must be true if point primitives will be rendered after setting the GL state.
283     bool flushGLState(const GrPipeline&, const GrPrimitiveProcessor&, bool willDrawPoints);
284 
285     // Sets up vertex/instance attribute pointers and strides.
286     void setupGeometry(const GrPrimitiveProcessor&,
287                        const GrBuffer* indexBuffer,
288                        const GrBuffer* vertexBuffer,
289                        int baseVertex,
290                        const GrBuffer* instanceBuffer,
291                        int baseInstance);
292 
293     void flushBlend(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle&);
294 
295     void onFinishFlush(bool insertedSemaphores) override;
296 
hasExtension(const char * ext)297     bool hasExtension(const char* ext) const { return fGLContext->hasExtension(ext); }
298 
299     bool copySurfaceAsDraw(GrSurface* dst, GrSurfaceOrigin dstOrigin,
300                            GrSurface* src, GrSurfaceOrigin srcOrigin,
301                            const SkIRect& srcRect, const SkIPoint& dstPoint);
302     void copySurfaceAsCopyTexSubImage(GrSurface* dst, GrSurfaceOrigin dstOrigin,
303                                       GrSurface* src, GrSurfaceOrigin srcOrigin,
304                                       const SkIRect& srcRect, const SkIPoint& dstPoint);
305     bool copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurfaceOrigin dstOrigin,
306                                       GrSurface* src, GrSurfaceOrigin srcOrigin,
307                                       const SkIRect& srcRect, const SkIPoint& dstPoint);
308     bool generateMipmap(GrGLTexture* texture, GrSurfaceOrigin textureOrigin, bool gammaCorrect);
309     void clearStencilClipAsDraw(const GrFixedClip&, bool insideStencilMask,
310                                 GrRenderTarget*, GrSurfaceOrigin);
311 
312     static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
313 
314     class ProgramCache : public ::SkNoncopyable {
315     public:
316         ProgramCache(GrGLGpu* gpu);
317         ~ProgramCache();
318 
319         void abandon();
320         GrGLProgram* refProgram(const GrGLGpu*, const GrPipeline&, const GrPrimitiveProcessor&,
321                                 bool hasPointSize);
322 
323     private:
324         // We may actually have kMaxEntries+1 shaders in the GL context because we create a new
325         // shader before evicting from the cache.
326         static const int kMaxEntries = 128;
327 
328         struct Entry;
329 
330         // binary search for entry matching desc. returns index into fEntries that matches desc or ~
331         // of the index of where it should be inserted.
332         int search(const GrProgramDesc& desc) const;
333 
334         struct DescHash {
operatorDescHash335             uint32_t operator()(const GrProgramDesc& desc) const {
336                 return SkOpts::hash_fn(desc.asKey(), desc.keyLength(), 0);
337             }
338         };
339 
340         SkLRUCache<GrProgramDesc, std::unique_ptr<Entry>, DescHash> fMap;
341 
342         GrGLGpu*                    fGpu;
343 #ifdef PROGRAM_CACHE_STATS
344         int                         fTotalRequests;
345         int                         fCacheMisses;
346         int                         fHashMisses; // cache hit but hash table missed
347 #endif
348     };
349 
350     void flushColorWrite(bool writeColor);
351 
352     // flushes the scissor. see the note on flushBoundTextureAndParams about
353     // flushing the scissor after that function is called.
354     void flushScissor(const GrScissorState&,
355                       const GrGLIRect& rtViewport,
356                       GrSurfaceOrigin rtOrigin);
357 
358     // disables the scissor
359     void disableScissor();
360 
361     void flushWindowRectangles(const GrWindowRectsState&, const GrGLRenderTarget*, GrSurfaceOrigin);
362     void disableWindowRectangles();
363 
364     // sets a texture unit to use for texture operations other than binding a texture to a program.
365     // ensures that such operations don't negatively interact with tracking bound textures.
366     void setScratchTextureUnit();
367 
368     // bounds is region that may be modified.
369     // nullptr means whole target. Can be an empty rect.
370     void flushRenderTarget(GrGLRenderTarget*, const SkIRect* bounds, bool disableSRGB = false);
371 
372     // Need not be called if flushRenderTarget is used.
373     void flushViewport(const GrGLIRect&);
374 
375     void flushStencil(const GrStencilSettings&);
376     void disableStencil();
377 
378     // rt is used only if useHWAA is true.
379     void flushHWAAState(GrRenderTarget* rt, bool useHWAA, bool stencilEnabled);
380 
381     void flushMinSampleShading(float minSampleShading);
382 
383     void flushFramebufferSRGB(bool enable);
384 
385     // helper for onCreateTexture and writeTexturePixels
386     enum UploadType {
387         kNewTexture_UploadType,   // we are creating a new texture
388         kWrite_UploadType,        // we are using TexSubImage2D to copy data to an existing texture
389     };
390     bool uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight,
391                        GrSurfaceOrigin texOrigin, GrGLenum target, UploadType uploadType, int left,
392                        int top, int width, int height, GrPixelConfig dataConfig,
393                        const GrMipLevel texels[], int mipLevelCount,
394                        GrMipMapsStatus* mipMapsStatus = nullptr);
395 
396     bool createRenderTargetObjects(const GrSurfaceDesc&, const GrGLTextureInfo& texInfo,
397                                    GrGLRenderTarget::IDDesc*);
398 
399     enum TempFBOTarget {
400         kSrc_TempFBOTarget,
401         kDst_TempFBOTarget
402     };
403 
404     // Binds a surface as a FBO for copying, reading, or clearing. If the surface already owns an
405     // FBO ID then that ID is bound. If not the surface is temporarily bound to a FBO and that FBO
406     // is bound. This must be paired with a call to unbindSurfaceFBOForPixelOps().
407     void bindSurfaceFBOForPixelOps(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport,
408                                    TempFBOTarget tempFBOTarget);
409 
410     // Must be called if bindSurfaceFBOForPixelOps was used to bind a surface for copying.
411     void unbindTextureFBOForPixelOps(GrGLenum fboTarget, GrSurface* surface);
412 
413     void onDumpJSON(SkJSONWriter*) const override;
414 
415     bool createCopyProgram(GrTexture* srcTexture);
416     bool createMipmapProgram(int progIdx);
417     bool createStencilClipClearProgram();
418     bool createClearColorProgram();
419 
420     std::unique_ptr<GrGLContext> fGLContext;
421 
422     // GL program-related state
423     ProgramCache*               fProgramCache;
424 
425     ///////////////////////////////////////////////////////////////////////////
426     ///@name Caching of GL State
427     ///@{
428     int                         fHWActiveTextureUnitIdx;
429     GrGLuint                    fHWProgramID;
430 
431     enum TriState {
432         kNo_TriState,
433         kYes_TriState,
434         kUnknown_TriState
435     };
436 
437     GrGLuint                    fTempSrcFBOID;
438     GrGLuint                    fTempDstFBOID;
439 
440     GrGLuint                    fStencilClearFBOID;
441 
442     // last scissor / viewport scissor state seen by the GL.
443     struct {
444         TriState    fEnabled;
445         GrGLIRect   fRect;
invalidate__anon8bc101fe0108446         void invalidate() {
447             fEnabled = kUnknown_TriState;
448             fRect.invalidate();
449         }
450     } fHWScissorSettings;
451 
452     class {
453     public:
valid()454         bool valid() const { return kInvalidSurfaceOrigin != fRTOrigin; }
invalidate()455         void invalidate() { fRTOrigin = kInvalidSurfaceOrigin; }
knownDisabled()456         bool knownDisabled() const { return this->valid() && !fWindowState.enabled(); }
setDisabled()457         void setDisabled() {
458             fRTOrigin = kTopLeft_GrSurfaceOrigin;
459             fWindowState.setDisabled();
460         }
461 
set(GrSurfaceOrigin rtOrigin,const GrGLIRect & viewport,const GrWindowRectsState & windowState)462         void set(GrSurfaceOrigin rtOrigin, const GrGLIRect& viewport,
463                  const GrWindowRectsState& windowState) {
464             fRTOrigin = rtOrigin;
465             fViewport = viewport;
466             fWindowState = windowState;
467         }
468 
knownEqualTo(GrSurfaceOrigin rtOrigin,const GrGLIRect & viewport,const GrWindowRectsState & windowState)469         bool knownEqualTo(GrSurfaceOrigin rtOrigin, const GrGLIRect& viewport,
470                           const GrWindowRectsState& windowState) const {
471             if (!this->valid()) {
472                 return false;
473             }
474             if (fWindowState.numWindows() && (fRTOrigin != rtOrigin || fViewport != viewport)) {
475                 return false;
476             }
477             return fWindowState == windowState;
478         }
479 
480     private:
481         enum { kInvalidSurfaceOrigin = -1 };
482 
483         int                  fRTOrigin;
484         GrGLIRect            fViewport;
485         GrWindowRectsState   fWindowState;
486     } fHWWindowRectsState;
487 
488     GrGLIRect                   fHWViewport;
489 
490     /**
491      * Tracks vertex attrib array state.
492      */
493     class HWVertexArrayState {
494     public:
HWVertexArrayState()495         HWVertexArrayState() : fCoreProfileVertexArray(nullptr) { this->invalidate(); }
496 
~HWVertexArrayState()497         ~HWVertexArrayState() { delete fCoreProfileVertexArray; }
498 
invalidate()499         void invalidate() {
500             fBoundVertexArrayIDIsValid = false;
501             fDefaultVertexArrayAttribState.invalidate();
502             if (fCoreProfileVertexArray) {
503                 fCoreProfileVertexArray->invalidateCachedState();
504             }
505         }
506 
notifyVertexArrayDelete(GrGLuint id)507         void notifyVertexArrayDelete(GrGLuint id) {
508             if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) {
509                 // Does implicit bind to 0
510                 fBoundVertexArrayID = 0;
511             }
512         }
513 
setVertexArrayID(GrGLGpu * gpu,GrGLuint arrayID)514         void setVertexArrayID(GrGLGpu* gpu, GrGLuint arrayID) {
515             if (!gpu->glCaps().vertexArrayObjectSupport()) {
516                 SkASSERT(0 == arrayID);
517                 return;
518             }
519             if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) {
520                 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID));
521                 fBoundVertexArrayIDIsValid = true;
522                 fBoundVertexArrayID = arrayID;
523             }
524         }
525 
526         /**
527          * Binds the vertex array that should be used for internal draws, and returns its attrib
528          * state. This binds the default VAO (ID=zero) unless we are on a core profile, in which
529          * case we use a dummy array instead.
530          *
531          * If an index buffer is privided, it will be bound to the vertex array. Otherwise the
532          * index buffer binding will be left unchanged.
533          *
534          * The returned GrGLAttribArrayState should be used to set vertex attribute arrays.
535          */
536         GrGLAttribArrayState* bindInternalVertexArray(GrGLGpu*, const GrBuffer* ibuff = nullptr);
537 
538     private:
539         GrGLuint             fBoundVertexArrayID;
540         bool                 fBoundVertexArrayIDIsValid;
541 
542         // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0
543         // is bound. However, this class is internal to GrGLGpu and this object never leaks out of
544         // GrGLGpu.
545         GrGLAttribArrayState fDefaultVertexArrayAttribState;
546 
547         // This is used when we're using a core profile.
548         GrGLVertexArray*     fCoreProfileVertexArray;
549     }                                       fHWVertexArrayState;
550 
551     struct {
552         GrGLenum                fGLTarget;
553         GrGpuResource::UniqueID fBoundBufferUniqueID;
554         bool                    fBufferZeroKnownBound;
555 
invalidate__anon8bc101fe0308556         void invalidate() {
557             fBoundBufferUniqueID.makeInvalid();
558             fBufferZeroKnownBound = false;
559         }
560     }                                       fHWBufferState[kGrBufferTypeCount];
561 
562     struct {
563         GrBlendEquation fEquation;
564         GrBlendCoeff    fSrcCoeff;
565         GrBlendCoeff    fDstCoeff;
566         GrColor         fConstColor;
567         bool            fConstColorValid;
568         TriState        fEnabled;
569 
invalidate__anon8bc101fe0408570         void invalidate() {
571             fEquation = static_cast<GrBlendEquation>(-1);
572             fSrcCoeff = static_cast<GrBlendCoeff>(-1);
573             fDstCoeff = static_cast<GrBlendCoeff>(-1);
574             fConstColorValid = false;
575             fEnabled = kUnknown_TriState;
576         }
577     }                                       fHWBlendState;
578 
579     TriState fMSAAEnabled;
580 
581     GrStencilSettings                       fHWStencilSettings;
582     TriState                                fHWStencilTestEnabled;
583 
584 
585     TriState                                fHWWriteToColor;
586     GrGpuResource::UniqueID                 fHWBoundRenderTargetUniqueID;
587     TriState                                fHWSRGBFramebuffer;
588     SkTArray<GrGpuResource::UniqueID, true> fHWBoundTextureUniqueIDs;
589 
590     struct BufferTexture {
BufferTextureBufferTexture591         BufferTexture() : fTextureID(0), fKnownBound(false),
592                           fAttachedBufferUniqueID(SK_InvalidUniqueID),
593                           fSwizzle(GrSwizzle::RGBA()) {}
594 
595         GrGLuint                fTextureID;
596         bool                    fKnownBound;
597         GrPixelConfig           fTexelConfig;
598         GrGpuResource::UniqueID fAttachedBufferUniqueID;
599         GrSwizzle               fSwizzle;
600     };
601 
602     SkTArray<BufferTexture, true>           fHWBufferTextures;
603     int                                     fHWMaxUsedBufferTextureUnit;
604 
605     // EXT_raster_multisample.
606     TriState                                fHWRasterMultisampleEnabled;
607     int                                     fHWNumRasterSamples;
608     ///@}
609 
610     /** IDs for copy surface program. (4 sampler types) */
611     struct {
612         GrGLuint    fProgram = 0;
613         GrGLint     fTextureUniform = 0;
614         GrGLint     fTexCoordXformUniform = 0;
615         GrGLint     fPosXformUniform = 0;
616     }                                       fCopyPrograms[4];
617     sk_sp<GrGLBuffer>                       fCopyProgramArrayBuffer;
618 
619     /** IDs for texture mipmap program. (4 filter configurations) */
620     struct {
621         GrGLuint    fProgram = 0;
622         GrGLint     fTextureUniform = 0;
623         GrGLint     fTexCoordXformUniform = 0;
624     }                                       fMipmapPrograms[4];
625     sk_sp<GrGLBuffer>                       fMipmapProgramArrayBuffer;
626 
627     GrGLuint                                fStencilClipClearProgram = 0;
628     sk_sp<GrGLBuffer>                       fStencilClipClearArrayBuffer;
629 
630     /** IDs for clear render target color program. */
631     struct {
632         GrGLuint    fProgram = 0;
633         GrGLint     fColorUniform = 0;
634     }                                       fClearColorProgram;
635     sk_sp<GrGLBuffer>                       fClearProgramArrayBuffer;
636 
637     static int TextureToCopyProgramIdx(GrTexture* texture);
638 
TextureSizeToMipmapProgramIdx(int width,int height)639     static int TextureSizeToMipmapProgramIdx(int width, int height) {
640         const bool wide = (width > 1) && SkToBool(width & 0x1);
641         const bool tall = (height > 1) && SkToBool(height & 0x1);
642         return (wide ? 0x2 : 0x0) | (tall ? 0x1 : 0x0);
643     }
644 
645     float                                   fHWMinSampleShading;
646     GrPrimitiveType                         fLastPrimitiveType;
647 
648     typedef GrGpu INHERITED;
649     friend class GrGLPathRendering; // For accessing setTextureUnit.
650 };
651 
652 #endif
653