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 "GrGLVertexArray.h"
     20 #include "GrGLVertexBuffer.h"
     21 #include "GrGpu.h"
     22 #include "GrPipelineBuilder.h"
     23 #include "GrXferProcessor.h"
     24 #include "SkTypes.h"
     25 
     26 class GrPipeline;
     27 class GrNonInstancedVertices;
     28 
     29 #ifdef SK_DEVELOPER
     30 #define PROGRAM_CACHE_STATS
     31 #endif
     32 
     33 class GrGLGpu : public GrGpu {
     34 public:
     35     GrGLGpu(const GrGLContext& ctx, GrContext* context);
     36     ~GrGLGpu() override;
     37 
     38     void contextAbandoned() override;
     39 
     40     const GrGLContext& glContext() const { return fGLContext; }
     41 
     42     const GrGLInterface* glInterface() const { return fGLContext.interface(); }
     43     const GrGLContextInfo& ctxInfo() const { return fGLContext; }
     44     GrGLStandard glStandard() const { return fGLContext.standard(); }
     45     GrGLVersion glVersion() const { return fGLContext.version(); }
     46     GrGLSLGeneration glslGeneration() const { return fGLContext.glslGeneration(); }
     47     const GrGLCaps& glCaps() const { return *fGLContext.caps(); }
     48 
     49     GrGLPathRendering* glPathRendering() {
     50         SkASSERT(glCaps().shaderCaps()->pathRenderingSupport());
     51         return static_cast<GrGLPathRendering*>(pathRendering());
     52     }
     53 
     54     void discard(GrRenderTarget*) override;
     55 
     56     // Used by GrGLProgram and GrGLPathTexGenProgramEffects to configure OpenGL
     57     // state.
     58     void bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture);
     59 
     60     // GrGpu overrides
     61     GrPixelConfig preferredReadPixelsConfig(GrPixelConfig readConfig,
     62                                             GrPixelConfig surfaceConfig) const override;
     63     GrPixelConfig preferredWritePixelsConfig(GrPixelConfig writeConfig,
     64                                              GrPixelConfig surfaceConfig) const override;
     65     bool canWriteTexturePixels(const GrTexture*, GrPixelConfig srcConfig) const override;
     66     bool readPixelsWillPayForYFlip(GrRenderTarget* renderTarget,
     67                                    int left, int top,
     68                                    int width, int height,
     69                                    GrPixelConfig config,
     70                                    size_t rowBytes) const override;
     71     bool fullReadPixelsIsFasterThanPartial() const override;
     72 
     73     bool initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) override;
     74 
     75     // These functions should be used to bind GL objects. They track the GL state and skip redundant
     76     // bindings. Making the equivalent glBind calls directly will confuse the state tracking.
     77     void bindVertexArray(GrGLuint id) {
     78         fHWGeometryState.setVertexArrayID(this, id);
     79     }
     80     void bindIndexBufferAndDefaultVertexArray(GrGLuint id) {
     81         fHWGeometryState.setIndexBufferIDOnDefaultVertexArray(this, id);
     82     }
     83     void bindVertexBuffer(GrGLuint id) {
     84         fHWGeometryState.setVertexBufferID(this, id);
     85     }
     86 
     87     // These callbacks update state tracking when GL objects are deleted. They are called from
     88     // GrGLResource onRelease functions.
     89     void notifyVertexArrayDelete(GrGLuint id) {
     90         fHWGeometryState.notifyVertexArrayDelete(id);
     91     }
     92     void notifyVertexBufferDelete(GrGLuint id) {
     93         fHWGeometryState.notifyVertexBufferDelete(id);
     94     }
     95     void notifyIndexBufferDelete(GrGLuint id) {
     96         fHWGeometryState.notifyIndexBufferDelete(id);
     97     }
     98 
     99     bool copySurface(GrSurface* dst,
    100                      GrSurface* src,
    101                      const SkIRect& srcRect,
    102                      const SkIPoint& dstPoint) override;
    103 
    104     bool canCopySurface(const GrSurface* dst,
    105                         const GrSurface* src,
    106                         const SkIRect& srcRect,
    107                         const SkIPoint& dstPoint) override;
    108 
    109     void xferBarrier(GrRenderTarget*, GrXferBarrierType) override;
    110 
    111     void buildProgramDesc(GrProgramDesc*,
    112                           const GrPrimitiveProcessor&,
    113                           const GrPipeline&,
    114                           const GrBatchTracker&) const override;
    115 
    116 private:
    117     // GrGpu overrides
    118     void onResetContext(uint32_t resetBits) override;
    119 
    120     GrTexture* onCreateTexture(const GrSurfaceDesc& desc, GrGpuResource::LifeCycle lifeCycle,
    121                                const void* srcData, size_t rowBytes) override;
    122     GrTexture* onCreateCompressedTexture(const GrSurfaceDesc& desc,
    123                                          GrGpuResource::LifeCycle lifeCycle,
    124                                          const void* srcData) override;
    125     GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) override;
    126     GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) override;
    127     GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&) override;
    128     GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&) override;
    129     bool createStencilAttachmentForRenderTarget(GrRenderTarget* rt, int width, int height) override;
    130     bool attachStencilAttachmentToRenderTarget(GrStencilAttachment* sb,
    131                                                GrRenderTarget* rt) override;
    132 
    133     void onClear(GrRenderTarget*, const SkIRect* rect, GrColor color,
    134                  bool canIgnoreRect) override;
    135 
    136     void onClearStencilClip(GrRenderTarget*, const SkIRect& rect, bool insideClip) override;
    137 
    138     bool onReadPixels(GrRenderTarget* target,
    139                       int left, int top,
    140                       int width, int height,
    141                       GrPixelConfig,
    142                       void* buffer,
    143                       size_t rowBytes) override;
    144 
    145     bool onWriteTexturePixels(GrTexture* texture,
    146                               int left, int top, int width, int height,
    147                               GrPixelConfig config, const void* buffer,
    148                               size_t rowBytes) override;
    149 
    150     void onResolveRenderTarget(GrRenderTarget* target) override;
    151 
    152     void onDraw(const DrawArgs&, const GrNonInstancedVertices&) override;
    153     void onStencilPath(const GrPath*, const StencilPathState&) override;
    154     void onDrawPath(const DrawArgs&, const GrPath*, const GrStencilSettings&) override;
    155     void onDrawPaths(const DrawArgs&,
    156                      const GrPathRange*,
    157                      const void* indices,
    158                      GrDrawTarget::PathIndexType,
    159                      const float transformValues[],
    160                      GrDrawTarget::PathTransformType,
    161                      int count,
    162                      const GrStencilSettings&) override;
    163 
    164     void clearStencil(GrRenderTarget*) override;
    165 
    166     // GrDrawTarget overrides
    167     void didAddGpuTraceMarker() override;
    168     void didRemoveGpuTraceMarker() override;
    169 
    170     // binds texture unit in GL
    171     void setTextureUnit(int unitIdx);
    172 
    173     // Flushes state from GrPipeline to GL. Returns false if the state couldn't be set.
    174     bool flushGLState(const DrawArgs&);
    175 
    176     // Sets up vertex attribute pointers and strides. On return indexOffsetInBytes gives the offset
    177     // an into the index buffer. It does not account for vertices.startIndex() but rather the start
    178     // index is relative to the returned offset.
    179     void setupGeometry(const GrPrimitiveProcessor&,
    180                        const GrNonInstancedVertices& vertices,
    181                        size_t* indexOffsetInBytes);
    182 
    183     // Subclasses should call this to flush the blend state.
    184     void flushBlend(const GrXferProcessor::BlendInfo& blendInfo);
    185 
    186     bool hasExtension(const char* ext) const { return fGLContext.hasExtension(ext); }
    187 
    188     static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
    189 
    190     class ProgramCache : public ::SkNoncopyable {
    191     public:
    192         ProgramCache(GrGLGpu* gpu);
    193         ~ProgramCache();
    194 
    195         void abandon();
    196         GrGLProgram* getProgram(const DrawArgs&);
    197 
    198     private:
    199         enum {
    200             // We may actually have kMaxEntries+1 shaders in the GL context because we create a new
    201             // shader before evicting from the cache.
    202             kMaxEntries = 128,
    203             kHashBits = 6,
    204         };
    205 
    206         struct Entry;
    207 
    208         struct ProgDescLess;
    209 
    210         // binary search for entry matching desc. returns index into fEntries that matches desc or ~
    211         // of the index of where it should be inserted.
    212         int search(const GrProgramDesc& desc) const;
    213 
    214         // sorted array of all the entries
    215         Entry*                      fEntries[kMaxEntries];
    216         // hash table based on lowest kHashBits bits of the program key. Used to avoid binary
    217         // searching fEntries.
    218         Entry*                      fHashTable[1 << kHashBits];
    219 
    220         int                         fCount;
    221         unsigned int                fCurrLRUStamp;
    222         GrGLGpu*                    fGpu;
    223 #ifdef PROGRAM_CACHE_STATS
    224         int                         fTotalRequests;
    225         int                         fCacheMisses;
    226         int                         fHashMisses; // cache hit but hash table missed
    227 #endif
    228     };
    229 
    230     void flushDither(bool dither);
    231     void flushColorWrite(bool writeColor);
    232     void flushDrawFace(GrPipelineBuilder::DrawFace face);
    233 
    234     // flushes the scissor. see the note on flushBoundTextureAndParams about
    235     // flushing the scissor after that function is called.
    236     void flushScissor(const GrScissorState&,
    237                       const GrGLIRect& rtViewport,
    238                       GrSurfaceOrigin rtOrigin);
    239 
    240     // disables the scissor
    241     void disableScissor();
    242 
    243     void initFSAASupport();
    244 
    245     // determines valid stencil formats
    246     void initStencilFormats();
    247 
    248     // sets a texture unit to use for texture operations other than binding a texture to a program.
    249     // ensures that such operations don't negatively interact with tracking bound textures.
    250     void setScratchTextureUnit();
    251 
    252     // bounds is region that may be modified and therefore has to be resolved.
    253     // NULL means whole target. Can be an empty rect.
    254     void flushRenderTarget(GrGLRenderTarget*, const SkIRect* bounds);
    255 
    256     void flushStencil(const GrStencilSettings&);
    257     void flushHWAAState(GrRenderTarget* rt, bool useHWAA);
    258 
    259     bool configToGLFormats(GrPixelConfig config,
    260                            bool getSizedInternal,
    261                            GrGLenum* internalFormat,
    262                            GrGLenum* externalFormat,
    263                            GrGLenum* externalType);
    264     // helper for onCreateTexture and writeTexturePixels
    265     bool uploadTexData(const GrSurfaceDesc& desc,
    266                        bool isNewTexture,
    267                        int left, int top, int width, int height,
    268                        GrPixelConfig dataConfig,
    269                        const void* data,
    270                        size_t rowBytes);
    271 
    272     // helper for onCreateCompressedTexture. If width and height are
    273     // set to -1, then this function will use desc.fWidth and desc.fHeight
    274     // for the size of the data. The isNewTexture flag should be set to true
    275     // whenever a new texture needs to be created. Otherwise, we assume that
    276     // the texture is already in GPU memory and that it's going to be updated
    277     // with new data.
    278     bool uploadCompressedTexData(const GrSurfaceDesc& desc,
    279                                  const void* data,
    280                                  bool isNewTexture = true,
    281                                  int left = 0, int top = 0,
    282                                  int width = -1, int height = -1);
    283 
    284     bool createRenderTargetObjects(const GrSurfaceDesc&, GrGpuResource::LifeCycle lifeCycle,
    285                                    GrGLuint texID, GrGLRenderTarget::IDDesc*);
    286 
    287     enum TempFBOTarget {
    288         kSrc_TempFBOTarget,
    289         kDst_TempFBOTarget
    290     };
    291 
    292     GrGLuint bindSurfaceAsFBO(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport,
    293                               TempFBOTarget tempFBOTarget);
    294 
    295     void unbindTextureFromFBO(GrGLenum fboTarget);
    296 
    297     GrGLContext fGLContext;
    298 
    299     // GL program-related state
    300     ProgramCache*               fProgramCache;
    301     SkAutoTUnref<GrGLProgram>   fCurrentProgram;
    302 
    303     ///////////////////////////////////////////////////////////////////////////
    304     ///@name Caching of GL State
    305     ///@{
    306     int                         fHWActiveTextureUnitIdx;
    307     GrGLuint                    fHWProgramID;
    308 
    309     enum TriState {
    310         kNo_TriState,
    311         kYes_TriState,
    312         kUnknown_TriState
    313     };
    314 
    315     GrGLuint                    fTempSrcFBOID;
    316     GrGLuint                    fTempDstFBOID;
    317 
    318     GrGLuint                    fStencilClearFBOID;
    319 
    320     // last scissor / viewport scissor state seen by the GL.
    321     struct {
    322         TriState    fEnabled;
    323         GrGLIRect   fRect;
    324         void invalidate() {
    325             fEnabled = kUnknown_TriState;
    326             fRect.invalidate();
    327         }
    328     } fHWScissorSettings;
    329 
    330     GrGLIRect   fHWViewport;
    331 
    332     /**
    333      * Tracks bound vertex and index buffers and vertex attrib array state.
    334      */
    335     class HWGeometryState {
    336     public:
    337         HWGeometryState() { fVBOVertexArray = NULL; this->invalidate(); }
    338 
    339         ~HWGeometryState() { SkDELETE(fVBOVertexArray); }
    340 
    341         void invalidate() {
    342             fBoundVertexArrayIDIsValid = false;
    343             fBoundVertexBufferIDIsValid = false;
    344             fDefaultVertexArrayBoundIndexBufferID = false;
    345             fDefaultVertexArrayBoundIndexBufferIDIsValid = false;
    346             fDefaultVertexArrayAttribState.invalidate();
    347             if (fVBOVertexArray) {
    348                 fVBOVertexArray->invalidateCachedState();
    349             }
    350         }
    351 
    352         void notifyVertexArrayDelete(GrGLuint id) {
    353             if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) {
    354                 // Does implicit bind to 0
    355                 fBoundVertexArrayID = 0;
    356             }
    357         }
    358 
    359         void setVertexArrayID(GrGLGpu* gpu, GrGLuint arrayID) {
    360             if (!gpu->glCaps().vertexArrayObjectSupport()) {
    361                 SkASSERT(0 == arrayID);
    362                 return;
    363             }
    364             if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) {
    365                 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID));
    366                 fBoundVertexArrayIDIsValid = true;
    367                 fBoundVertexArrayID = arrayID;
    368             }
    369         }
    370 
    371         void notifyVertexBufferDelete(GrGLuint id) {
    372             if (fBoundVertexBufferIDIsValid && id == fBoundVertexBufferID) {
    373                 fBoundVertexBufferID = 0;
    374             }
    375             if (fVBOVertexArray) {
    376                 fVBOVertexArray->notifyVertexBufferDelete(id);
    377             }
    378             fDefaultVertexArrayAttribState.notifyVertexBufferDelete(id);
    379         }
    380 
    381         void notifyIndexBufferDelete(GrGLuint id) {
    382             if (fDefaultVertexArrayBoundIndexBufferIDIsValid &&
    383                 id == fDefaultVertexArrayBoundIndexBufferID) {
    384                 fDefaultVertexArrayBoundIndexBufferID = 0;
    385             }
    386             if (fVBOVertexArray) {
    387                 fVBOVertexArray->notifyIndexBufferDelete(id);
    388             }
    389         }
    390 
    391         void setVertexBufferID(GrGLGpu* gpu, GrGLuint id) {
    392             if (!fBoundVertexBufferIDIsValid || id != fBoundVertexBufferID) {
    393                 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ARRAY_BUFFER, id));
    394                 fBoundVertexBufferIDIsValid = true;
    395                 fBoundVertexBufferID = id;
    396             }
    397         }
    398 
    399         /**
    400          * Binds the default vertex array and binds the index buffer. This is used when binding
    401          * an index buffer in order to update it.
    402          */
    403         void setIndexBufferIDOnDefaultVertexArray(GrGLGpu* gpu, GrGLuint id) {
    404             this->setVertexArrayID(gpu, 0);
    405             if (!fDefaultVertexArrayBoundIndexBufferIDIsValid ||
    406                 id != fDefaultVertexArrayBoundIndexBufferID) {
    407                 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, id));
    408                 fDefaultVertexArrayBoundIndexBufferIDIsValid = true;
    409                 fDefaultVertexArrayBoundIndexBufferID = id;
    410             }
    411         }
    412 
    413         /**
    414          * Binds the vertex array object that should be used to render from the vertex buffer.
    415          * The vertex array is bound and its attrib array state object is returned. The vertex
    416          * buffer is bound. The index buffer (if non-NULL) is bound to the vertex array. The
    417          * returned GrGLAttribArrayState should be used to set vertex attribute arrays.
    418          */
    419         GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGLGpu* gpu,
    420                                                         const GrGLVertexBuffer* vbuffer,
    421                                                         const GrGLIndexBuffer* ibuffer);
    422 
    423     private:
    424         GrGLuint                fBoundVertexArrayID;
    425         GrGLuint                fBoundVertexBufferID;
    426         bool                    fBoundVertexArrayIDIsValid;
    427         bool                    fBoundVertexBufferIDIsValid;
    428 
    429         GrGLuint                fDefaultVertexArrayBoundIndexBufferID;
    430         bool                    fDefaultVertexArrayBoundIndexBufferIDIsValid;
    431         // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0
    432         // is bound. However, this class is internal to GrGLGpu and this object never leaks out of
    433         // GrGLGpu.
    434         GrGLAttribArrayState    fDefaultVertexArrayAttribState;
    435 
    436         // This is used when we're using a core profile and the vertices are in a VBO.
    437         GrGLVertexArray*        fVBOVertexArray;
    438     } fHWGeometryState;
    439 
    440     struct {
    441         GrBlendEquation fEquation;
    442         GrBlendCoeff    fSrcCoeff;
    443         GrBlendCoeff    fDstCoeff;
    444         GrColor         fConstColor;
    445         bool            fConstColorValid;
    446         TriState        fEnabled;
    447 
    448         void invalidate() {
    449             fEquation = static_cast<GrBlendEquation>(-1);
    450             fSrcCoeff = static_cast<GrBlendCoeff>(-1);
    451             fDstCoeff = static_cast<GrBlendCoeff>(-1);
    452             fConstColorValid = false;
    453             fEnabled = kUnknown_TriState;
    454         }
    455     } fHWBlendState;
    456 
    457     TriState fMSAAEnabled;
    458 
    459     GrStencilSettings           fHWStencilSettings;
    460     TriState                    fHWStencilTestEnabled;
    461 
    462 
    463     GrPipelineBuilder::DrawFace fHWDrawFace;
    464     TriState                    fHWWriteToColor;
    465     TriState                    fHWDitherEnabled;
    466     uint32_t                    fHWBoundRenderTargetUniqueID;
    467     SkTArray<uint32_t, true>    fHWBoundTextureUniqueIDs;
    468 
    469     ///@}
    470 
    471     // we record what stencil format worked last time to hopefully exit early
    472     // from our loop that tries stencil formats and calls check fb status.
    473     int fLastSuccessfulStencilFmtIdx;
    474 
    475     typedef GrGpu INHERITED;
    476     friend class GrGLPathRendering; // For accessing setTextureUnit.
    477 };
    478 
    479 #endif
    480