mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 924102 - Add transform filter and remove offset filter. r=Bas
This commit is contained in:
parent
669377532c
commit
4cfec24dfa
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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(); }
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user