blob: 0c33eb344f8ce75442667817f7d25b67e0413c68 [file] [log] [blame]
/*
* 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 GrPipelineBuilder_DEFINED
#define GrPipelineBuilder_DEFINED
#include "GrBlend.h"
#include "GrCaps.h"
#include "GrGpuResourceRef.h"
#include "GrProcOptInfo.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 GrDrawBatch;
class GrCaps;
class GrPaint;
class GrTexture;
class GrPipelineBuilder : public SkNoncopyable {
public:
GrPipelineBuilder();
/**
* Initializes the GrPipelineBuilder based on a GrPaint and MSAA availability. Note
* that GrPipelineBuilder encompasses more than GrPaint. Aspects of GrPipelineBuilder that have
* no GrPaint equivalents are set to default values with the exception of vertex attribute state
* which is unmodified by this function and clipping which will be enabled.
*/
GrPipelineBuilder(const GrPaint&, bool useHWAA = false);
virtual ~GrPipelineBuilder();
///////////////////////////////////////////////////////////////////////////
/// @name Fragment Processors
///
/// GrFragmentProcessors are used to compute per-pixel color and per-pixel fractional coverage.
/// There are two chains of FPs, one for color and one for coverage. The first FP in each
/// chain gets the initial color/coverage from the GrPrimitiveProcessor. It computes an output
/// color/coverage which is fed to the next FP in the chain. The last color and coverage FPs
/// 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(); }
const GrFragmentProcessor* getColorFragmentProcessor(int idx) const {
return fColorFragmentProcessors[idx].get();
}
const GrFragmentProcessor* getCoverageFragmentProcessor(int idx) const {
return fCoverageFragmentProcessors[idx].get();
}
void addColorFragmentProcessor(sk_sp<GrFragmentProcessor> processor) {
SkASSERT(processor);
fColorFragmentProcessors.push_back(std::move(processor));
}
void addCoverageFragmentProcessor(sk_sp<GrFragmentProcessor> processor) {
SkASSERT(processor);
fCoverageFragmentProcessors.push_back(std::move(processor));
}
/**
* Creates a GrSimpleTextureEffect that uses local coords as texture coordinates.
*/
void addColorTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
this->addColorFragmentProcessor(GrSimpleTextureEffect::Make(texture, nullptr, matrix));
}
void addCoverageTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
this->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(texture, nullptr, matrix));
}
void addColorTextureProcessor(GrTexture* texture,
const SkMatrix& matrix,
const GrTextureParams& params) {
this->addColorFragmentProcessor(GrSimpleTextureEffect::Make(texture, nullptr, matrix,
params));
}
void addCoverageTextureProcessor(GrTexture* texture,
const SkMatrix& matrix,
const GrTextureParams& params) {
this->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(texture, nullptr, matrix,
params));
}
/**
* When this object is destroyed it will remove any color/coverage FPs from the pipeline builder
* that were added after its constructor.
* This class can transiently modify its "const" GrPipelineBuilder object but will restore it
* when done - so it is notionally "const" correct.
*/
class AutoRestoreFragmentProcessorState : public ::SkNoncopyable {
public:
AutoRestoreFragmentProcessorState()
: fPipelineBuilder(nullptr)
, fColorEffectCnt(0)
, fCoverageEffectCnt(0) {}
AutoRestoreFragmentProcessorState(const GrPipelineBuilder& ds)
: fPipelineBuilder(nullptr)
, fColorEffectCnt(0)
, fCoverageEffectCnt(0) {
this->set(&ds);
}
~AutoRestoreFragmentProcessorState() { this->set(nullptr); }
void set(const GrPipelineBuilder* ds);
bool isSet() const { return SkToBool(fPipelineBuilder); }
void addCoverageFragmentProcessor(sk_sp<GrFragmentProcessor> processor) {
SkASSERT(this->isSet());
return fPipelineBuilder->addCoverageFragmentProcessor(std::move(processor));
}
private:
// notionally const (as marginalia)
GrPipelineBuilder* fPipelineBuilder;
int fColorEffectCnt;
int fCoverageEffectCnt;
};
/// @}
///////////////////////////////////////////////////////////////////////////
/// @name Blending
////
/**
* Installs a GrXPFactory. This object controls how src color, fractional pixel coverage,
* and the dst color are blended.
*/
void setXPFactory(sk_sp<GrXPFactory> xpFactory) {
fXPFactory = std::move(xpFactory);
}
/**
* Sets a GrXPFactory that disables color writes to the destination. This is useful when
* rendering to the stencil buffer.
*/
void setDisableColorXPFactory() {
fXPFactory = GrDisableColorXPFactory::Make();
}
const GrXPFactory* getXPFactory() const {
return fXPFactory.get();
}
/**
* Checks whether the xp will need destination in a texture to correctly blend.
*/
bool willXPNeedDstTexture(const GrCaps& caps,
const GrPipelineOptimizations& optimizations) const;
/// @}
///////////////////////////////////////////////////////////////////////////
/// @name Stencil
////
bool hasUserStencilSettings() const { return !fUserStencilSettings->isUnused(); }
const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; }
/**
* Sets the user stencil settings for the next draw.
* This class only stores pointers to stencil settings objects.
* The caller guarantees the pointer will remain valid until it
* changes or goes out of scope.
* @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); }
/**
* 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) {
if (enable) {
this->enableState(flags);
} else {
this->disableState(flags);
}
}
/// @}
///////////////////////////////////////////////////////////////////////////
/// @name Face Culling
////
/**
* 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.
*/
void setDrawFace(GrDrawFace face) {
SkASSERT(GrDrawFace::kInvalid != face);
fDrawFace = face;
}
/// @}
///////////////////////////////////////////////////////////////////////////
bool usePLSDstRead(const GrDrawBatch* batch) const;
private:
// Some of the auto restore objects assume that no effects are removed during their lifetime.
// This is used to assert that this condition holds.
SkDEBUGCODE(mutable int fBlockEffectRemovalCnt;)
typedef SkSTArray<4, sk_sp<GrFragmentProcessor>> FragmentProcessorArray;
uint32_t fFlags;
const GrUserStencilSettings* fUserStencilSettings;
GrDrawFace fDrawFace;
mutable sk_sp<GrXPFactory> fXPFactory;
FragmentProcessorArray fColorFragmentProcessors;
FragmentProcessorArray fCoverageFragmentProcessors;
friend class GrPipeline;
friend class GrDrawTarget;
};
#endif