Bug 1769640 - P1: Cache content AUPDP in DocAccessibleParents. r=morgan,emilio

This change allows us to remove the `FullZoom` multiplier and fixes text
bounds caclulations in a zoomed page.

Testing: The current browser scroll/bounds tests pass (with the
exception of fission iframes which were already broken).

Differential Revision: https://phabricator.services.mozilla.com/D146507
This commit is contained in:
Eitan Isaacson 2022-05-20 16:39:50 +00:00
parent 981b10c3d0
commit c42dbc8b0f
5 changed files with 57 additions and 31 deletions

View File

@ -396,7 +396,7 @@ void nsAccessibilityService::NotifyOfResolutionChange(
if (StaticPrefs::accessibility_cache_enabled_AtStartup()) {
DocAccessible* document = GetDocAccessible(aPresShell);
if (document && document->IPCDoc()) {
nsTArray<mozilla::a11y::CacheData> data(1);
AutoTArray<mozilla::a11y::CacheData, 1> data;
RefPtr<AccAttributes> fields = new AccAttributes();
fields->SetAttribute(nsGkAtoms::resolution, aResolution);
data.AppendElement(mozilla::a11y::CacheData(0, fields));
@ -405,6 +405,21 @@ void nsAccessibilityService::NotifyOfResolutionChange(
}
}
void nsAccessibilityService::NotifyOfDevPixelRatioChange(
mozilla::PresShell* aPresShell, int32_t aAppUnitsPerDevPixel) {
if (StaticPrefs::accessibility_cache_enabled_AtStartup()) {
DocAccessible* document = GetDocAccessible(aPresShell);
if (document && document->IPCDoc()) {
AutoTArray<mozilla::a11y::CacheData, 1> data;
RefPtr<AccAttributes> fields = new AccAttributes();
fields->SetAttribute(nsGkAtoms::_moz_device_pixel_ratio,
aAppUnitsPerDevPixel);
data.AppendElement(mozilla::a11y::CacheData(0, fields));
document->IPCDoc()->SendCache(CacheUpdateType::Update, data, true);
}
}
}
LocalAccessible* nsAccessibilityService::GetRootDocumentAccessible(
PresShell* aPresShell, bool aCanCreate) {
PresShell* presShell = aPresShell;

View File

@ -242,6 +242,9 @@ class nsAccessibilityService final : public mozilla::a11y::DocManager,
void NotifyOfResolutionChange(mozilla::PresShell* aPresShell,
float aResolution);
void NotifyOfDevPixelRatioChange(mozilla::PresShell* aPresShell,
int32_t aAppUnitsPerDevPixel);
// nsAccessibiltiyService
/**

View File

@ -3500,6 +3500,10 @@ already_AddRefed<AccAttributes> LocalAccessible::BundleFieldsForCache(
// will ne notified via nsAS::NotifyOfResolutionChange
float resolution = presShell->GetResolution();
fields->SetAttribute(nsGkAtoms::resolution, resolution);
int32_t appUnitsPerDevPixel =
presShell->GetPresContext()->AppUnitsPerDevPixel();
fields->SetAttribute(nsGkAtoms::_moz_device_pixel_ratio,
appUnitsPerDevPixel);
}
}
}

View File

@ -396,28 +396,11 @@ LayoutDeviceIntRect RemoteAccessibleBase<Derived>::BoundsWithOffset(
Maybe<nsRect> maybeBounds = RetrieveCachedBounds();
if (maybeBounds) {
nsRect bounds = *maybeBounds;
#if !defined(ANDROID)
dom::CanonicalBrowsingContext* cbc =
static_cast<dom::BrowserParent*>(mDoc->Manager())
->GetBrowsingContext()
->Top();
dom::BrowserParent* bp = cbc->GetBrowserParent();
nsPresContext* presContext =
bp->GetOwnerElement()->OwnerDoc()->GetPresContext();
float fullZoom = cbc->GetFullZoom();
#else
// In Android the FullZoom is always 1.0 since we use APZ/resolution zoom.
float fullZoom = 1.0;
#endif
const DocAccessibleParent* topDoc = IsDoc() ? AsDoc() : nullptr;
if (aOffset.isSome()) {
// The rect we've passed in is in app units, so no conversion needed.
nsRect internalRect = *aOffset;
// XXX: Right now this is exclusively used for
// text bounds, which already have their zoom level
// applied. Remove it, because we'll multiply it back
// in later on.
internalRect.ScaleRoundOut(1 / fullZoom);
bounds.SetRectX(bounds.x + internalRect.x, internalRect.width);
bounds.SetRectY(bounds.y + internalRect.y, internalRect.height);
}
@ -450,6 +433,8 @@ LayoutDeviceIntRect RemoteAccessibleBase<Derived>::BoundsWithOffset(
nsGkAtoms::resolution);
MOZ_ASSERT(res, "No cached document resolution found.");
bounds.ScaleRoundOut(res.valueOr(1.0f));
topDoc = remoteAcc->AsDoc();
}
// Apply scroll offset, if applicable. Only the contents of an
@ -468,24 +453,31 @@ LayoutDeviceIntRect RemoteAccessibleBase<Derived>::BoundsWithOffset(
acc = acc->Parent();
}
MOZ_ASSERT(topDoc);
if (topDoc) {
// We use the top documents app-unites-per-dev-pixel even though
// theoretically nested docs can have different values. Practically,
// that isn't likely since we only offer zoom controls for the top
// document and all subdocuments inherit from it.
auto appUnitsPerDevPixel = topDoc->mCachedFields->GetAttribute<int32_t>(
nsGkAtoms::_moz_device_pixel_ratio);
MOZ_ASSERT(appUnitsPerDevPixel);
if (appUnitsPerDevPixel) {
// Convert our existing `bounds` rect from app units to dev pixels
devPxBounds = LayoutDeviceIntRect::FromAppUnitsToNearest(
bounds, *appUnitsPerDevPixel);
}
}
#if !defined(ANDROID)
// This block is not thread safe because it queries a LocalAccessible,
// the BrowsingContext, PresContext, etc. It is also not needed in
// Android since the only local accessible is the outer doc browser that
// has an offset of 0 and a FullZoom value of 1.0.
// This block is not thread safe because it queries a LocalAccessible.
// It is also not needed in Android since the only local accessible is
// the outer doc browser that has an offset of 0.
if (LocalAccessible* localAcc = const_cast<Accessible*>(acc)->AsLocal()) {
// LocalAccessible::Bounds returns screen-relative bounds in
// dev pixels.
LayoutDeviceIntRect localBounds = localAcc->Bounds();
// Convert our existing `bounds` rect from app units to dev pixels
devPxBounds = LayoutDeviceIntRect::FromAppUnitsToNearest(
bounds, presContext->AppUnitsPerDevPixel());
// We factor in our zoom level before offsetting by
// `localBounds`, which has already taken zoom into account.
devPxBounds.ScaleRoundOut(fullZoom);
// The root document will always have an APZ resolution of 1,
// so we don't factor in its scale here. We also don't scale
// by GetFullZoom because LocalAccessible::Bounds already does

View File

@ -91,6 +91,9 @@
#include "mozilla/layers/APZThreadUtils.h"
#include "MobileViewportManager.h"
#include "mozilla/dom/ImageTracker.h"
#ifdef ACCESSIBILITY
# include "mozilla/a11y/DocAccessible.h"
#endif
// Needed for Start/Stop of Image Animation
#include "imgIContainer.h"
@ -492,6 +495,15 @@ void nsPresContext::AppUnitsPerDevPixelChanged() {
mCurAppUnitsPerDevPixel = mDeviceContext->AppUnitsPerDevPixel();
#ifdef ACCESSIBILITY
if (mCurAppUnitsPerDevPixel != oldAppUnitsPerDevPixel) {
if (nsAccessibilityService* accService = GetAccService()) {
accService->NotifyOfDevPixelRatioChange(mPresShell,
mCurAppUnitsPerDevPixel);
}
}
#endif
// Recompute the size for vh units since it's changed by the dynamic toolbar
// max height which is stored in screen coord.
if (IsRootContentDocumentCrossProcess()) {