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     // 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.
     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.
     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 
    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 
    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 
    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 {
    317             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;
    433         void invalidate() {
    434             fEnabled = kUnknown_TriState;
    435             fRect.invalidate();
    436         }
    437     } fHWScissorSettings;
    438 
    439     class {
    440     public:
    441         bool valid() const { return kInvalidSurfaceOrigin != fRTOrigin; }
    442         void invalidate() { fRTOrigin = kInvalidSurfaceOrigin; }
    443         bool knownDisabled() const { return this->valid() && !fWindowState.enabled(); }
    444         void setDisabled() {
    445             fRTOrigin = kTopLeft_GrSurfaceOrigin;
    446             fWindowState.setDisabled();
    447         }
    448 
    449         void set(GrSurfaceOrigin rtOrigin, const GrGLIRect& viewport,
    450                  const GrWindowRectsState& windowState) {
    451             fRTOrigin = rtOrigin;
    452             fViewport = viewport;
    453             fWindowState = windowState;
    454         }
    455 
    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:
    482         HWVertexArrayState() : fCoreProfileVertexArray(nullptr) { this->invalidate(); }
    483 
    484         ~HWVertexArrayState() { delete fCoreProfileVertexArray; }
    485 
    486         void invalidate() {
    487             fBoundVertexArrayIDIsValid = false;
    488             fDefaultVertexArrayAttribState.invalidate();
    489             if (fCoreProfileVertexArray) {
    490                 fCoreProfileVertexArray->invalidateCachedState();
    491             }
    492         }
    493 
    494         void notifyVertexArrayDelete(GrGLuint id) {
    495             if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) {
    496                 // Does implicit bind to 0
    497                 fBoundVertexArrayID = 0;
    498             }
    499         }
    500 
    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 
    543         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 
    557         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 {
    578         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 
    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