diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi index 9415f30bb3..7ce4ff564c 100644 --- a/gyp/gpu.gypi +++ b/gyp/gpu.gypi @@ -173,6 +173,8 @@ '<(skia_src_path)/gpu/GrRenderTargetPriv.h', '<(skia_src_path)/gpu/GrReducedClip.cpp', '<(skia_src_path)/gpu/GrReducedClip.h', + '<(skia_src_path)/gpu/GrReorderCommandBuilder.h', + '<(skia_src_path)/gpu/GrReorderCommandBuilder.cpp', '<(skia_src_path)/gpu/GrResourceCache.cpp', '<(skia_src_path)/gpu/GrResourceCache.h', '<(skia_src_path)/gpu/GrResourceProvider.cpp', diff --git a/src/gpu/GrCommandBuilder.cpp b/src/gpu/GrCommandBuilder.cpp index 297424c6aa..2ff59bcecd 100644 --- a/src/gpu/GrCommandBuilder.cpp +++ b/src/gpu/GrCommandBuilder.cpp @@ -7,6 +7,17 @@ #include "GrCommandBuilder.h" +#include "GrInOrderCommandBuilder.h" +#include "GrReorderCommandBuilder.h" + +GrCommandBuilder* GrCommandBuilder::Create(GrGpu* gpu, bool reorder) { + if (reorder) { + return SkNEW_ARGS(GrReorderCommandBuilder, (gpu)); + } else { + return SkNEW_ARGS(GrInOrderCommandBuilder, (gpu)); + } +} + GrTargetCommands::Cmd* GrCommandBuilder::recordClear(const SkIRect* rect, GrColor color, bool canIgnoreRect, diff --git a/src/gpu/GrCommandBuilder.h b/src/gpu/GrCommandBuilder.h index eb51b5b721..90099ee2ef 100644 --- a/src/gpu/GrCommandBuilder.h +++ b/src/gpu/GrCommandBuilder.h @@ -17,7 +17,7 @@ public: typedef GrTargetCommands::Cmd Cmd; typedef GrTargetCommands::State State; - GrCommandBuilder(GrGpu* gpu) : fCommands(gpu) { } + static GrCommandBuilder* Create(GrGpu* gpu, bool reorder); virtual ~GrCommandBuilder() {} @@ -69,6 +69,8 @@ protected: typedef GrTargetCommands::CopySurface CopySurface; typedef GrTargetCommands::XferBarrier XferBarrier; + GrCommandBuilder(GrGpu* gpu) : fCommands(gpu) {} + GrTargetCommands::CmdBuffer* cmdBuffer() { return fCommands.cmdBuffer(); } GrBatchTarget* batchTarget() { return fCommands.batchTarget(); } diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index 1b88153c28..84f7eb2197 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -224,6 +224,7 @@ public: protected: friend class GrCommandBuilder; // for PipelineInfo friend class GrInOrderCommandBuilder; // for PipelineInfo + friend class GrReorderCommandBuilder; // for PipelineInfo friend class GrTargetCommands; // for PipelineInfo GrContext* getContext() { return fContext; } diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp index f28a83f2b5..6b6490c7ea 100644 --- a/src/gpu/GrInOrderDrawBuffer.cpp +++ b/src/gpu/GrInOrderDrawBuffer.cpp @@ -9,7 +9,7 @@ GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrContext* context) : INHERITED(context) - , fCommands(SkNEW_ARGS(GrInOrderCommandBuilder, (context->getGpu()))) + , fCommands(GrCommandBuilder::Create(context->getGpu(), false)) , 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 182ba80511..b3de1925a0 100644 --- a/src/gpu/GrInOrderDrawBuffer.h +++ b/src/gpu/GrInOrderDrawBuffer.h @@ -9,7 +9,7 @@ #define GrInOrderDrawBuffer_DEFINED #include "GrDrawTarget.h" -#include "GrInOrderCommandBuilder.h" +#include "GrCommandBuilder.h" #include "SkChunkAlloc.h" /** diff --git a/src/gpu/GrReorderCommandBuilder.cpp b/src/gpu/GrReorderCommandBuilder.cpp new file mode 100644 index 0000000000..3ba95d7c96 --- /dev/null +++ b/src/gpu/GrReorderCommandBuilder.cpp @@ -0,0 +1,46 @@ +/* + * 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 "GrReorderCommandBuilder.h" + +static bool intersect(const SkRect& a, const SkRect& b) { + SkASSERT(a.fLeft <= a.fRight && a.fTop <= a.fBottom && + b.fLeft <= b.fRight && b.fTop <= b.fBottom); + return a.fLeft < b.fRight && b.fLeft < a.fRight && + a.fTop < b.fBottom && b.fTop < a.fBottom; +} + +GrTargetCommands::Cmd* GrReorderCommandBuilder::recordDrawBatch(State* state, GrBatch* batch) { + // Check if there is a Batch Draw we can batch with by linearly searching back until we either + // 1) check every draw + // 2) intersect with something + // 3) find a 'blocker' + if (!this->cmdBuffer()->empty()) { + GrTargetCommands::CmdBuffer::ReverseIter reverseIter(*this->cmdBuffer()); + + do { + if (Cmd::kDrawBatch_CmdType == reverseIter->type()) { + DrawBatch* previous = static_cast(reverseIter.get()); + + if (previous->fState->getPipeline()->isEqual(*state->getPipeline()) && + previous->fBatch->combineIfPossible(batch)) { + return NULL; + } + + if (intersect(previous->fBatch->bounds(), batch->bounds())) { + break; + } + } else { + // TODO temporary until we can navigate the other types of commands + break; + } + } while (reverseIter.previous()); + } + + return GrNEW_APPEND_TO_RECORDER(*this->cmdBuffer(), DrawBatch, (state, batch, + this->batchTarget())); +} diff --git a/src/gpu/GrReorderCommandBuilder.h b/src/gpu/GrReorderCommandBuilder.h new file mode 100644 index 0000000000..99a2c11c27 --- /dev/null +++ b/src/gpu/GrReorderCommandBuilder.h @@ -0,0 +1,58 @@ +/* + * 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 GrReorderCommandBuilder_DEFINED +#define GrReorderCommandBuilder_DEFINED + +#include "GrCommandBuilder.h" + +class GrReorderCommandBuilder : public GrCommandBuilder { +public: + typedef GrCommandBuilder::Cmd Cmd; + typedef GrCommandBuilder::State State; + + GrReorderCommandBuilder(GrGpu* gpu) : INHERITED(gpu) {} + + Cmd* recordDrawBatch(State*, GrBatch*) override; + Cmd* recordStencilPath(const GrPipelineBuilder&, + const GrPathProcessor*, + const GrPath*, + const GrScissorState&, + const GrStencilSettings&) override { + SkFAIL("Unsupported\n"); + return NULL; + } + + Cmd* recordDrawPath(State*, + const GrPathProcessor*, + const GrPath*, + const GrStencilSettings&) override { + SkFAIL("Unsupported\n"); + return NULL; + } + + Cmd* recordDrawPaths(State*, + GrInOrderDrawBuffer*, + const GrPathProcessor*, + const GrPathRange*, + const void*, + GrDrawTarget::PathIndexType, + const float transformValues[], + GrDrawTarget::PathTransformType , + int, + const GrStencilSettings&, + const GrDrawTarget::PipelineInfo&) override { + SkFAIL("Unsupported\n"); + return NULL; + } + +private: + typedef GrCommandBuilder INHERITED; + +}; + +#endif diff --git a/src/gpu/GrTargetCommands.h b/src/gpu/GrTargetCommands.h index 71ce4706b5..5e35e50bbf 100644 --- a/src/gpu/GrTargetCommands.h +++ b/src/gpu/GrTargetCommands.h @@ -65,6 +65,7 @@ public: private: friend class GrCommandBuilder; friend class GrInOrderDrawBuffer; // This goes away when State becomes just a pipeline + friend class GrReorderCommandBuilder; typedef GrGpu::DrawArgs DrawArgs;