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 "GrGLIndexBuffer.h"
     14 #include "GrGLPathRendering.h"
     15 #include "GrGLProgram.h"
     16 #include "GrGLRenderTarget.h"
     17 #include "GrGLStencilAttachment.h"
     18 #include "GrGLTexture.h"
     19 #include "GrGLTransferBuffer.h"
     20 #include "GrGLVertexArray.h"
     21 #include "GrGLVertexBuffer.h"
     22 #include "GrGpu.h"
     23 #include "GrPipelineBuilder.h"
     24 #include "GrXferProcessor.h"
     25 #include "SkTypes.h"
     26 
     27 class GrPipeline;
     28 class GrNonInstancedVertices;
     29 class GrSwizzle;
     30 
     31 #ifdef SK_DEVELOPER
     32 #define PROGRAM_CACHE_STATS
     33 #endif
     34 
     35 class GrGLGpu : public GrGpu {
     36 public:
     37     static GrGpu* Create(GrBackendContext backendContext, const GrContextOptions& options,
     38                          GrContext* context);
     39     ~GrGLGpu() override;
     40 
     41     void contextAbandoned() 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     void discard(GrRenderTarget*) override;
     58 
     59     // Used by GrGLProgram to configure OpenGL state.
     60     void bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture);
     61 
     62     bool onGetReadPixelsInfo(GrSurface* srcSurface, int readWidth, int readHeight, size_t rowBytes,
     63                              GrPixelConfig readConfig, DrawPreference*,
     64                              ReadPixelTempDrawInfo*) override;
     65 
     66     bool onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height,
     67                               GrPixelConfig srcConfig, DrawPreference*,
     68                               WritePixelTempDrawInfo*) override;
     69 
     70     bool initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) const override;
     71 
     72     // These functions should be used to bind GL objects. They track the GL state and skip redundant
     73     // bindings. Making the equivalent glBind calls directly will confuse the state tracking.
     74     void bindVertexArray(GrGLuint id) {
     75         fHWGeometryState.setVertexArrayID(this, id);
     76     }
     77     void bindIndexBufferAndDefaultVertexArray(GrGLuint id) {
     78         fHWGeometryState.setIndexBufferIDOnDefaultVertexArray(this, id);
     79     }
     80     void bindVertexBuffer(GrGLuint id) {
     81         fHWGeometryState.setVertexBufferID(this, id);
     82     }
     83 
     84     // These callbacks update state tracking when GL objects are deleted. They are called from
     85     // GrGLResource onRelease functions.
     86     void notifyVertexArrayDelete(GrGLuint id) {
     87         fHWGeometryState.notifyVertexArrayDelete(id);
     88     }
     89     void notifyVertexBufferDelete(GrGLuint id) {
     90         fHWGeometryState.notifyVertexBufferDelete(id);
     91     }
     92     void notifyIndexBufferDelete(GrGLuint id) {
     93         fHWGeometryState.notifyIndexBufferDelete(id);
     94     }
     95 
     96     void buildProgramDesc(GrProgramDesc*,
     97                           const GrPrimitiveProcessor&,
     98                           const GrPipeline&) const override;
     99 
    100     // id and type (GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER) of buffer to bind
    101     void bindBuffer(GrGLuint id, GrGLenum type);
    102 
    103     void releaseBuffer(GrGLuint id, GrGLenum type);
    104 
    105     // sizes are in bytes
    106     void* mapBuffer(GrGLuint id, GrGLenum type, GrGLBufferImpl::Usage usage, size_t currentSize,
    107                     size_t requestedSize);
    108 
    109     void unmapBuffer(GrGLuint id, GrGLenum type, void* mapPtr);
    110 
    111     void bufferData(GrGLuint id, GrGLenum type, GrGLBufferImpl::Usage usage, size_t currentSize,
    112                     const void* src, size_t srcSizeInBytes);
    113 
    114     const GrGLContext* glContextForTesting() const override {
    115         return &this->glContext();
    116     }
    117 
    118     void clearStencil(GrRenderTarget*) override;
    119 
    120     void invalidateBoundRenderTarget() {
    121         fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
    122     }
    123 
    124     GrStencilAttachment* createStencilAttachmentForRenderTarget(const GrRenderTarget* rt,
    125                                                                 int width,
    126                                                                 int height) override;
    127 
    128     GrBackendObject createTestingOnlyBackendTexture(void* pixels, int w, int h,
    129                                                     GrPixelConfig config) override;
    130     bool isTestingOnlyBackendTexture(GrBackendObject) const override;
    131     void deleteTestingOnlyBackendTexture(GrBackendObject, bool abandonTexture) override;
    132 
    133     void resetShaderCacheForTesting() const override;
    134 
    135     void drawDebugWireRect(GrRenderTarget*, const SkIRect&, GrColor) override;
    136 
    137     void finishDrawTarget() override;
    138 
    139 private:
    140     GrGLGpu(GrGLContext* ctx, GrContext* context);
    141 
    142     // GrGpu overrides
    143     void onResetContext(uint32_t resetBits) override;
    144 
    145     void xferBarrier(GrRenderTarget*, GrXferBarrierType) override;
    146 
    147     GrTexture* onCreateTexture(const GrSurfaceDesc& desc, GrGpuResource::LifeCycle lifeCycle,
    148                                const void* srcData, size_t rowBytes) override;
    149     GrTexture* onCreateCompressedTexture(const GrSurfaceDesc& desc,
    150                                          GrGpuResource::LifeCycle lifeCycle,
    151                                          const void* srcData) override;
    152     GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) override;
    153     GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) override;
    154     GrTransferBuffer* onCreateTransferBuffer(size_t size, TransferType type) override;
    155     GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&, GrWrapOwnership) override;
    156     GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&,
    157                                               GrWrapOwnership) override;
    158     GrRenderTarget* onWrapBackendTextureAsRenderTarget(const GrBackendTextureDesc&,
    159                                                        GrWrapOwnership) override;
    160     // Given a GrPixelConfig return the index into the stencil format array on GrGLCaps to a
    161     // compatible stencil format, or negative if there is no compatible stencil format.
    162     int getCompatibleStencilIndex(GrPixelConfig config);
    163 
    164     // If |desc.fTextureStorageAllocator| exists, use that to create the
    165     // texture. Otherwise, create the texture directly.
    166     // Returns whether the texture is successfully created. On success, the
    167     // result is stored in |info|.
    168     // The texture is populated with |srcData|, if it exists.
    169     // The texture parameters are cached in |initialTexParams|.
    170     bool createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info,
    171                            bool renderTarget, const void* srcData,
    172                            GrGLTexture::TexParams* initialTexParams, size_t rowBytes);
    173     bool createTextureExternalAllocatorImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info,
    174                                             const void* srcData, size_t rowBytes);
    175 
    176     void onClear(GrRenderTarget*, const SkIRect& rect, GrColor color) override;
    177 
    178     void onClearStencilClip(GrRenderTarget*, const SkIRect& rect, bool insideClip) override;
    179 
    180     bool onMakeCopyForTextureParams(GrTexture*, const GrTextureParams&,
    181                                     GrTextureProducer::CopyParams*) const override;
    182 
    183     // Checks whether glReadPixels can be called to get pixel values in readConfig from the
    184     // render target.
    185     bool readPixelsSupported(GrRenderTarget* target, GrPixelConfig readConfig);
    186 
    187     // Checks whether glReadPixels can be called to get pixel values in readConfig from a
    188     // render target that has renderTargetConfig. This may have to create a temporary
    189     // render target and thus is less preferable than the variant that takes a render target.
    190     bool readPixelsSupported(GrPixelConfig renderTargetConfig, GrPixelConfig readConfig);
    191 
    192     // Checks whether glReadPixels can be called to get pixel values in readConfig from a
    193     // render target that has the same config as surfaceForConfig. Calls one of the the two
    194     // variations above, depending on whether the surface is a render target or not.
    195     bool readPixelsSupported(GrSurface* surfaceForConfig, GrPixelConfig readConfig);
    196 
    197     bool onReadPixels(GrSurface*,
    198                       int left, int top,
    199                       int width, int height,
    200                       GrPixelConfig,
    201                       void* buffer,
    202                       size_t rowBytes) override;
    203 
    204     bool onWritePixels(GrSurface*,
    205                        int left, int top, int width, int height,
    206                        GrPixelConfig config, const void* buffer,
    207                        size_t rowBytes) override;
    208 
    209     bool onTransferPixels(GrSurface*,
    210                           int left, int top, int width, int height,
    211                           GrPixelConfig config, GrTransferBuffer* buffer,
    212                           size_t offset, size_t rowBytes) override;
    213 
    214     void onResolveRenderTarget(GrRenderTarget* target) override;
    215 
    216     void onDraw(const DrawArgs&, const GrNonInstancedVertices&) override;
    217 
    218     bool onCopySurface(GrSurface* dst,
    219                        GrSurface* src,
    220                        const SkIRect& srcRect,
    221                        const SkIPoint& dstPoint) override;
    222 
    223     // binds texture unit in GL
    224     void setTextureUnit(int unitIdx);
    225 
    226     // Flushes state from GrPipeline to GL. Returns false if the state couldn't be set.
    227     bool flushGLState(const DrawArgs&);
    228 
    229     // Sets up vertex attribute pointers and strides. On return indexOffsetInBytes gives the offset
    230     // an into the index buffer. It does not account for vertices.startIndex() but rather the start
    231     // index is relative to the returned offset.
    232     void setupGeometry(const GrPrimitiveProcessor&,
    233                        const GrNonInstancedVertices& vertices,
    234                        size_t* indexOffsetInBytes);
    235 
    236     void flushBlend(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle&);
    237 
    238     bool hasExtension(const char* ext) const { return fGLContext->hasExtension(ext); }
    239 
    240     void copySurfaceAsDraw(GrSurface* dst,
    241                            GrSurface* src,
    242                            const SkIRect& srcRect,
    243                            const SkIPoint& dstPoint);
    244     void copySurfaceAsCopyTexSubImage(GrSurface* dst,
    245                                       GrSurface* src,
    246                                       const SkIRect& srcRect,
    247                                       const SkIPoint& dstPoint);
    248     bool copySurfaceAsBlitFramebuffer(GrSurface* dst,
    249                                       GrSurface* src,
    250                                       const SkIRect& srcRect,
    251                                       const SkIPoint& dstPoint);
    252 
    253     void stampRectUsingProgram(GrGLuint program, const SkRect& bounds, GrGLint posXformUniform,
    254                                GrGLuint arrayBuffer);
    255 
    256     void setupPixelLocalStorage(const DrawArgs& args);
    257 
    258     static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
    259 
    260     class ProgramCache : public ::SkNoncopyable {
    261     public:
    262         ProgramCache(GrGLGpu* gpu);
    263         ~ProgramCache();
    264 
    265         void reset();
    266         void abandon();
    267         GrGLProgram* refProgram(const DrawArgs&);
    268 
    269     private:
    270         enum {
    271             // We may actually have kMaxEntries+1 shaders in the GL context because we create a new
    272             // shader before evicting from the cache.
    273             kMaxEntries = 128,
    274             kHashBits = 6,
    275         };
    276 
    277         struct Entry;
    278 
    279         struct ProgDescLess;
    280 
    281         // binary search for entry matching desc. returns index into fEntries that matches desc or ~
    282         // of the index of where it should be inserted.
    283         int search(const GrProgramDesc& desc) const;
    284 
    285         // sorted array of all the entries
    286         Entry*                      fEntries[kMaxEntries];
    287         // hash table based on lowest kHashBits bits of the program key. Used to avoid binary
    288         // searching fEntries.
    289         Entry*                      fHashTable[1 << kHashBits];
    290 
    291         int                         fCount;
    292         unsigned int                fCurrLRUStamp;
    293         GrGLGpu*                    fGpu;
    294 #ifdef PROGRAM_CACHE_STATS
    295         int                         fTotalRequests;
    296         int                         fCacheMisses;
    297         int                         fHashMisses; // cache hit but hash table missed
    298 #endif
    299     };
    300 
    301     void flushColorWrite(bool writeColor);
    302     void flushDrawFace(GrPipelineBuilder::DrawFace face);
    303 
    304     // flushes the scissor. see the note on flushBoundTextureAndParams about
    305     // flushing the scissor after that function is called.
    306     void flushScissor(const GrScissorState&,
    307                       const GrGLIRect& rtViewport,
    308                       GrSurfaceOrigin rtOrigin);
    309 
    310     // disables the scissor
    311     void disableScissor();
    312 
    313     void initFSAASupport();
    314 
    315     // determines valid stencil formats
    316     void initStencilFormats();
    317 
    318     // sets a texture unit to use for texture operations other than binding a texture to a program.
    319     // ensures that such operations don't negatively interact with tracking bound textures.
    320     void setScratchTextureUnit();
    321 
    322     // bounds is region that may be modified.
    323     // nullptr means whole target. Can be an empty rect.
    324     void flushRenderTarget(GrGLRenderTarget*, const SkIRect* bounds);
    325     // Handles cases where a surface will be updated without a call to flushRenderTarget
    326     void didWriteToSurface(GrSurface*, const SkIRect* bounds) const;
    327 
    328     // Need not be called if flushRenderTarget is used.
    329     void flushViewport(const GrGLIRect&);
    330 
    331     void flushStencil(const GrStencilSettings&);
    332 
    333     // rt is used only if useHWAA is true.
    334     void flushHWAAState(GrRenderTarget* rt, bool useHWAA, bool stencilEnabled);
    335 
    336     // helper for onCreateTexture and writeTexturePixels
    337     enum UploadType {
    338         kNewTexture_UploadType,    // we are creating a new texture
    339         kWrite_UploadType,         // we are using TexSubImage2D to copy data to an existing texture
    340         kTransfer_UploadType,      // we are using a transfer buffer to copy data
    341     };
    342     bool uploadTexData(const GrSurfaceDesc& desc,
    343                        GrGLenum target,
    344                        UploadType uploadType,
    345                        int left, int top, int width, int height,
    346                        GrPixelConfig dataConfig,
    347                        const void* data,
    348                        size_t rowBytes);
    349 
    350     // helper for onCreateCompressedTexture. If width and height are
    351     // set to -1, then this function will use desc.fWidth and desc.fHeight
    352     // for the size of the data. The isNewTexture flag should be set to true
    353     // whenever a new texture needs to be created. Otherwise, we assume that
    354     // the texture is already in GPU memory and that it's going to be updated
    355     // with new data.
    356     bool uploadCompressedTexData(const GrSurfaceDesc& desc,
    357                                  GrGLenum target,
    358                                  const void* data,
    359                                  UploadType uploadType = kNewTexture_UploadType,
    360                                  int left = 0, int top = 0,
    361                                  int width = -1, int height = -1);
    362 
    363     bool createRenderTargetObjects(const GrSurfaceDesc&, GrGpuResource::LifeCycle lifeCycle,
    364                                    const GrGLTextureInfo& texInfo, GrGLRenderTarget::IDDesc*);
    365 
    366     enum TempFBOTarget {
    367         kSrc_TempFBOTarget,
    368         kDst_TempFBOTarget
    369     };
    370 
    371     // Binds a surface as a FBO for a copy operation. If the surface already owns an FBO ID then
    372     // that ID is bound. If not the surface is temporarily bound to a FBO and that FBO is bound.
    373     // This must be paired with a call to unbindSurfaceFBOForCopy().
    374     void bindSurfaceFBOForCopy(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport,
    375                               TempFBOTarget tempFBOTarget);
    376 
    377     // Must be called if bindSurfaceFBOForCopy was used to bind a surface for copying.
    378     void unbindTextureFBOForCopy(GrGLenum fboTarget, GrSurface* surface);
    379 
    380     SkAutoTUnref<GrGLContext>  fGLContext;
    381 
    382     void createCopyPrograms();
    383     void createWireRectProgram();
    384     void createUnitRectBuffer();
    385 
    386     void createPLSSetupProgram();
    387 
    388     // GL program-related state
    389     ProgramCache*               fProgramCache;
    390 
    391     ///////////////////////////////////////////////////////////////////////////
    392     ///@name Caching of GL State
    393     ///@{
    394     int                         fHWActiveTextureUnitIdx;
    395     GrGLuint                    fHWProgramID;
    396 
    397     enum TriState {
    398         kNo_TriState,
    399         kYes_TriState,
    400         kUnknown_TriState
    401     };
    402 
    403     GrGLuint                    fTempSrcFBOID;
    404     GrGLuint                    fTempDstFBOID;
    405 
    406     GrGLuint                    fStencilClearFBOID;
    407 
    408     // last scissor / viewport scissor state seen by the GL.
    409     struct {
    410         TriState    fEnabled;
    411         GrGLIRect   fRect;
    412         void invalidate() {
    413             fEnabled = kUnknown_TriState;
    414             fRect.invalidate();
    415         }
    416     } fHWScissorSettings;
    417 
    418     GrGLIRect                   fHWViewport;
    419 
    420     /**
    421      * Tracks bound vertex and index buffers and vertex attrib array state.
    422      */
    423     class HWGeometryState {
    424     public:
    425         HWGeometryState() { fVBOVertexArray = nullptr; this->invalidate(); }
    426 
    427         ~HWGeometryState() { delete fVBOVertexArray; }
    428 
    429         void invalidate() {
    430             fBoundVertexArrayIDIsValid = false;
    431             fBoundVertexBufferIDIsValid = false;
    432             fDefaultVertexArrayBoundIndexBufferID = false;
    433             fDefaultVertexArrayBoundIndexBufferIDIsValid = false;
    434             fDefaultVertexArrayAttribState.invalidate();
    435             if (fVBOVertexArray) {
    436                 fVBOVertexArray->invalidateCachedState();
    437             }
    438         }
    439 
    440         void notifyVertexArrayDelete(GrGLuint id) {
    441             if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) {
    442                 // Does implicit bind to 0
    443                 fBoundVertexArrayID = 0;
    444             }
    445         }
    446 
    447         void setVertexArrayID(GrGLGpu* gpu, GrGLuint arrayID) {
    448             if (!gpu->glCaps().vertexArrayObjectSupport()) {
    449                 SkASSERT(0 == arrayID);
    450                 return;
    451             }
    452             if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) {
    453                 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID));
    454                 fBoundVertexArrayIDIsValid = true;
    455                 fBoundVertexArrayID = arrayID;
    456             }
    457         }
    458 
    459         void notifyVertexBufferDelete(GrGLuint id) {
    460             if (fBoundVertexBufferIDIsValid && id == fBoundVertexBufferID) {
    461                 fBoundVertexBufferID = 0;
    462             }
    463             if (fVBOVertexArray) {
    464                 fVBOVertexArray->notifyVertexBufferDelete(id);
    465             }
    466             fDefaultVertexArrayAttribState.notifyVertexBufferDelete(id);
    467         }
    468 
    469         void notifyIndexBufferDelete(GrGLuint id) {
    470             if (fDefaultVertexArrayBoundIndexBufferIDIsValid &&
    471                 id == fDefaultVertexArrayBoundIndexBufferID) {
    472                 fDefaultVertexArrayBoundIndexBufferID = 0;
    473             }
    474             if (fVBOVertexArray) {
    475                 fVBOVertexArray->notifyIndexBufferDelete(id);
    476             }
    477         }
    478 
    479         void setVertexBufferID(GrGLGpu* gpu, GrGLuint id) {
    480             if (!fBoundVertexBufferIDIsValid || id != fBoundVertexBufferID) {
    481                 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ARRAY_BUFFER, id));
    482                 fBoundVertexBufferIDIsValid = true;
    483                 fBoundVertexBufferID = id;
    484             }
    485         }
    486 
    487         /**
    488          * Binds the default vertex array and binds the index buffer. This is used when binding
    489          * an index buffer in order to update it.
    490          */
    491         void setIndexBufferIDOnDefaultVertexArray(GrGLGpu* gpu, GrGLuint id) {
    492             this->setVertexArrayID(gpu, 0);
    493             if (!fDefaultVertexArrayBoundIndexBufferIDIsValid ||
    494                 id != fDefaultVertexArrayBoundIndexBufferID) {
    495                 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, id));
    496                 fDefaultVertexArrayBoundIndexBufferIDIsValid = true;
    497                 fDefaultVertexArrayBoundIndexBufferID = id;
    498             }
    499         }
    500 
    501         /**
    502          * Binds the vertex array object that should be used to render from the vertex buffer.
    503          * The vertex array is bound and its attrib array state object is returned. The vertex
    504          * buffer is bound. The index buffer (if non-nullptr) is bound to the vertex array. The
    505          * returned GrGLAttribArrayState should be used to set vertex attribute arrays.
    506          */
    507         GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGLGpu* gpu,
    508                                                         const GrGLVertexBuffer* vbuffer,
    509                                                         const GrGLIndexBuffer* ibuffer);
    510 
    511         /** Variants of the above that takes GL buffer IDs. Note that 0 does not imply that a
    512             buffer won't be bound. The "default buffer" will be bound, which is used for client-side
    513             array rendering. */
    514         GrGLAttribArrayState* bindArrayAndBufferToDraw(GrGLGpu* gpu, GrGLuint vbufferID);
    515         GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGLGpu* gpu,
    516                                                         GrGLuint vbufferID,
    517                                                         GrGLuint ibufferID);
    518 
    519     private:
    520         GrGLAttribArrayState* internalBind(GrGLGpu* gpu, GrGLuint vbufferID, GrGLuint* ibufferID);
    521 
    522         GrGLuint                fBoundVertexArrayID;
    523         GrGLuint                fBoundVertexBufferID;
    524         bool                    fBoundVertexArrayIDIsValid;
    525         bool                    fBoundVertexBufferIDIsValid;
    526 
    527         GrGLuint                fDefaultVertexArrayBoundIndexBufferID;
    528         bool                    fDefaultVertexArrayBoundIndexBufferIDIsValid;
    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 and the vertices are in a VBO.
    535         GrGLVertexArray*        fVBOVertexArray;
    536     } fHWGeometryState;
    537 
    538     struct {
    539         GrBlendEquation fEquation;
    540         GrBlendCoeff    fSrcCoeff;
    541         GrBlendCoeff    fDstCoeff;
    542         GrColor         fConstColor;
    543         bool            fConstColorValid;
    544         TriState        fEnabled;
    545 
    546         void invalidate() {
    547             fEquation = static_cast<GrBlendEquation>(-1);
    548             fSrcCoeff = static_cast<GrBlendCoeff>(-1);
    549             fDstCoeff = static_cast<GrBlendCoeff>(-1);
    550             fConstColorValid = false;
    551             fEnabled = kUnknown_TriState;
    552         }
    553     } fHWBlendState;
    554 
    555     TriState fMSAAEnabled;
    556 
    557     GrStencilSettings           fHWStencilSettings;
    558     TriState                    fHWStencilTestEnabled;
    559 
    560 
    561     GrPipelineBuilder::DrawFace fHWDrawFace;
    562     TriState                    fHWWriteToColor;
    563     uint32_t                    fHWBoundRenderTargetUniqueID;
    564     TriState                    fHWSRGBFramebuffer;
    565     SkTArray<uint32_t, true>    fHWBoundTextureUniqueIDs;
    566 
    567     // EXT_raster_multisample.
    568     TriState                    fHWRasterMultisampleEnabled;
    569     int                         fHWNumRasterSamples;
    570     ///@}
    571 
    572     /** IDs for copy surface program. */
    573     struct {
    574         GrGLuint    fProgram;
    575         GrGLint     fTextureUniform;
    576         GrGLint     fTexCoordXformUniform;
    577         GrGLint     fPosXformUniform;
    578     }                           fCopyPrograms[3];
    579     GrGLuint                    fCopyProgramArrayBuffer;
    580 
    581     struct {
    582         GrGLuint fProgram;
    583         GrGLint  fColorUniform;
    584         GrGLint  fRectUniform;
    585     }                           fWireRectProgram;
    586     GrGLuint                    fWireRectArrayBuffer;
    587 
    588     static int TextureTargetToCopyProgramIdx(GrGLenum target) {
    589         switch (target) {
    590             case GR_GL_TEXTURE_2D:
    591                 return 0;
    592             case GR_GL_TEXTURE_EXTERNAL:
    593                 return 1;
    594             case GR_GL_TEXTURE_RECTANGLE:
    595                 return 2;
    596             default:
    597                 SkFAIL("Unexpected texture target type.");
    598                 return 0;
    599         }
    600     }
    601 
    602     struct {
    603         GrGLuint    fProgram;
    604         GrGLint     fPosXformUniform;
    605         GrGLuint    fArrayBuffer;
    606     } fPLSSetupProgram;
    607 
    608     bool fHWPLSEnabled;
    609     bool fPLSHasBeenUsed;
    610 
    611     typedef GrGpu INHERITED;
    612     friend class GrGLPathRendering; // For accessing setTextureUnit.
    613 };
    614 
    615 #endif
    616