blob: 1f90603f5da8cd0b1e1bb65dd136baec8ba8e869 [file] [log] [blame]
bsalomon@google.com27847de2011-02-22 20:59:41 +00001/*
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 "GrGpu.h"
22#include "GrTextureCache.h"
23#include "GrPaint.h"
24
25class GrFontCache;
26class GrPathIter;
27class GrVertexBufferAllocPool;
28class GrIndexBufferAllocPool;
29class GrInOrderDrawBuffer;
30class GrPathRenderer;
31
32class GrContext : public GrRefCnt {
33public:
34 /**
35 * Creates a GrContext from within a 3D context.
36 */
37 static GrContext* Create(GrGpu::Engine engine,
38 GrGpu::Platform3DContext 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 // Textures
57
58 /**
59 * Abandons all textures. Call this if you have lost the associated GPU
60 * context, and thus internal texture references/IDs are now invalid.
61 */
62 void abandonAllTextures();
63
64 /**
65 * Search for an entry with the same Key. If found, "lock" it and return it.
66 * If not found, return null.
67 */
68 GrTextureEntry* findAndLockTexture(GrTextureKey*,
69 const GrSamplerState&);
70
71
72 /**
73 * Create a new entry, based on the specified key and texture, and return
74 * its "locked" entry.
75 *
76 * Ownership of the texture is transferred to the Entry, which will unref()
77 * it when we are purged or deleted.
78 */
79 GrTextureEntry* createAndLockTexture(GrTextureKey* key,
80 const GrSamplerState&,
81 const GrGpu::TextureDesc&,
82 void* srcData, size_t rowBytes);
83
84 /**
85 * When done with an entry, call unlockTexture(entry) on it, which returns
86 * it to the cache, where it may be purged.
87 */
88 void unlockTexture(GrTextureEntry* entry);
89
90 /**
91 * Removes an texture from the cache. This prevents the texture from
92 * being found by a subsequent findAndLockTexture() until it is
93 * reattached. The entry still counts against the cache's budget and should
94 * be reattached when exclusive access is no longer needed.
95 */
96 void detachCachedTexture(GrTextureEntry*);
97
98 /**
99 * Reattaches a texture to the cache and unlocks it. Allows it to be found
100 * by a subsequent findAndLock or be purged (provided its lock count is
101 * now 0.)
102 */
103 void reattachAndUnlockCachedTexture(GrTextureEntry*);
104
105 /**
106 * Creates a texture that is outside the cache. Does not count against
107 * cache's budget.
108 */
109 GrTexture* createUncachedTexture(const GrGpu::TextureDesc&,
110 void* srcData,
111 size_t rowBytes);
112
113 /**
114 * Returns true if the specified use of an indexed texture is supported.
115 */
116 bool supportsIndex8PixelConfig(const GrSamplerState&, int width, int height);
117
118 /**
119 * Return the current texture cache limits.
120 *
121 * @param maxTextures If non-null, returns maximum number of textures that
122 * can be held in the cache.
123 * @param maxTextureBytes If non-null, returns maximum number of bytes of
124 * texture memory that can be held in the cache.
125 */
126 void getTextureCacheLimits(int* maxTextures, size_t* maxTextureBytes) const;
127
128 /**
129 * Specify the texture cache limits. If the current cache exceeds either
130 * of these, it will be purged (LRU) to keep the cache within these limits.
131 *
132 * @param maxTextures The maximum number of textures that can be held in
133 * the cache.
134 * @param maxTextureBytes The maximum number of bytes of texture memory
135 * that can be held in the cache.
136 */
137 void setTextureCacheLimits(int maxTextures, size_t maxTextureBytes);
138
139 /**
140 * Return the max width or height of a texture supported by the current gpu
141 */
142 int getMaxTextureDimension();
143
144 ///////////////////////////////////////////////////////////////////////////
145 // Render targets
146
147 /**
148 * Wraps an externally-created rendertarget in a GrRenderTarget.
149 * @param platformRenderTarget 3D API-specific render target identifier
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000150 * e.g. in GL platforamRenderTarget is an FBO
bsalomon@google.com27847de2011-02-22 20:59:41 +0000151 * id.
152 * @param stencilBits the number of stencil bits that the render
153 * target has.
154 * @param width width of the render target.
155 * @param height height of the render target.
156 */
157 GrRenderTarget* createPlatformRenderTarget(intptr_t platformRenderTarget,
158 int stencilBits,
159 int width, int height);
160
161 /**
162 * Reads the current target object (e.g. FBO or IDirect3DSurface9*) and
163 * viewport state from the underlying 3D API and wraps it in a
164 * GrRenderTarget. The GrRenderTarget will not attempt to delete/destroy the
165 * underlying object in its destructor and it is up to caller to guarantee
166 * that it remains valid while the GrRenderTarget is used.
167 *
168 * @return the newly created GrRenderTarget
169 */
170 GrRenderTarget* createRenderTargetFrom3DApiState() {
171 return fGpu->createRenderTargetFrom3DApiState();
172 }
173
174 /**
175 * Sets the render target.
176 * @param target the render target to set. (should not be NULL.)
177 */
178 void setRenderTarget(GrRenderTarget* target);
179
180 /**
181 * Gets the current render target.
182 * @return the currently bound render target. Should never be NULL.
183 */
184 const GrRenderTarget* getRenderTarget() const;
185 GrRenderTarget* getRenderTarget();
186
187 ///////////////////////////////////////////////////////////////////////////
188 // Matrix state
189
190 /**
191 * Gets the current transformation matrix.
192 * @return the current matrix.
193 */
194 const GrMatrix& getMatrix() const;
195
196 /**
197 * Sets the transformation matrix.
198 * @param m the matrix to set.
199 */
200 void setMatrix(const GrMatrix& m);
201
202 /**
203 * Concats the current matrix. The passed matrix is applied before the
204 * current matrix.
205 * @param m the matrix to concat.
206 */
207 void concatMatrix(const GrMatrix& m) const;
208
209
210 ///////////////////////////////////////////////////////////////////////////
211 // Clip state
212 /**
213 * Gets the current clip.
214 * @return the current clip.
215 */
216 const GrClip& getClip() const { return fGpu->getClip(); }
217
218 /**
219 * Sets the clip.
220 * @param clip the clip to set.
221 */
222 void setClip(const GrClip& clip);
223
224 /**
225 * Convenience method for setting the clip to a rect.
226 * @param rect the rect to set as the new clip.
227 */
228 void setClip(const GrIRect& rect);
229
230 ///////////////////////////////////////////////////////////////////////////
231 // Draws
232
233 /**
234 * Erase the entire render target, ignoring any clips
235 */
236 void eraseColor(GrColor color);
237
238 /**
239 * Draw everywhere (respecting the clip) with the paint.
240 */
241 void drawPaint(const GrPaint& paint);
242
243 /**
244 * Draw the rect using a paint.
245 * @param paint describes how to color pixels.
246 * @param strokeWidth If strokeWidth < 0, then the rect is filled, else
247 * the rect is mitered stroked based on strokeWidth. If
248 * strokeWidth == 0, then the stroke is always a single
249 * pixel thick.
250 * @param matrix Optional matrix applied to the rect. Applied before
251 * context's matrix or the paint's matrix.
252 * The rects coords are used to access the paint (through texture matrix)
253 */
254 void drawRect(const GrPaint& paint,
255 const GrRect&,
256 GrScalar strokeWidth = -1,
257 const GrMatrix* matrix = NULL);
258
259 /**
260 * Maps a rect of paint coordinates onto the a rect of destination
261 * coordinates. Each rect can optionally be transformed. The srcRect
262 * is stretched over the dstRect. The dstRect is transformed by the
263 * context's matrix and the srcRect is transformed by the paint's matrix.
264 * Additional optional matrices can be provided by parameters.
265 *
266 * @param paint describes how to color pixels.
267 * @param dstRect the destination rect to draw.
268 * @param srcRect rect of paint coordinates to be mapped onto dstRect
269 * @param dstMatrix Optional matrix to transform dstRect. Applied before
270 * context's matrix.
271 * @param srcMatrix Optional matrix to transform srcRect Applied before
272 * paint's matrix.
273 */
274 void drawRectToRect(const GrPaint& paint,
275 const GrRect& dstRect,
276 const GrRect& srcRect,
277 const GrMatrix* dstMatrix = NULL,
278 const GrMatrix* srcMatrix = NULL);
279
280 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000281 * Draws a path.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000282 *
283 * @param paint describes how to color pixels.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000284 * @param pathIter the path to draw
bsalomon@google.com27847de2011-02-22 20:59:41 +0000285 * @param fill the path filling rule to use.
286 * @param translate optional additional translation applied to the
287 * path.
288 */
289 void drawPath(const GrPaint& paint,
bsalomon@google.comd302f142011-03-03 13:54:13 +0000290 GrPathIter* pathIter,
291 GrPathFill fill,
292 const GrPoint* translate = NULL);
293 /**
294 * Helper version of drawPath that takes a GrPath
295 */
296 void drawPath(const GrPaint& paint,
297 const GrPath& path,
bsalomon@google.com27847de2011-02-22 20:59:41 +0000298 GrPathFill fill,
299 const GrPoint* translate = NULL);
300 /**
301 * Draws vertices with a paint.
302 *
303 * @param paint describes how to color pixels.
304 * @param primitiveType primitives type to draw.
305 * @param vertexCount number of vertices.
306 * @param positions array of vertex positions, required.
307 * @param texCoords optional array of texture coordinates used
308 * to access the paint.
309 * @param colors optional array of per-vertex colors, supercedes
310 * the paint's color field.
311 * @param indices optional array of indices. If NULL vertices
312 * are drawn non-indexed.
313 * @param indexCount if indices is non-null then this is the
314 * number of indices.
315 */
316 void drawVertices(const GrPaint& paint,
317 GrPrimitiveType primitiveType,
318 int vertexCount,
319 const GrPoint positions[],
320 const GrPoint texs[],
321 const GrColor colors[],
322 const uint16_t indices[],
323 int indexCount);
324
325 /**
326 * Similar to drawVertices but caller provides objects that convert to Gr
327 * types. The count of vertices is given by posSrc.
328 *
329 * @param paint describes how to color pixels.
330 * @param primitiveType primitives type to draw.
331 * @param posSrc Source of vertex positions. Must implement
332 * int count() const;
333 * void writeValue(int i, GrPoint* point) const;
334 * count returns the total number of vertices and
335 * writeValue writes a vertex position to point.
336 * @param texSrc optional, pass NULL to not use explicit tex
337 * coords. If present provides tex coords with
338 * method:
339 * void writeValue(int i, GrPoint* point) const;
340 * @param texSrc optional, pass NULL to not use per-vertex colors
341 * If present provides colors with method:
342 * void writeValue(int i, GrColor* point) const;
343 * @param indices optional, pass NULL for non-indexed drawing. If
344 * present supplies indices for indexed drawing
345 * with following methods:
346 * int count() const;
347 * void writeValue(int i, uint16_t* point) const;
348 * count returns the number of indices and
349 * writeValue supplies each index.
350 */
351 template <typename POS_SRC,
352 typename TEX_SRC,
353 typename COL_SRC,
354 typename IDX_SRC>
355 void drawCustomVertices(const GrPaint& paint,
356 GrPrimitiveType primitiveType,
357 const POS_SRC& posSrc,
358 const TEX_SRC* texCoordSrc,
359 const COL_SRC* colorSrc,
360 const IDX_SRC* idxSrc);
361 /**
362 * To avoid the problem of having to create a typename for NULL parameters,
363 * these reduced versions of drawCustomVertices are provided.
364 */
365 template <typename POS_SRC>
366 void drawCustomVertices(const GrPaint& paint,
367 GrPrimitiveType primitiveType,
368 const POS_SRC& posSrc);
369 template <typename POS_SRC, typename TEX_SRC>
370 void drawCustomVertices(const GrPaint& paint,
371 GrPrimitiveType primitiveType,
372 const POS_SRC& posSrc,
373 const TEX_SRC* texCoordSrc);
374 template <typename POS_SRC, typename TEX_SRC, typename COL_SRC>
375 void drawCustomVertices(const GrPaint& paint,
376 GrPrimitiveType primitiveType,
377 const POS_SRC& posSrc,
378 const TEX_SRC* texCoordSrc,
379 const COL_SRC* colorSrc);
380
381
382 ///////////////////////////////////////////////////////////////////////////
383 // Misc.
384
385 /**
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000386 * Flags that affect flush() behavior.
387 */
388 enum FlushBits {
389 /**
390 * A client may want Gr to bind a GrRenderTarget in the 3D API so that
391 * it can be rendered to directly. However, Gr lazily sets state. Simply
392 * calling setRenderTarget() followed by flush() without flags may not
393 * bind the render target. This flag forces the context to bind the last
394 * set render target in the 3D API.
395 */
396 kForceCurrentRenderTarget_FlushBit = 0x1,
397 /**
398 * A client may reach a point where it has partially rendered a frame
399 * through a GrContext that it knows the user will never see. This flag
400 * causes the flush to skip submission of deferred content to the 3D API
401 * during the flush.
402 */
403 kDiscard_FlushBit = 0x2,
404 };
405
406 /**
bsalomon@google.com27847de2011-02-22 20:59:41 +0000407 * Call to ensure all drawing to the context has been issued to the
408 * underlying 3D API.
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000409 * @param flagsBitfield flags that control the flushing behavior. See
410 * FlushBits.
bsalomon@google.com27847de2011-02-22 20:59:41 +0000411 */
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000412 void flush(int flagsBitfield);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000413 /**
414 * Return true on success, i.e. if we could copy the specified range of
415 * pixels from the current render-target into the buffer, converting into
416 * the specified pixel-config.
417 */
418 bool readPixels(int left, int top, int width, int height,
419 GrTexture::PixelConfig, void* buffer);
420
421 /**
422 * Copy the src pixels [buffer, stride, pixelconfig] into the current
423 * render-target at the specified rectangle.
424 */
425 void writePixels(int left, int top, int width, int height,
426 GrTexture::PixelConfig, const void* buffer, size_t stride);
427
428
429 ///////////////////////////////////////////////////////////////////////////
430 // Statistics
431
432 void resetStats();
433
434 const GrGpu::Stats& getStats() const;
435
436 void printStats() const;
437
438 ///////////////////////////////////////////////////////////////////////////
439 // Helpers
440
441 class AutoRenderTarget : ::GrNoncopyable {
442 public:
443 AutoRenderTarget(GrContext* context, GrRenderTarget* target) {
444 fContext = NULL;
445 fPrevTarget = context->getRenderTarget();
446 if (fPrevTarget != target) {
447 context->setRenderTarget(target);
448 fContext = context;
449 }
450 }
451 ~AutoRenderTarget() {
452 if (fContext) {
453 fContext->setRenderTarget(fPrevTarget);
454 }
455 }
456 private:
457 GrContext* fContext;
458 GrRenderTarget* fPrevTarget;
459 };
460
461
462 ///////////////////////////////////////////////////////////////////////////
463 // Functions intended for internal use only.
464 GrGpu* getGpu() { return fGpu; }
465 GrFontCache* getFontCache() { return fFontCache; }
466 GrDrawTarget* getTextTarget(const GrPaint& paint);
467 void flushText();
468 const GrIndexBuffer* getQuadIndexBuffer() const;
469
470private:
471 // used to keep track of when we need to flush the draw buffer
472 enum DrawCategory {
473 kBuffered_DrawCategory, // last draw was inserted in draw buffer
474 kUnbuffered_DrawCategory, // last draw was not inserted in the draw buffer
475 kText_DrawCategory // text context was last to draw
476 };
477 DrawCategory fLastDrawCategory;
478
479 GrGpu* fGpu;
480 GrTextureCache* fTextureCache;
481 GrFontCache* fFontCache;
482 GrPathRenderer* fPathRenderer;
483
484 GrVertexBufferAllocPool* fDrawBufferVBAllocPool;
485 GrIndexBufferAllocPool* fDrawBufferIBAllocPool;
486 GrInOrderDrawBuffer* fDrawBuffer;
487
488 GrContext(GrGpu* gpu);
489 void flushDrawBuffer();
490
491 static void SetPaint(const GrPaint& paint, GrDrawTarget* target);
492
493 bool finalizeTextureKey(GrTextureKey*, const GrSamplerState&) const;
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000494
bsalomon@google.com27847de2011-02-22 20:59:41 +0000495 GrDrawTarget* prepareToDraw(const GrPaint& paint, DrawCategory drawType);
496
497 void drawClipIntoStencil();
498};
499
500/**
501 * Save/restore the view-matrix in the context.
502 */
503class GrAutoMatrix : GrNoncopyable {
504public:
505 GrAutoMatrix(GrContext* ctx) : fContext(ctx) {
506 fMatrix = ctx->getMatrix();
507 }
508 GrAutoMatrix(GrContext* ctx, const GrMatrix& matrix) : fContext(ctx) {
509 fMatrix = ctx->getMatrix();
510 ctx->setMatrix(matrix);
511 }
512 ~GrAutoMatrix() {
513 fContext->setMatrix(fMatrix);
514 }
515
516private:
517 GrContext* fContext;
518 GrMatrix fMatrix;
519};
520
521#endif
522
523#include "GrContext_impl.h"