blob: cfa150921101af5eb1078d06946b7d109b80a960 [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;
reed@google.comac10a2d2010-12-22 21:39:39 +000028
29class GrGpu : public GrDrawTarget {
30
31public:
32 /**
33 * Possible 3D APIs that may be used by Ganesh.
34 */
35 enum Engine {
36 kOpenGL_Shaders_Engine,
37 kOpenGL_Fixed_Engine,
38 kDirect3D9_Engine
39 };
40
41 /**
42 * Platform specific 3D context.
43 * For
44 * kOpenGL_Shaders_Engine use NULL
45 * kOpenGL_Fixed_Engine use NULL
46 * kDirect3D9_Engine use an IDirect3DDevice9*
47 */
48 typedef void* Platform3DContext;
49
50 /**
51 * Create an instance of GrGpu that matches the specified Engine backend.
52 * If the requested engine is not supported (at compile-time or run-time)
53 * this returns NULL.
54 */
55 static GrGpu* Create(Engine, Platform3DContext context3D);
56
57 /**
reed@google.comac10a2d2010-12-22 21:39:39 +000058 * Used to control the level of antialiasing available for a rendertarget.
59 * Anti-alias quality levels depend on the underlying API/GPU capabilities.
60 */
61 enum AALevels {
62 kNone_AALevel, //<! No antialiasing available.
63 kLow_AALevel, //<! Low quality antialiased rendering. Actual
64 // interpretation is platform-dependent.
65 kMed_AALevel, //<! Medium quality antialiased rendering. Actual
66 // interpretation is platform-dependent.
67 kHigh_AALevel, //<! High quality antialiased rendering. Actual
68 // interpretation is platform-dependent.
69 };
70
71
72 /**
73 * Optional bitfield flags that can be passed to createTexture.
74 */
75 enum TextureFlags {
76 kRenderTarget_TextureFlag = 0x1, //<! Creates a texture that can be
77 // rendered to by calling
78 // GrGpu::setRenderTarget() with
79 // GrTexture::asRenderTarget().
80 kNoPathRendering_TextureFlag = 0x2, //<! If the texture is used as a
81 // rendertarget but paths will not
82 // be rendered to it.
83 kDynamicUpdate_TextureFlag = 0x4 //!< Hint that the CPU may modify
84 // this texture after creation
85 };
86
87 enum {
88 /**
89 * For Index8 pixel config, the colortable must be 256 entries
90 */
91 kColorTableSize = 256 * sizeof(GrColor)
92 };
93 /**
94 * Describes a texture to be created.
95 */
96 struct TextureDesc {
97 uint32_t fFlags; //!< bitfield of TextureFlags
98 GrGpu::AALevels fAALevel;//!< The level of antialiasing available
99 // for a rendertarget texture. Only
100 // flags contains
101 // kRenderTarget_TextureFlag.
102 uint32_t fWidth; //!< Width of the texture
103 uint32_t fHeight; //!< Height of the texture
104 GrTexture::PixelConfig fFormat; //!< Format of source data of the
105 // texture. Not guaraunteed to be the
106 // same as internal format used by
107 // 3D API.
108 };
109
110 /**
111 * Gpu usage statistics.
112 */
113 struct Stats {
114 uint32_t fVertexCnt; //<! Number of vertices drawn
115 uint32_t fIndexCnt; //<! Number of indices drawn
116 uint32_t fDrawCnt; //<! Number of draws
117
118 uint32_t fProgChngCnt;//<! Number of program changes (N/A for fixed)
119
120 /*
121 * Number of times the texture is set in 3D API
122 */
123 uint32_t fTextureChngCnt;
124 /*
125 * Number of times the render target is set in 3D API
126 */
127 uint32_t fRenderTargetChngCnt;
128 /*
129 * Number of textures created (includes textures that are rendertargets).
130 */
131 uint32_t fTextureCreateCnt;
132 /*
133 * Number of rendertargets created.
134 */
135 uint32_t fRenderTargetCreateCnt;
136 };
137
138 ////////////////////////////////////////////////////////////////////////////
139
140 GrGpu();
141 virtual ~GrGpu();
142
143 /**
144 * The GrGpu object normally assumes that no outsider is setting state
145 * within the underlying 3D API's context/device/whatever. This call informs
146 * the GrGpu that the state was modified and it should resend. Shouldn't
147 * be called frequently for good performance.
148 */
149 virtual void resetContext();
150
151 void unimpl(const char[]);
152
153 /**
bsalomon@google.com0748f212011-02-01 22:56:16 +0000154 * Creates a texture object. If desc width or height is not a power of
155 * two but underlying API requires a power of two texture then srcData
156 * will be embedded in a power of two texture. The extra width and height
157 * is filled as though srcData were rendered clamped into the texture.
reed@google.comac10a2d2010-12-22 21:39:39 +0000158 *
159 * @param desc describes the texture to be created.
160 * @param srcData texel data to load texture. Begins with full-size
161 * palette data for paletted textures. Contains width*
162 * height texels. If NULL texture data is uninitialized.
163 *
164 * @return The texture object if successful, otherwise NULL.
165 */
166 virtual GrTexture* createTexture(const TextureDesc& desc,
167 const void* srcData, size_t rowBytes) = 0;
168 /**
169 * Wraps an externally-created rendertarget in a GrRenderTarget.
170 * @param platformRenderTarget handle to the the render target in the
171 * underlying 3D API. Interpretation depends on
172 * GrGpu subclass in use.
bsalomon@google.com8895a7a2011-02-18 16:09:55 +0000173 * @param stencilBits number of stencil bits the target has
reed@google.comac10a2d2010-12-22 21:39:39 +0000174 * @param width width of the render target
175 * @param height height of the render target
176 */
177 virtual GrRenderTarget* createPlatformRenderTarget(
178 intptr_t platformRenderTarget,
bsalomon@google.com8895a7a2011-02-18 16:09:55 +0000179 int stencilBits,
reed@google.comac10a2d2010-12-22 21:39:39 +0000180 int width, int height) = 0;
181
182 /**
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000183 * Reads the current target object (e.g. FBO or IDirect3DSurface9*) and
184 * viewport state from the underlying 3D API and wraps it in a
185 * GrRenderTarget. The GrRenderTarget will not attempt to delete/destroy the
186 * underlying object in its destructor and it is up to caller to guarantee
187 * that it remains valid while the GrRenderTarget is used.
188 *
189 * @return the newly created GrRenderTarget
190 */
191 virtual GrRenderTarget* createRenderTargetFrom3DApiState() = 0;
192
193 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000194 * Creates a vertex buffer.
195 *
196 * @param size size in bytes of the vertex buffer
197 * @param dynamic hints whether the data will be frequently changed
198 * by either GrVertexBuffer::lock or
199 * GrVertexBuffer::updateData.
200 *
201 * @return The vertex buffer if successful, otherwise NULL.
202 */
203 virtual GrVertexBuffer* createVertexBuffer(uint32_t size, bool dynamic) = 0;
204
205 /**
206 * Creates an index buffer.
207 *
208 * @param size size in bytes of the index buffer
209 * @param dynamic hints whether the data will be frequently changed
210 * by either GrIndexBuffer::lock or
211 * GrIndexBuffer::updateData.
212 *
213 * @return The index buffer if successful, otherwise NULL.
214 */
215 virtual GrIndexBuffer* createIndexBuffer(uint32_t size, bool dynamic) = 0;
216
217 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000218 * Erase the entire render target, ignoring any clips/scissors.
219 *
220 * This is issued to the GPU driver immediately.
221 */
222 virtual void eraseColor(GrColor color) = 0;
223
224 /**
225 * Are 8 bit paletted textures supported.
226 *
227 * @return true if 8bit palette textures are supported, false otherwise
228 */
229 bool supports8BitPalette() const { return f8bitPaletteSupport; }
230
231 /**
232 * If single stencil pass winding is supported then one stencil pass
233 * (kWindingStencil1_PathPass) is required to do winding rule path filling
234 * (or inverse winding rule). Otherwise, two passes are required
235 * (kWindingStencil1_PathPass followed by kWindingStencil2_PathPass).
236 *
237 * @return true if only a single stencil pass is needed.
238 */
239 bool supportsSingleStencilPassWinding() const
240 { return fSingleStencilPassForWinding; }
241
242 /**
243 * Checks whether locking vertex and index buffers is supported.
244 *
245 * @return true if locking is supported.
246 */
247 bool supportsBufferLocking() const { return fBufferLockSupport; }
248
249 /**
250 * Gets the minimum width of a render target. If a texture/rt is created
251 * with a width less than this size the GrGpu object will clamp it to this
252 * value.
253 */
254 int minRenderTargetWidth() const { return fMinRenderTargetWidth; }
255
256 /**
257 * Gets the minimum width of a render target. If a texture/rt is created
258 * with a height less than this size the GrGpu object will clamp it to this
259 * value.
260 */
261 int minRenderTargetHeight() const { return fMinRenderTargetHeight; }
262
263 /**
bsalomon@google.com0748f212011-02-01 22:56:16 +0000264 * Returns true if NPOT textures can be created
reed@google.comac10a2d2010-12-22 21:39:39 +0000265 *
bsalomon@google.com0748f212011-02-01 22:56:16 +0000266 * @return true if NPOT textures can be created
reed@google.comac10a2d2010-12-22 21:39:39 +0000267 */
bsalomon@google.com0748f212011-02-01 22:56:16 +0000268 bool npotTextureSupport() const { return fNPOTTextureSupport; }
269
270 /**
271 * Returns true if NPOT textures can be repeat/mirror tiled.
272 *
273 * @return true if NPOT textures can be tiled
274 */
275 bool npotTextureTileSupport() const { return fNPOTTextureTileSupport; }
276
277 /**
278 * Returns true if a NPOT texture can be a rendertarget
279 *
280 * @return the true if NPOT texture/rendertarget can be created.
281 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000282 bool npotRenderTargetSupport() const { return fNPOTRenderTargetSupport; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000283
reed@google.com02a7e6c2011-01-28 21:21:49 +0000284 int maxTextureDimension() const { return fMaxTextureDimension; }
285
reed@google.comac10a2d2010-12-22 21:39:39 +0000286 // GrDrawTarget overrides
287 virtual void drawIndexed(PrimitiveType type,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000288 int startVertex,
289 int startIndex,
290 int vertexCount,
291 int indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000292
293 virtual void drawNonIndexed(PrimitiveType type,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000294 int startVertex,
295 int vertexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000296
297 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000298 * Returns an index buffer that can be used to render quads.
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000299 * Six indices per quad: 0, 1, 2, 0, 2, 3, etc.
300 * The max number of quads can be queried using GrIndexBuffer::maxQuads().
reed@google.comac10a2d2010-12-22 21:39:39 +0000301 * Draw with kTriangles_PrimitiveType
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000302 * @ return the quad index buffer
reed@google.comac10a2d2010-12-22 21:39:39 +0000303 */
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000304 const GrIndexBuffer* getQuadIndexBuffer() const;
reed@google.comac10a2d2010-12-22 21:39:39 +0000305
306 /**
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000307 * Returns a vertex buffer with four position-only vertices [(0,0), (1,0),
308 * (1,1), (0,1)].
309 * @ return unit square vertex buffer
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000310 */
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000311 const GrVertexBuffer* getUnitSquareVertexBuffer() const;
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000312
313 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000314 * Ensures that the current render target is actually set in the
315 * underlying 3D API. Used when client wants to use 3D API to directly
316 * render to the RT.
317 */
318 virtual void forceRenderTargetFlush() = 0;
319
320 virtual bool readPixels(int left, int top, int width, int height,
321 GrTexture::PixelConfig, void* buffer) = 0;
322
323
324 const Stats& getStats() const;
325 void resetStats();
326 void printStats() const;
327
328protected:
329 /**
330 * Extensions to GrDrawTarget::StencilPass to implement stencil clipping
331 */
332 enum GpuStencilPass {
333 kSetClip_StencilPass = kDrawTargetCount_StencilPass,
334 /* rendering a hard clip to the stencil
335 buffer. Subsequent draws with other
336 StencilPass values will be clipped
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000337 if kClip_StateBit is set. */
reed@google.comac10a2d2010-12-22 21:39:39 +0000338 kGpuCount_StencilPass
339 };
340
341 /**
342 * Extensions to GrDrawTarget::StateBits to implement stencil clipping
343 */
344 struct ClipState {
345 bool fClipInStencil;
346 bool fClipIsDirty;
347 GrRenderTarget* fStencilClipTarget;
348 } fClipState;
349
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000350 // GrDrawTarget override
351 virtual void clipWillBeSet(const GrClip& newClip);
352
353 // prepares clip flushes gpu state before a draw
reed@google.comac10a2d2010-12-22 21:39:39 +0000354 bool setupClipAndFlushState(PrimitiveType type);
355
reed@google.comac10a2d2010-12-22 21:39:39 +0000356 // defaults to false, subclass can set true to support palleted textures
357 bool f8bitPaletteSupport;
358
bsalomon@google.com0748f212011-02-01 22:56:16 +0000359 // set by subclass
360 bool fNPOTTextureSupport;
361 bool fNPOTTextureTileSupport;
362 bool fNPOTRenderTargetSupport;
reed@google.comac10a2d2010-12-22 21:39:39 +0000363
364 // True if only one stencil pass is required to implement the winding path
365 // fill rule. Subclass responsible for setting this value.
366 bool fSingleStencilPassForWinding;
367
368 // set by subclass to true if index and vertex buffers can be locked, false
369 // otherwise.
370 bool fBufferLockSupport;
371
372 // set by subclass
373 int fMinRenderTargetWidth;
374 int fMinRenderTargetHeight;
reed@google.com02a7e6c2011-01-28 21:21:49 +0000375 int fMaxTextureDimension;
reed@google.comac10a2d2010-12-22 21:39:39 +0000376
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000377 Stats fStats;
378
379 const GrVertexBuffer* fCurrPoolVertexBuffer;
380 int fCurrPoolStartVertex;
381
382 const GrIndexBuffer* fCurrPoolIndexBuffer;
383 int fCurrPoolStartIndex;
384
385 // GrDrawTarget overrides
386 virtual bool acquireGeometryHelper(GrVertexLayout vertexLayout,
387 void** vertices,
388 void** indices);
389 virtual void releaseGeometryHelper();
390
391 virtual void setVertexSourceToArrayHelper(const void* vertexArray,
392 int vertexCount);
393
394 virtual void setIndexSourceToArrayHelper(const void* indexArray,
395 int indexCount);
396 // Helpers for setting up geometry state
397 void finalizeReservedVertices();
398 void finalizeReservedIndices();
399
reed@google.comac10a2d2010-12-22 21:39:39 +0000400 // overridden by API specific GrGpu-derived class to perform the draw call.
401 virtual void drawIndexedHelper(PrimitiveType type,
402 uint32_t startVertex,
403 uint32_t startIndex,
404 uint32_t vertexCount,
405 uint32_t indexCount) = 0;
406
407 virtual void drawNonIndexedHelper(PrimitiveType type,
408 uint32_t vertexCount,
409 uint32_t numVertices) = 0;
410
411 // called to program the vertex data, indexCount will be 0 if drawing non-
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000412 // indexed geometry. The subclass may adjust the startVertex and/or
413 // startIndex since it may have already accounted for these in the setup.
414 virtual void setupGeometry(int* startVertex,
415 int* startIndex,
416 int vertexCount,
417 int indexCount) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000418
419
420 // The GrGpu typically records the clients requested state and then flushes
421 // deltas from previous state at draw time. This function does the
422 // API-specific flush of the state
423 // returns false if current state is unsupported.
424 virtual bool flushGraphicsState(PrimitiveType type) = 0;
425
426 // Sets the scissor rect, or disables if rect is NULL.
427 virtual void flushScissor(const GrIRect* rect) = 0;
428
429 // GrGpu subclass removes the clip from the stencil buffer
430 virtual void eraseStencilClip() = 0;
431
reed@google.comac10a2d2010-12-22 21:39:39 +0000432private:
reed@google.comac10a2d2010-12-22 21:39:39 +0000433
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000434 void prepareVertexPool();
435 void prepareIndexPool();
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000436
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000437 GrVertexBufferAllocPool* fVertexPool;
reed@google.comac10a2d2010-12-22 21:39:39 +0000438
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000439 GrIndexBufferAllocPool* fIndexPool;
reed@google.comac10a2d2010-12-22 21:39:39 +0000440
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000441 mutable GrIndexBuffer* fQuadIndexBuffer; // mutable so it can be
442 // created on-demand
reed@google.comac10a2d2010-12-22 21:39:39 +0000443
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000444 mutable GrVertexBuffer* fUnitSquareVertexBuffer; // mutable so it can be
445 // created on-demand
446 typedef GrDrawTarget INHERITED;
reed@google.comac10a2d2010-12-22 21:39:39 +0000447};
448
449#endif