From e46760e8b2b2fc4a11a43a3b7cc9da7166c83c46 Mon Sep 17 00:00:00 2001 From: joshualitt Date: Tue, 5 May 2015 08:41:50 -0700 Subject: [PATCH] Create GrCommandBuilder BUG=skia: Review URL: https://codereview.chromium.org/1113313003 --- gyp/gpu.gypi | 2 + src/gpu/GrCommandBuilder.cpp | 197 ++++++++++++++++++++++++++++++++ src/gpu/GrCommandBuilder.h | 85 ++++++++++++++ src/gpu/GrDrawTarget.h | 1 + src/gpu/GrInOrderDrawBuffer.cpp | 38 +++--- src/gpu/GrInOrderDrawBuffer.h | 5 +- src/gpu/GrTargetCommands.cpp | 184 ----------------------------- src/gpu/GrTargetCommands.h | 44 +------ 8 files changed, 313 insertions(+), 243 deletions(-) create mode 100644 src/gpu/GrCommandBuilder.cpp create mode 100644 src/gpu/GrCommandBuilder.h diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi index 3944a0355e..1b9246ec55 100644 --- a/gyp/gpu.gypi +++ b/gyp/gpu.gypi @@ -86,6 +86,8 @@ '<(skia_src_path)/gpu/GrClipMaskManager.h', '<(skia_src_path)/gpu/GrClipMaskManager.cpp', '<(skia_src_path)/gpu/GrContext.cpp', + '<(skia_src_path)/gpu/GrCommandBuilder.h', + '<(skia_src_path)/gpu/GrCommandBuilder.cpp', '<(skia_src_path)/gpu/GrCoordTransform.cpp', '<(skia_src_path)/gpu/GrDashLinePathRenderer.cpp', '<(skia_src_path)/gpu/GrDashLinePathRenderer.h', diff --git a/src/gpu/GrCommandBuilder.cpp b/src/gpu/GrCommandBuilder.cpp new file mode 100644 index 0000000000..aafc3455b2 --- /dev/null +++ b/src/gpu/GrCommandBuilder.cpp @@ -0,0 +1,197 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "GrCommandBuilder.h" + +#include "GrColor.h" +#include "GrInOrderDrawBuffer.h" +#include "GrTemplates.h" +#include "SkPoint.h" + +static bool path_fill_type_is_winding(const GrStencilSettings& pathStencilSettings) { + static const GrStencilSettings::Face pathFace = GrStencilSettings::kFront_Face; + bool isWinding = kInvert_StencilOp != pathStencilSettings.passOp(pathFace); + if (isWinding) { + // Double check that it is in fact winding. + SkASSERT(kIncClamp_StencilOp == pathStencilSettings.passOp(pathFace)); + SkASSERT(kIncClamp_StencilOp == pathStencilSettings.failOp(pathFace)); + SkASSERT(0x1 != pathStencilSettings.writeMask(pathFace)); + SkASSERT(!pathStencilSettings.isTwoSided()); + } + return isWinding; +} + +GrTargetCommands::Cmd* GrCommandBuilder::recordDrawBatch(State* state, GrBatch* batch) { + // Check if there is a Batch Draw we can batch with + if (!this->cmdBuffer()->empty() && + Cmd::kDrawBatch_CmdType == this->cmdBuffer()->back().type()) { + DrawBatch* previous = static_cast(&this->cmdBuffer()->back()); + if (previous->fState == state && previous->fBatch->combineIfPossible(batch)) { + return NULL; + } + } + + return GrNEW_APPEND_TO_RECORDER(*this->cmdBuffer(), DrawBatch, (state, batch, + this->batchTarget())); +} + +GrTargetCommands::Cmd* +GrCommandBuilder::recordStencilPath(const GrPipelineBuilder& pipelineBuilder, + const GrPathProcessor* pathProc, + const GrPath* path, + const GrScissorState& scissorState, + const GrStencilSettings& stencilSettings) { + StencilPath* sp = GrNEW_APPEND_TO_RECORDER(*this->cmdBuffer(), StencilPath, + (path, pipelineBuilder.getRenderTarget())); + + sp->fScissor = scissorState; + sp->fUseHWAA = pipelineBuilder.isHWAntialias(); + sp->fViewMatrix = pathProc->viewMatrix(); + sp->fStencil = stencilSettings; + return sp; +} + +GrTargetCommands::Cmd* +GrCommandBuilder::recordDrawPath(State* state, + const GrPathProcessor* pathProc, + const GrPath* path, + const GrStencilSettings& stencilSettings) { + DrawPath* dp = GrNEW_APPEND_TO_RECORDER(*this->cmdBuffer(), DrawPath, (state, path)); + dp->fStencilSettings = stencilSettings; + return dp; +} + +GrTargetCommands::Cmd* +GrCommandBuilder::recordDrawPaths(State* state, + GrInOrderDrawBuffer* iodb, + const GrPathProcessor* pathProc, + const GrPathRange* pathRange, + const void* indexValues, + GrDrawTarget::PathIndexType indexType, + const float transformValues[], + GrDrawTarget::PathTransformType transformType, + int count, + const GrStencilSettings& stencilSettings, + const GrDrawTarget::PipelineInfo& pipelineInfo) { + SkASSERT(pathRange); + SkASSERT(indexValues); + SkASSERT(transformValues); + + char* savedIndices; + float* savedTransforms; + + iodb->appendIndicesAndTransforms(indexValues, indexType, + transformValues, transformType, + count, &savedIndices, &savedTransforms); + + if (!this->cmdBuffer()->empty() && + Cmd::kDrawPaths_CmdType == this->cmdBuffer()->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, + // and the combined calls may also cancel each other's winding numbers in some + // places. For now the winding numbers are only an issue if the fill is even/odd, + // because DrawPaths is currently only used for glyphs, and glyphs in the same + // font tend to all wind in the same direction. + DrawPaths* previous = static_cast(&this->cmdBuffer()->back()); + if (pathRange == previous->pathRange() && + indexType == previous->fIndexType && + transformType == previous->fTransformType && + stencilSettings == previous->fStencilSettings && + path_fill_type_is_winding(stencilSettings) && + !pipelineInfo.willBlendWithDst(pathProc) && + previous->fState == state) { + const int indexBytes = GrPathRange::PathIndexSizeInBytes(indexType); + const int xformSize = GrPathRendering::PathTransformSize(transformType); + if (&previous->fIndices[previous->fCount*indexBytes] == savedIndices && + (0 == xformSize || + &previous->fTransforms[previous->fCount*xformSize] == savedTransforms)) { + // Fold this DrawPaths call into the one previous. + previous->fCount += count; + return NULL; + } + } + } + + DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(*this->cmdBuffer(), DrawPaths, (state, pathRange)); + dp->fIndices = savedIndices; + dp->fIndexType = indexType; + dp->fTransforms = savedTransforms; + dp->fTransformType = transformType; + dp->fCount = count; + dp->fStencilSettings = stencilSettings; + return dp; +} + +GrTargetCommands::Cmd* GrCommandBuilder::recordClear(const SkIRect* rect, + GrColor color, + bool canIgnoreRect, + GrRenderTarget* renderTarget) { + SkASSERT(renderTarget); + + SkIRect r; + if (NULL == rect) { + // We could do something smart and remove previous draws and clears to + // the current render target. If we get that smart we have to make sure + // those draws aren't read before this clear (render-to-texture). + r.setLTRB(0, 0, renderTarget->width(), renderTarget->height()); + rect = &r; + } + Clear* clr = GrNEW_APPEND_TO_RECORDER(*this->cmdBuffer(), Clear, (renderTarget)); + GrColorIsPMAssert(color); + clr->fColor = color; + clr->fRect = *rect; + clr->fCanIgnoreRect = canIgnoreRect; + return clr; +} + +GrTargetCommands::Cmd* GrCommandBuilder::recordClearStencilClip(const SkIRect& rect, + bool insideClip, + GrRenderTarget* renderTarget) { + SkASSERT(renderTarget); + + ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(*this->cmdBuffer(), + ClearStencilClip, + (renderTarget)); + clr->fRect = rect; + clr->fInsideClip = insideClip; + return clr; +} + +GrTargetCommands::Cmd* GrCommandBuilder::recordDiscard(GrRenderTarget* renderTarget) { + SkASSERT(renderTarget); + + Clear* clr = GrNEW_APPEND_TO_RECORDER(*this->cmdBuffer(), Clear, (renderTarget)); + clr->fColor = GrColor_ILLEGAL; + return clr; +} + +GrTargetCommands::Cmd* GrCommandBuilder::recordCopySurface(GrSurface* dst, + GrSurface* src, + const SkIRect& srcRect, + const SkIPoint& dstPoint) { + CopySurface* cs = GrNEW_APPEND_TO_RECORDER(*this->cmdBuffer(), CopySurface, (dst, src)); + cs->fSrcRect = srcRect; + cs->fDstPoint = dstPoint; + return cs; +} + +GrTargetCommands::Cmd* +GrCommandBuilder::recordXferBarrierIfNecessary(const GrPipeline& pipeline, + const GrDrawTargetCaps& caps) { + const GrXferProcessor& xp = *pipeline.getXferProcessor(); + GrRenderTarget* rt = pipeline.getRenderTarget(); + + GrXferBarrierType barrierType; + if (!xp.willNeedXferBarrier(rt, caps, &barrierType)) { + return NULL; + } + + XferBarrier* xb = GrNEW_APPEND_TO_RECORDER(*this->cmdBuffer(), XferBarrier, ()); + xb->fBarrierType = barrierType; + return xb; +} diff --git a/src/gpu/GrCommandBuilder.h b/src/gpu/GrCommandBuilder.h new file mode 100644 index 0000000000..165c2c2035 --- /dev/null +++ b/src/gpu/GrCommandBuilder.h @@ -0,0 +1,85 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrCommandBuilder_DEFINED +#define GrCommandBuilder_DEFINED + +#include "GrTargetCommands.h" + +class GrInOrderDrawBuffer; +class GrVertexBufferAllocPool; +class GrIndexBufferAllocPool; + +class GrCommandBuilder : ::SkNoncopyable { +public: + typedef GrTargetCommands::Cmd Cmd; + typedef GrTargetCommands::State State; + + GrCommandBuilder(GrGpu* gpu, + GrVertexBufferAllocPool* vertexPool, + GrIndexBufferAllocPool* indexPool) + : fCommands(gpu, vertexPool, indexPool) { + } + + virtual ~GrCommandBuilder() {} + + void reset() { fCommands.reset(); } + void flush(GrInOrderDrawBuffer* iodb) { fCommands.flush(iodb); } + + virtual Cmd* recordClearStencilClip(const SkIRect& rect, + bool insideClip, + GrRenderTarget* renderTarget); + virtual Cmd* recordDiscard(GrRenderTarget*); + virtual Cmd* recordDrawBatch(State*, GrBatch*); + virtual Cmd* recordStencilPath(const GrPipelineBuilder&, + const GrPathProcessor*, + const GrPath*, + const GrScissorState&, + const GrStencilSettings&); + virtual Cmd* recordDrawPath(State*, + const GrPathProcessor*, + const GrPath*, + const GrStencilSettings&); + virtual Cmd* recordDrawPaths(State*, + GrInOrderDrawBuffer*, + const GrPathProcessor*, + const GrPathRange*, + const void*, + GrDrawTarget::PathIndexType, + const float transformValues[], + GrDrawTarget::PathTransformType , + int, + const GrStencilSettings&, + const GrDrawTarget::PipelineInfo&); + virtual Cmd* recordClear(const SkIRect* rect, + GrColor, + bool canIgnoreRect, + GrRenderTarget*); + virtual Cmd* recordCopySurface(GrSurface* dst, + GrSurface* src, + const SkIRect& srcRect, + const SkIPoint& dstPoint); + virtual Cmd* recordXferBarrierIfNecessary(const GrPipeline&, const GrDrawTargetCaps&); + +private: + typedef GrTargetCommands::DrawBatch DrawBatch; + typedef GrTargetCommands::StencilPath StencilPath; + typedef GrTargetCommands::DrawPath DrawPath; + typedef GrTargetCommands::DrawPaths DrawPaths; + typedef GrTargetCommands::Clear Clear; + typedef GrTargetCommands::ClearStencilClip ClearStencilClip; + typedef GrTargetCommands::CopySurface CopySurface; + typedef GrTargetCommands::XferBarrier XferBarrier; + + GrTargetCommands::CmdBuffer* cmdBuffer() { return fCommands.cmdBuffer(); } + GrBatchTarget* batchTarget() { return fCommands.batchTarget(); } + + GrTargetCommands fCommands; + +}; + +#endif diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index c584181396..458e6e14a9 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -373,6 +373,7 @@ public: bool programUnitTest(int maxStages); protected: + friend class GrCommandBuilder; // for PipelineInfo friend class GrTargetCommands; // for PipelineInfo GrContext* getContext() { return fContext; } diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp index a766af2c7e..1e8f3ae659 100644 --- a/src/gpu/GrInOrderDrawBuffer.cpp +++ b/src/gpu/GrInOrderDrawBuffer.cpp @@ -14,7 +14,7 @@ GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrContext* context, GrVertexBufferAllocPool* vertexPool, GrIndexBufferAllocPool* indexPool) : INHERITED(context, vertexPool, indexPool) - , fCommands(context->getGpu(), vertexPool, indexPool) + , fCommands(SkNEW_ARGS(GrCommandBuilder, (context->getGpu(), vertexPool, indexPool))) , fPathIndexBuffer(kPathIdxBufferMinReserve * sizeof(char)/4) , fPathTransformBuffer(kPathXformBufferMinReserve * sizeof(float)/4) , fPipelineBuffer(kPipelineBufferMinReserve) @@ -272,7 +272,7 @@ void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch, return; } - GrTargetCommands::Cmd* cmd = fCommands.recordDrawBatch(state, batch); + GrTargetCommands::Cmd* cmd = fCommands->recordDrawBatch(state, batch); this->recordTraceMarkersIfNecessary(cmd); } @@ -281,9 +281,9 @@ void GrInOrderDrawBuffer::onStencilPath(const GrPipelineBuilder& pipelineBuilder const GrPath* path, const GrScissorState& scissorState, const GrStencilSettings& stencilSettings) { - GrTargetCommands::Cmd* cmd = fCommands.recordStencilPath(pipelineBuilder, - pathProc, path, scissorState, - stencilSettings); + GrTargetCommands::Cmd* cmd = fCommands->recordStencilPath(pipelineBuilder, + pathProc, path, scissorState, + stencilSettings); this->recordTraceMarkersIfNecessary(cmd); } @@ -295,7 +295,7 @@ void GrInOrderDrawBuffer::onDrawPath(const GrPathProcessor* pathProc, if (!state) { return; } - GrTargetCommands::Cmd* cmd = fCommands.recordDrawPath(state, pathProc, path, stencilSettings); + GrTargetCommands::Cmd* cmd = fCommands->recordDrawPath(state, pathProc, path, stencilSettings); this->recordTraceMarkersIfNecessary(cmd); } @@ -312,23 +312,23 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrPathProcessor* pathProc, if (!state) { return; } - GrTargetCommands::Cmd* cmd = fCommands.recordDrawPaths(state, this, pathProc, pathRange, - indices, indexType, transformValues, - transformType, count, - stencilSettings, pipelineInfo); + GrTargetCommands::Cmd* cmd = fCommands->recordDrawPaths(state, this, pathProc, pathRange, + indices, indexType, transformValues, + transformType, count, + stencilSettings, pipelineInfo); this->recordTraceMarkersIfNecessary(cmd); } 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(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(rect, insideClip, renderTarget); this->recordTraceMarkersIfNecessary(cmd); } @@ -337,12 +337,12 @@ void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) { return; } - GrTargetCommands::Cmd* cmd = fCommands.recordDiscard(renderTarget); + GrTargetCommands::Cmd* cmd = fCommands->recordDiscard(renderTarget); this->recordTraceMarkersIfNecessary(cmd); } void GrInOrderDrawBuffer::onReset() { - fCommands.reset(); + fCommands->reset(); fPathIndexBuffer.rewind(); fPathTransformBuffer.rewind(); fGpuCmdMarkers.reset(); @@ -358,7 +358,7 @@ void GrInOrderDrawBuffer::onReset() { } void GrInOrderDrawBuffer::onFlush() { - fCommands.flush(this); + fCommands->flush(this); ++fDrawID; } @@ -367,7 +367,7 @@ void GrInOrderDrawBuffer::onCopySurface(GrSurface* dst, const SkIRect& srcRect, const SkIPoint& dstPoint) { SkASSERT(this->getGpu()->canCopySurface(dst, src, srcRect, dstPoint)); - GrTargetCommands::Cmd* cmd = fCommands.recordCopySurface(dst, src, srcRect, dstPoint); + GrTargetCommands::Cmd* cmd = fCommands->recordCopySurface(dst, src, srcRect, dstPoint); this->recordTraceMarkersIfNecessary(cmd); } @@ -410,7 +410,8 @@ GrInOrderDrawBuffer::setupPipelineAndShouldDraw(const GrPrimitiveProcessor* prim fPrevState.reset(state); } - fCommands.recordXferBarrierIfNecessary(*fPrevState->getPipeline(), this); + this->recordTraceMarkersIfNecessary( + fCommands->recordXferBarrierIfNecessary(*fPrevState->getPipeline(), *this->caps())); return fPrevState; } @@ -434,6 +435,7 @@ GrInOrderDrawBuffer::setupPipelineAndShouldDraw(GrBatch* batch, fPrevState.reset(state); } - fCommands.recordXferBarrierIfNecessary(*fPrevState->getPipeline(), this); + this->recordTraceMarkersIfNecessary( + fCommands->recordXferBarrierIfNecessary(*fPrevState->getPipeline(), *this->caps())); return fPrevState; } diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h index b253768f84..264d2a7297 100644 --- a/src/gpu/GrInOrderDrawBuffer.h +++ b/src/gpu/GrInOrderDrawBuffer.h @@ -9,7 +9,7 @@ #define GrInOrderDrawBuffer_DEFINED #include "GrDrawTarget.h" -#include "GrTargetCommands.h" +#include "GrCommandBuilder.h" #include "SkChunkAlloc.h" /** @@ -71,6 +71,7 @@ protected: } private: + friend class GrCommandBuilder; friend class GrTargetCommands; typedef GrTargetCommands::State State; @@ -148,7 +149,7 @@ private: // highwater mark static const int kPipelineBufferHighWaterMark = 100; - GrTargetCommands fCommands; + SkAutoTDelete fCommands; SkTArray fGpuCmdMarkers; SkChunkAlloc fPathIndexBuffer; SkChunkAlloc fPathTransformBuffer; diff --git a/src/gpu/GrTargetCommands.cpp b/src/gpu/GrTargetCommands.cpp index d68a24292e..bf1a7af281 100644 --- a/src/gpu/GrTargetCommands.cpp +++ b/src/gpu/GrTargetCommands.cpp @@ -7,164 +7,7 @@ #include "GrTargetCommands.h" -#include "GrColor.h" -#include "GrDefaultGeoProcFactory.h" #include "GrInOrderDrawBuffer.h" -#include "GrTemplates.h" -#include "SkPoint.h" - -static bool path_fill_type_is_winding(const GrStencilSettings& pathStencilSettings) { - static const GrStencilSettings::Face pathFace = GrStencilSettings::kFront_Face; - bool isWinding = kInvert_StencilOp != pathStencilSettings.passOp(pathFace); - if (isWinding) { - // Double check that it is in fact winding. - SkASSERT(kIncClamp_StencilOp == pathStencilSettings.passOp(pathFace)); - SkASSERT(kIncClamp_StencilOp == pathStencilSettings.failOp(pathFace)); - SkASSERT(0x1 != pathStencilSettings.writeMask(pathFace)); - SkASSERT(!pathStencilSettings.isTwoSided()); - } - return isWinding; -} - -GrTargetCommands::Cmd* GrTargetCommands::recordDrawBatch(State* state, GrBatch* batch) { - // Check if there is a Batch Draw we can batch with - if (!fCmdBuffer.empty() && Cmd::kDrawBatch_CmdType == fCmdBuffer.back().type()) { - DrawBatch* previous = static_cast(&fCmdBuffer.back()); - if (previous->fState == state && previous->fBatch->combineIfPossible(batch)) { - return NULL; - } - } - - return GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (state, batch, &fBatchTarget)); -} - -GrTargetCommands::Cmd* GrTargetCommands::recordStencilPath( - const GrPipelineBuilder& pipelineBuilder, - const GrPathProcessor* pathProc, - const GrPath* path, - const GrScissorState& scissorState, - const GrStencilSettings& stencilSettings) { - StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, - (path, pipelineBuilder.getRenderTarget())); - - sp->fScissor = scissorState; - sp->fUseHWAA = pipelineBuilder.isHWAntialias(); - sp->fViewMatrix = pathProc->viewMatrix(); - sp->fStencil = stencilSettings; - return sp; -} - -GrTargetCommands::Cmd* GrTargetCommands::recordDrawPath( - State* state, - const GrPathProcessor* pathProc, - const GrPath* path, - const GrStencilSettings& stencilSettings) { - DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (state, path)); - dp->fStencilSettings = stencilSettings; - return dp; -} - -GrTargetCommands::Cmd* GrTargetCommands::recordDrawPaths( - State* state, - GrInOrderDrawBuffer* iodb, - const GrPathProcessor* pathProc, - const GrPathRange* pathRange, - const void* indexValues, - GrDrawTarget::PathIndexType indexType, - const float transformValues[], - GrDrawTarget::PathTransformType transformType, - int count, - const GrStencilSettings& stencilSettings, - const GrDrawTarget::PipelineInfo& pipelineInfo) { - SkASSERT(pathRange); - SkASSERT(indexValues); - SkASSERT(transformValues); - - char* savedIndices; - float* savedTransforms; - - iodb->appendIndicesAndTransforms(indexValues, indexType, - transformValues, transformType, - count, &savedIndices, &savedTransforms); - - if (!fCmdBuffer.empty() && 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, - // and the combined calls may also cancel each other's winding numbers in some - // places. For now the winding numbers are only an issue if the fill is even/odd, - // because DrawPaths is currently only used for glyphs, and glyphs in the same - // font tend to all wind in the same direction. - DrawPaths* previous = static_cast(&fCmdBuffer.back()); - if (pathRange == previous->pathRange() && - indexType == previous->fIndexType && - transformType == previous->fTransformType && - stencilSettings == previous->fStencilSettings && - path_fill_type_is_winding(stencilSettings) && - !pipelineInfo.willBlendWithDst(pathProc) && - previous->fState == state) { - const int indexBytes = GrPathRange::PathIndexSizeInBytes(indexType); - const int xformSize = GrPathRendering::PathTransformSize(transformType); - if (&previous->fIndices[previous->fCount*indexBytes] == savedIndices && - (0 == xformSize || - &previous->fTransforms[previous->fCount*xformSize] == savedTransforms)) { - // Fold this DrawPaths call into the one previous. - previous->fCount += count; - return NULL; - } - } - } - - DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (state, pathRange)); - dp->fIndices = savedIndices; - dp->fIndexType = indexType; - dp->fTransforms = savedTransforms; - dp->fTransformType = transformType; - dp->fCount = count; - dp->fStencilSettings = stencilSettings; - return dp; -} - -GrTargetCommands::Cmd* GrTargetCommands::recordClear(const SkIRect* rect, - GrColor color, - bool canIgnoreRect, - GrRenderTarget* renderTarget) { - SkASSERT(renderTarget); - - SkIRect r; - if (NULL == rect) { - // We could do something smart and remove previous draws and clears to - // the current render target. If we get that smart we have to make sure - // those draws aren't read before this clear (render-to-texture). - r.setLTRB(0, 0, renderTarget->width(), renderTarget->height()); - rect = &r; - } - Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget)); - GrColorIsPMAssert(color); - clr->fColor = color; - clr->fRect = *rect; - clr->fCanIgnoreRect = canIgnoreRect; - return clr; -} - -GrTargetCommands::Cmd* GrTargetCommands::recordClearStencilClip(const SkIRect& rect, - bool insideClip, - GrRenderTarget* renderTarget) { - SkASSERT(renderTarget); - - ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilClip, (renderTarget)); - clr->fRect = rect; - clr->fInsideClip = insideClip; - return clr; -} - -GrTargetCommands::Cmd* GrTargetCommands::recordDiscard(GrRenderTarget* renderTarget) { - SkASSERT(renderTarget); - - Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget)); - clr->fColor = GrColor_ILLEGAL; - return clr; -} void GrTargetCommands::reset() { fCmdBuffer.reset(); @@ -271,30 +114,3 @@ void GrTargetCommands::CopySurface::execute(GrGpu* gpu) { void GrTargetCommands::XferBarrier::execute(GrGpu* gpu) { gpu->xferBarrier(fBarrierType); } - -GrTargetCommands::Cmd* GrTargetCommands::recordCopySurface(GrSurface* dst, - GrSurface* src, - const SkIRect& srcRect, - const SkIPoint& dstPoint) { - CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst, src)); - cs->fSrcRect = srcRect; - cs->fDstPoint = dstPoint; - return cs; -} - -void GrTargetCommands::recordXferBarrierIfNecessary(const GrPipeline& pipeline, - GrInOrderDrawBuffer* iodb) { - const GrXferProcessor& xp = *pipeline.getXferProcessor(); - GrRenderTarget* rt = pipeline.getRenderTarget(); - - GrXferBarrierType barrierType; - if (!xp.willNeedXferBarrier(rt, *iodb->caps(), &barrierType)) { - return; - } - - XferBarrier* xb = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, XferBarrier, ()); - xb->fBarrierType = barrierType; - - iodb->recordTraceMarkersIfNecessary(xb); -} - diff --git a/src/gpu/GrTargetCommands.h b/src/gpu/GrTargetCommands.h index 4dfad2f409..aaecac6989 100644 --- a/src/gpu/GrTargetCommands.h +++ b/src/gpu/GrTargetCommands.h @@ -24,9 +24,6 @@ class GrVertexBufferAllocPool; class GrIndexBufferAllocPool; class GrTargetCommands : ::SkNoncopyable { - struct State; - struct SetState; - public: GrTargetCommands(GrGpu* gpu, GrVertexBufferAllocPool* vertexPool, @@ -68,43 +65,9 @@ public: void reset(); void flush(GrInOrderDrawBuffer*); - Cmd* recordClearStencilClip(const SkIRect& rect, - bool insideClip, - GrRenderTarget* renderTarget); - - Cmd* recordDiscard(GrRenderTarget*); - Cmd* recordDrawBatch(State*, GrBatch*); - Cmd* recordStencilPath(const GrPipelineBuilder&, - const GrPathProcessor*, - const GrPath*, - const GrScissorState&, - const GrStencilSettings&); - Cmd* recordDrawPath(State*, - const GrPathProcessor*, - const GrPath*, - const GrStencilSettings&); - Cmd* recordDrawPaths(State*, - GrInOrderDrawBuffer*, - const GrPathProcessor*, - const GrPathRange*, - const void*, - GrDrawTarget::PathIndexType, - const float transformValues[], - GrDrawTarget::PathTransformType , - int, - const GrStencilSettings&, - const GrDrawTarget::PipelineInfo&); - Cmd* recordClear(const SkIRect* rect, - GrColor, - bool canIgnoreRect, - GrRenderTarget*); - Cmd* recordCopySurface(GrSurface* dst, - GrSurface* src, - const SkIRect& srcRect, - const SkIPoint& dstPoint); - private: - friend class GrInOrderDrawBuffer; + friend class GrCommandBuilder; + friend class GrInOrderDrawBuffer; // This goes away when State becomes just a pipeline typedef GrGpu::DrawArgs DrawArgs; @@ -293,6 +256,9 @@ private: typedef void* TCmdAlign; // This wouldn't be enough align if a command used long double. typedef GrTRecorder CmdBuffer; + CmdBuffer* cmdBuffer() { return &fCmdBuffer; } + GrBatchTarget* batchTarget() { return &fBatchTarget; } + CmdBuffer fCmdBuffer; GrBatchTarget fBatchTarget; };