mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 668801 - Part 3: Adjust dealing with clipped shadows to be accurate. r=jrmuizel
This commit is contained in:
parent
1234946c68
commit
951afc154e
@ -122,29 +122,7 @@ public:
|
||||
gfxWarning() << "Failed to create shared bitmap for old surface.";
|
||||
}
|
||||
|
||||
factory()->CreatePathGeometry(byRef(mClippedArea));
|
||||
RefPtr<ID2D1GeometrySink> currentSink;
|
||||
mClippedArea->Open(byRef(currentSink));
|
||||
|
||||
std::vector<DrawTargetD2D::PushedClip>::iterator iter = mDT->mPushedClips.begin();
|
||||
iter->mPath->GetGeometry()->Simplify(D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
|
||||
iter->mTransform, currentSink);
|
||||
|
||||
currentSink->Close();
|
||||
|
||||
iter++;
|
||||
for (;iter != mDT->mPushedClips.end(); iter++) {
|
||||
RefPtr<ID2D1PathGeometry> newGeom;
|
||||
factory()->CreatePathGeometry(byRef(newGeom));
|
||||
|
||||
newGeom->Open(byRef(currentSink));
|
||||
mClippedArea->CombineWithGeometry(iter->mPath->GetGeometry(), D2D1_COMBINE_MODE_INTERSECT,
|
||||
iter->mTransform, currentSink);
|
||||
|
||||
currentSink->Close();
|
||||
|
||||
mClippedArea = newGeom;
|
||||
}
|
||||
mClippedArea = mDT->GetClippedGeometry();
|
||||
}
|
||||
|
||||
ID2D1Factory *factory() { return mDT->factory(); }
|
||||
@ -163,7 +141,9 @@ public:
|
||||
mDT->mTransformDirty = true;
|
||||
|
||||
RefPtr<ID2D1RectangleGeometry> rectGeom;
|
||||
factory()->CreateRectangleGeometry(D2D1::InfiniteRect(), byRef(rectGeom));
|
||||
factory()->CreateRectangleGeometry(
|
||||
D2D1::RectF(0, 0, float(mDT->mSize.width), float(mDT->mSize.height)),
|
||||
byRef(rectGeom));
|
||||
|
||||
RefPtr<ID2D1PathGeometry> invClippedArea;
|
||||
factory()->CreatePathGeometry(byRef(invClippedArea));
|
||||
@ -188,7 +168,7 @@ private:
|
||||
// with the old dest surface data.
|
||||
RefPtr<ID2D1Bitmap> mOldSurfBitmap;
|
||||
// This contains the area drawing is clipped to.
|
||||
RefPtr<ID2D1PathGeometry> mClippedArea;
|
||||
RefPtr<ID2D1Geometry> mClippedArea;
|
||||
};
|
||||
|
||||
DrawTargetD2D::DrawTargetD2D()
|
||||
@ -317,6 +297,12 @@ DrawTargetD2D::DrawSurfaceWithShadow(SourceSurface *aSurface,
|
||||
|
||||
Flush();
|
||||
|
||||
AutoSaveRestoreClippedOut restoreClippedOut(this);
|
||||
|
||||
if (!IsOperatorBoundByMask(aOperator)) {
|
||||
restoreClippedOut.Save();
|
||||
}
|
||||
|
||||
srView = static_cast<SourceSurfaceD2DTarget*>(aSurface)->GetSRView();
|
||||
|
||||
EnsureViews();
|
||||
@ -331,35 +317,36 @@ DrawTargetD2D::DrawSurfaceWithShadow(SourceSurface *aSurface,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RefPtr<ID3D10RenderTargetView> destRTView = mRTView;
|
||||
RefPtr<ID3D10Texture2D> destTexture;
|
||||
HRESULT hr;
|
||||
|
||||
RefPtr<ID3D10Texture2D> maskTexture;
|
||||
RefPtr<ID3D10ShaderResourceView> maskSRView;
|
||||
if (mPushedClips.size()) {
|
||||
// We need to take clips into account, draw into a temporary surface, which
|
||||
// we then blend back with the proper clips set, using D2D.
|
||||
CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_A8_UNORM,
|
||||
mSize.width, mSize.height,
|
||||
1, 1);
|
||||
desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
|
||||
|
||||
hr = mDevice->CreateTexture2D(&desc, NULL, byRef(destTexture));
|
||||
if (FAILED(hr)) {
|
||||
gfxWarning() << "Failure to create temporary texture. Size: " << mSize << " Code: " << hr;
|
||||
return;
|
||||
}
|
||||
hr = mDevice->CreateTexture2D(&desc, NULL, byRef(maskTexture));
|
||||
|
||||
hr = mDevice->CreateRenderTargetView(destTexture, NULL, byRef(destRTView));
|
||||
if (FAILED(hr)) {
|
||||
gfxWarning() << "Failure to create RenderTargetView. Code: " << hr;
|
||||
return;
|
||||
}
|
||||
RefPtr<ID2D1RenderTarget> rt = CreateRTForTexture(maskTexture);
|
||||
|
||||
float color[4] = { 0, 0, 0, 0 };
|
||||
mDevice->ClearRenderTargetView(destRTView, color);
|
||||
RefPtr<ID2D1SolidColorBrush> brush;
|
||||
rt->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White), byRef(brush));
|
||||
|
||||
RefPtr<ID2D1Geometry> geometry = GetClippedGeometry();
|
||||
|
||||
rt->BeginDraw();
|
||||
rt->Clear(D2D1::ColorF(0, 0));
|
||||
rt->FillGeometry(geometry, brush);
|
||||
rt->EndDraw();
|
||||
|
||||
mDevice->CreateShaderResourceView(maskTexture, NULL, byRef(maskSRView));
|
||||
}
|
||||
|
||||
|
||||
IntSize srcSurfSize;
|
||||
ID3D10RenderTargetView *rtViews;
|
||||
D3D10_VIEWPORT viewport;
|
||||
@ -596,8 +583,18 @@ DrawTargetD2D::DrawSurfaceWithShadow(SourceSurface *aSurface,
|
||||
SetFloatVector(ShaderConstantRectD3D10(-correctedOffset.x / Float(tmpSurfSize.width), -correctedOffset.y / Float(tmpSurfSize.height),
|
||||
mSize.width / Float(tmpSurfSize.width) * dsFactorX,
|
||||
mSize.height / Float(tmpSurfSize.height) * dsFactorY));
|
||||
mPrivateData->mEffect->GetTechniqueByName("SampleTextureWithShadow")->
|
||||
GetPassByIndex(1)->Apply(0);
|
||||
|
||||
if (!mPushedClips.size()) {
|
||||
mPrivateData->mEffect->GetTechniqueByName("SampleTextureWithShadow")->
|
||||
GetPassByIndex(1)->Apply(0);
|
||||
} else {
|
||||
mPrivateData->mEffect->GetVariableByName("mask")->AsShaderResource()->SetResource(maskSRView);
|
||||
mPrivateData->mEffect->GetVariableByName("MaskTexCoords")->AsVector()->
|
||||
SetFloatVector(ShaderConstantRectD3D10(0, 0, 1.0f, 1.0f));
|
||||
mPrivateData->mEffect->GetTechniqueByName("SampleTextureWithShadow")->
|
||||
GetPassByIndex(2)->Apply(0);
|
||||
}
|
||||
|
||||
mDevice->OMSetBlendState(GetBlendStateForOperator(aOperator), NULL, 0xffffffff);
|
||||
|
||||
mDevice->Draw(4, 0);
|
||||
@ -607,39 +604,17 @@ DrawTargetD2D::DrawSurfaceWithShadow(SourceSurface *aSurface,
|
||||
SetFloatVector(ShaderConstantRectD3D10(-aDest.x / aSurface->GetSize().width, -aDest.y / aSurface->GetSize().height,
|
||||
Float(mSize.width) / aSurface->GetSize().width,
|
||||
Float(mSize.height) / aSurface->GetSize().height));
|
||||
mPrivateData->mEffect->GetTechniqueByName("SampleTexture")->
|
||||
GetPassByIndex(0)->Apply(0);
|
||||
if (!mPushedClips.size()) {
|
||||
mPrivateData->mEffect->GetTechniqueByName("SampleTexture")->
|
||||
GetPassByIndex(0)->Apply(0);
|
||||
} else {
|
||||
mPrivateData->mEffect->GetTechniqueByName("SampleMaskedTexture")->
|
||||
GetPassByIndex(0)->Apply(0);
|
||||
}
|
||||
|
||||
mDevice->OMSetBlendState(GetBlendStateForOperator(aOperator), NULL, 0xffffffff);
|
||||
|
||||
mDevice->Draw(4, 0);
|
||||
|
||||
if (mPushedClips.size()) {
|
||||
// Assert destTexture
|
||||
|
||||
// Blend back using the proper clips.
|
||||
PrepareForDrawing(mRT);
|
||||
|
||||
RefPtr<IDXGISurface> surf;
|
||||
hr = destTexture->QueryInterface((IDXGISurface**) byRef(surf));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
gfxWarning() << "Failure to QI texture to surface. Code: " << hr;
|
||||
return;
|
||||
}
|
||||
|
||||
D2D1_BITMAP_PROPERTIES props =
|
||||
D2D1::BitmapProperties(D2D1::PixelFormat(DXGIFormat(mFormat), AlphaMode(mFormat)));
|
||||
RefPtr<ID2D1Bitmap> bitmap;
|
||||
hr = mRT->CreateSharedBitmap(IID_IDXGISurface, surf,
|
||||
&props, byRef(bitmap));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
gfxWarning() << "Failure to create shared bitmap for surface. Code: " << hr;
|
||||
return;
|
||||
}
|
||||
|
||||
mRT->DrawBitmap(bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -1415,6 +1390,38 @@ DrawTargetD2D::FinalizeRTForOperator(CompositionOp aOperator, const Rect &aBound
|
||||
mDevice->Draw(4, 0);
|
||||
}
|
||||
|
||||
TemporaryRef<ID2D1Geometry>
|
||||
DrawTargetD2D::GetClippedGeometry()
|
||||
{
|
||||
RefPtr<ID2D1GeometrySink> currentSink;
|
||||
RefPtr<ID2D1PathGeometry> clippedGeometry;
|
||||
|
||||
factory()->CreatePathGeometry(byRef(clippedGeometry));
|
||||
clippedGeometry->Open(byRef(currentSink));
|
||||
|
||||
std::vector<DrawTargetD2D::PushedClip>::iterator iter = mPushedClips.begin();
|
||||
iter->mPath->GetGeometry()->Simplify(D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
|
||||
iter->mTransform, currentSink);
|
||||
|
||||
currentSink->Close();
|
||||
|
||||
iter++;
|
||||
for (;iter != mPushedClips.end(); iter++) {
|
||||
RefPtr<ID2D1PathGeometry> newGeom;
|
||||
factory()->CreatePathGeometry(byRef(newGeom));
|
||||
|
||||
newGeom->Open(byRef(currentSink));
|
||||
clippedGeometry->CombineWithGeometry(iter->mPath->GetGeometry(), D2D1_COMBINE_MODE_INTERSECT,
|
||||
iter->mTransform, currentSink);
|
||||
|
||||
currentSink->Close();
|
||||
|
||||
clippedGeometry = newGeom;
|
||||
}
|
||||
|
||||
return clippedGeometry;
|
||||
}
|
||||
|
||||
TemporaryRef<ID2D1RenderTarget>
|
||||
DrawTargetD2D::CreateRTForTexture(ID3D10Texture2D *aTexture)
|
||||
{
|
||||
|
@ -160,6 +160,7 @@ private:
|
||||
void PopAllClips();
|
||||
|
||||
TemporaryRef<ID2D1RenderTarget> CreateRTForTexture(ID3D10Texture2D *aTexture);
|
||||
TemporaryRef<ID2D1Geometry> GetClippedGeometry();
|
||||
|
||||
TemporaryRef<ID2D1Brush> CreateBrushForPattern(const Pattern &aPattern, Float aAlpha = 1.0f);
|
||||
TemporaryRef<ID2D1StrokeStyle> CreateStrokeStyleForOptions(const StrokeOptions &aStrokeOptions);
|
||||
|
@ -13,6 +13,7 @@ cbuffer cb0
|
||||
{
|
||||
float4 QuadDesc;
|
||||
float4 TexCoords;
|
||||
float4 MaskTexCoords;
|
||||
}
|
||||
|
||||
cbuffer cb1
|
||||
@ -27,9 +28,11 @@ struct VS_OUTPUT
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float2 TexCoord : TEXCOORD0;
|
||||
float2 MaskTexCoord : TEXCOORD1;
|
||||
};
|
||||
|
||||
Texture2D tex;
|
||||
Texture2D mask;
|
||||
|
||||
sampler sSampler = sampler_state {
|
||||
Filter = MIN_MAG_MIP_LINEAR;
|
||||
@ -38,6 +41,13 @@ sampler sSampler = sampler_state {
|
||||
AddressV = Clamp;
|
||||
};
|
||||
|
||||
sampler sMaskSampler = sampler_state {
|
||||
Filter = MIN_MAG_MIP_LINEAR;
|
||||
Texture = mask;
|
||||
AddressU = Clamp;
|
||||
AddressV = Clamp;
|
||||
};
|
||||
|
||||
sampler sShadowSampler = sampler_state {
|
||||
Filter = MIN_MAG_MIP_LINEAR;
|
||||
Texture = tex;
|
||||
@ -79,6 +89,8 @@ VS_OUTPUT SampleTextureVS(float3 pos : POSITION)
|
||||
Output.Position.z = 0;
|
||||
Output.TexCoord.x = pos.x * TexCoords.z + TexCoords.x;
|
||||
Output.TexCoord.y = pos.y * TexCoords.w + TexCoords.y;
|
||||
Output.MaskTexCoord.x = pos.x * MaskTexCoords.z + MaskTexCoords.x;
|
||||
Output.MaskTexCoord.y = pos.y * MaskTexCoords.w + MaskTexCoords.y;
|
||||
return Output;
|
||||
}
|
||||
|
||||
@ -87,6 +99,11 @@ float4 SampleTexturePS( VS_OUTPUT In) : SV_Target
|
||||
return tex.Sample(sSampler, In.TexCoord);
|
||||
};
|
||||
|
||||
float4 SampleMaskTexturePS( VS_OUTPUT In) : SV_Target
|
||||
{
|
||||
return tex.Sample(sSampler, In.TexCoord) * mask.Sample(sMaskSampler, In.MaskTexCoord).a;
|
||||
};
|
||||
|
||||
float4 SampleShadowHPS( VS_OUTPUT In) : SV_Target
|
||||
{
|
||||
float outputStrength = 0;
|
||||
@ -121,6 +138,23 @@ float4 SampleShadowVPS( VS_OUTPUT In) : SV_Target
|
||||
return outputColor;
|
||||
};
|
||||
|
||||
float4 SampleMaskShadowVPS( VS_OUTPUT In) : SV_Target
|
||||
{
|
||||
float4 outputColor = float4(0, 0, 0, 0);
|
||||
|
||||
outputColor += BlurWeights[0].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].x));
|
||||
outputColor += BlurWeights[0].y * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].y));
|
||||
outputColor += BlurWeights[0].z * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].z));
|
||||
outputColor += BlurWeights[0].w * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].w));
|
||||
outputColor += BlurWeights[1].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].x));
|
||||
outputColor += BlurWeights[1].y * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].y));
|
||||
outputColor += BlurWeights[1].z * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].z));
|
||||
outputColor += BlurWeights[1].w * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].w));
|
||||
outputColor += BlurWeights[2].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[2].x));
|
||||
|
||||
return outputColor * mask.Sample(sMaskSampler, In.MaskTexCoord).a;
|
||||
};
|
||||
|
||||
technique10 SampleTexture
|
||||
{
|
||||
pass P0
|
||||
@ -132,6 +166,16 @@ technique10 SampleTexture
|
||||
}
|
||||
}
|
||||
|
||||
technique10 SampleMaskedTexture
|
||||
{
|
||||
pass P0
|
||||
{
|
||||
SetRasterizerState(TextureRast);
|
||||
SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
|
||||
SetGeometryShader(NULL);
|
||||
SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleMaskTexturePS()));
|
||||
}
|
||||
}
|
||||
|
||||
technique10 SampleTextureWithShadow
|
||||
{
|
||||
@ -153,4 +197,13 @@ technique10 SampleTextureWithShadow
|
||||
SetGeometryShader(NULL);
|
||||
SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleShadowVPS()));
|
||||
}
|
||||
}
|
||||
// Vertical pass - used when using a mask
|
||||
pass P2
|
||||
{
|
||||
SetRasterizerState(TextureRast);
|
||||
SetBlendState(ShadowBlendV, float4(1.0f, 1.0f, 1.0f, 1.0f), 0xffffffff);
|
||||
SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
|
||||
SetGeometryShader(NULL);
|
||||
SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleMaskShadowVPS()));
|
||||
}
|
||||
}
|
||||
|
3691
gfx/2d/ShadersD2D.h
3691
gfx/2d/ShadersD2D.h
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user