/* * Copyright 2011 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef GrGpu_DEFINED #define GrGpu_DEFINED #include "GrDrawTarget.h" #include "GrRect.h" #include "GrRefCnt.h" #include "GrTexture.h" #include "GrClipMaskManager.h" class GrContext; class GrIndexBufferAllocPool; class GrPathRenderer; class GrPathRendererChain; class GrResource; class GrStencilBuffer; class GrVertexBufferAllocPool; /** * Gpu usage statistics. */ struct GrGpuStats { uint32_t fVertexCnt; // config); return fConfigRenderSupport[config]; } virtual void enableScissoring(const GrIRect& rect) = 0; virtual void disableScissor() = 0; // GrGpu subclass sets clip bit in the stencil buffer. The subclass is // free to clear the remaining bits to zero if masked clears are more // expensive than clearing all bits. virtual void clearStencilClip(const GrIRect& rect, bool insideClip) = 0; enum PrivateDrawStateStateBits { kFirstBit = (GrDrawState::kLastPublicStateBit << 1), kModifyStencilClip_StateBit = kFirstBit, // allows draws to modify // stencil bits used for // clipping. }; virtual void postClipPush() SK_OVERRIDE { fClipMaskManager.postClipPush(); } virtual void preClipPop() SK_OVERRIDE { fClipMaskManager.preClipPop(); } protected: // prepares clip flushes gpu state before a draw bool setupClipAndFlushState(GrPrimitiveType type); // Functions used to map clip-respecting stencil tests into normal // stencil funcs supported by GPUs. static GrStencilFunc ConvertStencilFunc(bool stencilInClip, GrStencilFunc func); static void ConvertStencilFuncAndMask(GrStencilFunc func, bool clipInStencil, unsigned int clipBit, unsigned int userBits, unsigned int* ref, unsigned int* mask); // stencil settings to clip drawing when stencil clipping is in effect // and the client isn't using the stencil test. static const GrStencilSettings* GetClipStencilSettings(); GrGpuStats fStats; GrClipMaskManager fClipMaskManager; struct GeometryPoolState { const GrVertexBuffer* fPoolVertexBuffer; int fPoolStartVertex; const GrIndexBuffer* fPoolIndexBuffer; int fPoolStartIndex; }; const GeometryPoolState& getGeomPoolState() { return fGeomPoolStateStack.back(); } // Derived classes need access to this so they can fill it out in their // constructors bool fConfigRenderSupport[kGrPixelConfigCount]; // GrDrawTarget overrides virtual bool onReserveVertexSpace(GrVertexLayout vertexLayout, int vertexCount, void** vertices); virtual bool onReserveIndexSpace(int indexCount, void** indices); virtual void releaseReservedVertexSpace(); virtual void releaseReservedIndexSpace(); virtual void onSetVertexSourceToArray(const void* vertexArray, int vertexCount); virtual void onSetIndexSourceToArray(const void* indexArray, int indexCount); virtual void releaseVertexArray(); virtual void releaseIndexArray(); virtual void geometrySourceWillPush(); virtual void geometrySourceWillPop(const GeometrySrcState& restoredState); // Helpers for setting up geometry state void finalizeReservedVertices(); void finalizeReservedIndices(); // called when the 3D context state is unknown. Subclass should emit any // assumed 3D context state and dirty any state cache virtual void onResetContext() = 0; // overridden by API-specific derived class to create objects. virtual GrTexture* onCreateTexture(const GrTextureDesc& desc, const void* srcData, size_t rowBytes) = 0; virtual GrTexture* onCreatePlatformTexture(const GrPlatformTextureDesc& desc) = 0; virtual GrRenderTarget* onCreatePlatformRenderTarget(const GrPlatformRenderTargetDesc& desc) = 0; virtual GrVertexBuffer* onCreateVertexBuffer(uint32_t size, bool dynamic) = 0; virtual GrIndexBuffer* onCreateIndexBuffer(uint32_t size, bool dynamic) = 0; // overridden by API-specific derivated class to perform the clear and // clearRect. NULL rect means clear whole target. virtual void onClear(const GrIRect* rect, GrColor color) = 0; // overridden by API-specific derived class to perform the draw call. virtual void onGpuDrawIndexed(GrPrimitiveType type, uint32_t startVertex, uint32_t startIndex, uint32_t vertexCount, uint32_t indexCount) = 0; virtual void onGpuDrawNonIndexed(GrPrimitiveType type, uint32_t vertexCount, uint32_t numVertices) = 0; // overridden by API-specific derived class to perform flush virtual void onForceRenderTargetFlush() = 0; // overridden by API-specific derived class to perform the read pixels. virtual bool onReadPixels(GrRenderTarget* target, int left, int top, int width, int height, GrPixelConfig, void* buffer, size_t rowBytes, bool invertY) = 0; // overridden by API-specific derived class to perform the texture update virtual void onWriteTexturePixels(GrTexture* texture, int left, int top, int width, int height, GrPixelConfig config, const void* buffer, size_t rowBytes) = 0; // overridden by API-specific derived class to perform the resolve virtual void onResolveRenderTarget(GrRenderTarget* target) = 0; // called to program the vertex data, indexCount will be 0 if drawing non- // indexed geometry. The subclass may adjust the startVertex and/or // startIndex since it may have already accounted for these in the setup. virtual void setupGeometry(int* startVertex, int* startIndex, int vertexCount, int indexCount) = 0; // width and height may be larger than rt (if underlying API allows it). // Should attach the SB to the RT. Returns false if compatible sb could // not be created. virtual bool createStencilBufferForRenderTarget(GrRenderTarget* rt, int width, int height) = 0; // attaches an existing SB to an existing RT. virtual bool attachStencilBufferToRenderTarget(GrStencilBuffer* sb, GrRenderTarget* rt) = 0; // The GrGpu typically records the clients requested state and then flushes // deltas from previous state at draw time. This function does the // API-specific flush of the state // returns false if current state is unsupported. virtual bool flushGraphicsState(GrPrimitiveType type) = 0; // clears the entire stencil buffer to 0 virtual void clearStencil() = 0; private: GrContext* fContext; // not reffed (context refs gpu) ResetTimestamp fResetTimestamp; GrVertexBufferAllocPool* fVertexPool; GrIndexBufferAllocPool* fIndexPool; // counts number of uses of vertex/index pool in the geometry stack int fVertexPoolUseCnt; int fIndexPoolUseCnt; enum { kPreallocGeomPoolStateStackCnt = 4, }; SkSTArray fGeomPoolStateStack; mutable GrIndexBuffer* fQuadIndexBuffer; // mutable so it can be // created on-demand mutable GrVertexBuffer* fUnitSquareVertexBuffer; // mutable so it can be // created on-demand bool fContextIsDirty; GrResource* fResourceHead; // Given a rt, find or create a stencil buffer and attach it bool attachStencilBufferToRenderTarget(GrRenderTarget* target); // GrDrawTarget overrides virtual void onDrawIndexed(GrPrimitiveType type, int startVertex, int startIndex, int vertexCount, int indexCount); virtual void onDrawNonIndexed(GrPrimitiveType type, int startVertex, int vertexCount); // readies the pools to provide vertex/index data. void prepareVertexPool(); void prepareIndexPool(); void resetContext() { this->onResetContext(); ++fResetTimestamp; } void handleDirtyContext() { if (fContextIsDirty) { this->resetContext(); fContextIsDirty = false; } } typedef GrDrawTarget INHERITED; }; #endif