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 
      9 
     10 #ifndef GrGpuGL_DEFINED
     11 #define GrGpuGL_DEFINED
     12 
     13 #include "GrBinHashKey.h"
     14 #include "GrDrawState.h"
     15 #include "GrGpu.h"
     16 #include "GrGLContextInfo.h"
     17 #include "GrGLIndexBuffer.h"
     18 #include "GrGLIRect.h"
     19 #include "GrGLProgram.h"
     20 #include "GrGLStencilBuffer.h"
     21 #include "GrGLTexture.h"
     22 #include "GrGLVertexBuffer.h"
     23 #include "../GrTHashCache.h"
     24 
     25 class GrGpuGL : public GrGpu {
     26 public:
     27     GrGpuGL(const GrGLContextInfo& ctxInfo);
     28     virtual ~GrGpuGL();
     29 
     30     const GrGLInterface* glInterface() const {
     31         return fGLContextInfo.interface();
     32     }
     33     GrGLBinding glBinding() const { return fGLContextInfo.binding(); }
     34     GrGLVersion glVersion() const { return fGLContextInfo.version(); }
     35     GrGLSLGeneration glslGeneration() const {
     36         return fGLContextInfo.glslGeneration();
     37     }
     38 
     39     // Used by GrGLProgram to bind necessary textures for GrGLEffects.
     40     void bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture);
     41 
     42     bool programUnitTest();
     43 
     44     // GrGpu overrides
     45     virtual GrPixelConfig preferredReadPixelsConfig(GrPixelConfig config)
     46                                                             const SK_OVERRIDE;
     47     virtual GrPixelConfig preferredWritePixelsConfig(GrPixelConfig config)
     48                                                             const SK_OVERRIDE;
     49     virtual bool readPixelsWillPayForYFlip(
     50                                     GrRenderTarget* renderTarget,
     51                                     int left, int top,
     52                                     int width, int height,
     53                                     GrPixelConfig config,
     54                                     size_t rowBytes) const SK_OVERRIDE;
     55     virtual bool fullReadPixelsIsFasterThanPartial() const SK_OVERRIDE;
     56 
     57     virtual void abandonResources() SK_OVERRIDE;
     58 
     59 private:
     60     // GrGpu overrides
     61     virtual void onResetContext() SK_OVERRIDE;
     62 
     63     virtual GrTexture* onCreateTexture(const GrTextureDesc& desc,
     64                                        const void* srcData,
     65                                        size_t rowBytes) SK_OVERRIDE;
     66     virtual GrVertexBuffer* onCreateVertexBuffer(uint32_t size,
     67                                                  bool dynamic) SK_OVERRIDE;
     68     virtual GrIndexBuffer* onCreateIndexBuffer(uint32_t size,
     69                                                bool dynamic) SK_OVERRIDE;
     70     virtual GrPath* onCreatePath(const SkPath&) SK_OVERRIDE;
     71     virtual GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&) SK_OVERRIDE;
     72     virtual GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&) SK_OVERRIDE;
     73     virtual bool createStencilBufferForRenderTarget(GrRenderTarget* rt,
     74                                                     int width,
     75                                                     int height) SK_OVERRIDE;
     76     virtual bool attachStencilBufferToRenderTarget(
     77         GrStencilBuffer* sb,
     78         GrRenderTarget* rt) SK_OVERRIDE;
     79 
     80     virtual void onClear(const GrIRect* rect, GrColor color) SK_OVERRIDE;
     81 
     82     virtual void onForceRenderTargetFlush() SK_OVERRIDE;
     83 
     84     virtual bool onReadPixels(GrRenderTarget* target,
     85                               int left, int top,
     86                               int width, int height,
     87                               GrPixelConfig,
     88                               void* buffer,
     89                               size_t rowBytes,
     90                               bool invertY) SK_OVERRIDE;
     91 
     92     virtual void onWriteTexturePixels(GrTexture* texture,
     93                                       int left, int top, int width, int height,
     94                                       GrPixelConfig config, const void* buffer,
     95                                       size_t rowBytes) SK_OVERRIDE;
     96 
     97     virtual void onResolveRenderTarget(GrRenderTarget* target) SK_OVERRIDE;
     98 
     99     virtual void onGpuDraw(const DrawInfo&) SK_OVERRIDE;
    100 
    101     virtual void setStencilPathSettings(const GrPath&,
    102                                         SkPath::FillType,
    103                                         GrStencilSettings* settings)
    104                                         SK_OVERRIDE;
    105     virtual void onGpuStencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE;
    106 
    107     virtual void clearStencil() SK_OVERRIDE;
    108     virtual void clearStencilClip(const GrIRect& rect,
    109                                   bool insideClip) SK_OVERRIDE;
    110     virtual bool flushGraphicsState(DrawType) SK_OVERRIDE;
    111 
    112     const GrGLCaps& glCaps() const { return fGLContextInfo.caps(); }
    113 
    114     // binds texture unit in GL
    115     void setTextureUnit(int unitIdx);
    116 
    117     // Sets up vertex attribute pointers and strides. On return startIndexOffset specifies an
    118     // offset into the index buffer to the first index to be read (in addition to
    119     // info.startIndex()). It accounts for the fact that index buffer pool may have provided space
    120     // in the middle of a larger index buffer.
    121     void setupGeometry(const DrawInfo& info, int* startIndexOffset);
    122     // binds appropriate vertex and index buffers, also returns any extra verts or indices to
    123     // offset by based on how space was allocated in pool VB/IBs.
    124     void setBuffers(bool indexed, int* extraVertexOffset, int* extraIndexOffset);
    125 
    126     // Subclasses should call this to flush the blend state.
    127     // The params should be the final coefficients to apply
    128     // (after any blending optimizations or dual source blending considerations
    129     // have been accounted for).
    130     void flushBlend(bool isLines, GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff);
    131 
    132     bool hasExtension(const char* ext) const {
    133         return fGLContextInfo.hasExtension(ext);
    134     }
    135 
    136     const GrGLContextInfo& glContextInfo() const { return fGLContextInfo; }
    137 
    138     static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
    139 
    140     // for readability of function impls
    141     typedef GrGLProgram::Desc        ProgramDesc;
    142 
    143     class ProgramCache : public ::GrNoncopyable {
    144     public:
    145         ProgramCache(const GrGLContextInfo& gl);
    146 
    147         void abandon();
    148         GrGLProgram* getProgram(const GrGLProgram::Desc& desc, const GrEffectStage* stages[]);
    149     private:
    150         enum {
    151             kKeySize = sizeof(ProgramDesc),
    152             // We may actually have kMaxEntries+1 shaders in the GL context because we create a new
    153             // shader before evicting from the cache.
    154             kMaxEntries = 32
    155         };
    156 
    157         class Entry;
    158         // The value of the hash key is based on the ProgramDesc.
    159         typedef GrTBinHashKey<Entry, kKeySize> ProgramHashKey;
    160 
    161         class Entry : public ::GrNoncopyable {
    162         public:
    163             Entry() : fProgram(NULL), fLRUStamp(0) {}
    164             Entry& operator = (const Entry& entry) {
    165                 GrSafeRef(entry.fProgram.get());
    166                 fProgram.reset(entry.fProgram.get());
    167                 fKey = entry.fKey;
    168                 fLRUStamp = entry.fLRUStamp;
    169                 return *this;
    170             }
    171             int compare(const ProgramHashKey& key) const {
    172                 return fKey.compare(key);
    173             }
    174 
    175         public:
    176             SkAutoTUnref<GrGLProgram>   fProgram;
    177             ProgramHashKey              fKey;
    178             unsigned int                fLRUStamp; // Move outside entry?
    179         };
    180 
    181         GrTHashTable<Entry, ProgramHashKey, 8> fHashCache;
    182 
    183         Entry                       fEntries[kMaxEntries];
    184         int                         fCount;
    185         unsigned int                fCurrLRUStamp;
    186         const GrGLContextInfo&      fGL;
    187     };
    188 
    189     // sets the color specified by GrDrawState::setColor()
    190     void flushColor(GrColor color);
    191 
    192     // sets the color specified by GrDrawState::setCoverage()
    193     void flushCoverage(GrColor color);
    194 
    195     // sets the MVP matrix uniform for currently bound program
    196     void flushViewMatrix(DrawType type);
    197 
    198 
    199     // flushes dithering, color-mask, and face culling stat
    200     void flushMiscFixedFunctionState();
    201 
    202     // flushes the scissor. see the note on flushBoundTextureAndParams about
    203     // flushing the scissor after that function is called.
    204     void flushScissor();
    205 
    206     void buildProgram(bool isPoints,
    207                       BlendOptFlags blendOpts,
    208                       GrBlendCoeff dstCoeff,
    209                       ProgramDesc* desc);
    210 
    211     // Inits GrDrawTarget::Caps, subclass may enable additional caps.
    212     void initCaps();
    213 
    214     void initFSAASupport();
    215 
    216     // determines valid stencil formats
    217     void initStencilFormats();
    218 
    219     // notify callbacks to update state tracking when related
    220     // objects are bound to GL or deleted outside of the class
    221     void notifyVertexBufferBind(const GrGLVertexBuffer* buffer);
    222     void notifyVertexBufferDelete(const GrGLVertexBuffer* buffer);
    223     void notifyIndexBufferBind(const GrGLIndexBuffer* buffer);
    224     void notifyIndexBufferDelete(const GrGLIndexBuffer* buffer);
    225     void notifyTextureDelete(GrGLTexture* texture);
    226     void notifyRenderTargetDelete(GrRenderTarget* renderTarget);
    227 
    228     void setSpareTextureUnit();
    229 
    230     // bound is region that may be modified and therefore has to be resolved.
    231     // NULL means whole target. Can be an empty rect.
    232     void flushRenderTarget(const GrIRect* bound);
    233     void flushStencil(DrawType);
    234     void flushAAState(DrawType);
    235 
    236     bool configToGLFormats(GrPixelConfig config,
    237                            bool getSizedInternal,
    238                            GrGLenum* internalFormat,
    239                            GrGLenum* externalFormat,
    240                            GrGLenum* externalType);
    241     // helper for onCreateTexture and writeTexturePixels
    242     bool uploadTexData(const GrGLTexture::Desc& desc,
    243                        bool isNewTexture,
    244                        int left, int top, int width, int height,
    245                        GrPixelConfig dataConfig,
    246                        const void* data,
    247                        size_t rowBytes);
    248 
    249     bool createRenderTargetObjects(int width, int height,
    250                                    GrGLuint texID,
    251                                    GrGLRenderTarget::Desc* desc);
    252 
    253     void fillInConfigRenderableTable();
    254 
    255     friend class GrGLVertexBuffer;
    256     friend class GrGLIndexBuffer;
    257     friend class GrGLTexture;
    258     friend class GrGLRenderTarget;
    259 
    260     GrGLContextInfo fGLContextInfo;
    261 
    262     // GL program-related state
    263     ProgramCache*               fProgramCache;
    264     SkAutoTUnref<GrGLProgram>   fCurrentProgram;
    265 
    266     ///////////////////////////////////////////////////////////////////////////
    267     ///@name Caching of GL State
    268     ///@{
    269     int                         fHWActiveTextureUnitIdx;
    270     GrGLuint                    fHWProgramID;
    271     GrColor                     fHWConstAttribColor;
    272     GrColor                     fHWConstAttribCoverage;
    273 
    274     enum TriState {
    275         kNo_TriState,
    276         kYes_TriState,
    277         kUnknown_TriState
    278     };
    279 
    280     // last scissor / viewport scissor state seen by the GL.
    281     struct {
    282         TriState    fEnabled;
    283         GrGLIRect   fRect;
    284         void invalidate() {
    285             fEnabled = kUnknown_TriState;
    286             fRect.invalidate();
    287         }
    288     } fHWScissorSettings;
    289 
    290     GrGLIRect   fHWViewport;
    291 
    292     struct {
    293         size_t                  fVertexOffset;
    294         GrVertexLayout          fVertexLayout;
    295         const GrVertexBuffer*   fVertexBuffer;
    296         const GrIndexBuffer*    fIndexBuffer;
    297         bool                    fArrayPtrsDirty;
    298     } fHWGeometryState;
    299 
    300     struct {
    301         GrBlendCoeff    fSrcCoeff;
    302         GrBlendCoeff    fDstCoeff;
    303         GrColor         fConstColor;
    304         bool            fConstColorValid;
    305         TriState        fEnabled;
    306 
    307         void invalidate() {
    308             fSrcCoeff = kInvalid_GrBlendCoeff;
    309             fDstCoeff = kInvalid_GrBlendCoeff;
    310             fConstColorValid = false;
    311             fEnabled = kUnknown_TriState;
    312         }
    313     } fHWBlendState;
    314 
    315     struct {
    316         TriState fMSAAEnabled;
    317         TriState fSmoothLineEnabled;
    318         void invalidate() {
    319             fMSAAEnabled = kUnknown_TriState;
    320             fSmoothLineEnabled = kUnknown_TriState;
    321         }
    322     } fHWAAState;
    323 
    324     struct {
    325         SkMatrix    fViewMatrix;
    326         SkISize     fRTSize;
    327         void invalidate() {
    328             fViewMatrix = SkMatrix::InvalidMatrix();
    329             fRTSize.fWidth = -1; // just make the first value compared illegal.
    330         }
    331     } fHWPathMatrixState;
    332 
    333     GrStencilSettings       fHWStencilSettings;
    334     TriState                fHWStencilTestEnabled;
    335 
    336     GrDrawState::DrawFace   fHWDrawFace;
    337     TriState                fHWWriteToColor;
    338     TriState                fHWDitherEnabled;
    339     GrRenderTarget*         fHWBoundRenderTarget;
    340     GrTexture*              fHWBoundTextures[GrDrawState::kNumStages];
    341     ///@}
    342 
    343     // we record what stencil format worked last time to hopefully exit early
    344     // from our loop that tries stencil formats and calls check fb status.
    345     int fLastSuccessfulStencilFmtIdx;
    346 
    347     bool fPrintedCaps;
    348 
    349     typedef GrGpu INHERITED;
    350 };
    351 
    352 #endif
    353