aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar joshualitt <joshualitt@google.com>2015-05-04 07:51:09 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-05-04 07:51:09 -0700
commitedae3096afe674efce917825f8d44726037405eb (patch)
tree69fddf021a1d08e5a8283cd56c7142d970a09973
parent5d6bb6f795143ca360b868560b52165de51fa269 (diff)
Revert of Move state management to GrInOrderDrawBuffer (patchset #4 id:60001 of https://codereview.chromium.org/1120143002/)
Reason for revert: Breaks windows Original issue's description: > Move state management to GrInOrderDrawBuffer > > BUG=skia: > > Committed: https://skia.googlesource.com/skia/+/5d6bb6f795143ca360b868560b52165de51fa269 TBR=bsalomon@google.com,robertphillips@google.com,joshualitt@chromium.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=skia: Review URL: https://codereview.chromium.org/1119353002
-rw-r--r--src/gpu/GrAtlasTextContext.h1
-rw-r--r--src/gpu/GrInOrderDrawBuffer.cpp93
-rw-r--r--src/gpu/GrInOrderDrawBuffer.h24
-rw-r--r--src/gpu/GrTargetCommands.cpp194
-rw-r--r--src/gpu/GrTargetCommands.h162
5 files changed, 245 insertions, 229 deletions
diff --git a/src/gpu/GrAtlasTextContext.h b/src/gpu/GrAtlasTextContext.h
index c6e1d2f0b2..c0b8b00071 100644
--- a/src/gpu/GrAtlasTextContext.h
+++ b/src/gpu/GrAtlasTextContext.h
@@ -61,6 +61,7 @@ private:
* The only thing(aside from a memcopy) required to flush a BitmapTextBlob is to ensure that
* the GrAtlas will not evict anything the Blob needs.
*/
+ // TODO Pack these bytes
struct BitmapTextBlob : public SkRefCnt {
SK_DECLARE_INTERNAL_LLIST_INTERFACE(BitmapTextBlob);
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index 76e085dffa..e298be6c8b 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -17,7 +17,6 @@ GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrContext* context,
, fCommands(context->getGpu(), vertexPool, indexPool)
, fPathIndexBuffer(kPathIdxBufferMinReserve * sizeof(char)/4)
, fPathTransformBuffer(kPathXformBufferMinReserve * sizeof(float)/4)
- , fPipelineBuffer(kPipelineBufferMinReserve)
, fDrawID(0) {
SkASSERT(vertexPool);
@@ -301,12 +300,7 @@ void GrInOrderDrawBuffer::onDrawRect(GrPipelineBuilder* pipelineBuilder,
void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch,
const PipelineInfo& pipelineInfo) {
- State* state = this->setupPipelineAndShouldDraw(batch, pipelineInfo);
- if (!state) {
- return;
- }
-
- GrTargetCommands::Cmd* cmd = fCommands.recordDrawBatch(state, batch);
+ GrTargetCommands::Cmd* cmd = fCommands.recordDrawBatch(this, batch, pipelineInfo);
this->recordTraceMarkersIfNecessary(cmd);
}
@@ -315,7 +309,7 @@ void GrInOrderDrawBuffer::onStencilPath(const GrPipelineBuilder& pipelineBuilder
const GrPath* path,
const GrScissorState& scissorState,
const GrStencilSettings& stencilSettings) {
- GrTargetCommands::Cmd* cmd = fCommands.recordStencilPath(pipelineBuilder,
+ GrTargetCommands::Cmd* cmd = fCommands.recordStencilPath(this, pipelineBuilder,
pathProc, path, scissorState,
stencilSettings);
this->recordTraceMarkersIfNecessary(cmd);
@@ -325,11 +319,9 @@ void GrInOrderDrawBuffer::onDrawPath(const GrPathProcessor* pathProc,
const GrPath* path,
const GrStencilSettings& stencilSettings,
const PipelineInfo& pipelineInfo) {
- State* state = this->setupPipelineAndShouldDraw(pathProc, pipelineInfo);
- if (!state) {
- return;
- }
- GrTargetCommands::Cmd* cmd = fCommands.recordDrawPath(state, pathProc, path, stencilSettings);
+ GrTargetCommands::Cmd* cmd = fCommands.recordDrawPath(this, pathProc,
+ path, stencilSettings,
+ pipelineInfo);
this->recordTraceMarkersIfNecessary(cmd);
}
@@ -342,11 +334,7 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrPathProcessor* pathProc,
int count,
const GrStencilSettings& stencilSettings,
const PipelineInfo& pipelineInfo) {
- State* state = this->setupPipelineAndShouldDraw(pathProc, pipelineInfo);
- if (!state) {
- return;
- }
- GrTargetCommands::Cmd* cmd = fCommands.recordDrawPaths(state, this, pathProc, pathRange,
+ GrTargetCommands::Cmd* cmd = fCommands.recordDrawPaths(this, pathProc, pathRange,
indices, indexType, transformValues,
transformType, count,
stencilSettings, pipelineInfo);
@@ -355,14 +343,16 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrPathProcessor* pathProc,
void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color,
bool canIgnoreRect, GrRenderTarget* renderTarget) {
- GrTargetCommands::Cmd* cmd = fCommands.recordClear(rect, color, canIgnoreRect, renderTarget);
+ GrTargetCommands::Cmd* cmd = fCommands.recordClear(this, rect, color,
+ canIgnoreRect, renderTarget);
this->recordTraceMarkersIfNecessary(cmd);
}
void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect,
bool insideClip,
GrRenderTarget* renderTarget) {
- GrTargetCommands::Cmd* cmd = fCommands.recordClearStencilClip(rect, insideClip, renderTarget);
+ GrTargetCommands::Cmd* cmd = fCommands.recordClearStencilClip(this, rect,
+ insideClip, renderTarget);
this->recordTraceMarkersIfNecessary(cmd);
}
@@ -371,7 +361,7 @@ void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
return;
}
- GrTargetCommands::Cmd* cmd = fCommands.recordDiscard(renderTarget);
+ GrTargetCommands::Cmd* cmd = fCommands.recordDiscard(this, renderTarget);
this->recordTraceMarkersIfNecessary(cmd);
}
@@ -380,15 +370,6 @@ void GrInOrderDrawBuffer::onReset() {
fPathIndexBuffer.rewind();
fPathTransformBuffer.rewind();
fGpuCmdMarkers.reset();
-
- fPrevState.reset(NULL);
- // Note, fPrevState points into fPipelineBuffer's allocation, so we have to reset first.
- // Furthermore, we have to reset fCommands before fPipelineBuffer too.
- if (fDrawID % kPipelineBufferHighWaterMark) {
- fPipelineBuffer.rewind();
- } else {
- fPipelineBuffer.reset();
- }
}
void GrInOrderDrawBuffer::onFlush() {
@@ -419,55 +400,3 @@ void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary(GrTargetCommands::Cmd* c
}
}
}
-
-GrTargetCommands::State*
-GrInOrderDrawBuffer::setupPipelineAndShouldDraw(const GrPrimitiveProcessor* primProc,
- const GrDrawTarget::PipelineInfo& pipelineInfo) {
- State* state = this->allocState();
- this->setupPipeline(pipelineInfo, state->pipelineLocation());
-
- if (state->getPipeline()->mustSkip()) {
- this->unallocState(state);
- return NULL;
- }
-
- state->fPrimitiveProcessor->initBatchTracker(&state->fBatchTracker,
- state->getPipeline()->getInitBatchTracker());
-
- if (fPrevState && fPrevState->fPrimitiveProcessor.get() &&
- fPrevState->fPrimitiveProcessor->canMakeEqual(fPrevState->fBatchTracker,
- *state->fPrimitiveProcessor,
- state->fBatchTracker) &&
- fPrevState->getPipeline()->isEqual(*state->getPipeline())) {
- this->unallocState(state);
- } else {
- fPrevState.reset(state);
- }
-
- fCommands.recordXferBarrierIfNecessary(*fPrevState->getPipeline(), this);
- return fPrevState;
-}
-
-GrTargetCommands::State*
-GrInOrderDrawBuffer::setupPipelineAndShouldDraw(GrBatch* batch,
- const GrDrawTarget::PipelineInfo& pipelineInfo) {
- State* state = this->allocState();
- this->setupPipeline(pipelineInfo, state->pipelineLocation());
-
- if (state->getPipeline()->mustSkip()) {
- this->unallocState(state);
- return NULL;
- }
-
- batch->initBatchTracker(state->getPipeline()->getInitBatchTracker());
-
- if (fPrevState && !fPrevState->fPrimitiveProcessor.get() &&
- fPrevState->getPipeline()->isEqual(*state->getPipeline())) {
- this->unallocState(state);
- } else {
- fPrevState.reset(state);
- }
-
- fCommands.recordXferBarrierIfNecessary(*fPrevState->getPipeline(), this);
- return fPrevState;
-}
diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h
index b253768f84..ce82c889a7 100644
--- a/src/gpu/GrInOrderDrawBuffer.h
+++ b/src/gpu/GrInOrderDrawBuffer.h
@@ -72,17 +72,6 @@ protected:
private:
friend class GrTargetCommands;
- typedef GrTargetCommands::State State;
-
- State* allocState(const GrPrimitiveProcessor* primProc = NULL) {
- void* allocation = fPipelineBuffer.alloc(sizeof(State), SkChunkAlloc::kThrow_AllocFailType);
- return SkNEW_PLACEMENT_ARGS(allocation, State, (primProc));
- }
-
- void unallocState(State* state) {
- state->unref();
- fPipelineBuffer.unalloc(state);
- }
void onReset() override;
void onFlush() override;
@@ -95,6 +84,7 @@ private:
const SkRect& rect,
const SkRect* localRect,
const SkMatrix* localMatrix) override;
+
void onStencilPath(const GrPipelineBuilder&,
const GrPathProcessor*,
const GrPath*,
@@ -132,29 +122,17 @@ private:
}
bool isIssued(uint32_t drawID) override { return drawID != fDrawID; }
- State* SK_WARN_UNUSED_RESULT setupPipelineAndShouldDraw(const GrPrimitiveProcessor*,
- const GrDrawTarget::PipelineInfo&);
- State* SK_WARN_UNUSED_RESULT setupPipelineAndShouldDraw(GrBatch*,
- const GrDrawTarget::PipelineInfo&);
-
// TODO: Use a single allocator for commands and records
enum {
kPathIdxBufferMinReserve = 2 * 64, // 64 uint16_t's
kPathXformBufferMinReserve = 2 * 64, // 64 two-float transforms
- kPipelineBufferMinReserve = 32 * sizeof(State),
};
- // every 100 flushes we should reset our fPipelineBuffer to prevent us from holding at a
- // highwater mark
- static const int kPipelineBufferHighWaterMark = 100;
-
GrTargetCommands fCommands;
SkTArray<GrTraceMarkerSet, false> fGpuCmdMarkers;
SkChunkAlloc fPathIndexBuffer;
SkChunkAlloc fPathTransformBuffer;
- SkChunkAlloc fPipelineBuffer;
uint32_t fDrawID;
- SkAutoTUnref<State> fPrevState;
typedef GrClipTarget INHERITED;
};
diff --git a/src/gpu/GrTargetCommands.cpp b/src/gpu/GrTargetCommands.cpp
index d68a24292e..a6d3148141 100644
--- a/src/gpu/GrTargetCommands.cpp
+++ b/src/gpu/GrTargetCommands.cpp
@@ -26,19 +26,27 @@ static bool path_fill_type_is_winding(const GrStencilSettings& pathStencilSettin
return isWinding;
}
-GrTargetCommands::Cmd* GrTargetCommands::recordDrawBatch(State* state, GrBatch* batch) {
+GrTargetCommands::Cmd* GrTargetCommands::recordDrawBatch(
+ GrInOrderDrawBuffer* iodb,
+ GrBatch* batch,
+ const GrDrawTarget::PipelineInfo& pipelineInfo) {
+ if (!this->setupPipelineAndShouldDraw(iodb, batch, pipelineInfo)) {
+ return NULL;
+ }
+
// Check if there is a Batch Draw we can batch with
- if (!fCmdBuffer.empty() && Cmd::kDrawBatch_CmdType == fCmdBuffer.back().type()) {
+ if (Cmd::kDrawBatch_CmdType == fCmdBuffer.back().type()) {
DrawBatch* previous = static_cast<DrawBatch*>(&fCmdBuffer.back());
- if (previous->fState == state && previous->fBatch->combineIfPossible(batch)) {
+ if (previous->fBatch->combineIfPossible(batch)) {
return NULL;
}
}
- return GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (state, batch, &fBatchTarget));
+ return GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch, &fBatchTarget));
}
GrTargetCommands::Cmd* GrTargetCommands::recordStencilPath(
+ GrInOrderDrawBuffer* iodb,
const GrPipelineBuilder& pipelineBuilder,
const GrPathProcessor* pathProc,
const GrPath* path,
@@ -55,17 +63,21 @@ GrTargetCommands::Cmd* GrTargetCommands::recordStencilPath(
}
GrTargetCommands::Cmd* GrTargetCommands::recordDrawPath(
- State* state,
+ GrInOrderDrawBuffer* iodb,
const GrPathProcessor* pathProc,
const GrPath* path,
- const GrStencilSettings& stencilSettings) {
- DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (state, path));
+ const GrStencilSettings& stencilSettings,
+ const GrDrawTarget::PipelineInfo& pipelineInfo) {
+ // TODO: Only compare the subset of GrPipelineBuilder relevant to path covering?
+ if (!this->setupPipelineAndShouldDraw(iodb, pathProc, pipelineInfo)) {
+ return NULL;
+ }
+ DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path));
dp->fStencilSettings = stencilSettings;
return dp;
}
GrTargetCommands::Cmd* GrTargetCommands::recordDrawPaths(
- State* state,
GrInOrderDrawBuffer* iodb,
const GrPathProcessor* pathProc,
const GrPathRange* pathRange,
@@ -80,6 +92,10 @@ GrTargetCommands::Cmd* GrTargetCommands::recordDrawPaths(
SkASSERT(indexValues);
SkASSERT(transformValues);
+ if (!this->setupPipelineAndShouldDraw(iodb, pathProc, pipelineInfo)) {
+ return NULL;
+ }
+
char* savedIndices;
float* savedTransforms;
@@ -87,7 +103,7 @@ GrTargetCommands::Cmd* GrTargetCommands::recordDrawPaths(
transformValues, transformType,
count, &savedIndices, &savedTransforms);
- if (!fCmdBuffer.empty() && Cmd::kDrawPaths_CmdType == fCmdBuffer.back().type()) {
+ if (Cmd::kDrawPaths_CmdType == fCmdBuffer.back().type()) {
// The previous command was also DrawPaths. Try to collapse this call into the one
// before. Note that stenciling all the paths at once, then covering, may not be
// equivalent to two separate draw calls if there is overlap. Blending won't work,
@@ -101,8 +117,7 @@ GrTargetCommands::Cmd* GrTargetCommands::recordDrawPaths(
transformType == previous->fTransformType &&
stencilSettings == previous->fStencilSettings &&
path_fill_type_is_winding(stencilSettings) &&
- !pipelineInfo.willBlendWithDst(pathProc) &&
- previous->fState == state) {
+ !pipelineInfo.willBlendWithDst(pathProc)) {
const int indexBytes = GrPathRange::PathIndexSizeInBytes(indexType);
const int xformSize = GrPathRendering::PathTransformSize(transformType);
if (&previous->fIndices[previous->fCount*indexBytes] == savedIndices &&
@@ -115,7 +130,7 @@ GrTargetCommands::Cmd* GrTargetCommands::recordDrawPaths(
}
}
- DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (state, pathRange));
+ DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange));
dp->fIndices = savedIndices;
dp->fIndexType = indexType;
dp->fTransforms = savedTransforms;
@@ -125,7 +140,8 @@ GrTargetCommands::Cmd* GrTargetCommands::recordDrawPaths(
return dp;
}
-GrTargetCommands::Cmd* GrTargetCommands::recordClear(const SkIRect* rect,
+GrTargetCommands::Cmd* GrTargetCommands::recordClear(GrInOrderDrawBuffer* iodb,
+ const SkIRect* rect,
GrColor color,
bool canIgnoreRect,
GrRenderTarget* renderTarget) {
@@ -147,7 +163,8 @@ GrTargetCommands::Cmd* GrTargetCommands::recordClear(const SkIRect* rect,
return clr;
}
-GrTargetCommands::Cmd* GrTargetCommands::recordClearStencilClip(const SkIRect& rect,
+GrTargetCommands::Cmd* GrTargetCommands::recordClearStencilClip(GrInOrderDrawBuffer* iodb,
+ const SkIRect& rect,
bool insideClip,
GrRenderTarget* renderTarget) {
SkASSERT(renderTarget);
@@ -158,7 +175,8 @@ GrTargetCommands::Cmd* GrTargetCommands::recordClearStencilClip(const SkIRect& r
return clr;
}
-GrTargetCommands::Cmd* GrTargetCommands::recordDiscard(GrRenderTarget* renderTarget) {
+GrTargetCommands::Cmd* GrTargetCommands::recordDiscard(GrInOrderDrawBuffer* iodb,
+ GrRenderTarget* renderTarget) {
SkASSERT(renderTarget);
Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
@@ -168,6 +186,7 @@ GrTargetCommands::Cmd* GrTargetCommands::recordDiscard(GrRenderTarget* renderTar
void GrTargetCommands::reset() {
fCmdBuffer.reset();
+ fPrevState = NULL;
}
void GrTargetCommands::flush(GrInOrderDrawBuffer* iodb) {
@@ -175,6 +194,10 @@ void GrTargetCommands::flush(GrInOrderDrawBuffer* iodb) {
return;
}
+ // Updated every time we find a set state cmd to reflect the current state in the playback
+ // stream.
+ SetState* currentState = NULL;
+
GrGpu* gpu = iodb->getGpu();
// Loop over all batches and generate geometry
@@ -183,8 +206,13 @@ void GrTargetCommands::flush(GrInOrderDrawBuffer* iodb) {
if (Cmd::kDrawBatch_CmdType == genIter->type()) {
DrawBatch* db = reinterpret_cast<DrawBatch*>(genIter.get());
fBatchTarget.resetNumberOfDraws();
- db->fBatch->generateGeometry(&fBatchTarget, db->fState->getPipeline());
+ db->execute(NULL, currentState);
db->fBatch->setNumberOfDraws(fBatchTarget.numberOfDraws());
+ } else if (Cmd::kSetState_CmdType == genIter->type()) {
+ SetState* ss = reinterpret_cast<SetState*>(genIter.get());
+
+ ss->execute(gpu, currentState);
+ currentState = ss;
}
}
@@ -203,7 +231,29 @@ void GrTargetCommands::flush(GrInOrderDrawBuffer* iodb) {
gpu->addGpuTraceMarker(&newMarker);
}
- iter->execute(gpu);
+ if (Cmd::kDrawBatch_CmdType == iter->type()) {
+ DrawBatch* db = reinterpret_cast<DrawBatch*>(iter.get());
+ fBatchTarget.flushNext(db->fBatch->numberOfDraws());
+
+ if (iter->isTraced()) {
+ gpu->removeGpuTraceMarker(&newMarker);
+ }
+ continue;
+ }
+
+ if (Cmd::kSetState_CmdType == iter->type()) {
+ // TODO this is just until NVPR is in batch
+ SetState* ss = reinterpret_cast<SetState*>(iter.get());
+
+ if (ss->fPrimitiveProcessor) {
+ ss->execute(gpu, currentState);
+ }
+ currentState = ss;
+
+ } else {
+ iter->execute(gpu, currentState);
+ }
+
if (iter->isTraced()) {
gpu->removeGpuTraceMarker(&newMarker);
}
@@ -212,7 +262,7 @@ void GrTargetCommands::flush(GrInOrderDrawBuffer* iodb) {
fBatchTarget.postFlush();
}
-void GrTargetCommands::StencilPath::execute(GrGpu* gpu) {
+void GrTargetCommands::StencilPath::execute(GrGpu* gpu, const SetState*) {
GrGpu::StencilPathState state;
state.fRenderTarget = fRenderTarget.get();
state.fScissor = &fScissor;
@@ -223,36 +273,37 @@ void GrTargetCommands::StencilPath::execute(GrGpu* gpu) {
gpu->stencilPath(this->path(), state);
}
-void GrTargetCommands::DrawPath::execute(GrGpu* gpu) {
- if (!fState->fCompiled) {
- gpu->buildProgramDesc(&fState->fDesc, *fState->fPrimitiveProcessor, *fState->getPipeline(),
- fState->fBatchTracker);
- fState->fCompiled = true;
- }
- DrawArgs args(fState->fPrimitiveProcessor.get(), fState->getPipeline(),
- &fState->fDesc, &fState->fBatchTracker);
+void GrTargetCommands::DrawPath::execute(GrGpu* gpu, const SetState* state) {
+ SkASSERT(state);
+ DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
+ &state->fBatchTracker);
gpu->drawPath(args, this->path(), fStencilSettings);
}
-void GrTargetCommands::DrawPaths::execute(GrGpu* gpu) {
- if (!fState->fCompiled) {
- gpu->buildProgramDesc(&fState->fDesc, *fState->fPrimitiveProcessor, *fState->getPipeline(),
- fState->fBatchTracker);
- fState->fCompiled = true;
- }
- DrawArgs args(fState->fPrimitiveProcessor.get(), fState->getPipeline(),
- &fState->fDesc, &fState->fBatchTracker);
+void GrTargetCommands::DrawPaths::execute(GrGpu* gpu, const SetState* state) {
+ SkASSERT(state);
+ DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
+ &state->fBatchTracker);
gpu->drawPaths(args, this->pathRange(),
fIndices, fIndexType,
fTransforms, fTransformType,
fCount, fStencilSettings);
}
-void GrTargetCommands::DrawBatch::execute(GrGpu*) {
- fBatchTarget->flushNext(fBatch->numberOfDraws());
+void GrTargetCommands::DrawBatch::execute(GrGpu*, const SetState* state) {
+ SkASSERT(state);
+ fBatch->generateGeometry(fBatchTarget, state->getPipeline());
+}
+
+void GrTargetCommands::SetState::execute(GrGpu* gpu, const SetState*) {
+ // TODO sometimes we have a prim proc, othertimes we have a GrBatch. Eventually we
+ // will only have GrBatch and we can delete this
+ if (fPrimitiveProcessor) {
+ gpu->buildProgramDesc(&fDesc, *fPrimitiveProcessor, *getPipeline(), fBatchTracker);
+ }
}
-void GrTargetCommands::Clear::execute(GrGpu* gpu) {
+void GrTargetCommands::Clear::execute(GrGpu* gpu, const SetState*) {
if (GrColor_ILLEGAL == fColor) {
gpu->discard(this->renderTarget());
} else {
@@ -260,15 +311,15 @@ void GrTargetCommands::Clear::execute(GrGpu* gpu) {
}
}
-void GrTargetCommands::ClearStencilClip::execute(GrGpu* gpu) {
+void GrTargetCommands::ClearStencilClip::execute(GrGpu* gpu, const SetState*) {
gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget());
}
-void GrTargetCommands::CopySurface::execute(GrGpu* gpu) {
+void GrTargetCommands::CopySurface::execute(GrGpu* gpu, const SetState*) {
gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint);
}
-void GrTargetCommands::XferBarrier::execute(GrGpu* gpu) {
+void GrTargetCommands::XferBarrier::execute(GrGpu* gpu, const SetState* state) {
gpu->xferBarrier(fBarrierType);
}
@@ -282,10 +333,65 @@ GrTargetCommands::Cmd* GrTargetCommands::recordCopySurface(GrSurface* dst,
return cs;
}
-void GrTargetCommands::recordXferBarrierIfNecessary(const GrPipeline& pipeline,
- GrInOrderDrawBuffer* iodb) {
- const GrXferProcessor& xp = *pipeline.getXferProcessor();
- GrRenderTarget* rt = pipeline.getRenderTarget();
+bool GrTargetCommands::setupPipelineAndShouldDraw(GrInOrderDrawBuffer* iodb,
+ const GrPrimitiveProcessor* primProc,
+ const GrDrawTarget::PipelineInfo& pipelineInfo) {
+ SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (primProc));
+ iodb->setupPipeline(pipelineInfo, ss->pipelineLocation());
+
+ if (ss->getPipeline()->mustSkip()) {
+ fCmdBuffer.pop_back();
+ return false;
+ }
+
+ ss->fPrimitiveProcessor->initBatchTracker(&ss->fBatchTracker,
+ ss->getPipeline()->getInitBatchTracker());
+
+ if (fPrevState && fPrevState->fPrimitiveProcessor.get() &&
+ fPrevState->fPrimitiveProcessor->canMakeEqual(fPrevState->fBatchTracker,
+ *ss->fPrimitiveProcessor,
+ ss->fBatchTracker) &&
+ fPrevState->getPipeline()->isEqual(*ss->getPipeline())) {
+ fCmdBuffer.pop_back();
+ } else {
+ fPrevState = ss;
+ iodb->recordTraceMarkersIfNecessary(ss);
+ }
+
+ this->recordXferBarrierIfNecessary(iodb, pipelineInfo);
+ return true;
+}
+
+bool GrTargetCommands::setupPipelineAndShouldDraw(GrInOrderDrawBuffer* iodb,
+ GrBatch* batch,
+ const GrDrawTarget::PipelineInfo& pipelineInfo) {
+ SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, ());
+ iodb->setupPipeline(pipelineInfo, ss->pipelineLocation());
+
+ if (ss->getPipeline()->mustSkip()) {
+ fCmdBuffer.pop_back();
+ return false;
+ }
+
+ batch->initBatchTracker(ss->getPipeline()->getInitBatchTracker());
+
+ if (fPrevState && !fPrevState->fPrimitiveProcessor.get() &&
+ fPrevState->getPipeline()->isEqual(*ss->getPipeline())) {
+ fCmdBuffer.pop_back();
+ } else {
+ fPrevState = ss;
+ iodb->recordTraceMarkersIfNecessary(ss);
+ }
+
+ this->recordXferBarrierIfNecessary(iodb, pipelineInfo);
+ return true;
+}
+
+void GrTargetCommands::recordXferBarrierIfNecessary(GrInOrderDrawBuffer* iodb,
+ const GrDrawTarget::PipelineInfo& info) {
+ SkASSERT(fPrevState);
+ const GrXferProcessor& xp = *fPrevState->getXferProcessor();
+ GrRenderTarget* rt = fPrevState->getRenderTarget();
GrXferBarrierType barrierType;
if (!xp.willNeedXferBarrier(rt, *iodb->caps(), &barrierType)) {
diff --git a/src/gpu/GrTargetCommands.h b/src/gpu/GrTargetCommands.h
index 8c0a3fd0ca..f9259c72b3 100644
--- a/src/gpu/GrTargetCommands.h
+++ b/src/gpu/GrTargetCommands.h
@@ -24,7 +24,6 @@ class GrVertexBufferAllocPool;
class GrIndexBufferAllocPool;
class GrTargetCommands : ::SkNoncopyable {
- struct State;
struct SetState;
public:
@@ -32,6 +31,7 @@ public:
GrVertexBufferAllocPool* vertexPool,
GrIndexBufferAllocPool* indexPool)
: fCmdBuffer(kCmdBufferInitialSizeInBytes)
+ , fPrevState(NULL)
, fBatchTarget(gpu, vertexPool, indexPool) {
}
@@ -51,7 +51,7 @@ public:
Cmd(CmdType type) : fMarkerID(-1), fType(type) {}
virtual ~Cmd() {}
- virtual void execute(GrGpu*) = 0;
+ virtual void execute(GrGpu*, const SetState*) = 0;
CmdType type() const { return fType; }
@@ -68,23 +68,32 @@ public:
void reset();
void flush(GrInOrderDrawBuffer*);
- Cmd* recordClearStencilClip(const SkIRect& rect,
+ Cmd* recordClearStencilClip(GrInOrderDrawBuffer*,
+ const SkIRect& rect,
bool insideClip,
GrRenderTarget* renderTarget);
- Cmd* recordDiscard(GrRenderTarget*);
- Cmd* recordDrawBatch(State*, GrBatch*);
- Cmd* recordStencilPath(const GrPipelineBuilder&,
+ Cmd* recordDiscard(GrInOrderDrawBuffer*, GrRenderTarget*);
+
+ Cmd* recordDraw(GrInOrderDrawBuffer*,
+ const GrGeometryProcessor*,
+ const GrDrawTarget::DrawInfo&,
+ const GrDrawTarget::PipelineInfo&);
+ Cmd* recordDrawBatch(GrInOrderDrawBuffer*,
+ GrBatch*,
+ const GrDrawTarget::PipelineInfo&);
+ Cmd* recordStencilPath(GrInOrderDrawBuffer*,
+ const GrPipelineBuilder&,
const GrPathProcessor*,
const GrPath*,
const GrScissorState&,
const GrStencilSettings&);
- Cmd* recordDrawPath(State*,
+ Cmd* recordDrawPath(GrInOrderDrawBuffer*,
const GrPathProcessor*,
const GrPath*,
- const GrStencilSettings&);
- Cmd* recordDrawPaths(State*,
- GrInOrderDrawBuffer*,
+ const GrStencilSettings&,
+ const GrDrawTarget::PipelineInfo&);
+ Cmd* recordDrawPaths(GrInOrderDrawBuffer*,
const GrPathProcessor*,
const GrPathRange*,
const void*,
@@ -94,7 +103,8 @@ public:
int,
const GrStencilSettings&,
const GrDrawTarget::PipelineInfo&);
- Cmd* recordClear(const SkIRect* rect,
+ Cmd* recordClear(GrInOrderDrawBuffer*,
+ const SkIRect* rect,
GrColor,
bool canIgnoreRect,
GrRenderTarget*);
@@ -108,51 +118,18 @@ private:
typedef GrGpu::DrawArgs DrawArgs;
- void recordXferBarrierIfNecessary(const GrPipeline&, GrInOrderDrawBuffer*);
-
- // TODO: This can be just a pipeline once paths are in batch, and it should live elsewhere
- struct State : public SkRefCnt {
- // TODO get rid of the prim proc parameter when we use batch everywhere
- State(const GrPrimitiveProcessor* primProc = NULL)
- : fPrimitiveProcessor(primProc)
- , fCompiled(false) {}
-
- ~State() { reinterpret_cast<GrPipeline*>(fPipeline.get())->~GrPipeline(); }
-
- // This function is only for getting the location in memory where we will create our
- // pipeline object.
- GrPipeline* pipelineLocation() { return reinterpret_cast<GrPipeline*>(fPipeline.get()); }
-
- const GrPipeline* getPipeline() const {
- return reinterpret_cast<const GrPipeline*>(fPipeline.get());
- }
- GrRenderTarget* getRenderTarget() const {
- return this->getPipeline()->getRenderTarget();
- }
- const GrXferProcessor* getXferProcessor() const {
- return this->getPipeline()->getXferProcessor();
- }
-
- void operator delete(void* p) {
- //SkDebugf("destruction\n");
- }
- void* operator new(size_t) {
- SkFAIL("All States are created by placement new.");
- return sk_malloc_throw(0);
- }
+ // Attempts to concat instances from info onto the previous draw. info must represent an
+ // instanced draw. The caller must have already recorded a new draw state and clip if necessary.
+ int concatInstancedDraw(GrInOrderDrawBuffer*, const GrDrawTarget::DrawInfo&);
- void* operator new(size_t, void* p) { return p; }
- void operator delete(void* target, void* placement) {
- ::operator delete(target, placement);
- }
+ bool SK_WARN_UNUSED_RESULT setupPipelineAndShouldDraw(GrInOrderDrawBuffer*,
+ const GrPrimitiveProcessor*,
+ const GrDrawTarget::PipelineInfo&);
+ bool SK_WARN_UNUSED_RESULT setupPipelineAndShouldDraw(GrInOrderDrawBuffer*,
+ GrBatch*,
+ const GrDrawTarget::PipelineInfo&);
- typedef GrPendingProgramElement<const GrPrimitiveProcessor> ProgramPrimitiveProcessor;
- ProgramPrimitiveProcessor fPrimitiveProcessor;
- SkAlignedSStorage<sizeof(GrPipeline)> fPipeline;
- GrProgramDesc fDesc;
- GrBatchTracker fBatchTracker;
- bool fCompiled;
- };
+ void recordXferBarrierIfNecessary(GrInOrderDrawBuffer*, const GrDrawTarget::PipelineInfo&);
struct StencilPath : public Cmd {
StencilPath(const GrPath* path, GrRenderTarget* rt)
@@ -162,7 +139,7 @@ private:
const GrPath* path() const { return fPath.get(); }
- void execute(GrGpu*) override;
+ void execute(GrGpu*, const SetState*) override;
SkMatrix fViewMatrix;
bool fUseHWAA;
@@ -174,32 +151,25 @@ private:
};
struct DrawPath : public Cmd {
- DrawPath(State* state, const GrPath* path)
- : Cmd(kDrawPath_CmdType)
- , fState(SkRef(state))
- , fPath(path) {}
+ DrawPath(const GrPath* path) : Cmd(kDrawPath_CmdType), fPath(path) {}
const GrPath* path() const { return fPath.get(); }
- void execute(GrGpu*) override;
+ void execute(GrGpu*, const SetState*) override;
- SkAutoTUnref<State> fState;
GrStencilSettings fStencilSettings;
+
private:
GrPendingIOResource<const GrPath, kRead_GrIOType> fPath;
};
struct DrawPaths : public Cmd {
- DrawPaths(State* state, const GrPathRange* pathRange)
- : Cmd(kDrawPaths_CmdType)
- , fState(SkRef(state))
- , fPathRange(pathRange) {}
+ DrawPaths(const GrPathRange* pathRange) : Cmd(kDrawPaths_CmdType), fPathRange(pathRange) {}
const GrPathRange* pathRange() const { return fPathRange.get(); }
- void execute(GrGpu*) override;
+ void execute(GrGpu*, const SetState*) override;
- SkAutoTUnref<State> fState;
char* fIndices;
GrDrawTarget::PathIndexType fIndexType;
float* fTransforms;
@@ -217,7 +187,7 @@ private:
GrRenderTarget* renderTarget() const { return fRenderTarget.get(); }
- void execute(GrGpu*) override;
+ void execute(GrGpu*, const SetState*) override;
SkIRect fRect;
GrColor fColor;
@@ -233,7 +203,7 @@ private:
GrRenderTarget* renderTarget() const { return fRenderTarget.get(); }
- void execute(GrGpu*) override;
+ void execute(GrGpu*, const SetState*) override;
SkIRect fRect;
bool fInsideClip;
@@ -252,7 +222,7 @@ private:
GrSurface* dst() const { return fDst.get(); }
GrSurface* src() const { return fSrc.get(); }
- void execute(GrGpu*) override;
+ void execute(GrGpu*, const SetState*) override;
SkIPoint fDstPoint;
SkIRect fSrcRect;
@@ -262,18 +232,49 @@ private:
GrPendingIOResource<GrSurface, kRead_GrIOType> fSrc;
};
+ // TODO: rename to SetPipeline once pp, batch tracker, and desc are removed
+ struct SetState : public Cmd {
+ // TODO get rid of the prim proc parameter when we use batch everywhere
+ SetState(const GrPrimitiveProcessor* primProc = NULL)
+ : Cmd(kSetState_CmdType)
+ , fPrimitiveProcessor(primProc) {}
+
+ ~SetState() { reinterpret_cast<GrPipeline*>(fPipeline.get())->~GrPipeline(); }
+
+ // This function is only for getting the location in memory where we will create our
+ // pipeline object.
+ GrPipeline* pipelineLocation() { return reinterpret_cast<GrPipeline*>(fPipeline.get()); }
+
+ const GrPipeline* getPipeline() const {
+ return reinterpret_cast<const GrPipeline*>(fPipeline.get());
+ }
+ GrRenderTarget* getRenderTarget() const {
+ return this->getPipeline()->getRenderTarget();
+ }
+ const GrXferProcessor* getXferProcessor() const {
+ return this->getPipeline()->getXferProcessor();
+ }
+
+ void execute(GrGpu*, const SetState*) override;
+
+ typedef GrPendingProgramElement<const GrPrimitiveProcessor> ProgramPrimitiveProcessor;
+ ProgramPrimitiveProcessor fPrimitiveProcessor;
+ SkAlignedSStorage<sizeof(GrPipeline)> fPipeline;
+ GrProgramDesc fDesc;
+ GrBatchTracker fBatchTracker;
+ };
+
struct DrawBatch : public Cmd {
- DrawBatch(State* state, GrBatch* batch, GrBatchTarget* batchTarget)
+ DrawBatch(GrBatch* batch, GrBatchTarget* batchTarget)
: Cmd(kDrawBatch_CmdType)
- , fState(SkRef(state))
, fBatch(SkRef(batch))
, fBatchTarget(batchTarget) {
SkASSERT(!batch->isUsed());
}
- void execute(GrGpu*) override;
+ void execute(GrGpu*, const SetState*) override;
- SkAutoTUnref<State> fState;
+ // TODO it wouldn't be too hard to let batches allocate in the cmd buffer
SkAutoTUnref<GrBatch> fBatch;
private:
@@ -283,18 +284,19 @@ private:
struct XferBarrier : public Cmd {
XferBarrier() : Cmd(kXferBarrier_CmdType) {}
- void execute(GrGpu*) override;
+ void execute(GrGpu*, const SetState*) override;
GrXferBarrierType fBarrierType;
};
- static const int kCmdBufferInitialSizeInBytes = 8 * 1024;
+ static const int kCmdBufferInitialSizeInBytes = 8 * 1024;
- typedef void* TCmdAlign; // This wouldn't be enough align if a command used long double.
- typedef GrTRecorder<Cmd, TCmdAlign> CmdBuffer;
+ typedef void* TCmdAlign; // This wouldn't be enough align if a command used long double.
+ typedef GrTRecorder<Cmd, TCmdAlign> CmdBuffer;
- CmdBuffer fCmdBuffer;
- GrBatchTarget fBatchTarget;
+ CmdBuffer fCmdBuffer;
+ SetState* fPrevState;
+ GrBatchTarget fBatchTarget;
};
#endif