author | Bogdan Szekely <bszekely@mozilla.com> |
Fri, 01 Jul 2022 18:16:27 +0300 | |
changeset 622859 | 691d7c190c9f2d4f2f6f6d88824f697be7858e80 |
parent 622858 | 67a693c5a54337e856a7a1d4787aa276f61dc79d |
child 622860 | eed559991e00fe684db25261d51838cecb6ff57a |
child 622866 | 5140fba12e4a4c58953227b0ba20efbefbf8086b |
push id | 165601 |
push user | bszekely@mozilla.com |
push date | Fri, 01 Jul 2022 15:19:06 +0000 |
treeherder | autoland@691d7c190c9f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 1777209 |
milestone | 104.0a1 |
backs out | 566b061ee95dd7b50c015ecac604c731290e2a9e |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
gfx/2d/DrawTargetCairo.cpp | file | annotate | diff | comparison | revisions | |
layout/generic/nsHTMLCanvasFrame.cpp | file | annotate | diff | comparison | revisions |
--- a/gfx/2d/DrawTargetCairo.cpp +++ b/gfx/2d/DrawTargetCairo.cpp @@ -886,27 +886,17 @@ void DrawTargetCairo::DrawSurface(Source return; } cairo_pattern_t* pat = cairo_pattern_create_for_surface(surf); cairo_surface_destroy(surf); cairo_pattern_set_matrix(pat, &src_mat); cairo_pattern_set_filter( pat, GfxSamplingFilterToCairoFilter(aSurfOptions.mSamplingFilter)); - // For PDF output, we avoid using EXTEND_PAD here because floating-point - // error accumulation may lead cairo_pdf_surface to conclude that padding - // is needed due to an apparent one- or two-pixel mismatch between source - // pattern and destination rect sizes when we're rendering a pdf.js page, - // and this forces undesirable fallback to the rasterization codepath - // instead of simply replaying the recording. - // (See bug 1777209.) - cairo_pattern_set_extend( - pat, cairo_surface_get_type(mSurface) == CAIRO_SURFACE_TYPE_PDF - ? CAIRO_EXTEND_NONE - : CAIRO_EXTEND_PAD); + cairo_pattern_set_extend(pat, CAIRO_EXTEND_PAD); cairo_set_antialias(mContext, GfxAntialiasToCairoAntialias(aOptions.mAntialiasMode)); // If the destination rect covers the entire clipped area, then unbounded and // bounded operations are identical, and we don't need to push a group. bool needsGroup = !IsOperatorBoundByMask(aOptions.mCompositionOp) && !aDest.Contains(GetUserSpaceClip());
--- a/layout/generic/nsHTMLCanvasFrame.cpp +++ b/layout/generic/nsHTMLCanvasFrame.cpp @@ -295,28 +295,27 @@ class nsDisplayCanvas final : public nsP IntrinsicSize intrinsicSize = IntrinsicSizeFromCanvasSize(canvasSizeInPx); AspectRatio intrinsicRatio = IntrinsicRatioFromCanvasSize(canvasSizeInPx); nsRect dest = nsLayoutUtils::ComputeObjectDestRect( area, intrinsicSize, intrinsicRatio, f->StylePosition()); gfxRect destGFXRect = presContext->AppUnitsToGfxUnits(dest); + // Transform the canvas into the right place + gfxPoint p = destGFXRect.TopLeft(); + Matrix transform = Matrix::Translation(p.x, p.y); + transform.PreScale(destGFXRect.Width() / canvasSizeInPx.width, + destGFXRect.Height() / canvasSizeInPx.height); gfxContextMatrixAutoSaveRestore saveMatrix(aCtx); + aCtx->SetMatrix( + gfxUtils::SnapTransformTranslation(aCtx->CurrentMatrix(), nullptr)); + if (RefPtr<layers::Image> image = canvas->GetAsImage()) { - // Transform the canvas into the right place - gfxPoint p = destGFXRect.TopLeft(); - Matrix transform = Matrix::Translation(p.x, p.y); - transform.PreScale(destGFXRect.Width() / canvasSizeInPx.width, - destGFXRect.Height() / canvasSizeInPx.height); - - aCtx->SetMatrix( - gfxUtils::SnapTransformTranslation(aCtx->CurrentMatrix(), nullptr)); - RefPtr<gfx::SourceSurface> surface = image->GetAsSourceSurface(); if (!surface || !surface->IsValid()) { return; } gfx::IntSize size = surface->GetSize(); transform = gfxUtils::SnapTransform( transform, gfxRect(0, 0, size.width, size.height), nullptr); @@ -334,37 +333,33 @@ class nsDisplayCanvas final : public nsP } RefPtr<CanvasRenderer> renderer = new CanvasRenderer(); if (!canvas->InitializeCanvasRenderer(aBuilder, renderer)) { return; } renderer->FirePreTransactionCallback(); const auto snapshot = renderer->BorrowSnapshot(); - if (!snapshot) { - return; - } + if (!snapshot) return; const auto& surface = snapshot->mSurf; + transform = gfxUtils::SnapTransform( + transform, gfxRect(0, 0, canvasSizeInPx.width, canvasSizeInPx.height), + nullptr); + if (!renderer->YIsDown()) { - // Calculate y-coord that is as far below the bottom of destGFXRect as - // the origin was above the top, then reflect about that. - float y = destGFXRect.Y() + destGFXRect.YMost(); - Matrix transform = Matrix::Translation(0.0f, y).PreScale(1.0f, -1.0f); - aCtx->Multiply(transform); + // y-flip + transform.PreTranslate(0.0f, canvasSizeInPx.height).PreScale(1.0f, -1.0f); } + aCtx->Multiply(transform); - const auto& rect = surface->GetRect(); - aCtx->GetDrawTarget()->DrawSurface( - surface, - Rect(float(destGFXRect.X()), float(destGFXRect.Y()), - float(destGFXRect.Width()), float(destGFXRect.Height())), - Rect(float(rect.X()), float(rect.Y()), float(rect.Width()), - float(rect.Height())), - DrawSurfaceOptions(nsLayoutUtils::GetSamplingFilterForFrame(f))); + aCtx->GetDrawTarget()->FillRect( + Rect(0, 0, canvasSizeInPx.width, canvasSizeInPx.height), + SurfacePattern(surface, ExtendMode::CLAMP, Matrix(), + nsLayoutUtils::GetSamplingFilterForFrame(f))); renderer->FireDidTransactionCallback(); renderer->ResetDirty(); } }; nsIFrame* NS_NewHTMLCanvasFrame(PresShell* aPresShell, ComputedStyle* aStyle) { return new (aPresShell)