Index: include/gpu/GrInvariantOutput.h |
diff --git a/include/gpu/GrInvariantOutput.h b/include/gpu/GrInvariantOutput.h |
index 4977333de4e80779432c0eb20289ad5065f47ae3..5bf929f2ae80af81e87722085aa364a6a4c4dfcf 100644 |
--- a/include/gpu/GrInvariantOutput.h |
+++ b/include/gpu/GrInvariantOutput.h |
@@ -79,6 +79,7 @@ public: |
}; |
void mulByUnknownOpaqueFourComponents() { |
+ SkDEBUGCODE(this->validate()); |
if (this->isOpaque()) { |
fValidFlags = kA_GrColorComponentFlag; |
fIsSingleComponent = false; |
@@ -87,26 +88,32 @@ public: |
// multiplied is opaque. |
this->mulByUnknownFourComponents(); |
} |
+ SkDEBUGCODE(this->validate()); |
} |
void mulByUnknownFourComponents() { |
+ SkDEBUGCODE(this->validate()); |
if (this->hasZeroAlpha()) { |
this->internalSetToTransparentBlack(); |
} else { |
this->internalSetToUnknown(); |
} |
+ SkDEBUGCODE(this->validate()); |
} |
void mulByUnknownSingleComponent() { |
+ SkDEBUGCODE(this->validate()); |
if (this->hasZeroAlpha()) { |
this->internalSetToTransparentBlack(); |
} else { |
// We don't need to change fIsSingleComponent in this case |
fValidFlags = 0; |
} |
+ SkDEBUGCODE(this->validate()); |
} |
void mulByKnownSingleComponent(uint8_t alpha) { |
+ SkDEBUGCODE(this->validate()); |
if (this->hasZeroAlpha() || 0 == alpha) { |
this->internalSetToTransparentBlack(); |
} else { |
@@ -116,20 +123,92 @@ public: |
SkMulDiv255Round(GrColorUnpackG(fColor), alpha), |
SkMulDiv255Round(GrColorUnpackB(fColor), alpha), |
SkMulDiv255Round(GrColorUnpackA(fColor), alpha)); |
+ // We don't need to change fIsSingleComponent in this case |
} |
} |
+ SkDEBUGCODE(this->validate()); |
+ } |
+ |
+ void mulByKnownFourComponents(GrColor color) { |
+ SkDEBUGCODE(this->validate()); |
+ uint32_t a; |
+ if (GetAlphaAndCheckSingleChannel(color, &a)) { |
+ this->mulByKnownSingleComponent(a); |
+ } else { |
+ if (color != 0xffffffff) { |
+ fColor = GrColorPackRGBA( |
+ SkMulDiv255Round(GrColorUnpackR(fColor), GrColorUnpackR(color)), |
+ SkMulDiv255Round(GrColorUnpackG(fColor), GrColorUnpackG(color)), |
+ SkMulDiv255Round(GrColorUnpackB(fColor), GrColorUnpackB(color)), |
+ SkMulDiv255Round(GrColorUnpackA(fColor), a)); |
+ if (kRGBA_GrColorComponentFlags == fValidFlags) { |
+ fIsSingleComponent = GetAlphaAndCheckSingleChannel(fColor, &a); |
+ } |
+ } |
+ } |
+ SkDEBUGCODE(this->validate()); |
+ } |
+ |
+ // Ignores the incoming color's RGB and muls its alpha by color. |
+ void mulAlphaByKnownFourComponents(GrColor color) { |
+ SkDEBUGCODE(this->validate()); |
+ uint32_t a; |
+ if (GetAlphaAndCheckSingleChannel(color, &a)) { |
+ this->mulAlphaByKnownSingleComponent(a); |
+ } else if (fValidFlags & kA_GrColorComponentFlag) { |
+ GrColor preAlpha = GrColorUnpackA(fColor); |
+ if (0 == preAlpha) { |
+ this->internalSetToTransparentBlack(); |
+ } else { |
+ // We know that color has different component values |
+ fIsSingleComponent = false; |
+ fColor = GrColorPackRGBA( |
+ SkMulDiv255Round(preAlpha, GrColorUnpackR(color)), |
+ SkMulDiv255Round(preAlpha, GrColorUnpackG(color)), |
+ SkMulDiv255Round(preAlpha, GrColorUnpackB(color)), |
+ SkMulDiv255Round(preAlpha, a)); |
+ fValidFlags = kRGBA_GrColorComponentFlags; |
+ } |
+ } else { |
+ fIsSingleComponent = false; |
+ fValidFlags = 0; |
+ } |
+ SkDEBUGCODE(this->validate()); |
+ } |
+ |
+ // Ignores the incoming color's RGB and muls its alpha by the alpha param and sets all channels |
+ // equal to that value. |
+ void mulAlphaByKnownSingleComponent(uint8_t alpha) { |
+ SkDEBUGCODE(this->validate()); |
+ if (0 == alpha || this->hasZeroAlpha()) { |
+ this->internalSetToTransparentBlack(); |
+ } else { |
+ if (fValidFlags & kA_GrColorComponentFlag) { |
+ GrColor a = GrColorUnpackA(fColor); |
+ a = SkMulDiv255Round(alpha, a); |
+ fColor = GrColorPackRGBA(a, a, a, a); |
+ fValidFlags = kRGBA_GrColorComponentFlags; |
+ } else { |
+ fValidFlags = 0; |
+ } |
+ fIsSingleComponent = true; |
+ } |
+ SkDEBUGCODE(this->validate()); |
} |
void invalidateComponents(uint8_t invalidateFlags, ReadInput readsInput) { |
+ SkDEBUGCODE(this->validate()); |
fValidFlags &= ~invalidateFlags; |
fIsSingleComponent = false; |
fNonMulStageFound = true; |
if (kWillNot_ReadInput == readsInput) { |
fWillUseInputColor = false; |
} |
+ SkDEBUGCODE(this->validate()); |
} |
void setToOther(uint8_t validFlags, GrColor color, ReadInput readsInput) { |
+ SkDEBUGCODE(this->validate()); |
fValidFlags = validFlags; |
fColor = color; |
fIsSingleComponent = false; |
@@ -137,14 +216,28 @@ public: |
if (kWillNot_ReadInput == readsInput) { |
fWillUseInputColor = false; |
} |
+ if (kRGBA_GrColorComponentFlags == fValidFlags) { |
+ uint32_t a; |
+ if (GetAlphaAndCheckSingleChannel(color, &a)) { |
+ fIsSingleComponent = true; |
+ } |
+ } else if (kA_GrColorComponentFlag & fValidFlags) { |
+ // Assuming fColor is premul means if a is 0 the color must be all 0s. |
+ if (!GrColorUnpackA(fColor)) { |
+ this->internalSetToTransparentBlack(); |
+ } |
+ } |
+ SkDEBUGCODE(this->validate()); |
} |
void setToUnknown(ReadInput readsInput) { |
+ SkDEBUGCODE(this->validate()); |
this->internalSetToUnknown(); |
fNonMulStageFound= true; |
if (kWillNot_ReadInput == readsInput) { |
fWillUseInputColor = false; |
} |
+ SkDEBUGCODE(this->validate()); |
} |
// Temporary setter to handle LCD text correctly until we improve texture pixel config queries |
@@ -165,6 +258,13 @@ public: |
private: |
friend class GrProcOptInfo; |
+ /** Extracts the alpha channel and returns true if r,g,b == a. */ |
+ static bool GetAlphaAndCheckSingleChannel(GrColor color, uint32_t* alpha) { |
+ *alpha = GrColorUnpackA(color); |
+ return *alpha == GrColorUnpackR(color) && *alpha == GrColorUnpackG(color) && |
+ *alpha == GrColorUnpackB(color); |
+ } |
+ |
void reset(GrColor color, GrColorComponentFlags flags, bool isSingleComponent) { |
fColor = color; |
fValidFlags = flags; |