blob: a132e9f4cc4166e5831f0aea8943a7ddc0c67824 [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.
173 * @param width width of the render target
174 * @param height height of the render target
175 */
176 virtual GrRenderTarget* createPlatformRenderTarget(
177 intptr_t platformRenderTarget,
178 int width, int height) = 0;
179
180 /**
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000181 * Reads the current target object (e.g. FBO or IDirect3DSurface9*) and
182 * viewport state from the underlying 3D API and wraps it in a
183 * GrRenderTarget. The GrRenderTarget will not attempt to delete/destroy the
184 * underlying object in its destructor and it is up to caller to guarantee
185 * that it remains valid while the GrRenderTarget is used.
186 *
187 * @return the newly created GrRenderTarget
188 */
189 virtual GrRenderTarget* createRenderTargetFrom3DApiState() = 0;
190
191 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000192 * Creates a vertex buffer.
193 *
194 * @param size size in bytes of the vertex buffer
195 * @param dynamic hints whether the data will be frequently changed
196 * by either GrVertexBuffer::lock or
197 * GrVertexBuffer::updateData.
198 *
199 * @return The vertex buffer if successful, otherwise NULL.
200 */
201 virtual GrVertexBuffer* createVertexBuffer(uint32_t size, bool dynamic) = 0;
202
203 /**
204 * Creates an index buffer.
205 *
206 * @param size size in bytes of the index buffer
207 * @param dynamic hints whether the data will be frequently changed
208 * by either GrIndexBuffer::lock or
209 * GrIndexBuffer::updateData.
210 *
211 * @return The index buffer if successful, otherwise NULL.
212 */
213 virtual GrIndexBuffer* createIndexBuffer(uint32_t size, bool dynamic) = 0;
214
215 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000216 * Erase the entire render target, ignoring any clips/scissors.
217 *
218 * This is issued to the GPU driver immediately.
219 */
220 virtual void eraseColor(GrColor color) = 0;
221
222 /**
223 * Are 8 bit paletted textures supported.
224 *
225 * @return true if 8bit palette textures are supported, false otherwise
226 */
227 bool supports8BitPalette() const { return f8bitPaletteSupport; }
228
229 /**
230 * If single stencil pass winding is supported then one stencil pass
231 * (kWindingStencil1_PathPass) is required to do winding rule path filling
232 * (or inverse winding rule). Otherwise, two passes are required
233 * (kWindingStencil1_PathPass followed by kWindingStencil2_PathPass).
234 *
235 * @return true if only a single stencil pass is needed.
236 */
237 bool supportsSingleStencilPassWinding() const
238 { return fSingleStencilPassForWinding; }
239
240 /**
241 * Checks whether locking vertex and index buffers is supported.
242 *
243 * @return true if locking is supported.
244 */
245 bool supportsBufferLocking() const { return fBufferLockSupport; }
246
247 /**
248 * Gets the minimum width of a render target. If a texture/rt is created
249 * with a width less than this size the GrGpu object will clamp it to this
250 * value.
251 */
252 int minRenderTargetWidth() const { return fMinRenderTargetWidth; }
253
254 /**
255 * Gets the minimum width of a render target. If a texture/rt is created
256 * with a height less than this size the GrGpu object will clamp it to this
257 * value.
258 */
259 int minRenderTargetHeight() const { return fMinRenderTargetHeight; }
260
261 /**
bsalomon@google.com0748f212011-02-01 22:56:16 +0000262 * Returns true if NPOT textures can be created
reed@google.comac10a2d2010-12-22 21:39:39 +0000263 *
bsalomon@google.com0748f212011-02-01 22:56:16 +0000264 * @return 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 bool npotTextureSupport() const { return fNPOTTextureSupport; }
267
268 /**
269 * Returns true if NPOT textures can be repeat/mirror tiled.
270 *
271 * @return true if NPOT textures can be tiled
272 */
273 bool npotTextureTileSupport() const { return fNPOTTextureTileSupport; }
274
275 /**
276 * Returns true if a NPOT texture can be a rendertarget
277 *
278 * @return the true if NPOT texture/rendertarget can be created.
279 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000280 bool npotRenderTargetSupport() const { return fNPOTRenderTargetSupport; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000281
reed@google.com02a7e6c2011-01-28 21:21:49 +0000282 int maxTextureDimension() const { return fMaxTextureDimension; }
283
reed@google.comac10a2d2010-12-22 21:39:39 +0000284 // GrDrawTarget overrides
285 virtual void drawIndexed(PrimitiveType type,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000286 int startVertex,
287 int startIndex,
288 int vertexCount,
289 int indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000290
291 virtual void drawNonIndexed(PrimitiveType type,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000292 int startVertex,
293 int vertexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000294
295 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000296 * Returns an index buffer that can be used to render quads.
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000297 * Six indices per quad: 0, 1, 2, 0, 2, 3, etc.
298 * The max number of quads can be queried using GrIndexBuffer::maxQuads().
reed@google.comac10a2d2010-12-22 21:39:39 +0000299 * Draw with kTriangles_PrimitiveType
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000300 * @ return the quad index buffer
reed@google.comac10a2d2010-12-22 21:39:39 +0000301 */
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000302 const GrIndexBuffer* getQuadIndexBuffer() const;
reed@google.comac10a2d2010-12-22 21:39:39 +0000303
304 /**
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000305 * Returns a vertex buffer with four position-only vertices [(0,0), (1,0),
306 * (1,1), (0,1)].
307 * @ return unit square vertex buffer
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000308 */
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000309 const GrVertexBuffer* getUnitSquareVertexBuffer() const;
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000310
311 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000312 * Ensures that the current render target is actually set in the
313 * underlying 3D API. Used when client wants to use 3D API to directly
314 * render to the RT.
315 */
316 virtual void forceRenderTargetFlush() = 0;
317
318 virtual bool readPixels(int left, int top, int width, int height,
319 GrTexture::PixelConfig, void* buffer) = 0;
320
321
322 const Stats& getStats() const;
323 void resetStats();
324 void printStats() const;
325
326protected:
327 /**
328 * Extensions to GrDrawTarget::StencilPass to implement stencil clipping
329 */
330 enum GpuStencilPass {
331 kSetClip_StencilPass = kDrawTargetCount_StencilPass,
332 /* rendering a hard clip to the stencil
333 buffer. Subsequent draws with other
334 StencilPass values will be clipped
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000335 if kClip_StateBit is set. */
reed@google.comac10a2d2010-12-22 21:39:39 +0000336 kGpuCount_StencilPass
337 };
338
339 /**
340 * Extensions to GrDrawTarget::StateBits to implement stencil clipping
341 */
342 struct ClipState {
343 bool fClipInStencil;
344 bool fClipIsDirty;
345 GrRenderTarget* fStencilClipTarget;
346 } fClipState;
347
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000348 // GrDrawTarget override
349 virtual void clipWillBeSet(const GrClip& newClip);
350
351 // prepares clip flushes gpu state before a draw
reed@google.comac10a2d2010-12-22 21:39:39 +0000352 bool setupClipAndFlushState(PrimitiveType type);
353
354 struct BoundsState {
355 bool fScissorEnabled;
356 GrIRect fScissorRect;
357 GrIRect fViewportRect;
358 };
359
360 // defaults to false, subclass can set true to support palleted textures
361 bool f8bitPaletteSupport;
362
bsalomon@google.com0748f212011-02-01 22:56:16 +0000363 // set by subclass
364 bool fNPOTTextureSupport;
365 bool fNPOTTextureTileSupport;
366 bool fNPOTRenderTargetSupport;
reed@google.comac10a2d2010-12-22 21:39:39 +0000367
368 // True if only one stencil pass is required to implement the winding path
369 // fill rule. Subclass responsible for setting this value.
370 bool fSingleStencilPassForWinding;
371
372 // set by subclass to true if index and vertex buffers can be locked, false
373 // otherwise.
374 bool fBufferLockSupport;
375
376 // set by subclass
377 int fMinRenderTargetWidth;
378 int fMinRenderTargetHeight;
reed@google.com02a7e6c2011-01-28 21:21:49 +0000379 int fMaxTextureDimension;
reed@google.comac10a2d2010-12-22 21:39:39 +0000380
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000381 Stats fStats;
382
383 const GrVertexBuffer* fCurrPoolVertexBuffer;
384 int fCurrPoolStartVertex;
385
386 const GrIndexBuffer* fCurrPoolIndexBuffer;
387 int fCurrPoolStartIndex;
388
389 // GrDrawTarget overrides
390 virtual bool acquireGeometryHelper(GrVertexLayout vertexLayout,
391 void** vertices,
392 void** indices);
393 virtual void releaseGeometryHelper();
394
395 virtual void setVertexSourceToArrayHelper(const void* vertexArray,
396 int vertexCount);
397
398 virtual void setIndexSourceToArrayHelper(const void* indexArray,
399 int indexCount);
400 // Helpers for setting up geometry state
401 void finalizeReservedVertices();
402 void finalizeReservedIndices();
403
reed@google.comac10a2d2010-12-22 21:39:39 +0000404 // overridden by API specific GrGpu-derived class to perform the draw call.
405 virtual void drawIndexedHelper(PrimitiveType type,
406 uint32_t startVertex,
407 uint32_t startIndex,
408 uint32_t vertexCount,
409 uint32_t indexCount) = 0;
410
411 virtual void drawNonIndexedHelper(PrimitiveType type,
412 uint32_t vertexCount,
413 uint32_t numVertices) = 0;
414
415 // called to program the vertex data, indexCount will be 0 if drawing non-
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000416 // indexed geometry. The subclass may adjust the startVertex and/or
417 // startIndex since it may have already accounted for these in the setup.
418 virtual void setupGeometry(int* startVertex,
419 int* startIndex,
420 int vertexCount,
421 int indexCount) = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000422
423
424 // The GrGpu typically records the clients requested state and then flushes
425 // deltas from previous state at draw time. This function does the
426 // API-specific flush of the state
427 // returns false if current state is unsupported.
428 virtual bool flushGraphicsState(PrimitiveType type) = 0;
429
430 // Sets the scissor rect, or disables if rect is NULL.
431 virtual void flushScissor(const GrIRect* rect) = 0;
432
433 // GrGpu subclass removes the clip from the stencil buffer
434 virtual void eraseStencilClip() = 0;
435
reed@google.comac10a2d2010-12-22 21:39:39 +0000436private:
reed@google.comac10a2d2010-12-22 21:39:39 +0000437
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000438 void prepareVertexPool();
439 void prepareIndexPool();
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000440
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000441 GrVertexBufferAllocPool* fVertexPool;
reed@google.comac10a2d2010-12-22 21:39:39 +0000442
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000443 GrIndexBufferAllocPool* fIndexPool;
reed@google.comac10a2d2010-12-22 21:39:39 +0000444
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000445 mutable GrIndexBuffer* fQuadIndexBuffer; // mutable so it can be
446 // created on-demand
reed@google.comac10a2d2010-12-22 21:39:39 +0000447
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000448 mutable GrVertexBuffer* fUnitSquareVertexBuffer; // mutable so it can be
449 // created on-demand
450 typedef GrDrawTarget INHERITED;
reed@google.comac10a2d2010-12-22 21:39:39 +0000451};
452
453#endif