• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright 2011 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 
9 
10 #ifndef GrGpu_DEFINED
11 #define GrGpu_DEFINED
12 
13 #include "GrDrawTarget.h"
14 #include "GrRect.h"
15 #include "GrRefCnt.h"
16 #include "GrTexture.h"
17 
18 class GrContext;
19 class GrIndexBufferAllocPool;
20 class GrPathRenderer;
21 class GrPathRendererChain;
22 class GrResource;
23 class GrStencilBuffer;
24 class GrVertexBufferAllocPool;
25 
26 /**
27  * Gpu usage statistics.
28  */
29 struct GrGpuStats {
30     uint32_t fVertexCnt;  //<! Number of vertices drawn
31     uint32_t fIndexCnt;   //<! Number of indices drawn
32     uint32_t fDrawCnt;    //<! Number of draws
33 
34     uint32_t fProgChngCnt;//<! Number of program changes
35 
36     /**
37      *  Number of times the texture is set in 3D API
38      */
39     uint32_t fTextureChngCnt;
40     /**
41      *  Number of times the render target is set in 3D API
42      */
43     uint32_t fRenderTargetChngCnt;
44     /**
45      *  Number of textures created (includes textures that are rendertargets).
46      */
47     uint32_t fTextureCreateCnt;
48     /**
49      *  Number of rendertargets created.
50      */
51     uint32_t fRenderTargetCreateCnt;
52 };
53 
54 class GrGpu : public GrDrawTarget {
55 
56 public:
57 
58     /**
59      * Additional blend coeffecients for dual source blending, not exposed
60      * through GrPaint/GrContext.
61      */
62     enum ExtendedBlendCoeffs {
63         // source 2 refers to second output color when
64         // using dual source blending.
65         kS2C_BlendCoeff = kPublicBlendCoeffCount,
66         kIS2C_BlendCoeff,
67         kS2A_BlendCoeff,
68         kIS2A_BlendCoeff,
69 
70         kTotalBlendCoeffCount
71     };
72 
73     /**
74      *  Create an instance of GrGpu that matches the specified Engine backend.
75      *  If the requested engine is not supported (at compile-time or run-time)
76      *  this returns NULL.
77      */
78     static GrGpu* Create(GrEngine, GrPlatform3DContext context3D);
79 
80     ////////////////////////////////////////////////////////////////////////////
81 
82     GrGpu();
83     virtual ~GrGpu();
84 
85     // The GrContext sets itself as the owner of this Gpu object
setContext(GrContext * context)86     void setContext(GrContext* context) {
87         GrAssert(NULL == fContext);
88         fContext = context;
89     }
getContext()90     GrContext* getContext() { return fContext; }
getContext()91     const GrContext* getContext() const { return fContext; }
92 
93     /**
94      * The GrGpu object normally assumes that no outsider is setting state
95      * within the underlying 3D API's context/device/whatever. This call informs
96      * the GrGpu that the state was modified and it shouldn't make assumptions
97      * about the state.
98      */
markContextDirty()99     void markContextDirty() { fContextIsDirty = true; }
100 
101     void unimpl(const char[]);
102 
103     /**
104      * Creates a texture object. If desc width or height is not a power of
105      * two but underlying API requires a power of two texture then srcData
106      * will be embedded in a power of two texture. The extra width and height
107      * is filled as though srcData were rendered clamped into the texture.
108      *
109      * If kRenderTarget_TextureFlag is specified the GrRenderTarget is
110      * accessible via GrTexture::asRenderTarget(). The texture will hold a ref
111      * on the render target until its releaseRenderTarget() is called or it is
112      * destroyed.
113      *
114      * @param desc        describes the texture to be created.
115      * @param srcData     texel data to load texture. Begins with full-size
116      *                    palette data for paletted textures. Contains width*
117      *                    height texels. If NULL texture data is uninitialized.
118      *
119      * @return    The texture object if successful, otherwise NULL.
120      */
121     GrTexture* createTexture(const GrTextureDesc& desc,
122                              const void* srcData, size_t rowBytes);
123 
124     /**
125      * Implements GrContext::createPlatformTexture
126      */
127     GrTexture* createPlatformTexture(const GrPlatformTextureDesc& desc);
128 
129     /**
130      * Implements GrContext::createPlatformTexture
131      */
132     GrRenderTarget* createPlatformRenderTarget(const GrPlatformRenderTargetDesc& desc);
133 
134     /**
135      * Creates a vertex buffer.
136      *
137      * @param size    size in bytes of the vertex buffer
138      * @param dynamic hints whether the data will be frequently changed
139      *                by either GrVertexBuffer::lock or
140      *                GrVertexBuffer::updateData.
141      *
142      * @return    The vertex buffer if successful, otherwise NULL.
143      */
144     GrVertexBuffer* createVertexBuffer(uint32_t size, bool dynamic);
145 
146     /**
147      * Creates an index buffer.
148      *
149      * @param size    size in bytes of the index buffer
150      * @param dynamic hints whether the data will be frequently changed
151      *                by either GrIndexBuffer::lock or
152      *                GrIndexBuffer::updateData.
153      *
154      * @return The index buffer if successful, otherwise NULL.
155      */
156     GrIndexBuffer* createIndexBuffer(uint32_t size, bool dynamic);
157 
158     /**
159      * Returns an index buffer that can be used to render quads.
160      * Six indices per quad: 0, 1, 2, 0, 2, 3, etc.
161      * The max number of quads can be queried using GrIndexBuffer::maxQuads().
162      * Draw with kTriangles_PrimitiveType
163      * @ return the quad index buffer
164      */
165     const GrIndexBuffer* getQuadIndexBuffer() const;
166 
167     /**
168      * Returns a vertex buffer with four position-only vertices [(0,0), (1,0),
169      * (1,1), (0,1)].
170      * @ return unit square vertex buffer
171      */
172     const GrVertexBuffer* getUnitSquareVertexBuffer() const;
173 
174     /**
175      * Resolves MSAA.
176      */
177     void resolveRenderTarget(GrRenderTarget* target);
178 
179     /**
180      * Ensures that the current render target is actually set in the
181      * underlying 3D API. Used when client wants to use 3D API to directly
182      * render to the RT.
183      */
184     void forceRenderTargetFlush();
185 
186     /**
187      * If this returns true then a sequence that reads unpremultiplied pixels
188      * from a surface, writes back the same values, and reads them again will
189      * give the same pixel values back in both reads.
190      */
191     virtual bool canPreserveReadWriteUnpremulPixels() = 0;
192 
193     /**
194      * readPixels with some configs may be slow. Given a desired config this
195      * function returns a fast-path config. The returned config must have the
196      * same components, component sizes, and not require conversion between
197      * pre- and unpremultiplied alpha. The caller is free to ignore the result
198      * and call readPixels with the original config.
199      */
preferredReadPixelsConfig(GrPixelConfig config)200     virtual GrPixelConfig preferredReadPixelsConfig(GrPixelConfig config)
201                                                                         const {
202         return config;
203     }
204 
205     /**
206      * Same as above but applies to writeTexturePixels
207      */
preferredWritePixelsConfig(GrPixelConfig config)208     virtual GrPixelConfig preferredWritePixelsConfig(GrPixelConfig config)
209                                                                         const {
210         return config;
211     }
212 
213     /**
214      * OpenGL's readPixels returns the result bottom-to-top while the skia
215      * API is top-to-bottom. Thus we have to do a y-axis flip. The obvious
216      * solution is to have the subclass do the flip using either the CPU or GPU.
217      * However, the caller (GrContext) may have transformations to apply and can
218      * simply fold in the y-flip for free. On the other hand, the subclass may
219      * be able to do it for free itself. For example, the subclass may have to
220      * do memcpys to handle rowBytes that aren't tight. It could do the y-flip
221      * concurrently.
222      *
223      * This function returns true if a y-flip is required to put the pixels in
224      * top-to-bottom order and the subclass cannot do it for free.
225      *
226      * See read pixels for the params
227      * @return true if calling readPixels with the same set of params will
228      *              produce bottom-to-top data
229      */
230      virtual bool readPixelsWillPayForYFlip(GrRenderTarget* renderTarget,
231                                             int left, int top,
232                                             int width, int height,
233                                             GrPixelConfig config,
234                                             size_t rowBytes) const = 0;
235      /**
236       * This should return true if reading a NxM rectangle of pixels from a
237       * render target is faster if the target has dimensons N and M and the read
238       * rectangle has its top-left at 0,0.
239       */
fullReadPixelsIsFasterThanPartial()240      virtual bool fullReadPixelsIsFasterThanPartial() const { return false; };
241 
242     /**
243      * Reads a rectangle of pixels from a render target. Fails if read requires
244      * conversion between premultiplied and unpremultiplied configs. The caller
245      * should do the conversion by rendering to a target with the desire config
246      * first.
247      *
248      * @param renderTarget  the render target to read from. NULL means the
249      *                      current render target.
250      * @param left          left edge of the rectangle to read (inclusive)
251      * @param top           top edge of the rectangle to read (inclusive)
252      * @param width         width of rectangle to read in pixels.
253      * @param height        height of rectangle to read in pixels.
254      * @param config        the pixel config of the destination buffer
255      * @param buffer        memory to read the rectangle into.
256      * @param rowBytes      the number of bytes between consecutive rows. Zero
257      *                      means rows are tightly packed.
258      * @param invertY       buffer should be populated bottom-to-top as opposed
259      *                      to top-to-bottom (skia's usual order)
260      *
261      * @return true if the read succeeded, false if not. The read can fail
262      *              because of a unsupported pixel config or because no render
263      *              target is currently set.
264      */
265     bool readPixels(GrRenderTarget* renderTarget,
266                     int left, int top, int width, int height,
267                     GrPixelConfig config, void* buffer, size_t rowBytes,
268                     bool invertY);
269 
270     /**
271      * Updates the pixels in a rectangle of a texture.
272      *
273      * @param left          left edge of the rectangle to write (inclusive)
274      * @param top           top edge of the rectangle to write (inclusive)
275      * @param width         width of rectangle to write in pixels.
276      * @param height        height of rectangle to write in pixels.
277      * @param config        the pixel config of the source buffer
278      * @param buffer        memory to read pixels from
279      * @param rowBytes      number of bytes bewtween consecutive rows. Zero
280      *                      means rows are tightly packed.
281      */
282     void writeTexturePixels(GrTexture* texture,
283                             int left, int top, int width, int height,
284                             GrPixelConfig config, const void* buffer,
285                             size_t rowBytes);
286 
287     const GrGpuStats& getStats() const;
288     void resetStats();
289     void printStats() const;
290 
291     /**
292      * Called to tell Gpu object that all GrResources have been lost and should
293      * be abandoned. Overrides must call INHERITED::abandonResources().
294      */
295     virtual void abandonResources();
296 
297     /**
298      * Called to tell Gpu object to release all GrResources. Overrides must call
299      * INHERITED::releaseResources().
300      */
301     void releaseResources();
302 
303     /**
304      * Add resource to list of resources. Should only be called by GrResource.
305      * @param resource  the resource to add.
306      */
307     void insertResource(GrResource* resource);
308 
309     /**
310      * Remove resource from list of resources. Should only be called by
311      * GrResource.
312      * @param resource  the resource to remove.
313      */
314     void removeResource(GrResource* resource);
315 
316     // GrDrawTarget overrides
317     virtual void clear(const GrIRect* rect, GrColor color);
318 
319     // After the client interacts directly with the 3D context state the GrGpu
320     // must resync its internal state and assumptions about 3D context state.
321     // Each time this occurs the GrGpu bumps a timestamp.
322     // state of the 3D context
323     // At 10 resets / frame and 60fps a 64bit timestamp will overflow in about
324     // a billion years.
325     typedef uint64_t ResetTimestamp;
326 
327     // This timestamp is always older than the current timestamp
328     static const ResetTimestamp kExpiredTimestamp = 0;
329     // Returns a timestamp based on the number of times the context was reset.
330     // This timestamp can be used to lazily detect when cached 3D context state
331     // is dirty.
getResetTimestamp()332     ResetTimestamp getResetTimestamp() const {
333         return fResetTimestamp;
334     }
335 
336 protected:
337     enum PrivateDrawStateStateBits {
338         kFirstBit = (GrDrawState::kLastPublicStateBit << 1),
339 
340         kModifyStencilClip_StateBit = kFirstBit, // allows draws to modify
341                                                  // stencil bits used for
342                                                  // clipping.
343     };
344 
345     // keep track of whether we are using stencil clipping (as opposed to
346     // scissor).
347     bool    fClipInStencil;
348 
349     // prepares clip flushes gpu state before a draw
350     bool setupClipAndFlushState(GrPrimitiveType type);
351 
352     // Functions used to map clip-respecting stencil tests into normal
353     // stencil funcs supported by GPUs.
354     static GrStencilFunc ConvertStencilFunc(bool stencilInClip,
355                                             GrStencilFunc func);
356     static void ConvertStencilFuncAndMask(GrStencilFunc func,
357                                           bool clipInStencil,
358                                           unsigned int clipBit,
359                                           unsigned int userBits,
360                                           unsigned int* ref,
361                                           unsigned int* mask);
362 
363     // stencil settings to clip drawing when stencil clipping is in effect
364     // and the client isn't using the stencil test.
365     static const GrStencilSettings* GetClipStencilSettings();
366 
367     GrGpuStats fStats;
368 
369     struct GeometryPoolState {
370         const GrVertexBuffer* fPoolVertexBuffer;
371         int                   fPoolStartVertex;
372 
373         const GrIndexBuffer*  fPoolIndexBuffer;
374         int                   fPoolStartIndex;
375     };
getGeomPoolState()376     const GeometryPoolState& getGeomPoolState() {
377         return fGeomPoolStateStack.back();
378     }
379 
380     // GrDrawTarget overrides
381     virtual bool onReserveVertexSpace(GrVertexLayout vertexLayout,
382                                       int vertexCount,
383                                       void** vertices);
384     virtual bool onReserveIndexSpace(int indexCount, void** indices);
385     virtual void releaseReservedVertexSpace();
386     virtual void releaseReservedIndexSpace();
387     virtual void onSetVertexSourceToArray(const void* vertexArray,
388                                           int vertexCount);
389     virtual void onSetIndexSourceToArray(const void* indexArray,
390                                          int indexCount);
391     virtual void releaseVertexArray();
392     virtual void releaseIndexArray();
393     virtual void geometrySourceWillPush();
394     virtual void geometrySourceWillPop(const GeometrySrcState& restoredState);
395 
396     // Helpers for setting up geometry state
397     void finalizeReservedVertices();
398     void finalizeReservedIndices();
399 
400     // called when the 3D context state is unknown. Subclass should emit any
401     // assumed 3D context state and dirty any state cache
402     virtual void onResetContext() = 0;
403 
404 
405     // overridden by API-specific derived class to create objects.
406     virtual GrTexture* onCreateTexture(const GrTextureDesc& desc,
407                                        const void* srcData,
408                                        size_t rowBytes) = 0;
409     virtual GrTexture* onCreatePlatformTexture(const GrPlatformTextureDesc& desc) = 0;
410     virtual GrRenderTarget* onCreatePlatformRenderTarget(const GrPlatformRenderTargetDesc& desc) = 0;
411     virtual GrVertexBuffer* onCreateVertexBuffer(uint32_t size,
412                                                  bool dynamic) = 0;
413     virtual GrIndexBuffer* onCreateIndexBuffer(uint32_t size,
414                                                bool dynamic) = 0;
415 
416     // overridden by API-specific derivated class to perform the clear and
417     // clearRect. NULL rect means clear whole target.
418     virtual void onClear(const GrIRect* rect, GrColor color) = 0;
419 
420     // overridden by API-specific derived class to perform the draw call.
421     virtual void onGpuDrawIndexed(GrPrimitiveType type,
422                                   uint32_t startVertex,
423                                   uint32_t startIndex,
424                                   uint32_t vertexCount,
425                                   uint32_t indexCount) = 0;
426 
427     virtual void onGpuDrawNonIndexed(GrPrimitiveType type,
428                                      uint32_t vertexCount,
429                                      uint32_t numVertices) = 0;
430 
431     // overridden by API-specific derived class to perform flush
432     virtual void onForceRenderTargetFlush() = 0;
433 
434     // overridden by API-specific derived class to perform the read pixels.
435     virtual bool onReadPixels(GrRenderTarget* target,
436                               int left, int top, int width, int height,
437                               GrPixelConfig,
438                               void* buffer,
439                               size_t rowBytes,
440                               bool invertY) = 0;
441 
442     // overridden by API-specific derived class to perform the texture update
443     virtual void onWriteTexturePixels(GrTexture* texture,
444                                       int left, int top, int width, int height,
445                                       GrPixelConfig config, const void* buffer,
446                                       size_t rowBytes) = 0;
447 
448     // overridden by API-specific derived class to perform the resolve
449     virtual void onResolveRenderTarget(GrRenderTarget* target) = 0;
450 
451     // called to program the vertex data, indexCount will be 0 if drawing non-
452     // indexed geometry. The subclass may adjust the startVertex and/or
453     // startIndex since it may have already accounted for these in the setup.
454     virtual void setupGeometry(int* startVertex,
455                                int* startIndex,
456                                int vertexCount,
457                                int indexCount) = 0;
458 
459     // width and height may be larger than rt (if underlying API allows it).
460     // Should attach the SB to the RT. Returns false if compatible sb could
461     // not be created.
462     virtual bool createStencilBufferForRenderTarget(GrRenderTarget* rt,
463                                                     int width,
464                                                     int height) = 0;
465 
466     // attaches an existing SB to an existing RT.
467     virtual bool attachStencilBufferToRenderTarget(GrStencilBuffer* sb,
468                                                    GrRenderTarget* rt) = 0;
469 
470     // The GrGpu typically records the clients requested state and then flushes
471     // deltas from previous state at draw time. This function does the
472     // API-specific flush of the state
473     // returns false if current state is unsupported.
474     virtual bool flushGraphicsState(GrPrimitiveType type) = 0;
475 
476     // Sets the scissor rect, or disables if rect is NULL.
477     virtual void flushScissor(const GrIRect* rect) = 0;
478 
479     // GrGpu subclass sets clip bit in the stencil buffer. The subclass is
480     // free to clear the remaining bits to zero if masked clears are more
481     // expensive than clearing all bits.
482     virtual void clearStencilClip(const GrIRect& rect, bool insideClip) = 0;
483 
484     // clears the entire stencil buffer to 0
485     virtual void clearStencil() = 0;
486 
487 private:
488     GrContext*                  fContext; // not reffed (context refs gpu)
489 
490     ResetTimestamp              fResetTimestamp;
491 
492     GrVertexBufferAllocPool*    fVertexPool;
493 
494     GrIndexBufferAllocPool*     fIndexPool;
495 
496     // counts number of uses of vertex/index pool in the geometry stack
497     int                         fVertexPoolUseCnt;
498     int                         fIndexPoolUseCnt;
499 
500     enum {
501         kPreallocGeomPoolStateStackCnt = 4,
502     };
503     SkSTArray<kPreallocGeomPoolStateStackCnt,
504               GeometryPoolState, true>              fGeomPoolStateStack;
505 
506     mutable GrIndexBuffer*      fQuadIndexBuffer; // mutable so it can be
507                                                   // created on-demand
508 
509     mutable GrVertexBuffer*     fUnitSquareVertexBuffer; // mutable so it can be
510                                                          // created on-demand
511 
512     // must be instantiated after GrGpu object has been given its owning
513     // GrContext ptr. (GrGpu is constructed first then handed off to GrContext).
514     GrPathRendererChain*        fPathRendererChain;
515 
516     bool                        fContextIsDirty;
517 
518     GrResource*                 fResourceHead;
519 
520     // Given a rt, find or create a stencil buffer and attach it
521     bool attachStencilBufferToRenderTarget(GrRenderTarget* target);
522 
523     // GrDrawTarget overrides
524     virtual void onDrawIndexed(GrPrimitiveType type,
525                                int startVertex,
526                                int startIndex,
527                                int vertexCount,
528                                int indexCount);
529     virtual void onDrawNonIndexed(GrPrimitiveType type,
530                                   int startVertex,
531                                   int vertexCount);
532 
533     // readies the pools to provide vertex/index data.
534     void prepareVertexPool();
535     void prepareIndexPool();
536 
537     // determines the path renderer used to draw a clip path element.
538     GrPathRenderer* getClipPathRenderer(const SkPath& path, GrPathFill fill);
539 
resetContext()540     void resetContext() {
541         this->onResetContext();
542         ++fResetTimestamp;
543     }
544 
handleDirtyContext()545     void handleDirtyContext() {
546         if (fContextIsDirty) {
547             this->resetContext();
548             fContextIsDirty = false;
549         }
550     }
551 
552     typedef GrDrawTarget INHERITED;
553 };
554 
555 #endif
556