2014-11-12 16:35:25 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2014 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef GrInvariantOutput_DEFINED
|
|
|
|
#define GrInvariantOutput_DEFINED
|
|
|
|
|
|
|
|
#include "GrColor.h"
|
|
|
|
|
2014-12-11 23:44:02 +00:00
|
|
|
struct GrInitInvariantOutput {
|
|
|
|
GrInitInvariantOutput()
|
|
|
|
: fValidFlags(0)
|
|
|
|
, fColor(0)
|
|
|
|
, fIsSingleComponent(false)
|
|
|
|
, fIsLCDCoverage(false) {}
|
|
|
|
|
|
|
|
void setKnownFourComponents(GrColor color) {
|
|
|
|
fColor = color;
|
|
|
|
fValidFlags = kRGBA_GrColorComponentFlags;
|
|
|
|
fIsSingleComponent = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setUnknownFourComponents() {
|
|
|
|
fValidFlags = 0;
|
|
|
|
fIsSingleComponent = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setUnknownOpaqueFourComponents() {
|
|
|
|
fColor = 0xff << GrColor_SHIFT_A;
|
|
|
|
fValidFlags = kA_GrColorComponentFlag;
|
|
|
|
fIsSingleComponent = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setKnownSingleComponent(uint8_t alpha) {
|
|
|
|
fColor = GrColorPackRGBA(alpha, alpha, alpha, alpha);
|
|
|
|
fValidFlags = kRGBA_GrColorComponentFlags;
|
|
|
|
fIsSingleComponent = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setUnknownSingleComponent() {
|
|
|
|
fValidFlags = 0;
|
|
|
|
fIsSingleComponent = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setUsingLCDCoverage() { fIsLCDCoverage = true; }
|
|
|
|
|
|
|
|
uint32_t fValidFlags;
|
|
|
|
GrColor fColor;
|
|
|
|
bool fIsSingleComponent;
|
|
|
|
bool fIsLCDCoverage; // Temorary data member until texture pixel configs are updated
|
|
|
|
};
|
|
|
|
|
2014-11-12 16:35:25 +00:00
|
|
|
class GrInvariantOutput {
|
|
|
|
public:
|
|
|
|
GrInvariantOutput(GrColor color, GrColorComponentFlags flags, bool isSingleComponent)
|
2014-12-09 18:35:58 +00:00
|
|
|
: fColor(color)
|
|
|
|
, fValidFlags(flags)
|
|
|
|
, fIsSingleComponent(isSingleComponent)
|
|
|
|
, fNonMulStageFound(false)
|
|
|
|
, fWillUseInputColor(true)
|
|
|
|
, fIsLCDCoverage(false) {}
|
2014-11-12 16:35:25 +00:00
|
|
|
|
2014-12-11 23:44:02 +00:00
|
|
|
GrInvariantOutput(const GrInitInvariantOutput& io)
|
|
|
|
: fColor(io.fColor)
|
|
|
|
, fValidFlags(io.fValidFlags)
|
|
|
|
, fIsSingleComponent(io.fIsSingleComponent)
|
|
|
|
, fNonMulStageFound(false)
|
|
|
|
, fWillUseInputColor(false)
|
|
|
|
, fIsLCDCoverage(io.fIsLCDCoverage) {}
|
|
|
|
|
2014-11-12 16:35:25 +00:00
|
|
|
virtual ~GrInvariantOutput() {}
|
|
|
|
|
|
|
|
enum ReadInput {
|
|
|
|
kWill_ReadInput,
|
|
|
|
kWillNot_ReadInput,
|
|
|
|
};
|
|
|
|
|
2014-12-11 23:44:02 +00:00
|
|
|
void mulByUnknownOpaqueFourComponents() {
|
2014-11-12 16:35:25 +00:00
|
|
|
if (this->isOpaque()) {
|
|
|
|
fValidFlags = kA_GrColorComponentFlag;
|
|
|
|
fIsSingleComponent = false;
|
|
|
|
} else {
|
|
|
|
// Since the current state is not opaque we no longer care if the color being
|
|
|
|
// multiplied is opaque.
|
2014-12-11 23:44:02 +00:00
|
|
|
this->mulByUnknownFourComponents();
|
2014-11-12 16:35:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-11 23:44:02 +00:00
|
|
|
void mulByUnknownFourComponents() {
|
2014-11-12 16:35:25 +00:00
|
|
|
if (this->hasZeroAlpha()) {
|
|
|
|
this->internalSetToTransparentBlack();
|
|
|
|
} else {
|
|
|
|
this->internalSetToUnknown();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-11 23:44:02 +00:00
|
|
|
void mulByUnknownSingleComponent() {
|
2014-11-12 16:35:25 +00:00
|
|
|
if (this->hasZeroAlpha()) {
|
|
|
|
this->internalSetToTransparentBlack();
|
|
|
|
} else {
|
|
|
|
// We don't need to change fIsSingleComponent in this case
|
|
|
|
fValidFlags = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-11 23:44:02 +00:00
|
|
|
void mulByKnownSingleComponent(uint8_t alpha) {
|
2014-11-12 16:35:25 +00:00
|
|
|
if (this->hasZeroAlpha() || 0 == alpha) {
|
|
|
|
this->internalSetToTransparentBlack();
|
|
|
|
} else {
|
|
|
|
if (alpha != 255) {
|
|
|
|
// Multiply color by alpha
|
|
|
|
fColor = GrColorPackRGBA(SkMulDiv255Round(GrColorUnpackR(fColor), alpha),
|
|
|
|
SkMulDiv255Round(GrColorUnpackG(fColor), alpha),
|
|
|
|
SkMulDiv255Round(GrColorUnpackB(fColor), alpha),
|
|
|
|
SkMulDiv255Round(GrColorUnpackA(fColor), alpha));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void invalidateComponents(uint8_t invalidateFlags, ReadInput readsInput) {
|
|
|
|
fValidFlags &= ~invalidateFlags;
|
|
|
|
fIsSingleComponent = false;
|
|
|
|
fNonMulStageFound = true;
|
|
|
|
if (kWillNot_ReadInput == readsInput) {
|
|
|
|
fWillUseInputColor = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void setToOther(uint8_t validFlags, GrColor color, ReadInput readsInput) {
|
|
|
|
fValidFlags = validFlags;
|
|
|
|
fColor = color;
|
|
|
|
fIsSingleComponent = false;
|
|
|
|
fNonMulStageFound = true;
|
|
|
|
if (kWillNot_ReadInput == readsInput) {
|
|
|
|
fWillUseInputColor = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void setToUnknown(ReadInput readsInput) {
|
|
|
|
this->internalSetToUnknown();
|
|
|
|
fNonMulStageFound= true;
|
|
|
|
if (kWillNot_ReadInput == readsInput) {
|
|
|
|
fWillUseInputColor = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-09 18:35:58 +00:00
|
|
|
// Temporary setter to handle LCD text correctly until we improve texture pixel config queries
|
|
|
|
// and thus can rely solely on number of coverage components for RGA vs single channel coverage.
|
|
|
|
void setUsingLCDCoverage() {
|
|
|
|
fIsLCDCoverage = true;
|
|
|
|
}
|
|
|
|
|
2014-11-12 16:35:25 +00:00
|
|
|
GrColor color() const { return fColor; }
|
|
|
|
uint8_t validFlags() const { return fValidFlags; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* If isSingleComponent is true, then the flag values for r, g, b, and a must all be the
|
|
|
|
* same. If the flags are all set then all color components must be equal.
|
|
|
|
*/
|
|
|
|
SkDEBUGCODE(void validate() const;)
|
|
|
|
|
|
|
|
private:
|
2014-11-13 19:00:34 +00:00
|
|
|
friend class GrProcOptInfo;
|
|
|
|
|
|
|
|
void reset(GrColor color, GrColorComponentFlags flags, bool isSingleComponent) {
|
|
|
|
fColor = color;
|
|
|
|
fValidFlags = flags;
|
|
|
|
fIsSingleComponent = isSingleComponent;
|
|
|
|
fNonMulStageFound = false;
|
|
|
|
fWillUseInputColor = true;
|
|
|
|
}
|
|
|
|
|
2014-12-11 23:44:02 +00:00
|
|
|
void reset(const GrInitInvariantOutput& io) {
|
|
|
|
fColor = io.fColor;
|
|
|
|
fValidFlags = io.fValidFlags;
|
|
|
|
fIsSingleComponent = io.fIsSingleComponent;
|
|
|
|
fNonMulStageFound = false;
|
|
|
|
fWillUseInputColor = true;
|
|
|
|
fIsLCDCoverage = io.fIsLCDCoverage;
|
|
|
|
}
|
|
|
|
|
2014-11-12 16:35:25 +00:00
|
|
|
void internalSetToTransparentBlack() {
|
|
|
|
fValidFlags = kRGBA_GrColorComponentFlags;
|
|
|
|
fColor = 0;
|
|
|
|
fIsSingleComponent = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void internalSetToUnknown() {
|
|
|
|
fValidFlags = 0;
|
|
|
|
fIsSingleComponent = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool hasZeroAlpha() const {
|
|
|
|
return ((fValidFlags & kA_GrColorComponentFlag) && 0 == GrColorUnpackA(fColor));
|
|
|
|
}
|
|
|
|
|
2014-11-13 19:00:34 +00:00
|
|
|
bool isOpaque() const {
|
|
|
|
return ((fValidFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(fColor));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isSolidWhite() const {
|
|
|
|
return (fValidFlags == kRGBA_GrColorComponentFlags && 0xFFFFFFFF == fColor);
|
|
|
|
}
|
|
|
|
|
2014-12-03 18:40:13 +00:00
|
|
|
bool isSingleComponent() const { return fIsSingleComponent; }
|
|
|
|
|
2014-11-13 19:00:34 +00:00
|
|
|
bool willUseInputColor() const { return fWillUseInputColor; }
|
|
|
|
void resetWillUseInputColor() { fWillUseInputColor = true; }
|
|
|
|
|
2015-02-13 20:11:00 +00:00
|
|
|
bool allStagesMulInput() const { return !fNonMulStageFound; }
|
2014-11-13 19:00:34 +00:00
|
|
|
void resetNonMulStageFound() { fNonMulStageFound = false; }
|
|
|
|
|
2014-12-09 18:35:58 +00:00
|
|
|
bool isLCDCoverage() const { return fIsLCDCoverage; }
|
|
|
|
|
2014-11-12 16:35:25 +00:00
|
|
|
SkDEBUGCODE(bool colorComponentsAllEqual() const;)
|
|
|
|
/**
|
|
|
|
* If alpha is valid, check that any valid R,G,B values are <= A
|
|
|
|
*/
|
|
|
|
SkDEBUGCODE(bool validPreMulColor() const;)
|
2014-12-09 18:35:58 +00:00
|
|
|
|
|
|
|
GrColor fColor;
|
|
|
|
uint32_t fValidFlags;
|
|
|
|
bool fIsSingleComponent;
|
|
|
|
bool fNonMulStageFound;
|
|
|
|
bool fWillUseInputColor;
|
|
|
|
bool fIsLCDCoverage; // Temorary data member until texture pixel configs are updated
|
|
|
|
|
2014-11-12 16:35:25 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|