• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     Copyright 2010 Google Inc.
3 
4     Licensed under the Apache License, Version 2.0 (the "License");
5     you may not use this file except in compliance with the License.
6     You may obtain a copy of the License at
7 
8          http://www.apache.org/licenses/LICENSE-2.0
9 
10     Unless required by applicable law or agreed to in writing, software
11     distributed under the License is distributed on an "AS IS" BASIS,
12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13     See the License for the specific language governing permissions and
14     limitations under the License.
15  */
16 
17 #ifndef GrContext_DEFINED
18 #define GrContext_DEFINED
19 
20 #include "GrClip.h"
21 #include "GrTextureCache.h"
22 #include "GrPaint.h"
23 #include "GrPathRenderer.h"
24 
25 class GrFontCache;
26 class GrGpu;
27 struct GrGpuStats;
28 class GrVertexBufferAllocPool;
29 class GrIndexBufferAllocPool;
30 class GrInOrderDrawBuffer;
31 
32 class GR_API GrContext : public GrRefCnt {
33 public:
34     /**
35      * Creates a GrContext from within a 3D context.
36      */
37     static GrContext* Create(GrEngine engine,
38                              GrPlatform3DContext context3D);
39 
40     /**
41      *  Helper to create a opengl-shader based context
42      */
43     static GrContext* CreateGLShaderContext();
44 
45     virtual ~GrContext();
46 
47     /**
48      * The GrContext normally assumes that no outsider is setting state
49      * within the underlying 3D API's context/device/whatever. This call informs
50      * the context that the state was modified and it should resend. Shouldn't
51      * be called frequently for good performance.
52      */
53     void resetContext();
54 
55     /**
56      * Abandons all gpu resources, assumes 3D API state is unknown. Call this
57      * if you have lost the associated GPU context, and thus internal texture,
58      * buffer, etc. references/IDs are now invalid. Should be called even when
59      * GrContext is no longer going to be used for two reasons:
60      *  1) ~GrContext will not try to free the objects in the 3D API.
61      *  2) If you've created GrResources that outlive the GrContext they will
62      *     be marked as invalid (GrResource::isValid()) and won't attempt to
63      *     free their underlying resource in the 3D API.
64      * Content drawn since the last GrContext::flush() may be lost.
65      */
66     void contextLost();
67 
68     /**
69      * Similar to contextLost, but makes no attempt to reset state.
70      * Use this method when GrContext destruction is pending, but
71      * the graphics context is destroyed first.
72      */
73     void contextDestroyed();
74 
75     /**
76      * Frees gpu created by the context. Can be called to reduce GPU memory
77      * pressure.
78      */
79     void freeGpuResources();
80 
81     ///////////////////////////////////////////////////////////////////////////
82     // Textures
83 
84     /**
85      *  Search for an entry with the same Key. If found, "lock" it and return it.
86      *  If not found, return null.
87      */
88     GrTextureEntry* findAndLockTexture(GrTextureKey*,
89                                        const GrSamplerState&);
90 
91 
92     /**
93      *  Create a new entry, based on the specified key and texture, and return
94      *  its "locked" entry.
95      *
96      *  Ownership of the texture is transferred to the Entry, which will unref()
97      *  it when we are purged or deleted.
98      */
99     GrTextureEntry* createAndLockTexture(GrTextureKey* key,
100                                          const GrSamplerState&,
101                                          const GrTextureDesc&,
102                                          void* srcData, size_t rowBytes);
103 
104     /**
105      * Returns a texture matching the desc. It's contents are unknown. Subsequent
106      * requests with the same descriptor are not guaranteed to return the same
107      * texture. The same texture is guaranteed not be returned again until it is
108      * unlocked.
109      *
110      * Textures created by createAndLockTexture() hide the complications of
111      * tiling non-power-of-two textures on APIs that don't support this (e.g.
112      * unextended GLES2). Tiling a npot texture created by lockKeylessTexture on
113      * such an API will create gaps in the tiling pattern. This includes clamp
114      * mode. (This may be addressed in a future update.)
115      */
116     GrTextureEntry* lockKeylessTexture(const GrTextureDesc& desc);
117 
118     /**
119      *  When done with an entry, call unlockTexture(entry) on it, which returns
120      *  it to the cache, where it may be purged.
121      */
122     void unlockTexture(GrTextureEntry* entry);
123 
124     /**
125      * Creates a texture that is outside the cache. Does not count against
126      * cache's budget.
127      */
128     GrTexture* createUncachedTexture(const GrTextureDesc&,
129                                      void* srcData,
130                                      size_t rowBytes);
131 
132     /**
133      *  Returns true if the specified use of an indexed texture is supported.
134      */
135     bool supportsIndex8PixelConfig(const GrSamplerState&, int width, int height);
136 
137     /**
138      *  Return the current texture cache limits.
139      *
140      *  @param maxTextures If non-null, returns maximum number of textures that
141      *                     can be held in the cache.
142      *  @param maxTextureBytes If non-null, returns maximum number of bytes of
143      *                         texture memory that can be held in the cache.
144      */
145     void getTextureCacheLimits(int* maxTextures, size_t* maxTextureBytes) const;
146 
147     /**
148      *  Specify the texture cache limits. If the current cache exceeds either
149      *  of these, it will be purged (LRU) to keep the cache within these limits.
150      *
151      *  @param maxTextures The maximum number of textures that can be held in
152      *                     the cache.
153      *  @param maxTextureBytes The maximum number of bytes of texture memory
154      *                         that can be held in the cache.
155      */
156     void setTextureCacheLimits(int maxTextures, size_t maxTextureBytes);
157 
158     /**
159      *  Return the max width or height of a texture supported by the current gpu
160      */
161     int getMaxTextureDimension();
162 
163     ///////////////////////////////////////////////////////////////////////////
164     // Render targets
165 
166     /**
167      * Sets the render target.
168      * @param target    the render target to set. (should not be NULL.)
169      */
170     void setRenderTarget(GrRenderTarget* target);
171 
172     /**
173      * Gets the current render target.
174      * @return the currently bound render target. Should never be NULL.
175      */
176     const GrRenderTarget* getRenderTarget() const;
177     GrRenderTarget* getRenderTarget();
178 
179     ///////////////////////////////////////////////////////////////////////////
180     // Platform Surfaces
181 
182     // GrContext provides an interface for wrapping externally created textures
183     // and rendertargets in their Gr-equivalents.
184 
185     /**
186      * Wraps an existing 3D API surface in a GrObject. desc.fFlags determines
187      * the type of object returned. If kIsTexture is set the returned object
188      * will be a GrTexture*. Otherwise, it will be a GrRenderTarget*. If both
189      * are set the render target object is accessible by
190      * GrTexture::asRenderTarget().
191      *
192      * GL: if the object is a texture Gr may change its GL texture parameters
193      *     when it is drawn.
194      *
195      * @param   desc    description of the object to create.
196      * @return either a GrTexture* or GrRenderTarget* depending on desc. NULL
197      *         on failure.
198      */
199     GrResource* createPlatformSurface(const GrPlatformSurfaceDesc& desc);
200     /**
201      * Reads the current target object (e.g. FBO or IDirect3DSurface9*) and
202      * viewport state from the underlying 3D API and wraps it in a
203      * GrRenderTarget. The GrRenderTarget will not attempt to delete/destroy the
204      * underlying object in its destructor and it is up to caller to guarantee
205      * that it remains valid while the GrRenderTarget is used.
206      *
207      * Will not detect that the render target is also a texture. If you need
208      * to also use the render target as a GrTexture use createPlatformSurface.
209      *
210      * @return the newly created GrRenderTarget
211      */
212     GrRenderTarget* createRenderTargetFrom3DApiState();
213 
214     ///////////////////////////////////////////////////////////////////////////
215     // Matrix state
216 
217     /**
218      * Gets the current transformation matrix.
219      * @return the current matrix.
220      */
221     const GrMatrix& getMatrix() const;
222 
223     /**
224      * Sets the transformation matrix.
225      * @param m the matrix to set.
226      */
227     void setMatrix(const GrMatrix& m);
228 
229     /**
230      * Concats the current matrix. The passed matrix is applied before the
231      * current matrix.
232      * @param m the matrix to concat.
233      */
234     void concatMatrix(const GrMatrix& m) const;
235 
236 
237     ///////////////////////////////////////////////////////////////////////////
238     // Clip state
239     /**
240      * Gets the current clip.
241      * @return the current clip.
242      */
243     const GrClip& getClip() const;
244 
245     /**
246      * Sets the clip.
247      * @param clip  the clip to set.
248      */
249     void setClip(const GrClip& clip);
250 
251     /**
252      * Convenience method for setting the clip to a rect.
253      * @param rect  the rect to set as the new clip.
254      */
255     void setClip(const GrIRect& rect);
256 
257     ///////////////////////////////////////////////////////////////////////////
258     // Draws
259 
260     /**
261      * Clear the entire or rect of the render target, ignoring any clips.
262      * @param rect  the rect to clear or the whole thing if rect is NULL.
263      * @param color the color to clear to.
264      */
265     void clear(const GrIRect* rect, GrColor color);
266 
267     /**
268      *  Draw everywhere (respecting the clip) with the paint.
269      */
270     void drawPaint(const GrPaint& paint);
271 
272     /**
273      *  Draw the rect using a paint.
274      *  @param paint        describes how to color pixels.
275      *  @param strokeWidth  If strokeWidth < 0, then the rect is filled, else
276      *                      the rect is mitered stroked based on strokeWidth. If
277      *                      strokeWidth == 0, then the stroke is always a single
278      *                      pixel thick.
279      *  @param matrix       Optional matrix applied to the rect. Applied before
280      *                      context's matrix or the paint's matrix.
281      *  The rects coords are used to access the paint (through texture matrix)
282      */
283     void drawRect(const GrPaint& paint,
284                   const GrRect&,
285                   GrScalar strokeWidth = -1,
286                   const GrMatrix* matrix = NULL);
287 
288     /**
289      * Maps a rect of paint coordinates onto the a rect of destination
290      * coordinates. Each rect can optionally be transformed. The srcRect
291      * is stretched over the dstRect. The dstRect is transformed by the
292      * context's matrix and the srcRect is transformed by the paint's matrix.
293      * Additional optional matrices can be provided by parameters.
294      *
295      * @param paint     describes how to color pixels.
296      * @param dstRect   the destination rect to draw.
297      * @param srcRect   rect of paint coordinates to be mapped onto dstRect
298      * @param dstMatrix Optional matrix to transform dstRect. Applied before
299      *                  context's matrix.
300      * @param srcMatrix Optional matrix to transform srcRect Applied before
301      *                  paint's matrix.
302      */
303     void drawRectToRect(const GrPaint& paint,
304                         const GrRect& dstRect,
305                         const GrRect& srcRect,
306                         const GrMatrix* dstMatrix = NULL,
307                         const GrMatrix* srcMatrix = NULL);
308 
309     /**
310      * Draws a path.
311      *
312      * @param paint         describes how to color pixels.
313      * @param path          the path to draw
314      * @param fill          the path filling rule to use.
315      * @param translate     optional additional translation applied to the
316      *                      path.
317      */
318     void drawPath(const GrPaint& paint, const GrPath& path, GrPathFill fill,
319                   const GrPoint* translate = NULL);
320 
321     /**
322      * Draws vertices with a paint.
323      *
324      * @param   paint           describes how to color pixels.
325      * @param   primitiveType   primitives type to draw.
326      * @param   vertexCount     number of vertices.
327      * @param   positions       array of vertex positions, required.
328      * @param   texCoords       optional array of texture coordinates used
329      *                          to access the paint.
330      * @param   colors          optional array of per-vertex colors, supercedes
331      *                          the paint's color field.
332      * @param   indices         optional array of indices. If NULL vertices
333      *                          are drawn non-indexed.
334      * @param   indexCount      if indices is non-null then this is the
335      *                          number of indices.
336      */
337     void drawVertices(const GrPaint& paint,
338                       GrPrimitiveType primitiveType,
339                       int vertexCount,
340                       const GrPoint positions[],
341                       const GrPoint texs[],
342                       const GrColor colors[],
343                       const uint16_t indices[],
344                       int indexCount);
345 
346     /**
347      * Similar to drawVertices but caller provides objects that convert to Gr
348      * types. The count of vertices is given by posSrc.
349      *
350      * @param   paint           describes how to color pixels.
351      * @param   primitiveType   primitives type to draw.
352      * @param   posSrc          Source of vertex positions. Must implement
353      *                              int count() const;
354      *                              void writeValue(int i, GrPoint* point) const;
355      *                          count returns the total number of vertices and
356      *                          writeValue writes a vertex position to point.
357      * @param   texSrc          optional, pass NULL to not use explicit tex
358      *                          coords. If present provides tex coords with
359      *                          method:
360      *                              void writeValue(int i, GrPoint* point) const;
361      * @param   texSrc          optional, pass NULL to not use per-vertex colors
362      *                          If present provides colors with method:
363      *                              void writeValue(int i, GrColor* point) const;
364      * @param   indices         optional, pass NULL for non-indexed drawing. If
365      *                          present supplies indices for indexed drawing
366      *                          with following methods:
367      *                              int count() const;
368      *                              void writeValue(int i, uint16_t* point) const;
369      *                          count returns the number of indices and
370      *                          writeValue supplies each index.
371      */
372     template <typename POS_SRC,
373               typename TEX_SRC,
374               typename COL_SRC,
375               typename IDX_SRC>
376     void drawCustomVertices(const GrPaint& paint,
377                             GrPrimitiveType primitiveType,
378                             const POS_SRC& posSrc,
379                             const TEX_SRC* texCoordSrc,
380                             const COL_SRC* colorSrc,
381                             const IDX_SRC* idxSrc);
382     /**
383      * To avoid the problem of having to create a typename for NULL parameters,
384      * these reduced versions of drawCustomVertices are provided.
385      */
386     template <typename POS_SRC>
387     void drawCustomVertices(const GrPaint& paint,
388                             GrPrimitiveType primitiveType,
389                             const POS_SRC& posSrc);
390     template <typename POS_SRC, typename TEX_SRC>
391     void drawCustomVertices(const GrPaint& paint,
392                             GrPrimitiveType primitiveType,
393                             const POS_SRC& posSrc,
394                             const TEX_SRC* texCoordSrc);
395     template <typename POS_SRC, typename TEX_SRC, typename COL_SRC>
396     void drawCustomVertices(const GrPaint& paint,
397                             GrPrimitiveType primitiveType,
398                             const POS_SRC& posSrc,
399                             const TEX_SRC* texCoordSrc,
400                             const COL_SRC* colorSrc);
401 
402 
403     ///////////////////////////////////////////////////////////////////////////
404     // Misc.
405 
406     /**
407      * Flags that affect flush() behavior.
408      */
409     enum FlushBits {
410         /**
411          * A client may want Gr to bind a GrRenderTarget in the 3D API so that
412          * it can be rendered to directly. However, Gr lazily sets state. Simply
413          * calling setRenderTarget() followed by flush() without flags may not
414          * bind the render target. This flag forces the context to bind the last
415          * set render target in the 3D API.
416          */
417         kForceCurrentRenderTarget_FlushBit   = 0x1,
418         /**
419          * A client may reach a point where it has partially rendered a frame
420          * through a GrContext that it knows the user will never see. This flag
421          * causes the flush to skip submission of deferred content to the 3D API
422          * during the flush.
423          */
424         kDiscard_FlushBit                    = 0x2,
425     };
426 
427     /**
428      * Call to ensure all drawing to the context has been issued to the
429      * underlying 3D API.
430      * @param flagsBitfield     flags that control the flushing behavior. See
431      *                          FlushBits.
432      */
433     void flush(int flagsBitfield = 0);
434 
435     /**
436      * Reads a rectangle of pixels from a render target.
437      * @param renderTarget  the render target to read from. NULL means the
438      *                      current render target.
439      * @param left          left edge of the rectangle to read (inclusive)
440      * @param top           top edge of the rectangle to read (inclusive)
441      * @param width         width of rectangle to read in pixels.
442      * @param height        height of rectangle to read in pixels.
443      * @param config        the pixel config of the destination buffer
444      * @param buffer        memory to read the rectangle into.
445      *
446      * @return true if the read succeeded, false if not. The read can fail
447      *              because of a unsupported pixel config or because no render
448      *              target is currently set.
449      */
450     bool readRenderTargetPixels(GrRenderTarget* target,
451                                 int left, int top, int width, int height,
452                                 GrPixelConfig config, void* buffer);
453 
454     /**
455      * Reads a rectangle of pixels from a texture.
456      * @param texture       the render target to read from.
457      * @param left          left edge of the rectangle to read (inclusive)
458      * @param top           top edge of the rectangle to read (inclusive)
459      * @param width         width of rectangle to read in pixels.
460      * @param height        height of rectangle to read in pixels.
461      * @param config        the pixel config of the destination buffer
462      * @param buffer        memory to read the rectangle into.
463      *
464      * @return true if the read succeeded, false if not. The read can fail
465      *              because of a unsupported pixel config.
466      */
467     bool readTexturePixels(GrTexture* target,
468                            int left, int top, int width, int height,
469                            GrPixelConfig config, void* buffer);
470 
471     /**
472      *  Copy the src pixels [buffer, stride, pixelconfig] into the current
473      *  render-target at the specified rectangle.
474      */
475     void writePixels(int left, int top, int width, int height,
476                      GrPixelConfig, const void* buffer, size_t stride);
477 
478     ///////////////////////////////////////////////////////////////////////////
479     // Helpers
480 
481     class AutoRenderTarget : ::GrNoncopyable {
482     public:
AutoRenderTarget(GrContext * context,GrRenderTarget * target)483         AutoRenderTarget(GrContext* context, GrRenderTarget* target) {
484             fContext = NULL;
485             fPrevTarget = context->getRenderTarget();
486             if (fPrevTarget != target) {
487                 context->setRenderTarget(target);
488                 fContext = context;
489             }
490         }
~AutoRenderTarget()491         ~AutoRenderTarget() {
492             if (fContext) {
493                 fContext->setRenderTarget(fPrevTarget);
494             }
495         }
496     private:
497         GrContext*      fContext;
498         GrRenderTarget* fPrevTarget;
499     };
500 
501 
502     ///////////////////////////////////////////////////////////////////////////
503     // Functions intended for internal use only.
getGpu()504     GrGpu* getGpu() { return fGpu; }
getFontCache()505     GrFontCache* getFontCache() { return fFontCache; }
506     GrDrawTarget* getTextTarget(const GrPaint& paint);
507     void flushText();
508     const GrIndexBuffer* getQuadIndexBuffer() const;
509     void resetStats();
510     const GrGpuStats& getStats() const;
511     void printStats() const;
512 
513 private:
514     // used to keep track of when we need to flush the draw buffer
515     enum DrawCategory {
516         kBuffered_DrawCategory,      // last draw was inserted in draw buffer
517         kUnbuffered_DrawCategory,    // last draw was not inserted in the draw buffer
518         kText_DrawCategory           // text context was last to draw
519     };
520     DrawCategory fLastDrawCategory;
521 
522     GrGpu*          fGpu;
523     GrTextureCache* fTextureCache;
524     GrFontCache*    fFontCache;
525 
526     GrPathRenderer*         fCustomPathRenderer;
527     GrDefaultPathRenderer   fDefaultPathRenderer;
528 
529     GrVertexBufferAllocPool*    fDrawBufferVBAllocPool;
530     GrIndexBufferAllocPool*     fDrawBufferIBAllocPool;
531     GrInOrderDrawBuffer*        fDrawBuffer;
532 
533     GrIndexBuffer*              fAAFillRectIndexBuffer;
534     GrIndexBuffer*              fAAStrokeRectIndexBuffer;
535 
536     GrContext(GrGpu* gpu);
537 
538     void fillAARect(GrDrawTarget* target,
539                     const GrPaint& paint,
540                     const GrRect& devRect);
541 
542     void strokeAARect(GrDrawTarget* target,
543                       const GrPaint& paint,
544                       const GrRect& devRect,
545                       const GrVec& devStrokeSize);
546 
547     inline int aaFillRectIndexCount() const;
548     GrIndexBuffer* aaFillRectIndexBuffer();
549 
550     inline int aaStrokeRectIndexCount() const;
551     GrIndexBuffer* aaStrokeRectIndexBuffer();
552 
553     void setupDrawBuffer();
554 
555     void flushDrawBuffer();
556 
557     static void SetPaint(const GrPaint& paint, GrDrawTarget* target);
558 
559     bool finalizeTextureKey(GrTextureKey*,
560                             const GrSamplerState&,
561                             bool keyless) const;
562 
563     GrDrawTarget* prepareToDraw(const GrPaint& paint, DrawCategory drawType);
564 
565     void drawClipIntoStencil();
566 
567     GrPathRenderer* getPathRenderer(const GrDrawTarget*, const GrPath&, GrPathFill);
568 
569     struct OffscreenRecord;
570 
571     bool doOffscreenAA(GrDrawTarget* target,
572                        const GrPaint& paint,
573                        bool isLines) const;
574 
575     // sets up target to draw coverage to the supersampled render target
576     bool setupOffscreenAAPass1(GrDrawTarget* target,
577                                bool requireStencil,
578                                const GrIRect& boundRect,
579                                OffscreenRecord* record);
580 
581     // sets up target to sample coverage of supersampled render target back
582     // to the main render target using stage kOffscreenStage.
583     void offscreenAAPass2(GrDrawTarget* target,
584                           const GrPaint& paint,
585                           const GrIRect& boundRect,
586                           OffscreenRecord* record);
587 
588     // computes vertex layout bits based on the paint. If paint expresses
589     // a texture for a stage, the stage coords will be bound to postitions
590     // unless hasTexCoords[s]==true in which case stage s's input coords
591     // are bound to tex coord index s. hasTexCoords == NULL is a shortcut
592     // for an array where all the values are false.
593     static int PaintStageVertexLayoutBits(
594                                     const GrPaint& paint,
595                                     const bool hasTexCoords[GrPaint::kTotalStages]);
596 
597 };
598 
599 /**
600  *  Save/restore the view-matrix in the context.
601  */
602 class GrAutoMatrix : GrNoncopyable {
603 public:
GrAutoMatrix(GrContext * ctx)604     GrAutoMatrix(GrContext* ctx) : fContext(ctx) {
605         fMatrix = ctx->getMatrix();
606     }
GrAutoMatrix(GrContext * ctx,const GrMatrix & matrix)607     GrAutoMatrix(GrContext* ctx, const GrMatrix& matrix) : fContext(ctx) {
608         fMatrix = ctx->getMatrix();
609         ctx->setMatrix(matrix);
610     }
~GrAutoMatrix()611     ~GrAutoMatrix() {
612         fContext->setMatrix(fMatrix);
613     }
614 
615 private:
616     GrContext*  fContext;
617     GrMatrix    fMatrix;
618 };
619 
620 #endif
621 
622 #include "GrContext_impl.h"
623 
624