blob: 2bbb419e6f425d45d35bb32b9a60226e9ad4cd45 [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"
24#include "GrGpuVertex.h"
25#include "GrTexture.h"
26#include "GrMemory.h"
27
28
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 */
280 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,
286 uint32_t startVertex,
287 uint32_t startIndex,
288 uint32_t vertexCount,
289 uint32_t indexCount);
290
291 virtual void drawNonIndexed(PrimitiveType type,
292 uint32_t startVertex,
293 uint32_t vertexCount);
294
295 /**
296 * Determines if blend is effectively disabled.
297 *
298 * @return true if blend can be disabled without changing the rendering
299 * result given the current state including the vertex layout specified
300 * with the vertex source.
301 */
302 bool canDisableBlend() const;
303
304 /**
305 * Returns an index buffer that can be used to render quads.
306 * Indices are 0, 1, 2, 0, 2, 3, etc.
307 * Draw with kTriangles_PrimitiveType
308 */
309 const GrIndexBuffer* quadIndexBuffer() const;
310 /**
311 * Gets the number of quads that can be rendered using quadIndexBuffer.
312 */
313 int maxQuadsInIndexBuffer() const;
314
315 /**
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000316 * Returns a vertex buffer with four position-only vertices [(0,0), (1,0), (1,1), (0,1)]
317 */
318 const GrVertexBuffer* unitSquareVertexBuffer() const;
319
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:
336 /**
337 * Extensions to GrDrawTarget::StencilPass to implement stencil clipping
338 */
339 enum GpuStencilPass {
340 kSetClip_StencilPass = kDrawTargetCount_StencilPass,
341 /* rendering a hard clip to the stencil
342 buffer. Subsequent draws with other
343 StencilPass values will be clipped
344 if kStencilClip_StateBit is set. */
345 kGpuCount_StencilPass
346 };
347
348 /**
349 * Extensions to GrDrawTarget::StateBits to implement stencil clipping
350 */
351 struct ClipState {
352 bool fClipInStencil;
353 bool fClipIsDirty;
354 GrRenderTarget* fStencilClipTarget;
355 } fClipState;
356
357 virtual void clipWillChange(const GrClip& clip);
358 bool setupClipAndFlushState(PrimitiveType type);
359
360 struct BoundsState {
361 bool fScissorEnabled;
362 GrIRect fScissorRect;
363 GrIRect fViewportRect;
364 };
365
366 // defaults to false, subclass can set true to support palleted textures
367 bool f8bitPaletteSupport;
368
bsalomon@google.com0748f212011-02-01 22:56:16 +0000369 // set by subclass
370 bool fNPOTTextureSupport;
371 bool fNPOTTextureTileSupport;
372 bool fNPOTRenderTargetSupport;
reed@google.comac10a2d2010-12-22 21:39:39 +0000373
374 // True if only one stencil pass is required to implement the winding path
375 // fill rule. Subclass responsible for setting this value.
376 bool fSingleStencilPassForWinding;
377
378 // set by subclass to true if index and vertex buffers can be locked, false
379 // otherwise.
380 bool fBufferLockSupport;
381
382 // set by subclass
383 int fMinRenderTargetWidth;
384 int fMinRenderTargetHeight;
reed@google.com02a7e6c2011-01-28 21:21:49 +0000385 int fMaxTextureDimension;
reed@google.comac10a2d2010-12-22 21:39:39 +0000386
387 // overridden by API specific GrGpu-derived class to perform the draw call.
388 virtual void drawIndexedHelper(PrimitiveType type,
389 uint32_t startVertex,
390 uint32_t startIndex,
391 uint32_t vertexCount,
392 uint32_t indexCount) = 0;
393
394 virtual void drawNonIndexedHelper(PrimitiveType type,
395 uint32_t vertexCount,
396 uint32_t numVertices) = 0;
397
398 // called to program the vertex data, indexCount will be 0 if drawing non-
399 // indexed geometry.
400 virtual void setupGeometry(uint32_t startVertex,
401 uint32_t startIndex,
402 uint32_t vertexCount,
403 uint32_t indexCount) = 0;
404
405
406 // The GrGpu typically records the clients requested state and then flushes
407 // deltas from previous state at draw time. This function does the
408 // API-specific flush of the state
409 // returns false if current state is unsupported.
410 virtual bool flushGraphicsState(PrimitiveType type) = 0;
411
412 // Sets the scissor rect, or disables if rect is NULL.
413 virtual void flushScissor(const GrIRect* rect) = 0;
414
415 // GrGpu subclass removes the clip from the stencil buffer
416 virtual void eraseStencilClip() = 0;
417
418 // GrDrawTarget overrides
419 virtual bool acquireGeometryHelper(GrVertexLayout vertexLayout,
420 void** vertices,
421 void** indices);
422 virtual void releaseGeometryHelper();
423
424private:
425 mutable GrIndexBuffer* fQuadIndexBuffer; // mutable so it can be
426 // created on-demand
427
bsalomon@google.com6f7fbc92011-02-01 19:12:40 +0000428 mutable GrVertexBuffer* fUnitSquareVertexBuffer; // mutable so it can be
429 // created on-demand
430
reed@google.comac10a2d2010-12-22 21:39:39 +0000431 static const int MAX_VERTEX_SIZE = GR_CT_MAX(2*sizeof(GrPoint) + sizeof(GrColor),
432 2*sizeof(GrGpuTextVertex));
433 static const int VERTEX_STORAGE = 16 * MAX_VERTEX_SIZE;
434 static const int INDEX_STORAGE = 32 * sizeof(uint16_t);
435
436protected:
437 GrAutoSMalloc<VERTEX_STORAGE> fVertices;
438 GrAutoSMalloc<INDEX_STORAGE> fIndices;
439
440 Stats fStats;
441
442private:
443 typedef GrRefCnt INHERITED;
444};
445
446#endif
447