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