blob: c2838b8dffec98c00fc66a270b1ffeb2f3617e6a [file] [log] [blame]
reed@google.com873cb1e2010-12-23 15:00:45 +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
reed@google.comac10a2d2010-12-22 21:39:39 +000017#ifndef GrContext_DEFINED
18#define GrContext_DEFINED
19
20#include "GrClip.h"
21#include "GrGpu.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000022#include "GrTextureCache.h"
23#include "GrInOrderDrawBuffer.h"
24#include "GrVertexBufferAllocPool.h"
bsalomon@google.com5782d712011-01-21 21:03:59 +000025#include "GrPaint.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000026
27class GrFontCache;
28class GrPathIter;
29
reed@google.comac10a2d2010-12-22 21:39:39 +000030class GrContext : public GrRefCnt {
31public:
32 /**
33 * Creates a GrContext from within a 3D context.
34 */
35 static GrContext* Create(GrGpu::Engine engine,
36 GrGpu::Platform3DContext context3D);
37
reed@google.com873cb1e2010-12-23 15:00:45 +000038 /**
39 * Helper to create a opengl-shader based context
40 */
41 static GrContext* CreateGLShaderContext();
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +000042
reed@google.comac10a2d2010-12-22 21:39:39 +000043 virtual ~GrContext();
44
45 /**
46 * The GrContext normally assumes that no outsider is setting state
47 * within the underlying 3D API's context/device/whatever. This call informs
48 * the context that the state was modified and it should resend. Shouldn't
49 * be called frequently for good performance.
50 */
51 void resetContext();
52
bsalomon@google.com5782d712011-01-21 21:03:59 +000053 ///////////////////////////////////////////////////////////////////////////
54 // Textures
55
reed@google.comac10a2d2010-12-22 21:39:39 +000056 /**
57 * Abandons all textures. Call this if you have lost the associated GPU
58 * context, and thus internal texture references/IDs are now invalid.
59 */
60 void abandonAllTextures();
61
62 /**
63 * Search for an entry with the same Key. If found, "lock" it and return it.
64 * If not found, return null.
65 */
66 GrTextureEntry* findAndLockTexture(GrTextureKey*,
67 const GrSamplerState&);
68
69
70 /**
71 * Create a new entry, based on the specified key and texture, and return
72 * its "locked" entry.
73 *
74 * Ownership of the texture is transferred to the Entry, which will unref()
75 * it when we are purged or deleted.
76 */
77 GrTextureEntry* createAndLockTexture(GrTextureKey* key,
78 const GrSamplerState&,
79 const GrGpu::TextureDesc&,
80 void* srcData, size_t rowBytes);
81
82 /**
83 * When done with an entry, call unlockTexture(entry) on it, which returns
84 * it to the cache, where it may be purged.
85 */
86 void unlockTexture(GrTextureEntry* entry);
87
88 /**
89 * Removes an texture from the cache. This prevents the texture from
90 * being found by a subsequent findAndLockTexture() until it is
91 * reattached. The entry still counts against the cache's budget and should
92 * be reattached when exclusive access is no longer needed.
93 */
94 void detachCachedTexture(GrTextureEntry*);
95
96 /**
97 * Reattaches a texture to the cache and unlocks it. Allows it to be found
98 * by a subsequent findAndLock or be purged (provided its lock count is
99 * now 0.)
100 */
101 void reattachAndUnlockCachedTexture(GrTextureEntry*);
102
103 /**
104 * Creates a texture that is outside the cache. Does not count against
105 * cache's budget.
106 */
107 GrTexture* createUncachedTexture(const GrGpu::TextureDesc&,
108 void* srcData,
109 size_t rowBytes);
110
111 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +0000112 * Returns true if the specified use of an indexed texture is supported.
113 */
114 bool supportsIndex8PixelConfig(const GrSamplerState&, int width, int height);
115
116 /**
117 * Return the current texture cache limits.
118 *
119 * @param maxTextures If non-null, returns maximum number of textures that
120 * can be held in the cache.
121 * @param maxTextureBytes If non-null, returns maximum number of bytes of
122 * texture memory that can be held in the cache.
123 */
124 void getTextureCacheLimits(int* maxTextures, size_t* maxTextureBytes) const;
125
126 /**
127 * Specify the texture cache limits. If the current cache exceeds either
128 * of these, it will be purged (LRU) to keep the cache within these limits.
129 *
130 * @param maxTextures The maximum number of textures that can be held in
131 * the cache.
132 * @param maxTextureBytes The maximum number of bytes of texture memory
133 * that can be held in the cache.
134 */
135 void setTextureCacheLimits(int maxTextures, size_t maxTextureBytes);
136
137 ///////////////////////////////////////////////////////////////////////////
138 // Render targets
139
140 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000141 * Wraps an externally-created rendertarget in a GrRenderTarget.
142 * e.g. in GL platforamRenderTarget is an FBO id.
143 */
144 GrRenderTarget* createPlatformRenderTarget(intptr_t platformRenderTarget,
145 int width, int height);
146
147 /**
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000148 * Reads the current target object (e.g. FBO or IDirect3DSurface9*) and
149 * viewport state from the underlying 3D API and wraps it in a
150 * GrRenderTarget. The GrRenderTarget will not attempt to delete/destroy the
151 * underlying object in its destructor and it is up to caller to guarantee
152 * that it remains valid while the GrRenderTarget is used.
153 *
154 * @return the newly created GrRenderTarget
155 */
156 GrRenderTarget* createRenderTargetFrom3DApiState() {
157 return fGpu->createRenderTargetFrom3DApiState();
158 }
159
160 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +0000161 * Sets the render target.
162 * @param target the render target to set. (should not be NULL.)
reed@google.comac10a2d2010-12-22 21:39:39 +0000163 */
reed@google.comac10a2d2010-12-22 21:39:39 +0000164 void setRenderTarget(GrRenderTarget* target);
reed@google.comac10a2d2010-12-22 21:39:39 +0000165
bsalomon@google.com5782d712011-01-21 21:03:59 +0000166 /**
167 * Gets the current render target.
168 * @return the currently bound render target. Should never be NULL.
169 */
170 const GrRenderTarget* getRenderTarget() const;
171 GrRenderTarget* getRenderTarget();
reed@google.comac10a2d2010-12-22 21:39:39 +0000172
bsalomon@google.com5782d712011-01-21 21:03:59 +0000173 ///////////////////////////////////////////////////////////////////////////
174 // Matrix state
reed@google.comac10a2d2010-12-22 21:39:39 +0000175
176 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +0000177 * Gets the current transformation matrix.
178 * @return the current matrix.
179 */
180 const GrMatrix& getMatrix() const;
181
182 /**
183 * Sets the transformation matrix.
184 * @param m the matrix to set.
185 */
186 void setMatrix(const GrMatrix& m);
187
188 /**
189 * Concats the current matrix. The passed matrix is applied before the
190 * current matrix.
191 * @param m the matrix to concat.
192 */
193 void concatMatrix(const GrMatrix& m) const;
194
195
196 ///////////////////////////////////////////////////////////////////////////
197 // Clip state
198 /**
199 * Gets the current clip.
200 * @return the current clip.
201 */
202 const GrClip& getClip() const { return fGpu->getClip(); }
203
204 /**
205 * Sets the clip.
206 * @param clip the clip to set.
207 */
208 void setClip(const GrClip& clip);
209
210 /**
211 * Convenience method for setting the clip to a rect.
212 * @param rect the rect to set as the new clip.
213 */
214 void setClip(const GrIRect& rect);
215
216 ///////////////////////////////////////////////////////////////////////////
217 // Draws
218
219 /**
220 * Erase the entire render target, ignoring any clips
reed@google.comac10a2d2010-12-22 21:39:39 +0000221 */
222 void eraseColor(GrColor color);
223
224 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +0000225 * Draw everywhere (respecting the clip) with the paint.
reed@google.comac10a2d2010-12-22 21:39:39 +0000226 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000227 void drawPaint(const GrPaint& paint);
reed@google.comac10a2d2010-12-22 21:39:39 +0000228
229 /**
bsalomon@google.com5782d712011-01-21 21:03:59 +0000230 * Draw the rect using a paint.
231 * If strokeWidth < 0, then the rect is filled, else the rect is mitered
232 * stroked based on strokeWidth. If strokeWidth == 0, then the stroke is
233 * always a single pixel thick.
234 * The rects coords are used to access the paint (through texture matrix)
reed@google.comac10a2d2010-12-22 21:39:39 +0000235 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000236 void drawRect(const GrPaint& paint, const GrRect&, GrScalar strokeWidth = -1);
reed@google.comac10a2d2010-12-22 21:39:39 +0000237
bsalomon@google.com5782d712011-01-21 21:03:59 +0000238 /**
239 * Maps a rect of paint coordinates onto the a rect of destination
240 * coordinates. The srcRect is transformed by the paint's matrix and the
241 * dstRect is transformed by the context's matrix.
242 */
243 void drawRectToRect(const GrPaint& paint,
244 const GrRect& dstRect,
245 const GrRect& srcRect);
reed@google.comac10a2d2010-12-22 21:39:39 +0000246
247 /**
248 * Path filling rules
249 */
250 enum PathFills {
251 kWinding_PathFill,
252 kEvenOdd_PathFill,
253 kInverseWinding_PathFill,
254 kInverseEvenOdd_PathFill,
255 kHairLine_PathFill,
256
257 kPathFillCount
258 };
259
260 /**
261 * Tessellates and draws a path.
262 *
bsalomon@google.com5782d712011-01-21 21:03:59 +0000263 * @param paint describes how to color pixels.
reed@google.comac10a2d2010-12-22 21:39:39 +0000264 * @param path the path to draw
bsalomon@google.com5782d712011-01-21 21:03:59 +0000265 * @param fill the path filling rule to use.
266 * @param translate optional additional translation applied to the
267 * path.
reed@google.comac10a2d2010-12-22 21:39:39 +0000268 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000269 void drawPath(const GrPaint& paint,
270 GrPathIter* path,
reed@google.comac10a2d2010-12-22 21:39:39 +0000271 PathFills fill,
reed@google.comac10a2d2010-12-22 21:39:39 +0000272 const GrPoint* translate = NULL);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000273 /**
274 * Draws vertices with a paint.
275 *
276 * @param paint describes how to color pixels.
277 * @param primitiveType primitives type to draw.
278 * @param vertexCount number of vertices.
279 * @param positions array of vertex positions, required.
280 * @param texCoords optional array of texture coordinates used
281 * to access the paint.
282 * @param colors optional array of per-vertex colors, supercedes
283 * the paint's color field.
284 * @param indices optional array of indices. If NULL vertices
285 * are drawn non-indexed.
286 * @param indexCount if indices is non-null then this is the
287 * number of indices.
288 */
289 void drawVertices(const GrPaint& paint,
290 GrDrawTarget::PrimitiveType primitiveType,
291 int vertexCount,
292 const GrPoint positions[],
293 const GrPoint texs[],
294 const GrColor colors[],
295 const uint16_t indices[],
296 int indexCount);
297
298 /**
299 * Similar to drawVertices but caller provides objects that convert to Gr
300 * types. The count of vertices is given by posSrc.
301 *
302 * @param paint describes how to color pixels.
303 * @param primitiveType primitives type to draw.
304 * @param posSrc Source of vertex positions. Must implement
305 * int count() const;
306 * void writeValue(int i, GrPoint* point) const;
307 * count returns the total number of vertices and
308 * writeValue writes a vertex position to point.
309 * @param texSrc optional, pass NULL to not use explicit tex
310 * coords. If present provides tex coords with
311 * method:
312 * void writeValue(int i, GrPoint* point) const;
313 * @param texSrc optional, pass NULL to not use per-vertex colors
314 * If present provides colors with method:
315 * void writeValue(int i, GrColor* point) const;
316 * @param indices optional, pass NULL for non-indexed drawing. If
317 * present supplies indices for indexed drawing
318 * with following methods:
319 * int count() const;
320 * void writeValue(int i, uint16_t* point) const;
321 * count returns the number of indices and
322 * writeValue supplies each index.
323 */
324 template <typename POS_SRC,
325 typename TEX_SRC,
326 typename COL_SRC,
327 typename IDX_SRC>
328 void drawCustomVertices(const GrPaint& paint,
329 GrDrawTarget::PrimitiveType primitiveType,
330 const POS_SRC& posSrc,
331 const TEX_SRC* texCoordSrc,
332 const COL_SRC* colorSrc,
333 const IDX_SRC* idxSrc);
334 /**
335 * To avoid the problem of having to create a typename for NULL parameters,
336 * these reduced versions of drawCustomVertices are provided.
337 */
338 template <typename POS_SRC>
339 void drawCustomVertices(const GrPaint& paint,
340 GrDrawTarget::PrimitiveType primitiveType,
341 const POS_SRC& posSrc);
342 template <typename POS_SRC, typename TEX_SRC>
343 void drawCustomVertices(const GrPaint& paint,
344 GrDrawTarget::PrimitiveType primitiveType,
345 const POS_SRC& posSrc,
346 const TEX_SRC* texCoordSrc);
347 template <typename POS_SRC, typename TEX_SRC, typename COL_SRC>
348 void drawCustomVertices(const GrPaint& paint,
349 GrDrawTarget::PrimitiveType primitiveType,
350 const POS_SRC& posSrc,
351 const TEX_SRC* texCoordSrc,
352 const COL_SRC* colorSrc);
353
354
355 ///////////////////////////////////////////////////////////////////////////
356 // Misc.
reed@google.comac10a2d2010-12-22 21:39:39 +0000357
358 /**
359 * Call to ensure all drawing to the context has been issued to the
360 * underlying 3D API.
361 * if flushRenderTarget is true then after the call the last
362 * rendertarget set will be current in the underlying 3D API, otherwise
363 * it may not be. It is useful to set if the caller plans to use the 3D
364 * context outside of Ganesh to render into the current RT.
365 */
366 void flush(bool flushRenderTarget);
367
368 /**
369 * Return true on success, i.e. if we could copy the specified range of
370 * pixels from the current render-target into the buffer, converting into
371 * the specified pixel-config.
372 */
373 bool readPixels(int left, int top, int width, int height,
374 GrTexture::PixelConfig, void* buffer);
375
376 /**
377 * Copy the src pixels [buffer, stride, pixelconfig] into the current
378 * render-target at the specified rectangle.
379 */
380 void writePixels(int left, int top, int width, int height,
381 GrTexture::PixelConfig, const void* buffer, size_t stride);
382
reed@google.comac10a2d2010-12-22 21:39:39 +0000383
bsalomon@google.com5782d712011-01-21 21:03:59 +0000384 ///////////////////////////////////////////////////////////////////////////
385 // Statistics
reed@google.comac10a2d2010-12-22 21:39:39 +0000386
387 void resetStats();
388
389 const GrGpu::Stats& getStats() const;
390
391 void printStats() const;
392
bsalomon@google.com5782d712011-01-21 21:03:59 +0000393 ///////////////////////////////////////////////////////////////////////////
394 // Helpers
395
reed@google.comac10a2d2010-12-22 21:39:39 +0000396 class AutoRenderTarget : ::GrNoncopyable {
397 public:
398 AutoRenderTarget(GrContext* context, GrRenderTarget* target) {
399 fContext = NULL;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000400 fPrevTarget = context->getRenderTarget();
reed@google.comac10a2d2010-12-22 21:39:39 +0000401 if (fPrevTarget != target) {
402 context->setRenderTarget(target);
403 fContext = context;
404 }
405 }
406 ~AutoRenderTarget() {
407 if (fContext) {
408 fContext->setRenderTarget(fPrevTarget);
409 }
410 }
411 private:
412 GrContext* fContext;
413 GrRenderTarget* fPrevTarget;
414 };
415
bsalomon@google.com5782d712011-01-21 21:03:59 +0000416
reed@google.com01804b42011-01-18 21:50:41 +0000417 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com5782d712011-01-21 21:03:59 +0000418 // Functions intended for internal use only.
reed@google.comac10a2d2010-12-22 21:39:39 +0000419 GrGpu* getGpu() { return fGpu; }
420 GrFontCache* getFontCache() { return fFontCache; }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000421 GrDrawTarget* getTextTarget(const GrPaint& paint);
reed@google.comac10a2d2010-12-22 21:39:39 +0000422 void flushText();
423
424 const GrIndexBuffer* quadIndexBuffer() const;
425 int maxQuadsInIndexBuffer() const;
426
427private:
428 GrGpu* fGpu;
429 GrTextureCache* fTextureCache;
430 GrFontCache* fFontCache;
431
432 GrVertexBufferAllocPool fVBAllocPool;
433 GrInOrderDrawBuffer fTextDrawBuffer;
434
435 GrContext(GrGpu* gpu);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000436
437 static void SetPaint(const GrPaint& paint, GrDrawTarget* target);
438
reed@google.comac10a2d2010-12-22 21:39:39 +0000439 bool finalizeTextureKey(GrTextureKey*, const GrSamplerState&) const;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000440 void prepareToDraw(const GrPaint& paint);
reed@google.comac10a2d2010-12-22 21:39:39 +0000441
442 void drawClipIntoStencil();
443};
444
445/**
446 * Save/restore the view-matrix in the context.
447 */
bsalomon@google.com5782d712011-01-21 21:03:59 +0000448class GrAutoMatrix : GrNoncopyable {
reed@google.comac10a2d2010-12-22 21:39:39 +0000449public:
bsalomon@google.com5782d712011-01-21 21:03:59 +0000450 GrAutoMatrix(GrContext* ctx) : fContext(ctx) {
451 fMatrix = ctx->getMatrix();
reed@google.comac10a2d2010-12-22 21:39:39 +0000452 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000453 GrAutoMatrix(GrContext* ctx, const GrMatrix& matrix) : fContext(ctx) {
454 fMatrix = ctx->getMatrix();
455 ctx->setMatrix(matrix);
reed@google.comac10a2d2010-12-22 21:39:39 +0000456 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000457 ~GrAutoMatrix() {
458 fContext->setMatrix(fMatrix);
reed@google.comac10a2d2010-12-22 21:39:39 +0000459 }
460
461private:
462 GrContext* fContext;
463 GrMatrix fMatrix;
464};
465
466#endif
reed@google.com873cb1e2010-12-23 15:00:45 +0000467
bsalomon@google.com5782d712011-01-21 21:03:59 +0000468#include "GrContext_impl.h"