GrContext.h revision 0797c2cceadd7dfc2e7f9efa30b611d18efcdcdd
1
2/*
3 * Copyright 2010 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 GrContext_DEFINED
11#define GrContext_DEFINED
12
13#include "GrColor.h"
14#include "GrAARectRenderer.h"
15#include "GrClipData.h"
16#include "SkMatrix.h"
17#include "GrPaint.h"
18#include "GrPathRendererChain.h"
19// not strictly needed but requires WK change in LayerTextureUpdaterCanvas to
20// remove.
21#include "GrRenderTarget.h"
22#include "GrRefCnt.h"
23#include "GrTexture.h"
24
25class GrAutoScratchTexture;
26class GrDrawState;
27class GrDrawTarget;
28class GrEffect;
29class GrFontCache;
30class GrGpu;
31class GrIndexBuffer;
32class GrIndexBufferAllocPool;
33class GrInOrderDrawBuffer;
34class GrPathRenderer;
35class GrResourceEntry;
36class GrResourceCache;
37class GrStencilBuffer;
38class GrTextureParams;
39class GrVertexBuffer;
40class GrVertexBufferAllocPool;
41class GrSoftwarePathRenderer;
42class SkStrokeRec;
43
44class GR_API GrContext : public GrRefCnt {
45public:
46    SK_DECLARE_INST_COUNT(GrContext)
47
48    /**
49     * Creates a GrContext for a backend context.
50     */
51    static GrContext* Create(GrBackend, GrBackendContext);
52
53    /**
54     * Returns the number of GrContext instances for the current thread.
55     */
56    static int GetThreadInstanceCount();
57
58    virtual ~GrContext();
59
60    /**
61     * The GrContext normally assumes that no outsider is setting state
62     * within the underlying 3D API's context/device/whatever. This call informs
63     * the context that the state was modified and it should resend. Shouldn't
64     * be called frequently for good performance.
65     */
66    void resetContext();
67
68    /**
69     * Callback function to allow classes to cleanup on GrContext destruction.
70     * The 'info' field is filled in with the 'info' passed to addCleanUp.
71     */
72    typedef void (*PFCleanUpFunc)(const GrContext* context, void* info);
73
74    /**
75     * Add a function to be called from within GrContext's destructor.
76     * This gives classes a chance to free resources held on a per context basis.
77     * The 'info' parameter will be stored and passed to the callback function.
78     */
79    void addCleanUp(PFCleanUpFunc cleanUp, void* info) {
80        CleanUpData* entry = fCleanUpData.push();
81
82        entry->fFunc = cleanUp;
83        entry->fInfo = info;
84    }
85
86    /**
87     * Abandons all GPU resources, assumes 3D API state is unknown. Call this
88     * if you have lost the associated GPU context, and thus internal texture,
89     * buffer, etc. references/IDs are now invalid. Should be called even when
90     * GrContext is no longer going to be used for two reasons:
91     *  1) ~GrContext will not try to free the objects in the 3D API.
92     *  2) If you've created GrResources that outlive the GrContext they will
93     *     be marked as invalid (GrResource::isValid()) and won't attempt to
94     *     free their underlying resource in the 3D API.
95     * Content drawn since the last GrContext::flush() may be lost.
96     */
97    void contextLost();
98
99    /**
100     * Similar to contextLost, but makes no attempt to reset state.
101     * Use this method when GrContext destruction is pending, but
102     * the graphics context is destroyed first.
103     */
104    void contextDestroyed();
105
106    /**
107     * Frees GPU created by the context. Can be called to reduce GPU memory
108     * pressure.
109     */
110    void freeGpuResources();
111
112    /**
113     * Returns the number of bytes of GPU memory hosted by the texture cache.
114     */
115    size_t getGpuTextureCacheBytes() const;
116
117    ///////////////////////////////////////////////////////////////////////////
118    // Textures
119
120    /**
121     * Create a new entry, based on the specified key and texture and return it.
122     *
123     * @param params    The texture params used to draw a texture may help determine
124     *                  the cache entry used. (e.g. different versions may exist
125     *                  for different wrap modes on GPUs with limited NPOT
126     *                  texture support). NULL implies clamp wrap modes.
127     * @param desc      Description of the texture properties.
128     * @param cacheID Cache-specific properties (e.g., texture gen ID)
129     * @param srcData   Pointer to the pixel values.
130     * @param rowBytes  The number of bytes between rows of the texture. Zero
131     *                  implies tightly packed rows.
132     */
133    GrTexture* createTexture(const GrTextureParams* params,
134                             const GrTextureDesc& desc,
135                             const GrCacheID& cacheID,
136                             void* srcData, size_t rowBytes);
137
138    /**
139     *  Search for an entry based on key and dimensions. If found,
140     *  return it. The return value will be NULL if not found.
141     *
142     *  @param desc     Description of the texture properties.
143     *  @param cacheID Cache-specific properties (e.g., texture gen ID)
144     *  @param params   The texture params used to draw a texture may help determine
145     *                  the cache entry used. (e.g. different versions may exist
146     *                  for different wrap modes on GPUs with limited NPOT
147     *                  texture support). NULL implies clamp wrap modes.
148     */
149    GrTexture* findTexture(const GrTextureDesc& desc,
150                           const GrCacheID& cacheID,
151                           const GrTextureParams* params);
152    /**
153     * Determines whether a texture is in the cache. If the texture is found it
154     * will not be locked or returned. This call does not affect the priority of
155     * the texture for deletion.
156     */
157    bool isTextureInCache(const GrTextureDesc& desc,
158                          const GrCacheID& cacheID,
159                          const GrTextureParams* params) const;
160
161    /**
162     * Enum that determines how closely a returned scratch texture must match
163     * a provided GrTextureDesc.
164     */
165    enum ScratchTexMatch {
166        /**
167         * Finds a texture that exactly matches the descriptor.
168         */
169        kExact_ScratchTexMatch,
170        /**
171         * Finds a texture that approximately matches the descriptor. Will be
172         * at least as large in width and height as desc specifies. If desc
173         * specifies that texture is a render target then result will be a
174         * render target. If desc specifies a render target and doesn't set the
175         * no stencil flag then result will have a stencil. Format and aa level
176         * will always match.
177         */
178        kApprox_ScratchTexMatch
179    };
180
181    /**
182     * Returns a texture matching the desc. It's contents are unknown. Subsequent
183     * requests with the same descriptor are not guaranteed to return the same
184     * texture. The same texture is guaranteed not be returned again until it is
185     * unlocked. Call must be balanced with an unlockTexture() call.
186     *
187     * Textures created by createAndLockTexture() hide the complications of
188     * tiling non-power-of-two textures on APIs that don't support this (e.g.
189     * unextended GLES2). Tiling a NPOT texture created by lockScratchTexture on
190     * such an API will create gaps in the tiling pattern. This includes clamp
191     * mode. (This may be addressed in a future update.)
192     */
193    GrTexture* lockScratchTexture(const GrTextureDesc&, ScratchTexMatch match);
194
195    /**
196     *  When done with an entry, call unlockScratchTexture(entry) on it, which returns
197     *  it to the cache, where it may be purged.
198     */
199    void unlockScratchTexture(GrTexture* texture);
200
201    /**
202     * This method should be called whenever a GrTexture is unreffed or
203     * switched from exclusive to non-exclusive. This
204     * gives the resource cache a chance to discard unneeded textures.
205     * Note: this entry point will be removed once totally ref-driven
206     * cache maintenance is implemented
207     */
208    void purgeCache();
209
210    /**
211     * Creates a texture that is outside the cache. Does not count against
212     * cache's budget.
213     */
214    GrTexture* createUncachedTexture(const GrTextureDesc& desc,
215                                     void* srcData,
216                                     size_t rowBytes);
217
218    /**
219     * Returns true if the specified use of an indexed texture is supported.
220     * Support may depend upon whether the texture params indicate that the
221     * texture will be tiled. Passing NULL for the texture params indicates
222     * clamp mode.
223     */
224    bool supportsIndex8PixelConfig(const GrTextureParams*,
225                                   int width,
226                                   int height) const;
227
228    /**
229     *  Return the current texture cache limits.
230     *
231     *  @param maxTextures If non-null, returns maximum number of textures that
232     *                     can be held in the cache.
233     *  @param maxTextureBytes If non-null, returns maximum number of bytes of
234     *                         texture memory that can be held in the cache.
235     */
236    void getTextureCacheLimits(int* maxTextures, size_t* maxTextureBytes) const;
237
238    /**
239     *  Specify the texture cache limits. If the current cache exceeds either
240     *  of these, it will be purged (LRU) to keep the cache within these limits.
241     *
242     *  @param maxTextures The maximum number of textures that can be held in
243     *                     the cache.
244     *  @param maxTextureBytes The maximum number of bytes of texture memory
245     *                         that can be held in the cache.
246     */
247    void setTextureCacheLimits(int maxTextures, size_t maxTextureBytes);
248
249    /**
250     *  Return the max width or height of a texture supported by the current GPU.
251     */
252    int getMaxTextureSize() const;
253
254    /**
255     * Return the max width or height of a render target supported by the
256     * current GPU.
257     */
258    int getMaxRenderTargetSize() const;
259
260    ///////////////////////////////////////////////////////////////////////////
261    // Render targets
262
263    /**
264     * Sets the render target.
265     * @param target    the render target to set. (should not be NULL.)
266     */
267    void setRenderTarget(GrRenderTarget* target);
268
269    /**
270     * Gets the current render target.
271     * @return the currently bound render target. Should never be NULL.
272     */
273    const GrRenderTarget* getRenderTarget() const;
274    GrRenderTarget* getRenderTarget();
275
276    GrAARectRenderer* getAARectRenderer() { return fAARectRenderer; }
277
278    /**
279     * Can the provided configuration act as a color render target?
280     */
281    bool isConfigRenderable(GrPixelConfig config) const;
282
283    ///////////////////////////////////////////////////////////////////////////
284    // Backend Surfaces
285
286    /**
287     * Wraps an existing texture with a GrTexture object.
288     *
289     * OpenGL: if the object is a texture Gr may change its GL texture params
290     *         when it is drawn.
291     *
292     * @param  desc     description of the object to create.
293     *
294     * @return GrTexture object or NULL on failure.
295     */
296    GrTexture* wrapBackendTexture(const GrBackendTextureDesc& desc);
297
298    /**
299     * Wraps an existing render target with a GrRenderTarget object. It is
300     * similar to wrapBackendTexture but can be used to draw into surfaces
301     * that are not also textures (e.g. FBO 0 in OpenGL, or an MSAA buffer that
302     * the client will resolve to a texture).
303     *
304     * @param  desc     description of the object to create.
305     *
306     * @return GrTexture object or NULL on failure.
307     */
308     GrRenderTarget* wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc);
309
310    ///////////////////////////////////////////////////////////////////////////
311    // Matrix state
312
313    /**
314     * Gets the current transformation matrix.
315     * @return the current matrix.
316     */
317    const SkMatrix& getMatrix() const;
318
319    /**
320     * Sets the transformation matrix.
321     * @param m the matrix to set.
322     */
323    void setMatrix(const SkMatrix& m);
324
325    /**
326     * Sets the current transformation matrix to identity.
327     */
328    void setIdentityMatrix();
329
330    /**
331     * Concats the current matrix. The passed matrix is applied before the
332     * current matrix.
333     * @param m the matrix to concat.
334     */
335    void concatMatrix(const SkMatrix& m) const;
336
337
338    ///////////////////////////////////////////////////////////////////////////
339    // Clip state
340    /**
341     * Gets the current clip.
342     * @return the current clip.
343     */
344    const GrClipData* getClip() const;
345
346    /**
347     * Sets the clip.
348     * @param clipData  the clip to set.
349     */
350    void setClip(const GrClipData* clipData);
351
352    ///////////////////////////////////////////////////////////////////////////
353    // Draws
354
355    /**
356     * Clear the entire or rect of the render target, ignoring any clips.
357     * @param rect  the rect to clear or the whole thing if rect is NULL.
358     * @param color the color to clear to.
359     * @param target if non-NULL, the render target to clear otherwise clear
360     *               the current render target
361     */
362    void clear(const GrIRect* rect, GrColor color,
363               GrRenderTarget* target = NULL);
364
365    /**
366     *  Draw everywhere (respecting the clip) with the paint.
367     */
368    void drawPaint(const GrPaint& paint);
369
370    /**
371     *  Draw the rect using a paint.
372     *  @param paint        describes how to color pixels.
373     *  @param strokeWidth  If strokeWidth < 0, then the rect is filled, else
374     *                      the rect is mitered stroked based on strokeWidth. If
375     *                      strokeWidth == 0, then the stroke is always a single
376     *                      pixel thick.
377     *  @param matrix       Optional matrix applied to the rect. Applied before
378     *                      context's matrix or the paint's matrix.
379     *  The rects coords are used to access the paint (through texture matrix)
380     */
381    void drawRect(const GrPaint& paint,
382                  const GrRect&,
383                  SkScalar strokeWidth = -1,
384                  const SkMatrix* matrix = NULL);
385
386    /**
387     * Maps a rect of paint coordinates onto the a rect of destination
388     * coordinates. Each rect can optionally be transformed. The srcRect
389     * is stretched over the dstRect. The dstRect is transformed by the
390     * context's matrix and the srcRect is transformed by the paint's matrix.
391     * Additional optional matrices can be provided by parameters.
392     *
393     * @param paint     describes how to color pixels.
394     * @param dstRect   the destination rect to draw.
395     * @param srcRect   rect of paint coordinates to be mapped onto dstRect
396     * @param dstMatrix Optional matrix to transform dstRect. Applied before
397     *                  context's matrix.
398     * @param srcMatrix Optional matrix to transform srcRect Applied before
399     *                  paint's matrix.
400     */
401    void drawRectToRect(const GrPaint& paint,
402                        const GrRect& dstRect,
403                        const GrRect& srcRect,
404                        const SkMatrix* dstMatrix = NULL,
405                        const SkMatrix* srcMatrix = NULL);
406
407    /**
408     * Draws a path.
409     *
410     * @param paint         describes how to color pixels.
411     * @param path          the path to draw
412     * @param stroke        the stroke information (width, join, cap)
413     */
414    void drawPath(const GrPaint& paint, const SkPath& path, const SkStrokeRec& stroke);
415
416    /**
417     * Draws vertices with a paint.
418     *
419     * @param   paint           describes how to color pixels.
420     * @param   primitiveType   primitives type to draw.
421     * @param   vertexCount     number of vertices.
422     * @param   positions       array of vertex positions, required.
423     * @param   texCoords       optional array of texture coordinates used
424     *                          to access the paint.
425     * @param   colors          optional array of per-vertex colors, supercedes
426     *                          the paint's color field.
427     * @param   indices         optional array of indices. If NULL vertices
428     *                          are drawn non-indexed.
429     * @param   indexCount      if indices is non-null then this is the
430     *                          number of indices.
431     */
432    void drawVertices(const GrPaint& paint,
433                      GrPrimitiveType primitiveType,
434                      int vertexCount,
435                      const GrPoint positions[],
436                      const GrPoint texs[],
437                      const GrColor colors[],
438                      const uint16_t indices[],
439                      int indexCount);
440
441    /**
442     * Draws an oval.
443     *
444     * @param paint         describes how to color pixels.
445     * @param rect          the bounding rect of the oval.
446     * @param strokeWidth   if strokeWidth < 0, then the oval is filled, else
447     *                      the rect is stroked based on strokeWidth. If
448     *                      strokeWidth == 0, then the stroke is always a single
449     *                      pixel thick.
450     */
451    void drawOval(const GrPaint& paint,
452                  const GrRect& rect,
453                  SkScalar strokeWidth);
454
455    ///////////////////////////////////////////////////////////////////////////
456    // Misc.
457
458    /**
459     * Flags that affect flush() behavior.
460     */
461    enum FlushBits {
462        /**
463         * A client may want Gr to bind a GrRenderTarget in the 3D API so that
464         * it can be rendered to directly. However, Gr lazily sets state. Simply
465         * calling setRenderTarget() followed by flush() without flags may not
466         * bind the render target. This flag forces the context to bind the last
467         * set render target in the 3D API.
468         */
469        kForceCurrentRenderTarget_FlushBit   = 0x1,
470        /**
471         * A client may reach a point where it has partially rendered a frame
472         * through a GrContext that it knows the user will never see. This flag
473         * causes the flush to skip submission of deferred content to the 3D API
474         * during the flush.
475         */
476        kDiscard_FlushBit                    = 0x2,
477    };
478
479    /**
480     * Call to ensure all drawing to the context has been issued to the
481     * underlying 3D API.
482     * @param flagsBitfield     flags that control the flushing behavior. See
483     *                          FlushBits.
484     */
485    void flush(int flagsBitfield = 0);
486
487   /**
488    * These flags can be used with the read/write pixels functions below.
489    */
490    enum PixelOpsFlags {
491        /** The GrContext will not be flushed. This means that the read or write may occur before
492            previous draws have executed. */
493        kDontFlush_PixelOpsFlag = 0x1,
494        /** The src for write or dst read is unpremultiplied. This is only respected if both the
495            config src and dst configs are an RGBA/BGRA 8888 format. */
496        kUnpremul_PixelOpsFlag  = 0x2,
497    };
498
499    /**
500     * Reads a rectangle of pixels from a render target.
501     * @param target        the render target to read from. NULL means the current render target.
502     * @param left          left edge of the rectangle to read (inclusive)
503     * @param top           top edge of the rectangle to read (inclusive)
504     * @param width         width of rectangle to read in pixels.
505     * @param height        height of rectangle to read in pixels.
506     * @param config        the pixel config of the destination buffer
507     * @param buffer        memory to read the rectangle into.
508     * @param rowBytes      number of bytes bewtween consecutive rows. Zero means rows are tightly
509     *                      packed.
510     * @param pixelOpsFlags see PixelOpsFlags enum above.
511     *
512     * @return true if the read succeeded, false if not. The read can fail because of an unsupported
513     *         pixel config or because no render target is currently set and NULL was passed for
514     *         target.
515     */
516    bool readRenderTargetPixels(GrRenderTarget* target,
517                                int left, int top, int width, int height,
518                                GrPixelConfig config, void* buffer,
519                                size_t rowBytes = 0,
520                                uint32_t pixelOpsFlags = 0);
521
522    /**
523     * Copy the src pixels [buffer, row bytes, pixel config] into a render target at the specified
524     * rectangle.
525     * @param target        the render target to write into. NULL means the current render target.
526     * @param left          left edge of the rectangle to write (inclusive)
527     * @param top           top edge of the rectangle to write (inclusive)
528     * @param width         width of rectangle to write in pixels.
529     * @param height        height of rectangle to write in pixels.
530     * @param config        the pixel config of the source buffer
531     * @param buffer        memory to read the rectangle from.
532     * @param rowBytes      number of bytes between consecutive rows. Zero means rows are tightly
533     *                      packed.
534     * @param pixelOpsFlags see PixelOpsFlags enum above.
535     */
536    void writeRenderTargetPixels(GrRenderTarget* target,
537                                 int left, int top, int width, int height,
538                                 GrPixelConfig config, const void* buffer,
539                                 size_t rowBytes = 0,
540                                 uint32_t pixelOpsFlags = 0);
541
542    /**
543     * Reads a rectangle of pixels from a texture.
544     * @param texture       the texture to read from.
545     * @param left          left edge of the rectangle to read (inclusive)
546     * @param top           top edge of the rectangle to read (inclusive)
547     * @param width         width of rectangle to read in pixels.
548     * @param height        height of rectangle to read in pixels.
549     * @param config        the pixel config of the destination buffer
550     * @param buffer        memory to read the rectangle into.
551     * @param rowBytes      number of bytes between consecutive rows. Zero means rows are tightly
552     *                      packed.
553     * @param pixelOpsFlags see PixelOpsFlags enum above.
554     *
555     * @return true if the read succeeded, false if not. The read can fail because of an unsupported
556     *         pixel config.
557     */
558    bool readTexturePixels(GrTexture* texture,
559                           int left, int top, int width, int height,
560                           GrPixelConfig config, void* buffer,
561                           size_t rowBytes = 0,
562                           uint32_t pixelOpsFlags = 0);
563
564    /**
565     * Writes a rectangle of pixels to a texture.
566     * @param texture       the render target to read from.
567     * @param left          left edge of the rectangle to write (inclusive)
568     * @param top           top edge of the rectangle to write (inclusive)
569     * @param width         width of rectangle to write in pixels.
570     * @param height        height of rectangle to write in pixels.
571     * @param config        the pixel config of the source buffer
572     * @param buffer        memory to read pixels from
573     * @param rowBytes      number of bytes between consecutive rows. Zero
574     *                      means rows are tightly packed.
575     * @param pixelOpsFlags see PixelOpsFlags enum above.
576     */
577    void writeTexturePixels(GrTexture* texture,
578                            int left, int top, int width, int height,
579                            GrPixelConfig config, const void* buffer,
580                            size_t rowBytes,
581                            uint32_t pixelOpsFlags = 0);
582
583
584    /**
585     * Copies a rectangle of texels from src to dst. The size of dst is the size of the rectangle
586     * copied and topLeft is the position of the rect in src. The rectangle is clipped to src's
587     * bounds.
588     * @param src           the texture to copy from.
589     * @param dst           the render target to copy to.
590     * @param topLeft       the point in src that will be copied to the top-left of dst. If NULL,
591     *                      (0, 0) will be used.
592     */
593    void copyTexture(GrTexture* src, GrRenderTarget* dst, const SkIPoint* topLeft = NULL);
594
595    /**
596     * Resolves a render target that has MSAA. The intermediate MSAA buffer is
597     * down-sampled to the associated GrTexture (accessible via
598     * GrRenderTarget::asTexture()). Any pending draws to the render target will
599     * be executed before the resolve.
600     *
601     * This is only necessary when a client wants to access the object directly
602     * using the backend API directly. GrContext will detect when it must
603     * perform a resolve to a GrTexture used as the source of a draw or before
604     * reading pixels back from a GrTexture or GrRenderTarget.
605     */
606    void resolveRenderTarget(GrRenderTarget* target);
607
608    /**
609     * Applies a 2D Gaussian blur to a given texture.
610     * @param srcTexture      The source texture to be blurred.
611     * @param canClobberSrc   If true, srcTexture may be overwritten, and
612     *                        may be returned as the result.
613     * @param rect            The destination rectangle.
614     * @param sigmaX          The blur's standard deviation in X.
615     * @param sigmaY          The blur's standard deviation in Y.
616     * @return the blurred texture, which may be srcTexture reffed, or a
617     * new texture.  It is the caller's responsibility to unref this texture.
618     */
619     GrTexture* gaussianBlur(GrTexture* srcTexture,
620                             bool canClobberSrc,
621                             const SkRect& rect,
622                             float sigmaX, float sigmaY);
623
624    /**
625     * Zooms a subset of the texture to a larger size with a nice edge.
626     * The inner rectangle is a simple scaling of the texture by a factor of
627     * |zoom|.  The outer |inset| pixels transition from the background texture
628     * to the zoomed coordinate system at a rate of
629     * (distance_to_edge / inset) ^2, producing a rounded lens effect.
630     * @param srcTexture      The source texture to be zoomed.
631     * @param dstRect         The destination rectangle.
632     * @param srcRect         The source rectangle.  Must be smaller than
633     *                        dstRect
634     * @param inset           Number of pixels to blend along the edges.
635     * @return the zoomed texture, which is dstTexture.
636     */
637     GrTexture* zoom(GrTexture* srcTexture,
638                     const SkRect& dstRect, const SkRect& srcRect, float inset);
639
640    ///////////////////////////////////////////////////////////////////////////
641    // Helpers
642
643    class AutoRenderTarget : public ::GrNoncopyable {
644    public:
645        AutoRenderTarget(GrContext* context, GrRenderTarget* target) {
646            fPrevTarget = context->getRenderTarget();
647            GrSafeRef(fPrevTarget);
648            context->setRenderTarget(target);
649            fContext = context;
650        }
651        AutoRenderTarget(GrContext* context) {
652            fPrevTarget = context->getRenderTarget();
653            GrSafeRef(fPrevTarget);
654            fContext = context;
655        }
656        ~AutoRenderTarget() {
657            if (NULL != fContext) {
658                fContext->setRenderTarget(fPrevTarget);
659            }
660            GrSafeUnref(fPrevTarget);
661        }
662    private:
663        GrContext*      fContext;
664        GrRenderTarget* fPrevTarget;
665    };
666
667    /**
668     * Save/restore the view-matrix in the context. It can optionally adjust a paint to account
669     * for a coordinate system change. Here is an example of how the paint param can be used:
670     *
671     * A GrPaint is setup with GrEffects. The stages will have access to the pre-matrix source
672     * geometry positions when the draw is executed. Later on a decision is made to transform the
673     * geometry to device space on the CPU. The effects now need to know that the space in which
674     * the geometry will be specified has changed.
675     *
676     * Note that when restore is called (or in the destructor) the context's matrix will be
677     * restored. However, the paint will not be restored. The caller must make a copy of the
678     * paint if necessary. Hint: use SkTCopyOnFirstWrite if the AutoMatrix is conditionally
679     * initialized.
680     */
681    class AutoMatrix : GrNoncopyable {
682    public:
683        AutoMatrix() : fContext(NULL) {}
684
685        ~AutoMatrix() { this->restore(); }
686
687        /**
688         * Initializes by pre-concat'ing the context's current matrix with the preConcat param.
689         */
690        void setPreConcat(GrContext* context, const SkMatrix& preConcat, GrPaint* paint = NULL) {
691            GrAssert(NULL != context);
692
693            this->restore();
694
695            fContext = context;
696            fMatrix = context->getMatrix();
697            this->preConcat(preConcat, paint);
698        }
699
700        /**
701         * Sets the context's matrix to identity. Returns false if the inverse matrix is required to
702         * update a paint but the matrix cannot be inverted.
703         */
704        bool setIdentity(GrContext* context, GrPaint* paint = NULL) {
705            GrAssert(NULL != context);
706
707            this->restore();
708
709            if (NULL != paint) {
710                if (!paint->sourceCoordChangeByInverse(context->getMatrix())) {
711                    return false;
712                }
713            }
714            fMatrix = context->getMatrix();
715            fContext = context;
716            context->setIdentityMatrix();
717            return true;
718        }
719
720        /**
721         * Replaces the context's matrix with a new matrix. Returns false if the inverse matrix is
722         * required to update a paint but the matrix cannot be inverted.
723         */
724        bool set(GrContext* context, const SkMatrix& newMatrix, GrPaint* paint = NULL) {
725            if (NULL != paint) {
726                if (!this->setIdentity(context, paint)) {
727                    return false;
728                }
729                this->preConcat(newMatrix, paint);
730            } else {
731                this->restore();
732                fContext = context;
733                fMatrix = context->getMatrix();
734                context->setMatrix(newMatrix);
735            }
736            return true;
737        }
738
739        /**
740         * If this has been initialized then the context's matrix will be further updated by
741         * pre-concat'ing the preConcat param. The matrix that will be restored remains unchanged.
742         * The paint is assumed to be relative to the context's matrix at the time this call is
743         * made, not the matrix at the time AutoMatrix was first initialized. In other words, this
744         * performs an incremental update of the paint.
745         */
746        void preConcat(const SkMatrix& preConcat, GrPaint* paint = NULL) {
747            if (NULL != paint) {
748                paint->sourceCoordChange(preConcat);
749            }
750            fContext->concatMatrix(preConcat);
751        }
752
753        /**
754         * Returns false if never initialized or the inverse matrix was required to update a paint
755         * but the matrix could not be inverted.
756         */
757        bool succeeded() const { return NULL != fContext; }
758
759        /**
760         * If this has been initialized then the context's original matrix is restored.
761         */
762        void restore() {
763            if (NULL != fContext) {
764                fContext->setMatrix(fMatrix);
765                fContext = NULL;
766            }
767        }
768
769    private:
770        GrContext*  fContext;
771        SkMatrix    fMatrix;
772    };
773
774    class AutoClip : GrNoncopyable {
775    public:
776        // This enum exists to require a caller of the constructor to acknowledge that the clip will
777        // initially be wide open. It also could be extended if there are other desirable initial
778        // clip states.
779        enum InitialClip {
780            kWideOpen_InitialClip,
781        };
782
783        AutoClip(GrContext* context, InitialClip initialState)
784        : fContext(context) {
785            GrAssert(kWideOpen_InitialClip == initialState);
786            fNewClipData.fClipStack = &fNewClipStack;
787
788            fOldClip = context->getClip();
789            context->setClip(&fNewClipData);
790        }
791
792        AutoClip(GrContext* context, const GrRect& newClipRect)
793        : fContext(context)
794        , fNewClipStack(newClipRect) {
795            fNewClipData.fClipStack = &fNewClipStack;
796
797            fOldClip = fContext->getClip();
798            fContext->setClip(&fNewClipData);
799        }
800
801        ~AutoClip() {
802            if (NULL != fContext) {
803                fContext->setClip(fOldClip);
804            }
805        }
806    private:
807        GrContext*        fContext;
808        const GrClipData* fOldClip;
809
810        SkClipStack       fNewClipStack;
811        GrClipData        fNewClipData;
812    };
813
814    class AutoWideOpenIdentityDraw {
815    public:
816        AutoWideOpenIdentityDraw(GrContext* ctx, GrRenderTarget* rt)
817            : fAutoClip(ctx, AutoClip::kWideOpen_InitialClip)
818            , fAutoRT(ctx, rt) {
819            fAutoMatrix.setIdentity(ctx);
820            // should never fail with no paint param.
821            GrAssert(fAutoMatrix.succeeded());
822        }
823
824    private:
825        AutoClip fAutoClip;
826        AutoRenderTarget fAutoRT;
827        AutoMatrix fAutoMatrix;
828    };
829
830    ///////////////////////////////////////////////////////////////////////////
831    // Functions intended for internal use only.
832    GrGpu* getGpu() { return fGpu; }
833    const GrGpu* getGpu() const { return fGpu; }
834    GrFontCache* getFontCache() { return fFontCache; }
835    GrDrawTarget* getTextTarget(const GrPaint& paint);
836    const GrIndexBuffer* getQuadIndexBuffer() const;
837
838    /**
839     * Stencil buffers add themselves to the cache using addStencilBuffer. findStencilBuffer is
840     * called to check the cache for a SB that matches an RT's criteria.
841     */
842    void addStencilBuffer(GrStencilBuffer* sb);
843    GrStencilBuffer* findStencilBuffer(int width, int height, int sampleCnt);
844
845    GrPathRenderer* getPathRenderer(
846                    const SkPath& path,
847                    const SkStrokeRec& stroke,
848                    const GrDrawTarget* target,
849                    bool allowSW,
850                    GrPathRendererChain::DrawType drawType = GrPathRendererChain::kColor_DrawType,
851                    GrPathRendererChain::StencilSupport* stencilSupport = NULL);
852
853#if GR_CACHE_STATS
854    void printCacheStats() const;
855#endif
856
857    ///////////////////////////////////////////////////////////////////////////
858    // Legacy names that will be kept until WebKit can be updated.
859    GrTexture* createPlatformTexture(const GrPlatformTextureDesc& desc) {
860        return this->wrapBackendTexture(desc);
861    }
862
863    GrRenderTarget* createPlatformRenderTarget(const GrPlatformRenderTargetDesc& desc) {
864        return wrapBackendRenderTarget(desc);
865    }
866
867private:
868    // Used to indicate whether a draw should be performed immediately or queued in fDrawBuffer.
869    enum BufferedDraw {
870        kYes_BufferedDraw,
871        kNo_BufferedDraw,
872    };
873    BufferedDraw fLastDrawWasBuffered;
874
875    GrGpu*              fGpu;
876    GrDrawState*        fDrawState;
877
878    GrResourceCache*    fTextureCache;
879    GrFontCache*        fFontCache;
880
881    GrPathRendererChain*        fPathRendererChain;
882    GrSoftwarePathRenderer*     fSoftwarePathRenderer;
883
884    GrVertexBufferAllocPool*    fDrawBufferVBAllocPool;
885    GrIndexBufferAllocPool*     fDrawBufferIBAllocPool;
886    GrInOrderDrawBuffer*        fDrawBuffer;
887
888    GrAARectRenderer*           fAARectRenderer;
889
890    bool                        fDidTestPMConversions;
891    int                         fPMToUPMConversion;
892    int                         fUPMToPMConversion;
893
894    struct CleanUpData {
895        PFCleanUpFunc fFunc;
896        void*         fInfo;
897    };
898
899    SkTDArray<CleanUpData>      fCleanUpData;
900
901    GrContext(GrGpu* gpu);
902
903    void setupDrawBuffer();
904
905    void flushDrawBuffer();
906
907    /// Sets the paint and returns the target to draw into. The paint can be NULL in which case the
908    /// draw state is left unmodified.
909    GrDrawTarget* prepareToDraw(const GrPaint*, BufferedDraw);
910
911    void internalDrawPath(const GrPaint& paint, const SkPath& path, const SkStrokeRec& stroke);
912
913    GrTexture* createResizedTexture(const GrTextureDesc& desc,
914                                    const GrCacheID& cacheID,
915                                    void* srcData,
916                                    size_t rowBytes,
917                                    bool needsFiltering);
918
919    // Needed so GrTexture's returnToCache helper function can call
920    // addExistingTextureToCache
921    friend class GrTexture;
922
923    // Add an existing texture to the texture cache. This is intended solely
924    // for use with textures released from an GrAutoScratchTexture.
925    void addExistingTextureToCache(GrTexture* texture);
926
927    bool installPMToUPMEffect(GrTexture* texture,
928                              bool swapRAndB,
929                              const SkMatrix& matrix,
930                              GrEffectStage* stage);
931    bool installUPMToPMEffect(GrTexture* texture,
932                              bool swapRAndB,
933                              const SkMatrix& matrix,
934                              GrEffectStage* stage);
935
936    typedef GrRefCnt INHERITED;
937};
938
939/**
940 * Gets and locks a scratch texture from a descriptor using either exact or approximate criteria.
941 * Unlocks texture in the destructor.
942 */
943class GrAutoScratchTexture : ::GrNoncopyable {
944public:
945    GrAutoScratchTexture()
946        : fContext(NULL)
947        , fTexture(NULL) {
948    }
949
950    GrAutoScratchTexture(GrContext* context,
951                         const GrTextureDesc& desc,
952                         GrContext::ScratchTexMatch match = GrContext::kApprox_ScratchTexMatch)
953      : fContext(NULL)
954      , fTexture(NULL) {
955      this->set(context, desc, match);
956    }
957
958    ~GrAutoScratchTexture() {
959        this->reset();
960    }
961
962    void reset() {
963        if (NULL != fContext && NULL != fTexture) {
964            fContext->unlockScratchTexture(fTexture);
965            fTexture = NULL;
966        }
967    }
968
969    /*
970     * When detaching a texture we do not unlock it in the texture cache but
971     * we do set the returnToCache flag. In this way the texture remains
972     * "locked" in the texture cache until it is freed and recycled in
973     * GrTexture::internal_dispose. In reality, the texture has been removed
974     * from the cache (because this is in AutoScratchTexture) and by not
975     * calling unlockTexture we simply don't re-add it. It will be reattached
976     * in GrTexture::internal_dispose.
977     *
978     * Note that the caller is assumed to accept and manage the ref to the
979     * returned texture.
980     */
981    GrTexture* detach() {
982        GrTexture* temp = fTexture;
983
984        // Conceptually the texture's cache entry loses its ref to the
985        // texture while the caller of this method gets a ref.
986        GrAssert(NULL != temp->getCacheEntry());
987
988        fTexture = NULL;
989
990        temp->setFlag((GrTextureFlags) GrTexture::kReturnToCache_FlagBit);
991        return temp;
992    }
993
994    GrTexture* set(GrContext* context,
995                   const GrTextureDesc& desc,
996                   GrContext::ScratchTexMatch match = GrContext::kApprox_ScratchTexMatch) {
997        this->reset();
998
999        fContext = context;
1000        if (NULL != fContext) {
1001            fTexture = fContext->lockScratchTexture(desc, match);
1002            if (NULL == fTexture) {
1003                fContext = NULL;
1004            }
1005            return fTexture;
1006        } else {
1007            return NULL;
1008        }
1009    }
1010
1011    GrTexture* texture() { return fTexture; }
1012
1013private:
1014    GrContext*                    fContext;
1015    GrTexture*                    fTexture;
1016};
1017
1018#endif
1019