Bug 924102 - Add transform filter and remove offset filter. r=Bas

This commit is contained in:
Markus Stange 2013-11-27 12:25:27 +01:00
parent 669377532c
commit 4cfec24dfa
6 changed files with 181 additions and 86 deletions

View File

@ -30,6 +30,22 @@ D2D1_COLORMATRIX_ALPHA_MODE D2DAlphaMode(uint32_t aMode)
return D2D1_COLORMATRIX_ALPHA_MODE_PREMULTIPLIED;
}
D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE D2DAffineTransformInterpolationMode(uint32_t aFilter)
{
switch (aFilter) {
case FILTER_GOOD:
return D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE_LINEAR;
case FILTER_LINEAR:
return D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE_LINEAR;
case FILTER_POINT:
return D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE_NEAREST_NEIGHBOR;
default:
MOZ_CRASH("Unknown enum value!");
}
return D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE_LINEAR;
}
D2D1_BLEND_MODE D2DBlendMode(uint32_t aMode)
{
switch (aMode) {
@ -145,6 +161,11 @@ uint32_t ConvertValue(uint32_t aType, uint32_t aAttribute, uint32_t aValue)
aValue = D2DAlphaMode(aValue);
}
break;
case FILTER_TRANSFORM:
if (aAttribute == ATT_TRANSFORM_FILTER) {
aValue = D2DAffineTransformInterpolationMode(aValue);
}
break;
case FILTER_BLEND:
if (aAttribute == ATT_BLEND_BLENDMODE) {
aValue = D2DBlendMode(aValue);
@ -210,6 +231,11 @@ GetD2D1PropForAttribute(uint32_t aType, uint32_t aIndex)
CONVERT_PROP(COLOR_MATRIX_ALPHA_MODE, COLORMATRIX_PROP_ALPHA_MODE);
}
break;
case FILTER_TRANSFORM:
switch (aIndex) {
CONVERT_PROP(TRANSFORM_MATRIX, 2DAFFINETRANSFORM_PROP_TRANSFORM_MATRIX);
CONVERT_PROP(TRANSFORM_FILTER, 2DAFFINETRANSFORM_PROP_INTERPOLATION_MODE);
}
case FILTER_BLEND:
switch (aIndex) {
CONVERT_PROP(BLEND_BLENDMODE, BLEND_PROP_MODE);
@ -430,6 +456,8 @@ static inline REFCLSID GetCLDIDForFilterType(FilterType aType)
switch (aType) {
case FILTER_COLOR_MATRIX:
return CLSID_D2D1ColorMatrix;
case FILTER_TRANSFORM:
return CLSID_D2D12DAffineTransform;
case FILTER_BLEND:
return CLSID_D2D1Blend;
case FILTER_MORPHOLOGY:
@ -446,8 +474,6 @@ static inline REFCLSID GetCLDIDForFilterType(FilterType aType)
return CLSID_D2D1DiscreteTransfer;
case FILTER_GAMMA_TRANSFER:
return CLSID_D2D1GammaTransfer;
case FILTER_OFFSET:
return CLSID_D2D12DAffineTransform;
case FILTER_DISPLACEMENT_MAP:
return CLSID_D2D1DisplacementMap;
case FILTER_TURBULENCE:
@ -511,6 +537,18 @@ FilterNodeD2D1::Create(DrawTarget* aDT, ID2D1DeviceContext *aDC, FilterType aTyp
}
}
void
FilterNodeD2D1::InitUnmappedProperties()
{
switch (mType) {
case FILTER_TRANSFORM:
mEffect->SetValue(D2D1_2DAFFINETRANSFORM_PROP_BORDER_MODE, D2D1_BORDER_MODE_HARD);
break;
default:
break;
}
}
void
FilterNodeD2D1::SetInput(uint32_t aIndex, SourceSurface *aSurface)
{
@ -705,21 +743,21 @@ FilterNodeD2D1::SetAttribute(uint32_t aIndex, const Float *aValues, uint32_t aSi
void
FilterNodeD2D1::SetAttribute(uint32_t aIndex, const IntPoint &aValue)
{
if (mType == FILTER_OFFSET) {
MOZ_ASSERT(aIndex == ATT_OFFSET_OFFSET);
Matrix mat;
mat.Translate(Float(aValue.x), Float(aValue.y));
mEffect->SetValue(D2D1_2DAFFINETRANSFORM_PROP_TRANSFORM_MATRIX, D2DMatrix(mat));
return;
}
UINT32 input = GetD2D1PropForAttribute(mType, aIndex);
MOZ_ASSERT(input < mEffect->GetPropertyCount());
mEffect->SetValue(input, D2DPoint(aValue));
}
void
FilterNodeD2D1::SetAttribute(uint32_t aIndex, const Matrix &aMatrix)
{
UINT32 input = GetD2D1PropForAttribute(mType, aIndex);
MOZ_ASSERT(input < mEffect->GetPropertyCount());
mEffect->SetValue(input, D2DMatrix(aMatrix));
}
FilterNodeConvolveD2D1::FilterNodeConvolveD2D1(DrawTarget *aDT, ID2D1DeviceContext *aDC)
: FilterNodeD2D1(aDT, nullptr, FILTER_CONVOLVE_MATRIX)
, mEdgeMode(EDGE_MODE_DUPLICATE)

View File

@ -23,7 +23,9 @@ public:
: mDT(aDT)
, mEffect(aEffect)
, mType(aType)
{}
{
InitUnmappedProperties();
}
virtual FilterBackend GetBackendType() { return FILTER_BACKEND_DIRECT2D1_1; }
@ -43,6 +45,7 @@ public:
virtual void SetAttribute(uint32_t aIndex, bool aValue);
virtual void SetAttribute(uint32_t aIndex, const Float *aValues, uint32_t aSize);
virtual void SetAttribute(uint32_t aIndex, const IntPoint &aValue);
virtual void SetAttribute(uint32_t aIndex, const Matrix &aValue);
protected:
friend class DrawTargetD2D1;
@ -52,6 +55,8 @@ protected:
virtual ID2D1Effect* InputEffect() { return mEffect.get(); }
virtual ID2D1Effect* OutputEffect() { return mEffect.get(); }
void InitUnmappedProperties();
RefPtr<DrawTarget> mDT;
RefPtr<ID2D1Effect> mEffect;
FilterType mType;

View File

@ -473,6 +473,9 @@ FilterNodeSoftware::Create(FilterType aType)
case FILTER_BLEND:
filter = new FilterNodeBlendSoftware();
break;
case FILTER_TRANSFORM:
filter = new FilterNodeTransformSoftware();
break;
case FILTER_MORPHOLOGY:
filter = new FilterNodeMorphologySoftware();
break;
@ -500,9 +503,6 @@ FilterNodeSoftware::Create(FilterType aType)
case FILTER_CONVOLVE_MATRIX:
filter = new FilterNodeConvolveMatrixSoftware();
break;
case FILTER_OFFSET:
filter = new FilterNodeOffsetSoftware();
break;
case FILTER_DISPLACEMENT_MAP:
filter = new FilterNodeDisplacementMapSoftware();
break;
@ -908,6 +908,96 @@ FilterNodeBlendSoftware::GetOutputRectInRect(const IntRect& aRect)
GetInputRectInRect(IN_BLEND_IN2, aRect)).Intersect(aRect);
}
FilterNodeTransformSoftware::FilterNodeTransformSoftware()
: mFilter(FILTER_GOOD)
{}
int32_t
FilterNodeTransformSoftware::InputIndex(uint32_t aInputEnumIndex)
{
switch (aInputEnumIndex) {
case IN_TRANSFORM_IN: return 0;
default: return -1;
}
}
void
FilterNodeTransformSoftware::SetAttribute(uint32_t aIndex, uint32_t aFilter)
{
MOZ_ASSERT(aIndex == ATT_TRANSFORM_FILTER);
mFilter = static_cast<Filter>(aFilter);
Invalidate();
}
void
FilterNodeTransformSoftware::SetAttribute(uint32_t aIndex, const Matrix &aMatrix)
{
MOZ_ASSERT(aIndex == ATT_TRANSFORM_MATRIX);
mMatrix = aMatrix;
Invalidate();
}
IntRect
FilterNodeTransformSoftware::SourceRectForOutputRect(const IntRect &aRect)
{
Matrix inverted(mMatrix);
if (!inverted.Invert()) {
return IntRect();
}
Rect neededRect = inverted.TransformBounds(Rect(aRect));
neededRect.RoundOut();
return GetInputRectInRect(IN_TRANSFORM_IN, RoundedToInt(neededRect));
}
TemporaryRef<DataSourceSurface>
FilterNodeTransformSoftware::Render(const IntRect& aRect)
{
IntRect srcRect = SourceRectForOutputRect(aRect);
RefPtr<DataSourceSurface> input =
GetInputDataSourceSurface(IN_TRANSFORM_IN, srcRect, NEED_COLOR_CHANNELS);
if (!input) {
return nullptr;
}
Matrix transform = Matrix().Translate(srcRect.x, srcRect.y) * mMatrix *
Matrix().Translate(-aRect.x, -aRect.y);
if (transform.IsIdentity() && srcRect.Size() == aRect.Size()) {
return input;
}
RefPtr<DrawTarget> dt =
Factory::CreateDrawTarget(BACKEND_CAIRO, aRect.Size(), input->GetFormat());
if (!dt) {
return nullptr;
}
Rect r(0, 0, srcRect.width, srcRect.height);
dt->SetTransform(transform);
dt->DrawSurface(input, r, r, DrawSurfaceOptions(mFilter));
RefPtr<SourceSurface> result = dt->Snapshot();
RefPtr<DataSourceSurface> resultData = result->GetDataSurface();
return resultData;
}
void
FilterNodeTransformSoftware::RequestFromInputsForRect(const IntRect &aRect)
{
RequestInputRect(IN_TRANSFORM_IN, SourceRectForOutputRect(aRect));
}
IntRect
FilterNodeTransformSoftware::GetOutputRectInRect(const IntRect& aRect)
{
IntRect srcRect = SourceRectForOutputRect(aRect);
Rect outRect = mMatrix.TransformBounds(Rect(srcRect));
outRect.RoundOut();
return RoundedToInt(outRect).Intersect(aRect);
}
FilterNodeMorphologySoftware::FilterNodeMorphologySoftware()
: mOperator(MORPHOLOGY_OPERATOR_ERODE)
{}
@ -2187,49 +2277,6 @@ FilterNodeConvolveMatrixSoftware::GetOutputRectInRect(const IntRect& aRect)
return InflatedDestRect(srcOutput).Intersect(aRect);
}
int32_t
FilterNodeOffsetSoftware::InputIndex(uint32_t aInputEnumIndex)
{
switch (aInputEnumIndex) {
case IN_OFFSET_IN: return 0;
default: return -1;
}
}
void
FilterNodeOffsetSoftware::SetAttribute(uint32_t aIndex,
const IntPoint &aOffset)
{
MOZ_ASSERT(aIndex == ATT_OFFSET_OFFSET);
mOffset = aOffset;
Invalidate();
}
TemporaryRef<DataSourceSurface>
FilterNodeOffsetSoftware::Render(const IntRect& aRect)
{
return GetInputDataSourceSurface(IN_OFFSET_IN, aRect - mOffset);
}
// Override GetOutput in order to disable caching.
TemporaryRef<DataSourceSurface>
FilterNodeOffsetSoftware::GetOutput(const IntRect& aRect)
{
return Render(aRect);
}
void
FilterNodeOffsetSoftware::RequestFromInputsForRect(const IntRect &aRect)
{
RequestInputRect(IN_OFFSET_IN, aRect - mOffset);
}
IntRect
FilterNodeOffsetSoftware::GetOutputRectInRect(const IntRect& aRect)
{
return GetInputRectInRect(IN_OFFSET_IN, aRect - mOffset) + mOffset;
}
FilterNodeDisplacementMapSoftware::FilterNodeDisplacementMapSoftware()
: mScale(0.0f)
, mChannelX(COLOR_CHANNEL_R)

View File

@ -212,6 +212,26 @@ protected:
// Subclasses for specific filters.
class FilterNodeTransformSoftware : public FilterNodeSoftware
{
public:
FilterNodeTransformSoftware();
using FilterNodeSoftware::SetAttribute;
virtual void SetAttribute(uint32_t aIndex, uint32_t aGraphicsFilter) MOZ_OVERRIDE;
virtual void SetAttribute(uint32_t aIndex, const Matrix &aMatrix) MOZ_OVERRIDE;
protected:
virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
virtual int32_t InputIndex(uint32_t aInputEnumIndex) MOZ_OVERRIDE;
virtual void RequestFromInputsForRect(const IntRect &aRect) MOZ_OVERRIDE;
IntRect SourceRectForOutputRect(const IntRect &aRect);
private:
Matrix mMatrix;
Filter mFilter;
};
class FilterNodeBlendSoftware : public FilterNodeSoftware
{
public:
@ -449,23 +469,6 @@ private:
bool mPreserveAlpha;
};
class FilterNodeOffsetSoftware : public FilterNodeSoftware
{
public:
using FilterNodeSoftware::SetAttribute;
virtual void SetAttribute(uint32_t aIndex, const IntPoint &aOffset) MOZ_OVERRIDE;
protected:
virtual TemporaryRef<DataSourceSurface> GetOutput(const IntRect &aRect) MOZ_OVERRIDE;
virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
virtual int32_t InputIndex(uint32_t aInputEnumIndex) MOZ_OVERRIDE;
virtual void RequestFromInputsForRect(const IntRect &aRect) MOZ_OVERRIDE;
private:
IntPoint mOffset;
};
class FilterNodeDisplacementMapSoftware : public FilterNodeSoftware
{
public:

View File

@ -23,6 +23,17 @@ enum FilterBackend {
FILTER_BACKEND_DIRECT2D1_1
};
enum TransformFilterAtts
{
ATT_TRANSFORM_MATRIX = 0, // Matrix
ATT_TRANSFORM_FILTER // Filter
};
enum TransformFilterInputs
{
IN_TRANSFORM_IN = 0
};
enum BlendFilterAtts
{
ATT_BLEND_BLENDMODE = 0 // uint32_t
@ -214,16 +225,6 @@ enum ConvolveMatrixInputs
IN_CONVOLVE_MATRIX_IN = 0
};
enum OffsetAtts
{
ATT_OFFSET_OFFSET = 0 // IntPoint
};
enum OffsetInputs
{
IN_OFFSET_IN = 0
};
enum DisplacementMapAtts
{
ATT_DISPLACEMENT_MAP_SCALE = 0, // Float
@ -480,6 +481,7 @@ public:
virtual void SetAttribute(uint32_t aIndex, const Rect &) { MOZ_CRASH(); }
virtual void SetAttribute(uint32_t aIndex, const IntRect &) { MOZ_CRASH(); }
virtual void SetAttribute(uint32_t aIndex, const Point &) { MOZ_CRASH(); }
virtual void SetAttribute(uint32_t aIndex, const Matrix &) { MOZ_CRASH(); }
virtual void SetAttribute(uint32_t aIndex, const Matrix5x4 &) { MOZ_CRASH(); }
virtual void SetAttribute(uint32_t aIndex, const Point3D &) { MOZ_CRASH(); }
virtual void SetAttribute(uint32_t aIndex, const Color &) { MOZ_CRASH(); }

View File

@ -46,6 +46,7 @@ enum SurfaceFormat
enum FilterType
{
FILTER_BLEND = 0,
FILTER_TRANSFORM,
FILTER_MORPHOLOGY,
FILTER_COLOR_MATRIX,
FILTER_FLOOD,
@ -55,7 +56,6 @@ enum FilterType
FILTER_LINEAR_TRANSFER,
FILTER_GAMMA_TRANSFER,
FILTER_CONVOLVE_MATRIX,
FILTER_OFFSET,
FILTER_DISPLACEMENT_MAP,
FILTER_TURBULENCE,
FILTER_ARITHMETIC_COMBINE,