Bug 1736479 - Make gfx SanityTest.jsm work again r=gfx-reviewers,bradwerth

If we want to re-enable SanityTest.jsm test, we need to disable native compositor(DirectComposition) on the testing window, since taking snapshot of native compositor is very slow on Windows. Then CompositorOptions could be used to notice to disable native compositor(DirectComposition).
To notice it from SanityTest.jsm to gecko, nsIAppWindow::needFastSnaphot() is used.

Differential Revision: https://phabricator.services.mozilla.com/D130824
This commit is contained in:
sotaro 2022-04-20 01:08:52 +00:00
parent b02d6d2fd9
commit 0054e1bdb2
9 changed files with 70 additions and 9 deletions

View File

@ -41,6 +41,7 @@ class CompositorOptions {
}
bool AllowSoftwareWebRenderOGL() const { return mAllowSoftwareWebRenderOGL; }
bool InitiallyPaused() const { return mInitiallyPaused; }
bool NeedFastSnaphot() const { return mNeedFastSnaphot; }
void SetUseAPZ(bool aUseAPZ) { mUseAPZ = aUseAPZ; }
@ -56,12 +57,17 @@ class CompositorOptions {
mInitiallyPaused = aPauseAtStartup;
}
void SetNeedFastSnaphot(bool aNeedFastSnaphot) {
mNeedFastSnaphot = aNeedFastSnaphot;
}
bool operator==(const CompositorOptions& aOther) const {
return mUseAPZ == aOther.mUseAPZ &&
mUseSoftwareWebRender == aOther.mUseSoftwareWebRender &&
mAllowSoftwareWebRenderD3D11 ==
aOther.mAllowSoftwareWebRenderD3D11 &&
mAllowSoftwareWebRenderOGL == aOther.mAllowSoftwareWebRenderOGL;
mAllowSoftwareWebRenderOGL == aOther.mAllowSoftwareWebRenderOGL &&
mNeedFastSnaphot == aOther.mNeedFastSnaphot;
}
friend struct IPC::ParamTraits<CompositorOptions>;
@ -72,6 +78,7 @@ class CompositorOptions {
bool mAllowSoftwareWebRenderD3D11 = false;
bool mAllowSoftwareWebRenderOGL = false;
bool mInitiallyPaused = false;
bool mNeedFastSnaphot = false;
// Make sure to add new fields to the ParamTraits implementation
// in LayersMessageUtils.h

View File

@ -814,6 +814,7 @@ struct ParamTraits<mozilla::layers::CompositorOptions> {
WriteParam(aWriter, aParam.mAllowSoftwareWebRenderD3D11);
WriteParam(aWriter, aParam.mAllowSoftwareWebRenderOGL);
WriteParam(aWriter, aParam.mInitiallyPaused);
WriteParam(aWriter, aParam.mNeedFastSnaphot);
}
static bool Read(MessageReader* aReader, paramType* aResult) {
@ -821,7 +822,8 @@ struct ParamTraits<mozilla::layers::CompositorOptions> {
ReadParam(aReader, &aResult->mUseSoftwareWebRender) &&
ReadParam(aReader, &aResult->mAllowSoftwareWebRenderD3D11) &&
ReadParam(aReader, &aResult->mAllowSoftwareWebRenderOGL) &&
ReadParam(aReader, &aResult->mInitiallyPaused);
ReadParam(aReader, &aResult->mInitiallyPaused) &&
ReadParam(aReader, &aResult->mNeedFastSnaphot);
}
};

View File

@ -146,6 +146,12 @@ bool RenderCompositorANGLE::Initialize(nsACString& aError) {
return false;
}
// Disable native compositor when fast snapshot is needed.
// Taking snapshot of native compositor is very slow on Windows.
if (mWidget->GetCompositorOptions().NeedFastSnaphot()) {
mUseNativeCompositor = false;
}
// Create DCLayerTree when DirectComposition is used.
if (gfx::gfxVars::UseWebRenderDCompWin()) {
HWND compositorHwnd = GetCompositorHwnd();

View File

@ -200,13 +200,6 @@ function verifyLayersRendering(ctx) {
}
function testCompositor(test, win, ctx) {
if (win.windowUtils.layerManagerType.startsWith("WebRender")) {
// When layer manger type is WebRender, drawWindow() is skipped, since
// drawWindow() could take long time.
reportResult(TEST_PASSED);
return true;
}
takeWindowSnapshot(win, ctx);
var testPassed = true;
@ -430,6 +423,14 @@ SanityTest.prototype = {
null
);
let appWin = sanityTest.docShell.treeOwner
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIAppWindow);
// Request fast snapshot at RenderCompositor of WebRender.
// Since readback of Windows DirectComposition is very slow.
appWin.needFastSnaphot();
// There's no clean way to have an invisible window and ensure it's always painted.
// Instead, move the window far offscreen so it doesn't show up during launch.
sanityTest.moveTo(100000000, 1000000000);

View File

@ -153,6 +153,7 @@ nsBaseWidget::nsBaseWidget(nsBorderStyle aBorderStyle)
mIMEHasFocus(false),
mIMEHasQuit(false),
mIsFullyOccluded(false),
mNeedFastSnaphot(false),
mCurrentPanGestureBelongsToSwipe(false) {
#ifdef NOISY_WIDGET_LEAKS
gNumWidgets++;
@ -480,6 +481,10 @@ already_AddRefed<nsIWidget> nsBaseWidget::CreateChild(
widget = nsIWidget::CreateChildWindow();
}
if (widget && mNeedFastSnaphot) {
widget->SetNeedFastSnaphot();
}
if (widget &&
NS_SUCCEEDED(widget->Create(parent, nativeParent, aRect, aInitData))) {
return widget.forget();
@ -1205,6 +1210,9 @@ already_AddRefed<WebRenderLayerManager> nsBaseWidget::CreateCompositorSession(
options.SetAllowSoftwareWebRenderD3D11(
gfx::gfxVars::AllowSoftwareWebRenderD3D11());
}
if (mNeedFastSnaphot) {
options.SetNeedFastSnaphot(true);
}
#elif defined(MOZ_WIDGET_ANDROID)
MOZ_ASSERT(supportsAcceleration);
options.SetAllowSoftwareWebRenderOGL(
@ -1384,6 +1392,18 @@ void nsBaseWidget::ClearCachedWebrenderResources() {
mWindowRenderer->AsWebRender()->ClearCachedResources();
}
bool nsBaseWidget::SetNeedFastSnaphot() {
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(!mCompositorSession);
if (!XRE_IsParentProcess() || mCompositorSession) {
return false;
}
mNeedFastSnaphot = true;
return true;
}
already_AddRefed<gfx::DrawTarget> nsBaseWidget::StartRemoteDrawing() {
return nullptr;
}

View File

@ -620,6 +620,8 @@ class nsBaseWidget : public nsIWidget, public nsSupportsWeakReference {
void ClearCachedWebrenderResources() override;
bool SetNeedFastSnaphot() override;
/**
* Notify the widget that this window is being used with OMTC.
*/
@ -730,6 +732,7 @@ class nsBaseWidget : public nsIWidget, public nsSupportsWeakReference {
bool mIMEHasFocus;
bool mIMEHasQuit;
bool mIsFullyOccluded;
bool mNeedFastSnaphot;
// This flag is only used when APZ is off. It indicates that the current pan
// gesture was processed as a swipe. Sometimes the swipe animation can finish
// before momentum events of the pan gesture have stopped firing, so this

View File

@ -1985,6 +1985,12 @@ class nsIWidget : public nsISupports {
*/
virtual void ClearCachedWebrenderResources() {}
/**
* Request fast snapshot at RenderCompositor of WebRender.
* Since readback of Windows DirectComposition is very slow.
*/
virtual bool SetNeedFastSnaphot() { return false; }
/**
* If this widget has its own vsync source, return it, otherwise return
* nullptr. An example of such local source would be Wayland frame callbacks.

View File

@ -2580,6 +2580,16 @@ AppWindow::LockAspectRatio(bool aShouldLock) {
return NS_OK;
}
NS_IMETHODIMP
AppWindow::NeedFastSnaphot() {
MOZ_ASSERT(mWindow);
if (!mWindow) {
return NS_ERROR_FAILURE;
}
mWindow->SetNeedFastSnaphot();
return NS_OK;
}
void AppWindow::LoadPersistentWindowState() {
nsCOMPtr<dom::Element> docShellElement = GetWindowDOMElement();
if (!docShellElement) {

View File

@ -179,4 +179,10 @@ interface nsIAppWindow : nsISupports
* nsIOpenWindowInfo to use.
*/
readonly attribute nsIOpenWindowInfo initialOpenWindowInfo;
/**
* Request fast snapshot at RenderCompositor of WebRender.
* Since readback of Windows DirectComposition is very slow.
*/
void needFastSnaphot();
};