blob: 5a88ef481fa493929a81f27c8534ea6686cfc2a2 [file] [log] [blame]
reed@google.comac10a2d2010-12-22 21:39:39 +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
18#ifndef GrGpu_DEFINED
19#define GrGpu_DEFINED
20
21#include "GrRect.h"
22#include "GrRefCnt.h"
23#include "GrDrawTarget.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000024#include "GrTexture.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000025
bsalomon@google.com1c13c962011-02-14 16:51:21 +000026class GrVertexBufferAllocPool;
27class GrIndexBufferAllocPool;
bsalomon@google.comd302f142011-03-03 13:54:13 +000028class GrPathRenderer;
reed@google.comac10a2d2010-12-22 21:39:39 +000029
30class GrGpu : public GrDrawTarget {
31
32public:
33 /**
34 * Possible 3D APIs that may be used by Ganesh.
35 */
36 enum Engine {
37 kOpenGL_Shaders_Engine,
38 kOpenGL_Fixed_Engine,
39 kDirect3D9_Engine
40 };
41
42 /**
43 * Platform specific 3D context.
44 * For
45 * kOpenGL_Shaders_Engine use NULL
46 * kOpenGL_Fixed_Engine use NULL
47 * kDirect3D9_Engine use an IDirect3DDevice9*
48 */
49 typedef void* Platform3DContext;
50
51 /**
52 * Create an instance of GrGpu that matches the specified Engine backend.
53 * If the requested engine is not supported (at compile-time or run-time)
54 * this returns NULL.
55 */
56 static GrGpu* Create(Engine, Platform3DContext context3D);
57
58 /**
reed@google.comac10a2d2010-12-22 21:39:39 +000059 * Used to control the level of antialiasing available for a rendertarget.
60 * Anti-alias quality levels depend on the underlying API/GPU capabilities.
61 */
62 enum AALevels {
63 kNone_AALevel, //<! No antialiasing available.
64 kLow_AALevel, //<! Low quality antialiased rendering. Actual
65 // interpretation is platform-dependent.
66 kMed_AALevel, //<! Medium quality antialiased rendering. Actual
67 // interpretation is platform-dependent.
68 kHigh_AALevel, //<! High quality antialiased rendering. Actual
69 // interpretation is platform-dependent.
70 };
71
72
73 /**
74 * Optional bitfield flags that can be passed to createTexture.
75 */
76 enum TextureFlags {
77 kRenderTarget_TextureFlag = 0x1, //<! Creates a texture that can be
78 // rendered to by calling
79 // GrGpu::setRenderTarget() with
80 // GrTexture::asRenderTarget().
81 kNoPathRendering_TextureFlag = 0x2, //<! If the texture is used as a
82 // rendertarget but paths will not
83 // be rendered to it.
84 kDynamicUpdate_TextureFlag = 0x4 //!< Hint that the CPU may modify
85 // this texture after creation
86 };
87
88 enum {
89 /**
90 * For Index8 pixel config, the colortable must be 256 entries
91 */
92 kColorTableSize = 256 * sizeof(GrColor)
93 };
94 /**
95 * Describes a texture to be created.
96 */
97 struct TextureDesc {
98 uint32_t fFlags; //!< bitfield of TextureFlags
99 GrGpu::AALevels fAALevel;//!< The level of antialiasing available
100 // for a rendertarget texture. Only
101 // flags contains
102 // kRenderTarget_TextureFlag.
103 uint32_t fWidth; //!< Width of the texture
104 uint32_t fHeight; //!< Height of the texture
105 GrTexture::PixelConfig fFormat; //!< Format of source data of the
106 // texture. Not guaraunteed to be the
107 // same as internal format used by
108 // 3D API.
109 };
110
111 /**
112 * Gpu usage statistics.
113 */
114 struct Stats {
115 uint32_t fVertexCnt; //<! Number of vertices drawn
116 uint32_t fIndexCnt; //<! Number of indices drawn
117 uint32_t fDrawCnt; //<! Number of draws
118
119 uint32_t fProgChngCnt;//<! Number of program changes (N/A for fixed)
120
121 /*
122 * Number of times the texture is set in 3D API
123 */
124 uint32_t fTextureChngCnt;
125 /*
126 * Number of times the render target is set in 3D API
127 */
128 uint32_t fRenderTargetChngCnt;
129 /*
130 * Number of textures created (includes textures that are rendertargets).
131 */
132 uint32_t fTextureCreateCnt;
133 /*
134 * Number of rendertargets created.
135 */
136 uint32_t fRenderTargetCreateCnt;
137 };
138
139 ////////////////////////////////////////////////////////////////////////////
140
141 GrGpu();
142 virtual ~GrGpu();
143
144 /**
145 * The GrGpu object normally assumes that no outsider is setting state
146 * within the underlying 3D API's context/device/whatever. This call informs
147 * the GrGpu that the state was modified and it should resend. Shouldn't
148 * be called frequently for good performance.
149 */
150 virtual void resetContext();
151
152 void unimpl(const char[]);
153
154 /**
bsalomon@google.com0748f212011-02-01 22:56:16 +0000155 * Creates a texture object. If desc width or height is not a power of
156 * two but underlying API requires a power of two texture then srcData
157 * will be embedded in a power of two texture. The extra width and height
158 * is filled as though srcData were rendered clamped into the texture.
reed@google.comac10a2d2010-12-22 21:39:39 +0000159 *
160 * @param desc describes the texture to be created.
161 * @param srcData texel data to load texture. Begins with full-size
162 * palette data for paletted textures. Contains width*
163 * height texels. If NULL texture data is uninitialized.
164 *
165 * @return The texture object if successful, otherwise NULL.
166 */
167 virtual GrTexture* createTexture(const TextureDesc& desc,
168 const void* srcData, size_t rowBytes) = 0;
169 /**
170 * Wraps an externally-created rendertarget in a GrRenderTarget.
171 * @param platformRenderTarget handle to the the render target in the
172 * underlying 3D API. Interpretation depends on
173 * GrGpu subclass in use.
bsalomon@google.com8895a7a2011-02-18 16:09:55 +0000174 * @param stencilBits number of stencil bits the target has
reed@google.comac10a2d2010-12-22 21:39:39 +0000175 * @param width width of the render target
176 * @param height height of the render target
177 */
178 virtual GrRenderTarget* createPlatformRenderTarget(
179 intptr_t platformRenderTarget,
bsalomon@google.com8895a7a2011-02-18 16:09:55 +0000180 int stencilBits,
reed@google.comac10a2d2010-12-22 21:39:39 +0000181 int width, int height) = 0;
182
183 /**
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000184 * Reads the current target object (e.g. FBO or IDirect3DSurface9*) and
185 * viewport state from the underlying 3D API and wraps it in a
186 * GrRenderTarget. The GrRenderTarget will not attempt to delete/destroy the
187 * underlying object in its destructor and it is up to caller to guarantee
188 * that it remains valid while the GrRenderTarget is used.
189 *
190 * @return the newly created GrRenderTarget
191 */
192 virtual GrRenderTarget* createRenderTargetFrom3DApiState() = 0;
193
194 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000195 * Creates a vertex buffer.
196 *
197 * @param size size in bytes of the vertex buffer
198 * @param dynamic hints whether the data will be frequently changed
199 * by either GrVertexBuffer::lock or
200 * GrVertexBuffer::updateData.
201 *
202 * @return The vertex buffer if successful, otherwise NULL.
203 */
204 virtual GrVertexBuffer* createVertexBuffer(uint32_t size, bool dynamic) = 0;
205
206 /**
207 * Creates an index buffer.
208 *
209 * @param size size in bytes of the index buffer
210 * @param dynamic hints whether the data will be frequently changed
211 * by either GrIndexBuffer::lock or
212 * GrIndexBuffer::updateData.
213 *
214 * @return The index buffer if successful, otherwise NULL.
215 */
216 virtual GrIndexBuffer* createIndexBuffer(uint32_t size, bool dynamic) = 0;
217
218 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000219 * Erase the entire render target, ignoring any clips/scissors.
220 *
221 * This is issued to the GPU driver immediately.
222 */
223 virtual void eraseColor(GrColor color) = 0;
224
225 /**
226 * Are 8 bit paletted textures supported.
227 *
228 * @return true if 8bit palette textures are supported, false otherwise
229 */
230 bool supports8BitPalette() const { return f8bitPaletteSupport; }
231
232 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000233 * returns true if two sided stenciling is supported. If false then only
234 * the front face values of the GrStencilSettings
reed@google.comac10a2d2010-12-22 21:39:39 +0000235 * @return true if only a single stencil pass is needed.
236 */
bsalomon@google.comd302f142011-03-03 13:54:13 +0000237 bool supportsTwoSidedStencil() const
238 { return fTwoSidedStencilSupport; }
239
240 /**
241 * returns true if stencil wrap is supported. If false then
242 * kIncWrap_StencilOp and kDecWrap_StencilOp are treated as
243 * kIncClamp_StencilOp and kDecClamp_StencilOp, respectively.
244 * @return true if stencil wrap ops are supported.
245 */
246 bool supportsStencilWrapOps() const
247 { return fStencilWrapOpsSupport; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000248
249 /**
250 * Checks whether locking vertex and index buffers is supported.
251 *
252 * @return true if locking is supported.
253 */
254 bool supportsBufferLocking() const { return fBufferLockSupport; }
255
256 /**
257 * Gets the minimum width of a render target. If a texture/rt is created
258 * with a width less than this size the GrGpu object will clamp it to this
259 * value.
260 */
261 int minRenderTargetWidth() const { return fMinRenderTargetWidth; }
262
263 /**
264 * Gets the minimum width of a render target. If a texture/rt is created
265 * with a height less than this size the GrGpu object will clamp it to this
266 * value.
267 */
268 int minRenderTargetHeight() const { return fMinRenderTargetHeight; }
269
270 /**
bsalomon@google.com0748f212011-02-01 22:56:16 +0000271 * Returns true if NPOT textures can be created
reed@google.comac10a2d2010-12-22 21:39:39 +0000272 *
bsalomon@google.com0748f212011-02-01 22:56:16 +0000273 * @return true if NPOT textures can be created
reed@google.comac10a2d2010-12-22 21:39:39 +0000274 */
bsalomon@google.com0748f212011-02-01 22:56:16 +0000275 bool npotTextureSupport() const { return fNPOTTextureSupport; }
276
277 /**
278 * Returns true if NPOT textures can be repeat/mirror tiled.
279 *
280 * @return true if NPOT textures can be tiled
281 */
282 bool npotTextureTileSupport() const { return fNPOTTextureTileSupport; }
283
284 /**
285 * Returns true if a NPOT texture can be a rendertarget
286 *
287 * @return the true if NPOT texture/rendertarget can be created.
288 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000289 bool npotRenderTargetSupport() const { return fNPOTRenderTargetSupport; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000290
reed@google.com02a7e6c2011-01-28 21:21:49 +0000291 int maxTextureDimension() const { return fMaxTextureDimension; }
292
reed@google.comac10a2d2010-12-22 21:39:39 +0000293 // GrDrawTarget overrides
bsalomon@google.comffca4002011-02-22 20:34:01 +0000294 virtual void drawIndexed(GrPrimitiveType type,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000295 int startVertex,
296 int startIndex,
297 int vertexCount,
298 int indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000299
bsalomon@google.comffca4002011-02-22 20:34:01 +0000300 virtual void drawNonIndexed(GrPrimitiveType type,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000301 int startVertex,
302 int vertexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000303
304 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000305 * Returns an index buffer that can be used to render quads.
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000306 * Six indices per quad: 0, 1, 2, 0, 2, 3, etc.
307 * The max number of quads can be queried using GrIndexBuffer::maxQuads().
reed@google.comac10a2d2010-12-22 21:39:39 +0000308 * Draw with kTriangles_PrimitiveType
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000309 * @ return the quad index buffer
reed@google.comac10a2d2010-12-22 21:39:39 +0000310 */
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000311 const GrIndexBuffer* getQuadIndexBuffer() const;
reed@google.comac10a2d2010-12-22 21:39:39 +0000312
313 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000314 * Returns a vertex buffer with four position-only vertices [(0,0), (1,0),
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000315 * (1,1), (0,1)].
316 * @ return unit square vertex buffer
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000317 */
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000318 const GrVertexBuffer* getUnitSquareVertexBuffer() const;
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000319
320 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000321 * Ensures that the current render target is actually set in the
322 * underlying 3D API. Used when client wants to use 3D API to directly
323 * render to the RT.
324 */
325 virtual void forceRenderTargetFlush() = 0;
326
327 virtual bool readPixels(int left, int top, int width, int height,
328 GrTexture::PixelConfig, void* buffer) = 0;
329
330
331 const Stats& getStats() const;
332 void resetStats();
333 void printStats() const;
334
335protected:
bsalomon@google.comd302f142011-03-03 13:54:13 +0000336 enum PrivateStateBits {
337 kFirstBit = (kLastPublicStateBit << 1),
338
339 kModifyStencilClip_StateBit = kFirstBit, // allows draws to modify
340 // stencil bits used for
341 // clipping.
reed@google.comac10a2d2010-12-22 21:39:39 +0000342 };
343
344 /**
345 * Extensions to GrDrawTarget::StateBits to implement stencil clipping
346 */
347 struct ClipState {
348 bool fClipInStencil;
349 bool fClipIsDirty;
reed@google.comac10a2d2010-12-22 21:39:39 +0000350 } fClipState;
351
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000352 // GrDrawTarget override
353 virtual void clipWillBeSet(const GrClip& newClip);
354
355 // prepares clip flushes gpu state before a draw
bsalomon@google.comffca4002011-02-22 20:34:01 +0000356 bool setupClipAndFlushState(GrPrimitiveType type);
reed@google.comac10a2d2010-12-22 21:39:39 +0000357
bsalomon@google.comd302f142011-03-03 13:54:13 +0000358 // Functions used to map clip-respecting stencil tests into normal
359 // stencil funcs supported by GPUs.
360 static GrStencilFunc ConvertStencilFunc(bool stencilInClip,
361 GrStencilFunc func);
362 static void ConvertStencilFuncAndMask(GrStencilFunc func,
363 bool clipInStencil,
364 unsigned int clipBit,
365 unsigned int userBits,
366 unsigned int* ref,
367 unsigned int* mask);
368
369 // stencil settings to clip drawing when stencil clipping is in effect
370 // and the client isn't using the stencil test.
371 static const GrStencilSettings gClipStencilSettings;
372
reed@google.comac10a2d2010-12-22 21:39:39 +0000373 // defaults to false, subclass can set true to support palleted textures
374 bool f8bitPaletteSupport;
375
bsalomon@google.com0748f212011-02-01 22:56:16 +0000376 // set by subclass
377 bool fNPOTTextureSupport;
378 bool fNPOTTextureTileSupport;
379 bool fNPOTRenderTargetSupport;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000380 bool fTwoSidedStencilSupport;
381 bool fStencilWrapOpsSupport;
reed@google.comac10a2d2010-12-22 21:39:39 +0000382
383 // set by subclass to true if index and vertex buffers can be locked, false
384 // otherwise.
385 bool fBufferLockSupport;
386
387 // set by subclass
388 int fMinRenderTargetWidth;
389 int fMinRenderTargetHeight;
reed@google.com02a7e6c2011-01-28 21:21:49 +0000390 int fMaxTextureDimension;
reed@google.comac10a2d2010-12-22 21:39:39 +0000391
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000392 Stats fStats;
393
394 const GrVertexBuffer* fCurrPoolVertexBuffer;
395 int fCurrPoolStartVertex;
396
397 const GrIndexBuffer* fCurrPoolIndexBuffer;
398 int fCurrPoolStartIndex;
399
400 // GrDrawTarget overrides
401 virtual bool acquireGeometryHelper(GrVertexLayout vertexLayout,
402 void** vertices,
403 void** indices);
404 virtual void releaseGeometryHelper();
405
406 virtual void setVertexSourceToArrayHelper(const void* vertexArray,
407 int vertexCount);
408
409 virtual void setIndexSourceToArrayHelper(const void* indexArray,
410 int indexCount);
411 // Helpers for setting up geometry state
412 void finalizeReservedVertices();
413 void finalizeReservedIndices();
414
reed@google.comac10a2d2010-12-22 21:39:39 +0000415 // overridden by API specific GrGpu-derived class to perform the draw call.
bsalomon@google.comffca4002011-02-22 20:34:01 +0000416 virtual void drawIndexedHelper(GrPrimitiveType type,
reed@google.comac10a2d2010-12-22 21:39:39 +0000417 uint32_t startVertex,
418 uint32_t startIndex,
419 uint32_t vertexCount,
420 uint32_t indexCount) = 0;
421
bsalomon@google.comffca4002011-02-22 20:34:01 +0000422 virtual void drawNonIndexedHelper(GrPrimitiveType type,
reed@google.comac10a2d2010-12-22 21:39:39 +0000423 uint32_t vertexCount,
424 uint32_t numVertices) = 0;
425
426 // called to program the vertex data, indexCount will be 0 if drawing non-
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000427 // indexed geometry. The subclass may adjust the startVertex and/or
428 // startIndex since it may have already accounted for these in the setup.
429 virtual void setupGeometry(int* startVertex,
430 int* startIndex,
431 int vertexCount,
432 int indexCount) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000433
434
435 // The GrGpu typically records the clients requested state and then flushes
436 // deltas from previous state at draw time. This function does the
437 // API-specific flush of the state
438 // returns false if current state is unsupported.
bsalomon@google.comffca4002011-02-22 20:34:01 +0000439 virtual bool flushGraphicsState(GrPrimitiveType type) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000440
441 // Sets the scissor rect, or disables if rect is NULL.
442 virtual void flushScissor(const GrIRect* rect) = 0;
443
444 // GrGpu subclass removes the clip from the stencil buffer
bsalomon@google.comd302f142011-03-03 13:54:13 +0000445 virtual void eraseStencilClip(const GrIRect& rect) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000446
reed@google.comac10a2d2010-12-22 21:39:39 +0000447private:
bsalomon@google.comd302f142011-03-03 13:54:13 +0000448 // readies the pools to provide vertex/index data.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000449 void prepareVertexPool();
450 void prepareIndexPool();
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000451
bsalomon@google.comd302f142011-03-03 13:54:13 +0000452 GrPathRenderer* getPathRenderer();
453
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000454 GrVertexBufferAllocPool* fVertexPool;
reed@google.comac10a2d2010-12-22 21:39:39 +0000455
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000456 GrIndexBufferAllocPool* fIndexPool;
reed@google.comac10a2d2010-12-22 21:39:39 +0000457
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000458 mutable GrIndexBuffer* fQuadIndexBuffer; // mutable so it can be
459 // created on-demand
reed@google.comac10a2d2010-12-22 21:39:39 +0000460
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000461 mutable GrVertexBuffer* fUnitSquareVertexBuffer; // mutable so it can be
462 // created on-demand
bsalomon@google.comd302f142011-03-03 13:54:13 +0000463
464 GrPathRenderer* fPathRenderer;
465
466 // when in an internal draw these indicate whether the pools are in use
467 // by one of the outer draws. If false then it is safe to reset the
468 // pool.
469 bool fVertexPoolInUse;
470 bool fIndexPoolInUse;
471
472 // used to save and restore state when the GrGpu needs
473 // to make its geometry pools available internally
474 class AutoInternalDrawGeomRestore {
475 public:
476 AutoInternalDrawGeomRestore(GrGpu* gpu) : fAgsr(gpu) {
477 fGpu = gpu;
478
479 fVertexPoolWasInUse = gpu->fVertexPoolInUse;
480 fIndexPoolWasInUse = gpu->fIndexPoolInUse;
481
482 gpu->fVertexPoolInUse = fVertexPoolWasInUse ||
483 (kBuffer_GeometrySrcType !=
484 gpu->fGeometrySrc.fVertexSrc);
485 gpu->fIndexPoolInUse = fIndexPoolWasInUse ||
486 (kBuffer_GeometrySrcType !=
487 gpu->fGeometrySrc.fIndexSrc);;
488
489 fSavedPoolVertexBuffer = gpu->fCurrPoolVertexBuffer;
490 fSavedPoolStartVertex = gpu->fCurrPoolStartVertex;
491 fSavedPoolIndexBuffer = gpu->fCurrPoolIndexBuffer;
492 fSavedPoolStartIndex = gpu->fCurrPoolStartIndex;
493
494 fSavedReservedGeometry = gpu->fReservedGeometry;
495 gpu->fReservedGeometry.fLocked = false;
496 }
497 ~AutoInternalDrawGeomRestore() {
498 fGpu->fCurrPoolVertexBuffer = fSavedPoolVertexBuffer;
499 fGpu->fCurrPoolStartVertex = fSavedPoolStartVertex;
500 fGpu->fCurrPoolIndexBuffer = fSavedPoolIndexBuffer;
501 fGpu->fCurrPoolStartIndex = fSavedPoolStartIndex;
502 fGpu->fVertexPoolInUse = fVertexPoolWasInUse;
503 fGpu->fIndexPoolInUse = fIndexPoolWasInUse;
504 fGpu->fReservedGeometry = fSavedReservedGeometry;
505 }
506 private:
507 AutoGeometrySrcRestore fAgsr;
508 GrGpu* fGpu;
509 const GrVertexBuffer* fSavedPoolVertexBuffer;
510 int fSavedPoolStartVertex;
511 const GrIndexBuffer* fSavedPoolIndexBuffer;
512 int fSavedPoolStartIndex;
513 bool fVertexPoolWasInUse;
514 bool fIndexPoolWasInUse;
515 ReservedGeometry fSavedReservedGeometry;
516 };
517
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000518 typedef GrDrawTarget INHERITED;
reed@google.comac10a2d2010-12-22 21:39:39 +0000519};
520
521#endif