GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args,
GrPipelineOptimizations* optimizations) {
- const GrPipelineBuilder& builder = *args.fPipelineBuilder;
- const GrUserStencilSettings* userStencil = builder.getUserStencil();
GrRenderTarget* rt = args.fRenderTargetContext->accessRenderTarget();
if (!rt) {
return nullptr;
SkASSERT(pipeline->fRenderTarget);
pipeline->fScissorState = args.fAppliedClip->scissorState();
pipeline->fWindowRectsState = args.fAppliedClip->windowRectsState();
- pipeline->fUserStencilSettings = userStencil;
- pipeline->fDrawFace = builder.getDrawFace();
+ pipeline->fUserStencilSettings = args.fUserStencil;
+ pipeline->fDrawFace = static_cast<int16_t>(args.fDrawFace);
- pipeline->fFlags = 0;
- if (builder.isHWAntialias()) {
- pipeline->fFlags |= kHWAA_Flag;
- }
- if (builder.snapVerticesToPixelCenters()) {
- pipeline->fFlags |= kSnapVertices_Flag;
- }
- if (builder.getDisableOutputConversionToSRGB()) {
- pipeline->fFlags |= kDisableOutputConversionToSRGB_Flag;
- }
- if (builder.getAllowSRGBInputs()) {
- pipeline->fFlags |= kAllowSRGBInputs_Flag;
- }
- if (builder.getUsesDistanceVectorField()) {
+ pipeline->fFlags = args.fFlags;
+ if (args.fProcessors->usesDistanceVectorField()) {
pipeline->fFlags |= kUsesDistanceVectorField_Flag;
}
if (args.fAppliedClip->hasStencilClip()) {
pipeline->fFlags |= kHasStencilClip_Flag;
}
- if (!userStencil->isDisabled(args.fAppliedClip->hasStencilClip())) {
+ if (!args.fUserStencil->isDisabled(args.fAppliedClip->hasStencilClip())) {
pipeline->fFlags |= kStencilEnabled_Flag;
}
+ bool isHWAA = kHWAntialias_Flag & args.fFlags;
+
// Create XferProcessor from DS's XPFactory
bool hasMixedSamples = args.fRenderTargetContext->hasMixedSamples() &&
- (builder.isHWAntialias() || pipeline->isStencilEnabled());
- const GrXPFactory* xpFactory = builder.getXPFactory();
+ (isHWAA || pipeline->isStencilEnabled());
+ const GrXPFactory* xpFactory = args.fProcessors->xpFactory();
sk_sp<GrXferProcessor> xferProcessor;
if (xpFactory) {
xferProcessor.reset(xpFactory->createXferProcessor(
const GrXferProcessor* xpForOpts = xferProcessor ? xferProcessor.get() :
&GrPorterDuffXPFactory::SimpleSrcOverXP();
optFlags = xpForOpts->getOptimizations(
- args.fAnalysis, userStencil->doesWrite(args.fAppliedClip->hasStencilClip()),
+ args.fAnalysis, args.fUserStencil->doesWrite(args.fAppliedClip->hasStencilClip()),
&overrideColor, *args.fCaps);
// When path rendering the stencil settings are not always set on the GrPipelineBuilder
if ((optFlags & GrXferProcessor::kIgnoreColor_OptFlag) ||
(optFlags & GrXferProcessor::kOverrideColor_OptFlag)) {
- firstColorProcessorIdx = builder.numColorFragmentProcessors();
+ firstColorProcessorIdx = args.fProcessors->numColorFragmentProcessors();
}
bool usesLocalCoords = false;
// Copy GrFragmentProcessors from GrPipelineBuilder to Pipeline
- pipeline->fNumColorProcessors = builder.numColorFragmentProcessors() - firstColorProcessorIdx;
+ pipeline->fNumColorProcessors =
+ args.fProcessors->numColorFragmentProcessors() - firstColorProcessorIdx;
int numTotalProcessors = pipeline->fNumColorProcessors +
- builder.numCoverageFragmentProcessors() - firstCoverageProcessorIdx;
+ args.fProcessors->numCoverageFragmentProcessors() -
+ firstCoverageProcessorIdx;
if (args.fAppliedClip->clipCoverageFragmentProcessor()) {
++numTotalProcessors;
}
pipeline->fFragmentProcessors.reset(numTotalProcessors);
int currFPIdx = 0;
- for (int i = firstColorProcessorIdx; i < builder.numColorFragmentProcessors();
+ for (int i = firstColorProcessorIdx; i < args.fProcessors->numColorFragmentProcessors();
++i, ++currFPIdx) {
- const GrFragmentProcessor* fp = builder.getColorFragmentProcessor(i);
+ const GrFragmentProcessor* fp = args.fProcessors->colorFragmentProcessor(i);
pipeline->fFragmentProcessors[currFPIdx].reset(fp);
usesLocalCoords = usesLocalCoords || fp->usesLocalCoords();
}
- for (int i = firstCoverageProcessorIdx; i < builder.numCoverageFragmentProcessors();
+ for (int i = firstCoverageProcessorIdx; i < args.fProcessors->numCoverageFragmentProcessors();
++i, ++currFPIdx) {
- const GrFragmentProcessor* fp = builder.getCoverageFragmentProcessor(i);
+ const GrFragmentProcessor* fp = args.fProcessors->coverageFragmentProcessor(i);
pipeline->fFragmentProcessors[currFPIdx].reset(fp);
usesLocalCoords = usesLocalCoords || fp->usesLocalCoords();
}
bool fUsesPLSDstRead = false;
};
+class GrProcessorSet;
+
/**
* Class that holds an optimized version of a GrPipelineBuilder. It is meant to be an immutable
* class, and contains all data needed to set the state for a gpu draw.
///////////////////////////////////////////////////////////////////////////
/// @name Creation
+ enum Flags {
+ /**
+ * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
+ * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
+ * the 3D API.
+ */
+ kHWAntialias_Flag = 0x1,
+
+ /**
+ * Modifies the vertex shader so that vertices will be positioned at pixel centers.
+ */
+ kSnapVerticesToPixelCenters_Flag = 0x2,
+
+ /**
+ * Suppress linear -> sRGB conversion when rendering to sRGB render targets.
+ */
+ kDisableOutputConversionToSRGB_Flag = 0x4,
+
+ /**
+ * Allow sRGB -> linear conversion when reading from sRGB inputs.
+ */
+ kAllowSRGBInputs_Flag = 0x8,
+ };
+
struct CreateArgs {
- const GrPipelineBuilder* fPipelineBuilder;
- GrAppliedClip* fAppliedClip;
- GrRenderTargetContext* fRenderTargetContext;
- const GrCaps* fCaps;
+ uint32_t fFlags = 0;
+ GrDrawFace fDrawFace = GrDrawFace::kBoth;
+ const GrProcessorSet* fProcessors = nullptr;
+ const GrUserStencilSettings* fUserStencil = &GrUserStencilSettings::kUnused;
+ GrAppliedClip* fAppliedClip = nullptr;
+ GrRenderTargetContext* fRenderTargetContext = nullptr;
+ const GrCaps* fCaps = nullptr;
GrPipelineAnalysis fAnalysis;
GrXferProcessor::DstTexture fDstTexture;
};
const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; }
- bool isHWAntialiasState() const { return SkToBool(fFlags & kHWAA_Flag); }
- bool snapVerticesToPixelCenters() const { return SkToBool(fFlags & kSnapVertices_Flag); }
+ bool isHWAntialiasState() const { return SkToBool(fFlags & kHWAntialias_Flag); }
+ bool snapVerticesToPixelCenters() const {
+ return SkToBool(fFlags & kSnapVerticesToPixelCenters_Flag);
+ }
bool getDisableOutputConversionToSRGB() const {
return SkToBool(fFlags & kDisableOutputConversionToSRGB_Flag);
}
* or both faces.
* @return the current draw face(s).
*/
- GrDrawFace getDrawFace() const { return fDrawFace; }
-
+ GrDrawFace getDrawFace() const { return static_cast<GrDrawFace>(fDrawFace); }
private:
GrPipeline() { /** Initialized in factory function*/ }
- /**
- * Calculates the primary and secondary output types of the shader. For certain output types
- * the function may adjust the blend coefficients. After this function is called the src and dst
- * blend coeffs will represent those used by backend API.
- */
- void setOutputStateInfo(const GrPipelineBuilder& ds, GrXferProcessor::OptFlags,
- const GrCaps&);
-
- enum Flags {
- kHWAA_Flag = 0x1,
- kSnapVertices_Flag = 0x2,
- kDisableOutputConversionToSRGB_Flag = 0x4,
- kAllowSRGBInputs_Flag = 0x8,
- kUsesDistanceVectorField_Flag = 0x10,
- kHasStencilClip_Flag = 0x20,
- kStencilEnabled_Flag = 0x40,
+ enum PrivateFlags {
+ kUsesDistanceVectorField_Flag = 0x10,
+ kHasStencilClip_Flag = 0x20,
+ kStencilEnabled_Flag = 0x40,
};
typedef GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> RenderTarget;
GrScissorState fScissorState;
GrWindowRectsState fWindowRectsState;
const GrUserStencilSettings* fUserStencilSettings;
- GrDrawFace fDrawFace;
- uint32_t fFlags;
+ uint16_t fDrawFace;
+ uint16_t fFlags;
ProgramXferProcessor fXferProcessor;
FragmentProcessorArray fFragmentProcessors;
GrPipelineBuilder::GrPipelineBuilder(GrPaint&& paint, GrAAType aaType)
: fFlags(0x0)
- , fUserStencilSettings(&GrUserStencilSettings::kUnused)
, fDrawFace(GrDrawFace::kBoth)
+ , fUserStencilSettings(&GrUserStencilSettings::kUnused)
, 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,
- paint.getAllowSRGBInputs());
- this->setState(GrPipelineBuilder::kUsesDistanceVectorField_Flag,
- paint.usesDistanceVectorField());
+ if (GrAATypeIsHW(aaType)) {
+ fFlags |= GrPipeline::kHWAntialias_Flag;
+ }
+ if (paint.getDisableOutputConversionToSRGB()) {
+ fFlags |= GrPipeline::kDisableOutputConversionToSRGB_Flag;
+ }
+ if (paint.getAllowSRGBInputs()) {
+ fFlags |= GrPipeline::kAllowSRGBInputs_Flag;
+ }
}
bool GrPipelineBuilder::willXPNeedDstTexture(const GrCaps& caps,
const GrPipelineAnalysis& analysis) const {
- if (this->getXPFactory()) {
- return this->getXPFactory()->willNeedDstTexture(caps, analysis);
+ if (fProcessors.xpFactory()) {
+ return fProcessors.xpFactory()->willNeedDstTexture(caps, analysis);
}
return GrPorterDuffXPFactory::SrcOverWillNeedDstTexture(caps, analysis);
}
#define GrPipelineBuilder_DEFINED
#include "GrGpuResourceRef.h"
+#include "GrPipeline.h"
#include "GrProcessorSet.h"
#include "GrRenderTarget.h"
#include "GrUserStencilSettings.h"
/// @name Blending
////
- const GrXPFactory* getXPFactory() const { return fProcessors.xpFactory(); }
-
/**
* Checks whether the xp will need destination in a texture to correctly blend.
*/
////
bool hasUserStencilSettings() const { return !fUserStencilSettings->isUnused(); }
- const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; }
/**
* Sets the user stencil settings for the next draw.
* @param settings the stencil settings to use.
*/
void setUserStencil(const GrUserStencilSettings* settings) { fUserStencilSettings = settings; }
- void disableUserStencil() { fUserStencilSettings = &GrUserStencilSettings::kUnused; }
/// @}
/// @name State Flags
////
- /**
- * Flags that affect rendering. Controlled using enable/disableState(). All
- * default to disabled.
- */
- enum Flags {
- /**
- * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
- * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
- * the 3D API.
- */
- kHWAntialias_Flag = 0x01,
-
- /**
- * Modifies the vertex shader so that vertices will be positioned at pixel centers.
- */
- kSnapVerticesToPixelCenters_Flag = 0x02,
-
- /**
- * Suppress linear -> sRGB conversion when rendering to sRGB render targets.
- */
- kDisableOutputConversionToSRGB_Flag = 0x04,
-
- /**
- * Allow sRGB -> linear conversion when reading from sRGB inputs.
- */
- kAllowSRGBInputs_Flag = 0x08,
-
- /**
- * Signals that one or more FPs need access to the distance vector field to the nearest
- * edge
- */
- kUsesDistanceVectorField_Flag = 0x10,
-
- kLast_Flag = kUsesDistanceVectorField_Flag,
- };
-
- bool isHWAntialias() const { return SkToBool(fFlags & kHWAntialias_Flag); }
- bool snapVerticesToPixelCenters() const {
- return SkToBool(fFlags & kSnapVerticesToPixelCenters_Flag); }
- bool getDisableOutputConversionToSRGB() const {
- return SkToBool(fFlags & kDisableOutputConversionToSRGB_Flag); }
- bool getAllowSRGBInputs() const {
- return SkToBool(fFlags & kAllowSRGBInputs_Flag); }
- bool getUsesDistanceVectorField() const {
- return SkToBool(fFlags & kUsesDistanceVectorField_Flag); }
-
- /**
- * Enable render state settings.
- *
- * @param flags bitfield of Flags specifying the states to enable
- */
- void enableState(uint32_t flags) { fFlags |= flags; }
-
- /**
- * Disable render state settings.
- *
- * @param flags bitfield of Flags specifying the states to disable
- */
- void disableState(uint32_t flags) { fFlags &= ~(flags); }
+ bool isHWAntialias() const { return SkToBool(fFlags & GrPipeline::kHWAntialias_Flag); }
- /**
- * Enable or disable flags based on a boolean.
- *
- * @param flags bitfield of Flags to enable or disable
- * @param enable if true enable stateBits, otherwise disable
- */
- void setState(uint32_t flags, bool enable) {
+ void setSnapVerticesToPixelCenters(bool enable) {
if (enable) {
- this->enableState(flags);
+ fFlags |= GrPipeline::kSnapVerticesToPixelCenters_Flag;
} else {
- this->disableState(flags);
+ fFlags &= ~GrPipeline::kSnapVerticesToPixelCenters_Flag;
}
}
////
/**
- * Gets whether the target is drawing clockwise, counterclockwise,
- * or both faces.
- * @return the current draw face(s).
- */
- GrDrawFace getDrawFace() const { return fDrawFace; }
-
- /**
* Controls whether clockwise, counterclockwise, or both faces are drawn.
* @param face the face(s) to draw.
*/
/// @}
- ///////////////////////////////////////////////////////////////////////////
-
- bool usePLSDstRead(const GrDrawOp*) const;
+ void initPipelineCreateArgs(GrPipeline::CreateArgs* args) const {
+ args->fFlags = fFlags;
+ args->fUserStencil = fUserStencilSettings;
+ args->fDrawFace = fDrawFace;
+ args->fProcessors = &fProcessors;
+ }
private:
uint32_t fFlags;
- const GrUserStencilSettings* fUserStencilSettings;
GrDrawFace fDrawFace;
+ const GrUserStencilSettings* fUserStencilSettings;
GrProcessorSet fProcessors;
};
for (auto& fp : paint.fCoverageFragmentProcessors) {
fFragmentProcessors[i++] = fp.release();
}
+ fUsesDistanceVectorField = paint.usesDistanceVectorField();
}
analysis->fCoveragePOI.analyzeProcessors(fps, this->numCoverageFragmentProcessors());
}
+ bool usesDistanceVectorField() const { return fUsesDistanceVectorField; }
+
private:
const GrXPFactory* fXPFactory = nullptr;
SkAutoSTArray<4, const GrFragmentProcessor*> fFragmentProcessors;
int fColorFragmentProcessorCnt;
+ bool fUsesDistanceVectorField;
};
#endif
if (op) {
GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
-
- if (snapToPixelCenters) {
- pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCenters_Flag,
- snapToPixelCenters);
- }
-
+ pipelineBuilder.setSnapVerticesToPixelCenters(snapToPixelCenters);
this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
return;
}
}
GrPipeline::CreateArgs args;
- args.fPipelineBuilder = &pipelineBuilder;
+ pipelineBuilder.initPipelineCreateArgs(&args);
args.fAppliedClip = &appliedClip;
args.fRenderTargetContext = renderTargetContext;
args.fCaps = this->caps();
GrAppliedClip dummyAppliedClip(SkRect::MakeLargest());
GrPipeline::CreateArgs args;
- args.fPipelineBuilder = &dummyBuilder;
+ dummyBuilder.initPipelineCreateArgs(&args);
args.fRenderTargetContext = dc;
args.fCaps = dc->caps();
args.fAppliedClip = &dummyAppliedClip;
if (uss) {
pipelineBuilder.setUserStencil(uss);
}
- if (snapToCenters) {
- pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCenters_Flag, true);
- }
+ pipelineBuilder.setSnapVerticesToPixelCenters(snapToCenters);
fRenderTargetContext->getOpList()->addDrawOp(pipelineBuilder, fRenderTargetContext, GrNoClip(),
std::move(op));