diff options
-rw-r--r-- | gyp/gpu.gypi | 2 | ||||
-rw-r--r-- | src/gpu/GrCommandBuilder.cpp | 120 | ||||
-rw-r--r-- | src/gpu/GrCommandBuilder.h | 11 | ||||
-rw-r--r-- | src/gpu/GrDrawTarget.h | 1 | ||||
-rw-r--r-- | src/gpu/GrInOrderCommandBuilder.cpp | 128 | ||||
-rw-r--r-- | src/gpu/GrInOrderCommandBuilder.h | 51 | ||||
-rw-r--r-- | src/gpu/GrInOrderDrawBuffer.cpp | 2 | ||||
-rw-r--r-- | src/gpu/GrInOrderDrawBuffer.h | 5 |
8 files changed, 192 insertions, 128 deletions
diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi index c9bd851228..12ae9796c3 100644 --- a/gyp/gpu.gypi +++ b/gyp/gpu.gypi @@ -114,6 +114,8 @@ '<(skia_src_path)/gpu/GrGpuFactory.h', '<(skia_src_path)/gpu/GrIndexBuffer.h', '<(skia_src_path)/gpu/GrInvariantOutput.cpp', + '<(skia_src_path)/gpu/GrInOrderCommandBuilder.cpp', + '<(skia_src_path)/gpu/GrInOrderCommandBuilder.h', '<(skia_src_path)/gpu/GrInOrderDrawBuffer.cpp', '<(skia_src_path)/gpu/GrInOrderDrawBuffer.h', '<(skia_src_path)/gpu/GrLayerCache.cpp', diff --git a/src/gpu/GrCommandBuilder.cpp b/src/gpu/GrCommandBuilder.cpp index aafc3455b2..297424c6aa 100644 --- a/src/gpu/GrCommandBuilder.cpp +++ b/src/gpu/GrCommandBuilder.cpp @@ -7,126 +7,6 @@ #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<DrawBatch*>(&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<DrawPaths*>(&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, diff --git a/src/gpu/GrCommandBuilder.h b/src/gpu/GrCommandBuilder.h index 165c2c2035..05c29fb014 100644 --- a/src/gpu/GrCommandBuilder.h +++ b/src/gpu/GrCommandBuilder.h @@ -34,16 +34,16 @@ public: bool insideClip, GrRenderTarget* renderTarget); virtual Cmd* recordDiscard(GrRenderTarget*); - virtual Cmd* recordDrawBatch(State*, GrBatch*); + virtual Cmd* recordDrawBatch(State*, GrBatch*) = 0; virtual Cmd* recordStencilPath(const GrPipelineBuilder&, const GrPathProcessor*, const GrPath*, const GrScissorState&, - const GrStencilSettings&); + const GrStencilSettings&) = 0; virtual Cmd* recordDrawPath(State*, const GrPathProcessor*, const GrPath*, - const GrStencilSettings&); + const GrStencilSettings&) = 0; virtual Cmd* recordDrawPaths(State*, GrInOrderDrawBuffer*, const GrPathProcessor*, @@ -54,7 +54,7 @@ public: GrDrawTarget::PathTransformType , int, const GrStencilSettings&, - const GrDrawTarget::PipelineInfo&); + const GrDrawTarget::PipelineInfo&) = 0; virtual Cmd* recordClear(const SkIRect* rect, GrColor, bool canIgnoreRect, @@ -65,7 +65,7 @@ public: const SkIPoint& dstPoint); virtual Cmd* recordXferBarrierIfNecessary(const GrPipeline&, const GrDrawTargetCaps&); -private: +protected: typedef GrTargetCommands::DrawBatch DrawBatch; typedef GrTargetCommands::StencilPath StencilPath; typedef GrTargetCommands::DrawPath DrawPath; @@ -78,6 +78,7 @@ private: GrTargetCommands::CmdBuffer* cmdBuffer() { return fCommands.cmdBuffer(); } GrBatchTarget* batchTarget() { return fCommands.batchTarget(); } +private: GrTargetCommands fCommands; }; diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index b80991efd1..cadf3e3423 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -225,6 +225,7 @@ public: protected: friend class GrCommandBuilder; // for PipelineInfo + friend class GrInOrderCommandBuilder; // for PipelineInfo friend class GrTargetCommands; // for PipelineInfo GrContext* getContext() { return fContext; } diff --git a/src/gpu/GrInOrderCommandBuilder.cpp b/src/gpu/GrInOrderCommandBuilder.cpp new file mode 100644 index 0000000000..e56607b570 --- /dev/null +++ b/src/gpu/GrInOrderCommandBuilder.cpp @@ -0,0 +1,128 @@ +/* + * 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 "GrInOrderCommandBuilder.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* GrInOrderCommandBuilder::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<DrawBatch*>(&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* +GrInOrderCommandBuilder::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* +GrInOrderCommandBuilder::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* +GrInOrderCommandBuilder::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<DrawPaths*>(&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; +} diff --git a/src/gpu/GrInOrderCommandBuilder.h b/src/gpu/GrInOrderCommandBuilder.h new file mode 100644 index 0000000000..4fc7cc74dd --- /dev/null +++ b/src/gpu/GrInOrderCommandBuilder.h @@ -0,0 +1,51 @@ +/* + * 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 GrInOrderCommandBuilder_DEFINED +#define GrInOrderCommandBuilder_DEFINED + +#include "GrCommandBuilder.h" + +class GrInOrderCommandBuilder : public GrCommandBuilder { +public: + typedef GrCommandBuilder::Cmd Cmd; + typedef GrCommandBuilder::State State; + + GrInOrderCommandBuilder(GrGpu* gpu, + GrVertexBufferAllocPool* vertexPool, + GrIndexBufferAllocPool* indexPool) + : INHERITED(gpu, vertexPool, indexPool) { + } + + Cmd* recordDrawBatch(State*, GrBatch*) override; + Cmd* recordStencilPath(const GrPipelineBuilder&, + const GrPathProcessor*, + const GrPath*, + const GrScissorState&, + const GrStencilSettings&) override; + Cmd* recordDrawPath(State*, + const GrPathProcessor*, + const GrPath*, + const GrStencilSettings&) override; + Cmd* recordDrawPaths(State*, + GrInOrderDrawBuffer*, + const GrPathProcessor*, + const GrPathRange*, + const void*, + GrDrawTarget::PathIndexType, + const float transformValues[], + GrDrawTarget::PathTransformType , + int, + const GrStencilSettings&, + const GrDrawTarget::PipelineInfo&) override; + +private: + typedef GrCommandBuilder INHERITED; + +}; + +#endif diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp index 4aaff8e68e..35e71a910c 100644 --- a/src/gpu/GrInOrderDrawBuffer.cpp +++ b/src/gpu/GrInOrderDrawBuffer.cpp @@ -11,7 +11,7 @@ GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrContext* context, GrVertexBufferAllocPool* vertexPool, GrIndexBufferAllocPool* indexPool) : INHERITED(context, vertexPool, indexPool) - , fCommands(SkNEW_ARGS(GrCommandBuilder, (context->getGpu(), vertexPool, indexPool))) + , fCommands(SkNEW_ARGS(GrInOrderCommandBuilder, (context->getGpu(), vertexPool, indexPool))) , fPathIndexBuffer(kPathIdxBufferMinReserve * sizeof(char)/4) , fPathTransformBuffer(kPathXformBufferMinReserve * sizeof(float)/4) , fPipelineBuffer(kPipelineBufferMinReserve) diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h index 3e266b23ed..37d89735c0 100644 --- a/src/gpu/GrInOrderDrawBuffer.h +++ b/src/gpu/GrInOrderDrawBuffer.h @@ -9,7 +9,7 @@ #define GrInOrderDrawBuffer_DEFINED #include "GrDrawTarget.h" -#include "GrCommandBuilder.h" +#include "GrInOrderCommandBuilder.h" #include "SkChunkAlloc.h" /** @@ -71,8 +71,9 @@ protected: } private: - friend class GrCommandBuilder; + friend class GrInOrderCommandBuilder; friend class GrTargetCommands; + typedef GrTargetCommands::State State; State* allocState(const GrPrimitiveProcessor* primProc = NULL) { |