GrFP can express distance vector field req., program builder declares variable for it
This update allows fragment processors to require a field of vectors to the nearest edge. This requirement propagates: - from child FPs to their parent - from parent FPs to the GrPaint - from GrPaint through the PipelineBuilder into GrPipeline - acessed from GrPipeline by GrGLSLProgramBuilder GrGLSL generates a variable for the distance vector and passes it down to the GeometryProcessor->emitCode() method. This CL's base is the CL for adding the BevelNormalSource API: https://codereview.chromium.org/2080993002 BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2114993002 Committed: https://skia.googlesource.com/skia/+/4ef6dfa7089c092c67b0d5ec34e89c1e319af196 Review-Url: https://codereview.chromium.org/2114993002
This commit is contained in:
parent
6be452c800
commit
9b03e7b29d
@ -197,6 +197,7 @@
|
|||||||
'<(skia_src_path)/core/SkNormalFlatSource.h',
|
'<(skia_src_path)/core/SkNormalFlatSource.h',
|
||||||
'<(skia_src_path)/core/SkNormalSource.cpp',
|
'<(skia_src_path)/core/SkNormalSource.cpp',
|
||||||
'<(skia_src_path)/core/SkNormalSource.h',
|
'<(skia_src_path)/core/SkNormalSource.h',
|
||||||
|
'<(skia_src_path)/core/SkNormalSourcePriv.h',
|
||||||
'<(skia_src_path)/core/SkNx.h',
|
'<(skia_src_path)/core/SkNx.h',
|
||||||
'<(skia_src_path)/core/SkOpts.cpp',
|
'<(skia_src_path)/core/SkOpts.cpp',
|
||||||
'<(skia_src_path)/core/SkOpts.h',
|
'<(skia_src_path)/core/SkOpts.h',
|
||||||
|
@ -16,12 +16,14 @@
|
|||||||
'include_dirs': [
|
'include_dirs': [
|
||||||
'../include/effects',
|
'../include/effects',
|
||||||
'../include/client/android',
|
'../include/client/android',
|
||||||
|
'../include/gpu',
|
||||||
'../include/images',
|
'../include/images',
|
||||||
'../include/ports',
|
'../include/ports',
|
||||||
'../include/private',
|
'../include/private',
|
||||||
'../include/utils',
|
'../include/utils',
|
||||||
'../include/utils/win',
|
'../include/utils/win',
|
||||||
'../src/core',
|
'../src/core',
|
||||||
|
'../src/gpu',
|
||||||
'../src/image',
|
'../src/image',
|
||||||
'../src/lazy',
|
'../src/lazy',
|
||||||
'../src/ports',
|
'../src/ports',
|
||||||
|
@ -65,6 +65,7 @@ public:
|
|||||||
|
|
||||||
GrFragmentProcessor()
|
GrFragmentProcessor()
|
||||||
: INHERITED()
|
: INHERITED()
|
||||||
|
, fUsesDistanceVectorField(false)
|
||||||
, fUsesLocalCoords(false)
|
, fUsesLocalCoords(false)
|
||||||
, fNumTexturesExclChildren(0)
|
, fNumTexturesExclChildren(0)
|
||||||
, fNumBuffersExclChildren(0)
|
, fNumBuffersExclChildren(0)
|
||||||
@ -110,6 +111,9 @@ public:
|
|||||||
/** Do any of the coordtransforms for this processor require local coords? */
|
/** Do any of the coordtransforms for this processor require local coords? */
|
||||||
bool usesLocalCoords() const { return fUsesLocalCoords; }
|
bool usesLocalCoords() const { return fUsesLocalCoords; }
|
||||||
|
|
||||||
|
/** Does this FP need a vector to the nearest edge? */
|
||||||
|
bool usesDistanceVectorField() const { return fUsesDistanceVectorField; }
|
||||||
|
|
||||||
/** Returns true if this and other processor conservatively draw identically. It can only return
|
/** Returns true if this and other processor conservatively draw identically. It can only return
|
||||||
true when the two processor are of the same subclass (i.e. they return the same object from
|
true when the two processor are of the same subclass (i.e. they return the same object from
|
||||||
from getFactory()).
|
from getFactory()).
|
||||||
@ -173,6 +177,11 @@ protected:
|
|||||||
*/
|
*/
|
||||||
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const = 0;
|
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const = 0;
|
||||||
|
|
||||||
|
/* Sub-classes should set this to true in their constructors if they need access to a distance
|
||||||
|
* vector field to the nearest edge
|
||||||
|
*/
|
||||||
|
bool fUsesDistanceVectorField;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void notifyRefCntIsZero() const final;
|
void notifyRefCntIsZero() const final;
|
||||||
|
|
||||||
|
@ -77,6 +77,11 @@ public:
|
|||||||
void setAllowSRGBInputs(bool allowSRGBInputs) { fAllowSRGBInputs = allowSRGBInputs; }
|
void setAllowSRGBInputs(bool allowSRGBInputs) { fAllowSRGBInputs = allowSRGBInputs; }
|
||||||
bool getAllowSRGBInputs() const { return fAllowSRGBInputs; }
|
bool getAllowSRGBInputs() const { return fAllowSRGBInputs; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does one of the fragment processors need a field of distance vectors to the nearest edge?
|
||||||
|
*/
|
||||||
|
bool usesDistanceVectorField() const { return fUsesDistanceVectorField; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should rendering be gamma-correct, end-to-end. Causes sRGB render targets to behave
|
* Should rendering be gamma-correct, end-to-end. Causes sRGB render targets to behave
|
||||||
* as such (with linear blending), and sRGB inputs to be filtered and decoded correctly.
|
* as such (with linear blending), and sRGB inputs to be filtered and decoded correctly.
|
||||||
@ -101,6 +106,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
void addColorFragmentProcessor(sk_sp<GrFragmentProcessor> fp) {
|
void addColorFragmentProcessor(sk_sp<GrFragmentProcessor> fp) {
|
||||||
SkASSERT(fp);
|
SkASSERT(fp);
|
||||||
|
fUsesDistanceVectorField |= fp->usesDistanceVectorField();
|
||||||
fColorFragmentProcessors.push_back(std::move(fp));
|
fColorFragmentProcessors.push_back(std::move(fp));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,6 +115,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
void addCoverageFragmentProcessor(sk_sp<GrFragmentProcessor> fp) {
|
void addCoverageFragmentProcessor(sk_sp<GrFragmentProcessor> fp) {
|
||||||
SkASSERT(fp);
|
SkASSERT(fp);
|
||||||
|
fUsesDistanceVectorField |= fp->usesDistanceVectorField();
|
||||||
fCoverageFragmentProcessors.push_back(std::move(fp));
|
fCoverageFragmentProcessors.push_back(std::move(fp));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +149,7 @@ public:
|
|||||||
fAntiAlias = paint.fAntiAlias;
|
fAntiAlias = paint.fAntiAlias;
|
||||||
fDisableOutputConversionToSRGB = paint.fDisableOutputConversionToSRGB;
|
fDisableOutputConversionToSRGB = paint.fDisableOutputConversionToSRGB;
|
||||||
fAllowSRGBInputs = paint.fAllowSRGBInputs;
|
fAllowSRGBInputs = paint.fAllowSRGBInputs;
|
||||||
|
fUsesDistanceVectorField = paint.fUsesDistanceVectorField;
|
||||||
|
|
||||||
fColor = paint.fColor;
|
fColor = paint.fColor;
|
||||||
fColorFragmentProcessors = paint.fColorFragmentProcessors;
|
fColorFragmentProcessors = paint.fColorFragmentProcessors;
|
||||||
@ -168,6 +176,7 @@ private:
|
|||||||
bool fAntiAlias;
|
bool fAntiAlias;
|
||||||
bool fDisableOutputConversionToSRGB;
|
bool fDisableOutputConversionToSRGB;
|
||||||
bool fAllowSRGBInputs;
|
bool fAllowSRGBInputs;
|
||||||
|
bool fUsesDistanceVectorField;
|
||||||
|
|
||||||
GrColor4f fColor;
|
GrColor4f fColor;
|
||||||
};
|
};
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "SkNormalBevelSource.h"
|
#include "SkNormalBevelSource.h"
|
||||||
|
|
||||||
#include "SkNormalSource.h"
|
#include "SkNormalSource.h"
|
||||||
|
#include "SkNormalSourcePriv.h"
|
||||||
#include "SkPoint3.h"
|
#include "SkPoint3.h"
|
||||||
#include "SkReadBuffer.h"
|
#include "SkReadBuffer.h"
|
||||||
#include "SkWriteBuffer.h"
|
#include "SkWriteBuffer.h"
|
||||||
@ -25,17 +26,19 @@ public:
|
|||||||
, fWidth(width)
|
, fWidth(width)
|
||||||
, fHeight(height) {
|
, fHeight(height) {
|
||||||
this->initClassID<NormalBevelFP>();
|
this->initClassID<NormalBevelFP>();
|
||||||
|
|
||||||
|
fUsesDistanceVectorField = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
class GLSLNormalBevelFP : public GrGLSLFragmentProcessor {
|
class GLSLNormalBevelFP : public GLSLNormalFP {
|
||||||
public:
|
public:
|
||||||
GLSLNormalBevelFP() {
|
GLSLNormalBevelFP() {
|
||||||
fPrevWidth = SkFloatToScalar(0.0f);
|
fPrevWidth = SkFloatToScalar(0.0f);
|
||||||
fPrevHeight = SkFloatToScalar(0.0f);
|
fPrevHeight = SkFloatToScalar(0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void emitCode(EmitArgs& args) override {
|
void onEmitCode(EmitArgs& args) override {
|
||||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||||
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
|
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
|
||||||
|
|
||||||
const char* widthUniName = nullptr;
|
const char* widthUniName = nullptr;
|
||||||
@ -46,7 +49,7 @@ public:
|
|||||||
fHeightUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kFloat_GrSLType,
|
fHeightUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kFloat_GrSLType,
|
||||||
kDefault_GrSLPrecision, "Height", &heightUniName);
|
kDefault_GrSLPrecision, "Height", &heightUniName);
|
||||||
|
|
||||||
fragBuilder->codeAppendf("%s = vec4(0, 0, 1, 0);", args.fOutputColor);
|
fragBuilder->codeAppendf("%s = vec4(0.0, 0.0, 1.0, 0.0);", args.fOutputColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GenKey(const GrProcessor& proc, const GrGLSLCaps&,
|
static void GenKey(const GrProcessor& proc, const GrGLSLCaps&,
|
||||||
@ -56,7 +59,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override {
|
void setNormalData(const GrGLSLProgramDataManager& pdman,
|
||||||
|
const GrProcessor& proc) override {
|
||||||
const NormalBevelFP& normalBevelFP = proc.cast<NormalBevelFP>();
|
const NormalBevelFP& normalBevelFP = proc.cast<NormalBevelFP>();
|
||||||
|
|
||||||
if (fPrevWidth != normalBevelFP.fWidth) {
|
if (fPrevWidth != normalBevelFP.fWidth) {
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "SkNormalFlatSource.h"
|
#include "SkNormalFlatSource.h"
|
||||||
|
|
||||||
#include "SkNormalSource.h"
|
#include "SkNormalSource.h"
|
||||||
|
#include "SkNormalSourcePriv.h"
|
||||||
#include "SkPoint3.h"
|
#include "SkPoint3.h"
|
||||||
#include "SkReadBuffer.h"
|
#include "SkReadBuffer.h"
|
||||||
#include "SkWriteBuffer.h"
|
#include "SkWriteBuffer.h"
|
||||||
@ -23,12 +24,12 @@ public:
|
|||||||
this->initClassID<NormalFlatFP>();
|
this->initClassID<NormalFlatFP>();
|
||||||
}
|
}
|
||||||
|
|
||||||
class GLSLNormalFlatFP : public GrGLSLFragmentProcessor {
|
class GLSLNormalFlatFP : public GLSLNormalFP {
|
||||||
public:
|
public:
|
||||||
GLSLNormalFlatFP() {}
|
GLSLNormalFlatFP() {}
|
||||||
|
|
||||||
void emitCode(EmitArgs& args) override {
|
void onEmitCode(EmitArgs& args) override {
|
||||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||||
|
|
||||||
fragBuilder->codeAppendf("%s = vec4(0, 0, 1, 0);", args.fOutputColor);
|
fragBuilder->codeAppendf("%s = vec4(0, 0, 1, 0);", args.fOutputColor);
|
||||||
}
|
}
|
||||||
@ -39,7 +40,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override {}
|
void setNormalData(const GrGLSLProgramDataManager& pdman,
|
||||||
|
const GrProcessor& proc) override {}
|
||||||
};
|
};
|
||||||
|
|
||||||
void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override {
|
void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override {
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "SkLightingShader.h"
|
#include "SkLightingShader.h"
|
||||||
#include "SkMatrix.h"
|
#include "SkMatrix.h"
|
||||||
#include "SkNormalSource.h"
|
#include "SkNormalSource.h"
|
||||||
|
#include "SkNormalSourcePriv.h"
|
||||||
#include "SkPM4f.h"
|
#include "SkPM4f.h"
|
||||||
#include "SkReadBuffer.h"
|
#include "SkReadBuffer.h"
|
||||||
#include "SkWriteBuffer.h"
|
#include "SkWriteBuffer.h"
|
||||||
@ -31,13 +32,13 @@ public:
|
|||||||
this->initClassID<NormalMapFP>();
|
this->initClassID<NormalMapFP>();
|
||||||
}
|
}
|
||||||
|
|
||||||
class GLSLNormalMapFP : public GrGLSLFragmentProcessor {
|
class GLSLNormalMapFP : public GLSLNormalFP {
|
||||||
public:
|
public:
|
||||||
GLSLNormalMapFP()
|
GLSLNormalMapFP()
|
||||||
: fColumnMajorInvCTM22{0.0f} {}
|
: fColumnMajorInvCTM22{0.0f} {}
|
||||||
|
|
||||||
void emitCode(EmitArgs& args) override {
|
void onEmitCode(EmitArgs& args) override {
|
||||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||||
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
|
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
|
||||||
|
|
||||||
// add uniform
|
// add uniform
|
||||||
@ -78,7 +79,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override {
|
void setNormalData(const GrGLSLProgramDataManager& pdman,
|
||||||
|
const GrProcessor& proc) override {
|
||||||
const NormalMapFP& normalMapFP = proc.cast<NormalMapFP>();
|
const NormalMapFP& normalMapFP = proc.cast<NormalMapFP>();
|
||||||
|
|
||||||
const SkMatrix& invCTM = normalMapFP.invCTM();
|
const SkMatrix& invCTM = normalMapFP.invCTM();
|
||||||
|
@ -111,7 +111,7 @@ public:
|
|||||||
/** Returns a normal source that generates a bevel for the given shape. UNIMPLEMENTED: Will
|
/** Returns a normal source that generates a bevel for the given shape. UNIMPLEMENTED: Will
|
||||||
return straight-up normals only.
|
return straight-up normals only.
|
||||||
|
|
||||||
@param type the type of bevel to add
|
@param type the type of bevel to add.
|
||||||
@param width the width of the bevel, in source space. Must be positive.
|
@param width the width of the bevel, in source space. Must be positive.
|
||||||
@param height the height of the plateau, in source space. Can be positive, negative,
|
@param height the height of the plateau, in source space. Can be positive, negative,
|
||||||
or zero. A negative height means the simulated bevels slope downwards.
|
or zero. A negative height means the simulated bevels slope downwards.
|
||||||
|
57
src/core/SkNormalSourcePriv.h
Normal file
57
src/core/SkNormalSourcePriv.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 Google Inc.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license that can be
|
||||||
|
* found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SkNormalSourcePriv_DEFINED
|
||||||
|
#define SkNormalSourcePriv_DEFINED
|
||||||
|
|
||||||
|
#if SK_SUPPORT_GPU
|
||||||
|
#include "glsl/GrGLSLFragmentProcessor.h"
|
||||||
|
#include "glsl/GrGLSLFragmentShaderBuilder.h"
|
||||||
|
|
||||||
|
/* GLSLFragmentProcessors for NormalSourceImpls must sub-class this class and override onEmitCode,
|
||||||
|
* and setNormalData calls, as well as all other calls FPs normally override, except for the 2
|
||||||
|
* defined in this superclass.
|
||||||
|
* This class exists to intercept emitCode calls and emit <0, 0, 1> if the FP requires a distance
|
||||||
|
* vector but the GP doesn't provide it. onSetData calls need to be intercepted too because
|
||||||
|
* uniform handlers will be invalid in subclasses where onEmitCode isn't called.
|
||||||
|
* We don't need to adjust the key here since the use of a given GP (through its class ID already in
|
||||||
|
* the key), will determine what code gets emitted here.
|
||||||
|
*/
|
||||||
|
class GLSLNormalFP : public GrGLSLFragmentProcessor {
|
||||||
|
public:
|
||||||
|
GLSLNormalFP()
|
||||||
|
: fDidIntercept(false) {}
|
||||||
|
|
||||||
|
void emitCode(EmitArgs& args) final override {
|
||||||
|
if (args.fFp.usesDistanceVectorField() && !args.fGpImplementsDistanceVector) {
|
||||||
|
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||||
|
fragBuilder->codeAppendf("// GLSLNormalFP intercepted emitCode call, GP does not "
|
||||||
|
"implement required distance vector feature\n");
|
||||||
|
fragBuilder->codeAppendf("%s = vec4(0, 0, 1, 0);", args.fOutputColor);
|
||||||
|
|
||||||
|
fDidIntercept = true;
|
||||||
|
} else {
|
||||||
|
this->onEmitCode(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) final override {
|
||||||
|
if (!fDidIntercept) {
|
||||||
|
this->setNormalData(pdman, proc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void onEmitCode(EmitArgs& args) = 0;
|
||||||
|
virtual void setNormalData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool fDidIntercept;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -106,6 +106,9 @@ int GrFragmentProcessor::registerChildProcessor(sk_sp<GrFragmentProcessor> child
|
|||||||
if (child->usesLocalCoords()) {
|
if (child->usesLocalCoords()) {
|
||||||
fUsesLocalCoords = true;
|
fUsesLocalCoords = true;
|
||||||
}
|
}
|
||||||
|
if (child->usesDistanceVectorField()) {
|
||||||
|
fUsesDistanceVectorField = true;
|
||||||
|
}
|
||||||
|
|
||||||
int index = fChildProcessors.count();
|
int index = fChildProcessors.count();
|
||||||
fChildProcessors.push_back(child.release());
|
fChildProcessors.push_back(child.release());
|
||||||
|
@ -16,6 +16,7 @@ GrPaint::GrPaint()
|
|||||||
: fAntiAlias(false)
|
: fAntiAlias(false)
|
||||||
, fDisableOutputConversionToSRGB(false)
|
, fDisableOutputConversionToSRGB(false)
|
||||||
, fAllowSRGBInputs(false)
|
, fAllowSRGBInputs(false)
|
||||||
|
, fUsesDistanceVectorField(false)
|
||||||
, fColor(GrColor4f::FromGrColor(GrColor_WHITE)) {}
|
, fColor(GrColor4f::FromGrColor(GrColor_WHITE)) {}
|
||||||
|
|
||||||
void GrPaint::setCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage) {
|
void GrPaint::setCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage) {
|
||||||
|
@ -48,6 +48,9 @@ GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args,
|
|||||||
if (builder.getAllowSRGBInputs()) {
|
if (builder.getAllowSRGBInputs()) {
|
||||||
pipeline->fFlags |= kAllowSRGBInputs_Flag;
|
pipeline->fFlags |= kAllowSRGBInputs_Flag;
|
||||||
}
|
}
|
||||||
|
if (builder.getUsesDistanceVectorField()) {
|
||||||
|
pipeline->fFlags |= kUsesDistanceVectorField_Flag;
|
||||||
|
}
|
||||||
if (args.fHasStencilClip) {
|
if (args.fHasStencilClip) {
|
||||||
pipeline->fFlags |= kHasStencilClip_Flag;
|
pipeline->fFlags |= kHasStencilClip_Flag;
|
||||||
}
|
}
|
||||||
|
@ -160,6 +160,9 @@ public:
|
|||||||
bool getAllowSRGBInputs() const {
|
bool getAllowSRGBInputs() const {
|
||||||
return SkToBool(fFlags & kAllowSRGBInputs_Flag);
|
return SkToBool(fFlags & kAllowSRGBInputs_Flag);
|
||||||
}
|
}
|
||||||
|
bool usesDistanceVectorField() const {
|
||||||
|
return SkToBool(fFlags & kUsesDistanceVectorField_Flag);
|
||||||
|
}
|
||||||
bool hasStencilClip() const {
|
bool hasStencilClip() const {
|
||||||
return SkToBool(fFlags & kHasStencilClip_Flag);
|
return SkToBool(fFlags & kHasStencilClip_Flag);
|
||||||
}
|
}
|
||||||
@ -206,7 +209,8 @@ private:
|
|||||||
kSnapVertices_Flag = 0x2,
|
kSnapVertices_Flag = 0x2,
|
||||||
kDisableOutputConversionToSRGB_Flag = 0x4,
|
kDisableOutputConversionToSRGB_Flag = 0x4,
|
||||||
kAllowSRGBInputs_Flag = 0x8,
|
kAllowSRGBInputs_Flag = 0x8,
|
||||||
kHasStencilClip_Flag = 0x10
|
kUsesDistanceVectorField_Flag = 0x10,
|
||||||
|
kHasStencilClip_Flag = 0x20,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> RenderTarget;
|
typedef GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> RenderTarget;
|
||||||
|
@ -41,6 +41,8 @@ GrPipelineBuilder::GrPipelineBuilder(const GrPaint& paint, bool useHWAA)
|
|||||||
paint.getDisableOutputConversionToSRGB());
|
paint.getDisableOutputConversionToSRGB());
|
||||||
this->setState(GrPipelineBuilder::kAllowSRGBInputs_Flag,
|
this->setState(GrPipelineBuilder::kAllowSRGBInputs_Flag,
|
||||||
paint.getAllowSRGBInputs());
|
paint.getAllowSRGBInputs());
|
||||||
|
this->setState(GrPipelineBuilder::kUsesDistanceVectorField_Flag,
|
||||||
|
paint.usesDistanceVectorField());
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////s
|
//////////////////////////////////////////////////////////////////////////////s
|
||||||
|
@ -221,7 +221,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
kAllowSRGBInputs_Flag = 0x08,
|
kAllowSRGBInputs_Flag = 0x08,
|
||||||
|
|
||||||
kLast_Flag = kAllowSRGBInputs_Flag,
|
/**
|
||||||
|
* 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 isHWAntialias() const { return SkToBool(fFlags & kHWAntialias_Flag); }
|
||||||
@ -231,6 +237,8 @@ public:
|
|||||||
return SkToBool(fFlags & kDisableOutputConversionToSRGB_Flag); }
|
return SkToBool(fFlags & kDisableOutputConversionToSRGB_Flag); }
|
||||||
bool getAllowSRGBInputs() const {
|
bool getAllowSRGBInputs() const {
|
||||||
return SkToBool(fFlags & kAllowSRGBInputs_Flag); }
|
return SkToBool(fFlags & kAllowSRGBInputs_Flag); }
|
||||||
|
bool getUsesDistanceVectorField() const {
|
||||||
|
return SkToBool(fFlags & kUsesDistanceVectorField_Flag); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable render state settings.
|
* Enable render state settings.
|
||||||
|
@ -221,6 +221,10 @@ public:
|
|||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sub-class should override and return true if this primitive processor implements the distance
|
||||||
|
* vector field, a field of vectors to the nearest point in the edge of the shape. */
|
||||||
|
virtual bool implementsDistanceVector() const { return false; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GrPrimitiveProcessor() : fVertexStride(0) {}
|
GrPrimitiveProcessor() : fVertexStride(0) {}
|
||||||
|
|
||||||
|
@ -107,7 +107,8 @@ void GrGLSLFragmentProcessor::internalEmitChild(int childIndex, const char* inpu
|
|||||||
inputColor,
|
inputColor,
|
||||||
childCoords,
|
childCoords,
|
||||||
childTexSamplers,
|
childTexSamplers,
|
||||||
childBufferSamplers);
|
childBufferSamplers,
|
||||||
|
args.fGpImplementsDistanceVector);
|
||||||
this->childProcessor(childIndex)->emitCode(childArgs);
|
this->childProcessor(childIndex)->emitCode(childArgs);
|
||||||
fragBuilder->codeAppend("}\n");
|
fragBuilder->codeAppend("}\n");
|
||||||
|
|
||||||
|
@ -61,7 +61,8 @@ public:
|
|||||||
const char* inputColor,
|
const char* inputColor,
|
||||||
const GrGLSLTransformedCoordsArray& coords,
|
const GrGLSLTransformedCoordsArray& coords,
|
||||||
const SamplerHandle* texSamplers,
|
const SamplerHandle* texSamplers,
|
||||||
const SamplerHandle* bufferSamplers)
|
const SamplerHandle* bufferSamplers,
|
||||||
|
bool gpImplementsDistanceVector)
|
||||||
: fFragBuilder(fragBuilder)
|
: fFragBuilder(fragBuilder)
|
||||||
, fUniformHandler(uniformHandler)
|
, fUniformHandler(uniformHandler)
|
||||||
, fGLSLCaps(caps)
|
, fGLSLCaps(caps)
|
||||||
@ -70,7 +71,8 @@ public:
|
|||||||
, fInputColor(inputColor)
|
, fInputColor(inputColor)
|
||||||
, fCoords(coords)
|
, fCoords(coords)
|
||||||
, fTexSamplers(texSamplers)
|
, fTexSamplers(texSamplers)
|
||||||
, fBufferSamplers(bufferSamplers) {}
|
, fBufferSamplers(bufferSamplers)
|
||||||
|
, fGpImplementsDistanceVector(gpImplementsDistanceVector){}
|
||||||
GrGLSLFPFragmentBuilder* fFragBuilder;
|
GrGLSLFPFragmentBuilder* fFragBuilder;
|
||||||
GrGLSLUniformHandler* fUniformHandler;
|
GrGLSLUniformHandler* fUniformHandler;
|
||||||
const GrGLSLCaps* fGLSLCaps;
|
const GrGLSLCaps* fGLSLCaps;
|
||||||
@ -80,6 +82,7 @@ public:
|
|||||||
const GrGLSLTransformedCoordsArray& fCoords;
|
const GrGLSLTransformedCoordsArray& fCoords;
|
||||||
const SamplerHandle* fTexSamplers;
|
const SamplerHandle* fTexSamplers;
|
||||||
const SamplerHandle* fBufferSamplers;
|
const SamplerHandle* fBufferSamplers;
|
||||||
|
bool fGpImplementsDistanceVector;
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual void emitCode(EmitArgs&) = 0;
|
virtual void emitCode(EmitArgs&) = 0;
|
||||||
|
@ -189,6 +189,10 @@ const char* GrGLSLFragmentShaderBuilder::fragmentPosition() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* GrGLSLFragmentShaderBuilder::distanceVectorName() const {
|
||||||
|
return "fsDistanceVector";
|
||||||
|
}
|
||||||
|
|
||||||
void GrGLSLFragmentShaderBuilder::appendOffsetToSample(const char* sampleIdx, Coordinates coords) {
|
void GrGLSLFragmentShaderBuilder::appendOffsetToSample(const char* sampleIdx, Coordinates coords) {
|
||||||
SkASSERT(fProgramBuilder->header().fSamplePatternKey);
|
SkASSERT(fProgramBuilder->header().fSamplePatternKey);
|
||||||
SkDEBUGCODE(fUsedProcessorFeatures |= GrProcessor::kSampleLocations_RequiredFeature);
|
SkDEBUGCODE(fUsedProcessorFeatures |= GrProcessor::kSampleLocations_RequiredFeature);
|
||||||
|
@ -96,6 +96,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual void maskSampleCoverage(const char* mask, bool invert = false) = 0;
|
virtual void maskSampleCoverage(const char* mask, bool invert = false) = 0;
|
||||||
|
|
||||||
|
/** Returns a variable name that represents a vector to the nearest edge of the shape, in source
|
||||||
|
space coordinates. */
|
||||||
|
virtual const char* distanceVectorName() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fragment procs with child procs should call these functions before/after calling emitCode
|
* Fragment procs with child procs should call these functions before/after calling emitCode
|
||||||
* on a child proc.
|
* on a child proc.
|
||||||
@ -166,6 +170,7 @@ public:
|
|||||||
virtual SkString ensureFSCoords2D(const GrGLSLTransformedCoordsArray& coords,
|
virtual SkString ensureFSCoords2D(const GrGLSLTransformedCoordsArray& coords,
|
||||||
int index) override;
|
int index) override;
|
||||||
const char* fragmentPosition() override;
|
const char* fragmentPosition() override;
|
||||||
|
const char* distanceVectorName() const override;
|
||||||
|
|
||||||
// GrGLSLFPFragmentBuilder interface.
|
// GrGLSLFPFragmentBuilder interface.
|
||||||
void appendOffsetToSample(const char* sampleIdx, Coordinates) override;
|
void appendOffsetToSample(const char* sampleIdx, Coordinates) override;
|
||||||
@ -235,6 +240,7 @@ private:
|
|||||||
bool fHasSecondaryOutput;
|
bool fHasSecondaryOutput;
|
||||||
uint8_t fUsedSampleOffsetArrays;
|
uint8_t fUsedSampleOffsetArrays;
|
||||||
bool fHasInitializedSampleMask;
|
bool fHasInitializedSampleMask;
|
||||||
|
SkString fDistanceVectorOutput;
|
||||||
|
|
||||||
#ifdef SK_DEBUG
|
#ifdef SK_DEBUG
|
||||||
// some state to verify shaders and effects are consistent, this is reset between effects by
|
// some state to verify shaders and effects are consistent, this is reset between effects by
|
||||||
|
@ -42,6 +42,7 @@ public:
|
|||||||
const GrPrimitiveProcessor& gp,
|
const GrPrimitiveProcessor& gp,
|
||||||
const char* outputColor,
|
const char* outputColor,
|
||||||
const char* outputCoverage,
|
const char* outputCoverage,
|
||||||
|
const char* distanceVectorName,
|
||||||
const SamplerHandle* texSamplers,
|
const SamplerHandle* texSamplers,
|
||||||
const SamplerHandle* bufferSamplers,
|
const SamplerHandle* bufferSamplers,
|
||||||
const TransformsIn& transformsIn,
|
const TransformsIn& transformsIn,
|
||||||
@ -54,6 +55,7 @@ public:
|
|||||||
, fGP(gp)
|
, fGP(gp)
|
||||||
, fOutputColor(outputColor)
|
, fOutputColor(outputColor)
|
||||||
, fOutputCoverage(outputCoverage)
|
, fOutputCoverage(outputCoverage)
|
||||||
|
, fDistanceVectorName(distanceVectorName)
|
||||||
, fTexSamplers(texSamplers)
|
, fTexSamplers(texSamplers)
|
||||||
, fBufferSamplers(bufferSamplers)
|
, fBufferSamplers(bufferSamplers)
|
||||||
, fTransformsIn(transformsIn)
|
, fTransformsIn(transformsIn)
|
||||||
@ -66,6 +68,7 @@ public:
|
|||||||
const GrPrimitiveProcessor& fGP;
|
const GrPrimitiveProcessor& fGP;
|
||||||
const char* fOutputColor;
|
const char* fOutputColor;
|
||||||
const char* fOutputCoverage;
|
const char* fOutputCoverage;
|
||||||
|
const char* fDistanceVectorName;
|
||||||
const SamplerHandle* fTexSamplers;
|
const SamplerHandle* fTexSamplers;
|
||||||
const SamplerHandle* fBufferSamplers;
|
const SamplerHandle* fBufferSamplers;
|
||||||
const TransformsIn& fTransformsIn;
|
const TransformsIn& fTransformsIn;
|
||||||
@ -78,7 +81,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual void emitCode(EmitArgs&) = 0;
|
virtual void emitCode(EmitArgs&) = 0;
|
||||||
|
|
||||||
|
|
||||||
/** A GrGLSLPrimitiveProcessor instance can be reused with any GrGLSLPrimitiveProcessor that
|
/** A GrGLSLPrimitiveProcessor instance can be reused with any GrGLSLPrimitiveProcessor that
|
||||||
produces the same stage key; this function reads data from a GrGLSLPrimitiveProcessor and
|
produces the same stage key; this function reads data from a GrGLSLPrimitiveProcessor and
|
||||||
uploads any uniform variables required by the shaders created in emitCode(). The
|
uploads any uniform variables required by the shaders created in emitCode(). The
|
||||||
|
@ -87,6 +87,13 @@ void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& pr
|
|||||||
this->nameExpression(outputColor, "outputColor");
|
this->nameExpression(outputColor, "outputColor");
|
||||||
this->nameExpression(outputCoverage, "outputCoverage");
|
this->nameExpression(outputCoverage, "outputCoverage");
|
||||||
|
|
||||||
|
const char* distanceVectorName = nullptr;
|
||||||
|
if (this->fPipeline.usesDistanceVectorField() && proc.implementsDistanceVector()) {
|
||||||
|
distanceVectorName = fFS.distanceVectorName();
|
||||||
|
fFS.codeAppend( "// Un-normalized vector to the closed geometric edge (in source space)\n");
|
||||||
|
fFS.codeAppendf("vec2 %s;", distanceVectorName);
|
||||||
|
}
|
||||||
|
|
||||||
// Enclose custom code in a block to avoid namespace conflicts
|
// Enclose custom code in a block to avoid namespace conflicts
|
||||||
SkString openBrace;
|
SkString openBrace;
|
||||||
openBrace.printf("{ // Stage %d, %s\n", fStageIndex, proc.name());
|
openBrace.printf("{ // Stage %d, %s\n", fStageIndex, proc.name());
|
||||||
@ -108,6 +115,7 @@ void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& pr
|
|||||||
proc,
|
proc,
|
||||||
outputColor->c_str(),
|
outputColor->c_str(),
|
||||||
outputCoverage->c_str(),
|
outputCoverage->c_str(),
|
||||||
|
distanceVectorName,
|
||||||
texSamplers.begin(),
|
texSamplers.begin(),
|
||||||
bufferSamplers.begin(),
|
bufferSamplers.begin(),
|
||||||
fCoordTransforms,
|
fCoordTransforms,
|
||||||
@ -161,7 +169,9 @@ void GrGLSLProgramBuilder::emitAndInstallFragProc(const GrFragmentProcessor& fp,
|
|||||||
input.isOnes() ? nullptr : input.c_str(),
|
input.isOnes() ? nullptr : input.c_str(),
|
||||||
fOutCoords[index],
|
fOutCoords[index],
|
||||||
texSamplers.begin(),
|
texSamplers.begin(),
|
||||||
bufferSamplers.begin());
|
bufferSamplers.begin(),
|
||||||
|
this->primitiveProcessor().implementsDistanceVector());
|
||||||
|
|
||||||
fragProc->emitCode(args);
|
fragProc->emitCode(args);
|
||||||
|
|
||||||
// We have to check that effects and the code they emit are consistent, ie if an effect
|
// We have to check that effects and the code they emit are consistent, ie if an effect
|
||||||
|
Loading…
Reference in New Issue
Block a user