Slightly generalize GPU hard stop gradient implementation.
With this CL we handle single off-center hardstop gradients. BUG=chromium:543625 GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=3303 Change-Id: Ic754e87469475ce15865c54055b8ed492e1d826d Reviewed-on: https://skia-review.googlesource.com/3303 Commit-Queue: Brian Salomon <bsalomon@google.com> Reviewed-by: Greg Daniel <egdaniel@google.com> Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
22f939e849
commit
466ad99868
@ -14,15 +14,16 @@
|
||||
* order to highlight the differences between tile modes, the gradient
|
||||
* starts and ends at 30 pixel inset from either side of the rectangle.
|
||||
*
|
||||
* | Clamp Repeat Mirror
|
||||
* ___________________________|___________________________________________
|
||||
* 2-color | rect00 rect01 rect02
|
||||
* 3-color even | rect10 rect11 rect12
|
||||
* 3-color texture | rect20 rect21 rect22
|
||||
* 5-color hard stop | rect30 rect31 rect32
|
||||
* 4-color hard stop centered | rect40 rect41 rect42
|
||||
* 3-color hard stop 001 | rect50 rect51 rect52
|
||||
* 3-color hard stop 011 | rect60 rect61 rect62
|
||||
* | Clamp Repeat Mirror
|
||||
* _____________________________|___________________________________________
|
||||
* 2-color | rect00 rect01 rect02
|
||||
* 3-color even | rect10 rect11 rect12
|
||||
* 3-color texture | rect20 rect21 rect22
|
||||
* 5-color hard stop | rect30 rect31 rect32
|
||||
* 4-color hard stop centered | rect40 rect41 rect42
|
||||
* 3-color hard stop 001 | rect50 rect51 rect52
|
||||
* 3-color hard stop 011 | rect60 rect61 rect62
|
||||
* 4-color hard stop off-center | rect70 rect71 rect72
|
||||
*
|
||||
* The first three rows are cases covered by pre-hard-stop code; simple
|
||||
* 2-color gradients, 3-color gradients with the middle color centered,
|
||||
@ -32,7 +33,7 @@
|
||||
* is a generic hard stop gradient, while the three subsequent rows deal
|
||||
* with special cases of hard stop gradients; centered hard stop gradients
|
||||
* (with t-values 0, 0.5, 0.5, 1), and two edge cases (with t-values
|
||||
* 0, 0, 1 and 0, 1, 1).
|
||||
* 0, 0, 1 and 0, 1, 1). The final row has a single off-center hard stop.
|
||||
*/
|
||||
|
||||
#include "gm.h"
|
||||
@ -42,7 +43,7 @@
|
||||
const int WIDTH = 500;
|
||||
const int HEIGHT = 500;
|
||||
|
||||
const int NUM_ROWS = 7;
|
||||
const int NUM_ROWS = 8;
|
||||
const int NUM_COLS = 3;
|
||||
|
||||
const int CELL_WIDTH = WIDTH / NUM_COLS;
|
||||
@ -108,6 +109,7 @@ protected:
|
||||
SkScalar row5[] = {0.00f, 0.50f, 0.50f, 1.00f};
|
||||
SkScalar row6[] = {0.00f, 0.00f, 1.00f};
|
||||
SkScalar row7[] = {0.00f, 1.00f, 1.00f};
|
||||
SkScalar row8[] = {0.00f, 0.30f, 0.30f, 1.00f};
|
||||
|
||||
SkScalar* positions[NUM_ROWS] = {
|
||||
nullptr,
|
||||
@ -117,6 +119,7 @@ protected:
|
||||
row5,
|
||||
row6,
|
||||
row7,
|
||||
row8,
|
||||
};
|
||||
|
||||
int numGradientColors[NUM_ROWS] = {
|
||||
@ -127,6 +130,7 @@ protected:
|
||||
4,
|
||||
3,
|
||||
3,
|
||||
4,
|
||||
};
|
||||
|
||||
SkShader::TileMode tilemodes[NUM_COLS] = {
|
||||
|
@ -1125,7 +1125,7 @@ static inline bool close_to_one_half(const SkFixed& val) {
|
||||
static inline int color_type_to_color_count(GrGradientEffect::ColorType colorType) {
|
||||
switch (colorType) {
|
||||
#if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS
|
||||
case GrGradientEffect::kHardStopCentered_ColorType:
|
||||
case GrGradientEffect::kSingleHardStop_ColorType:
|
||||
return 4;
|
||||
case GrGradientEffect::kHardStopLeftEdged_ColorType:
|
||||
case GrGradientEffect::kHardStopRightEdged_ColorType:
|
||||
@ -1149,11 +1149,10 @@ GrGradientEffect::ColorType GrGradientEffect::determineColorType(
|
||||
if (shader.fOrigPos) {
|
||||
if (4 == shader.fColorCount) {
|
||||
if (SkScalarNearlyEqual(shader.fOrigPos[0], 0.0f) &&
|
||||
SkScalarNearlyEqual(shader.fOrigPos[1], 0.5f) &&
|
||||
SkScalarNearlyEqual(shader.fOrigPos[2], 0.5f) &&
|
||||
SkScalarNearlyEqual(shader.fOrigPos[1], shader.fOrigPos[2]) &&
|
||||
SkScalarNearlyEqual(shader.fOrigPos[3], 1.0f)) {
|
||||
|
||||
return kHardStopCentered_ColorType;
|
||||
return kSingleHardStop_ColorType;
|
||||
}
|
||||
} else if (3 == shader.fColorCount) {
|
||||
if (SkScalarNearlyEqual(shader.fOrigPos[0], 0.0f) &&
|
||||
@ -1191,6 +1190,10 @@ void GrGradientEffect::GLSLProcessor::emitUniforms(GrGLSLUniformHandler* uniform
|
||||
kDefault_GrSLPrecision,
|
||||
"Colors",
|
||||
colorCount);
|
||||
if (ge.fColorType == kSingleHardStop_ColorType) {
|
||||
fHardStopT = uniformHandler->addUniform(kFragment_GrShaderFlag, kFloat_GrSLType,
|
||||
kDefault_GrSLPrecision, "HardStopT");
|
||||
}
|
||||
} else {
|
||||
fFSYUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
|
||||
kFloat_GrSLType, kDefault_GrSLPrecision,
|
||||
@ -1291,7 +1294,9 @@ void GrGradientEffect::GLSLProcessor::onSetData(const GrGLSLProgramDataManager&
|
||||
|
||||
switch (e.getColorType()) {
|
||||
#if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS
|
||||
case GrGradientEffect::kHardStopCentered_ColorType:
|
||||
case GrGradientEffect::kSingleHardStop_ColorType:
|
||||
pdman.set1f(fHardStopT, e.fPositions[1]);
|
||||
// fall through
|
||||
case GrGradientEffect::kHardStopLeftEdged_ColorType:
|
||||
case GrGradientEffect::kHardStopRightEdged_ColorType:
|
||||
#endif
|
||||
@ -1347,7 +1352,7 @@ uint32_t GrGradientEffect::GLSLProcessor::GenBaseGradientKey(const GrProcessor&
|
||||
key |= kThreeColorKey;
|
||||
}
|
||||
#if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS
|
||||
else if (GrGradientEffect::kHardStopCentered_ColorType == e.getColorType()) {
|
||||
else if (GrGradientEffect::kSingleHardStop_ColorType == e.getColorType()) {
|
||||
key |= kHardStopCenteredKey;
|
||||
} else if (GrGradientEffect::kHardStopLeftEdged_ColorType == e.getColorType()) {
|
||||
key |= kHardStopZeroZeroOneKey;
|
||||
@ -1379,9 +1384,10 @@ void GrGradientEffect::GLSLProcessor::emitColor(GrGLSLFPFragmentBuilder* fragBui
|
||||
const TextureSamplers& texSamplers) {
|
||||
switch (ge.getColorType()) {
|
||||
#if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS
|
||||
case kHardStopCentered_ColorType: {
|
||||
case kSingleHardStop_ColorType: {
|
||||
const char* t = gradientTValue;
|
||||
const char* colors = uniformHandler->getUniformCStr(fColorsUni);
|
||||
const char* stopT = uniformHandler->getUniformCStr(fHardStopT);
|
||||
|
||||
fragBuilder->codeAppendf("float clamp_t = clamp(%s, 0.0, 1.0);", t);
|
||||
|
||||
@ -1399,18 +1405,18 @@ void GrGradientEffect::GLSLProcessor::emitColor(GrGLSLFPFragmentBuilder* fragBui
|
||||
}
|
||||
|
||||
// Calculate color
|
||||
fragBuilder->codeAppendf("float relative_t = fract(2.0 * clamp_t);");
|
||||
if (SkShader::kClamp_TileMode == ge.fTileMode) {
|
||||
fragBuilder->codeAppendf("relative_t += step(1.0, %s);", t);
|
||||
}
|
||||
|
||||
fragBuilder->codeAppendf("vec4 start = %s[0];", colors);
|
||||
fragBuilder->codeAppendf("vec4 end = %s[1];", colors);
|
||||
fragBuilder->codeAppendf("if (clamp_t >= 0.5) {");
|
||||
fragBuilder->codeAppend ("vec4 start, end;");
|
||||
fragBuilder->codeAppend ("float relative_t;");
|
||||
fragBuilder->codeAppendf("if (clamp_t < %s) {", stopT);
|
||||
fragBuilder->codeAppendf(" start = %s[0];", colors);
|
||||
fragBuilder->codeAppendf(" end = %s[1];", colors);
|
||||
fragBuilder->codeAppendf(" relative_t = clamp_t / %s;", stopT);
|
||||
fragBuilder->codeAppend ("} else {");
|
||||
fragBuilder->codeAppendf(" start = %s[2];", colors);
|
||||
fragBuilder->codeAppendf(" end = %s[3];", colors);
|
||||
fragBuilder->codeAppendf("}");
|
||||
fragBuilder->codeAppendf("vec4 colorTemp = mix(start, end, relative_t);");
|
||||
fragBuilder->codeAppendf(" relative_t = (clamp_t - %s) / (1 - %s);", stopT, stopT);
|
||||
fragBuilder->codeAppend ("}");
|
||||
fragBuilder->codeAppend ("vec4 colorTemp = mix(start, end, relative_t);");
|
||||
|
||||
if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) {
|
||||
fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;");
|
||||
@ -1599,7 +1605,7 @@ GrGradientEffect::GrGradientEffect(const CreateArgs& args) {
|
||||
#if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS
|
||||
case kHardStopLeftEdged_ColorType:
|
||||
case kHardStopRightEdged_ColorType:
|
||||
case kHardStopCentered_ColorType:
|
||||
case kSingleHardStop_ColorType:
|
||||
#endif
|
||||
fRow = -1;
|
||||
|
||||
@ -1683,36 +1689,38 @@ GrGradientEffect::~GrGradientEffect() {
|
||||
bool GrGradientEffect::onIsEqual(const GrFragmentProcessor& processor) const {
|
||||
const GrGradientEffect& ge = processor.cast<GrGradientEffect>();
|
||||
|
||||
if (this->fColorType == ge.getColorType()) {
|
||||
if (kTexture_ColorType == fColorType) {
|
||||
if (fYCoord != ge.getYCoord()) {
|
||||
if (this->fColorType != ge.getColorType()) {
|
||||
return false;
|
||||
}
|
||||
SkASSERT(this->useAtlas() == ge.useAtlas());
|
||||
if (kTexture_ColorType == fColorType) {
|
||||
if (fYCoord != ge.getYCoord()) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (kSingleHardStop_ColorType == fColorType) {
|
||||
if (!SkScalarNearlyEqual(ge.fPositions[1], fPositions[1])) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (this->getPremulType() != ge.getPremulType() ||
|
||||
this->fColors.count() != ge.fColors.count() ||
|
||||
this->fColors4f.count() != ge.fColors4f.count()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < this->fColors.count(); i++) {
|
||||
if (*this->getColors(i) != *ge.getColors(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < this->fColors4f.count(); i++) {
|
||||
if (*this->getColors4f(i) != *ge.getColors4f(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this->getPremulType() != ge.getPremulType() ||
|
||||
this->fColors.count() != ge.fColors.count() ||
|
||||
this->fColors4f.count() != ge.fColors4f.count()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
SkASSERT(this->useAtlas() == ge.useAtlas());
|
||||
return GrColorSpaceXform::Equals(this->fColorSpaceXform.get(), ge.fColorSpaceXform.get());
|
||||
for (int i = 0; i < this->fColors.count(); i++) {
|
||||
if (*this->getColors(i) != *ge.getColors(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < this->fColors4f.count(); i++) {
|
||||
if (*this->getColors4f(i) != *ge.getColors4f(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return GrColorSpaceXform::Equals(this->fColorSpaceXform.get(), ge.fColorSpaceXform.get());
|
||||
}
|
||||
|
||||
void GrGradientEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
|
||||
|
@ -363,7 +363,7 @@ public:
|
||||
kTexture_ColorType,
|
||||
|
||||
#if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS
|
||||
kHardStopCentered_ColorType, // 0, 0.5, 0.5, 1
|
||||
kSingleHardStop_ColorType, // 0, t, t, 1
|
||||
kHardStopLeftEdged_ColorType, // 0, 0, 1
|
||||
kHardStopRightEdged_ColorType, // 0, 1, 1
|
||||
#endif
|
||||
@ -510,6 +510,7 @@ private:
|
||||
|
||||
SkScalar fCachedYCoord;
|
||||
GrGLSLProgramDataManager::UniformHandle fColorsUni;
|
||||
GrGLSLProgramDataManager::UniformHandle fHardStopT;
|
||||
GrGLSLProgramDataManager::UniformHandle fFSYUni;
|
||||
GrGLSLProgramDataManager::UniformHandle fColorSpaceXformUni;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user