This is an automated email from the git hooks/post-receive script.
pierov pushed a commit to branch geckoview-99.0.1-11.0-1 in repository tor-browser.
commit 61e6e8dd248efacb607f7875c3fba5728090249b Author: Lee Salzman lsalzman@mozilla.com AuthorDate: Fri Mar 11 10:02:07 2022 +0000
Bug 1758968 - Clip drawing in DrawTargetD2D1::DrawSurfaceWithShadow. r=gfx-reviewers,nical, a=dmeehan
DrawSurfaceWithShadow is supposed to ignore transforms but still support clipping. It appears that DrawTargetD2D1 for some reason never actually implemented clipping.
The DrawImage calls on the DC just need to happen within the bounds of PrepareForDrawing and FinalizeDrawing. Since PrepareForDrawing handles the overriding of the blend mode via SetPrimitiveBlend, we need to use DrawImage with D2D1_COMPOSITE_MODE_SOURCE_OVER so that it will blend appropriately.
Differential Revision: https://phabricator.services.mozilla.com/D140798 --- dom/canvas/test/reftest/1758968-1-ref.html | 13 +++++++++ dom/canvas/test/reftest/1758968-1.html | 16 ++++++++++ dom/canvas/test/reftest/reftest.list | 2 ++ gfx/2d/DrawTargetD2D1.cpp | 47 +++++++++++++++++------------- 4 files changed, 58 insertions(+), 20 deletions(-)
diff --git a/dom/canvas/test/reftest/1758968-1-ref.html b/dom/canvas/test/reftest/1758968-1-ref.html new file mode 100644 index 0000000000000..a97e27d5fef7e --- /dev/null +++ b/dom/canvas/test/reftest/1758968-1-ref.html @@ -0,0 +1,13 @@ +<div style="width: 100px; height: 100px;"><canvas id="canvas" width="100" height="50"></canvas></div> +<script> + var can = document.getElementById('canvas'); + var ctx = can.getContext('2d'); + + ctx.shadowOffsetX = 24; + ctx.shadowOffsetY = 24; + ctx.shadowColor = 'blue'; + ctx.shadowBlur = 20; + + ctx.fillStyle = 'black'; + ctx.fillRect(0,0,40,40); +</script> diff --git a/dom/canvas/test/reftest/1758968-1.html b/dom/canvas/test/reftest/1758968-1.html new file mode 100644 index 0000000000000..0a786865946d6 --- /dev/null +++ b/dom/canvas/test/reftest/1758968-1.html @@ -0,0 +1,16 @@ +<canvas id="canvas" width="100" height="100"></canvas> +<script> + var can = document.getElementById('canvas'); + var ctx = can.getContext('2d'); + + ctx.shadowOffsetX = 24; + ctx.shadowOffsetY = 24; + ctx.shadowColor = 'blue'; + ctx.shadowBlur = 20; + + ctx.rect(0,0,100,50); + ctx.clip(); + + ctx.fillStyle = 'black'; + ctx.fillRect(0,0,40,40); +</script> diff --git a/dom/canvas/test/reftest/reftest.list b/dom/canvas/test/reftest/reftest.list index 28d507058ce4b..492030fb27b6e 100644 --- a/dom/canvas/test/reftest/reftest.list +++ b/dom/canvas/test/reftest/reftest.list @@ -250,3 +250,5 @@ skip-if(Android) == visible-occluded.html visible-occluded-ref.html == 1719886-1.html 1719886-1-ref.html
skip-if(isDebugBuild) == draw-large-image.html draw-large-image-ref.html + +== 1758968-1.html 1758968-1-ref.html diff --git a/gfx/2d/DrawTargetD2D1.cpp b/gfx/2d/DrawTargetD2D1.cpp index 5c00c7bad7f03..7f53fe93b0986 100644 --- a/gfx/2d/DrawTargetD2D1.cpp +++ b/gfx/2d/DrawTargetD2D1.cpp @@ -312,8 +312,6 @@ void DrawTargetD2D1::DrawSurfaceWithShadow(SourceSurface* aSurface, return; } MarkChanged(); - mDC->SetTransform(D2D1::IdentityMatrix()); - mTransformDirty = true;
Matrix mat; RefPtr<ID2D1Image> image = @@ -331,35 +329,44 @@ void DrawTargetD2D1::DrawSurfaceWithShadow(SourceSurface* aSurface, return; }
- // Step 1, create the shadow effect. + if (!PrepareForDrawing(aOperator, ColorPattern(aColor))) { + return; + } + + mDC->SetTransform(D2D1::IdentityMatrix()); + mTransformDirty = true; + RefPtr<ID2D1Effect> shadowEffect; HRESULT hr = mDC->CreateEffect( mFormat == SurfaceFormat::A8 ? CLSID_D2D1GaussianBlur : CLSID_D2D1Shadow, getter_AddRefs(shadowEffect)); - if (FAILED(hr) || !shadowEffect) { - gfxWarning() << "Failed to create shadow effect. Code: " << hexa(hr); - return; - } - shadowEffect->SetInput(0, image); - if (mFormat == SurfaceFormat::A8) { - shadowEffect->SetValue(D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION, aSigma); - shadowEffect->SetValue(D2D1_GAUSSIANBLUR_PROP_BORDER_MODE, - D2D1_BORDER_MODE_HARD); + if (SUCCEEDED(hr) && shadowEffect) { + shadowEffect->SetInput(0, image); + if (mFormat == SurfaceFormat::A8) { + shadowEffect->SetValue(D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION, aSigma); + shadowEffect->SetValue(D2D1_GAUSSIANBLUR_PROP_BORDER_MODE, + D2D1_BORDER_MODE_HARD); + } else { + shadowEffect->SetValue(D2D1_SHADOW_PROP_BLUR_STANDARD_DEVIATION, aSigma); + D2D1_VECTOR_4F color = {aColor.r, aColor.g, aColor.b, aColor.a}; + shadowEffect->SetValue(D2D1_SHADOW_PROP_COLOR, color); + } + + D2D1_POINT_2F shadowPoint = D2DPoint(aDest + aOffset); + mDC->DrawImage(shadowEffect, &shadowPoint, nullptr, + D2D1_INTERPOLATION_MODE_LINEAR, + D2D1_COMPOSITE_MODE_SOURCE_OVER); } else { - shadowEffect->SetValue(D2D1_SHADOW_PROP_BLUR_STANDARD_DEVIATION, aSigma); - D2D1_VECTOR_4F color = {aColor.r, aColor.g, aColor.b, aColor.a}; - shadowEffect->SetValue(D2D1_SHADOW_PROP_COLOR, color); + gfxWarning() << "Failed to create shadow effect. Code: " << hexa(hr); }
- D2D1_POINT_2F shadowPoint = D2DPoint(aDest + aOffset); - mDC->DrawImage(shadowEffect, &shadowPoint, nullptr, - D2D1_INTERPOLATION_MODE_LINEAR, D2DCompositionMode(aOperator)); - if (aSurface->GetFormat() != SurfaceFormat::A8) { D2D1_POINT_2F imgPoint = D2DPoint(aDest); mDC->DrawImage(image, &imgPoint, nullptr, D2D1_INTERPOLATION_MODE_LINEAR, - D2DCompositionMode(aOperator)); + D2D1_COMPOSITE_MODE_SOURCE_OVER); } + + FinalizeDrawing(aOperator, ColorPattern(aColor)); }
void DrawTargetD2D1::ClearRect(const Rect& aRect) {