зеркало из https://github.com/mozilla/moz-skia.git
add reflection asColorMode to SkColorFilter (for gpu)
git-svn-id: http://skia.googlecode.com/svn/trunk@1126 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
586f48cfa8
Коммит
43c50c8c77
|
@ -23,6 +23,13 @@
|
|||
|
||||
class SkColorFilter : public SkFlattenable {
|
||||
public:
|
||||
/**
|
||||
* If the filter can be represented by a source color plus Mode, this
|
||||
* returns true, and sets (if not NULL) the color and mode appropriately.
|
||||
* If not, this returns false and ignores the parameters.
|
||||
*/
|
||||
virtual bool asColorMode(SkColor* color, SkXfermode::Mode* mode);
|
||||
|
||||
/** Called with a scanline of colors, as if there was a shader installed.
|
||||
The implementation writes out its filtered version into result[].
|
||||
Note: shader and result may be the same buffer.
|
||||
|
|
|
@ -75,6 +75,12 @@ public:
|
|||
*/
|
||||
virtual bool asCoeff(Coeff* src, Coeff* dst);
|
||||
|
||||
/**
|
||||
* The same as calling xfermode->asCoeff(..), except that this also checks
|
||||
* if the xfermode is NULL, and if so, treats its as kSrcOver_Mode.
|
||||
*/
|
||||
static bool AsCoeff(SkXfermode*, Coeff* src, Coeff* dst);
|
||||
|
||||
/** List of predefined xfermodes.
|
||||
The algebra for the modes uses the following symbols:
|
||||
Sa, Sc - source alpha and color
|
||||
|
@ -122,6 +128,12 @@ public:
|
|||
*/
|
||||
virtual bool asMode(Mode* mode);
|
||||
|
||||
/**
|
||||
* The same as calling xfermode->asMode(mode), except that this also checks
|
||||
* if the xfermode is NULL, and if so, treats its as kSrcOver_Mode.
|
||||
*/
|
||||
static bool AsMode(SkXfermode*, Mode* mode);
|
||||
|
||||
/** Return an SkXfermode object for the specified mode.
|
||||
*/
|
||||
static SkXfermode* Create(Mode mode);
|
||||
|
@ -137,13 +149,20 @@ public:
|
|||
16bit proc, and this will return NULL.
|
||||
*/
|
||||
static SkXfermodeProc16 GetProc16(Mode mode, SkColor srcColor);
|
||||
|
||||
|
||||
/**
|
||||
* The same as calling xfermode->asMode(mode), except that this also checks
|
||||
* if the xfermode is NULL, and if so, treats its as kSrcOver_Mode.
|
||||
* If the specified mode can be represented by a pair of Coeff, then return
|
||||
* true and set (if not NULL) the corresponding coeffs. If the mode is
|
||||
* not representable as a pair of Coeffs, return false and ignore the
|
||||
* src and dst parameters.
|
||||
*/
|
||||
static bool IsMode(SkXfermode*, Mode* mode);
|
||||
static bool ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst);
|
||||
|
||||
// DEPRECATED: call AsMode(...)
|
||||
static bool IsMode(SkXfermode* xfer, Mode* mode) {
|
||||
return AsMode(xfer, mode);
|
||||
}
|
||||
|
||||
protected:
|
||||
SkXfermode(SkFlattenableReadBuffer& rb) : SkFlattenable(rb) {}
|
||||
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
#include "SkColorFilter.h"
|
||||
#include "SkShader.h"
|
||||
|
||||
bool SkColorFilter::asColorMode(SkColor* color, SkXfermode::Mode* mode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void SkColorFilter::filterSpan16(const uint16_t s[], int count, uint16_t d[])
|
||||
{
|
||||
SkASSERT(this->getFlags() & SkColorFilter::kHasFilter16_Flag);
|
||||
|
|
|
@ -977,7 +977,39 @@ SkXfermode* SkXfermode::Create(Mode mode) {
|
|||
}
|
||||
}
|
||||
|
||||
bool SkXfermode::IsMode(SkXfermode* xfer, Mode* mode) {
|
||||
SkXfermodeProc SkXfermode::GetProc(Mode mode) {
|
||||
SkXfermodeProc proc = NULL;
|
||||
if ((unsigned)mode < kModeCount) {
|
||||
proc = gProcCoeffs[mode].fProc;
|
||||
}
|
||||
return proc;
|
||||
}
|
||||
|
||||
bool SkXfermode::ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst) {
|
||||
SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount);
|
||||
|
||||
if ((unsigned)mode >= (unsigned)kModeCount) {
|
||||
// illegal mode parameter
|
||||
return false;
|
||||
}
|
||||
|
||||
const ProcCoeff& rec = gProcCoeffs[mode];
|
||||
|
||||
if (CANNOT_USE_COEFF == rec.fSC) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SkASSERT(CANNOT_USE_COEFF != rec.fDC);
|
||||
if (src) {
|
||||
*src = rec.fSC;
|
||||
}
|
||||
if (dst) {
|
||||
*dst = rec.fDC;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SkXfermode::AsMode(SkXfermode* xfer, Mode* mode) {
|
||||
if (NULL == xfer) {
|
||||
if (mode) {
|
||||
*mode = kSrcOver_Mode;
|
||||
|
@ -987,12 +1019,11 @@ bool SkXfermode::IsMode(SkXfermode* xfer, Mode* mode) {
|
|||
return xfer->asMode(mode);
|
||||
}
|
||||
|
||||
SkXfermodeProc SkXfermode::GetProc(Mode mode) {
|
||||
SkXfermodeProc proc = NULL;
|
||||
if ((unsigned)mode < kModeCount) {
|
||||
proc = gProcCoeffs[mode].fProc;
|
||||
bool SkXfermode::AsCoeff(SkXfermode* xfer, Coeff* src, Coeff* dst) {
|
||||
if (NULL == xfer) {
|
||||
return ModeAsCoeff(kSrcOver_Mode, src, dst);
|
||||
}
|
||||
return proc;
|
||||
return xfer->asCoeff(src, dst);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -19,26 +19,67 @@
|
|||
#include "SkColorPriv.h"
|
||||
#include "SkUtils.h"
|
||||
|
||||
// common baseclass
|
||||
class Sk_XfermodeColorFilter : public SkColorFilter {
|
||||
#define ILLEGAL_XFERMODE_MODE ((SkXfermode::Mode)-1)
|
||||
|
||||
// baseclass for filters that store a color and mode
|
||||
class SkModeColorFilter : public SkColorFilter {
|
||||
public:
|
||||
SkModeColorFilter(SkColor color) {
|
||||
fColor = color;
|
||||
fMode = ILLEGAL_XFERMODE_MODE;
|
||||
|
||||
fPMColor = SkPreMultiplyColor(fColor);
|
||||
}
|
||||
|
||||
SkModeColorFilter(SkColor color, SkXfermode::Mode mode) {
|
||||
fColor = color;
|
||||
fMode = mode;
|
||||
|
||||
fPMColor = SkPreMultiplyColor(fColor);
|
||||
};
|
||||
|
||||
virtual bool asColorMode(SkColor* color, SkXfermode::Mode* mode) {
|
||||
if (ILLEGAL_XFERMODE_MODE == fMode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (color) {
|
||||
*color = fColor;
|
||||
}
|
||||
if (mode) {
|
||||
*mode = fMode;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
SkColor getColor() const { return fColor; }
|
||||
SkXfermode::Mode getMode() const { return fMode; }
|
||||
bool isModeValid() const { return ILLEGAL_XFERMODE_MODE != fMode; }
|
||||
|
||||
protected:
|
||||
Sk_XfermodeColorFilter(SkColor color)
|
||||
: fPMColor(SkPreMultiplyColor(color)) {}
|
||||
|
||||
virtual void flatten(SkFlattenableWriteBuffer& buffer) {
|
||||
buffer.write32(fPMColor);
|
||||
}
|
||||
|
||||
Sk_XfermodeColorFilter(SkFlattenableReadBuffer& buffer) {
|
||||
fPMColor = buffer.readU32();
|
||||
buffer.write32(fColor);
|
||||
buffer.write32(fMode);
|
||||
}
|
||||
|
||||
SkModeColorFilter(SkFlattenableReadBuffer& buffer) {
|
||||
fColor = buffer.readU32();
|
||||
fMode = (SkXfermode::Mode)buffer.readU32();
|
||||
|
||||
fPMColor = SkPreMultiplyColor(fColor);
|
||||
}
|
||||
|
||||
// cache of fColor in premultiply space
|
||||
SkPMColor fPMColor;
|
||||
|
||||
private:
|
||||
SkColor fColor;
|
||||
SkXfermode::Mode fMode;
|
||||
};
|
||||
|
||||
class SkSrc_XfermodeColorFilter : public Sk_XfermodeColorFilter {
|
||||
class Src_SkModeColorFilter : public SkModeColorFilter {
|
||||
public:
|
||||
SkSrc_XfermodeColorFilter(SkColor color) : INHERITED(color) {}
|
||||
Src_SkModeColorFilter(SkColor color) : INHERITED(color, SkXfermode::kSrc_Mode) {}
|
||||
|
||||
virtual uint32_t getFlags() {
|
||||
if (SkGetPackedA32(fPMColor) == 0xFF) {
|
||||
|
@ -62,21 +103,23 @@ public:
|
|||
protected:
|
||||
virtual Factory getFactory() { return CreateProc; }
|
||||
|
||||
SkSrc_XfermodeColorFilter(SkFlattenableReadBuffer& buffer)
|
||||
Src_SkModeColorFilter(SkFlattenableReadBuffer& buffer)
|
||||
: INHERITED(buffer) {}
|
||||
|
||||
private:
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
|
||||
return SkNEW_ARGS(SkSrc_XfermodeColorFilter, (buffer));
|
||||
return SkNEW_ARGS(Src_SkModeColorFilter, (buffer));
|
||||
}
|
||||
|
||||
typedef Sk_XfermodeColorFilter INHERITED;
|
||||
typedef SkModeColorFilter INHERITED;
|
||||
};
|
||||
|
||||
class SkSrcOver_XfermodeColorFilter : public Sk_XfermodeColorFilter {
|
||||
class SrcOver_SkModeColorFilter : public SkModeColorFilter {
|
||||
public:
|
||||
SkSrcOver_XfermodeColorFilter(SkColor color)
|
||||
: INHERITED(color), fColor32Proc(SkBlitRow::ColorProcFactory()) {}
|
||||
SrcOver_SkModeColorFilter(SkColor color)
|
||||
: INHERITED(color, SkXfermode::kSrcOver_Mode) {
|
||||
fColor32Proc = NULL;
|
||||
}
|
||||
|
||||
virtual uint32_t getFlags() {
|
||||
if (SkGetPackedA32(fPMColor) == 0xFF) {
|
||||
|
@ -88,6 +131,9 @@ public:
|
|||
|
||||
virtual void filterSpan(const SkPMColor shader[], int count,
|
||||
SkPMColor result[]) {
|
||||
if (NULL == fColor32Proc) {
|
||||
fColor32Proc = SkBlitRow::ColorProcFactory();
|
||||
}
|
||||
fColor32Proc(result, shader, count, fPMColor);
|
||||
}
|
||||
|
||||
|
@ -100,24 +146,31 @@ public:
|
|||
protected:
|
||||
virtual Factory getFactory() { return CreateProc; }
|
||||
|
||||
SkSrcOver_XfermodeColorFilter(SkFlattenableReadBuffer& buffer)
|
||||
: INHERITED(buffer), fColor32Proc(SkBlitRow::ColorProcFactory()) {}
|
||||
SrcOver_SkModeColorFilter(SkFlattenableReadBuffer& buffer)
|
||||
: INHERITED(buffer), fColor32Proc(NULL) {}
|
||||
|
||||
private:
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
|
||||
return SkNEW_ARGS(SkSrcOver_XfermodeColorFilter, (buffer));
|
||||
return SkNEW_ARGS(SrcOver_SkModeColorFilter, (buffer));
|
||||
}
|
||||
|
||||
typedef Sk_XfermodeColorFilter INHERITED;
|
||||
SkBlitRow::ColorProc fColor32Proc;
|
||||
|
||||
typedef SkModeColorFilter INHERITED;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SkXfermodeColorFilter : public Sk_XfermodeColorFilter {
|
||||
class Proc_SkModeColorFilter : public SkModeColorFilter {
|
||||
public:
|
||||
SkXfermodeColorFilter(SkColor color, SkXfermodeProc proc,
|
||||
SkXfermodeProc16 proc16) : INHERITED(color) {
|
||||
Proc_SkModeColorFilter(SkColor color, SkXfermode::Mode mode) : INHERITED(color, mode) {
|
||||
fProc = SkXfermode::GetProc(mode);
|
||||
fProc16 = SkXfermode::GetProc16(mode, color);
|
||||
}
|
||||
|
||||
Proc_SkModeColorFilter(SkColor color,
|
||||
SkXfermodeProc proc, SkXfermodeProc16 proc16)
|
||||
: INHERITED(color, ILLEGAL_XFERMODE_MODE) {
|
||||
fProc = proc;
|
||||
fProc16 = proc16;
|
||||
}
|
||||
|
@ -159,26 +212,27 @@ protected:
|
|||
return CreateProc;
|
||||
}
|
||||
|
||||
SkXfermodeColorFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
|
||||
Proc_SkModeColorFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
|
||||
fProc = (SkXfermodeProc) buffer.readFunctionPtr();
|
||||
fProc16 = (SkXfermodeProc16) buffer.readFunctionPtr();
|
||||
}
|
||||
|
||||
private:
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
|
||||
return SkNEW_ARGS(SkXfermodeColorFilter, (buffer));
|
||||
return SkNEW_ARGS(Proc_SkModeColorFilter, (buffer));
|
||||
}
|
||||
|
||||
SkXfermodeProc fProc;
|
||||
SkXfermodeProc16 fProc16;
|
||||
|
||||
typedef Sk_XfermodeColorFilter INHERITED;
|
||||
typedef SkModeColorFilter INHERITED;
|
||||
};
|
||||
|
||||
SkColorFilter* SkColorFilter::CreateProcFilter(SkColor color,
|
||||
SkXfermodeProc proc,
|
||||
SkXfermodeProc16 proc16) {
|
||||
return proc ?
|
||||
SkNEW_ARGS(SkXfermodeColorFilter, (color, proc, proc16)) :
|
||||
SkNEW_ARGS(Proc_SkModeColorFilter, (color, proc, proc16)) :
|
||||
NULL;
|
||||
}
|
||||
|
||||
|
@ -215,13 +269,12 @@ SkColorFilter* SkColorFilter::CreateModeFilter(SkColor color,
|
|||
}
|
||||
|
||||
switch (mode) {
|
||||
case SkXfermode::kSrc_Mode:
|
||||
return SkNEW_ARGS(SkSrc_XfermodeColorFilter, (color));
|
||||
case SkXfermode::kSrcOver_Mode:
|
||||
return SkNEW_ARGS(SkSrcOver_XfermodeColorFilter, (color));
|
||||
default:
|
||||
return SkColorFilter::CreateProcFilter(color, SkXfermode::GetProc(mode),
|
||||
SkXfermode::GetProc16(mode, color));
|
||||
case SkXfermode::kSrc_Mode:
|
||||
return SkNEW_ARGS(Src_SkModeColorFilter, (color));
|
||||
case SkXfermode::kSrcOver_Mode:
|
||||
return SkNEW_ARGS(SrcOver_SkModeColorFilter, (color));
|
||||
default:
|
||||
return SkNEW_ARGS(Proc_SkModeColorFilter, (color, mode));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
#include "Test.h"
|
||||
#include "SkColor.h"
|
||||
#include "SkColorFilter.h"
|
||||
#include "SkRandom.h"
|
||||
#include "SkXfermode.h"
|
||||
|
||||
static SkFlattenable* reincarnate_flattenable(SkFlattenable* obj) {
|
||||
SkFlattenable::Factory fact = obj->getFactory();
|
||||
if (NULL == fact) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SkFlattenableWriteBuffer wb(1024);
|
||||
obj->flatten(wb);
|
||||
|
||||
size_t size = wb.size();
|
||||
SkAutoSMalloc<1024> storage(size);
|
||||
// make a copy into storage
|
||||
wb.flatten(storage.get());
|
||||
|
||||
SkFlattenableReadBuffer rb(storage.get(), size);
|
||||
return fact(rb);
|
||||
}
|
||||
|
||||
template <typename T> T* reincarnate(T* obj) {
|
||||
return (T*)reincarnate_flattenable(obj);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define ILLEGAL_MODE ((SkXfermode::Mode)-1)
|
||||
|
||||
static void test_asColorMode(skiatest::Reporter* reporter) {
|
||||
SkRandom rand;
|
||||
|
||||
for (int mode = 0; mode <= SkXfermode::kLastMode; mode++) {
|
||||
SkColor color = rand.nextU();
|
||||
|
||||
// ensure we always get a filter, by avoiding the possibility of a
|
||||
// special case that would return NULL (if color's alpha is 0 or 0xFF)
|
||||
color = SkColorSetA(color, 0x7F);
|
||||
|
||||
SkColorFilter* cf = SkColorFilter::CreateModeFilter(color,
|
||||
(SkXfermode::Mode)mode);
|
||||
|
||||
// allow for no filter if we're in Dst mode (its a no op)
|
||||
if (SkXfermode::kDst_Mode == mode && NULL == cf) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SkAutoUnref aur(cf);
|
||||
REPORTER_ASSERT(reporter, cf);
|
||||
|
||||
SkColor c = ~color;
|
||||
SkXfermode::Mode m = ILLEGAL_MODE;
|
||||
|
||||
SkColor expectedColor = color;
|
||||
SkXfermode::Mode expectedMode = (SkXfermode::Mode)mode;
|
||||
|
||||
// SkDebugf("--- mc [%d %x] ", mode, color);
|
||||
|
||||
REPORTER_ASSERT(reporter, cf->asColorMode(&c, &m));
|
||||
// handle special-case folding by the factory
|
||||
if (SkXfermode::kClear_Mode == mode) {
|
||||
if (c != expectedColor) {
|
||||
expectedColor = 0;
|
||||
}
|
||||
if (m != expectedMode) {
|
||||
expectedMode = SkXfermode::kSrc_Mode;
|
||||
}
|
||||
}
|
||||
|
||||
// SkDebugf("--- got [%d %x] expected [%d %x]\n", m, c, expectedMode, expectedColor);
|
||||
|
||||
REPORTER_ASSERT(reporter, c == expectedColor);
|
||||
REPORTER_ASSERT(reporter, m == expectedMode);
|
||||
|
||||
{
|
||||
SkColorFilter* cf2 = reincarnate(cf);
|
||||
SkAutoUnref aur2(cf2);
|
||||
REPORTER_ASSERT(reporter, cf2);
|
||||
|
||||
SkColor c2 = ~color;
|
||||
SkXfermode::Mode m2 = ILLEGAL_MODE;
|
||||
REPORTER_ASSERT(reporter, cf2->asColorMode(&c2, &m2));
|
||||
REPORTER_ASSERT(reporter, c2 == expectedColor);
|
||||
REPORTER_ASSERT(reporter, m2 == expectedMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include "TestClassDef.h"
|
||||
DEFINE_TESTCLASS("ColorFilter", ColorFilterTestClass, test_asColorMode)
|
|
@ -5,6 +5,7 @@ SOURCE := \
|
|||
ClipCubicTest.cpp \
|
||||
ClipStackTest.cpp \
|
||||
ClipperTest.cpp \
|
||||
ColorFilterTest.cpp \
|
||||
DequeTest.cpp \
|
||||
DrawBitmapRectTest.cpp \
|
||||
FillPathTest.cpp \
|
||||
|
|
Загрузка…
Ссылка в новой задаче