Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(256)

Unified Diff: src/gpu/SkGr.cpp

Issue 1348583002: Make skpaint->grpaint flow work for composing draws (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: remove unused inheriteds to satisfy clang Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/SkGpuDevice.cpp ('k') | src/gpu/SkGrPriv.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/SkGr.cpp
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 09c83b929a8c575b1a2b9e15116c76abc4968c5c..e0892d8ab974e88db4034b429cba09727ab8cb93 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -24,8 +24,10 @@
#include "SkTextureCompressor.h"
#include "SkYUVPlanesCache.h"
#include "effects/GrBicubicEffect.h"
+#include "effects/GrConstColorProcessor.h"
#include "effects/GrDitherEffect.h"
#include "effects/GrPorterDuffXferProcessor.h"
+#include "effects/GrXfermodeFragmentProcessor.h"
#include "effects/GrYUVtoRGBEffect.h"
#ifndef SK_IGNORE_ETC1_SUPPORT
@@ -706,46 +708,132 @@ bool GrPixelConfig2ColorAndProfileType(GrPixelConfig config, SkColorType* ctOut,
return true;
}
-///////////////////////////////////////////////////////////////////////////////
-bool SkPaint2GrPaintNoShader(GrContext* context, const SkPaint& skPaint, GrColor paintColor,
- bool constantColor, GrPaint* grPaint) {
+////////////////////////////////////////////////////////////////////////////////////////////////
+static inline bool skpaint_to_grpaint_impl(GrContext* context,
+ const SkPaint& skPaint,
+ const SkMatrix& viewM,
+ const GrFragmentProcessor** shaderProcessor,
+ SkXfermode::Mode* primColorMode,
+ bool primitiveIsSrc,
+ GrPaint* grPaint) {
grPaint->setAntiAlias(skPaint.isAntiAlias());
- SkXfermode* mode = skPaint.getXfermode();
- GrXPFactory* xpFactory = nullptr;
- if (!SkXfermode::AsXPFactory(mode, &xpFactory)) {
- // Fall back to src-over
- // return false here?
- xpFactory = GrPorterDuffXPFactory::Create(SkXfermode::kSrcOver_Mode);
+ // 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;
+ }
}
- SkASSERT(xpFactory);
- grPaint->setXPFactory(xpFactory)->unref();
- //set the color of the paint to the one of the parameter
- grPaint->setColor(paintColor);
+ // Set this in below cases if the output of the shader/paint-color/paint-alpha/primXfermode is
+ // a known constant value. In that case we can simply apply a color filter during this
+ // conversion without converting the color filter to a GrFragmentProcessor.
+ bool applyColorFilterToPaintColor = false;
+ if (shaderFP) {
+ if (primColorMode) {
+ // There is a blend between the primitive color and the shader color. The shader sees
+ // the opaque paint color. The shader's output is blended using the provided mode by
+ // the primitive color. The blended color is then modulated by the paint's alpha.
+
+ // The geometry processor will insert the primitive color to start the color chain, so
+ // the GrPaint color will be ignored.
+
+ GrColor shaderInput = SkColorToOpaqueGrColor(skPaint.getColor());
+
+ shaderFP = GrFragmentProcessor::OverrideInput(shaderFP, shaderInput);
+ aufp.reset(shaderFP);
+
+ if (primitiveIsSrc) {
+ shaderFP = GrXfermodeFragmentProcessor::CreateFromDstProcessor(shaderFP,
+ *primColorMode);
+ } else {
+ shaderFP = GrXfermodeFragmentProcessor::CreateFromSrcProcessor(shaderFP,
+ *primColorMode);
+ }
+ aufp.reset(shaderFP);
+ // The above may return null if compose results in a pass through of the prim color.
+ if (shaderFP) {
+ grPaint->addColorFragmentProcessor(shaderFP);
+ }
+
+ GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor());
+ if (GrColor_WHITE != paintAlpha) {
+ grPaint->addColorFragmentProcessor(GrConstColorProcessor::Create(
+ paintAlpha, GrConstColorProcessor::kModulateRGBA_InputMode))->unref();
+ }
+ } else {
+ // The shader's FP sees the paint unpremul color
+ grPaint->setColor(SkColorToUnpremulGrColor(skPaint.getColor()));
+ grPaint->addColorFragmentProcessor(shaderFP);
+ }
+ } else {
+ if (primColorMode) {
+ // There is a blend between the primitive color and the paint color. The blend considers
+ // the opaque paint color. The paint's alpha is applied to the post-blended color.
+ SkAutoTUnref<const GrFragmentProcessor> processor(
+ GrConstColorProcessor::Create(SkColorToOpaqueGrColor(skPaint.getColor()),
+ GrConstColorProcessor::kIgnore_InputMode));
+ if (primitiveIsSrc) {
+ processor.reset(GrXfermodeFragmentProcessor::CreateFromDstProcessor(processor,
+ *primColorMode));
+ } else {
+ processor.reset(GrXfermodeFragmentProcessor::CreateFromSrcProcessor(processor,
+ *primColorMode));
+
+ }
+ if (processor) {
+ grPaint->addColorFragmentProcessor(processor);
+ }
+
+ grPaint->setColor(SkColorToUnpremulGrColor(skPaint.getColor()) | 0xFF000000);
+
+ GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor());
+ grPaint->addColorFragmentProcessor(GrConstColorProcessor::Create(
+ paintAlpha, GrConstColorProcessor::kModulateRGBA_InputMode))->unref();
+ } else {
+ // No shader, no primitive color.
+ grPaint->setColor(SkColorToPremulGrColor(skPaint.getColor()));
+ applyColorFilterToPaintColor = true;
+ }
+ }
SkColorFilter* colorFilter = skPaint.getColorFilter();
if (colorFilter) {
- // if the source color is a constant then apply the filter here once rather than per pixel
- // in a shader.
- if (constantColor) {
- SkColor filtered = colorFilter->filterColor(skPaint.getColor());
- grPaint->setColor(SkColor2GrColor(filtered));
+ if (applyColorFilterToPaintColor) {
+ grPaint->setColor(SkColorToPremulGrColor(colorFilter->filterColor(skPaint.getColor())));
} else {
SkTDArray<const GrFragmentProcessor*> array;
- // return false if failed?
if (colorFilter->asFragmentProcessors(context, grPaint->getProcessorDataManager(),
&array)) {
for (int i = 0; i < array.count(); ++i) {
- grPaint->addColorFragmentProcessor(array[i]);
- array[i]->unref();
+ grPaint->addColorFragmentProcessor(array[i])->unref();
}
+ } else {
+ return false;
}
}
}
+ SkXfermode* mode = skPaint.getXfermode();
+ GrXPFactory* xpFactory = nullptr;
+ if (!SkXfermode::AsXPFactory(mode, &xpFactory)) {
+ // Fall back to src-over
+ // return false here?
+ xpFactory = GrPorterDuffXPFactory::Create(SkXfermode::kSrcOver_Mode);
+ }
+ SkASSERT(xpFactory);
+ grPaint->setXPFactory(xpFactory)->unref();
+
#ifndef SK_IGNORE_GPU_DITHER
if (skPaint.isDither() && grPaint->numColorFragmentProcessors() > 0) {
grPaint->addColorFragmentProcessor(GrDitherEffect::Create())->unref();
@@ -754,29 +842,49 @@ bool SkPaint2GrPaintNoShader(GrContext* context, const SkPaint& skPaint, GrColor
return true;
}
-bool SkPaint2GrPaint(GrContext* context,const SkPaint& skPaint, const SkMatrix& viewM,
- bool constantColor, GrPaint* grPaint) {
- SkShader* shader = skPaint.getShader();
- if (nullptr == shader) {
- return SkPaint2GrPaintNoShader(context, skPaint, SkColor2GrColor(skPaint.getColor()),
- constantColor, grPaint);
- }
-
- GrColor paintColor = SkColor2GrColor(skPaint.getColor());
+bool SkPaintToGrPaint(GrContext* context, const SkPaint& skPaint, const SkMatrix& viewM,
+ GrPaint* grPaint) {
+ return skpaint_to_grpaint_impl(context, skPaint, viewM, nullptr, nullptr, false, grPaint);
+}
- const GrFragmentProcessor* fp = shader->asFragmentProcessor(context, viewM, NULL,
- skPaint.getFilterQuality(), grPaint->getProcessorDataManager());
- if (!fp) {
+/** Replaces the SkShader (if any) on skPaint with the passed in GrFragmentProcessor. */
+bool SkPaintToGrPaintReplaceShader(GrContext* context,
+ const SkPaint& skPaint,
+ const GrFragmentProcessor* shaderFP,
+ GrPaint* grPaint) {
+ if (!shaderFP) {
return false;
}
- grPaint->addColorFragmentProcessor(fp)->unref();
- constantColor = false;
+ return skpaint_to_grpaint_impl(context, skPaint, SkMatrix::I(), &shaderFP, nullptr, false,
+ grPaint);
+}
+
+/** Ignores the SkShader (if any) on skPaint. */
+bool SkPaintToGrPaintNoShader(GrContext* context,
+ const SkPaint& skPaint,
+ GrPaint* grPaint) {
+ // Use a ptr to a nullptr to to indicate that the SkShader is ignored and not replaced.
+ static const GrFragmentProcessor* kNullShaderFP = nullptr;
+ static const GrFragmentProcessor** kIgnoreShader = &kNullShaderFP;
+ return skpaint_to_grpaint_impl(context, skPaint, SkMatrix::I(), kIgnoreShader, nullptr, false,
+ grPaint);
+}
- // The grcolor is automatically set when calling asFragmentProcessor.
- // If the shader can be seen as an effect it returns true and adds its effect to the grpaint.
- return SkPaint2GrPaintNoShader(context, skPaint, paintColor, constantColor, grPaint);
+/** Blends the SkPaint's shader (or color if no shader) with a per-primitive color which must
+be setup as a vertex attribute using the specified SkXfermode::Mode. */
+bool SkPaintToGrPaintWithXfermode(GrContext* context,
+ const SkPaint& skPaint,
+ const SkMatrix& viewM,
+ SkXfermode::Mode primColorMode,
+ bool primitiveIsSrc,
+ GrPaint* grPaint) {
+ return skpaint_to_grpaint_impl(context, skPaint, viewM, nullptr, &primColorMode, primitiveIsSrc,
+ grPaint);
}
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
SkImageInfo GrMakeInfoFromTexture(GrTexture* tex, int w, int h, bool isOpaque) {
#ifdef SK_DEBUG
const GrSurfaceDesc& desc = tex->desc();
« no previous file with comments | « src/gpu/SkGpuDevice.cpp ('k') | src/gpu/SkGrPriv.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698