aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/gpu/SkGpuDevice.cpp58
-rw-r--r--src/gpu/SkGr.cpp37
-rw-r--r--src/gpu/SkGrPriv.h20
3 files changed, 73 insertions, 42 deletions
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 5289019cc9..e2feefc31e 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -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;
- }
- if (!SkPaintToGrPaintWithXfermode(this->context(), paint, *draw.fMatrix, colorMode, false,
- &grPaint)) {
- return;
+ // We have a shader, but no colors to blend it against.
+ if (!SkPaintToGrPaint(this->context(), paint, *draw.fMatrix, &grPaint)) {
+ return;
+ }
}
- } else if (!texs) {
- // Defined to ignore the shader unless texs is provided.
- if (!SkPaintToGrPaintNoShader(this->context(), paint, &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 (!SkPaintToGrPaint(this->context(), paint, *draw.fMatrix, &grPaint)) {
- return;
}
fDrawContext->drawVertices(fRenderTarget,
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index a726939788..ce1ce32eb3 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -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()));
diff --git a/src/gpu/SkGrPriv.h b/src/gpu/SkGrPriv.h
index 25fda57d9e..36601fc3e3 100644
--- a/src/gpu/SkGrPriv.h
+++ b/src/gpu/SkGrPriv.h
@@ -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