Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2011 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef GrInOrderDrawBuffer_DEFINED
      9 #define GrInOrderDrawBuffer_DEFINED
     10 
     11 #include "GrDrawTarget.h"
     12 #include "GrCommandBuilder.h"
     13 #include "SkChunkAlloc.h"
     14 
     15 /**
     16  * GrInOrderDrawBuffer is an implementation of GrDrawTarget that queues up draws for eventual
     17  * playback into a GrGpu. In theory one draw buffer could playback into another. When index or
     18  * vertex buffers are used as geometry sources it is the callers the draw buffer only holds
     19  * references to the buffers. It is the callers responsibility to ensure that the data is still
     20  * valid when the draw buffer is played back into a GrGpu. Similarly, it is the caller's
     21  * responsibility to ensure that all referenced textures, buffers, and render-targets are associated
     22  * in the GrGpu object that the buffer is played back into. The buffer requires VB and IB pools to
     23  * store geometry.
     24  */
     25 class GrInOrderDrawBuffer : public GrClipTarget {
     26 public:
     27 
     28     /**
     29      * Creates a GrInOrderDrawBuffer
     30      *
     31      * @param context    the context object that owns this draw buffer.
     32      */
     33     GrInOrderDrawBuffer(GrContext* context);
     34 
     35     ~GrInOrderDrawBuffer() override;
     36 
     37     // tracking for draws
     38     DrawToken getCurrentDrawToken() override { return DrawToken(this, fDrawID); }
     39 
     40     void clearStencilClip(const SkIRect& rect,
     41                           bool insideClip,
     42                           GrRenderTarget* renderTarget) override;
     43 
     44     void discard(GrRenderTarget*) override;
     45 
     46 protected:
     47     void appendIndicesAndTransforms(const void* indexValues, PathIndexType indexType,
     48                                     const float* transformValues, PathTransformType transformType,
     49                                     int count, char** indicesLocation, float** xformsLocation) {
     50         int indexBytes = GrPathRange::PathIndexSizeInBytes(indexType);
     51         *indicesLocation = (char*) fPathIndexBuffer.alloc(count * indexBytes,
     52                                                           SkChunkAlloc::kThrow_AllocFailType);
     53         SkASSERT(SkIsAlign4((uintptr_t)*indicesLocation));
     54         memcpy(*indicesLocation, reinterpret_cast<const char*>(indexValues), count * indexBytes);
     55 
     56         const int xformBytes = GrPathRendering::PathTransformSize(transformType) * sizeof(float);
     57         *xformsLocation = NULL;
     58 
     59         if (0 != xformBytes) {
     60             *xformsLocation = (float*) fPathTransformBuffer.alloc(count * xformBytes,
     61                                                                SkChunkAlloc::kThrow_AllocFailType);
     62             SkASSERT(SkIsAlign4((uintptr_t)*xformsLocation));
     63             memcpy(*xformsLocation, transformValues, count * xformBytes);
     64         }
     65     }
     66 
     67 private:
     68     friend class GrInOrderCommandBuilder;
     69     friend class GrTargetCommands;
     70 
     71     typedef GrTargetCommands::State State;
     72 
     73     State* allocState(const GrPrimitiveProcessor* primProc = NULL) {
     74         void* allocation = fPipelineBuffer.alloc(sizeof(State), SkChunkAlloc::kThrow_AllocFailType);
     75         return SkNEW_PLACEMENT_ARGS(allocation, State, (primProc));
     76     }
     77 
     78     void unallocState(State* state) {
     79         state->unref();
     80         fPipelineBuffer.unalloc(state);
     81     }
     82 
     83     void onReset() override;
     84     void onFlush() override;
     85 
     86     // overrides from GrDrawTarget
     87     void onDrawBatch(GrBatch*, const PipelineInfo&) override;
     88     void onStencilPath(const GrPipelineBuilder&,
     89                        const GrPathProcessor*,
     90                        const GrPath*,
     91                        const GrScissorState&,
     92                        const GrStencilSettings&) override;
     93     void onDrawPath(const GrPathProcessor*,
     94                     const GrPath*,
     95                     const GrStencilSettings&,
     96                     const PipelineInfo&) override;
     97     void onDrawPaths(const GrPathProcessor*,
     98                      const GrPathRange*,
     99                      const void* indices,
    100                      PathIndexType,
    101                      const float transformValues[],
    102                      PathTransformType,
    103                      int count,
    104                      const GrStencilSettings&,
    105                      const PipelineInfo&) override;
    106     void onClear(const SkIRect* rect,
    107                  GrColor color,
    108                  bool canIgnoreRect,
    109                  GrRenderTarget* renderTarget) override;
    110     void onCopySurface(GrSurface* dst,
    111                        GrSurface* src,
    112                        const SkIRect& srcRect,
    113                        const SkIPoint& dstPoint) override;
    114 
    115     // We lazily record clip changes in order to skip clips that have no effect.
    116     void recordClipIfNecessary();
    117     // Records any trace markers for a command
    118     void recordTraceMarkersIfNecessary(GrTargetCommands::Cmd*);
    119     SkString getCmdString(int index) const {
    120         SkASSERT(index < fGpuCmdMarkers.count());
    121         return fGpuCmdMarkers[index].toString();
    122     }
    123     bool isIssued(uint32_t drawID) override { return drawID != fDrawID; }
    124 
    125     State* SK_WARN_UNUSED_RESULT setupPipelineAndShouldDraw(const GrPrimitiveProcessor*,
    126                                                             const GrDrawTarget::PipelineInfo&);
    127     State* SK_WARN_UNUSED_RESULT setupPipelineAndShouldDraw(GrBatch*,
    128                                                             const GrDrawTarget::PipelineInfo&);
    129 
    130     // TODO: Use a single allocator for commands and records
    131     enum {
    132         kPathIdxBufferMinReserve     = 2 * 64,  // 64 uint16_t's
    133         kPathXformBufferMinReserve   = 2 * 64,  // 64 two-float transforms
    134         kPipelineBufferMinReserve    = 32 * sizeof(State),
    135     };
    136 
    137     // every 100 flushes we should reset our fPipelineBuffer to prevent us from holding at a
    138     // highwater mark
    139     static const int kPipelineBufferHighWaterMark = 100;
    140 
    141     SkAutoTDelete<GrCommandBuilder>     fCommands;
    142     SkTArray<GrTraceMarkerSet, false>   fGpuCmdMarkers;
    143     SkChunkAlloc                        fPathIndexBuffer;
    144     SkChunkAlloc                        fPathTransformBuffer;
    145     SkChunkAlloc                        fPipelineBuffer;
    146     uint32_t                            fDrawID;
    147     SkAutoTUnref<State>                 fPrevState;
    148 
    149     typedef GrClipTarget INHERITED;
    150 };
    151 
    152 #endif
    153