Bug 1751961 - Account for cross-process paint scale in nsSubDocumentFrame::Paint. r=tnikkel

This is the real fix.

Depends on D142908

Differential Revision: https://phabricator.services.mozilla.com/D142909
This commit is contained in:
Emilio Cobos Álvarez 2022-04-13 11:32:55 +00:00
parent 8d52156e82
commit 21c7930924
6 changed files with 65 additions and 9 deletions

View File

@ -142,6 +142,7 @@ PaintFragment PaintFragment::Record(dom::BrowsingContext* aBc,
RefPtr<gfxContext> thebes = gfxContext::CreateOrNull(dt);
thebes->SetMatrix(Matrix::Scaling(aScale, aScale));
thebes->SetCrossProcessPaintScale(aScale);
RefPtr<PresShell> presShell = presContext->PresShell();
Unused << presShell->RenderDocument(r, renderDocFlags, aBackgroundColor,
thebes);

View File

@ -150,6 +150,14 @@ class gfxContext final {
void SetMatrix(const mozilla::gfx::Matrix& matrix);
void SetMatrixDouble(const gfxMatrix& matrix);
void SetCrossProcessPaintScale(float aScale) {
MOZ_ASSERT(mCrossProcessPaintScale == 1.0f,
"Should only be initialized once");
mCrossProcessPaintScale = aScale;
}
float GetCrossProcessPaintScale() const { return mCrossProcessPaintScale; }
/**
* Returns the current transformation matrix.
*/
@ -512,6 +520,7 @@ class gfxContext final {
}
RefPtr<DrawTarget> mDT;
float mCrossProcessPaintScale = 1.0f;
};
/**

View File

@ -1330,19 +1330,25 @@ void nsDisplayRemote::Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) {
return;
}
// Rendering the inner document will apply a scale to account for its
// app units per dev pixel ratio. We want to apply the inverse scaling
// using our app units per dev pixel ratio, so that no actual scaling
// will be applied if they match. For in-process rendering,
// nsSubDocumentFrame creates an nsDisplayZoom item if the app units
// per dev pixel ratio changes.
int32_t appUnitsPerDevPixel = pc->AppUnitsPerDevPixel();
gfxFloat scale = gfxFloat(AppUnitsPerCSSPixel()) / appUnitsPerDevPixel;
// Rendering the inner document will apply a scale to account for its app
// units per dev pixel ratio. We want to apply the inverse scaling using our
// app units per dev pixel ratio, so that no actual scaling will be applied if
// they match. For in-process rendering, nsSubDocumentFrame creates an
// nsDisplayZoom item if the app units per dev pixel ratio changes.
//
// Similarly, rendering the inner document will scale up by the cross process
// paint scale again, so we also need to account for that.
const int32_t appUnitsPerDevPixel = pc->AppUnitsPerDevPixel();
gfxContextMatrixAutoSaveRestore saveMatrix(aCtx);
gfxFloat targetAuPerDev =
gfxFloat(AppUnitsPerCSSPixel()) / aCtx->GetCrossProcessPaintScale();
gfxFloat scale = targetAuPerDev / appUnitsPerDevPixel;
aCtx->Multiply(gfxMatrix::Scaling(scale, scale));
Rect destRect =
NSRectToSnappedRect(GetContentRect(), AppUnitsPerCSSPixel(), *target);
NSRectToSnappedRect(GetContentRect(), targetAuPerDev, *target);
target->DrawDependentSurface(mPaintData.mTabId, destRect);
}

View File

@ -0,0 +1,16 @@
<meta charset=utf-8>
<title>Upper square green, rest blue</title>
<style>
div {
position: absolute;
width: 50vw;
height: 50vh;
top: 0;
left: 0;
background-color: lime;
}
:root {
background-color: blue;
}
</style>
<div></div>

View File

@ -8,6 +8,7 @@ support-files =
file_contains_img.html
file_contains_iframe.html
file_green.html
file_green_blue.html
file_contentscript_activeTab.html
file_contentscript_activeTab2.html
file_contentscript_iframe.html

View File

@ -255,6 +255,29 @@ add_task(async function testOOPiframe() {
});
});
add_task(async function testOOPiframeScale() {
let scale = 2;
await runTest({
html: `<!DOCTYPE html>
<meta charset=utf-8>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
background: yellow;
margin: 0;
}
</style>
<iframe frameborder="0" style="width: 300px; height: 300px" src="http://example.net/tests/toolkit/components/extensions/test/mochitest/file_green_blue.html"></iframe>
`,
coords: [
{ x: 20 * scale, y: 20 * scale, color: [0, 255, 0] },
{ x: 200 * scale, y: 20 * scale, color: [0, 0, 255] },
{ x: 20 * scale, y: 200 * scale, color: [0, 0, 255] },
],
scale,
});
});
add_task(async function testCaptureTabPermissions() {
let extension = ExtensionTestUtils.loadExtension({
manifest: {