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);
|
static SkColorFilter* CreateComposeFilter(SkColorFilter* outer, SkColorFilter* inner);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A subclass may implement this factory function to work with the GPU backend.
|
* A subclass may implement this factory function to work with the GPU backend. It returns
|
||||||
* If it returns true, then 1 or more fragment processors will have been appended to the
|
* a GrFragmentProcessor that implemets the color filter in GPU shader code.
|
||||||
* 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.
|
|
||||||
*
|
*
|
||||||
* The fragment processor(s) must each return their color as a premul normalized value
|
* The fragment processor receives a premultiplied input color and produces a premultiplied
|
||||||
* e.g. each component between [0..1] and each color component <= alpha.
|
* 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*,
|
virtual const GrFragmentProcessor* asFragmentProcessor(GrContext*,
|
||||||
SkTDArray<const GrFragmentProcessor*>*) const {
|
GrProcessorDataManager*) const {
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool affectsTransparentBlack() const {
|
bool affectsTransparentBlack() const {
|
||||||
|
@ -25,8 +25,8 @@ public:
|
|||||||
uint32_t getFlags() const override;
|
uint32_t getFlags() const override;
|
||||||
|
|
||||||
#if SK_SUPPORT_GPU
|
#if SK_SUPPORT_GPU
|
||||||
bool asFragmentProcessors(GrContext*, GrProcessorDataManager*,
|
const GrFragmentProcessor* asFragmentProcessor(GrContext*,
|
||||||
SkTDArray<const GrFragmentProcessor*>*) const override;
|
GrProcessorDataManager*) const override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SK_TO_STRING_OVERRIDE()
|
SK_TO_STRING_OVERRIDE()
|
||||||
|
@ -26,8 +26,8 @@ public:
|
|||||||
SkColorFilter* newComposed(const SkColorFilter*) const override;
|
SkColorFilter* newComposed(const SkColorFilter*) const override;
|
||||||
|
|
||||||
#if SK_SUPPORT_GPU
|
#if SK_SUPPORT_GPU
|
||||||
bool asFragmentProcessors(GrContext*, GrProcessorDataManager*,
|
const GrFragmentProcessor* asFragmentProcessor(GrContext*,
|
||||||
SkTDArray<const GrFragmentProcessor*>*) const override;
|
GrProcessorDataManager*) const override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct State {
|
struct State {
|
||||||
|
@ -28,8 +28,8 @@ public:
|
|||||||
void filterSpan(const SkPMColor src[], int count, SkPMColor[]) const override;
|
void filterSpan(const SkPMColor src[], int count, SkPMColor[]) const override;
|
||||||
|
|
||||||
#if SK_SUPPORT_GPU
|
#if SK_SUPPORT_GPU
|
||||||
bool asFragmentProcessors(GrContext*, GrProcessorDataManager*,
|
const GrFragmentProcessor* asFragmentProcessor(GrContext*,
|
||||||
SkTDArray<const GrFragmentProcessor*>*) const override;
|
GrProcessorDataManager*) const override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SK_TO_STRING_OVERRIDE()
|
SK_TO_STRING_OVERRIDE()
|
||||||
|
@ -39,8 +39,8 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SK_SUPPORT_GPU
|
#if SK_SUPPORT_GPU
|
||||||
bool asFragmentProcessors(GrContext*, GrProcessorDataManager*,
|
const GrFragmentProcessor* asFragmentProcessor(GrContext*,
|
||||||
SkTDArray<const GrFragmentProcessor*>*) const override;
|
GrProcessorDataManager*) const override;
|
||||||
#endif
|
#endif
|
||||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkModeColorFilter)
|
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkModeColorFilter)
|
||||||
|
|
||||||
|
@ -41,12 +41,20 @@ public:
|
|||||||
static const GrFragmentProcessor* MulOutputByInputUnpremulColor(const GrFragmentProcessor*);
|
static const GrFragmentProcessor* MulOutputByInputUnpremulColor(const GrFragmentProcessor*);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a parent fragment processor that adopts the passed fragment processor as a child. The
|
* Returns a parent fragment processor that adopts the passed fragment processor as a child.
|
||||||
* parent will ignore its input color and instead feed the passed in color as input to the
|
* The parent will ignore its input color and instead feed the passed in color as input to the
|
||||||
* child.
|
* child.
|
||||||
*/
|
*/
|
||||||
static const GrFragmentProcessor* OverrideInput(const GrFragmentProcessor*, GrColor);
|
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()
|
GrFragmentProcessor()
|
||||||
: INHERITED()
|
: INHERITED()
|
||||||
, fUsesLocalCoords(false)
|
, fUsesLocalCoords(false)
|
||||||
|
@ -13,7 +13,9 @@
|
|||||||
#include "SkUnPreMultiply.h"
|
#include "SkUnPreMultiply.h"
|
||||||
#include "SkWriteBuffer.h"
|
#include "SkWriteBuffer.h"
|
||||||
|
|
||||||
class GrFragmentProcessor;
|
#if SK_SUPPORT_GPU
|
||||||
|
#include "GrFragmentProcessor.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
bool SkColorFilter::asColorMode(SkColor* color, SkXfermode::Mode* mode) const {
|
bool SkColorFilter::asColorMode(SkColor* color, SkXfermode::Mode* mode) const {
|
||||||
return false;
|
return false;
|
||||||
@ -67,11 +69,15 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SK_SUPPORT_GPU
|
#if SK_SUPPORT_GPU
|
||||||
bool asFragmentProcessors(GrContext* context, GrProcessorDataManager* procDataManager,
|
const GrFragmentProcessor* asFragmentProcessor(GrContext* context,
|
||||||
SkTDArray<const GrFragmentProcessor*>* array) const override {
|
GrProcessorDataManager* pdm) const override {
|
||||||
bool hasFrags = fInner->asFragmentProcessors(context, procDataManager, array);
|
SkAutoTUnref<const GrFragmentProcessor> innerFP(fInner->asFragmentProcessor(context, pdm));
|
||||||
hasFrags |= fOuter->asFragmentProcessors(context, procDataManager, array);
|
SkAutoTUnref<const GrFragmentProcessor> outerFP(fOuter->asFragmentProcessor(context, pdm));
|
||||||
return hasFrags;
|
if (!innerFP || !outerFP) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
const GrFragmentProcessor* series[] = { innerFP, outerFP };
|
||||||
|
return GrFragmentProcessor::RunInSeries(series, 2);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ void SkColorCubeFilter::toString(SkString* str) const {
|
|||||||
|
|
||||||
class GrColorCubeEffect : public GrFragmentProcessor {
|
class GrColorCubeEffect : public GrFragmentProcessor {
|
||||||
public:
|
public:
|
||||||
static GrFragmentProcessor* Create(GrTexture* colorCube) {
|
static const GrFragmentProcessor* Create(GrTexture* colorCube) {
|
||||||
return (nullptr != colorCube) ? new GrColorCubeEffect(colorCube) : nullptr;
|
return (nullptr != colorCube) ? new GrColorCubeEffect(colorCube) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,8 +303,8 @@ void GrColorCubeEffect::GLProcessor::GenKey(const GrProcessor& proc,
|
|||||||
const GrGLSLCaps&, GrProcessorKeyBuilder* b) {
|
const GrGLSLCaps&, GrProcessorKeyBuilder* b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkColorCubeFilter::asFragmentProcessors(GrContext* context, GrProcessorDataManager*,
|
const GrFragmentProcessor* SkColorCubeFilter::asFragmentProcessor(GrContext* context,
|
||||||
SkTDArray<const GrFragmentProcessor*>* array) const {
|
GrProcessorDataManager*) const {
|
||||||
static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
|
static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
|
||||||
GrUniqueKey key;
|
GrUniqueKey key;
|
||||||
GrUniqueKey::Builder builder(&key, kDomain, 2);
|
GrUniqueKey::Builder builder(&key, kDomain, 2);
|
||||||
@ -324,19 +324,11 @@ bool SkColorCubeFilter::asFragmentProcessors(GrContext* context, GrProcessorData
|
|||||||
desc, true, fCubeData->data(), 0));
|
desc, true, fCubeData->data(), 0));
|
||||||
if (textureCube) {
|
if (textureCube) {
|
||||||
context->textureProvider()->assignUniqueKeyToTexture(key, textureCube);
|
context->textureProvider()->assignUniqueKeyToTexture(key, textureCube);
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GrFragmentProcessor* frag = textureCube ? GrColorCubeEffect::Create(textureCube) : nullptr;
|
return GrColorCubeEffect::Create(textureCube);
|
||||||
if (frag) {
|
|
||||||
if (array) {
|
|
||||||
*array->append() = frag;
|
|
||||||
} else {
|
|
||||||
frag->unref();
|
|
||||||
SkDEBUGCODE(frag = nullptr;)
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -70,15 +70,20 @@ SkFlattenable* SkModeColorFilter::CreateProc(SkReadBuffer& buffer) {
|
|||||||
#include "effects/GrConstColorProcessor.h"
|
#include "effects/GrConstColorProcessor.h"
|
||||||
#include "SkGr.h"
|
#include "SkGr.h"
|
||||||
|
|
||||||
bool SkModeColorFilter::asFragmentProcessors(GrContext*, GrProcessorDataManager*,
|
const GrFragmentProcessor* SkModeColorFilter::asFragmentProcessor(GrContext*,
|
||||||
SkTDArray<const GrFragmentProcessor*>* array) const {
|
GrProcessorDataManager*) const {
|
||||||
if (SkXfermode::kDst_Mode != fMode) {
|
if (SkXfermode::kDst_Mode == fMode) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
SkAutoTUnref<const GrFragmentProcessor> constFP(
|
SkAutoTUnref<const GrFragmentProcessor> constFP(
|
||||||
GrConstColorProcessor::Create(SkColorToPremulGrColor(fColor),
|
GrConstColorProcessor::Create(SkColorToPremulGrColor(fColor),
|
||||||
GrConstColorProcessor::kIgnore_InputMode));
|
GrConstColorProcessor::kIgnore_InputMode));
|
||||||
const GrFragmentProcessor* fp =
|
const GrFragmentProcessor* fp =
|
||||||
GrXfermodeFragmentProcessor::CreateFromSrcProcessor(constFP, fMode);
|
GrXfermodeFragmentProcessor::CreateFromSrcProcessor(constFP, fMode);
|
||||||
if (fp) {
|
if (!fp) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
#ifdef SK_DEBUG
|
#ifdef SK_DEBUG
|
||||||
// With a solid color input this should always be able to compute the blended color
|
// With a solid color input this should always be able to compute the blended color
|
||||||
// (at least for coeff modes)
|
// (at least for coeff modes)
|
||||||
@ -90,16 +95,7 @@ bool SkModeColorFilter::asFragmentProcessors(GrContext*, GrProcessorDataManager*
|
|||||||
SkASSERT(io.validFlags() == kRGBA_GrColorComponentFlags);
|
SkASSERT(io.validFlags() == kRGBA_GrColorComponentFlags);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (array) {
|
return fp;
|
||||||
*array->append() = fp;
|
|
||||||
} else {
|
|
||||||
fp->unref();
|
|
||||||
SkDEBUGCODE(fp = nullptr;)
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -390,7 +390,7 @@ SkColorFilter* SkColorMatrixFilter::newComposed(const SkColorFilter* innerFilter
|
|||||||
|
|
||||||
class ColorMatrixEffect : public GrFragmentProcessor {
|
class ColorMatrixEffect : public GrFragmentProcessor {
|
||||||
public:
|
public:
|
||||||
static GrFragmentProcessor* Create(const SkColorMatrix& matrix) {
|
static const GrFragmentProcessor* Create(const SkColorMatrix& matrix) {
|
||||||
return new ColorMatrixEffect(matrix);
|
return new ColorMatrixEffect(matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -536,19 +536,9 @@ const GrFragmentProcessor* ColorMatrixEffect::TestCreate(GrProcessorTestData* d)
|
|||||||
return ColorMatrixEffect::Create(colorMatrix);
|
return ColorMatrixEffect::Create(colorMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkColorMatrixFilter::asFragmentProcessors(GrContext*, GrProcessorDataManager*,
|
const GrFragmentProcessor* SkColorMatrixFilter::asFragmentProcessor(GrContext*,
|
||||||
SkTDArray<const GrFragmentProcessor*>* array) const {
|
GrProcessorDataManager*) const {
|
||||||
GrFragmentProcessor* frag = ColorMatrixEffect::Create(fMatrix);
|
return ColorMatrixEffect::Create(fMatrix);
|
||||||
if (frag) {
|
|
||||||
if (array) {
|
|
||||||
*array->append() = frag;
|
|
||||||
} else {
|
|
||||||
frag->unref();
|
|
||||||
SkDEBUGCODE(frag = nullptr;)
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -54,7 +54,7 @@ void SkLumaColorFilter::toString(SkString* str) const {
|
|||||||
#if SK_SUPPORT_GPU
|
#if SK_SUPPORT_GPU
|
||||||
class LumaColorFilterEffect : public GrFragmentProcessor {
|
class LumaColorFilterEffect : public GrFragmentProcessor {
|
||||||
public:
|
public:
|
||||||
static GrFragmentProcessor* Create() {
|
static const GrFragmentProcessor* Create() {
|
||||||
static LumaColorFilterEffect gLumaEffect;
|
static LumaColorFilterEffect gLumaEffect;
|
||||||
return SkRef(&gLumaEffect);
|
return SkRef(&gLumaEffect);
|
||||||
}
|
}
|
||||||
@ -108,19 +108,9 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool SkLumaColorFilter::asFragmentProcessors(GrContext*, GrProcessorDataManager*,
|
const GrFragmentProcessor* SkLumaColorFilter::asFragmentProcessor(GrContext*,
|
||||||
SkTDArray<const GrFragmentProcessor*>* array) const {
|
GrProcessorDataManager*) const {
|
||||||
|
|
||||||
GrFragmentProcessor* frag = LumaColorFilterEffect::Create();
|
return LumaColorFilterEffect::Create();
|
||||||
if (frag) {
|
|
||||||
if (array) {
|
|
||||||
*array->append() = frag;
|
|
||||||
} else {
|
|
||||||
frag->unref();
|
|
||||||
SkDEBUGCODE(frag = nullptr;)
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -48,8 +48,8 @@ public:
|
|||||||
SkColorFilter* newComposed(const SkColorFilter* inner) const override;
|
SkColorFilter* newComposed(const SkColorFilter* inner) const override;
|
||||||
|
|
||||||
#if SK_SUPPORT_GPU
|
#if SK_SUPPORT_GPU
|
||||||
bool asFragmentProcessors(GrContext*, GrProcessorDataManager*,
|
const GrFragmentProcessor* asFragmentProcessor(GrContext*,
|
||||||
SkTDArray<const GrFragmentProcessor*>*) const override;
|
GrProcessorDataManager*) const override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const override;
|
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 {
|
class ColorTableEffect : public GrFragmentProcessor {
|
||||||
public:
|
public:
|
||||||
static GrFragmentProcessor* Create(GrContext* context, SkBitmap bitmap, unsigned flags);
|
static const GrFragmentProcessor* Create(GrContext* context, SkBitmap bitmap, unsigned flags);
|
||||||
|
|
||||||
virtual ~ColorTableEffect();
|
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;
|
GrTextureStripAtlas::Desc desc;
|
||||||
desc.fWidth = bitmap.width();
|
desc.fWidth = bitmap.width();
|
||||||
@ -563,31 +564,17 @@ const GrFragmentProcessor* ColorTableEffect::TestCreate(GrProcessorTestData* d)
|
|||||||
(flags & (1 << 3)) ? luts[3] : nullptr
|
(flags & (1 << 3)) ? luts[3] : nullptr
|
||||||
));
|
));
|
||||||
|
|
||||||
SkTDArray<const GrFragmentProcessor*> array;
|
const GrFragmentProcessor* fp = filter->asFragmentProcessor(d->fContext, d->fProcDataManager);
|
||||||
if (filter->asFragmentProcessors(d->fContext, d->fProcDataManager, &array)) {
|
SkASSERT(fp);
|
||||||
SkASSERT(1 == array.count()); // TableColorFilter only returns 1
|
return fp;
|
||||||
return array[0];
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkTable_ColorFilter::asFragmentProcessors(GrContext* context,
|
const GrFragmentProcessor* SkTable_ColorFilter::asFragmentProcessor(GrContext* context,
|
||||||
GrProcessorDataManager*,
|
GrProcessorDataManager*) const {
|
||||||
SkTDArray<const GrFragmentProcessor*>* array) const {
|
|
||||||
SkBitmap bitmap;
|
SkBitmap bitmap;
|
||||||
this->asComponentTable(&bitmap);
|
this->asComponentTable(&bitmap);
|
||||||
|
|
||||||
GrFragmentProcessor* frag = ColorTableEffect::Create(context, bitmap, fFlags);
|
return ColorTableEffect::Create(context, bitmap, fFlags);
|
||||||
if (frag) {
|
|
||||||
if (array) {
|
|
||||||
*array->append() = frag;
|
|
||||||
} else {
|
|
||||||
frag->unref();
|
|
||||||
SkDEBUGCODE(frag = nullptr;)
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // SK_SUPPORT_GPU
|
#endif // SK_SUPPORT_GPU
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "GrCoordTransform.h"
|
#include "GrCoordTransform.h"
|
||||||
#include "gl/GrGLFragmentProcessor.h"
|
#include "gl/GrGLFragmentProcessor.h"
|
||||||
#include "gl/builders/GrGLProgramBuilder.h"
|
#include "gl/builders/GrGLProgramBuilder.h"
|
||||||
|
#include "effects/GrConstColorProcessor.h"
|
||||||
#include "effects/GrXfermodeFragmentProcessor.h"
|
#include "effects/GrXfermodeFragmentProcessor.h"
|
||||||
|
|
||||||
GrFragmentProcessor::~GrFragmentProcessor() {
|
GrFragmentProcessor::~GrFragmentProcessor() {
|
||||||
@ -279,3 +280,96 @@ const GrFragmentProcessor* GrFragmentProcessor::OverrideInput(const GrFragmentPr
|
|||||||
return SkRef(fp);
|
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(); }
|
GrColor color() const { return fInOut.color(); }
|
||||||
|
|
||||||
GrColorComponentFlags validFlags() const {
|
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) {
|
if (applyColorFilterToPaintColor) {
|
||||||
grPaint->setColor(SkColorToPremulGrColor(colorFilter->filterColor(skPaint.getColor())));
|
grPaint->setColor(SkColorToPremulGrColor(colorFilter->filterColor(skPaint.getColor())));
|
||||||
} else {
|
} else {
|
||||||
SkTDArray<const GrFragmentProcessor*> array;
|
SkAutoTUnref<const GrFragmentProcessor> cfFP(
|
||||||
if (colorFilter->asFragmentProcessors(context, grPaint->getProcessorDataManager(),
|
colorFilter->asFragmentProcessor(context, grPaint->getProcessorDataManager()));
|
||||||
&array)) {
|
if (cfFP) {
|
||||||
for (int i = 0; i < array.count(); ++i) {
|
grPaint->addColorFragmentProcessor(cfFP);
|
||||||
grPaint->addColorFragmentProcessor(array[i])->unref();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -100,19 +100,18 @@ static void test_getConstantColorComponents(skiatest::Reporter* reporter, GrCont
|
|||||||
GrPaint paint;
|
GrPaint paint;
|
||||||
for (size_t i = 0; i < SK_ARRAY_COUNT(filterTests); ++i) {
|
for (size_t i = 0; i < SK_ARRAY_COUNT(filterTests); ++i) {
|
||||||
const GetConstantComponentTestCase& test = filterTests[i];
|
const GetConstantComponentTestCase& test = filterTests[i];
|
||||||
SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(test.filterColor, test.filterMode));
|
SkAutoTUnref<SkColorFilter> cf(
|
||||||
SkTDArray<const GrFragmentProcessor*> array;
|
SkColorFilter::CreateModeFilter(test.filterColor, test.filterMode));
|
||||||
bool hasFrag = cf->asFragmentProcessors(grContext, paint.getProcessorDataManager(), &array);
|
SkAutoTUnref<const GrFragmentProcessor> fp(
|
||||||
REPORTER_ASSERT(reporter, hasFrag);
|
cf->asFragmentProcessor(grContext, paint.getProcessorDataManager()));
|
||||||
REPORTER_ASSERT(reporter, 1 == array.count());
|
REPORTER_ASSERT(reporter, fp);
|
||||||
GrInvariantOutput inout(test.inputColor,
|
GrInvariantOutput inout(test.inputColor,
|
||||||
static_cast<GrColorComponentFlags>(test.inputComponents),
|
static_cast<GrColorComponentFlags>(test.inputComponents),
|
||||||
false);
|
false);
|
||||||
array[0]->computeInvariantOutput(&inout);
|
fp->computeInvariantOutput(&inout);
|
||||||
|
REPORTER_ASSERT(reporter, filterColor(inout.color(), inout.validFlags()) ==
|
||||||
REPORTER_ASSERT(reporter, filterColor(inout.color(), inout.validFlags()) == test.outputColor);
|
test.outputColor);
|
||||||
REPORTER_ASSERT(reporter, test.outputComponents == inout.validFlags());
|
REPORTER_ASSERT(reporter, test.outputComponents == inout.validFlags());
|
||||||
array[0]->unref();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user