mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 702878: Extend gfx::2d API and D2D backend with new functionality. r=jrmuizel sr=roc
This commit is contained in:
parent
a5c6a574f5
commit
c30eae6661
@ -809,7 +809,7 @@ protected:
|
||||
if (state.patternStyles[aStyle]->mRepeat == nsCanvasPatternAzure::NOREPEAT) {
|
||||
mode = EXTEND_CLAMP;
|
||||
} else {
|
||||
mode = EXTEND_WRAP;
|
||||
mode = EXTEND_REPEAT;
|
||||
}
|
||||
mPattern = new (mSurfacePattern.addr())
|
||||
SurfacePattern(state.patternStyles[aStyle]->mSurface, mode);
|
||||
|
107
gfx/2d/2D.h
107
gfx/2d/2D.h
@ -148,13 +148,19 @@ struct StrokeOptions {
|
||||
*
|
||||
* mFilter - Filter used when resampling source surface region to the
|
||||
* destination region.
|
||||
* aSamplingBounds - This indicates whether the implementation is allowed
|
||||
* to sample pixels outside the source rectangle as
|
||||
* specified in DrawSurface on the surface.
|
||||
*/
|
||||
struct DrawSurfaceOptions {
|
||||
DrawSurfaceOptions(Filter aFilter = FILTER_LINEAR)
|
||||
DrawSurfaceOptions(Filter aFilter = FILTER_LINEAR,
|
||||
SamplingBounds aSamplingBounds = SAMPLING_UNBOUNDED)
|
||||
: mFilter(aFilter)
|
||||
, mSamplingBounds(aSamplingBounds)
|
||||
{ }
|
||||
|
||||
Filter mFilter : 3;
|
||||
SamplingBounds mSamplingBounds : 1;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -212,16 +218,20 @@ class LinearGradientPattern : public Pattern
|
||||
public:
|
||||
/*
|
||||
* aBegin Start of the linear gradient
|
||||
* aEnd End of the linear gradient
|
||||
* aEnd End of the linear gradient - NOTE: In the case of a zero length
|
||||
* gradient it will act as the color of the last stop.
|
||||
* aStops GradientStops object for this gradient, this should match the
|
||||
* backend type of the draw target this pattern will be used with.
|
||||
* aMatrix A matrix that transforms the pattern into user space
|
||||
*/
|
||||
LinearGradientPattern(const Point &aBegin,
|
||||
const Point &aEnd,
|
||||
GradientStops *aStops)
|
||||
GradientStops *aStops,
|
||||
const Matrix &aMatrix = Matrix())
|
||||
: mBegin(aBegin)
|
||||
, mEnd(aEnd)
|
||||
, mStops(aStops)
|
||||
, mMatrix(aMatrix)
|
||||
{
|
||||
}
|
||||
|
||||
@ -230,6 +240,7 @@ public:
|
||||
Point mBegin;
|
||||
Point mEnd;
|
||||
RefPtr<GradientStops> mStops;
|
||||
Matrix mMatrix;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -245,17 +256,20 @@ public:
|
||||
* aEnd End of the linear gradient
|
||||
* aStops GradientStops object for this gradient, this should match the
|
||||
* backend type of the draw target this pattern will be used with.
|
||||
* aMatrix A matrix that transforms the pattern into user space
|
||||
*/
|
||||
RadialGradientPattern(const Point &aCenter1,
|
||||
const Point &aCenter2,
|
||||
Float aRadius1,
|
||||
Float aRadius2,
|
||||
GradientStops *aStops)
|
||||
GradientStops *aStops,
|
||||
const Matrix &aMatrix = Matrix())
|
||||
: mCenter1(aCenter1)
|
||||
, mCenter2(aCenter2)
|
||||
, mRadius1(aRadius1)
|
||||
, mRadius2(aRadius2)
|
||||
, mStops(aStops)
|
||||
, mMatrix(aMatrix)
|
||||
{
|
||||
}
|
||||
|
||||
@ -266,6 +280,7 @@ public:
|
||||
Float mRadius1;
|
||||
Float mRadius2;
|
||||
RefPtr<GradientStops> mStops;
|
||||
Matrix mMatrix;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -275,9 +290,19 @@ public:
|
||||
class SurfacePattern : public Pattern
|
||||
{
|
||||
public:
|
||||
SurfacePattern(SourceSurface *aSourceSurface, ExtendMode aExtendMode)
|
||||
/*
|
||||
* aSourceSurface Surface to use for drawing
|
||||
* aExtendMode This determines how the image is extended outside the bounds
|
||||
* of the image.
|
||||
* aMatrix A matrix that transforms the pattern into user space
|
||||
* aFilter Resampling filter used for resampling the image.
|
||||
*/
|
||||
SurfacePattern(SourceSurface *aSourceSurface, ExtendMode aExtendMode,
|
||||
const Matrix &aMatrix = Matrix(), Filter aFilter = FILTER_LINEAR)
|
||||
: mSurface(aSourceSurface)
|
||||
, mExtendMode(aExtendMode)
|
||||
, mFilter(aFilter)
|
||||
, mMatrix(aMatrix)
|
||||
{}
|
||||
|
||||
virtual PatternType GetType() const { return PATTERN_SURFACE; }
|
||||
@ -285,6 +310,7 @@ public:
|
||||
RefPtr<SourceSurface> mSurface;
|
||||
ExtendMode mExtendMode;
|
||||
Filter mFilter;
|
||||
Matrix mMatrix;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -311,6 +337,7 @@ public:
|
||||
class DataSourceSurface : public SourceSurface
|
||||
{
|
||||
public:
|
||||
virtual SurfaceType GetType() const { return SURFACE_DATA; }
|
||||
/* Get the raw bitmap data of the surface */
|
||||
virtual unsigned char *GetData() = 0;
|
||||
/*
|
||||
@ -319,6 +346,12 @@ public:
|
||||
*/
|
||||
virtual int32_t Stride() = 0;
|
||||
|
||||
/*
|
||||
* This function is called after modifying the data on the source surface
|
||||
* directly through the data pointer.
|
||||
*/
|
||||
virtual void MarkDirty() {}
|
||||
|
||||
virtual TemporaryRef<DataSourceSurface> GetDataSurface() { RefPtr<DataSourceSurface> temp = this; return temp.forget(); }
|
||||
};
|
||||
|
||||
@ -606,6 +639,19 @@ public:
|
||||
const Pattern &aPattern,
|
||||
const DrawOptions &aOptions = DrawOptions()) = 0;
|
||||
|
||||
/*
|
||||
* This takes a source pattern and a mask, and composites the source pattern
|
||||
* onto the destination surface using the alpha channel of the mask pattern
|
||||
* as a mask for the operation.
|
||||
*
|
||||
* aSource Source pattern
|
||||
* aMask Mask pattern
|
||||
* aOptions Drawing options
|
||||
*/
|
||||
virtual void Mask(const Pattern &aSource,
|
||||
const Pattern &aMask,
|
||||
const DrawOptions &aOptions = DrawOptions()) = 0;
|
||||
|
||||
/*
|
||||
* Push a clip to the DrawTarget.
|
||||
*
|
||||
@ -613,6 +659,14 @@ public:
|
||||
*/
|
||||
virtual void PushClip(const Path *aPath) = 0;
|
||||
|
||||
/*
|
||||
* Push an axis-aligned rectangular clip to the DrawTarget. This rectangle
|
||||
* is specified in user space.
|
||||
*
|
||||
* aRect The rect to clip to
|
||||
*/
|
||||
virtual void PushClipRect(const Rect &aRect) = 0;
|
||||
|
||||
/* Pop a clip from the DrawTarget. A pop without a corresponding push will
|
||||
* be ignored.
|
||||
*/
|
||||
@ -625,9 +679,9 @@ public:
|
||||
* The SourceSurface does not take ownership of aData, and may be freed at any time.
|
||||
*/
|
||||
virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
|
||||
const IntSize &aSize,
|
||||
int32_t aStride,
|
||||
SurfaceFormat aFormat) const = 0;
|
||||
const IntSize &aSize,
|
||||
int32_t aStride,
|
||||
SurfaceFormat aFormat) const = 0;
|
||||
|
||||
/*
|
||||
* Create a SourceSurface optimized for use with this DrawTarget from
|
||||
@ -666,8 +720,13 @@ public:
|
||||
*
|
||||
* aStops An array of gradient stops
|
||||
* aNumStops Number of stops in the array aStops
|
||||
* aExtendNone This describes how to extend the stop color outside of the
|
||||
* gradient area.
|
||||
*/
|
||||
virtual TemporaryRef<GradientStops> CreateGradientStops(GradientStop *aStops, uint32_t aNumStops) const = 0;
|
||||
virtual TemporaryRef<GradientStops>
|
||||
CreateGradientStops(GradientStop *aStops,
|
||||
uint32_t aNumStops,
|
||||
ExtendMode aExtendMode = EXTEND_CLAMP) const = 0;
|
||||
|
||||
const Matrix &GetTransform() const { return mTransform; }
|
||||
|
||||
@ -695,12 +754,34 @@ protected:
|
||||
class Factory
|
||||
{
|
||||
public:
|
||||
#ifdef USE_CAIRO
|
||||
static TemporaryRef<DrawTarget> CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface);
|
||||
#endif
|
||||
|
||||
static TemporaryRef<DrawTarget> CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFormat aFormat);
|
||||
static TemporaryRef<ScaledFont> CreateScaledFontForNativeFont(const NativeFont &aNativeFont, Float aSize);
|
||||
static TemporaryRef<DrawTarget>
|
||||
CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFormat aFormat);
|
||||
|
||||
static TemporaryRef<DrawTarget>
|
||||
CreateDrawTargetForData(BackendType aBackend, unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat);
|
||||
|
||||
static TemporaryRef<ScaledFont>
|
||||
CreateScaledFontForNativeFont(const NativeFont &aNativeFont, Float aSize);
|
||||
|
||||
/*
|
||||
* This creates a simple data source surface for a certain size. It allocates
|
||||
* new memory for the surface. This memory is freed when the surface is
|
||||
* destroyed.
|
||||
*/
|
||||
static TemporaryRef<DataSourceSurface>
|
||||
CreateDataSourceSurface(const IntSize &aSize, SurfaceFormat aFormat);
|
||||
|
||||
/*
|
||||
* This creates a simple data source surface for some existing data. It will
|
||||
* wrap this data and the data for this source surface. The caller is
|
||||
* responsible for deallocating the memory only after destruction of the
|
||||
* surface.
|
||||
*/
|
||||
static TemporaryRef<DataSourceSurface>
|
||||
CreateDataSourceSurfaceFromData(unsigned char *aData, int32_t aStride,
|
||||
const IntSize &aSize, SurfaceFormat aFormat);
|
||||
|
||||
#ifdef WIN32
|
||||
static TemporaryRef<DrawTarget> CreateDrawTargetForD3D10Texture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
|
||||
|
@ -106,8 +106,13 @@ public:
|
||||
const Pattern &aPattern,
|
||||
const DrawOptions &aOptions)
|
||||
{ return; }
|
||||
virtual void Mask(const Pattern &aSource,
|
||||
const Pattern &aMask,
|
||||
const DrawOptions &aOptions = DrawOptions())
|
||||
{ return; }
|
||||
|
||||
virtual void PushClip(const Path *aPath) { }
|
||||
virtual void PushClipRect(const Rect &aRect) { }
|
||||
virtual void PopClip() { }
|
||||
|
||||
virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FILL_WINDING) const { return NULL; }
|
||||
@ -123,7 +128,7 @@ public:
|
||||
CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const
|
||||
{ return NULL; }
|
||||
|
||||
virtual TemporaryRef<GradientStops> CreateGradientStops(GradientStop *aStops, uint32_t aNumStops) const
|
||||
virtual TemporaryRef<GradientStops> CreateGradientStops(GradientStop *aStops, uint32_t aNumStops, ExtendMode aExtendMode = EXTEND_CLAMP) const
|
||||
{ return NULL; }
|
||||
|
||||
virtual void *GetNativeSurface(NativeSurfaceType aType)
|
||||
|
@ -268,6 +268,8 @@ DrawTargetD2D::DrawSurface(SourceSurface *aSurface,
|
||||
|
||||
PrepareForDrawing(rt);
|
||||
|
||||
rt->SetAntialiasMode(D2DAAMode(aOptions.mAntialiasMode));
|
||||
|
||||
Rect srcRect = aSource;
|
||||
|
||||
switch (aSurface->GetType()) {
|
||||
@ -753,6 +755,8 @@ DrawTargetD2D::FillRect(const Rect &aRect,
|
||||
|
||||
PrepareForDrawing(rt);
|
||||
|
||||
rt->SetAntialiasMode(D2DAAMode(aOptions.mAntialiasMode));
|
||||
|
||||
RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aPattern, aOptions.mAlpha);
|
||||
|
||||
if (brush) {
|
||||
@ -772,6 +776,8 @@ DrawTargetD2D::StrokeRect(const Rect &aRect,
|
||||
|
||||
PrepareForDrawing(rt);
|
||||
|
||||
rt->SetAntialiasMode(D2DAAMode(aOptions.mAntialiasMode));
|
||||
|
||||
RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aPattern, aOptions.mAlpha);
|
||||
|
||||
RefPtr<ID2D1StrokeStyle> strokeStyle = CreateStrokeStyleForOptions(aStrokeOptions);
|
||||
@ -794,6 +800,8 @@ DrawTargetD2D::StrokeLine(const Point &aStart,
|
||||
|
||||
PrepareForDrawing(rt);
|
||||
|
||||
rt->SetAntialiasMode(D2DAAMode(aOptions.mAntialiasMode));
|
||||
|
||||
RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aPattern, aOptions.mAlpha);
|
||||
|
||||
RefPtr<ID2D1StrokeStyle> strokeStyle = CreateStrokeStyleForOptions(aStrokeOptions);
|
||||
@ -822,6 +830,8 @@ DrawTargetD2D::Stroke(const Path *aPath,
|
||||
|
||||
PrepareForDrawing(rt);
|
||||
|
||||
rt->SetAntialiasMode(D2DAAMode(aOptions.mAntialiasMode));
|
||||
|
||||
RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aPattern, aOptions.mAlpha);
|
||||
|
||||
RefPtr<ID2D1StrokeStyle> strokeStyle = CreateStrokeStyleForOptions(aStrokeOptions);
|
||||
@ -849,6 +859,8 @@ DrawTargetD2D::Fill(const Path *aPath,
|
||||
|
||||
PrepareForDrawing(rt);
|
||||
|
||||
rt->SetAntialiasMode(D2DAAMode(aOptions.mAntialiasMode));
|
||||
|
||||
RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aPattern, aOptions.mAlpha);
|
||||
|
||||
if (brush) {
|
||||
@ -916,6 +928,36 @@ DrawTargetD2D::FillGlyphs(ScaledFont *aFont,
|
||||
FinalizeRTForOperation(aOptions.mCompositionOp, aPattern, Rect(0, 0, (Float)mSize.width, (Float)mSize.height));
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetD2D::Mask(const Pattern &aSource,
|
||||
const Pattern &aMask,
|
||||
const DrawOptions &aOptions)
|
||||
{
|
||||
ID2D1RenderTarget *rt = GetRTForOperation(aOptions.mCompositionOp, aSource);
|
||||
|
||||
PrepareForDrawing(rt);
|
||||
|
||||
RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aSource, aOptions.mAlpha);
|
||||
RefPtr<ID2D1Brush> maskBrush = CreateBrushForPattern(aMask, 1.0f);
|
||||
|
||||
RefPtr<ID2D1Layer> layer;
|
||||
rt->CreateLayer(byRef(layer));
|
||||
rt->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), NULL,
|
||||
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
|
||||
D2D1::IdentityMatrix(),
|
||||
1.0f, maskBrush),
|
||||
layer);
|
||||
|
||||
Rect rect(0, 0, mSize.width, mSize.height);
|
||||
Matrix mat = mTransform;
|
||||
mat.Invert();
|
||||
|
||||
rt->FillRectangle(D2DRect(mat.TransformBounds(rect)), brush);
|
||||
rt->PopLayer();
|
||||
|
||||
FinalizeRTForOperation(aOptions.mCompositionOp, aSource, Rect(0, 0, (Float)mSize.width, (Float)mSize.height));
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetD2D::PushClip(const Path *aPath)
|
||||
{
|
||||
@ -957,11 +999,45 @@ DrawTargetD2D::PushClip(const Path *aPath)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetD2D::PushClipRect(const Rect &aRect)
|
||||
{
|
||||
if (!mTransform.IsRectilinear()) {
|
||||
// Whoops, this isn't a rectangle in device space, Direct2D will not deal
|
||||
// with this transform the way we want it to.
|
||||
// See remarks: http://msdn.microsoft.com/en-us/library/dd316860%28VS.85%29.aspx
|
||||
|
||||
RefPtr<PathBuilder> pathBuilder = CreatePathBuilder();
|
||||
pathBuilder->MoveTo(aRect.TopLeft());
|
||||
pathBuilder->LineTo(aRect.TopRight());
|
||||
pathBuilder->LineTo(aRect.BottomRight());
|
||||
pathBuilder->LineTo(aRect.BottomLeft());
|
||||
pathBuilder->Close();
|
||||
RefPtr<Path> path = pathBuilder->Finish();
|
||||
return PushClip(path);
|
||||
}
|
||||
|
||||
PushedClip clip;
|
||||
// Do not store the transform, just store the device space rectangle directly.
|
||||
clip.mBounds = D2DRect(mTransform.TransformBounds(aRect));
|
||||
|
||||
mPushedClips.push_back(clip);
|
||||
|
||||
mRT->SetTransform(D2D1::IdentityMatrix());
|
||||
if (mClipsArePushed) {
|
||||
mRT->PushAxisAlignedClip(clip.mBounds, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetD2D::PopClip()
|
||||
{
|
||||
if (mClipsArePushed) {
|
||||
mRT->PopLayer();
|
||||
if (mPushedClips.back().mLayer) {
|
||||
mRT->PopLayer();
|
||||
} else {
|
||||
mRT->PopAxisAlignedClip();
|
||||
}
|
||||
}
|
||||
mPushedClips.pop_back();
|
||||
}
|
||||
@ -975,7 +1051,6 @@ DrawTargetD2D::CreateSourceSurfaceFromData(unsigned char *aData,
|
||||
RefPtr<SourceSurfaceD2D> newSurf = new SourceSurfaceD2D();
|
||||
|
||||
if (!newSurf->InitFromData(aData, aSize, aStride, aFormat, mRT)) {
|
||||
gfxDebug() << *this << ": Failure to create source surface from data. Size: " << aSize;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1049,9 +1124,9 @@ DrawTargetD2D::CreatePathBuilder(FillRule aFillRule) const
|
||||
}
|
||||
|
||||
TemporaryRef<GradientStops>
|
||||
DrawTargetD2D::CreateGradientStops(GradientStop *rawStops, uint32_t aNumStops) const
|
||||
DrawTargetD2D::CreateGradientStops(GradientStop *rawStops, uint32_t aNumStops, ExtendMode aExtendMode) const
|
||||
{
|
||||
D2D1_GRADIENT_STOP *stops = new D2D1_GRADIENT_STOP[aNumStops];
|
||||
vector<D2D1_GRADIENT_STOP> stops(aNumStops);
|
||||
|
||||
for (uint32_t i = 0; i < aNumStops; i++) {
|
||||
stops[i].position = rawStops[i].offset;
|
||||
@ -1060,7 +1135,10 @@ DrawTargetD2D::CreateGradientStops(GradientStop *rawStops, uint32_t aNumStops) c
|
||||
|
||||
RefPtr<ID2D1GradientStopCollection> stopCollection;
|
||||
|
||||
HRESULT hr = mRT->CreateGradientStopCollection(stops, aNumStops, byRef(stopCollection));
|
||||
HRESULT hr =
|
||||
mRT->CreateGradientStopCollection(&stops.front(), aNumStops,
|
||||
D2D1_GAMMA_2_2, D2DExtend(aExtendMode),
|
||||
byRef(stopCollection));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
gfxWarning() << "Failed to create GradientStopCollection. Code: " << hr;
|
||||
@ -1097,7 +1175,7 @@ DrawTargetD2D::Init(const IntSize &aSize, SurfaceFormat aFormat)
|
||||
}
|
||||
mDevice = Factory::GetDirect3D10Device();
|
||||
|
||||
CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
CD3D10_TEXTURE2D_DESC desc(DXGIFormat(aFormat),
|
||||
mSize.width,
|
||||
mSize.height,
|
||||
1, 1);
|
||||
@ -1110,7 +1188,12 @@ DrawTargetD2D::Init(const IntSize &aSize, SurfaceFormat aFormat)
|
||||
return false;
|
||||
}
|
||||
|
||||
return InitD2DRenderTarget();
|
||||
if (!InitD2DRenderTarget()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mRT->Clear(D2D1::ColorF(0, 0));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1230,8 +1313,6 @@ DrawTargetD2D::InitD2DRenderTarget()
|
||||
|
||||
mRT->BeginDraw();
|
||||
|
||||
mRT->Clear(D2D1::ColorF(0, 0));
|
||||
|
||||
if (mFormat == FORMAT_B8G8R8X8) {
|
||||
mRT->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE);
|
||||
}
|
||||
@ -1246,23 +1327,30 @@ DrawTargetD2D::PrepareForDrawing(ID2D1RenderTarget *aRT)
|
||||
if (mPushedClips.size()) {
|
||||
// The transform of clips is relative to the world matrix, since we use the total
|
||||
// transform for the clips, make the world matrix identity.
|
||||
mRT->SetTransform(D2D1::IdentityMatrix());
|
||||
mTransformDirty = true;
|
||||
for (std::vector<PushedClip>::iterator iter = mPushedClips.begin();
|
||||
iter != mPushedClips.end(); iter++) {
|
||||
D2D1_LAYER_OPTIONS options = D2D1_LAYER_OPTIONS_NONE;
|
||||
|
||||
if (mFormat == FORMAT_B8G8R8X8) {
|
||||
options = D2D1_LAYER_OPTIONS_INITIALIZE_FOR_CLEARTYPE;
|
||||
}
|
||||
|
||||
aRT->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), iter->mPath->mGeometry,
|
||||
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
|
||||
iter->mTransform, 1.0f, NULL,
|
||||
options), iter->mLayer);
|
||||
}
|
||||
aRT->SetTransform(D2D1::IdentityMatrix());
|
||||
if (aRT == mRT) {
|
||||
mClipsArePushed = true;
|
||||
mTransformDirty = true;
|
||||
}
|
||||
for (std::vector<PushedClip>::iterator iter = mPushedClips.begin();
|
||||
iter != mPushedClips.end(); iter++) {
|
||||
D2D1_LAYER_OPTIONS options = D2D1_LAYER_OPTIONS_NONE;
|
||||
if (iter->mLayer) {
|
||||
D2D1_LAYER_OPTIONS options = D2D1_LAYER_OPTIONS_NONE;
|
||||
|
||||
if (mFormat == FORMAT_B8G8R8X8) {
|
||||
options = D2D1_LAYER_OPTIONS_INITIALIZE_FOR_CLEARTYPE;
|
||||
if (mFormat == FORMAT_B8G8R8X8) {
|
||||
options = D2D1_LAYER_OPTIONS_INITIALIZE_FOR_CLEARTYPE;
|
||||
}
|
||||
|
||||
aRT->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), iter->mPath->mGeometry,
|
||||
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
|
||||
iter->mTransform, 1.0f, NULL,
|
||||
options), iter->mLayer);
|
||||
} else {
|
||||
aRT->PushAxisAlignedClip(iter->mBounds, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1421,8 +1509,12 @@ DrawTargetD2D::FinalizeRTForOperation(CompositionOp aOperator, const Pattern &aP
|
||||
return;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < mPushedClips.size(); i++) {
|
||||
mTempRT->PopLayer();
|
||||
for (int i = mPushedClips.size() - 1; i >= 0; i--) {
|
||||
if (mPushedClips[i].mLayer) {
|
||||
mTempRT->PopLayer();
|
||||
} else {
|
||||
mTempRT->PopAxisAlignedClip();
|
||||
}
|
||||
}
|
||||
|
||||
mRT->Flush();
|
||||
@ -1535,7 +1627,7 @@ DrawTargetD2D::CreateRTForTexture(ID3D10Texture2D *aTexture)
|
||||
|
||||
D2D1_ALPHA_MODE alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
|
||||
|
||||
if (mFormat == FORMAT_B8G8R8X8) {
|
||||
if (mFormat == FORMAT_B8G8R8X8 && aTexture == mTexture) {
|
||||
alphaMode = D2D1_ALPHA_MODE_IGNORE;
|
||||
}
|
||||
|
||||
@ -1592,8 +1684,12 @@ void
|
||||
DrawTargetD2D::PopAllClips()
|
||||
{
|
||||
if (mClipsArePushed) {
|
||||
for (unsigned int i = 0; i < mPushedClips.size(); i++) {
|
||||
mRT->PopLayer();
|
||||
for (int i = mPushedClips.size() - 1; i >= 0; i--) {
|
||||
if (mPushedClips[i].mLayer) {
|
||||
mRT->PopLayer();
|
||||
} else {
|
||||
mRT->PopAxisAlignedClip();
|
||||
}
|
||||
}
|
||||
|
||||
mClipsArePushed = false;
|
||||
@ -1629,9 +1725,20 @@ DrawTargetD2D::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pat->mBegin == pat->mEnd) {
|
||||
RefPtr<ID2D1SolidColorBrush> colBrush;
|
||||
uint32_t stopCount = stops->mStopCollection->GetGradientStopCount();
|
||||
vector<D2D1_GRADIENT_STOP> d2dStops(stopCount);
|
||||
stops->mStopCollection->GetGradientStops(&d2dStops.front(), stopCount);
|
||||
mRT->CreateSolidColorBrush(d2dStops.back().color,
|
||||
D2D1::BrushProperties(aAlpha),
|
||||
byRef(colBrush));
|
||||
return colBrush;
|
||||
}
|
||||
|
||||
mRT->CreateLinearGradientBrush(D2D1::LinearGradientBrushProperties(D2DPoint(pat->mBegin),
|
||||
D2DPoint(pat->mEnd)),
|
||||
D2D1::BrushProperties(aAlpha),
|
||||
D2D1::BrushProperties(aAlpha, D2DMatrix(pat->mMatrix)),
|
||||
stops->mStopCollection,
|
||||
byRef(gradBrush));
|
||||
return gradBrush;
|
||||
@ -1652,7 +1759,7 @@ DrawTargetD2D::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
|
||||
D2D1::RadialGradientBrushProperties(D2DPoint(pat->mCenter1),
|
||||
D2D1::Point2F(),
|
||||
pat->mRadius2, pat->mRadius2),
|
||||
D2D1::BrushProperties(aAlpha),
|
||||
D2D1::BrushProperties(aAlpha, D2DMatrix(pat->mMatrix)),
|
||||
stops->mStopCollection,
|
||||
byRef(gradBrush));
|
||||
|
||||
@ -1668,6 +1775,8 @@ DrawTargetD2D::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
|
||||
}
|
||||
|
||||
RefPtr<ID2D1Bitmap> bitmap;
|
||||
|
||||
Matrix mat = pat->mMatrix;
|
||||
|
||||
switch (pat->mSurface->GetType()) {
|
||||
case SURFACE_D2D1_BITMAP:
|
||||
@ -1677,8 +1786,11 @@ DrawTargetD2D::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
|
||||
bitmap = surf->mBitmap;
|
||||
|
||||
if (!bitmap) {
|
||||
gfxDebug() << "Source surface used for pattern too large!";
|
||||
return NULL;
|
||||
bitmap = CreatePartialBitmapForSurface(surf, mat);
|
||||
|
||||
if (!bitmap) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1691,22 +1803,12 @@ DrawTargetD2D::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
D2D1_EXTEND_MODE extend = D2D1_EXTEND_MODE_CLAMP;
|
||||
switch (pat->mExtendMode) {
|
||||
case EXTEND_WRAP:
|
||||
extend = D2D1_EXTEND_MODE_WRAP;
|
||||
break;
|
||||
case EXTEND_MIRROR:
|
||||
extend = D2D1_EXTEND_MODE_MIRROR;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
mRT->CreateBitmapBrush(bitmap,
|
||||
D2D1::BitmapBrushProperties(extend,
|
||||
extend,
|
||||
D2D1::BitmapBrushProperties(D2DExtend(pat->mExtendMode),
|
||||
D2DExtend(pat->mExtendMode),
|
||||
D2DFilter(pat->mFilter)),
|
||||
D2D1::BrushProperties(aAlpha),
|
||||
D2D1::BrushProperties(aAlpha, D2DMatrix(mat)),
|
||||
byRef(bmBrush));
|
||||
|
||||
return bmBrush;
|
||||
@ -1855,6 +1957,59 @@ DrawTargetD2D::CreateGradientTexture(const GradientStopsD2D *aStops)
|
||||
return tex;
|
||||
}
|
||||
|
||||
TemporaryRef<ID2D1Bitmap>
|
||||
DrawTargetD2D::CreatePartialBitmapForSurface(SourceSurfaceD2D *aSurface, Matrix &aMatrix)
|
||||
{
|
||||
RefPtr<ID2D1Bitmap> bitmap;
|
||||
|
||||
// This is where things get complicated. The source surface was
|
||||
// created for a surface that was too large to fit in a texture.
|
||||
// We'll need to figure out if we can work with a partial upload
|
||||
// or downsample in software.
|
||||
|
||||
Matrix transform = mTransform;
|
||||
transform = aMatrix * transform;
|
||||
if (!transform.Invert()) {
|
||||
// Singular transform, nothing to be drawn.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Rect rect(0, 0, mSize.width, mSize.height);
|
||||
|
||||
// Calculate the rectangle of the source mapped to our surface.
|
||||
rect = transform.TransformBounds(rect);
|
||||
rect.RoundOut();
|
||||
|
||||
Rect uploadRect(0, 0, aSurface->mSize.width, aSurface->mSize.height);
|
||||
|
||||
// Calculate the rectangle on the source bitmap that touches our
|
||||
// surface.
|
||||
uploadRect = uploadRect.Intersect(rect);
|
||||
|
||||
if (uploadRect.width <= mRT->GetMaximumBitmapSize() &&
|
||||
uploadRect.height <= mRT->GetMaximumBitmapSize()) {
|
||||
|
||||
int Bpp = BytesPerPixel(aSurface->mFormat);
|
||||
int stride = Bpp * aSurface->mSize.width;
|
||||
|
||||
// A partial upload will suffice.
|
||||
mRT->CreateBitmap(D2D1::SizeU(uint32_t(uploadRect.width), uint32_t(uploadRect.height)),
|
||||
&aSurface->mRawData.front() + int(uploadRect.x) + int(uploadRect.y) * stride,
|
||||
stride,
|
||||
D2D1::BitmapProperties(D2DPixelFormat(aSurface->mFormat)),
|
||||
byRef(bitmap));
|
||||
|
||||
aMatrix.Translate(-uploadRect.x, -uploadRect.y);
|
||||
|
||||
return bitmap;
|
||||
} else {
|
||||
// XXX - FIX ME!!
|
||||
MOZ_ASSERT(false);
|
||||
gfxDebug() << "Source surface used for pattern too large!";
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetD2D::SetupEffectForRadialGradient(const RadialGradientPattern *aPattern)
|
||||
{
|
||||
@ -1907,13 +2062,26 @@ DrawTargetD2D::SetupEffectForRadialGradient(const RadialGradientPattern *aPatter
|
||||
AsMatrix()->SetMatrix(matrix);
|
||||
|
||||
float A = dc.x * dc.x + dc.y * dc.y - dr * dr;
|
||||
|
||||
uint32_t offset = 0;
|
||||
switch (stops->mStopCollection->GetExtendMode()) {
|
||||
case D2D1_EXTEND_MODE_WRAP:
|
||||
offset = 1;
|
||||
break;
|
||||
case D2D1_EXTEND_MODE_MIRROR:
|
||||
offset = 2;
|
||||
break;
|
||||
default:
|
||||
gfxWarning() << "This shouldn't happen! Invalid extend mode for gradient stops.";
|
||||
}
|
||||
|
||||
if (A == 0) {
|
||||
mPrivateData->mEffect->GetTechniqueByName("SampleRadialGradient")->
|
||||
GetPassByIndex(1)->Apply(0);
|
||||
GetPassByIndex(offset * 2 + 1)->Apply(0);
|
||||
} else {
|
||||
mPrivateData->mEffect->GetVariableByName("A")->AsScalar()->SetFloat(A);
|
||||
mPrivateData->mEffect->GetTechniqueByName("SampleRadialGradient")->
|
||||
GetPassByIndex(0)->Apply(0);
|
||||
GetPassByIndex(offset * 2)->Apply(0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1936,7 +2104,7 @@ DrawTargetD2D::factory()
|
||||
|
||||
D2D1_FACTORY_OPTIONS options;
|
||||
#ifdef _DEBUG
|
||||
options.debugLevel = D2D1_DEBUG_LEVEL_NONE;
|
||||
options.debugLevel = D2D1_DEBUG_LEVEL_WARNING;
|
||||
#else
|
||||
options.debugLevel = D2D1_DEBUG_LEVEL_NONE;
|
||||
#endif
|
||||
|
@ -56,6 +56,7 @@ namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
class SourceSurfaceD2DTarget;
|
||||
class SourceSurfaceD2D;
|
||||
class GradientStopsD2D;
|
||||
|
||||
struct PrivateD3D10DataD2D
|
||||
@ -117,7 +118,11 @@ public:
|
||||
const GlyphBuffer &aBuffer,
|
||||
const Pattern &aPattern,
|
||||
const DrawOptions &aOptions = DrawOptions());
|
||||
virtual void Mask(const Pattern &aSource,
|
||||
const Pattern &aMask,
|
||||
const DrawOptions &aOptions = DrawOptions());
|
||||
virtual void PushClip(const Path *aPath);
|
||||
virtual void PushClipRect(const Rect &aRect);
|
||||
virtual void PopClip();
|
||||
|
||||
virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
|
||||
@ -134,7 +139,10 @@ public:
|
||||
|
||||
virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FILL_WINDING) const;
|
||||
|
||||
virtual TemporaryRef<GradientStops> CreateGradientStops(GradientStop *aStops, uint32_t aNumStops) const;
|
||||
virtual TemporaryRef<GradientStops>
|
||||
CreateGradientStops(GradientStop *aStops,
|
||||
uint32_t aNumStops,
|
||||
ExtendMode aExtendMode = EXTEND_CLAMP) const;
|
||||
|
||||
virtual void *GetNativeSurface(NativeSurfaceType aType);
|
||||
|
||||
@ -186,6 +194,11 @@ private:
|
||||
|
||||
TemporaryRef<ID3D10Texture1D> CreateGradientTexture(const GradientStopsD2D *aStops);
|
||||
|
||||
// This creates a partially uploaded bitmap for a SourceSurfaceD2D that is
|
||||
// too big to fit in a bitmap. It adjusts the passed Matrix to accomodate the
|
||||
// partial upload.
|
||||
TemporaryRef<ID2D1Bitmap> CreatePartialBitmapForSurface(SourceSurfaceD2D *aSurface, Matrix &aMatrix);
|
||||
|
||||
void SetupEffectForRadialGradient(const RadialGradientPattern *aPattern);
|
||||
|
||||
static const uint32_t test = 4;
|
||||
|
@ -199,9 +199,9 @@ ExtendModeToTileMode(ExtendMode aMode)
|
||||
{
|
||||
case EXTEND_CLAMP:
|
||||
return SkShader::kClamp_TileMode;
|
||||
case EXTEND_WRAP:
|
||||
case EXTEND_REPEAT:
|
||||
return SkShader::kRepeat_TileMode;
|
||||
case EXTEND_MIRROR:
|
||||
case EXTEND_REFLECT:
|
||||
return SkShader::kMirror_TileMode;
|
||||
}
|
||||
return SkShader::kClamp_TileMode;
|
||||
@ -671,7 +671,7 @@ DrawTargetSkia::PopClip()
|
||||
}
|
||||
|
||||
TemporaryRef<GradientStops>
|
||||
DrawTargetSkia::CreateGradientStops(GradientStop *aStops, uint32_t aNumStops) const
|
||||
DrawTargetSkia::CreateGradientStops(GradientStop *aStops, uint32_t aNumStops, ExtendMode aExtendMode) const
|
||||
{
|
||||
std::vector<GradientStop> stops;
|
||||
stops.resize(aNumStops);
|
||||
|
@ -99,7 +99,12 @@ public:
|
||||
const GlyphBuffer &aBuffer,
|
||||
const Pattern &aPattern,
|
||||
const DrawOptions &aOptions = DrawOptions());
|
||||
virtual void Mask(const Pattern &aSource,
|
||||
const Pattern &aMask,
|
||||
const DrawOptions &aOptions = DrawOptions())
|
||||
{ return; }
|
||||
virtual void PushClip(const Path *aPath);
|
||||
virtual void PushClipRect(const Rect &aRect) { }
|
||||
virtual void PopClip();
|
||||
virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
|
||||
const IntSize &aSize,
|
||||
@ -111,7 +116,7 @@ public:
|
||||
virtual TemporaryRef<DrawTarget>
|
||||
CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const;
|
||||
virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FILL_WINDING) const;
|
||||
virtual TemporaryRef<GradientStops> CreateGradientStops(GradientStop *aStops, uint32_t aNumStops) const;
|
||||
virtual TemporaryRef<GradientStops> CreateGradientStops(GradientStop *aStops, uint32_t aNumStops, ExtendMode aExtendMode = EXTEND_CLAMP) const;
|
||||
virtual void SetTransform(const Matrix &aTransform);
|
||||
|
||||
bool Init(const IntSize &aSize, SurfaceFormat aFormat);
|
||||
|
@ -59,6 +59,21 @@ static inline D2D1_RECT_F D2DRect(const Rect &aRect)
|
||||
return D2D1::RectF(aRect.x, aRect.y, aRect.XMost(), aRect.YMost());
|
||||
}
|
||||
|
||||
static inline D2D1_EXTEND_MODE D2DExtend(ExtendMode aExtendMode)
|
||||
{
|
||||
D2D1_EXTEND_MODE extend = D2D1_EXTEND_MODE_CLAMP;
|
||||
switch (aExtendMode) {
|
||||
case EXTEND_REPEAT:
|
||||
extend = D2D1_EXTEND_MODE_WRAP;
|
||||
break;
|
||||
case EXTEND_REFLECT:
|
||||
extend = D2D1_EXTEND_MODE_MIRROR;
|
||||
break;
|
||||
}
|
||||
|
||||
return extend;
|
||||
}
|
||||
|
||||
static inline D2D1_BITMAP_INTERPOLATION_MODE D2DFilter(const Filter &aFilter)
|
||||
{
|
||||
switch (aFilter) {
|
||||
@ -69,11 +84,11 @@ static inline D2D1_BITMAP_INTERPOLATION_MODE D2DFilter(const Filter &aFilter)
|
||||
return D2D1_BITMAP_INTERPOLATION_MODE_LINEAR;
|
||||
}
|
||||
|
||||
static inline D2D1_ANTIALIAS_MODE D2DAAMode(const AntialiasMode &aMode)
|
||||
static inline D2D1_ANTIALIAS_MODE D2DAAMode(AntialiasMode aMode)
|
||||
{
|
||||
switch (aMode) {
|
||||
case AA_NONE:
|
||||
D2D1_ANTIALIAS_MODE_ALIASED;
|
||||
return D2D1_ANTIALIAS_MODE_ALIASED;
|
||||
}
|
||||
|
||||
return D2D1_ANTIALIAS_MODE_PER_PRIMITIVE;
|
||||
@ -141,6 +156,11 @@ static inline D2D1_ALPHA_MODE AlphaMode(SurfaceFormat aFormat)
|
||||
return D2D1_ALPHA_MODE_PREMULTIPLIED;
|
||||
}
|
||||
|
||||
static inline D2D1_PIXEL_FORMAT D2DPixelFormat(SurfaceFormat aFormat)
|
||||
{
|
||||
return D2D1::PixelFormat(DXGIFormat(aFormat), AlphaMode(aFormat));
|
||||
}
|
||||
|
||||
static inline int BytesPerPixel(SurfaceFormat aFormat)
|
||||
{
|
||||
switch (aFormat) {
|
||||
|
@ -143,6 +143,24 @@ public:
|
||||
|
||||
return resultMatrix;
|
||||
}
|
||||
|
||||
/* Returns true if the matrix is a rectilinear transformation (i.e.
|
||||
* grid-aligned rectangles are transformed to grid-aligned rectangles)
|
||||
*/
|
||||
bool IsRectilinear() {
|
||||
if (FuzzyEqual(_12, 0) && FuzzyEqual(_21, 0)) {
|
||||
return true;
|
||||
} else if (FuzzyEqual(_22, 0) && FuzzyEqual(_11, 0)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
private:
|
||||
static bool FuzzyEqual(Float aV1, Float aV2) {
|
||||
// XXX - Check if fabs does the smart thing and just negates the sign bit.
|
||||
return fabs(aV2 - aV1) < 1e-6;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -60,6 +60,20 @@ sampler sSampler = sampler_state {
|
||||
AddressV = Clamp;
|
||||
};
|
||||
|
||||
sampler sWrapSampler = sampler_state {
|
||||
Filter = MIN_MAG_MIP_LINEAR;
|
||||
Texture = tex;
|
||||
AddressU = Wrap;
|
||||
AddressV = Wrap;
|
||||
};
|
||||
|
||||
sampler sMirrorSampler = sampler_state {
|
||||
Filter = MIN_MAG_MIP_LINEAR;
|
||||
Texture = tex;
|
||||
AddressU = Mirror;
|
||||
AddressV = Mirror;
|
||||
};
|
||||
|
||||
sampler sMaskSampler = sampler_state {
|
||||
Filter = MIN_MAG_MIP_LINEAR;
|
||||
Texture = mask;
|
||||
@ -142,7 +156,7 @@ float4 SampleMaskTexturePS( VS_OUTPUT In) : SV_Target
|
||||
return tex.Sample(sSampler, In.TexCoord) * mask.Sample(sMaskSampler, In.MaskTexCoord).a;
|
||||
};
|
||||
|
||||
float4 SampleRadialGradientPS( VS_RADIAL_OUTPUT In) : SV_Target
|
||||
float4 SampleRadialGradientPS(VS_RADIAL_OUTPUT In, uniform sampler aSampler) : SV_Target
|
||||
{
|
||||
// Radial gradient painting is defined as the set of circles whose centers
|
||||
// are described by C(t) = (C2 - C1) * t + C1; with radii
|
||||
@ -178,7 +192,7 @@ float4 SampleRadialGradientPS( VS_RADIAL_OUTPUT In) : SV_Target
|
||||
|
||||
float upper_t = lerp(t.y, t.x, isValid.x);
|
||||
|
||||
float4 output = tex.Sample(sSampler, float2(upper_t, 0.5));
|
||||
float4 output = tex.Sample(aSampler, float2(upper_t, 0.5));
|
||||
// Premultiply
|
||||
output.rgb *= output.a;
|
||||
// Multiply the output color by the input mask for the operation.
|
||||
@ -186,7 +200,7 @@ float4 SampleRadialGradientPS( VS_RADIAL_OUTPUT In) : SV_Target
|
||||
return output;
|
||||
};
|
||||
|
||||
float4 SampleRadialGradientA0PS( VS_RADIAL_OUTPUT In) : SV_Target
|
||||
float4 SampleRadialGradientA0PS( VS_RADIAL_OUTPUT In, uniform sampler aSampler ) : SV_Target
|
||||
{
|
||||
// This simpler shader is used for the degenerate case where A is 0,
|
||||
// i.e. we're actually solving a linear equation.
|
||||
@ -205,7 +219,7 @@ float4 SampleRadialGradientA0PS( VS_RADIAL_OUTPUT In) : SV_Target
|
||||
return float4(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
float4 output = tex.Sample(sSampler, float2(t, 0.5));
|
||||
float4 output = tex.Sample(aSampler, float2(t, 0.5));
|
||||
// Premultiply
|
||||
output.rgb *= output.a;
|
||||
// Multiply the output color by the input mask for the operation.
|
||||
@ -277,19 +291,47 @@ technique10 SampleTexture
|
||||
|
||||
technique10 SampleRadialGradient
|
||||
{
|
||||
pass P0
|
||||
pass APos
|
||||
{
|
||||
SetRasterizerState(TextureRast);
|
||||
SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleRadialVS()));
|
||||
SetGeometryShader(NULL);
|
||||
SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientPS()));
|
||||
SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientPS( sSampler )));
|
||||
}
|
||||
pass P1
|
||||
pass A0
|
||||
{
|
||||
SetRasterizerState(TextureRast);
|
||||
SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleRadialVS()));
|
||||
SetGeometryShader(NULL);
|
||||
SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientA0PS()));
|
||||
SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientA0PS( sSampler )));
|
||||
}
|
||||
pass APosWrap
|
||||
{
|
||||
SetRasterizerState(TextureRast);
|
||||
SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleRadialVS()));
|
||||
SetGeometryShader(NULL);
|
||||
SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientPS( sWrapSampler )));
|
||||
}
|
||||
pass A0Wrap
|
||||
{
|
||||
SetRasterizerState(TextureRast);
|
||||
SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleRadialVS()));
|
||||
SetGeometryShader(NULL);
|
||||
SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientA0PS( sWrapSampler )));
|
||||
}
|
||||
pass APosMirror
|
||||
{
|
||||
SetRasterizerState(TextureRast);
|
||||
SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleRadialVS()));
|
||||
SetGeometryShader(NULL);
|
||||
SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientPS( sMirrorSampler )));
|
||||
}
|
||||
pass A0Mirror
|
||||
{
|
||||
SetRasterizerState(TextureRast);
|
||||
SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleRadialVS()));
|
||||
SetGeometryShader(NULL);
|
||||
SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientA0PS( sMirrorSampler )));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,6 +160,16 @@ SourceSurfaceD2DTarget::GetBitmap(ID2D1RenderTarget *aRT)
|
||||
hr = aRT->CreateSharedBitmap(IID_IDXGISurface, surf, &props, byRef(mBitmap));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
// This seems to happen for FORMAT_A8 sometimes...
|
||||
aRT->CreateBitmap(D2D1::SizeU(desc.Width, desc.Height),
|
||||
D2D1::BitmapProperties(D2D1::PixelFormat(DXGIFormat(mFormat),
|
||||
AlphaMode(mFormat))),
|
||||
byRef(mBitmap));
|
||||
|
||||
if (mDrawTarget) {
|
||||
mBitmap->CopyFromRenderTarget(NULL, mDrawTarget->mRT, NULL);
|
||||
return mBitmap;
|
||||
}
|
||||
gfxWarning() << "Failed to create shared bitmap for DrawTarget snapshot. Code: " << hr;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ enum SurfaceType
|
||||
SURFACE_D2D1_BITMAP, /* Surface wrapping a ID2D1Bitmap */
|
||||
SURFACE_D2D1_DRAWTARGET, /* Surface made from a D2D draw target */
|
||||
SURFACE_CAIRO, /* Surface wrapping a cairo surface */
|
||||
SURFACE_CAIRO_IMAGE, /* Data surface wrapping a cairo image surface */
|
||||
SURFACE_COREGRAPHICS_IMAGE, /* Surface wrapping a CoreGraphics Image */
|
||||
SURFACE_SKIA /* Surface wrapping a Skia bitmap */
|
||||
};
|
||||
@ -95,7 +96,7 @@ enum NativeFontType
|
||||
};
|
||||
|
||||
enum CompositionOp { OP_OVER, OP_ADD, OP_ATOP, OP_OUT, OP_IN, OP_SOURCE, OP_DEST_IN, OP_DEST_OUT, OP_DEST_OVER, OP_DEST_ATOP, OP_XOR, OP_COUNT };
|
||||
enum ExtendMode { EXTEND_CLAMP, EXTEND_WRAP, EXTEND_MIRROR };
|
||||
enum ExtendMode { EXTEND_CLAMP, EXTEND_REPEAT, EXTEND_REFLECT };
|
||||
enum FillRule { FILL_WINDING, FILL_EVEN_ODD };
|
||||
enum AntialiasMode { AA_NONE, AA_GRAY, AA_SUBPIXEL };
|
||||
enum Snapping { SNAP_NONE, SNAP_ALIGNED };
|
||||
@ -103,6 +104,7 @@ enum Filter { FILTER_LINEAR, FILTER_POINT };
|
||||
enum PatternType { PATTERN_COLOR, PATTERN_SURFACE, PATTERN_LINEAR_GRADIENT, PATTERN_RADIAL_GRADIENT };
|
||||
enum JoinStyle { JOIN_BEVEL, JOIN_ROUND, JOIN_MITER, JOIN_MITER_OR_BEVEL };
|
||||
enum CapStyle { CAP_BUTT, CAP_ROUND, CAP_SQUARE };
|
||||
enum SamplingBounds { SAMPLING_UNBOUNDED, SAMPLING_BOUNDED };
|
||||
|
||||
/* Color is stored in non-premultiplied form */
|
||||
struct Color
|
||||
|
Loading…
Reference in New Issue
Block a user