diff --git a/gn/gpu.gni b/gn/gpu.gni index 61dea745e5..8629ecdd7f 100644 --- a/gn/gpu.gni +++ b/gn/gpu.gni @@ -144,6 +144,8 @@ skia_gpu_sources = [ "$_src/gpu/GrPipelineBuilder.h", "$_src/gpu/GrPrimitiveProcessor.cpp", "$_src/gpu/GrPrimitiveProcessor.h", + "$_src/gpu/GrProcessorSet.cpp", + "$_src/gpu/GrProcessorSet.h", "$_src/gpu/GrProgramDesc.cpp", "$_src/gpu/GrProgramDesc.h", "$_src/gpu/GrProcessor.cpp", diff --git a/include/gpu/GrPaint.h b/include/gpu/GrPaint.h index 6897679e5d..3b136ac82e 100644 --- a/include/gpu/GrPaint.h +++ b/include/gpu/GrPaint.h @@ -169,7 +169,7 @@ public: private: GrPaint& operator=(const GrPaint&) = delete; - friend class GrPipelineBuilder; + friend class GrProcessorSet; bool internalIsConstantBlendedColor(GrColor paintColor, GrColor* constantColor) const; diff --git a/include/gpu/GrProgramElement.h b/include/gpu/GrProgramElement.h index 71905ac5ad..0e065c231f 100644 --- a/include/gpu/GrProgramElement.h +++ b/include/gpu/GrProgramElement.h @@ -117,6 +117,7 @@ private: // Only this class can access addPendingExecution() and completedExecution(). template friend class GrPendingProgramElement; + friend class GrProcessorSet; typedef SkNoncopyable INHERITED; }; diff --git a/include/private/SkTemplates.h b/include/private/SkTemplates.h index f50af8b7f9..c45de75a93 100644 --- a/include/private/SkTemplates.h +++ b/include/private/SkTemplates.h @@ -204,6 +204,14 @@ public: */ T* get() const { return fArray; } + T* begin() { return fArray; } + + const T* begin() const { return fArray; } + + T* end() { return fArray + fCount; } + + const T* end() const { return fArray + fCount; } + /** Return the nth element in the array */ T& operator[](int index) const { diff --git a/src/gpu/GrPipelineBuilder.cpp b/src/gpu/GrPipelineBuilder.cpp index fce8aa9694..ce3871873a 100644 --- a/src/gpu/GrPipelineBuilder.cpp +++ b/src/gpu/GrPipelineBuilder.cpp @@ -18,18 +18,10 @@ GrPipelineBuilder::GrPipelineBuilder(GrPaint&& paint, GrAAType aaType) : fFlags(0x0) , fUserStencilSettings(&GrUserStencilSettings::kUnused) - , fDrawFace(GrDrawFace::kBoth) { - for (int i = 0; i < paint.numColorFragmentProcessors(); ++i) { - fColorFragmentProcessors.emplace_back(paint.fColorFragmentProcessors[i].release()); - } - - for (int i = 0; i < paint.numCoverageFragmentProcessors(); ++i) { - fCoverageFragmentProcessors.emplace_back(paint.fCoverageFragmentProcessors[i].release()); - } - - fXPFactory = paint.getXPFactory(); - + , fDrawFace(GrDrawFace::kBoth) + , fProcessors(std::move(paint)) { this->setState(GrPipelineBuilder::kHWAntialias_Flag, GrAATypeIsHW(aaType)); + // The processors have been moved out of paint, but its flags should still be unmodified. this->setState(GrPipelineBuilder::kDisableOutputConversionToSRGB_Flag, paint.getDisableOutputConversionToSRGB()); this->setState(GrPipelineBuilder::kAllowSRGBInputs_Flag, diff --git a/src/gpu/GrPipelineBuilder.h b/src/gpu/GrPipelineBuilder.h index fcc692a950..e0c4d3d46e 100644 --- a/src/gpu/GrPipelineBuilder.h +++ b/src/gpu/GrPipelineBuilder.h @@ -8,26 +8,19 @@ #ifndef GrPipelineBuilder_DEFINED #define GrPipelineBuilder_DEFINED -#include "GrBlend.h" -#include "GrCaps.h" #include "GrGpuResourceRef.h" -#include "GrProcOptInfo.h" +#include "GrProcessorSet.h" #include "GrRenderTarget.h" #include "GrUserStencilSettings.h" #include "GrXferProcessor.h" -#include "SkMatrix.h" -#include "SkRefCnt.h" -#include "effects/GrCoverageSetOpXP.h" -#include "effects/GrDisableColorXP.h" -#include "effects/GrPorterDuffXferProcessor.h" -#include "effects/GrSimpleTextureEffect.h" -class GrDrawOp; class GrCaps; +class GrDrawOp; class GrPaint; +struct GrPipelineAnalysis; class GrTexture; -class GrPipelineBuilder : public SkNoncopyable { +class GrPipelineBuilder : private SkNoncopyable { public: /** * Initializes the GrPipelineBuilder based on a GrPaint and MSAA availability. Note @@ -47,16 +40,21 @@ public: /// feed their output to the GrXferProcessor which controls blending. //// - int numColorFragmentProcessors() const { return fColorFragmentProcessors.count(); } - int numCoverageFragmentProcessors() const { return fCoverageFragmentProcessors.count(); } - int numFragmentProcessors() const { return this->numColorFragmentProcessors() + - this->numCoverageFragmentProcessors(); } + int numColorFragmentProcessors() const { return fProcessors.numColorFragmentProcessors(); } + int numCoverageFragmentProcessors() const { + return fProcessors.numCoverageFragmentProcessors(); + } + int numFragmentProcessors() const { return fProcessors.numFragmentProcessors(); } const GrFragmentProcessor* getColorFragmentProcessor(int idx) const { - return fColorFragmentProcessors[idx].get(); + return fProcessors.colorFragmentProcessor(idx); } const GrFragmentProcessor* getCoverageFragmentProcessor(int idx) const { - return fCoverageFragmentProcessors[idx].get(); + return fProcessors.coverageFragmentProcessor(idx); + } + + void analyzeFragmentProcessors(GrPipelineAnalysis* analysis) const { + fProcessors.analyzeFragmentProcessors(analysis); } /// @} @@ -65,7 +63,7 @@ public: /// @name Blending //// - const GrXPFactory* getXPFactory() const { return fXPFactory; } + const GrXPFactory* getXPFactory() const { return fProcessors.xpFactory(); } /** * Checks whether the xp will need destination in a texture to correctly blend. @@ -201,20 +199,10 @@ public: bool usePLSDstRead(const GrDrawOp*) const; private: - typedef SkSTArray<4, sk_sp> FragmentProcessorArray; - - uint32_t fFlags; - const GrUserStencilSettings* fUserStencilSettings; - GrDrawFace fDrawFace; - const GrXPFactory* fXPFactory; - FragmentProcessorArray fColorFragmentProcessors; - FragmentProcessorArray fCoverageFragmentProcessors; - - friend class GrPipeline; - // This gives the GrRenderTargetOpList raw access to fColorFragmentProcessors & - // fCoverageFragmentProcessors - // TODO: that access seems a little dodgy - friend class GrRenderTargetOpList; + uint32_t fFlags; + const GrUserStencilSettings* fUserStencilSettings; + GrDrawFace fDrawFace; + GrProcessorSet fProcessors; }; #endif diff --git a/src/gpu/GrProcessorSet.cpp b/src/gpu/GrProcessorSet.cpp new file mode 100644 index 0000000000..0d72d9bafe --- /dev/null +++ b/src/gpu/GrProcessorSet.cpp @@ -0,0 +1,21 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "GrProcessorSet.h" + +GrProcessorSet::GrProcessorSet(GrPaint&& paint) { + fXPFactory = paint.fXPFactory; + fColorFragmentProcessorCnt = paint.numColorFragmentProcessors(); + fFragmentProcessors.reset(paint.numTotalFragmentProcessors()); + int i = 0; + for (auto& fp : paint.fColorFragmentProcessors) { + fFragmentProcessors[i++] = fp.release(); + } + for (auto& fp : paint.fCoverageFragmentProcessors) { + fFragmentProcessors[i++] = fp.release(); + } +} diff --git a/src/gpu/GrProcessorSet.h b/src/gpu/GrProcessorSet.h new file mode 100644 index 0000000000..684fb26a84 --- /dev/null +++ b/src/gpu/GrProcessorSet.h @@ -0,0 +1,59 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrProcessorSet_DEFINED +#define GrProcessorSet_DEFINED + +#include "GrFragmentProcessor.h" +#include "GrPaint.h" +#include "GrPipeline.h" +#include "SkTemplates.h" + +class GrXPFactory; + +class GrProcessorSet : private SkNoncopyable { +public: + GrProcessorSet(GrPaint&& paint); + + ~GrProcessorSet() { + // We are deliberately not using sk_sp here because this will be updated to work with + // "pending execution" refs. + for (auto fp : fFragmentProcessors) { + fp->unref(); + } + } + + int numColorFragmentProcessors() const { return fColorFragmentProcessorCnt; } + int numCoverageFragmentProcessors() const { + return fFragmentProcessors.count() - fColorFragmentProcessorCnt; + } + int numFragmentProcessors() const { return fFragmentProcessors.count(); } + + const GrFragmentProcessor* colorFragmentProcessor(int idx) const { + SkASSERT(idx < fColorFragmentProcessorCnt); + return fFragmentProcessors[idx]; + } + const GrFragmentProcessor* coverageFragmentProcessor(int idx) const { + return fFragmentProcessors[idx + fColorFragmentProcessorCnt]; + } + + const GrXPFactory* xpFactory() const { return fXPFactory; } + + void analyzeFragmentProcessors(GrPipelineAnalysis* analysis) const { + const GrFragmentProcessor* const* fps = fFragmentProcessors.get(); + analysis->fColorPOI.addProcessors(fps, fColorFragmentProcessorCnt); + fps += fColorFragmentProcessorCnt; + analysis->fCoveragePOI.addProcessors(fps, this->numCoverageFragmentProcessors()); + } + +private: + const GrXPFactory* fXPFactory = nullptr; + SkAutoSTArray<4, const GrFragmentProcessor*> fFragmentProcessors; + int fColorFragmentProcessorCnt; +}; + +#endif diff --git a/src/gpu/GrRenderTargetOpList.cpp b/src/gpu/GrRenderTargetOpList.cpp index e4bb34e84e..0a34019310 100644 --- a/src/gpu/GrRenderTargetOpList.cpp +++ b/src/gpu/GrRenderTargetOpList.cpp @@ -264,8 +264,7 @@ static void op_bounds(SkRect* bounds, const GrOp* op) { void GrRenderTargetOpList::addDrawOp(const GrPipelineBuilder& pipelineBuilder, GrRenderTargetContext* renderTargetContext, const GrClip& clip, - std::unique_ptr - op) { + std::unique_ptr op) { // Setup clip SkRect bounds; op_bounds(&bounds, op.get()); @@ -312,12 +311,7 @@ void GrRenderTargetOpList::addDrawOp(const GrPipelineBuilder& pipelineBuilder, return; } } - args.fAnalysis.fColorPOI.addProcessors( - sk_sp_address_as_pointer_address(pipelineBuilder.fColorFragmentProcessors.begin()), - pipelineBuilder.numColorFragmentProcessors()); - args.fAnalysis.fCoveragePOI.addProcessors( - sk_sp_address_as_pointer_address(pipelineBuilder.fCoverageFragmentProcessors.begin()), - pipelineBuilder.numCoverageFragmentProcessors()); + pipelineBuilder.analyzeFragmentProcessors(&args.fAnalysis); if (const GrFragmentProcessor* clipFP = appliedClip.clipCoverageFragmentProcessor()) { args.fAnalysis.fCoveragePOI.addProcessors(&clipFP, 1); }