Use child processors to implement compose color filter.
Review URL: https://codereview.chromium.org/1368423003
This commit is contained in:
parent
c56c6ef3ce
commit
e25eea4b36
@ -124,20 +124,17 @@ public:
|
||||
static SkColorFilter* CreateComposeFilter(SkColorFilter* outer, SkColorFilter* inner);
|
||||
|
||||
/**
|
||||
* A subclass may implement this factory function to work with the GPU backend.
|
||||
* If it returns true, then 1 or more fragment processors will have been appended to the
|
||||
* array, each of which has been ref'd, so that the caller is responsible for calling unref()
|
||||
* on them when they are finished. If more than one processor is appended, they will be
|
||||
* applied in FIFO order.
|
||||
* A subclass may implement this factory function to work with the GPU backend. It returns
|
||||
* a GrFragmentProcessor that implemets the color filter in GPU shader code.
|
||||
*
|
||||
* The fragment processor(s) must each return their color as a premul normalized value
|
||||
* e.g. each component between [0..1] and each color component <= alpha.
|
||||
* The fragment processor receives a premultiplied input color and produces a premultiplied
|
||||
* output color.
|
||||
*
|
||||
* If the subclass returns false, then it should not modify the array at all.
|
||||
* A null return indicates that the color filter isn't implemented for the GPU backend.
|
||||
*/
|
||||
virtual bool asFragmentProcessors(GrContext*, GrProcessorDataManager*,
|
||||
SkTDArray<const GrFragmentProcessor*>*) const {
|
||||
return false;
|
||||
virtual const GrFragmentProcessor* asFragmentProcessor(GrContext*,
|
||||
GrProcessorDataManager*) const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool affectsTransparentBlack() const {
|
||||
|
@ -25,8 +25,8 @@ public:
|
||||
uint32_t getFlags() const override;
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
bool asFragmentProcessors(GrContext*, GrProcessorDataManager*,
|
||||
SkTDArray<const GrFragmentProcessor*>*) const override;
|
||||
const GrFragmentProcessor* asFragmentProcessor(GrContext*,
|
||||
GrProcessorDataManager*) const override;
|
||||
#endif
|
||||
|
||||
SK_TO_STRING_OVERRIDE()
|
||||
|
@ -26,8 +26,8 @@ public:
|
||||
SkColorFilter* newComposed(const SkColorFilter*) const override;
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
bool asFragmentProcessors(GrContext*, GrProcessorDataManager*,
|
||||
SkTDArray<const GrFragmentProcessor*>*) const override;
|
||||
const GrFragmentProcessor* asFragmentProcessor(GrContext*,
|
||||
GrProcessorDataManager*) const override;
|
||||
#endif
|
||||
|
||||
struct State {
|
||||
|
@ -28,8 +28,8 @@ public:
|
||||
void filterSpan(const SkPMColor src[], int count, SkPMColor[]) const override;
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
bool asFragmentProcessors(GrContext*, GrProcessorDataManager*,
|
||||
SkTDArray<const GrFragmentProcessor*>*) const override;
|
||||
const GrFragmentProcessor* asFragmentProcessor(GrContext*,
|
||||
GrProcessorDataManager*) const override;
|
||||
#endif
|
||||
|
||||
SK_TO_STRING_OVERRIDE()
|
||||
|
@ -39,8 +39,8 @@ public:
|
||||
#endif
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
bool asFragmentProcessors(GrContext*, GrProcessorDataManager*,
|
||||
SkTDArray<const GrFragmentProcessor*>*) const override;
|
||||
const GrFragmentProcessor* asFragmentProcessor(GrContext*,
|
||||
GrProcessorDataManager*) const override;
|
||||
#endif
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkModeColorFilter)
|
||||
|
||||
|
@ -41,12 +41,20 @@ public:
|
||||
static const GrFragmentProcessor* MulOutputByInputUnpremulColor(const GrFragmentProcessor*);
|
||||
|
||||
/**
|
||||
* Returns a parent fragment processor that adopts the passed fragment processor as a child. The
|
||||
* parent will ignore its input color and instead feed the passed in color as input to the
|
||||
* Returns a parent fragment processor that adopts the passed fragment processor as a child.
|
||||
* The parent will ignore its input color and instead feed the passed in color as input to the
|
||||
* child.
|
||||
*/
|
||||
static const GrFragmentProcessor* OverrideInput(const GrFragmentProcessor*, GrColor);
|
||||
|
||||
/**
|
||||
* Returns a fragment processor that runs the passed in array of fragment processors in a
|
||||
* series. The original input is passed to the first, the first's output is passed to the
|
||||
* second, etc. The output of the returned processor is the output of the last processor of the
|
||||
* series.
|
||||
*/
|
||||
static const GrFragmentProcessor* RunInSeries(const GrFragmentProcessor*[], int cnt);
|
||||
|
||||
GrFragmentProcessor()
|
||||
: INHERITED()
|
||||
, fUsesLocalCoords(false)
|
||||
|
@ -13,7 +13,9 @@
|
||||
#include "SkUnPreMultiply.h"
|
||||
#include "SkWriteBuffer.h"
|
||||
|
||||
class GrFragmentProcessor;
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "GrFragmentProcessor.h"
|
||||
#endif
|
||||
|
||||
bool SkColorFilter::asColorMode(SkColor* color, SkXfermode::Mode* mode) const {
|
||||
return false;
|
||||
@ -67,11 +69,15 @@ public:
|
||||
#endif
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
bool asFragmentProcessors(GrContext* context, GrProcessorDataManager* procDataManager,
|
||||
SkTDArray<const GrFragmentProcessor*>* array) const override {
|
||||
bool hasFrags = fInner->asFragmentProcessors(context, procDataManager, array);
|
||||
hasFrags |= fOuter->asFragmentProcessors(context, procDataManager, array);
|
||||
return hasFrags;
|
||||
const GrFragmentProcessor* asFragmentProcessor(GrContext* context,
|
||||
GrProcessorDataManager* pdm) const override {
|
||||
SkAutoTUnref<const GrFragmentProcessor> innerFP(fInner->asFragmentProcessor(context, pdm));
|
||||
SkAutoTUnref<const GrFragmentProcessor> outerFP(fOuter->asFragmentProcessor(context, pdm));
|
||||
if (!innerFP || !outerFP) {
|
||||
return nullptr;
|
||||
}
|
||||
const GrFragmentProcessor* series[] = { innerFP, outerFP };
|
||||
return GrFragmentProcessor::RunInSeries(series, 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -160,7 +160,7 @@ void SkColorCubeFilter::toString(SkString* str) const {
|
||||
|
||||
class GrColorCubeEffect : public GrFragmentProcessor {
|
||||
public:
|
||||
static GrFragmentProcessor* Create(GrTexture* colorCube) {
|
||||
static const GrFragmentProcessor* Create(GrTexture* colorCube) {
|
||||
return (nullptr != colorCube) ? new GrColorCubeEffect(colorCube) : nullptr;
|
||||
}
|
||||
|
||||
@ -303,8 +303,8 @@ void GrColorCubeEffect::GLProcessor::GenKey(const GrProcessor& proc,
|
||||
const GrGLSLCaps&, GrProcessorKeyBuilder* b) {
|
||||
}
|
||||
|
||||
bool SkColorCubeFilter::asFragmentProcessors(GrContext* context, GrProcessorDataManager*,
|
||||
SkTDArray<const GrFragmentProcessor*>* array) const {
|
||||
const GrFragmentProcessor* SkColorCubeFilter::asFragmentProcessor(GrContext* context,
|
||||
GrProcessorDataManager*) const {
|
||||
static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
|
||||
GrUniqueKey key;
|
||||
GrUniqueKey::Builder builder(&key, kDomain, 2);
|
||||
@ -324,19 +324,11 @@ bool SkColorCubeFilter::asFragmentProcessors(GrContext* context, GrProcessorData
|
||||
desc, true, fCubeData->data(), 0));
|
||||
if (textureCube) {
|
||||
context->textureProvider()->assignUniqueKeyToTexture(key, textureCube);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
GrFragmentProcessor* frag = textureCube ? GrColorCubeEffect::Create(textureCube) : nullptr;
|
||||
if (frag) {
|
||||
if (array) {
|
||||
*array->append() = frag;
|
||||
} else {
|
||||
frag->unref();
|
||||
SkDEBUGCODE(frag = nullptr;)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return GrColorCubeEffect::Create(textureCube);
|
||||
}
|
||||
#endif
|
||||
|
@ -70,15 +70,20 @@ SkFlattenable* SkModeColorFilter::CreateProc(SkReadBuffer& buffer) {
|
||||
#include "effects/GrConstColorProcessor.h"
|
||||
#include "SkGr.h"
|
||||
|
||||
bool SkModeColorFilter::asFragmentProcessors(GrContext*, GrProcessorDataManager*,
|
||||
SkTDArray<const GrFragmentProcessor*>* array) const {
|
||||
if (SkXfermode::kDst_Mode != fMode) {
|
||||
const GrFragmentProcessor* SkModeColorFilter::asFragmentProcessor(GrContext*,
|
||||
GrProcessorDataManager*) const {
|
||||
if (SkXfermode::kDst_Mode == fMode) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SkAutoTUnref<const GrFragmentProcessor> constFP(
|
||||
GrConstColorProcessor::Create(SkColorToPremulGrColor(fColor),
|
||||
GrConstColorProcessor::kIgnore_InputMode));
|
||||
const GrFragmentProcessor* fp =
|
||||
GrXfermodeFragmentProcessor::CreateFromSrcProcessor(constFP, fMode);
|
||||
if (fp) {
|
||||
if (!fp) {
|
||||
return nullptr;
|
||||
}
|
||||
#ifdef SK_DEBUG
|
||||
// With a solid color input this should always be able to compute the blended color
|
||||
// (at least for coeff modes)
|
||||
@ -90,16 +95,7 @@ bool SkModeColorFilter::asFragmentProcessors(GrContext*, GrProcessorDataManager*
|
||||
SkASSERT(io.validFlags() == kRGBA_GrColorComponentFlags);
|
||||
}
|
||||
#endif
|
||||
if (array) {
|
||||
*array->append() = fp;
|
||||
} else {
|
||||
fp->unref();
|
||||
SkDEBUGCODE(fp = nullptr;)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return fp;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -390,7 +390,7 @@ SkColorFilter* SkColorMatrixFilter::newComposed(const SkColorFilter* innerFilter
|
||||
|
||||
class ColorMatrixEffect : public GrFragmentProcessor {
|
||||
public:
|
||||
static GrFragmentProcessor* Create(const SkColorMatrix& matrix) {
|
||||
static const GrFragmentProcessor* Create(const SkColorMatrix& matrix) {
|
||||
return new ColorMatrixEffect(matrix);
|
||||
}
|
||||
|
||||
@ -536,19 +536,9 @@ const GrFragmentProcessor* ColorMatrixEffect::TestCreate(GrProcessorTestData* d)
|
||||
return ColorMatrixEffect::Create(colorMatrix);
|
||||
}
|
||||
|
||||
bool SkColorMatrixFilter::asFragmentProcessors(GrContext*, GrProcessorDataManager*,
|
||||
SkTDArray<const GrFragmentProcessor*>* array) const {
|
||||
GrFragmentProcessor* frag = ColorMatrixEffect::Create(fMatrix);
|
||||
if (frag) {
|
||||
if (array) {
|
||||
*array->append() = frag;
|
||||
} else {
|
||||
frag->unref();
|
||||
SkDEBUGCODE(frag = nullptr;)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
const GrFragmentProcessor* SkColorMatrixFilter::asFragmentProcessor(GrContext*,
|
||||
GrProcessorDataManager*) const {
|
||||
return ColorMatrixEffect::Create(fMatrix);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -54,7 +54,7 @@ void SkLumaColorFilter::toString(SkString* str) const {
|
||||
#if SK_SUPPORT_GPU
|
||||
class LumaColorFilterEffect : public GrFragmentProcessor {
|
||||
public:
|
||||
static GrFragmentProcessor* Create() {
|
||||
static const GrFragmentProcessor* Create() {
|
||||
static LumaColorFilterEffect gLumaEffect;
|
||||
return SkRef(&gLumaEffect);
|
||||
}
|
||||
@ -108,19 +108,9 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
bool SkLumaColorFilter::asFragmentProcessors(GrContext*, GrProcessorDataManager*,
|
||||
SkTDArray<const GrFragmentProcessor*>* array) const {
|
||||
const GrFragmentProcessor* SkLumaColorFilter::asFragmentProcessor(GrContext*,
|
||||
GrProcessorDataManager*) const {
|
||||
|
||||
GrFragmentProcessor* frag = LumaColorFilterEffect::Create();
|
||||
if (frag) {
|
||||
if (array) {
|
||||
*array->append() = frag;
|
||||
} else {
|
||||
frag->unref();
|
||||
SkDEBUGCODE(frag = nullptr;)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return LumaColorFilterEffect::Create();
|
||||
}
|
||||
#endif
|
||||
|
@ -48,8 +48,8 @@ public:
|
||||
SkColorFilter* newComposed(const SkColorFilter* inner) const override;
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
bool asFragmentProcessors(GrContext*, GrProcessorDataManager*,
|
||||
SkTDArray<const GrFragmentProcessor*>*) const override;
|
||||
const GrFragmentProcessor* asFragmentProcessor(GrContext*,
|
||||
GrProcessorDataManager*) const override;
|
||||
#endif
|
||||
|
||||
void filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const override;
|
||||
@ -340,7 +340,7 @@ SkColorFilter* SkTable_ColorFilter::newComposed(const SkColorFilter* innerFilter
|
||||
|
||||
class ColorTableEffect : public GrFragmentProcessor {
|
||||
public:
|
||||
static GrFragmentProcessor* Create(GrContext* context, SkBitmap bitmap, unsigned flags);
|
||||
static const GrFragmentProcessor* Create(GrContext* context, SkBitmap bitmap, unsigned flags);
|
||||
|
||||
virtual ~ColorTableEffect();
|
||||
|
||||
@ -461,7 +461,8 @@ void GLColorTableEffect::emitCode(EmitArgs& args) {
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
GrFragmentProcessor* ColorTableEffect::Create(GrContext* context, SkBitmap bitmap, unsigned flags) {
|
||||
const GrFragmentProcessor* ColorTableEffect::Create(GrContext* context, SkBitmap bitmap,
|
||||
unsigned flags) {
|
||||
|
||||
GrTextureStripAtlas::Desc desc;
|
||||
desc.fWidth = bitmap.width();
|
||||
@ -563,31 +564,17 @@ const GrFragmentProcessor* ColorTableEffect::TestCreate(GrProcessorTestData* d)
|
||||
(flags & (1 << 3)) ? luts[3] : nullptr
|
||||
));
|
||||
|
||||
SkTDArray<const GrFragmentProcessor*> array;
|
||||
if (filter->asFragmentProcessors(d->fContext, d->fProcDataManager, &array)) {
|
||||
SkASSERT(1 == array.count()); // TableColorFilter only returns 1
|
||||
return array[0];
|
||||
}
|
||||
return nullptr;
|
||||
const GrFragmentProcessor* fp = filter->asFragmentProcessor(d->fContext, d->fProcDataManager);
|
||||
SkASSERT(fp);
|
||||
return fp;
|
||||
}
|
||||
|
||||
bool SkTable_ColorFilter::asFragmentProcessors(GrContext* context,
|
||||
GrProcessorDataManager*,
|
||||
SkTDArray<const GrFragmentProcessor*>* array) const {
|
||||
const GrFragmentProcessor* SkTable_ColorFilter::asFragmentProcessor(GrContext* context,
|
||||
GrProcessorDataManager*) const {
|
||||
SkBitmap bitmap;
|
||||
this->asComponentTable(&bitmap);
|
||||
|
||||
GrFragmentProcessor* frag = ColorTableEffect::Create(context, bitmap, fFlags);
|
||||
if (frag) {
|
||||
if (array) {
|
||||
*array->append() = frag;
|
||||
} else {
|
||||
frag->unref();
|
||||
SkDEBUGCODE(frag = nullptr;)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return ColorTableEffect::Create(context, bitmap, fFlags);
|
||||
}
|
||||
|
||||
#endif // SK_SUPPORT_GPU
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "GrCoordTransform.h"
|
||||
#include "gl/GrGLFragmentProcessor.h"
|
||||
#include "gl/builders/GrGLProgramBuilder.h"
|
||||
#include "effects/GrConstColorProcessor.h"
|
||||
#include "effects/GrXfermodeFragmentProcessor.h"
|
||||
|
||||
GrFragmentProcessor::~GrFragmentProcessor() {
|
||||
@ -279,3 +280,96 @@ const GrFragmentProcessor* GrFragmentProcessor::OverrideInput(const GrFragmentPr
|
||||
return SkRef(fp);
|
||||
}
|
||||
}
|
||||
|
||||
const GrFragmentProcessor* GrFragmentProcessor::RunInSeries(const GrFragmentProcessor* series[],
|
||||
int cnt) {
|
||||
class SeriesFragmentProcessor : public GrFragmentProcessor {
|
||||
public:
|
||||
SeriesFragmentProcessor(const GrFragmentProcessor* children[], int cnt){
|
||||
SkASSERT(cnt > 1);
|
||||
this->initClassID<SeriesFragmentProcessor>();
|
||||
for (int i = 0; i < cnt; ++i) {
|
||||
this->registerChildProcessor(children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
const char* name() const override { return "Series"; }
|
||||
|
||||
GrGLFragmentProcessor* onCreateGLInstance() const override {
|
||||
class GLFP : public GrGLFragmentProcessor {
|
||||
public:
|
||||
GLFP() {}
|
||||
void emitCode(EmitArgs& args) override {
|
||||
SkString input(args.fInputColor);
|
||||
for (int i = 0; i < this->numChildProcessors() - 1; ++i) {
|
||||
SkString temp;
|
||||
temp.printf("out%d", i);
|
||||
this->emitChild(i, input.c_str(), &temp, args);
|
||||
input = temp;
|
||||
}
|
||||
// Last guy writes to our output variable.
|
||||
this->emitChild(this->numChildProcessors() - 1, input.c_str(), args);
|
||||
}
|
||||
};
|
||||
return new GLFP;
|
||||
}
|
||||
|
||||
private:
|
||||
void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override {}
|
||||
|
||||
bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
|
||||
|
||||
void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
|
||||
GrProcOptInfo info;
|
||||
SkTDArray<const GrFragmentProcessor*> children;
|
||||
children.setCount(this->numChildProcessors());
|
||||
for (int i = 0; i < children.count(); ++i) {
|
||||
children[i] = &this->childProcessor(i);
|
||||
}
|
||||
info.calcWithInitialValues(children.begin(), children.count(), inout->color(),
|
||||
inout->validFlags(), false, false);
|
||||
for (int i = 0; i < this->numChildProcessors(); ++i) {
|
||||
this->childProcessor(i).computeInvariantOutput(inout);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (!cnt) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Run the through the series, do the invariant output processing, and look for eliminations.
|
||||
SkTDArray<const GrFragmentProcessor*> replacementSeries;
|
||||
SkAutoTUnref<const GrFragmentProcessor> colorFP;
|
||||
GrProcOptInfo info;
|
||||
|
||||
info.calcWithInitialValues(series, cnt, 0x0, kNone_GrColorComponentFlags, false, false);
|
||||
if (kRGBA_GrColorComponentFlags == info.validFlags()) {
|
||||
return GrConstColorProcessor::Create(info.color(),
|
||||
GrConstColorProcessor::kIgnore_InputMode);
|
||||
} else {
|
||||
int firstIdx = info.firstEffectiveProcessorIndex();
|
||||
cnt -= firstIdx;
|
||||
if (firstIdx > 0 && info.inputColorIsUsed()) {
|
||||
colorFP.reset(GrConstColorProcessor::Create(info.inputColorToFirstEffectiveProccesor(),
|
||||
GrConstColorProcessor::kIgnore_InputMode));
|
||||
cnt += 1;
|
||||
replacementSeries.setCount(cnt);
|
||||
replacementSeries[0] = colorFP;
|
||||
for (int i = 0; i < cnt - 1; ++i) {
|
||||
replacementSeries[i + 1] = series[firstIdx + i];
|
||||
}
|
||||
series = replacementSeries.begin();
|
||||
} else {
|
||||
series += firstIdx;
|
||||
cnt -= firstIdx;
|
||||
}
|
||||
}
|
||||
|
||||
if (1 == cnt) {
|
||||
return SkRef(series[0]);
|
||||
} else {
|
||||
return new SeriesFragmentProcessor(series, cnt);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ public:
|
||||
GrColor color() const { return fInOut.color(); }
|
||||
|
||||
GrColorComponentFlags validFlags() const {
|
||||
return static_cast<GrColorComponentFlags>(fInOut.validFlags());
|
||||
return fInOut.validFlags();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -812,12 +812,10 @@ static inline bool skpaint_to_grpaint_impl(GrContext* context,
|
||||
if (applyColorFilterToPaintColor) {
|
||||
grPaint->setColor(SkColorToPremulGrColor(colorFilter->filterColor(skPaint.getColor())));
|
||||
} else {
|
||||
SkTDArray<const GrFragmentProcessor*> array;
|
||||
if (colorFilter->asFragmentProcessors(context, grPaint->getProcessorDataManager(),
|
||||
&array)) {
|
||||
for (int i = 0; i < array.count(); ++i) {
|
||||
grPaint->addColorFragmentProcessor(array[i])->unref();
|
||||
}
|
||||
SkAutoTUnref<const GrFragmentProcessor> cfFP(
|
||||
colorFilter->asFragmentProcessor(context, grPaint->getProcessorDataManager()));
|
||||
if (cfFP) {
|
||||
grPaint->addColorFragmentProcessor(cfFP);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -100,19 +100,18 @@ static void test_getConstantColorComponents(skiatest::Reporter* reporter, GrCont
|
||||
GrPaint paint;
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(filterTests); ++i) {
|
||||
const GetConstantComponentTestCase& test = filterTests[i];
|
||||
SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(test.filterColor, test.filterMode));
|
||||
SkTDArray<const GrFragmentProcessor*> array;
|
||||
bool hasFrag = cf->asFragmentProcessors(grContext, paint.getProcessorDataManager(), &array);
|
||||
REPORTER_ASSERT(reporter, hasFrag);
|
||||
REPORTER_ASSERT(reporter, 1 == array.count());
|
||||
SkAutoTUnref<SkColorFilter> cf(
|
||||
SkColorFilter::CreateModeFilter(test.filterColor, test.filterMode));
|
||||
SkAutoTUnref<const GrFragmentProcessor> fp(
|
||||
cf->asFragmentProcessor(grContext, paint.getProcessorDataManager()));
|
||||
REPORTER_ASSERT(reporter, fp);
|
||||
GrInvariantOutput inout(test.inputColor,
|
||||
static_cast<GrColorComponentFlags>(test.inputComponents),
|
||||
false);
|
||||
array[0]->computeInvariantOutput(&inout);
|
||||
|
||||
REPORTER_ASSERT(reporter, filterColor(inout.color(), inout.validFlags()) == test.outputColor);
|
||||
fp->computeInvariantOutput(&inout);
|
||||
REPORTER_ASSERT(reporter, filterColor(inout.color(), inout.validFlags()) ==
|
||||
test.outputColor);
|
||||
REPORTER_ASSERT(reporter, test.outputComponents == inout.validFlags());
|
||||
array[0]->unref();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user