Add blend optimization helpers and use to convert rect draws to clears.
R=robertphillips@google.com, jvanverth@google.com Author: bsalomon@google.com Review URL: https://chromiumcodereview.appspot.com/22558003 git-svn-id: http://skia.googlecode.com/svn/trunk@10723 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
2865c44570
commit
24ab3b0ce5
@ -55,6 +55,8 @@
|
||||
'<(skia_src_path)/gpu/GrAtlas.cpp',
|
||||
'<(skia_src_path)/gpu/GrAtlas.h',
|
||||
'<(skia_src_path)/gpu/GrBinHashKey.h',
|
||||
'<(skia_src_path)/gpu/GrBlend.cpp',
|
||||
'<(skia_src_path)/gpu/GrBlend.h',
|
||||
'<(skia_src_path)/gpu/GrBufferAllocPool.cpp',
|
||||
'<(skia_src_path)/gpu/GrBufferAllocPool.h',
|
||||
'<(skia_src_path)/gpu/GrCacheID.cpp',
|
||||
|
@ -470,6 +470,18 @@ public:
|
||||
return this->mapRect(rect, *rect);
|
||||
}
|
||||
|
||||
/** Apply this matrix to the src rectangle, and write the four transformed
|
||||
points into dst. The points written to dst will be the original top-left, top-right,
|
||||
bottom-right, and bottom-left points transformed by the matrix.
|
||||
@param dst Where the transformed quad is written.
|
||||
@param rect The original rectangle to be transformed.
|
||||
*/
|
||||
void mapRectToQuad(SkPoint dst[4], const SkRect& rect) const {
|
||||
// This could potentially be faster if we only transformed each x and y of the rect once.
|
||||
rect.toQuad(dst);
|
||||
this->mapPoints(dst, 4);
|
||||
}
|
||||
|
||||
/** Return the mean radius of a circle after it has been mapped by
|
||||
this matrix. NOTE: in perspective this value assumes the circle
|
||||
has its center at the origin.
|
||||
|
@ -466,8 +466,9 @@ struct SK_API SkRect {
|
||||
return !SkScalarsEqual((SkScalar*)&a, (SkScalar*)&b, 4);
|
||||
}
|
||||
|
||||
/** return the 4 points that enclose the rectangle
|
||||
*/
|
||||
/** return the 4 points that enclose the rectangle (top-left, top-right, bottom-right,
|
||||
bottom-left). TODO: Consider adding param to control whether quad is CW or CCW.
|
||||
*/
|
||||
void toQuad(SkPoint quad[4]) const;
|
||||
|
||||
/** Set this rectangle to the empty rectangle (0,0,0,0)
|
||||
|
@ -174,7 +174,28 @@ public:
|
||||
this->resetColorFilter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the drawing with this paint is opaque with respect to both color blending
|
||||
* and fractional coverage. It does not consider whether AA has been enabled on the paint or
|
||||
* not. Depending upon whether multisampling or coverage-based AA is in use, AA may make the
|
||||
* result only apply to the interior of primitives.
|
||||
*
|
||||
*/
|
||||
bool isOpaque() const;
|
||||
|
||||
/**
|
||||
* Returns true if isOpaque would return true and the paint represents a solid constant color
|
||||
* draw. If the result is true, constantColor will be updated to contain the constant color.
|
||||
*/
|
||||
bool isOpaqueAndConstantColor(GrColor* constantColor) const;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Helper for isOpaque and isOpaqueAndConstantColor.
|
||||
*/
|
||||
bool getOpaqueAndKnownColor(GrColor* solidColor, uint32_t* solidColorKnownComponents) const;
|
||||
|
||||
/**
|
||||
* Called when the source coord system from which geometry is rendered changes. It ensures that
|
||||
* the local coordinates seen by effects remains unchanged. oldToNew gives the transformation
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "GrTypes.h"
|
||||
#include "GrResource.h"
|
||||
#include "SkRect.h"
|
||||
|
||||
class GrTexture;
|
||||
class GrRenderTarget;
|
||||
@ -33,6 +34,12 @@ public:
|
||||
*/
|
||||
int height() const { return fDesc.fHeight; }
|
||||
|
||||
/**
|
||||
* Helper that gets the width and height of the surface as a bounding rectangle.
|
||||
*/
|
||||
void getBoundsRect(SkRect* rect) const { rect->setWH(SkIntToScalar(this->width()),
|
||||
SkIntToScalar(this->height())); }
|
||||
|
||||
GrSurfaceOrigin origin() const {
|
||||
GrAssert(kTopLeft_GrSurfaceOrigin == fDesc.fOrigin || kBottomLeft_GrSurfaceOrigin == fDesc.fOrigin);
|
||||
return fDesc.fOrigin;
|
||||
|
154
src/gpu/GrBlend.cpp
Normal file
154
src/gpu/GrBlend.cpp
Normal file
@ -0,0 +1,154 @@
|
||||
|
||||
/*
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "GrBlend.h"
|
||||
|
||||
static inline GrBlendCoeff swap_coeff_src_dst(GrBlendCoeff coeff) {
|
||||
switch (coeff) {
|
||||
case kDC_GrBlendCoeff:
|
||||
return kSC_GrBlendCoeff;
|
||||
case kIDC_GrBlendCoeff:
|
||||
return kISC_GrBlendCoeff;
|
||||
case kDA_GrBlendCoeff:
|
||||
return kSA_GrBlendCoeff;
|
||||
case kIDA_GrBlendCoeff:
|
||||
return kISA_GrBlendCoeff;
|
||||
case kSC_GrBlendCoeff:
|
||||
return kDC_GrBlendCoeff;
|
||||
case kISC_GrBlendCoeff:
|
||||
return kIDC_GrBlendCoeff;
|
||||
case kSA_GrBlendCoeff:
|
||||
return kDA_GrBlendCoeff;
|
||||
case kISA_GrBlendCoeff:
|
||||
return kIDA_GrBlendCoeff;
|
||||
default:
|
||||
return coeff;
|
||||
}
|
||||
}
|
||||
|
||||
static inline unsigned saturated_add(unsigned a, unsigned b) {
|
||||
SkASSERT(a <= 255);
|
||||
SkASSERT(b <= 255);
|
||||
unsigned sum = a + b;
|
||||
if (sum > 255) {
|
||||
sum = 255;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
static GrColor add_colors(GrColor src, GrColor dst) {
|
||||
unsigned r = saturated_add(GrColorUnpackR(src), GrColorUnpackR(dst));
|
||||
unsigned g = saturated_add(GrColorUnpackG(src), GrColorUnpackG(dst));
|
||||
unsigned b = saturated_add(GrColorUnpackB(src), GrColorUnpackB(dst));
|
||||
unsigned a = saturated_add(GrColorUnpackA(src), GrColorUnpackA(dst));
|
||||
return GrColorPackRGBA(r, g, b, a);
|
||||
}
|
||||
|
||||
static inline bool valid_color(uint32_t compFlags) {
|
||||
return (kRGBA_GrColorComponentFlags & compFlags) == kRGBA_GrColorComponentFlags;
|
||||
}
|
||||
|
||||
static GrColor simplify_blend_term(GrBlendCoeff* srcCoeff,
|
||||
GrColor srcColor, uint32_t srcCompFlags,
|
||||
GrColor dstColor, uint32_t dstCompFlags,
|
||||
GrColor constantColor) {
|
||||
|
||||
GrAssert(!GrBlendCoeffRefsSrc(*srcCoeff));
|
||||
GrAssert(NULL != srcCoeff);
|
||||
|
||||
// Check whether srcCoeff can be reduced to kOne or kZero based on known color inputs.
|
||||
// We could pick out the coeff r,g,b,a values here and use them to compute the blend term color,
|
||||
// if possible, below but that is not implemented now.
|
||||
switch (*srcCoeff) {
|
||||
case kIDC_GrBlendCoeff:
|
||||
dstColor = ~dstColor; // fallthrough
|
||||
case kDC_GrBlendCoeff:
|
||||
if (valid_color(dstCompFlags)) {
|
||||
if (0xffffffff == dstColor) {
|
||||
*srcCoeff = kOne_GrBlendCoeff;
|
||||
} else if (0 == dstColor) {
|
||||
*srcCoeff = kZero_GrBlendCoeff;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case kIDA_GrBlendCoeff:
|
||||
dstColor = ~dstColor; // fallthrough
|
||||
case kDA_GrBlendCoeff:
|
||||
if (kA_GrColorComponentFlag & dstCompFlags) {
|
||||
if (0xff == GrColorUnpackA(dstColor)) {
|
||||
*srcCoeff = kOne_GrBlendCoeff;
|
||||
} else if (0 == GrColorUnpackA(dstColor)) {
|
||||
*srcCoeff = kZero_GrBlendCoeff;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case kIConstC_GrBlendCoeff:
|
||||
constantColor = ~constantColor; // fallthrough
|
||||
case kConstC_GrBlendCoeff:
|
||||
if (0xffffffff == constantColor) {
|
||||
*srcCoeff = kOne_GrBlendCoeff;
|
||||
} else if (0 == constantColor) {
|
||||
*srcCoeff = kZero_GrBlendCoeff;
|
||||
}
|
||||
break;
|
||||
|
||||
case kIConstA_GrBlendCoeff:
|
||||
constantColor = ~constantColor; // fallthrough
|
||||
case kConstA_GrBlendCoeff:
|
||||
if (0xff == GrColorUnpackA(constantColor)) {
|
||||
*srcCoeff = kOne_GrBlendCoeff;
|
||||
} else if (0 == GrColorUnpackA(constantColor)) {
|
||||
*srcCoeff = kZero_GrBlendCoeff;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// We may have invalidated these above and shouldn't read them again.
|
||||
GR_DEBUGCODE(dstColor = constantColor = GrColor_ILLEGAL;)
|
||||
|
||||
if (kZero_GrBlendCoeff == *srcCoeff || (valid_color(srcCompFlags) && 0 == srcColor)) {
|
||||
*srcCoeff = kZero_GrBlendCoeff;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (kOne_GrBlendCoeff == *srcCoeff && valid_color(srcCompFlags)) {
|
||||
return srcColor;
|
||||
} else {
|
||||
return GrColor_ILLEGAL;
|
||||
}
|
||||
}
|
||||
|
||||
GrColor GrSimplifyBlend(GrBlendCoeff* srcCoeff,
|
||||
GrBlendCoeff* dstCoeff,
|
||||
GrColor srcColor, uint32_t srcCompFlags,
|
||||
GrColor dstColor, uint32_t dstCompFlags,
|
||||
GrColor constantColor) {
|
||||
GrColor srcTermColor = simplify_blend_term(srcCoeff,
|
||||
srcColor, srcCompFlags,
|
||||
dstColor, dstCompFlags,
|
||||
constantColor);
|
||||
|
||||
// We call the same function to simplify the dst blend coeff. We trick it out by swapping the
|
||||
// src and dst.
|
||||
GrBlendCoeff spoofedCoeff = swap_coeff_src_dst(*dstCoeff);
|
||||
GrColor dstTermColor = simplify_blend_term(&spoofedCoeff,
|
||||
dstColor, dstCompFlags,
|
||||
srcColor, srcCompFlags,
|
||||
constantColor);
|
||||
*dstCoeff = swap_coeff_src_dst(spoofedCoeff);
|
||||
|
||||
if (GrColor_ILLEGAL != srcTermColor && GrColor_ILLEGAL != dstTermColor) {
|
||||
return add_colors(srcTermColor, dstTermColor);
|
||||
} else {
|
||||
return GrColor_ILLEGAL;
|
||||
}
|
||||
}
|
45
src/gpu/GrBlend.h
Normal file
45
src/gpu/GrBlend.h
Normal file
@ -0,0 +1,45 @@
|
||||
|
||||
/*
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "GrTypes.h"
|
||||
#include "GrColor.h"
|
||||
|
||||
#ifndef GrBlend_DEFINED
|
||||
#define GrBlend_DEFINED
|
||||
|
||||
static inline bool GrBlendCoeffRefsSrc(GrBlendCoeff coeff) {
|
||||
switch (coeff) {
|
||||
case kSC_GrBlendCoeff:
|
||||
case kISC_GrBlendCoeff:
|
||||
case kSA_GrBlendCoeff:
|
||||
case kISA_GrBlendCoeff:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool GrBlendCoeffRefsDst(GrBlendCoeff coeff) {
|
||||
switch (coeff) {
|
||||
case kDC_GrBlendCoeff:
|
||||
case kIDC_GrBlendCoeff:
|
||||
case kDA_GrBlendCoeff:
|
||||
case kIDA_GrBlendCoeff:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
GrColor GrSimplifyBlend(GrBlendCoeff* srcCoeff,
|
||||
GrBlendCoeff* dstCoeff,
|
||||
GrColor srcColor, uint32_t srcCompFlags,
|
||||
GrColor dstColor, uint32_t dstCompFlags,
|
||||
GrColor constantColor);
|
||||
|
||||
#endif
|
@ -681,9 +681,8 @@ static bool isIRect(const SkRect& r) {
|
||||
static bool apply_aa_to_rect(GrDrawTarget* target,
|
||||
const SkRect& rect,
|
||||
SkScalar strokeWidth,
|
||||
const SkMatrix* matrix,
|
||||
SkMatrix* combinedMatrix,
|
||||
SkRect* devRect,
|
||||
const SkMatrix& combinedMatrix,
|
||||
SkRect* devBoundRect,
|
||||
bool* useVertexCoverage) {
|
||||
// we use a simple coverage ramp to do aa on axis-aligned rects
|
||||
// we check if the rect will be axis-aligned, and the rect won't land on
|
||||
@ -716,52 +715,32 @@ static bool apply_aa_to_rect(GrDrawTarget* target,
|
||||
#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT)
|
||||
if (strokeWidth >= 0) {
|
||||
#endif
|
||||
if (!drawState.getViewMatrix().preservesAxisAlignment()) {
|
||||
if (!combinedMatrix.preservesAxisAlignment()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NULL != matrix && !matrix->preservesAxisAlignment()) {
|
||||
return false;
|
||||
}
|
||||
#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT)
|
||||
} else {
|
||||
if (!drawState.getViewMatrix().preservesAxisAlignment() &&
|
||||
!drawState.getViewMatrix().preservesRightAngles()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NULL != matrix && !matrix->preservesRightAngles()) {
|
||||
if (!combinedMatrix.preservesRightAngles()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
*combinedMatrix = drawState.getViewMatrix();
|
||||
if (NULL != matrix) {
|
||||
combinedMatrix->preConcat(*matrix);
|
||||
|
||||
#if GR_DEBUG
|
||||
#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT)
|
||||
if (strokeWidth >= 0) {
|
||||
#endif
|
||||
GrAssert(combinedMatrix->preservesAxisAlignment());
|
||||
#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT)
|
||||
} else {
|
||||
GrAssert(combinedMatrix->preservesRightAngles());
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
combinedMatrix->mapRect(devRect, rect);
|
||||
combinedMatrix.mapRect(devBoundRect, rect);
|
||||
|
||||
if (strokeWidth < 0) {
|
||||
return !isIRect(*devRect);
|
||||
return !isIRect(*devBoundRect);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& point) {
|
||||
return point.fX >= rect.fLeft && point.fX <= rect.fRight &&
|
||||
point.fY >= rect.fTop && point.fY <= rect.fBottom;
|
||||
}
|
||||
|
||||
void GrContext::drawRect(const GrPaint& paint,
|
||||
const SkRect& rect,
|
||||
SkScalar width,
|
||||
@ -771,13 +750,51 @@ void GrContext::drawRect(const GrPaint& paint,
|
||||
AutoRestoreEffects are;
|
||||
GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are);
|
||||
|
||||
SkRect devRect;
|
||||
SkMatrix combinedMatrix;
|
||||
SkMatrix combinedMatrix = target->drawState()->getViewMatrix();
|
||||
if (NULL != matrix) {
|
||||
combinedMatrix.preConcat(*matrix);
|
||||
}
|
||||
|
||||
// Check if this is a full RT draw and can be replaced with a clear. We don't bother checking
|
||||
// cases where the RT is fully inside a stroke.
|
||||
if (width < 0) {
|
||||
SkRect rtRect;
|
||||
target->getDrawState().getRenderTarget()->getBoundsRect(&rtRect);
|
||||
SkRect clipSpaceRTRect = rtRect;
|
||||
bool checkClip = false;
|
||||
if (NULL != this->getClip()) {
|
||||
checkClip = true;
|
||||
clipSpaceRTRect.offset(SkIntToScalar(this->getClip()->fOrigin.fX),
|
||||
SkIntToScalar(this->getClip()->fOrigin.fY));
|
||||
}
|
||||
// Does the clip contain the entire RT?
|
||||
if (!checkClip || target->getClip()->fClipStack->quickContains(clipSpaceRTRect)) {
|
||||
SkMatrix invM;
|
||||
if (!combinedMatrix.invert(&invM)) {
|
||||
return;
|
||||
}
|
||||
// Does the rect bound the RT?
|
||||
SkPoint srcSpaceRTQuad[4];
|
||||
invM.mapRectToQuad(srcSpaceRTQuad, rtRect);
|
||||
if (rect_contains_inclusive(rect, srcSpaceRTQuad[0]) &&
|
||||
rect_contains_inclusive(rect, srcSpaceRTQuad[1]) &&
|
||||
rect_contains_inclusive(rect, srcSpaceRTQuad[2]) &&
|
||||
rect_contains_inclusive(rect, srcSpaceRTQuad[3])) {
|
||||
// Will it blend?
|
||||
GrColor clearColor;
|
||||
if (paint.isOpaqueAndConstantColor(&clearColor)) {
|
||||
target->clear(NULL, clearColor);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SkRect devBoundRect;
|
||||
bool useVertexCoverage;
|
||||
bool needAA = paint.isAntiAlias() &&
|
||||
!target->getDrawState().getRenderTarget()->isMultisampled();
|
||||
bool doAA = needAA && apply_aa_to_rect(target, rect, width, matrix,
|
||||
&combinedMatrix, &devRect,
|
||||
bool doAA = needAA && apply_aa_to_rect(target, rect, width, combinedMatrix, &devBoundRect,
|
||||
&useVertexCoverage);
|
||||
if (doAA) {
|
||||
GrDrawState::AutoViewMatrixRestore avmr;
|
||||
@ -786,12 +803,12 @@ void GrContext::drawRect(const GrPaint& paint,
|
||||
}
|
||||
if (width >= 0) {
|
||||
fAARectRenderer->strokeAARect(this->getGpu(), target,
|
||||
rect, combinedMatrix, devRect,
|
||||
rect, combinedMatrix, devBoundRect,
|
||||
width, useVertexCoverage);
|
||||
} else {
|
||||
// filled AA rect
|
||||
fAARectRenderer->fillAARect(this->getGpu(), target,
|
||||
rect, combinedMatrix, devRect,
|
||||
rect, combinedMatrix, devBoundRect,
|
||||
useVertexCoverage);
|
||||
}
|
||||
return;
|
||||
|
@ -9,6 +9,7 @@
|
||||
#define GrDrawState_DEFINED
|
||||
|
||||
#include "GrBackendEffectFactory.h"
|
||||
#include "GrBlend.h"
|
||||
#include "GrColor.h"
|
||||
#include "GrEffectStage.h"
|
||||
#include "GrPaint.h"
|
||||
@ -469,27 +470,11 @@ public:
|
||||
fCommon.fSrcBlend = srcCoeff;
|
||||
fCommon.fDstBlend = dstCoeff;
|
||||
#if GR_DEBUG
|
||||
switch (dstCoeff) {
|
||||
case kDC_GrBlendCoeff:
|
||||
case kIDC_GrBlendCoeff:
|
||||
case kDA_GrBlendCoeff:
|
||||
case kIDA_GrBlendCoeff:
|
||||
GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
|
||||
"coverage stages.\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (GrBlendCoeffRefsDst(dstCoeff)) {
|
||||
GrPrintf("Unexpected dst blend coeff. Won't work correctly with coverage stages.\n");
|
||||
}
|
||||
switch (srcCoeff) {
|
||||
case kSC_GrBlendCoeff:
|
||||
case kISC_GrBlendCoeff:
|
||||
case kSA_GrBlendCoeff:
|
||||
case kISA_GrBlendCoeff:
|
||||
GrPrintf("Unexpected src blend coeff. Won't work correctly with"
|
||||
"coverage stages.\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (GrBlendCoeffRefsSrc(srcCoeff)) {
|
||||
GrPrintf("Unexpected src blend coeff. Won't work correctly with coverage stages.\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "GrPaint.h"
|
||||
|
||||
#include "GrBlend.h"
|
||||
#include "effects/GrSimpleTextureEffect.h"
|
||||
|
||||
void GrPaint::addColorTextureEffect(GrTexture* texture, const SkMatrix& matrix) {
|
||||
@ -33,3 +34,96 @@ void GrPaint::addCoverageTextureEffect(GrTexture* texture,
|
||||
GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
|
||||
this->addCoverageEffect(effect)->unref();
|
||||
}
|
||||
|
||||
bool GrPaint::isOpaque() const {
|
||||
return this->getOpaqueAndKnownColor(NULL, NULL);
|
||||
}
|
||||
|
||||
bool GrPaint::isOpaqueAndConstantColor(GrColor* color) const {
|
||||
GrColor tempColor;
|
||||
uint32_t colorComps;
|
||||
if (this->getOpaqueAndKnownColor(&tempColor, &colorComps)) {
|
||||
if (kRGBA_GrColorComponentFlags == colorComps) {
|
||||
*color = tempColor;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GrPaint::getOpaqueAndKnownColor(GrColor* solidColor,
|
||||
uint32_t* solidColorKnownComponents) const {
|
||||
|
||||
// TODO: Share this implementation with GrDrawState
|
||||
|
||||
// Since fColorFilterXfermode is going away soon, we aren't attempting to handle anything but
|
||||
// the default setting.
|
||||
if (SkXfermode::kDst_Mode != fColorFilterXfermode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GrColor coverage = GrColorPackRGBA(fCoverage, fCoverage, fCoverage, fCoverage);
|
||||
uint32_t coverageComps = kRGBA_GrColorComponentFlags;
|
||||
int count = fCoverageStages.count();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
(*fCoverageStages[i].getEffect())->getConstantColorComponents(&coverage, &coverageComps);
|
||||
}
|
||||
if (kRGBA_GrColorComponentFlags != coverageComps || 0xffffffff != coverage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GrColor color = fColor;
|
||||
uint32_t colorComps = kRGBA_GrColorComponentFlags;
|
||||
count = fColorStages.count();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
(*fColorStages[i].getEffect())->getConstantColorComponents(&color, &colorComps);
|
||||
}
|
||||
|
||||
GrAssert((NULL == solidColor) == (NULL == solidColorKnownComponents));
|
||||
|
||||
GrBlendCoeff srcCoeff = fSrcBlendCoeff;
|
||||
GrBlendCoeff dstCoeff = fDstBlendCoeff;
|
||||
GrSimplifyBlend(&srcCoeff, &dstCoeff, color, colorComps, 0, 0, 0);
|
||||
|
||||
bool opaque = kZero_GrBlendCoeff == dstCoeff && !GrBlendCoeffRefsDst(srcCoeff);
|
||||
if (NULL != solidColor) {
|
||||
if (opaque) {
|
||||
switch (srcCoeff) {
|
||||
case kZero_GrBlendCoeff:
|
||||
*solidColor = 0;
|
||||
*solidColorKnownComponents = kRGBA_GrColorComponentFlags;
|
||||
break;
|
||||
|
||||
case kOne_GrBlendCoeff:
|
||||
*solidColor = color;
|
||||
*solidColorKnownComponents = colorComps;
|
||||
break;
|
||||
|
||||
// The src coeff should never refer to the src and if it refers to dst then opaque
|
||||
// should have been false.
|
||||
case kSC_GrBlendCoeff:
|
||||
case kISC_GrBlendCoeff:
|
||||
case kDC_GrBlendCoeff:
|
||||
case kIDC_GrBlendCoeff:
|
||||
case kSA_GrBlendCoeff:
|
||||
case kISA_GrBlendCoeff:
|
||||
case kDA_GrBlendCoeff:
|
||||
case kIDA_GrBlendCoeff:
|
||||
default:
|
||||
GrCrash("srcCoeff should not refer to src or dst.");
|
||||
break;
|
||||
|
||||
// TODO: update this once GrPaint actually has a const color.
|
||||
case kConstC_GrBlendCoeff:
|
||||
case kIConstC_GrBlendCoeff:
|
||||
case kConstA_GrBlendCoeff:
|
||||
case kIConstA_GrBlendCoeff:
|
||||
*solidColorKnownComponents = 0;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
solidColorKnownComponents = 0;
|
||||
}
|
||||
}
|
||||
return opaque;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user