GrGpu.h revision 1bf1c21025e50dba3352ccb660e384f8540ff89c
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     * @param rowBytes      the number of bytes between consecutive rows. Zero
184     *                      means rows are tightly packed.
185     *
186     * @return true if the read succeeded, false if not. The read can fail
187     *              because of a unsupported pixel config or because no render
188     *              target is currently set.
189     */
190    bool readPixels(GrRenderTarget* renderTarget,
191                    int left, int top, int width, int height,
192                    GrPixelConfig config, void* buffer, size_t rowBytes);
193
194    const GrGpuStats& getStats() const;
195    void resetStats();
196    void printStats() const;
197
198    /**
199     * Called to tell Gpu object that all GrResources have been lost and should
200     * be abandoned. Overrides must call INHERITED::abandonResources().
201     */
202    virtual void abandonResources();
203
204    /**
205     * Called to tell Gpu object to release all GrResources. Overrides must call
206     * INHERITED::releaseResources().
207     */
208    void releaseResources();
209
210    /**
211     * Add resource to list of resources. Should only be called by GrResource.
212     * @param resource  the resource to add.
213     */
214    void insertResource(GrResource* resource);
215
216    /**
217     * Remove resource from list of resources. Should only be called by
218     * GrResource.
219     * @param resource  the resource to remove.
220     */
221    void removeResource(GrResource* resource);
222
223    // GrDrawTarget overrides
224    virtual void clear(const GrIRect* rect, GrColor color);
225
226protected:
227    enum PrivateStateBits {
228        kFirstBit = (kLastPublicStateBit << 1),
229
230        kModifyStencilClip_StateBit = kFirstBit, // allows draws to modify
231                                                 // stencil bits used for
232                                                 // clipping.
233    };
234
235    // keep track of whether we are using stencil clipping (as opposed to
236    // scissor).
237    bool    fClipInStencil;
238
239    // prepares clip flushes gpu state before a draw
240    bool setupClipAndFlushState(GrPrimitiveType type);
241
242    // Functions used to map clip-respecting stencil tests into normal
243    // stencil funcs supported by GPUs.
244    static GrStencilFunc ConvertStencilFunc(bool stencilInClip,
245                                            GrStencilFunc func);
246    static void ConvertStencilFuncAndMask(GrStencilFunc func,
247                                          bool clipInStencil,
248                                          unsigned int clipBit,
249                                          unsigned int userBits,
250                                          unsigned int* ref,
251                                          unsigned int* mask);
252
253    // stencil settings to clip drawing when stencil clipping is in effect
254    // and the client isn't using the stencil test.
255    static const GrStencilSettings gClipStencilSettings;
256
257
258    GrGpuStats fStats;
259
260    struct GeometryPoolState {
261        const GrVertexBuffer* fPoolVertexBuffer;
262        int                   fPoolStartVertex;
263
264        const GrIndexBuffer*  fPoolIndexBuffer;
265        int                   fPoolStartIndex;
266    };
267    const GeometryPoolState& getGeomPoolState() {
268        return fGeomPoolStateStack.back();
269    }
270
271    // GrDrawTarget overrides
272    virtual bool onReserveVertexSpace(GrVertexLayout vertexLayout,
273                                      int vertexCount,
274                                      void** vertices);
275    virtual bool onReserveIndexSpace(int indexCount, void** indices);
276    virtual void releaseReservedVertexSpace();
277    virtual void releaseReservedIndexSpace();
278    virtual void onSetVertexSourceToArray(const void* vertexArray,
279                                          int vertexCount);
280    virtual void onSetIndexSourceToArray(const void* indexArray,
281                                         int indexCount);
282    virtual void releaseVertexArray();
283    virtual void releaseIndexArray();
284    virtual void geometrySourceWillPush();
285    virtual void geometrySourceWillPop(const GeometrySrcState& restoredState);
286
287    // Helpers for setting up geometry state
288    void finalizeReservedVertices();
289    void finalizeReservedIndices();
290
291    // called to handle re-emitting 3D API preample and dirtying state cache.
292    void resetContext();
293    // returns the number of times resetContext has been called. This value
294    // can be used a timestamp to detect when state cache is dirty.
295    int resetCount() const { return fResetCnt; }
296
297    // subclass implementation of resetContext
298    virtual void onResetContext() = 0;
299
300    // overridden by API-specific derived class to create objects.
301    virtual GrTexture* onCreateTexture(const GrTextureDesc& desc,
302                                       const void* srcData,
303                                       size_t rowBytes) = 0;
304    virtual GrResource* onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc) = 0;
305    virtual GrVertexBuffer* onCreateVertexBuffer(uint32_t size,
306                                                 bool dynamic) = 0;
307    virtual GrIndexBuffer* onCreateIndexBuffer(uint32_t size,
308                                               bool dynamic) = 0;
309
310    // overridden by API-specific derivated class to perform the clear and
311    // clearRect. NULL rect means clear whole target.
312    virtual void onClear(const GrIRect* rect, GrColor color) = 0;
313
314    // overridden by API-specific derived class to perform the draw call.
315    virtual void onGpuDrawIndexed(GrPrimitiveType type,
316                                  uint32_t startVertex,
317                                  uint32_t startIndex,
318                                  uint32_t vertexCount,
319                                  uint32_t indexCount) = 0;
320
321    virtual void onGpuDrawNonIndexed(GrPrimitiveType type,
322                                     uint32_t vertexCount,
323                                     uint32_t numVertices) = 0;
324
325    // overridden by API-specific derived class to perform flush
326    virtual void onForceRenderTargetFlush() = 0;
327
328    // overridden by API-specific derived class to perform the read pixels.
329    virtual bool onReadPixels(GrRenderTarget* target,
330                              int left, int top, int width, int height,
331                              GrPixelConfig, void* buffer, size_t rowBytes) = 0;
332
333    // called to program the vertex data, indexCount will be 0 if drawing non-
334    // indexed geometry. The subclass may adjust the startVertex and/or
335    // startIndex since it may have already accounted for these in the setup.
336    virtual void setupGeometry(int* startVertex,
337                               int* startIndex,
338                               int vertexCount,
339                               int indexCount) = 0;
340
341    // width and height may be larger than rt (if underlying API allows it).
342    // Should attach the SB to the RT. Returns false if compatible sb could
343    // not be created.
344    virtual bool createStencilBufferForRenderTarget(GrRenderTarget* rt,
345                                                    int width,
346                                                    int height) = 0;
347
348    // attaches an existing SB to an existing RT.
349    virtual bool attachStencilBufferToRenderTarget(GrStencilBuffer* sb,
350                                                   GrRenderTarget* rt) = 0;
351
352    // The GrGpu typically records the clients requested state and then flushes
353    // deltas from previous state at draw time. This function does the
354    // API-specific flush of the state
355    // returns false if current state is unsupported.
356    virtual bool flushGraphicsState(GrPrimitiveType type) = 0;
357
358    // Sets the scissor rect, or disables if rect is NULL.
359    virtual void flushScissor(const GrIRect* rect) = 0;
360
361    // GrGpu subclass sets clip bit in the stencil buffer. The subclass is
362    // free to clear the remaining bits to zero if masked clears are more
363    // expensive than clearing all bits.
364    virtual void clearStencilClip(const GrIRect& rect, bool insideClip) = 0;
365
366    // clears the entire stencil buffer to 0
367    virtual void clearStencil() = 0;
368
369private:
370    GrContext*                  fContext; // not reffed (context refs gpu)
371
372    int                         fResetCnt;
373
374    GrVertexBufferAllocPool*    fVertexPool;
375
376    GrIndexBufferAllocPool*     fIndexPool;
377
378    // counts number of uses of vertex/index pool in the geometry stack
379    int                         fVertexPoolUseCnt;
380    int                         fIndexPoolUseCnt;
381
382    enum {
383        kPreallocGeomPoolStateStackCnt = 4,
384    };
385    SkSTArray<kPreallocGeomPoolStateStackCnt,
386              GeometryPoolState, true>              fGeomPoolStateStack;
387
388    mutable GrIndexBuffer*      fQuadIndexBuffer; // mutable so it can be
389                                                  // created on-demand
390
391    mutable GrVertexBuffer*     fUnitSquareVertexBuffer; // mutable so it can be
392                                                         // created on-demand
393
394    // must be instantiated after GrGpu object has been given its owning
395    // GrContext ptr. (GrGpu is constructed first then handed off to GrContext).
396    GrPathRendererChain*        fPathRendererChain;
397
398    bool                        fContextIsDirty;
399
400    GrResource*                 fResourceHead;
401
402    // Given a rt, find or create a stencil buffer and attach it
403    bool attachStencilBufferToRenderTarget(GrRenderTarget* target);
404
405    // GrDrawTarget overrides
406    virtual void onDrawIndexed(GrPrimitiveType type,
407                               int startVertex,
408                               int startIndex,
409                               int vertexCount,
410                               int indexCount);
411    virtual void onDrawNonIndexed(GrPrimitiveType type,
412                                  int startVertex,
413                                  int vertexCount);
414
415    // readies the pools to provide vertex/index data.
416    void prepareVertexPool();
417    void prepareIndexPool();
418
419    // determines the path renderer used to draw a clip path element.
420    GrPathRenderer* getClipPathRenderer(const SkPath& path, GrPathFill fill);
421
422    void handleDirtyContext() {
423        if (fContextIsDirty) {
424            this->resetContext();
425            fContextIsDirty = false;
426        }
427    }
428
429    typedef GrDrawTarget INHERITED;
430};
431
432#endif
433