GrGpu.h revision af091a176dbf900a9ff4526ef3b6966a1de44775
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 GrGpu_DEFINED
9#define GrGpu_DEFINED
10
11#include "GrDrawTarget.h"
12#include "GrClipMaskManager.h"
13#include "SkPath.h"
14
15class GrContext;
16class GrGpuObject;
17class GrIndexBufferAllocPool;
18class GrPath;
19class GrPathRenderer;
20class GrPathRendererChain;
21class GrStencilBuffer;
22class GrVertexBufferAllocPool;
23
24class GrGpu : public GrDrawTarget {
25public:
26
27    /**
28     * Additional blend coefficients for dual source blending, not exposed
29     * through GrPaint/GrContext.
30     */
31    enum ExtendedBlendCoeffs {
32        // source 2 refers to second output color when
33        // using dual source blending.
34        kS2C_GrBlendCoeff = kPublicGrBlendCoeffCount,
35        kIS2C_GrBlendCoeff,
36        kS2A_GrBlendCoeff,
37        kIS2A_GrBlendCoeff,
38
39        kTotalGrBlendCoeffCount
40    };
41
42    /**
43     * Create an instance of GrGpu that matches the specified backend. If the requested backend is
44     * not supported (at compile-time or run-time) this returns NULL. The context will not be
45     * fully constructed and should not be used by GrGpu until after this function returns.
46     */
47    static GrGpu* Create(GrBackend, GrBackendContext, GrContext* context);
48
49    ////////////////////////////////////////////////////////////////////////////
50
51    GrGpu(GrContext* context);
52    virtual ~GrGpu();
53
54    GrContext* getContext() { return this->INHERITED::getContext(); }
55    const GrContext* getContext() const { return this->INHERITED::getContext(); }
56
57    /**
58     * The GrGpu object normally assumes that no outsider is setting state
59     * within the underlying 3D API's context/device/whatever. This call informs
60     * the GrGpu that the state was modified and it shouldn't make assumptions
61     * about the state.
62     */
63    void markContextDirty(uint32_t state = kAll_GrBackendState) {
64        fResetBits |= state;
65    }
66
67    void unimpl(const char[]);
68
69    /**
70     * Creates a texture object. If desc width or height is not a power of
71     * two but underlying API requires a power of two texture then srcData
72     * will be embedded in a power of two texture. The extra width and height
73     * is filled as though srcData were rendered clamped into the texture.
74     * The exception is when using compressed data formats. In this case, the
75     * desc width and height must be a multiple of the compressed format block
76     * size otherwise this function returns NULL. Similarly, if the underlying
77     * API requires a power of two texture and the source width and height are not
78     * a power of two, then this function returns NULL.
79     *
80     * If kRenderTarget_TextureFlag is specified the GrRenderTarget is
81     * accessible via GrTexture::asRenderTarget(). The texture will hold a ref
82     * on the render target until the texture is destroyed. Compressed textures
83     * cannot have the kRenderTarget_TextureFlag set.
84     *
85     * @param desc        describes the texture to be created.
86     * @param srcData     texel data to load texture. Begins with full-size
87     *                    palette data for paletted textures. For compressed
88     *                    formats it contains the compressed pixel data. Otherwise,
89     *                    it contains width*height texels. If NULL texture data
90     *                    is uninitialized.
91     * @param rowBytes    the number of bytes between consecutive rows. Zero
92     *                    means rows are tightly packed. This field is ignored
93     *                    for compressed formats.
94     *
95     * @return    The texture object if successful, otherwise NULL.
96     */
97    GrTexture* createTexture(const GrTextureDesc& desc,
98                             const void* srcData, size_t rowBytes);
99
100    /**
101     * Implements GrContext::wrapBackendTexture
102     */
103    GrTexture* wrapBackendTexture(const GrBackendTextureDesc&);
104
105    /**
106     * Implements GrContext::wrapBackendTexture
107     */
108    GrRenderTarget* wrapBackendRenderTarget(const GrBackendRenderTargetDesc&);
109
110    /**
111     * Creates a vertex buffer.
112     *
113     * @param size    size in bytes of the vertex buffer
114     * @param dynamic hints whether the data will be frequently changed
115     *                by either GrVertexBuffer::map() or
116     *                GrVertexBuffer::updateData().
117     *
118     * @return    The vertex buffer if successful, otherwise NULL.
119     */
120    GrVertexBuffer* createVertexBuffer(size_t size, bool dynamic);
121
122    /**
123     * Creates an index buffer.
124     *
125     * @param size    size in bytes of the index buffer
126     * @param dynamic hints whether the data will be frequently changed
127     *                by either GrIndexBuffer::map() or
128     *                GrIndexBuffer::updateData().
129     *
130     * @return The index buffer if successful, otherwise NULL.
131     */
132    GrIndexBuffer* createIndexBuffer(size_t size, bool dynamic);
133
134    /**
135     * Creates a path object that can be stenciled using stencilPath(). It is
136     * only legal to call this if the caps report support for path stenciling.
137     */
138    GrPath* createPath(const SkPath& path, const SkStrokeRec& stroke);
139
140    /**
141     * Returns an index buffer that can be used to render quads.
142     * Six indices per quad: 0, 1, 2, 0, 2, 3, etc.
143     * The max number of quads can be queried using GrIndexBuffer::maxQuads().
144     * Draw with kTriangles_GrPrimitiveType
145     * @ return the quad index buffer
146     */
147    const GrIndexBuffer* getQuadIndexBuffer() const;
148
149    /**
150     * Resolves MSAA.
151     */
152    void resolveRenderTarget(GrRenderTarget* target);
153
154    /**
155     * Gets a preferred 8888 config to use for writing/reading pixel data to/from a surface with
156     * config surfaceConfig. The returned config must have at least as many bits per channel as the
157     * readConfig or writeConfig param.
158     */
159    virtual GrPixelConfig preferredReadPixelsConfig(GrPixelConfig readConfig,
160                                                    GrPixelConfig surfaceConfig) const {
161        return readConfig;
162    }
163    virtual GrPixelConfig preferredWritePixelsConfig(GrPixelConfig writeConfig,
164                                                     GrPixelConfig surfaceConfig) const {
165        return writeConfig;
166    }
167
168    /**
169     * Called before uploading writing pixels to a GrTexture when the src pixel config doesn't
170     * match the texture's config.
171     */
172    virtual bool canWriteTexturePixels(const GrTexture*, GrPixelConfig srcConfig) const = 0;
173
174    /**
175     * OpenGL's readPixels returns the result bottom-to-top while the skia
176     * API is top-to-bottom. Thus we have to do a y-axis flip. The obvious
177     * solution is to have the subclass do the flip using either the CPU or GPU.
178     * However, the caller (GrContext) may have transformations to apply and can
179     * simply fold in the y-flip for free. On the other hand, the subclass may
180     * be able to do it for free itself. For example, the subclass may have to
181     * do memcpys to handle rowBytes that aren't tight. It could do the y-flip
182     * concurrently.
183     *
184     * This function returns true if a y-flip is required to put the pixels in
185     * top-to-bottom order and the subclass cannot do it for free.
186     *
187     * See read pixels for the params
188     * @return true if calling readPixels with the same set of params will
189     *              produce bottom-to-top data
190     */
191     virtual bool readPixelsWillPayForYFlip(GrRenderTarget* renderTarget,
192                                            int left, int top,
193                                            int width, int height,
194                                            GrPixelConfig config,
195                                            size_t rowBytes) const = 0;
196     /**
197      * This should return true if reading a NxM rectangle of pixels from a
198      * render target is faster if the target has dimensons N and M and the read
199      * rectangle has its top-left at 0,0.
200      */
201     virtual bool fullReadPixelsIsFasterThanPartial() const { return false; };
202
203    /**
204     * Reads a rectangle of pixels from a render target.
205     *
206     * @param renderTarget  the render target to read from. NULL means the
207     *                      current render target.
208     * @param left          left edge of the rectangle to read (inclusive)
209     * @param top           top edge of the rectangle to read (inclusive)
210     * @param width         width of rectangle to read in pixels.
211     * @param height        height of rectangle to read in pixels.
212     * @param config        the pixel config of the destination buffer
213     * @param buffer        memory to read the rectangle into.
214     * @param rowBytes      the number of bytes between consecutive rows. Zero
215     *                      means rows are tightly packed.
216     * @param invertY       buffer should be populated bottom-to-top as opposed
217     *                      to top-to-bottom (skia's usual order)
218     *
219     * @return true if the read succeeded, false if not. The read can fail
220     *              because of a unsupported pixel config or because no render
221     *              target is currently set.
222     */
223    bool readPixels(GrRenderTarget* renderTarget,
224                    int left, int top, int width, int height,
225                    GrPixelConfig config, void* buffer, size_t rowBytes);
226
227    /**
228     * Updates the pixels in a rectangle of a texture.
229     *
230     * @param left          left edge of the rectangle to write (inclusive)
231     * @param top           top edge of the rectangle to write (inclusive)
232     * @param width         width of rectangle to write in pixels.
233     * @param height        height of rectangle to write in pixels.
234     * @param config        the pixel config of the source buffer
235     * @param buffer        memory to read pixels from
236     * @param rowBytes      number of bytes between consecutive rows. Zero
237     *                      means rows are tightly packed.
238     */
239    bool writeTexturePixels(GrTexture* texture,
240                            int left, int top, int width, int height,
241                            GrPixelConfig config, const void* buffer,
242                            size_t rowBytes);
243
244    /**
245     * Called to tell GrGpu that all GrGpuObjects have been lost and should
246     * be abandoned. Overrides must call INHERITED::abandonResources().
247     */
248    virtual void abandonResources();
249
250    /**
251     * Called to tell GrGpu to release all GrGpuObjects. Overrides must call
252     * INHERITED::releaseResources().
253     */
254    void releaseResources();
255
256    /**
257     * Add object to list of objects. Should only be called by GrGpuObject.
258     * @param resource  the resource to add.
259     */
260    void insertObject(GrGpuObject* object);
261
262    /**
263     * Remove object from list of objects. Should only be called by GrGpuObject.
264     * @param resource  the resource to remove.
265     */
266    void removeObject(GrGpuObject* object);
267
268    // GrDrawTarget overrides
269    virtual void clear(const SkIRect* rect,
270                       GrColor color,
271                       bool canIgnoreRect,
272                       GrRenderTarget* renderTarget = NULL) SK_OVERRIDE;
273
274    virtual void purgeResources() SK_OVERRIDE {
275        // The clip mask manager can rebuild all its clip masks so just
276        // get rid of them all.
277        fClipMaskManager.releaseResources();
278    }
279
280    // After the client interacts directly with the 3D context state the GrGpu
281    // must resync its internal state and assumptions about 3D context state.
282    // Each time this occurs the GrGpu bumps a timestamp.
283    // state of the 3D context
284    // At 10 resets / frame and 60fps a 64bit timestamp will overflow in about
285    // a billion years.
286    typedef uint64_t ResetTimestamp;
287
288    // This timestamp is always older than the current timestamp
289    static const ResetTimestamp kExpiredTimestamp = 0;
290    // Returns a timestamp based on the number of times the context was reset.
291    // This timestamp can be used to lazily detect when cached 3D context state
292    // is dirty.
293    ResetTimestamp getResetTimestamp() const {
294        return fResetTimestamp;
295    }
296
297    /**
298     * These methods are called by the clip manager's setupClipping function
299     * which (called as part of GrGpu's implementation of onDraw and
300     * onStencilPath member functions.) The GrGpu subclass should flush the
301     * stencil state to the 3D API in its implementation of flushGraphicsState.
302     */
303    void enableScissor(const SkIRect& rect) {
304        fScissorState.fEnabled = true;
305        fScissorState.fRect = rect;
306    }
307    void disableScissor() { fScissorState.fEnabled = false; }
308
309    /**
310     * Like the scissor methods above this is called by setupClipping and
311     * should be flushed by the GrGpu subclass in flushGraphicsState. These
312     * stencil settings should be used in place of those on the GrDrawState.
313     * They have been adjusted to account for any interactions between the
314     * GrDrawState's stencil settings and stencil clipping.
315     */
316    void setStencilSettings(const GrStencilSettings& settings) {
317        fStencilSettings = settings;
318    }
319    void disableStencil() { fStencilSettings.setDisabled(); }
320
321    // GrGpu subclass sets clip bit in the stencil buffer. The subclass is
322    // free to clear the remaining bits to zero if masked clears are more
323    // expensive than clearing all bits.
324    virtual void clearStencilClip(const SkIRect& rect, bool insideClip) = 0;
325
326    enum PrivateDrawStateStateBits {
327        kFirstBit = (GrDrawState::kLastPublicStateBit << 1),
328
329        kModifyStencilClip_StateBit = kFirstBit, // allows draws to modify
330                                                 // stencil bits used for
331                                                 // clipping.
332    };
333
334    void getPathStencilSettingsForFillType(SkPath::FillType fill, GrStencilSettings* outStencilSettings);
335
336    enum DrawType {
337        kDrawPoints_DrawType,
338        kDrawLines_DrawType,
339        kDrawTriangles_DrawType,
340        kStencilPath_DrawType,
341        kDrawPath_DrawType,
342        kDrawPaths_DrawType,
343    };
344
345protected:
346    DrawType PrimTypeToDrawType(GrPrimitiveType type) {
347        switch (type) {
348            case kTriangles_GrPrimitiveType:
349            case kTriangleStrip_GrPrimitiveType:
350            case kTriangleFan_GrPrimitiveType:
351                return kDrawTriangles_DrawType;
352            case kPoints_GrPrimitiveType:
353                return kDrawPoints_DrawType;
354            case kLines_GrPrimitiveType:
355            case kLineStrip_GrPrimitiveType:
356                return kDrawLines_DrawType;
357            default:
358                SkFAIL("Unexpected primitive type");
359                return kDrawTriangles_DrawType;
360        }
361    }
362
363    // prepares clip flushes gpu state before a draw
364    bool setupClipAndFlushState(DrawType,
365                                const GrDeviceCoordTexture* dstCopy,
366                                GrDrawState::AutoRestoreEffects* are,
367                                const SkRect* devBounds);
368
369    // Functions used to map clip-respecting stencil tests into normal
370    // stencil funcs supported by GPUs.
371    static GrStencilFunc ConvertStencilFunc(bool stencilInClip,
372                                            GrStencilFunc func);
373    static void ConvertStencilFuncAndMask(GrStencilFunc func,
374                                          bool clipInStencil,
375                                          unsigned int clipBit,
376                                          unsigned int userBits,
377                                          unsigned int* ref,
378                                          unsigned int* mask);
379
380    GrClipMaskManager           fClipMaskManager;
381
382    struct GeometryPoolState {
383        const GrVertexBuffer* fPoolVertexBuffer;
384        int                   fPoolStartVertex;
385
386        const GrIndexBuffer*  fPoolIndexBuffer;
387        int                   fPoolStartIndex;
388    };
389    const GeometryPoolState& getGeomPoolState() {
390        return fGeomPoolStateStack.back();
391    }
392
393    // The state of the scissor is controlled by the clip manager
394    struct ScissorState {
395        bool    fEnabled;
396        SkIRect fRect;
397    } fScissorState;
398
399    // The final stencil settings to use as determined by the clip manager.
400    GrStencilSettings fStencilSettings;
401
402    // Helpers for setting up geometry state
403    void finalizeReservedVertices();
404    void finalizeReservedIndices();
405
406private:
407    // GrDrawTarget overrides
408    virtual bool onReserveVertexSpace(size_t vertexSize, int vertexCount, void** vertices) SK_OVERRIDE;
409    virtual bool onReserveIndexSpace(int indexCount, void** indices) SK_OVERRIDE;
410    virtual void releaseReservedVertexSpace() SK_OVERRIDE;
411    virtual void releaseReservedIndexSpace() SK_OVERRIDE;
412    virtual void onSetVertexSourceToArray(const void* vertexArray, int vertexCount) SK_OVERRIDE;
413    virtual void onSetIndexSourceToArray(const void* indexArray, int indexCount) SK_OVERRIDE;
414    virtual void releaseVertexArray() SK_OVERRIDE;
415    virtual void releaseIndexArray() SK_OVERRIDE;
416    virtual void geometrySourceWillPush() SK_OVERRIDE;
417    virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) SK_OVERRIDE;
418
419
420    // called when the 3D context state is unknown. Subclass should emit any
421    // assumed 3D context state and dirty any state cache.
422    virtual void onResetContext(uint32_t resetBits) = 0;
423
424    // overridden by backend-specific derived class to create objects.
425    virtual GrTexture* onCreateTexture(const GrTextureDesc& desc,
426                                       const void* srcData,
427                                       size_t rowBytes) = 0;
428    virtual GrTexture* onCreateCompressedTexture(const GrTextureDesc& desc,
429                                                 const void* srcData) = 0;
430    virtual GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&) = 0;
431    virtual GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&) = 0;
432    virtual GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) = 0;
433    virtual GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) = 0;
434    virtual GrPath* onCreatePath(const SkPath& path, const SkStrokeRec&) = 0;
435
436    // overridden by backend-specific derived class to perform the clear and
437    // clearRect. NULL rect means clear whole target. If canIgnoreRect is
438    // true, it is okay to perform a full clear instead of a partial clear
439    virtual void onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect) = 0;
440
441    // overridden by backend-specific derived class to perform the draw call.
442    virtual void onGpuDraw(const DrawInfo&) = 0;
443
444    // overridden by backend-specific derived class to perform the path stenciling.
445    virtual void onGpuStencilPath(const GrPath*, SkPath::FillType) = 0;
446    virtual void onGpuDrawPath(const GrPath*, SkPath::FillType) = 0;
447    virtual void onGpuDrawPaths(int, const GrPath**, const SkMatrix*,
448                                SkPath::FillType, SkStrokeRec::Style) = 0;
449
450    // overridden by backend-specific derived class to perform the read pixels.
451    virtual bool onReadPixels(GrRenderTarget* target,
452                              int left, int top, int width, int height,
453                              GrPixelConfig,
454                              void* buffer,
455                              size_t rowBytes) = 0;
456
457    // overridden by backend-specific derived class to perform the texture update
458    virtual bool onWriteTexturePixels(GrTexture* texture,
459                                      int left, int top, int width, int height,
460                                      GrPixelConfig config, const void* buffer,
461                                      size_t rowBytes) = 0;
462
463    // overridden by backend-specific derived class to perform the resolve
464    virtual void onResolveRenderTarget(GrRenderTarget* target) = 0;
465
466    // width and height may be larger than rt (if underlying API allows it).
467    // Should attach the SB to the RT. Returns false if compatible sb could
468    // not be created.
469    virtual bool createStencilBufferForRenderTarget(GrRenderTarget*, int width, int height) = 0;
470
471    // attaches an existing SB to an existing RT.
472    virtual bool attachStencilBufferToRenderTarget(GrStencilBuffer*, GrRenderTarget*) = 0;
473
474    // The GrGpu typically records the clients requested state and then flushes
475    // deltas from previous state at draw time. This function does the
476    // backend-specific flush of the state.
477    // returns false if current state is unsupported.
478    virtual bool flushGraphicsState(DrawType, const GrDeviceCoordTexture* dstCopy) = 0;
479
480    // clears the entire stencil buffer to 0
481    virtual void clearStencil() = 0;
482
483    // Given a rt, find or create a stencil buffer and attach it
484    bool attachStencilBufferToRenderTarget(GrRenderTarget* target);
485
486    // GrDrawTarget overrides
487    virtual void onDraw(const DrawInfo&) SK_OVERRIDE;
488    virtual void onStencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE;
489    virtual void onDrawPath(const GrPath*, SkPath::FillType,
490                            const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
491    virtual void onDrawPaths(int, const GrPath**, const SkMatrix*,
492                             SkPath::FillType, SkStrokeRec::Style,
493                             const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
494
495    // readies the pools to provide vertex/index data.
496    void prepareVertexPool();
497    void prepareIndexPool();
498
499    void resetContext() {
500        // We call this because the client may have messed with the
501        // stencil buffer. Perhaps we should detect whether it is a
502        // internally created stencil buffer and if so skip the invalidate.
503        fClipMaskManager.invalidateStencilMask();
504        this->onResetContext(fResetBits);
505        fResetBits = 0;
506        ++fResetTimestamp;
507    }
508
509    void handleDirtyContext() {
510        if (fResetBits) {
511            this->resetContext();
512        }
513    }
514
515    enum {
516        kPreallocGeomPoolStateStackCnt = 4,
517    };
518    typedef SkTInternalLList<GrGpuObject> ObjectList;
519    SkSTArray<kPreallocGeomPoolStateStackCnt, GeometryPoolState, true>  fGeomPoolStateStack;
520    ResetTimestamp                                                      fResetTimestamp;
521    uint32_t                                                            fResetBits;
522    GrVertexBufferAllocPool*                                            fVertexPool;
523    GrIndexBufferAllocPool*                                             fIndexPool;
524    // counts number of uses of vertex/index pool in the geometry stack
525    int                                                                 fVertexPoolUseCnt;
526    int                                                                 fIndexPoolUseCnt;
527    // these are mutable so they can be created on-demand
528    mutable GrIndexBuffer*                                              fQuadIndexBuffer;
529    // Used to abandon/release all resources created by this GrGpu. TODO: Move this
530    // functionality to GrResourceCache.
531    ObjectList                                                          fObjectList;
532
533    typedef GrDrawTarget INHERITED;
534};
535
536#endif
537