Commit fefa5851 authored by fs@opera.com's avatar fs@opera.com

Use WebBlendMode in FEBlend

This replaces the BlendModeType enumeration with the WebBlendMode for
FEBlend::m_mode. The former is moved to SVGFEBlendElement.
This enables FEBlend to use all of the blend modes available in
WebBlendMode, and leave any subset selection to the client of FEBlend
(which is SVGFEBlendElement).
The BlendModeType->string mapping is replaced by compositeOperatorName().

BUG=389594

Review URL: https://codereview.chromium.org/419253002

git-svn-id: svn://svn.chromium.org/blink/trunk@179029 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent f542108b
...@@ -23,20 +23,40 @@ ...@@ -23,20 +23,40 @@
#include "core/svg/SVGFEBlendElement.h" #include "core/svg/SVGFEBlendElement.h"
#include "core/SVGNames.h" #include "core/SVGNames.h"
#include "platform/graphics/filters/FEBlend.h"
#include "platform/graphics/filters/FilterEffect.h" #include "platform/graphics/filters/FilterEffect.h"
#include "core/svg/graphics/filters/SVGFilterBuilder.h" #include "core/svg/graphics/filters/SVGFilterBuilder.h"
namespace blink { namespace blink {
template<> const SVGEnumerationStringEntries& getStaticStringEntries<BlendModeType>() static WebBlendMode toWebBlendMode(SVGFEBlendElement::Mode mode)
{
switch (mode) {
case SVGFEBlendElement::ModeNormal:
return WebBlendModeNormal;
case SVGFEBlendElement::ModeMultiply:
return WebBlendModeMultiply;
case SVGFEBlendElement::ModeScreen:
return WebBlendModeScreen;
case SVGFEBlendElement::ModeDarken:
return WebBlendModeDarken;
case SVGFEBlendElement::ModeLighten:
return WebBlendModeLighten;
default:
ASSERT_NOT_REACHED();
return WebBlendModeNormal;
}
}
template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGFEBlendElement::Mode>()
{ {
DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ()); DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
if (entries.isEmpty()) { if (entries.isEmpty()) {
entries.append(std::make_pair(FEBLEND_MODE_NORMAL, "normal")); entries.append(std::make_pair(SVGFEBlendElement::ModeNormal, "normal"));
entries.append(std::make_pair(FEBLEND_MODE_MULTIPLY, "multiply")); entries.append(std::make_pair(SVGFEBlendElement::ModeMultiply, "multiply"));
entries.append(std::make_pair(FEBLEND_MODE_SCREEN, "screen")); entries.append(std::make_pair(SVGFEBlendElement::ModeScreen, "screen"));
entries.append(std::make_pair(FEBLEND_MODE_DARKEN, "darken")); entries.append(std::make_pair(SVGFEBlendElement::ModeDarken, "darken"));
entries.append(std::make_pair(FEBLEND_MODE_LIGHTEN, "lighten")); entries.append(std::make_pair(SVGFEBlendElement::ModeLighten, "lighten"));
} }
return entries; return entries;
} }
...@@ -45,7 +65,7 @@ inline SVGFEBlendElement::SVGFEBlendElement(Document& document) ...@@ -45,7 +65,7 @@ inline SVGFEBlendElement::SVGFEBlendElement(Document& document)
: SVGFilterPrimitiveStandardAttributes(SVGNames::feBlendTag, document) : SVGFilterPrimitiveStandardAttributes(SVGNames::feBlendTag, document)
, m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create())) , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
, m_in2(SVGAnimatedString::create(this, SVGNames::in2Attr, SVGString::create())) , m_in2(SVGAnimatedString::create(this, SVGNames::in2Attr, SVGString::create()))
, m_mode(SVGAnimatedEnumeration<BlendModeType>::create(this, SVGNames::modeAttr, FEBLEND_MODE_NORMAL)) , m_mode(SVGAnimatedEnumeration<Mode>::create(this, SVGNames::modeAttr, SVGFEBlendElement::ModeNormal))
{ {
ScriptWrappable::init(this); ScriptWrappable::init(this);
addToPropertyMap(m_in1); addToPropertyMap(m_in1);
...@@ -91,7 +111,7 @@ bool SVGFEBlendElement::setFilterEffectAttribute(FilterEffect* effect, const Qua ...@@ -91,7 +111,7 @@ bool SVGFEBlendElement::setFilterEffectAttribute(FilterEffect* effect, const Qua
{ {
FEBlend* blend = static_cast<FEBlend*>(effect); FEBlend* blend = static_cast<FEBlend*>(effect);
if (attrName == SVGNames::modeAttr) if (attrName == SVGNames::modeAttr)
return blend->setBlendMode(m_mode->currentValue()->enumValue()); return blend->setBlendMode(toWebBlendMode(m_mode->currentValue()->enumValue()));
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
return false; return false;
...@@ -127,7 +147,7 @@ PassRefPtr<FilterEffect> SVGFEBlendElement::build(SVGFilterBuilder* filterBuilde ...@@ -127,7 +147,7 @@ PassRefPtr<FilterEffect> SVGFEBlendElement::build(SVGFilterBuilder* filterBuilde
if (!input1 || !input2) if (!input1 || !input2)
return nullptr; return nullptr;
RefPtr<FilterEffect> effect = FEBlend::create(filter, m_mode->currentValue()->enumValue()); RefPtr<FilterEffect> effect = FEBlend::create(filter, toWebBlendMode(m_mode->currentValue()->enumValue()));
FilterEffectVector& inputEffects = effect->inputEffects(); FilterEffectVector& inputEffects = effect->inputEffects();
inputEffects.reserveCapacity(2); inputEffects.reserveCapacity(2);
inputEffects.append(input1); inputEffects.append(input1);
......
...@@ -23,18 +23,24 @@ ...@@ -23,18 +23,24 @@
#include "core/svg/SVGAnimatedEnumeration.h" #include "core/svg/SVGAnimatedEnumeration.h"
#include "core/svg/SVGFilterPrimitiveStandardAttributes.h" #include "core/svg/SVGFilterPrimitiveStandardAttributes.h"
#include "platform/graphics/filters/FEBlend.h"
namespace blink { namespace blink {
template<> const SVGEnumerationStringEntries& getStaticStringEntries<BlendModeType>();
class SVGFEBlendElement FINAL : public SVGFilterPrimitiveStandardAttributes { class SVGFEBlendElement FINAL : public SVGFilterPrimitiveStandardAttributes {
public: public:
enum Mode {
ModeUnknown = 0,
ModeNormal = 1,
ModeMultiply = 2,
ModeScreen = 3,
ModeDarken = 4,
ModeLighten = 5
};
DECLARE_NODE_FACTORY(SVGFEBlendElement); DECLARE_NODE_FACTORY(SVGFEBlendElement);
SVGAnimatedString* in1() { return m_in1.get(); } SVGAnimatedString* in1() { return m_in1.get(); }
SVGAnimatedString* in2() { return m_in2.get(); } SVGAnimatedString* in2() { return m_in2.get(); }
SVGAnimatedEnumeration<BlendModeType>* mode() { return m_mode.get(); } SVGAnimatedEnumeration<Mode>* mode() { return m_mode.get(); }
private: private:
explicit SVGFEBlendElement(Document&); explicit SVGFEBlendElement(Document&);
...@@ -47,9 +53,11 @@ private: ...@@ -47,9 +53,11 @@ private:
RefPtr<SVGAnimatedString> m_in1; RefPtr<SVGAnimatedString> m_in1;
RefPtr<SVGAnimatedString> m_in2; RefPtr<SVGAnimatedString> m_in2;
RefPtr<SVGAnimatedEnumeration<BlendModeType> > m_mode; RefPtr<SVGAnimatedEnumeration<Mode> > m_mode;
}; };
template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGFEBlendElement::Mode>();
} // namespace blink } // namespace blink
#endif #endif
...@@ -130,22 +130,21 @@ void FEBlend::platformApplyNEON(unsigned char* srcPixelArrayA, unsigned char* sr ...@@ -130,22 +130,21 @@ void FEBlend::platformApplyNEON(unsigned char* srcPixelArrayA, unsigned char* sr
uint16x8_t result; uint16x8_t result;
switch (m_mode) { switch (m_mode) {
case FEBLEND_MODE_NORMAL: case WebBlendModeNormal:
result = FEBlendUtilitiesNEON::normal(doubblePixelA, doubblePixelB, alphaA, alphaB, sixteenConst255, sixteenConstOne); result = FEBlendUtilitiesNEON::normal(doubblePixelA, doubblePixelB, alphaA, alphaB, sixteenConst255, sixteenConstOne);
break; break;
case FEBLEND_MODE_MULTIPLY: case WebBlendModeMultiply:
result = FEBlendUtilitiesNEON::multiply(doubblePixelA, doubblePixelB, alphaA, alphaB, sixteenConst255, sixteenConstOne); result = FEBlendUtilitiesNEON::multiply(doubblePixelA, doubblePixelB, alphaA, alphaB, sixteenConst255, sixteenConstOne);
break; break;
case FEBLEND_MODE_SCREEN: case WebBlendModeScreen:
result = FEBlendUtilitiesNEON::screen(doubblePixelA, doubblePixelB, alphaA, alphaB, sixteenConst255, sixteenConstOne); result = FEBlendUtilitiesNEON::screen(doubblePixelA, doubblePixelB, alphaA, alphaB, sixteenConst255, sixteenConstOne);
break; break;
case FEBLEND_MODE_DARKEN: case WebBlendModeDarken:
result = FEBlendUtilitiesNEON::darken(doubblePixelA, doubblePixelB, alphaA, alphaB, sixteenConst255, sixteenConstOne); result = FEBlendUtilitiesNEON::darken(doubblePixelA, doubblePixelB, alphaA, alphaB, sixteenConst255, sixteenConstOne);
break; break;
case FEBLEND_MODE_LIGHTEN: case WebBlendModeLighten:
result = FEBlendUtilitiesNEON::lighten(doubblePixelA, doubblePixelB, alphaA, alphaB, sixteenConst255, sixteenConstOne); result = FEBlendUtilitiesNEON::lighten(doubblePixelA, doubblePixelB, alphaA, alphaB, sixteenConst255, sixteenConstOne);
break; break;
case FEBLEND_MODE_UNKNOWN:
default: default:
result = vdupq_n_u16(0); result = vdupq_n_u16(0);
break; break;
......
...@@ -39,23 +39,23 @@ typedef unsigned char (*BlendType)(unsigned char colorA, unsigned char colorB, u ...@@ -39,23 +39,23 @@ typedef unsigned char (*BlendType)(unsigned char colorA, unsigned char colorB, u
namespace blink { namespace blink {
FEBlend::FEBlend(Filter* filter, BlendModeType mode) FEBlend::FEBlend(Filter* filter, WebBlendMode mode)
: FilterEffect(filter) : FilterEffect(filter)
, m_mode(mode) , m_mode(mode)
{ {
} }
PassRefPtr<FEBlend> FEBlend::create(Filter* filter, BlendModeType mode) PassRefPtr<FEBlend> FEBlend::create(Filter* filter, WebBlendMode mode)
{ {
return adoptRef(new FEBlend(filter, mode)); return adoptRef(new FEBlend(filter, mode));
} }
BlendModeType FEBlend::blendMode() const WebBlendMode FEBlend::blendMode() const
{ {
return m_mode; return m_mode;
} }
bool FEBlend::setBlendMode(BlendModeType mode) bool FEBlend::setBlendMode(WebBlendMode mode)
{ {
if (m_mode == mode) if (m_mode == mode)
return false; return false;
...@@ -63,36 +63,22 @@ bool FEBlend::setBlendMode(BlendModeType mode) ...@@ -63,36 +63,22 @@ bool FEBlend::setBlendMode(BlendModeType mode)
return true; return true;
} }
static WebBlendMode toWebBlendMode(BlendModeType mode) #if HAVE(ARM_NEON_INTRINSICS)
{ bool FEBlend::applySoftwareNEON()
switch (mode) {
case FEBLEND_MODE_NORMAL:
return WebBlendModeNormal;
case FEBLEND_MODE_MULTIPLY:
return WebBlendModeMultiply;
case FEBLEND_MODE_SCREEN:
return WebBlendModeScreen;
case FEBLEND_MODE_DARKEN:
return WebBlendModeDarken;
case FEBLEND_MODE_LIGHTEN:
return WebBlendModeLighten;
default:
ASSERT_NOT_REACHED();
return WebBlendModeNormal;
}
}
void FEBlend::applySoftware()
{ {
FilterEffect* in = inputEffect(0); if (m_mode != WebBlendModeNormal
FilterEffect* in2 = inputEffect(1); && m_mode != WebBlendModeMultiply
&& m_mode != WebBlendModeScreen
ASSERT(m_mode > FEBLEND_MODE_UNKNOWN && m_mode <= FEBLEND_MODE_LIGHTEN); && m_mode != WebBlendModeDarken
&& m_mode != WebBlendModeLighten)
return false;
#if HAVE(ARM_NEON_INTRINSICS)
Uint8ClampedArray* dstPixelArray = createPremultipliedImageResult(); Uint8ClampedArray* dstPixelArray = createPremultipliedImageResult();
if (!dstPixelArray) if (!dstPixelArray)
return; return true;
FilterEffect* in = inputEffect(0);
FilterEffect* in2 = inputEffect(1);
IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
RefPtr<Uint8ClampedArray> srcPixelArrayA = in->asPremultipliedImage(effectADrawingRect); RefPtr<Uint8ClampedArray> srcPixelArrayA = in->asPremultipliedImage(effectADrawingRect);
...@@ -116,7 +102,20 @@ void FEBlend::applySoftware() ...@@ -116,7 +102,20 @@ void FEBlend::applySoftware()
platformApplyNEON(reinterpret_cast<uint8_t*>(sourceA), reinterpret_cast<uint8_t*>(sourceBAndDest), reinterpret_cast<uint8_t*>(sourceBAndDest), 8); platformApplyNEON(reinterpret_cast<uint8_t*>(sourceA), reinterpret_cast<uint8_t*>(sourceBAndDest), reinterpret_cast<uint8_t*>(sourceBAndDest), 8);
reinterpret_cast<uint32_t*>(dstPixelArray->data())[0] = sourceBAndDest[0]; reinterpret_cast<uint32_t*>(dstPixelArray->data())[0] = sourceBAndDest[0];
} }
#else return true;
}
#endif
void FEBlend::applySoftware()
{
#if HAVE(ARM_NEON_INTRINSICS)
if (applySoftwareNEON())
return;
#endif
FilterEffect* in = inputEffect(0);
FilterEffect* in2 = inputEffect(1);
ImageBuffer* resultImage = createImageBufferResult(); ImageBuffer* resultImage = createImageBufferResult();
if (!resultImage) if (!resultImage)
return; return;
...@@ -127,52 +126,25 @@ void FEBlend::applySoftware() ...@@ -127,52 +126,25 @@ void FEBlend::applySoftware()
ASSERT(imageBuffer); ASSERT(imageBuffer);
ASSERT(imageBuffer2); ASSERT(imageBuffer2);
WebBlendMode blendMode = toWebBlendMode(m_mode);
filterContext->drawImageBuffer(imageBuffer2, drawingRegionOfInputImage(in2->absolutePaintRect())); filterContext->drawImageBuffer(imageBuffer2, drawingRegionOfInputImage(in2->absolutePaintRect()));
filterContext->drawImageBuffer(imageBuffer, drawingRegionOfInputImage(in->absolutePaintRect()), 0, CompositeSourceOver, blendMode); filterContext->drawImageBuffer(imageBuffer, drawingRegionOfInputImage(in->absolutePaintRect()), 0, CompositeSourceOver, m_mode);
#endif
} }
PassRefPtr<SkImageFilter> FEBlend::createImageFilter(SkiaImageFilterBuilder* builder) PassRefPtr<SkImageFilter> FEBlend::createImageFilter(SkiaImageFilterBuilder* builder)
{ {
RefPtr<SkImageFilter> foreground(builder->build(inputEffect(0), operatingColorSpace())); RefPtr<SkImageFilter> foreground(builder->build(inputEffect(0), operatingColorSpace()));
RefPtr<SkImageFilter> background(builder->build(inputEffect(1), operatingColorSpace())); RefPtr<SkImageFilter> background(builder->build(inputEffect(1), operatingColorSpace()));
RefPtr<SkXfermode> mode(WebCoreCompositeToSkiaComposite(CompositeSourceOver, toWebBlendMode(m_mode))); RefPtr<SkXfermode> mode(WebCoreCompositeToSkiaComposite(CompositeSourceOver, m_mode));
SkImageFilter::CropRect cropRect = getCropRect(builder->cropOffset()); SkImageFilter::CropRect cropRect = getCropRect(builder->cropOffset());
return adoptRef(SkXfermodeImageFilter::Create(mode.get(), background.get(), foreground.get(), &cropRect)); return adoptRef(SkXfermodeImageFilter::Create(mode.get(), background.get(), foreground.get(), &cropRect));
} }
static TextStream& operator<<(TextStream& ts, const BlendModeType& type)
{
switch (type) {
case FEBLEND_MODE_UNKNOWN:
ts << "unknown";
break;
case FEBLEND_MODE_NORMAL:
ts << "normal";
break;
case FEBLEND_MODE_MULTIPLY:
ts << "multiply";
break;
case FEBLEND_MODE_SCREEN:
ts << "screen";
break;
case FEBLEND_MODE_DARKEN:
ts << "darken";
break;
case FEBLEND_MODE_LIGHTEN:
ts << "lighten";
break;
}
return ts;
}
TextStream& FEBlend::externalRepresentation(TextStream& ts, int indent) const TextStream& FEBlend::externalRepresentation(TextStream& ts, int indent) const
{ {
writeIndent(ts, indent); writeIndent(ts, indent);
ts << "[feBlend"; ts << "[feBlend";
FilterEffect::externalRepresentation(ts); FilterEffect::externalRepresentation(ts);
ts << " mode=\"" << m_mode << "\"]\n"; ts << " mode=\"" << (m_mode == WebBlendModeNormal ? "normal" : compositeOperatorName(CompositeSourceOver, m_mode)) << "\"]\n";
inputEffect(0)->externalRepresentation(ts, indent + 1); inputEffect(0)->externalRepresentation(ts, indent + 1);
inputEffect(1)->externalRepresentation(ts, indent + 1); inputEffect(1)->externalRepresentation(ts, indent + 1);
return ts; return ts;
......
...@@ -28,21 +28,12 @@ ...@@ -28,21 +28,12 @@
namespace blink { namespace blink {
enum BlendModeType {
FEBLEND_MODE_UNKNOWN = 0,
FEBLEND_MODE_NORMAL = 1,
FEBLEND_MODE_MULTIPLY = 2,
FEBLEND_MODE_SCREEN = 3,
FEBLEND_MODE_DARKEN = 4,
FEBLEND_MODE_LIGHTEN = 5
};
class PLATFORM_EXPORT FEBlend : public FilterEffect { class PLATFORM_EXPORT FEBlend : public FilterEffect {
public: public:
static PassRefPtr<FEBlend> create(Filter*, BlendModeType); static PassRefPtr<FEBlend> create(Filter*, WebBlendMode);
BlendModeType blendMode() const; WebBlendMode blendMode() const;
bool setBlendMode(BlendModeType); bool setBlendMode(WebBlendMode);
void platformApplyGeneric(unsigned char* srcPixelArrayA, unsigned char* srcPixelArrayB, unsigned char* dstPixelArray, void platformApplyGeneric(unsigned char* srcPixelArrayA, unsigned char* srcPixelArrayB, unsigned char* dstPixelArray,
unsigned colorArrayLength); unsigned colorArrayLength);
...@@ -53,11 +44,12 @@ public: ...@@ -53,11 +44,12 @@ public:
virtual TextStream& externalRepresentation(TextStream&, int indention) const OVERRIDE; virtual TextStream& externalRepresentation(TextStream&, int indention) const OVERRIDE;
private: private:
FEBlend(Filter*, BlendModeType); FEBlend(Filter*, WebBlendMode);
virtual void applySoftware() OVERRIDE; virtual void applySoftware() OVERRIDE;
bool applySoftwareNEON();
BlendModeType m_mode; WebBlendMode m_mode;
}; };
} // namespace blink } // namespace blink
......
...@@ -56,7 +56,7 @@ protected: ...@@ -56,7 +56,7 @@ protected:
// Add a blend effect (with inputs : blur, source) // Add a blend effect (with inputs : blur, source)
RefPtr<FilterEffect> blendEffect = RefPtr<FilterEffect> blendEffect =
FEBlend::create(referenceFilter.get(), FEBLEND_MODE_NORMAL); FEBlend::create(referenceFilter.get(), WebBlendModeNormal);
blendEffect->setOperatingColorSpace(ColorSpaceDeviceRGB); blendEffect->setOperatingColorSpace(ColorSpaceDeviceRGB);
FilterEffectVector& blendInputs = blendEffect->inputEffects(); FilterEffectVector& blendInputs = blendEffect->inputEffects();
blendInputs.reserveCapacity(2); blendInputs.reserveCapacity(2);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment