Fix concentric 2pt conical gradient in GPU where r1 < r0
Bug: skia:7683 Change-Id: I6608e72fa695c855af6a6a447885c4889b09fc1d Reviewed-on: https://skia-review.googlesource.com/115042 Commit-Queue: Yuqian Li <liyuqian@google.com> Reviewed-by: Greg Daniel <egdaniel@google.com>
This commit is contained in:
parent
cb88470d82
commit
650dd901e1
@ -98,17 +98,26 @@ static sk_sp<SkShader> Make2ConicalInsideFlip(const SkPoint pts[2], const GradDa
|
|||||||
|
|
||||||
static sk_sp<SkShader> Make2ConicalInsideCenter(const SkPoint pts[2], const GradData& data,
|
static sk_sp<SkShader> Make2ConicalInsideCenter(const SkPoint pts[2], const GradData& data,
|
||||||
SkShader::TileMode tm, const SkMatrix& localMatrix) {
|
SkShader::TileMode tm, const SkMatrix& localMatrix) {
|
||||||
SkPoint center0, center1;
|
SkPoint center0;
|
||||||
center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
|
center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
|
||||||
SkScalarAve(pts[0].fY, pts[1].fY));
|
SkScalarAve(pts[0].fY, pts[1].fY));
|
||||||
center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
|
|
||||||
SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
|
|
||||||
return SkGradientShader::MakeTwoPointConical(center0, (pts[1].fX - pts[0].fX) / 7,
|
return SkGradientShader::MakeTwoPointConical(center0, (pts[1].fX - pts[0].fX) / 7,
|
||||||
center0, (pts[1].fX - pts[0].fX) / 2,
|
center0, (pts[1].fX - pts[0].fX) / 2,
|
||||||
data.fColors, data.fPos, data.fCount, tm,
|
data.fColors, data.fPos, data.fCount, tm,
|
||||||
0, &localMatrix);
|
0, &localMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static sk_sp<SkShader> Make2ConicalInsideCenterReversed(const SkPoint pts[2], const GradData& data,
|
||||||
|
SkShader::TileMode tm, const SkMatrix& localMatrix) {
|
||||||
|
SkPoint center0;
|
||||||
|
center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
|
||||||
|
SkScalarAve(pts[0].fY, pts[1].fY));
|
||||||
|
return SkGradientShader::MakeTwoPointConical(center0, (pts[1].fX - pts[0].fX) / 2,
|
||||||
|
center0, (pts[1].fX - pts[0].fX) / 7,
|
||||||
|
data.fColors, data.fPos, data.fCount, tm,
|
||||||
|
0, &localMatrix);
|
||||||
|
}
|
||||||
|
|
||||||
static sk_sp<SkShader> Make2ConicalZeroRad(const SkPoint pts[2], const GradData& data,
|
static sk_sp<SkShader> Make2ConicalZeroRad(const SkPoint pts[2], const GradData& data,
|
||||||
SkShader::TileMode tm, const SkMatrix& localMatrix) {
|
SkShader::TileMode tm, const SkMatrix& localMatrix) {
|
||||||
SkPoint center0, center1;
|
SkPoint center0, center1;
|
||||||
@ -270,6 +279,7 @@ constexpr GradMaker gGradMakersOutside[] = {
|
|||||||
constexpr GradMaker gGradMakersInside[] = {
|
constexpr GradMaker gGradMakersInside[] = {
|
||||||
Make2ConicalInside, Make2ConicalInsideFlip, Make2ConicalInsideCenter,
|
Make2ConicalInside, Make2ConicalInsideFlip, Make2ConicalInsideCenter,
|
||||||
Make2ConicalZeroRad, Make2ConicalZeroRadFlip, Make2ConicalZeroRadCenter,
|
Make2ConicalZeroRad, Make2ConicalZeroRadFlip, Make2ConicalZeroRadCenter,
|
||||||
|
Make2ConicalInsideCenterReversed
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr GradMaker gGradMakersEdgeCases[] = {
|
constexpr GradMaker gGradMakersEdgeCases[] = {
|
||||||
|
@ -92,7 +92,9 @@ public:
|
|||||||
bool isNativelyFocal() const { return this->isFocal() && fData.fFocalData.isNativelyFocal(); }
|
bool isNativelyFocal() const { return this->isFocal() && fData.fFocalData.isNativelyFocal(); }
|
||||||
|
|
||||||
// Note that focalX = f = r0 / (r0 - r1), so 1 - focalX > 0 == r0 < r1
|
// Note that focalX = f = r0 / (r0 - r1), so 1 - focalX > 0 == r0 < r1
|
||||||
bool isRadiusIncreasing() const { return this->isFocal() && 1 - fData.fFocalData.fFocalX > 0; }
|
bool isRadiusIncreasing() const {
|
||||||
|
return this->isFocal() ? 1 - fData.fFocalData.fFocalX > 0 : this->diffRadius() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void onGetGLSLProcessorKey(const GrShaderCaps& c, GrProcessorKeyBuilder* b) const override {
|
void onGetGLSLProcessorKey(const GrShaderCaps& c, GrProcessorKeyBuilder* b) const override {
|
||||||
@ -237,7 +239,8 @@ protected:
|
|||||||
const char* p = coords2D.c_str();
|
const char* p = coords2D.c_str();
|
||||||
|
|
||||||
if (effect.getType() == Type::kRadial) {
|
if (effect.getType() == Type::kRadial) {
|
||||||
fragBuilder->codeAppendf("half %s = length(%s) - %s;", tName, p, p0.c_str());
|
char sign = effect.diffRadius() < 0 ? '-' : '+';
|
||||||
|
fragBuilder->codeAppendf("half %s = %clength(%s) - %s;", tName, sign, p, p0.c_str());
|
||||||
} else {
|
} else {
|
||||||
// output will default to transparent black (we simply won't write anything
|
// output will default to transparent black (we simply won't write anything
|
||||||
// else to it if invalid, instead of discarding or returning prematurely)
|
// else to it if invalid, instead of discarding or returning prematurely)
|
||||||
@ -263,8 +266,9 @@ protected:
|
|||||||
void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& p) override {
|
void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& p) override {
|
||||||
INHERITED::onSetData(pdman, p);
|
INHERITED::onSetData(pdman, p);
|
||||||
const TwoPointConicalEffect& effect = p.cast<TwoPointConicalEffect>();
|
const TwoPointConicalEffect& effect = p.cast<TwoPointConicalEffect>();
|
||||||
// kRadialType should imply r1 - r0 = 1 (after our transformation) so r0 = r0 / (r1 - r0)
|
// kRadialType should imply |r1 - r0| = 1 (after our transformation)
|
||||||
SkASSERT(effect.getType() == Type::kStrip || SkScalarNearlyZero(effect.diffRadius() - 1));
|
SkASSERT(effect.getType() == Type::kStrip ||
|
||||||
|
SkScalarNearlyZero(SkTAbs(effect.diffRadius()) - 1));
|
||||||
pdman.set1f(fParamUni, effect.getType() == Type::kRadial ? effect.r0()
|
pdman.set1f(fParamUni, effect.getType() == Type::kRadial ? effect.r0()
|
||||||
: effect.r0() * effect.r0());
|
: effect.r0() * effect.r0());
|
||||||
}
|
}
|
||||||
@ -407,12 +411,14 @@ std::unique_ptr<GrFragmentProcessor> Gr2PtConicalGradientEffect::Make(
|
|||||||
TwoPointConicalEffect::Data::Data(const SkTwoPointConicalGradient& shader, SkMatrix& matrix) {
|
TwoPointConicalEffect::Data::Data(const SkTwoPointConicalGradient& shader, SkMatrix& matrix) {
|
||||||
fType = shader.getType();
|
fType = shader.getType();
|
||||||
if (fType == Type::kRadial) {
|
if (fType == Type::kRadial) {
|
||||||
SkScalar dr = shader.getDiffRadius();
|
// Map center to (0, 0)
|
||||||
// Map center to (0, 0) and scale dr to 1
|
|
||||||
matrix.postTranslate(-shader.getStartCenter().fX, -shader.getStartCenter().fY);
|
matrix.postTranslate(-shader.getStartCenter().fX, -shader.getStartCenter().fY);
|
||||||
|
|
||||||
|
// scale |fDiffRadius| to 1
|
||||||
|
SkScalar dr = shader.getDiffRadius();
|
||||||
matrix.postScale(1 / dr, 1 / dr);
|
matrix.postScale(1 / dr, 1 / dr);
|
||||||
fRadius0 = shader.getStartRadius() / dr;
|
fRadius0 = shader.getStartRadius() / dr;
|
||||||
fDiffRadius = 1;
|
fDiffRadius = dr < 0 ? -1 : 1;
|
||||||
} else if (fType == Type::kStrip) {
|
} else if (fType == Type::kStrip) {
|
||||||
fRadius0 = shader.getStartRadius() / shader.getCenterX1();
|
fRadius0 = shader.getStartRadius() / shader.getCenterX1();
|
||||||
fDiffRadius = 0;
|
fDiffRadius = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user