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