Bug 1756700 - Enforce widget size constraints on Android. r=gfx-reviewers,geckoview-reviewers,calu,aosmond

With the later patch in this series to delay initializing the
compositor, we started crashing in ScreenshotTest#giantScreenshot due
to webrender's window size sanity check.

This check panics early if we attempt to render an area larger than
webrender can handle (rather than panicing internally in
webrender). However, this test deliberately creates a 999999x999999
sized window, to ensure that attempting to allocate a bitmap this size
for a screenshot results in an out of memory exception.

Previously this test only succeeded because we created the compositor
early with a default size of 0x0, whereas now we create it after the
widget has its very large size. Additionally, the test completes
before we have a chance to render anything, otherwise it would indeed
have crashed.

To ensure users do not hit the panic in the wild, in bug 1653649 we
added the necessary limit to the default widget size constraints,
ensuring we never create widgets that are too large. On Android,
however, we do not use the size constraints, so this had no effect.

This patch starts applying size constraints to android widgets,
meaning we do not attempt to render too large an area, and webrender
does not panic. The test still attempts to allocate a large bitmap,
and therefore still throws an out of memory exception and passes.

Differential Revision: https://phabricator.services.mozilla.com/D140050
This commit is contained in:
Jamie Nicol 2022-03-02 16:56:28 +00:00
Родитель a9045a9bb2
Коммит 8c605446e9
2 изменённых файлов: 10 добавлений и 8 удалений

Просмотреть файл

@ -1808,6 +1808,7 @@ nsresult nsWindow::Create(nsIWidget* aParent, nsNativeWidget aNativeParent,
}
mBounds = rect;
SetSizeConstraints(SizeConstraints());
BaseCreate(nullptr, aInitData);
@ -2052,16 +2053,20 @@ void nsWindow::Resize(double aX, double aY, double aWidth, double aHeight,
ALOG("nsWindow[%p]::Resize [%f %f %f %f] (repaint %d)", (void*)this, aX, aY,
aWidth, aHeight, aRepaint);
bool needPositionDispatch = aX != mBounds.x || aY != mBounds.y;
bool needSizeDispatch = aWidth != mBounds.width || aHeight != mBounds.height;
LayoutDeviceIntRect oldBounds = mBounds;
mBounds.x = NSToIntRound(aX);
mBounds.y = NSToIntRound(aY);
mBounds.width = NSToIntRound(aWidth);
mBounds.height = NSToIntRound(aHeight);
ConstrainSize(&mBounds.width, &mBounds.height);
bool needPositionDispatch = mBounds.TopLeft() != oldBounds.TopLeft();
bool needSizeDispatch = mBounds.Size() != oldBounds.Size();
if (needSizeDispatch) {
OnSizeChanged(gfx::IntSize::Truncate(aWidth, aHeight));
OnSizeChanged(mBounds.Size().ToUnknownSize());
}
if (needPositionDispatch) {
@ -2294,9 +2299,6 @@ void nsWindow::OnSizeChanged(const gfx::IntSize& aSize) {
ALOG("nsWindow: %p OnSizeChanged [%d %d]", (void*)this, aSize.width,
aSize.height);
mBounds.width = aSize.width;
mBounds.height = aSize.height;
if (mWidgetListener) {
mWidgetListener->WindowResized(this, aSize.width, aSize.height);
}

Просмотреть файл

@ -113,8 +113,6 @@ class nsWindow final : public nsBaseWidget {
static mozilla::Modifiers GetModifiers(int32_t aMetaState);
static mozilla::TimeStamp GetEventTimeStamp(int64_t aEventTime);
void OnSizeChanged(const mozilla::gfx::IntSize& aSize);
void InitEvent(mozilla::WidgetGUIEvent& event,
LayoutDeviceIntPoint* aPoint = 0);
@ -269,6 +267,8 @@ class nsWindow final : public nsBaseWidget {
void CreateLayerManager();
void RedrawAll();
void OnSizeChanged(const mozilla::gfx::IntSize& aSize);
mozilla::layers::LayersId GetRootLayerId() const;
RefPtr<mozilla::layers::UiCompositorControllerChild>
GetUiCompositorControllerChild();