• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     Copyright 2011 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 #ifndef GrGpu_DEFINED
18 #define GrGpu_DEFINED
19 
20 #include "GrDrawTarget.h"
21 #include "GrPathRenderer.h"
22 #include "GrRect.h"
23 #include "GrRefCnt.h"
24 #include "GrTexture.h"
25 
26 class GrContext;
27 class GrIndexBufferAllocPool;
28 class GrResource;
29 class GrVertexBufferAllocPool;
30 
31 /**
32  * Gpu usage statistics.
33  */
34 struct GrGpuStats {
35     uint32_t fVertexCnt;  //<! Number of vertices drawn
36     uint32_t fIndexCnt;   //<! Number of indices drawn
37     uint32_t fDrawCnt;    //<! Number of draws
38 
39     uint32_t fProgChngCnt;//<! Number of program changes (N/A for fixed)
40 
41     /*
42         *  Number of times the texture is set in 3D API
43         */
44     uint32_t fTextureChngCnt;
45     /*
46         *  Number of times the render target is set in 3D API
47         */
48     uint32_t fRenderTargetChngCnt;
49     /*
50         *  Number of textures created (includes textures that are rendertargets).
51         */
52     uint32_t fTextureCreateCnt;
53     /*
54         *  Number of rendertargets created.
55         */
56     uint32_t fRenderTargetCreateCnt;
57 };
58 
59 class GrGpu : public GrDrawTarget {
60 
61 public:
62     /**
63      * Additional blend coeffecients for dual source blending, not exposed
64      * through GrPaint/GrContext.
65      */
66     enum ExtendedBlendCoeffs {
67         // source 2 refers to second output color when
68         // using dual source blending.
69         kS2C_BlendCoeff = kPublicBlendCoeffCount,
70         kIS2C_BlendCoeff,
71         kS2A_BlendCoeff,
72         kIS2A_BlendCoeff,
73 
74         kTotalBlendCoeffCount
75     };
76 
77     /**
78      *  Create an instance of GrGpu that matches the specified Engine backend.
79      *  If the requested engine is not supported (at compile-time or run-time)
80      *  this returns NULL.
81      */
82     static GrGpu* Create(GrEngine, GrPlatform3DContext context3D);
83 
84     ////////////////////////////////////////////////////////////////////////////
85 
86     GrGpu();
87     virtual ~GrGpu();
88 
89     // The GrContext sets itself as the owner of this Gpu object
setContext(GrContext * context)90     void setContext(GrContext* context) {
91         GrAssert(NULL == fContext);
92         fContext = context;
93     }
getContext()94     GrContext* getContext() { return fContext; }
getContext()95     const GrContext* getContext() const { return fContext; }
96 
97     /**
98      * The GrGpu object normally assumes that no outsider is setting state
99      * within the underlying 3D API's context/device/whatever. This call informs
100      * the GrGpu that the state was modified and it shouldn't make assumptions
101      * about the state.
102      */
markContextDirty()103     void markContextDirty() { fContextIsDirty = true; }
104 
105     void unimpl(const char[]);
106 
107     /**
108      * Creates a texture object. If desc width or height is not a power of
109      * two but underlying API requires a power of two texture then srcData
110      * will be embedded in a power of two texture. The extra width and height
111      * is filled as though srcData were rendered clamped into the texture.
112      *
113      * If kRenderTarget_TextureFlag is specified the GrRenderTarget is
114      * accessible via GrTexture::asRenderTarget(). The texture will hold a ref
115      * on the render target until its releaseRenderTarget() is called or it is
116      * destroyed.
117      *
118      * @param desc        describes the texture to be created.
119      * @param srcData     texel data to load texture. Begins with full-size
120      *                    palette data for paletted textures. Contains width*
121      *                    height texels. If NULL texture data is uninitialized.
122      *
123      * @return    The texture object if successful, otherwise NULL.
124      */
125     GrTexture* createTexture(const GrTextureDesc& desc,
126                              const void* srcData, size_t rowBytes);
127 
128     GrResource* createPlatformSurface(const GrPlatformSurfaceDesc& desc);
129 
130     /**
131      * Reads the current target object (e.g. FBO or IDirect3DSurface9*) and
132      * viewport state from the underlying 3D API and wraps it in a
133      * GrRenderTarget. The GrRenderTarget will not attempt to delete/destroy the
134      * underlying object in its destructor and it is up to caller to guarantee
135      * that it remains valid while the GrRenderTarget is used.
136      *
137      * @return the newly created GrRenderTarget
138      */
139     GrRenderTarget* createRenderTargetFrom3DApiState();
140 
141     /**
142      * Creates a vertex buffer.
143      *
144      * @param size    size in bytes of the vertex buffer
145      * @param dynamic hints whether the data will be frequently changed
146      *                by either GrVertexBuffer::lock or
147      *                GrVertexBuffer::updateData.
148      *
149      * @return    The vertex buffer if successful, otherwise NULL.
150      */
151     GrVertexBuffer* createVertexBuffer(uint32_t size, bool dynamic);
152 
153     /**
154      * Creates an index buffer.
155      *
156      * @param size    size in bytes of the index buffer
157      * @param dynamic hints whether the data will be frequently changed
158      *                by either GrIndexBuffer::lock or
159      *                GrIndexBuffer::updateData.
160      *
161      * @return The index buffer if successful, otherwise NULL.
162      */
163     GrIndexBuffer* createIndexBuffer(uint32_t size, bool dynamic);
164 
165     /**
166      * Are 8 bit paletted textures supported.
167      *
168      * @return    true if 8bit palette textures are supported, false otherwise
169      */
supports8BitPalette()170     bool supports8BitPalette() const { return f8bitPaletteSupport; }
171 
172     /**
173      * returns true if two sided stenciling is supported. If false then only
174      * the front face values of the GrStencilSettings
175      * @return    true if only a single stencil pass is needed.
176      */
supportsTwoSidedStencil()177     bool supportsTwoSidedStencil() const
178                                         { return fTwoSidedStencilSupport; }
179 
180     /**
181      * returns true if stencil wrap is supported. If false then
182      * kIncWrap_StencilOp and kDecWrap_StencilOp are treated as
183      * kIncClamp_StencilOp and kDecClamp_StencilOp, respectively.
184      * @return    true if stencil wrap ops are supported.
185      */
supportsStencilWrapOps()186     bool supportsStencilWrapOps() const
187                                         { return fStencilWrapOpsSupport; }
188 
189     /**
190      * Checks whether locking vertex and index buffers is supported.
191      *
192      * @return true if locking is supported.
193      */
supportsBufferLocking()194     bool supportsBufferLocking() const { return fBufferLockSupport; }
195 
196     /**
197      * Does the 3D API support anti-aliased lines. If so then line primitive
198      * types will use this functionality when the AA state flag is set.
199      */
supportsAALines()200     bool supportsAALines() const { return fAALineSupport; }
201 
202     /**
203      * Does the subclass support GrSamplerState::k4x4Downsample_Filter
204      */
supports4x4DownsampleFilter()205     bool supports4x4DownsampleFilter() const { return f4X4DownsampleFilterSupport; }
206 
207     /**
208      * Does this instance support dual-source blending? Required for proper
209      * blending with partial coverage with certain blend modes (dst coeff is
210      * not 1, ISA, or ISC)
211      */
supportsDualSourceBlending()212     bool supportsDualSourceBlending() const {
213         return fDualSourceBlendingSupport;
214     }
215 
216     /**
217      * Gets the minimum width of a render target. If a texture/rt is created
218      * with a width less than this size the GrGpu object will clamp it to this
219      * value.
220      */
minRenderTargetWidth()221     int minRenderTargetWidth() const { return fMinRenderTargetWidth; }
222 
223     /**
224      * Gets the minimum width of a render target. If a texture/rt is created
225      * with a height less than this size the GrGpu object will clamp it to this
226      * value.
227      */
minRenderTargetHeight()228     int minRenderTargetHeight() const  { return fMinRenderTargetHeight; }
229 
230     /**
231      * Reports whether full scene anti-aliasing is supported.
232      */
supportsFullsceneAA()233     bool supportsFullsceneAA() const { return fFSAASupport; }
234 
235     /**
236      * Returns true if NPOT textures can be created
237      *
238      * @return    true if NPOT textures can be created
239      */
npotTextureSupport()240     bool npotTextureSupport() const { return fNPOTTextureSupport; }
241 
242     /**
243      * Returns true if NPOT textures can be repeat/mirror tiled.
244      *
245      * @return    true if NPOT textures can be tiled
246      */
npotTextureTileSupport()247     bool npotTextureTileSupport() const { return fNPOTTextureTileSupport; }
248 
249     /**
250      * Returns true if a NPOT texture can be a rendertarget
251      *
252      * @return    the true if NPOT texture/rendertarget can be created.
253      */
npotRenderTargetSupport()254     bool npotRenderTargetSupport() const { return fNPOTRenderTargetSupport; }
255 
maxTextureDimension()256     int maxTextureDimension() const { return fMaxTextureDimension; }
257 
258     // GrDrawTarget overrides
259     virtual void drawIndexed(GrPrimitiveType type,
260                              int startVertex,
261                              int startIndex,
262                              int vertexCount,
263                              int indexCount);
264 
265     virtual void drawNonIndexed(GrPrimitiveType type,
266                                 int startVertex,
267                                 int vertexCount);
268     virtual void clear(const GrIRect* rect, GrColor color);
269 
270     /**
271      * Installs a path renderer that will be used to draw paths that are
272      * part of the clip.
273      */
setClipPathRenderer(GrPathRenderer * pathRenderer)274     void setClipPathRenderer(GrPathRenderer* pathRenderer) {
275         GrSafeAssign(fClientPathRenderer, pathRenderer);
276     }
277 
278     /**
279      * Returns an index buffer that can be used to render quads.
280      * Six indices per quad: 0, 1, 2, 0, 2, 3, etc.
281      * The max number of quads can be queried using GrIndexBuffer::maxQuads().
282      * Draw with kTriangles_PrimitiveType
283      * @ return the quad index buffer
284      */
285     const GrIndexBuffer* getQuadIndexBuffer() const;
286 
287     /**
288      * Returns a vertex buffer with four position-only vertices [(0,0), (1,0),
289      * (1,1), (0,1)].
290      * @ return unit square vertex buffer
291      */
292     const GrVertexBuffer* getUnitSquareVertexBuffer() const;
293 
294     /**
295      * Ensures that the current render target is actually set in the
296      * underlying 3D API. Used when client wants to use 3D API to directly
297      * render to the RT.
298      */
299     void forceRenderTargetFlush();
300 
301     /**
302      * Reads a rectangle of pixels from a render target.
303      * @param renderTarget  the render target to read from. NULL means the
304      *                      current render target.
305      * @param left          left edge of the rectangle to read (inclusive)
306      * @param top           top edge of the rectangle to read (inclusive)
307      * @param width         width of rectangle to read in pixels.
308      * @param height        height of rectangle to read in pixels.
309      * @param config        the pixel config of the destination buffer
310      * @param buffer        memory to read the rectangle into.
311      *
312      * @return true if the read succeeded, false if not. The read can fail
313      *              because of a unsupported pixel config or because no render
314      *              target is currently set.
315      */
316     bool readPixels(GrRenderTarget* renderTarget,
317                     int left, int top, int width, int height,
318                     GrPixelConfig config, void* buffer);
319 
320     const GrGpuStats& getStats() const;
321     void resetStats();
322     void printStats() const;
323 
324     /**
325      * Called to tell Gpu object that all GrResources have been lost and should
326      * be abandoned.
327      */
328     virtual void abandonResources();
329 
330     /**
331      * Called to tell Gpu object to release all GrResources.
332      */
333     void releaseResources();
334 
335     /**
336      * Add resource to list of resources. Should only be called by GrResource.
337      * @param resource  the resource to add.
338      */
339     void insertResource(GrResource* resource);
340 
341     /**
342      * Remove resource from list of resources. Should only be called by
343      * GrResource.
344      * @param resource  the resource to remove.
345      */
346     void removeResource(GrResource* resource);
347 
348 protected:
349     enum PrivateStateBits {
350         kFirstBit = (kLastPublicStateBit << 1),
351 
352         kModifyStencilClip_StateBit = kFirstBit, // allows draws to modify
353                                                  // stencil bits used for
354                                                  // clipping.
355     };
356 
357     /**
358      * Extensions to GrDrawTarget::StateBits to implement stencil clipping
359      */
360     struct ClipState {
361         bool            fClipInStencil;
362         bool            fClipIsDirty;
363     } fClipState;
364 
365     // GrDrawTarget override
366     virtual void clipWillBeSet(const GrClip& newClip);
367 
368     // prepares clip flushes gpu state before a draw
369     bool setupClipAndFlushState(GrPrimitiveType type);
370 
371     // Functions used to map clip-respecting stencil tests into normal
372     // stencil funcs supported by GPUs.
373     static GrStencilFunc ConvertStencilFunc(bool stencilInClip,
374                                             GrStencilFunc func);
375     static void ConvertStencilFuncAndMask(GrStencilFunc func,
376                                           bool clipInStencil,
377                                           unsigned int clipBit,
378                                           unsigned int userBits,
379                                           unsigned int* ref,
380                                           unsigned int* mask);
381 
382     // stencil settings to clip drawing when stencil clipping is in effect
383     // and the client isn't using the stencil test.
384     static const GrStencilSettings gClipStencilSettings;
385 
386     // defaults to false, subclass can set true to support palleted textures
387     bool f8bitPaletteSupport;
388 
389     // set by subclass
390     bool fNPOTTextureSupport;
391     bool fNPOTTextureTileSupport;
392     bool fNPOTRenderTargetSupport;
393     bool fTwoSidedStencilSupport;
394     bool fStencilWrapOpsSupport;
395     bool fAALineSupport;
396     bool fFSAASupport;
397     bool f4X4DownsampleFilterSupport; // supports GrSamplerState::k4x4Downsample_Filter
398     bool fDualSourceBlendingSupport;
399 
400     // set by subclass to true if index and vertex buffers can be locked, false
401     // otherwise.
402     bool fBufferLockSupport;
403 
404     // set by subclass
405     int fMinRenderTargetWidth;
406     int fMinRenderTargetHeight;
407     int fMaxTextureDimension;
408 
409     GrGpuStats fStats;
410 
411     const GrVertexBuffer*           fCurrPoolVertexBuffer;
412     int                             fCurrPoolStartVertex;
413 
414     const GrIndexBuffer*            fCurrPoolIndexBuffer;
415     int                             fCurrPoolStartIndex;
416 
417     // GrDrawTarget overrides
418     virtual bool onAcquireGeometry(GrVertexLayout vertexLayout,
419                                    void**         vertices,
420                                    void**         indices);
421     virtual void onReleaseGeometry();
422 
423     virtual void onSetVertexSourceToArray(const void* vertexArray,
424                                           int vertexCount);
425 
426     virtual void onSetIndexSourceToArray(const void* indexArray,
427                                          int indexCount);
428     // Helpers for setting up geometry state
429     void finalizeReservedVertices();
430     void finalizeReservedIndices();
431 
432     // overridden by API-specific derived class to handle re-emitting 3D API
433     // preample and dirtying state cache.
434     virtual void resetContext() = 0;
435 
436     // overridden by API-specific derived class to create objects.
437     virtual GrTexture* onCreateTexture(const GrTextureDesc& desc,
438                                        const void* srcData,
439                                        size_t rowBytes) = 0;
440     virtual GrResource* onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc) = 0;
441     virtual GrRenderTarget* onCreateRenderTargetFrom3DApiState() = 0;
442     virtual GrVertexBuffer* onCreateVertexBuffer(uint32_t size,
443                                                  bool dynamic) = 0;
444     virtual GrIndexBuffer* onCreateIndexBuffer(uint32_t size,
445                                                bool dynamic) = 0;
446 
447     // overridden by API-specific derivated class to perform the clear and
448     // clearRect. NULL rect means clear whole target.
449     virtual void onClear(const GrIRect* rect, GrColor color) = 0;
450 
451     // overridden by API-specific derived class to perform the draw call.
452     virtual void onDrawIndexed(GrPrimitiveType type,
453                                uint32_t startVertex,
454                                uint32_t startIndex,
455                                uint32_t vertexCount,
456                                uint32_t indexCount) = 0;
457 
458     virtual void onDrawNonIndexed(GrPrimitiveType type,
459                                   uint32_t vertexCount,
460                                   uint32_t numVertices) = 0;
461 
462     // overridden by API-specific derived class to perform flush
463     virtual void onForceRenderTargetFlush() = 0;
464 
465     // overridden by API-specific derived class to perform the read pixels.
466     virtual bool onReadPixels(GrRenderTarget* target,
467                               int left, int top, int width, int height,
468                               GrPixelConfig, void* buffer) = 0;
469 
470     // called to program the vertex data, indexCount will be 0 if drawing non-
471     // indexed geometry. The subclass may adjust the startVertex and/or
472     // startIndex since it may have already accounted for these in the setup.
473     virtual void setupGeometry(int* startVertex,
474                                int* startIndex,
475                                int vertexCount,
476                                int indexCount) = 0;
477 
478 
479     // The GrGpu typically records the clients requested state and then flushes
480     // deltas from previous state at draw time. This function does the
481     // API-specific flush of the state
482     // returns false if current state is unsupported.
483     virtual bool flushGraphicsState(GrPrimitiveType type) = 0;
484 
485     // Sets the scissor rect, or disables if rect is NULL.
486     virtual void flushScissor(const GrIRect* rect) = 0;
487 
488     // GrGpu subclass removes the clip from the stencil buffer
489     virtual void clearStencilClip(const GrIRect& rect) = 0;
490 
491 private:
492     GrContext*                  fContext; // not reffed (context refs gpu)
493 
494     GrVertexBufferAllocPool*    fVertexPool;
495 
496     GrIndexBufferAllocPool*     fIndexPool;
497 
498     mutable GrIndexBuffer*      fQuadIndexBuffer; // mutable so it can be
499                                                   // created on-demand
500 
501     mutable GrVertexBuffer*     fUnitSquareVertexBuffer; // mutable so it can be
502                                                          // created on-demand
503 
504     GrDefaultPathRenderer*      fDefaultPathRenderer;
505     GrPathRenderer*             fClientPathRenderer;
506 
507     bool                        fContextIsDirty;
508 
509     // when in an internal draw these indicate whether the pools are in use
510     // by one of the outer draws. If false then it is safe to reset the
511     // pool.
512     bool                        fVertexPoolInUse;
513     bool                        fIndexPoolInUse;
514 
515     GrResource*                 fResourceHead;
516 
517     // readies the pools to provide vertex/index data.
518     void prepareVertexPool();
519     void prepareIndexPool();
520 
521     // determines the path renderer used to draw a clip path element.
522     GrPathRenderer* getClipPathRenderer(const SkPath& path, GrPathFill fill);
523 
handleDirtyContext()524     void handleDirtyContext() {
525         if (fContextIsDirty) {
526             this->resetContext();
527             fContextIsDirty = false;
528         }
529     }
530 
531     // used to save and restore state when the GrGpu needs
532     // to make its geometry pools available internally
533     class AutoInternalDrawGeomRestore {
534     public:
AutoInternalDrawGeomRestore(GrGpu * gpu)535         AutoInternalDrawGeomRestore(GrGpu* gpu) : fAgsr(gpu) {
536             fGpu = gpu;
537 
538             fVertexPoolWasInUse = gpu->fVertexPoolInUse;
539             fIndexPoolWasInUse  = gpu->fIndexPoolInUse;
540 
541             gpu->fVertexPoolInUse = fVertexPoolWasInUse ||
542                                    (kBuffer_GeometrySrcType !=
543                                     gpu->fGeometrySrc.fVertexSrc);
544             gpu->fIndexPoolInUse  = fIndexPoolWasInUse ||
545                                    (kBuffer_GeometrySrcType !=
546                                     gpu->fGeometrySrc.fIndexSrc);;
547 
548             fSavedPoolVertexBuffer = gpu->fCurrPoolVertexBuffer;
549             fSavedPoolStartVertex  = gpu->fCurrPoolStartVertex;
550             fSavedPoolIndexBuffer  = gpu->fCurrPoolIndexBuffer;
551             fSavedPoolStartIndex   = gpu->fCurrPoolStartIndex;
552 
553             fSavedReservedGeometry = gpu->fReservedGeometry;
554             gpu->fReservedGeometry.fLocked = false;
555         }
~AutoInternalDrawGeomRestore()556         ~AutoInternalDrawGeomRestore() {
557             fGpu->fCurrPoolVertexBuffer = fSavedPoolVertexBuffer;
558             fGpu->fCurrPoolStartVertex  = fSavedPoolStartVertex;
559             fGpu->fCurrPoolIndexBuffer  = fSavedPoolIndexBuffer;
560             fGpu->fCurrPoolStartIndex   = fSavedPoolStartIndex;
561             fGpu->fVertexPoolInUse = fVertexPoolWasInUse;
562             fGpu->fIndexPoolInUse  = fIndexPoolWasInUse;
563             fGpu->fReservedGeometry = fSavedReservedGeometry;
564         }
565     private:
566         AutoGeometrySrcRestore  fAgsr;
567         GrGpu*                  fGpu;
568         const GrVertexBuffer*   fSavedPoolVertexBuffer;
569         int                     fSavedPoolStartVertex;
570         const GrIndexBuffer*    fSavedPoolIndexBuffer;
571         int                     fSavedPoolStartIndex;
572         bool                    fVertexPoolWasInUse;
573         bool                    fIndexPoolWasInUse;
574         ReservedGeometry        fSavedReservedGeometry;
575     };
576 
577     typedef GrDrawTarget INHERITED;
578 };
579 
580 #endif
581