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 GrGLGpuRTCommandBuffer;
     29 class GrGLGpuTextureCommandBuffer;
     30 class GrPipeline;
     31 class GrSwizzle;
     32 
     33 #ifdef SK_DEBUG
     34 #define PROGRAM_CACHE_STATS
     35 #endif
     36 
     37 class GrGLGpu final : public GrGpu, private GrMesh::SendToGpuImpl {
     38 public:
     39     static sk_sp<GrGpu> Make(sk_sp<const GrGLInterface>, const GrContextOptions&, GrContext*);
     40     ~GrGLGpu() override;
     41 
     42     void disconnect(DisconnectType) override;
     43 
     44     const GrGLContext& glContext() const { return *fGLContext; }
     45 
     46     const GrGLInterface* glInterface() const { return fGLContext->interface(); }
     47     const GrGLContextInfo& ctxInfo() const { return *fGLContext; }
     48     GrGLStandard glStandard() const { return fGLContext->standard(); }
     49     GrGLVersion glVersion() const { return fGLContext->version(); }
     50     GrGLSLGeneration glslGeneration() const { return fGLContext->glslGeneration(); }
     51     const GrGLCaps& glCaps() const { return *fGLContext->caps(); }
     52 
     53     GrGLPathRendering* glPathRendering() {
     54         SkASSERT(glCaps().shaderCaps()->pathRenderingSupport());
     55         return static_cast<GrGLPathRendering*>(pathRendering());
     56     }
     57 
     58     // Used by GrGLProgram to configure OpenGL state.
     59     void bindTexture(int unitIdx, GrSamplerState samplerState, GrGLTexture* texture);
     60 
     61     // These functions should be used to bind GL objects. They track the GL state and skip redundant
     62     // bindings. Making the equivalent glBind calls directly will confuse the state tracking.
     63     void bindVertexArray(GrGLuint id) {
     64         fHWVertexArrayState.setVertexArrayID(this, id);
     65     }
     66 
     67     // These callbacks update state tracking when GL objects are deleted. They are called from
     68     // GrGLResource onRelease functions.
     69     void notifyVertexArrayDelete(GrGLuint id) {
     70         fHWVertexArrayState.notifyVertexArrayDelete(id);
     71     }
     72 
     73     // Binds a buffer to the GL target corresponding to 'type', updates internal state tracking, and
     74     // returns the GL target the buffer was bound to.
     75     // When 'type' is kIndex_GrBufferType, this function will also implicitly bind the default VAO.
     76     // If the caller wishes to bind an index buffer to a specific VAO, it can call glBind directly.
     77     GrGLenum bindBuffer(GrBufferType type, const GrBuffer*);
     78 
     79     // The GrGLGpuRTCommandBuffer does not buffer up draws before submitting them to the gpu.
     80     // Thus this is the implementation of the draw call for the corresponding passthrough function
     81     // on GrGLRTGpuCommandBuffer.
     82     void draw(GrRenderTarget*, GrSurfaceOrigin,
     83               const GrPrimitiveProcessor&,
     84               const GrPipeline&,
     85               const GrPipeline::FixedDynamicState*,
     86               const GrPipeline::DynamicStateArrays*,
     87               const GrMesh[],
     88               int meshCount);
     89 
     90     // GrMesh::SendToGpuImpl methods. These issue the actual GL draw calls.
     91     // Marked final as a hint to the compiler to not use virtual dispatch.
     92     void sendMeshToGpu(GrPrimitiveType, const GrBuffer* vertexBuffer, int vertexCount,
     93                        int baseVertex) final;
     94 
     95     void sendIndexedMeshToGpu(GrPrimitiveType, const GrBuffer* indexBuffer, int indexCount,
     96                               int baseIndex, uint16_t minIndexValue, uint16_t maxIndexValue,
     97                               const GrBuffer* vertexBuffer, int baseVertex,
     98                               GrPrimitiveRestart) final;
     99 
    100     void sendInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* vertexBuffer, int vertexCount,
    101                                 int baseVertex, const GrBuffer* instanceBuffer, int instanceCount,
    102                                 int baseInstance) final;
    103 
    104     void sendIndexedInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* indexBuffer, int indexCount,
    105                                        int baseIndex, const GrBuffer* vertexBuffer, int baseVertex,
    106                                        const GrBuffer* instanceBuffer, int instanceCount,
    107                                        int baseInstance, GrPrimitiveRestart) final;
    108 
    109     // The GrGLGpuRTCommandBuffer does not buffer up draws before submitting them to the gpu.
    110     // Thus this is the implementation of the clear call for the corresponding passthrough function
    111     // on GrGLGpuRTCommandBuffer.
    112     void clear(const GrFixedClip&, const SkPMColor4f&, GrRenderTarget*, GrSurfaceOrigin);
    113 
    114     // The GrGLGpuRTCommandBuffer does not buffer up draws before submitting them to the gpu.
    115     // Thus this is the implementation of the clearStencil call for the corresponding passthrough
    116     // function on GrGLGpuRTCommandBuffer.
    117     void clearStencilClip(const GrFixedClip&, bool insideStencilMask,
    118                           GrRenderTarget*, GrSurfaceOrigin);
    119 
    120     // FIXME (michaelludwig): Can this go away and just use clearStencilClip() + marking the
    121     // stencil buffer as not dirty?
    122     void clearStencil(GrRenderTarget*, int clearValue);
    123 
    124     GrGpuRTCommandBuffer* getCommandBuffer(
    125             GrRenderTarget*, GrSurfaceOrigin, const SkRect&,
    126             const GrGpuRTCommandBuffer::LoadAndStoreInfo&,
    127             const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo&) override;
    128 
    129     GrGpuTextureCommandBuffer* getCommandBuffer(GrTexture*, GrSurfaceOrigin) override;
    130 
    131     void invalidateBoundRenderTarget() {
    132         fHWBoundRenderTargetUniqueID.makeInvalid();
    133     }
    134 
    135     GrStencilAttachment* createStencilAttachmentForRenderTarget(const GrRenderTarget* rt,
    136                                                                 int width,
    137                                                                 int height) override;
    138 #if GR_TEST_UTILS
    139     GrBackendTexture createTestingOnlyBackendTexture(const void* pixels, int w, int h,
    140                                                      GrColorType colorType, bool isRenderTarget,
    141                                                      GrMipMapped mipMapped,
    142                                                      size_t rowBytes = 0) override;
    143     bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override;
    144     void deleteTestingOnlyBackendTexture(const GrBackendTexture&) override;
    145 
    146     GrBackendRenderTarget createTestingOnlyBackendRenderTarget(int w, int h, GrColorType) override;
    147 
    148     void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override;
    149 
    150     const GrGLContext* glContextForTesting() const override { return &this->glContext(); }
    151 
    152     void resetShaderCacheForTesting() const override { fProgramCache->abandon(); }
    153 
    154     void testingOnly_flushGpuAndSync() override;
    155 #endif
    156 
    157     void submit(GrGpuCommandBuffer* buffer) override;
    158 
    159     GrFence SK_WARN_UNUSED_RESULT insertFence() override;
    160     bool waitFence(GrFence, uint64_t timeout) override;
    161     void deleteFence(GrFence) const override;
    162 
    163     sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned) override;
    164     sk_sp<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
    165                                             GrResourceProvider::SemaphoreWrapType wrapType,
    166                                             GrWrapOwnership ownership) override;
    167     void insertSemaphore(sk_sp<GrSemaphore> semaphore) override;
    168     void waitSemaphore(sk_sp<GrSemaphore> semaphore) override;
    169 
    170     sk_sp<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override;
    171 
    172     void deleteSync(GrGLsync) const;
    173 
    174     void insertEventMarker(const char*);
    175 
    176     void bindFramebuffer(GrGLenum fboTarget, GrGLuint fboid);
    177     void deleteFramebuffer(GrGLuint fboid);
    178 
    179 private:
    180     GrGLGpu(std::unique_ptr<GrGLContext>, GrContext*);
    181 
    182     // GrGpu overrides
    183     void onResetContext(uint32_t resetBits) override;
    184 
    185     void xferBarrier(GrRenderTarget*, GrXferBarrierType) override;
    186 
    187     sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
    188                                      const GrMipLevel texels[], int mipLevelCount) override;
    189 
    190     sk_sp<GrBuffer> onCreateBuffer(size_t size, GrBufferType intendedType, GrAccessPattern,
    191                                    const void* data) override;
    192 
    193     sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership, GrWrapCacheable,
    194                                           GrIOType) override;
    195     sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&, int sampleCnt,
    196                                                     GrWrapOwnership, GrWrapCacheable) 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     void onFBOChanged();
    206 
    207     // Returns whether the texture is successfully created. On success, the
    208     // result is stored in |info|.
    209     // The texture is populated with |texels|, if it exists.
    210     // The texture parameters are cached in |initialTexParams|.
    211     bool createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info, bool renderTarget,
    212                            GrGLTexture::SamplerParams* initialTexParams, const GrMipLevel texels[],
    213                            int mipLevelCount, GrMipMapsStatus* mipMapsStatus);
    214 
    215     // Checks whether glReadPixels can be called to get pixel values in readConfig from the
    216     // render target.
    217     bool readPixelsSupported(GrRenderTarget* target, GrPixelConfig readConfig);
    218 
    219     // Checks whether glReadPixels can be called to get pixel values in readConfig from a
    220     // render target that has renderTargetConfig. This may have to create a temporary
    221     // render target and thus is less preferable than the variant that takes a render target.
    222     bool readPixelsSupported(GrPixelConfig renderTargetConfig, GrPixelConfig readConfig);
    223 
    224     // Checks whether glReadPixels can be called to get pixel values in readConfig from a
    225     // render target that has the same config as surfaceForConfig. Calls one of the the two
    226     // variations above, depending on whether the surface is a render target or not.
    227     bool readPixelsSupported(GrSurface* surfaceForConfig, GrPixelConfig readConfig);
    228 
    229     bool onReadPixels(GrSurface*, int left, int top, int width, int height, GrColorType,
    230                       void* buffer, size_t rowBytes) override;
    231 
    232     bool onWritePixels(GrSurface*, int left, int top, int width, int height, GrColorType,
    233                        const GrMipLevel texels[], int mipLevelCount) override;
    234 
    235     bool onTransferPixels(GrTexture*, int left, int top, int width, int height, GrColorType,
    236                           GrBuffer* transferBuffer, size_t offset, size_t rowBytes) override;
    237 
    238     // Before calling any variation of TexImage, TexSubImage, etc..., call this to ensure that the
    239     // PIXEL_UNPACK_BUFFER is unbound.
    240     void unbindCpuToGpuXferBuffer();
    241 
    242     void onResolveRenderTarget(GrRenderTarget* target) override;
    243 
    244     bool onRegenerateMipMapLevels(GrTexture*) override;
    245 
    246     bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
    247                        GrSurface* src, GrSurfaceOrigin srcOrigin,
    248                        const SkIRect& srcRect, const SkIPoint& dstPoint,
    249                        bool canDiscardOutsideDstRect) override;
    250 
    251     // binds texture unit in GL
    252     void setTextureUnit(int unitIdx);
    253 
    254     /**
    255      * primitiveProcessorTextures must contain GrPrimitiveProcessor::numTextureSamplers() *
    256      * numPrimitiveProcessorTextureSets entries.
    257      */
    258     void resolveAndGenerateMipMapsForProcessorTextures(
    259             const GrPrimitiveProcessor&, const GrPipeline&,
    260             const GrTextureProxy* const primitiveProcessorTextures[],
    261             int numPrimitiveProcessorTextureSets);
    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     // If DynamicStateArrays is not null then dynamicStateArraysLength is the number of dynamic
    266     // state entries in each array.
    267     bool flushGLState(GrRenderTarget*, GrSurfaceOrigin, const GrPrimitiveProcessor&,
    268                       const GrPipeline&, const GrPipeline::FixedDynamicState*,
    269                       const GrPipeline::DynamicStateArrays*, int dynamicStateArraysLength,
    270                       bool willDrawPoints);
    271 
    272     void flushProgram(sk_sp<GrGLProgram>);
    273 
    274     // Version for programs that aren't GrGLProgram.
    275     void flushProgram(GrGLuint);
    276 
    277     // Sets up vertex/instance attribute pointers and strides.
    278     void setupGeometry(const GrBuffer* indexBuffer,
    279                        const GrBuffer* vertexBuffer,
    280                        int baseVertex,
    281                        const GrBuffer* instanceBuffer,
    282                        int baseInstance,
    283                        GrPrimitiveRestart);
    284 
    285     void flushBlend(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle&);
    286 
    287     void onFinishFlush(bool insertedSemaphores) override;
    288 
    289     bool copySurfaceAsDraw(GrSurface* dst, GrSurfaceOrigin dstOrigin,
    290                            GrSurface* src, GrSurfaceOrigin srcOrigin,
    291                            const SkIRect& srcRect, const SkIPoint& dstPoint);
    292     void copySurfaceAsCopyTexSubImage(GrSurface* dst, GrSurfaceOrigin dstOrigin,
    293                                       GrSurface* src, GrSurfaceOrigin srcOrigin,
    294                                       const SkIRect& srcRect, const SkIPoint& dstPoint);
    295     bool copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurfaceOrigin dstOrigin,
    296                                       GrSurface* src, GrSurfaceOrigin srcOrigin,
    297                                       const SkIRect& srcRect, const SkIPoint& dstPoint);
    298 
    299     static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
    300 
    301     class ProgramCache : public ::SkNoncopyable {
    302     public:
    303         ProgramCache(GrGLGpu* gpu);
    304         ~ProgramCache();
    305 
    306         void abandon();
    307         GrGLProgram* refProgram(GrGLGpu*, GrRenderTarget*, GrSurfaceOrigin,
    308                                 const GrPrimitiveProcessor&,
    309                                 const GrTextureProxy* const primProcProxies[],
    310                                 const GrPipeline&, bool hasPointSize);
    311 
    312     private:
    313         // We may actually have kMaxEntries+1 shaders in the GL context because we create a new
    314         // shader before evicting from the cache.
    315         static const int kMaxEntries = 128;
    316 
    317         struct Entry;
    318 
    319         // binary search for entry matching desc. returns index into fEntries that matches desc or ~
    320         // of the index of where it should be inserted.
    321         int search(const GrProgramDesc& desc) const;
    322 
    323         struct DescHash {
    324             uint32_t operator()(const GrProgramDesc& desc) const {
    325                 return SkOpts::hash_fn(desc.asKey(), desc.keyLength(), 0);
    326             }
    327         };
    328 
    329         SkLRUCache<GrProgramDesc, std::unique_ptr<Entry>, DescHash> fMap;
    330 
    331         GrGLGpu*                    fGpu;
    332 #ifdef PROGRAM_CACHE_STATS
    333         int                         fTotalRequests;
    334         int                         fCacheMisses;
    335         int                         fHashMisses; // cache hit but hash table missed
    336 #endif
    337     };
    338 
    339     void flushColorWrite(bool writeColor);
    340     void flushClearColor(GrGLfloat r, GrGLfloat g, GrGLfloat b, GrGLfloat a);
    341 
    342     // flushes the scissor. see the note on flushBoundTextureAndParams about
    343     // flushing the scissor after that function is called.
    344     void flushScissor(const GrScissorState&,
    345                       const GrGLIRect& rtViewport,
    346                       GrSurfaceOrigin rtOrigin);
    347 
    348     // disables the scissor
    349     void disableScissor();
    350 
    351     void flushWindowRectangles(const GrWindowRectsState&, const GrGLRenderTarget*, GrSurfaceOrigin);
    352     void disableWindowRectangles();
    353 
    354     // sets a texture unit to use for texture operations other than binding a texture to a program.
    355     // ensures that such operations don't negatively interact with tracking bound textures.
    356     void setScratchTextureUnit();
    357 
    358     // The passed bounds contains the render target's color values that will subsequently be
    359     // written.
    360     void flushRenderTarget(GrGLRenderTarget*, GrSurfaceOrigin, const SkIRect& bounds);
    361     // This version has an implicit bounds of the entire render target.
    362     void flushRenderTarget(GrGLRenderTarget*);
    363     // This version can be used when the render target's colors will not be written.
    364     void flushRenderTargetNoColorWrites(GrGLRenderTarget*);
    365 
    366     // Need not be called if flushRenderTarget is used.
    367     void flushViewport(const GrGLIRect&);
    368 
    369     void flushStencil(const GrStencilSettings&);
    370     void disableStencil();
    371 
    372     // rt is used only if useHWAA is true.
    373     void flushHWAAState(GrRenderTarget* rt, bool useHWAA, bool stencilEnabled);
    374 
    375     void flushFramebufferSRGB(bool enable);
    376 
    377     // helper for onCreateTexture and writeTexturePixels
    378     enum UploadType {
    379         kNewTexture_UploadType,   // we are creating a new texture
    380         kWrite_UploadType,        // we are using TexSubImage2D to copy data to an existing texture
    381     };
    382     bool uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight, GrGLenum target,
    383                        UploadType uploadType, int left, int top, int width, int height,
    384                        GrPixelConfig dataConfig, const GrMipLevel texels[], int mipLevelCount,
    385                        GrMipMapsStatus* mipMapsStatus = nullptr);
    386 
    387     // helper for onCreateCompressedTexture. Compressed textures are read-only so we
    388     // only use this to populate a new texture.
    389     bool uploadCompressedTexData(GrPixelConfig texConfig, int texWidth, int texHeight,
    390                                  GrGLenum target, GrPixelConfig dataConfig,
    391                                  const GrMipLevel texels[], int mipLevelCount,
    392                                  GrMipMapsStatus* mipMapsStatus = nullptr);
    393 
    394     bool createRenderTargetObjects(const GrSurfaceDesc&, const GrGLTextureInfo& texInfo,
    395                                    GrGLRenderTarget::IDDesc*);
    396 
    397     enum TempFBOTarget {
    398         kSrc_TempFBOTarget,
    399         kDst_TempFBOTarget
    400     };
    401 
    402     // Binds a surface as a FBO for copying, reading, or clearing. If the surface already owns an
    403     // FBO ID then that ID is bound. If not the surface is temporarily bound to a FBO and that FBO
    404     // is bound. This must be paired with a call to unbindSurfaceFBOForPixelOps().
    405     void bindSurfaceFBOForPixelOps(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport,
    406                                    TempFBOTarget tempFBOTarget);
    407 
    408     // Must be called if bindSurfaceFBOForPixelOps was used to bind a surface for copying.
    409     void unbindTextureFBOForPixelOps(GrGLenum fboTarget, GrSurface* surface);
    410 
    411 #ifdef SK_ENABLE_DUMP_GPU
    412     void onDumpJSON(SkJSONWriter*) const override;
    413 #endif
    414 
    415     bool createCopyProgram(GrTexture* srcTexture);
    416     bool createMipmapProgram(int progIdx);
    417 
    418     std::unique_ptr<GrGLContext> fGLContext;
    419 
    420     // GL program-related state
    421     ProgramCache*               fProgramCache;
    422 
    423     ///////////////////////////////////////////////////////////////////////////
    424     ///@name Caching of GL State
    425     ///@{
    426     int                         fHWActiveTextureUnitIdx;
    427 
    428     GrGLuint                    fHWProgramID;
    429     sk_sp<GrGLProgram>          fHWProgram;
    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         SkPMColor4f     fConstColor;
    567         bool            fConstColorValid;
    568         TriState        fEnabled;
    569 
    570         void invalidate() {
    571             fEquation = kIllegal_GrBlendEquation;
    572             fSrcCoeff = kIllegal_GrBlendCoeff;
    573             fDstCoeff = kIllegal_GrBlendCoeff;
    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     GrGLfloat fHWClearColor[4];
    591 
    592     GrGLuint fBoundDrawFramebuffer = 0;
    593 
    594     // EXT_raster_multisample.
    595     TriState                                fHWRasterMultisampleEnabled;
    596     int                                     fHWNumRasterSamples;
    597     ///@}
    598 
    599     /** IDs for copy surface program. (3 sampler types) */
    600     struct {
    601         GrGLuint    fProgram = 0;
    602         GrGLint     fTextureUniform = 0;
    603         GrGLint     fTexCoordXformUniform = 0;
    604         GrGLint     fPosXformUniform = 0;
    605     }                                       fCopyPrograms[3];
    606     sk_sp<GrGLBuffer>                       fCopyProgramArrayBuffer;
    607 
    608     /** IDs for texture mipmap program. (4 filter configurations) */
    609     struct {
    610         GrGLuint    fProgram = 0;
    611         GrGLint     fTextureUniform = 0;
    612         GrGLint     fTexCoordXformUniform = 0;
    613     }                                       fMipmapPrograms[4];
    614     sk_sp<GrGLBuffer>                       fMipmapProgramArrayBuffer;
    615 
    616     static int TextureToCopyProgramIdx(GrTexture* texture);
    617 
    618     static int TextureSizeToMipmapProgramIdx(int width, int height) {
    619         const bool wide = (width > 1) && SkToBool(width & 0x1);
    620         const bool tall = (height > 1) && SkToBool(height & 0x1);
    621         return (wide ? 0x2 : 0x0) | (tall ? 0x1 : 0x0);
    622     }
    623 
    624     GrPrimitiveType fLastPrimitiveType;
    625 
    626     class SamplerObjectCache;
    627     std::unique_ptr<SamplerObjectCache> fSamplerObjectCache;
    628 
    629     std::unique_ptr<GrGLGpuRTCommandBuffer>      fCachedRTCommandBuffer;
    630     std::unique_ptr<GrGLGpuTextureCommandBuffer> fCachedTexCommandBuffer;
    631 
    632     friend class GrGLPathRendering; // For accessing setTextureUnit.
    633 
    634     typedef GrGpu INHERITED;
    635 };
    636 
    637 #endif
    638