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 #include "GrInOrderDrawBuffer.h"
      9 
     10 GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrContext* context)
     11     : INHERITED(context)
     12     , fCommands(GrCommandBuilder::Create(context->getGpu(), false))
     13     , fPathIndexBuffer(kPathIdxBufferMinReserve * sizeof(char)/4)
     14     , fPathTransformBuffer(kPathXformBufferMinReserve * sizeof(float)/4)
     15     , fPipelineBuffer(kPipelineBufferMinReserve)
     16     , fDrawID(0) {
     17 }
     18 
     19 GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
     20     this->reset();
     21 }
     22 
     23 void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch,
     24                                       const PipelineInfo& pipelineInfo) {
     25     State* state = this->setupPipelineAndShouldDraw(batch, pipelineInfo);
     26     if (!state) {
     27         return;
     28     }
     29 
     30     GrTargetCommands::Cmd* cmd = fCommands->recordDrawBatch(state, batch);
     31     this->recordTraceMarkersIfNecessary(cmd);
     32 }
     33 
     34 void GrInOrderDrawBuffer::onStencilPath(const GrPipelineBuilder& pipelineBuilder,
     35                                         const GrPathProcessor* pathProc,
     36                                         const GrPath* path,
     37                                         const GrScissorState& scissorState,
     38                                         const GrStencilSettings& stencilSettings) {
     39     GrTargetCommands::Cmd* cmd = fCommands->recordStencilPath(pipelineBuilder,
     40                                                               pathProc, path, scissorState,
     41                                                               stencilSettings);
     42     this->recordTraceMarkersIfNecessary(cmd);
     43 }
     44 
     45 void GrInOrderDrawBuffer::onDrawPath(const GrPathProcessor* pathProc,
     46                                      const GrPath* path,
     47                                      const GrStencilSettings& stencilSettings,
     48                                      const PipelineInfo& pipelineInfo) {
     49     State* state = this->setupPipelineAndShouldDraw(pathProc, pipelineInfo);
     50     if (!state) {
     51         return;
     52     }
     53     GrTargetCommands::Cmd* cmd = fCommands->recordDrawPath(state, pathProc, path, stencilSettings);
     54     this->recordTraceMarkersIfNecessary(cmd);
     55 }
     56 
     57 void GrInOrderDrawBuffer::onDrawPaths(const GrPathProcessor* pathProc,
     58                                       const GrPathRange* pathRange,
     59                                       const void* indices,
     60                                       PathIndexType indexType,
     61                                       const float transformValues[],
     62                                       PathTransformType transformType,
     63                                       int count,
     64                                       const GrStencilSettings& stencilSettings,
     65                                       const PipelineInfo& pipelineInfo) {
     66     State* state = this->setupPipelineAndShouldDraw(pathProc, pipelineInfo);
     67     if (!state) {
     68         return;
     69     }
     70     GrTargetCommands::Cmd* cmd = fCommands->recordDrawPaths(state, this, pathProc, pathRange,
     71                                                             indices, indexType, transformValues,
     72                                                             transformType, count,
     73                                                             stencilSettings, pipelineInfo);
     74     this->recordTraceMarkersIfNecessary(cmd);
     75 }
     76 
     77 void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color,
     78                                   bool canIgnoreRect, GrRenderTarget* renderTarget) {
     79     GrTargetCommands::Cmd* cmd = fCommands->recordClear(rect, color, canIgnoreRect, renderTarget);
     80     this->recordTraceMarkersIfNecessary(cmd);
     81 }
     82 
     83 void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect,
     84                                            bool insideClip,
     85                                            GrRenderTarget* renderTarget) {
     86     GrTargetCommands::Cmd* cmd = fCommands->recordClearStencilClip(rect, insideClip, renderTarget);
     87     this->recordTraceMarkersIfNecessary(cmd);
     88 }
     89 
     90 void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
     91     if (!this->caps()->discardRenderTargetSupport()) {
     92         return;
     93     }
     94 
     95     GrTargetCommands::Cmd* cmd = fCommands->recordDiscard(renderTarget);
     96     this->recordTraceMarkersIfNecessary(cmd);
     97 }
     98 
     99 void GrInOrderDrawBuffer::onReset() {
    100     fCommands->reset();
    101     fPathIndexBuffer.rewind();
    102     fPathTransformBuffer.rewind();
    103     fGpuCmdMarkers.reset();
    104 
    105     fPrevState.reset(NULL);
    106     // Note, fPrevState points into fPipelineBuffer's allocation, so we have to reset first.
    107     // Furthermore, we have to reset fCommands before fPipelineBuffer too.
    108     if (fDrawID % kPipelineBufferHighWaterMark) {
    109         fPipelineBuffer.rewind();
    110     } else {
    111         fPipelineBuffer.reset();
    112     }
    113 }
    114 
    115 void GrInOrderDrawBuffer::onFlush() {
    116     fCommands->flush(this);
    117     ++fDrawID;
    118 }
    119 
    120 void GrInOrderDrawBuffer::onCopySurface(GrSurface* dst,
    121                                         GrSurface* src,
    122                                         const SkIRect& srcRect,
    123                                         const SkIPoint& dstPoint) {
    124     SkASSERT(this->getGpu()->canCopySurface(dst, src, srcRect, dstPoint));
    125     GrTargetCommands::Cmd* cmd = fCommands->recordCopySurface(dst, src, srcRect, dstPoint);
    126     this->recordTraceMarkersIfNecessary(cmd);
    127 }
    128 
    129 void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary(GrTargetCommands::Cmd* cmd) {
    130     if (!cmd) {
    131         return;
    132     }
    133     const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers();
    134     if (activeTraceMarkers.count() > 0) {
    135         if (cmd->isTraced()) {
    136             fGpuCmdMarkers[cmd->markerID()].addSet(activeTraceMarkers);
    137         } else {
    138             cmd->setMarkerID(fGpuCmdMarkers.count());
    139             fGpuCmdMarkers.push_back(activeTraceMarkers);
    140         }
    141     }
    142 }
    143 
    144 GrTargetCommands::State*
    145 GrInOrderDrawBuffer::setupPipelineAndShouldDraw(const GrPrimitiveProcessor* primProc,
    146                                                 const GrDrawTarget::PipelineInfo& pipelineInfo) {
    147     State* state = this->allocState(primProc);
    148     this->setupPipeline(pipelineInfo, state->pipelineLocation());
    149 
    150     if (state->getPipeline()->mustSkip()) {
    151         this->unallocState(state);
    152         return NULL;
    153     }
    154 
    155     state->fPrimitiveProcessor->initBatchTracker(&state->fBatchTracker,
    156                                                  state->getPipeline()->getInitBatchTracker());
    157 
    158     if (fPrevState && fPrevState->fPrimitiveProcessor.get() &&
    159         fPrevState->fPrimitiveProcessor->canMakeEqual(fPrevState->fBatchTracker,
    160                                                       *state->fPrimitiveProcessor,
    161                                                       state->fBatchTracker) &&
    162         fPrevState->getPipeline()->isEqual(*state->getPipeline())) {
    163         this->unallocState(state);
    164     } else {
    165         fPrevState.reset(state);
    166     }
    167 
    168     this->recordTraceMarkersIfNecessary(
    169             fCommands->recordXferBarrierIfNecessary(*fPrevState->getPipeline(), *this->caps()));
    170     return fPrevState;
    171 }
    172 
    173 GrTargetCommands::State*
    174 GrInOrderDrawBuffer::setupPipelineAndShouldDraw(GrBatch* batch,
    175                                                 const GrDrawTarget::PipelineInfo& pipelineInfo) {
    176     State* state = this->allocState();
    177     this->setupPipeline(pipelineInfo, state->pipelineLocation());
    178 
    179     if (state->getPipeline()->mustSkip()) {
    180         this->unallocState(state);
    181         return NULL;
    182     }
    183 
    184     batch->initBatchTracker(state->getPipeline()->getInitBatchTracker());
    185 
    186     if (fPrevState && !fPrevState->fPrimitiveProcessor.get() &&
    187         fPrevState->getPipeline()->isEqual(*state->getPipeline())) {
    188         this->unallocState(state);
    189     } else {
    190         fPrevState.reset(state);
    191     }
    192 
    193     this->recordTraceMarkersIfNecessary(
    194             fCommands->recordXferBarrierIfNecessary(*fPrevState->getPipeline(), *this->caps()));
    195     return fPrevState;
    196 }
    197