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