Fix drawVertices when there is a paint alpha
Review URL: https://codereview.chromium.org/1382753002
This commit is contained in:
parent
5827653e42
commit
aa48d36397
@ -1742,42 +1742,50 @@ void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
|
||||
|
||||
SkAutoSTMalloc<128, GrColor> convertedColors(0);
|
||||
if (colors) {
|
||||
// need to convert byte order and from non-PM to PM
|
||||
// need to convert byte order and from non-PM to PM. TODO: Keep unpremul until after
|
||||
// interpolation.
|
||||
convertedColors.reset(vertexCount);
|
||||
SkColor color;
|
||||
for (int i = 0; i < vertexCount; ++i) {
|
||||
color = colors[i];
|
||||
if (paint.getAlpha() != 255) {
|
||||
color = SkColorSetA(color, SkMulDiv255Round(SkColorGetA(color), paint.getAlpha()));
|
||||
}
|
||||
/// TODO: Perform the premul after interpolating
|
||||
convertedColors[i] = SkColorToPremulGrColor(color);
|
||||
convertedColors[i] = SkColorToPremulGrColor(colors[i]);
|
||||
}
|
||||
colors = convertedColors.get();
|
||||
}
|
||||
GrPaint grPaint;
|
||||
if (texs && colors && paint.getShader()) {
|
||||
// When there are texs and colors the shader and colors are combined using xmode. A null
|
||||
// xmode is defined to mean modulate.
|
||||
SkXfermode::Mode colorMode;
|
||||
if (xmode) {
|
||||
if (!xmode->asMode(&colorMode)) {
|
||||
if (texs && paint.getShader()) {
|
||||
if (colors) {
|
||||
// When there are texs and colors the shader and colors are combined using xmode. A null
|
||||
// xmode is defined to mean modulate.
|
||||
SkXfermode::Mode colorMode;
|
||||
if (xmode) {
|
||||
if (!xmode->asMode(&colorMode)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
colorMode = SkXfermode::kModulate_Mode;
|
||||
}
|
||||
if (!SkPaintToGrPaintWithXfermode(this->context(), paint, *draw.fMatrix, colorMode,
|
||||
false, &grPaint)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
colorMode = SkXfermode::kModulate_Mode;
|
||||
// We have a shader, but no colors to blend it against.
|
||||
if (!SkPaintToGrPaint(this->context(), paint, *draw.fMatrix, &grPaint)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!SkPaintToGrPaintWithXfermode(this->context(), paint, *draw.fMatrix, colorMode, false,
|
||||
&grPaint)) {
|
||||
return;
|
||||
} else {
|
||||
if (colors) {
|
||||
// We have colors, but either have no shader or no texture coords (which implies that
|
||||
// we should ignore the shader).
|
||||
if (!SkPaintToGrPaintWithPrimitiveColor(this->context(), paint, &grPaint)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// No colors and no shaders. Just draw with the paint color.
|
||||
if (!SkPaintToGrPaintNoShader(this->context(), paint, &grPaint)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (!texs) {
|
||||
// Defined to ignore the shader unless texs is provided.
|
||||
if (!SkPaintToGrPaintNoShader(this->context(), paint, &grPaint)) {
|
||||
return;
|
||||
}
|
||||
} else if (!SkPaintToGrPaint(this->context(), paint, *draw.fMatrix, &grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fDrawContext->drawVertices(fRenderTarget,
|
||||
|
@ -677,6 +677,14 @@ bool GrPixelConfig2ColorAndProfileType(GrPixelConfig config, SkColorType* ctOut,
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline bool blend_requires_shader(const SkXfermode::Mode mode, bool primitiveIsSrc) {
|
||||
if (primitiveIsSrc) {
|
||||
return SkXfermode::kSrc_Mode != mode;
|
||||
} else {
|
||||
return SkXfermode::kDst_Mode != mode;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool skpaint_to_grpaint_impl(GrContext* context,
|
||||
const SkPaint& skPaint,
|
||||
const SkMatrix& viewM,
|
||||
@ -689,15 +697,18 @@ static inline bool skpaint_to_grpaint_impl(GrContext* context,
|
||||
// Setup the initial color considering the shader, the SkPaint color, and the presence or not
|
||||
// of per-vertex colors.
|
||||
SkAutoTUnref<const GrFragmentProcessor> aufp;
|
||||
const GrFragmentProcessor* shaderFP = NULL;
|
||||
if (shaderProcessor) {
|
||||
shaderFP = *shaderProcessor;
|
||||
} else if (const SkShader* shader = skPaint.getShader()) {
|
||||
aufp.reset(shader->asFragmentProcessor(context, viewM, NULL, skPaint.getFilterQuality(),
|
||||
grPaint->getProcessorDataManager()));
|
||||
shaderFP = aufp;
|
||||
if (!shaderFP) {
|
||||
return false;
|
||||
const GrFragmentProcessor* shaderFP = nullptr;
|
||||
if (!primColorMode || blend_requires_shader(*primColorMode, primitiveIsSrc)) {
|
||||
if (shaderProcessor) {
|
||||
shaderFP = *shaderProcessor;
|
||||
} else if (const SkShader* shader = skPaint.getShader()) {
|
||||
aufp.reset(shader->asFragmentProcessor(context, viewM, nullptr,
|
||||
skPaint.getFilterQuality(),
|
||||
grPaint->getProcessorDataManager()));
|
||||
shaderFP = aufp;
|
||||
if (!shaderFP) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -761,11 +772,13 @@ static inline bool skpaint_to_grpaint_impl(GrContext* context,
|
||||
grPaint->addColorFragmentProcessor(processor);
|
||||
}
|
||||
|
||||
grPaint->setColor(SkColorToUnpremulGrColor(skPaint.getColor()) | 0xFF000000);
|
||||
grPaint->setColor(SkColorToOpaqueGrColor(skPaint.getColor()));
|
||||
|
||||
GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor());
|
||||
grPaint->addColorFragmentProcessor(GrConstColorProcessor::Create(
|
||||
paintAlpha, GrConstColorProcessor::kModulateRGBA_InputMode))->unref();
|
||||
if (GrColor_WHITE != paintAlpha) {
|
||||
grPaint->addColorFragmentProcessor(GrConstColorProcessor::Create(
|
||||
paintAlpha, GrConstColorProcessor::kModulateRGBA_InputMode))->unref();
|
||||
}
|
||||
} else {
|
||||
// No shader, no primitive color.
|
||||
grPaint->setColor(SkColorToPremulGrColor(skPaint.getColor()));
|
||||
|
@ -54,19 +54,20 @@ void GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID, const SkIRect& ima
|
||||
bool GrMakeStretchedKey(const GrUniqueKey& origKey, const SkGrStretch&, GrUniqueKey* stretchedKey);
|
||||
|
||||
/** Converts an SkPaint to a GrPaint for a given GrContext. The matrix is required in order
|
||||
to convert the SkShader (if any) on the SkPaint. */
|
||||
to convert the SkShader (if any) on the SkPaint. The primitive itself has no color. */
|
||||
bool SkPaintToGrPaint(GrContext*,
|
||||
const SkPaint& skPaint,
|
||||
const SkMatrix& viewM,
|
||||
GrPaint* grPaint);
|
||||
|
||||
/** Ignores the SkShader (if any) on skPaint. */
|
||||
/** Same as above but ignores the SkShader (if any) on skPaint. */
|
||||
bool SkPaintToGrPaintNoShader(GrContext* context,
|
||||
const SkPaint& skPaint,
|
||||
GrPaint* grPaint);
|
||||
|
||||
/** Replaces the SkShader (if any) on skPaint with the passed in GrFragmentProcessor. The processor
|
||||
should expect an unpremul input color and produce a premultiplied output color. */
|
||||
should expect an unpremul input color and produce a premultiplied output color. There is
|
||||
no primitive color. */
|
||||
bool SkPaintToGrPaintReplaceShader(GrContext*,
|
||||
const SkPaint& skPaint,
|
||||
const GrFragmentProcessor* shaderFP,
|
||||
@ -75,8 +76,7 @@ bool SkPaintToGrPaintReplaceShader(GrContext*,
|
||||
/** Blends the SkPaint's shader (or color if no shader) with the color which specified via a
|
||||
GrBatch's GrPrimitiveProcesssor. Currently there is a bool param to indicate whether the
|
||||
primitive color is the dst or src color to the blend in order to work around differences between
|
||||
drawVertices and drawAtlas.
|
||||
*/
|
||||
drawVertices and drawAtlas. */
|
||||
bool SkPaintToGrPaintWithXfermode(GrContext* context,
|
||||
const SkPaint& skPaint,
|
||||
const SkMatrix& viewM,
|
||||
@ -84,6 +84,16 @@ bool SkPaintToGrPaintWithXfermode(GrContext* context,
|
||||
bool primitiveIsSrc,
|
||||
GrPaint* grPaint);
|
||||
|
||||
/** This is used when there is a primitive color, but the shader should be ignored. Currently,
|
||||
the expectation is that the primitive color will be premultiplied, though it really should be
|
||||
unpremultiplied so that interpolation is done in unpremul space. The paint's alpha will be
|
||||
applied to the primitive color after interpolation. */
|
||||
inline bool SkPaintToGrPaintWithPrimitiveColor(GrContext* context, const SkPaint& skPaint,
|
||||
GrPaint* grPaint) {
|
||||
return SkPaintToGrPaintWithXfermode(context, skPaint, SkMatrix::I(), SkXfermode::kDst_Mode,
|
||||
false, grPaint);
|
||||
}
|
||||
|
||||
bool GrTextureUsageSupported(const GrCaps&, int width, int height, SkImageUsageType);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user