GrGpu.h revision d38f137e9b813f8193675ebd3dfbfe8bc42639e9
1
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10#ifndef GrGpu_DEFINED
11#define GrGpu_DEFINED
12
13#include "GrDrawTarget.h"
14#include "GrRect.h"
15#include "GrRefCnt.h"
16#include "GrTexture.h"
17
18class GrContext;
19class GrIndexBufferAllocPool;
20class GrPathRenderer;
21class GrPathRendererChain;
22class GrResource;
23class GrStencilBuffer;
24class GrVertexBufferAllocPool;
25
26/**
27 * Gpu usage statistics.
28 */
29struct GrGpuStats {
30    uint32_t fVertexCnt;  //<! Number of vertices drawn
31    uint32_t fIndexCnt;   //<! Number of indices drawn
32    uint32_t fDrawCnt;    //<! Number of draws
33
34    uint32_t fProgChngCnt;//<! Number of program changes (N/A for fixed)
35
36    /**
37     *  Number of times the texture is set in 3D API
38     */
39    uint32_t fTextureChngCnt;
40    /**
41     *  Number of times the render target is set in 3D API
42     */
43    uint32_t fRenderTargetChngCnt;
44    /**
45     *  Number of textures created (includes textures that are rendertargets).
46     */
47    uint32_t fTextureCreateCnt;
48    /**
49     *  Number of rendertargets created.
50     */
51    uint32_t fRenderTargetCreateCnt;
52};
53
54class GrGpu : public GrDrawTarget {
55
56public:
57
58    /**
59     * Additional blend coeffecients for dual source blending, not exposed
60     * through GrPaint/GrContext.
61     */
62    enum ExtendedBlendCoeffs {
63        // source 2 refers to second output color when
64        // using dual source blending.
65        kS2C_BlendCoeff = kPublicBlendCoeffCount,
66        kIS2C_BlendCoeff,
67        kS2A_BlendCoeff,
68        kIS2A_BlendCoeff,
69
70        kTotalBlendCoeffCount
71    };
72
73    /**
74     *  Create an instance of GrGpu that matches the specified Engine backend.
75     *  If the requested engine is not supported (at compile-time or run-time)
76     *  this returns NULL.
77     */
78    static GrGpu* Create(GrEngine, GrPlatform3DContext context3D);
79
80    ////////////////////////////////////////////////////////////////////////////
81
82    GrGpu();
83    virtual ~GrGpu();
84
85    // The GrContext sets itself as the owner of this Gpu object
86    void setContext(GrContext* context) {
87        GrAssert(NULL == fContext);
88        fContext = context;
89    }
90    GrContext* getContext() { return fContext; }
91    const GrContext* getContext() const { return fContext; }
92
93    /**
94     * The GrGpu object normally assumes that no outsider is setting state
95     * within the underlying 3D API's context/device/whatever. This call informs
96     * the GrGpu that the state was modified and it shouldn't make assumptions
97     * about the state.
98     */
99    void markContextDirty() { fContextIsDirty = true; }
100
101    void unimpl(const char[]);
102
103    /**
104     * Creates a texture object. If desc width or height is not a power of
105     * two but underlying API requires a power of two texture then srcData
106     * will be embedded in a power of two texture. The extra width and height
107     * is filled as though srcData were rendered clamped into the texture.
108     *
109     * If kRenderTarget_TextureFlag is specified the GrRenderTarget is
110     * accessible via GrTexture::asRenderTarget(). The texture will hold a ref
111     * on the render target until its releaseRenderTarget() is called or it is
112     * destroyed.
113     *
114     * @param desc        describes the texture to be created.
115     * @param srcData     texel data to load texture. Begins with full-size
116     *                    palette data for paletted textures. Contains width*
117     *                    height texels. If NULL texture data is uninitialized.
118     *
119     * @return    The texture object if successful, otherwise NULL.
120     */
121    GrTexture* createTexture(const GrTextureDesc& desc,
122                             const void* srcData, size_t rowBytes);
123
124    GrResource* createPlatformSurface(const GrPlatformSurfaceDesc& desc);
125
126    /**
127     * Creates a vertex buffer.
128     *
129     * @param size    size in bytes of the vertex buffer
130     * @param dynamic hints whether the data will be frequently changed
131     *                by either GrVertexBuffer::lock or
132     *                GrVertexBuffer::updateData.
133     *
134     * @return    The vertex buffer if successful, otherwise NULL.
135     */
136    GrVertexBuffer* createVertexBuffer(uint32_t size, bool dynamic);
137
138    /**
139     * Creates an index buffer.
140     *
141     * @param size    size in bytes of the index buffer
142     * @param dynamic hints whether the data will be frequently changed
143     *                by either GrIndexBuffer::lock or
144     *                GrIndexBuffer::updateData.
145     *
146     * @return The index buffer if successful, otherwise NULL.
147     */
148    GrIndexBuffer* createIndexBuffer(uint32_t size, bool dynamic);
149
150    /**
151     * Returns an index buffer that can be used to render quads.
152     * Six indices per quad: 0, 1, 2, 0, 2, 3, etc.
153     * The max number of quads can be queried using GrIndexBuffer::maxQuads().
154     * Draw with kTriangles_PrimitiveType
155     * @ return the quad index buffer
156     */
157    const GrIndexBuffer* getQuadIndexBuffer() const;
158
159    /**
160     * Returns a vertex buffer with four position-only vertices [(0,0), (1,0),
161     * (1,1), (0,1)].
162     * @ return unit square vertex buffer
163     */
164    const GrVertexBuffer* getUnitSquareVertexBuffer() const;
165
166    /**
167     * Ensures that the current render target is actually set in the
168     * underlying 3D API. Used when client wants to use 3D API to directly
169     * render to the RT.
170     */
171    void forceRenderTargetFlush();
172
173    /**
174     * Reads a rectangle of pixels from a render target.
175     * @param renderTarget  the render target to read from. NULL means the
176     *                      current render target.
177     * @param left          left edge of the rectangle to read (inclusive)
178     * @param top           top edge of the rectangle to read (inclusive)
179     * @param width         width of rectangle to read in pixels.
180     * @param height        height of rectangle to read in pixels.
181     * @param config        the pixel config of the destination buffer
182     * @param buffer        memory to read the rectangle into.
183     *
184     * @return true if the read succeeded, false if not. The read can fail
185     *              because of a unsupported pixel config or because no render
186     *              target is currently set.
187     */
188    bool readPixels(GrRenderTarget* renderTarget,
189                    int left, int top, int width, int height,
190                    GrPixelConfig config, void* buffer);
191
192    const GrGpuStats& getStats() const;
193    void resetStats();
194    void printStats() const;
195
196    /**
197     * Called to tell Gpu object that all GrResources have been lost and should
198     * be abandoned. Overrides must call INHERITED::abandonResources().
199     */
200    virtual void abandonResources();
201
202    /**
203     * Called to tell Gpu object to release all GrResources. Overrides must call
204     * INHERITED::releaseResources().
205     */
206    void releaseResources();
207
208    /**
209     * Add resource to list of resources. Should only be called by GrResource.
210     * @param resource  the resource to add.
211     */
212    void insertResource(GrResource* resource);
213
214    /**
215     * Remove resource from list of resources. Should only be called by
216     * GrResource.
217     * @param resource  the resource to remove.
218     */
219    void removeResource(GrResource* resource);
220
221    // GrDrawTarget overrides
222    virtual void clear(const GrIRect* rect, GrColor color);
223
224protected:
225    enum PrivateStateBits {
226        kFirstBit = (kLastPublicStateBit << 1),
227
228        kModifyStencilClip_StateBit = kFirstBit, // allows draws to modify
229                                                 // stencil bits used for
230                                                 // clipping.
231    };
232
233    // keep track of whether we are using stencil clipping (as opposed to
234    // scissor).
235    bool    fClipInStencil;
236
237    // prepares clip flushes gpu state before a draw
238    bool setupClipAndFlushState(GrPrimitiveType type);
239
240    // Functions used to map clip-respecting stencil tests into normal
241    // stencil funcs supported by GPUs.
242    static GrStencilFunc ConvertStencilFunc(bool stencilInClip,
243                                            GrStencilFunc func);
244    static void ConvertStencilFuncAndMask(GrStencilFunc func,
245                                          bool clipInStencil,
246                                          unsigned int clipBit,
247                                          unsigned int userBits,
248                                          unsigned int* ref,
249                                          unsigned int* mask);
250
251    // stencil settings to clip drawing when stencil clipping is in effect
252    // and the client isn't using the stencil test.
253    static const GrStencilSettings gClipStencilSettings;
254
255
256    GrGpuStats fStats;
257
258    struct GeometryPoolState {
259        const GrVertexBuffer* fPoolVertexBuffer;
260        int                   fPoolStartVertex;
261
262        const GrIndexBuffer*  fPoolIndexBuffer;
263        int                   fPoolStartIndex;
264    };
265    const GeometryPoolState& getGeomPoolState() {
266        return fGeomPoolStateStack.back();
267    }
268
269    // GrDrawTarget overrides
270    virtual bool onReserveVertexSpace(GrVertexLayout vertexLayout,
271                                      int vertexCount,
272                                      void** vertices);
273    virtual bool onReserveIndexSpace(int indexCount, void** indices);
274    virtual void releaseReservedVertexSpace();
275    virtual void releaseReservedIndexSpace();
276    virtual void onSetVertexSourceToArray(const void* vertexArray,
277                                          int vertexCount);
278    virtual void onSetIndexSourceToArray(const void* indexArray,
279                                         int indexCount);
280    virtual void releaseVertexArray();
281    virtual void releaseIndexArray();
282    virtual void geometrySourceWillPush();
283    virtual void geometrySourceWillPop(const GeometrySrcState& restoredState);
284
285    // Helpers for setting up geometry state
286    void finalizeReservedVertices();
287    void finalizeReservedIndices();
288
289    // overridden by API-specific derived class to handle re-emitting 3D API
290    // preample and dirtying state cache.
291    virtual void resetContext() = 0;
292
293    // overridden by API-specific derived class to create objects.
294    virtual GrTexture* onCreateTexture(const GrTextureDesc& desc,
295                                       const void* srcData,
296                                       size_t rowBytes) = 0;
297    virtual GrResource* onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc) = 0;
298    virtual GrVertexBuffer* onCreateVertexBuffer(uint32_t size,
299                                                 bool dynamic) = 0;
300    virtual GrIndexBuffer* onCreateIndexBuffer(uint32_t size,
301                                               bool dynamic) = 0;
302
303    // overridden by API-specific derivated class to perform the clear and
304    // clearRect. NULL rect means clear whole target.
305    virtual void onClear(const GrIRect* rect, GrColor color) = 0;
306
307    // overridden by API-specific derived class to perform the draw call.
308    virtual void onGpuDrawIndexed(GrPrimitiveType type,
309                                  uint32_t startVertex,
310                                  uint32_t startIndex,
311                                  uint32_t vertexCount,
312                                  uint32_t indexCount) = 0;
313
314    virtual void onGpuDrawNonIndexed(GrPrimitiveType type,
315                                     uint32_t vertexCount,
316                                     uint32_t numVertices) = 0;
317
318    // overridden by API-specific derived class to perform flush
319    virtual void onForceRenderTargetFlush() = 0;
320
321    // overridden by API-specific derived class to perform the read pixels.
322    virtual bool onReadPixels(GrRenderTarget* target,
323                              int left, int top, int width, int height,
324                              GrPixelConfig, void* buffer) = 0;
325
326    // called to program the vertex data, indexCount will be 0 if drawing non-
327    // indexed geometry. The subclass may adjust the startVertex and/or
328    // startIndex since it may have already accounted for these in the setup.
329    virtual void setupGeometry(int* startVertex,
330                               int* startIndex,
331                               int vertexCount,
332                               int indexCount) = 0;
333
334    // width and height may be larger than rt (if underlying API allows it).
335    // Should attach the SB to the RT. Returns false if compatible sb could
336    // not be created.
337    virtual bool createStencilBufferForRenderTarget(GrRenderTarget* rt,
338                                                    int width,
339                                                    int height) = 0;
340
341    // attaches an existing SB to an existing RT.
342    virtual bool attachStencilBufferToRenderTarget(GrStencilBuffer* sb,
343                                                   GrRenderTarget* rt) = 0;
344
345    // The GrGpu typically records the clients requested state and then flushes
346    // deltas from previous state at draw time. This function does the
347    // API-specific flush of the state
348    // returns false if current state is unsupported.
349    virtual bool flushGraphicsState(GrPrimitiveType type) = 0;
350
351    // Sets the scissor rect, or disables if rect is NULL.
352    virtual void flushScissor(const GrIRect* rect) = 0;
353
354    // GrGpu subclass sets clip bit in the stencil buffer. The subclass is
355    // free to clear the remaining bits to zero if masked clears are more
356    // expensive than clearing all bits.
357    virtual void clearStencilClip(const GrIRect& rect, bool insideClip) = 0;
358
359    // clears the entire stencil buffer to 0
360    virtual void clearStencil() = 0;
361
362private:
363    GrContext*                  fContext; // not reffed (context refs gpu)
364
365    GrVertexBufferAllocPool*    fVertexPool;
366
367    GrIndexBufferAllocPool*     fIndexPool;
368
369    // counts number of uses of vertex/index pool in the geometry stack
370    int                         fVertexPoolUseCnt;
371    int                         fIndexPoolUseCnt;
372
373    enum {
374        kPreallocGeomPoolStateStackCnt = 4,
375    };
376    SkSTArray<kPreallocGeomPoolStateStackCnt,
377              GeometryPoolState, true>              fGeomPoolStateStack;
378
379    mutable GrIndexBuffer*      fQuadIndexBuffer; // mutable so it can be
380                                                  // created on-demand
381
382    mutable GrVertexBuffer*     fUnitSquareVertexBuffer; // mutable so it can be
383                                                         // created on-demand
384
385    // must be instantiated after GrGpu object has been given its owning
386    // GrContext ptr. (GrGpu is constructed first then handed off to GrContext).
387    GrPathRendererChain*        fPathRendererChain;
388
389    bool                        fContextIsDirty;
390
391    GrResource*                 fResourceHead;
392
393    // Given a rt, find or create a stencil buffer and attach it
394    bool attachStencilBufferToRenderTarget(GrRenderTarget* target);
395
396    // GrDrawTarget overrides
397    virtual void onDrawIndexed(GrPrimitiveType type,
398                               int startVertex,
399                               int startIndex,
400                               int vertexCount,
401                               int indexCount);
402    virtual void onDrawNonIndexed(GrPrimitiveType type,
403                                  int startVertex,
404                                  int vertexCount);
405
406    // readies the pools to provide vertex/index data.
407    void prepareVertexPool();
408    void prepareIndexPool();
409
410    // determines the path renderer used to draw a clip path element.
411    GrPathRenderer* getClipPathRenderer(const SkPath& path, GrPathFill fill);
412
413    void handleDirtyContext() {
414        if (fContextIsDirty) {
415            this->resetContext();
416            fContextIsDirty = false;
417        }
418    }
419
420    typedef GrDrawTarget INHERITED;
421};
422
423#endif
424