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