Home | History | Annotate | Download | only in gl
      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 
     43     const GrGLContext& glContext() const { return *fGLContext; }
     44 
     45     const GrGLInterface* glInterface() const { return fGLContext->interface(); }
     46     const GrGLContextInfo& ctxInfo() const { return *fGLContext; }
     47     GrGLStandard glStandard() const { return fGLContext->standard(); }
     48     GrGLVersion glVersion() const { return fGLContext->version(); }
     49     GrGLSLGeneration glslGeneration() const { return fGLContext->glslGeneration(); }
     50     const GrGLCaps& glCaps() const { return *fGLContext->caps(); }
     51 
     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.
     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.
     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 
    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 
    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 
    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 {
    335             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;
    446         void invalidate() {
    447             fEnabled = kUnknown_TriState;
    448             fRect.invalidate();
    449         }
    450     } fHWScissorSettings;
    451 
    452     class {
    453     public:
    454         bool valid() const { return kInvalidSurfaceOrigin != fRTOrigin; }
    455         void invalidate() { fRTOrigin = kInvalidSurfaceOrigin; }
    456         bool knownDisabled() const { return this->valid() && !fWindowState.enabled(); }
    457         void setDisabled() {
    458             fRTOrigin = kTopLeft_GrSurfaceOrigin;
    459             fWindowState.setDisabled();
    460         }
    461 
    462         void set(GrSurfaceOrigin rtOrigin, const GrGLIRect& viewport,
    463                  const GrWindowRectsState& windowState) {
    464             fRTOrigin = rtOrigin;
    465             fViewport = viewport;
    466             fWindowState = windowState;
    467         }
    468 
    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:
    495         HWVertexArrayState() : fCoreProfileVertexArray(nullptr) { this->invalidate(); }
    496 
    497         ~HWVertexArrayState() { delete fCoreProfileVertexArray; }
    498 
    499         void invalidate() {
    500             fBoundVertexArrayIDIsValid = false;
    501             fDefaultVertexArrayAttribState.invalidate();
    502             if (fCoreProfileVertexArray) {
    503                 fCoreProfileVertexArray->invalidateCachedState();
    504             }
    505         }
    506 
    507         void notifyVertexArrayDelete(GrGLuint id) {
    508             if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) {
    509                 // Does implicit bind to 0
    510                 fBoundVertexArrayID = 0;
    511             }
    512         }
    513 
    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 
    556         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 
    570         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 {
    591         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 
    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