зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1849162 - Clean-up scale management a bit. r=stransky
Always pull and track the scale from the topmost window. Keep that one always up-to-date, which makes accessing it cheaper. Differential Revision: https://phabricator.services.mozilla.com/D186465
This commit is contained in:
Родитель
eae6af8066
Коммит
a59976347b
|
@ -592,7 +592,7 @@ static void fractional_scale_handle_preferred_scale(
|
|||
LOGWAYLAND("%s [%p] scale: %f\n", __func__, window.get(),
|
||||
wl_container->current_fractional_scale);
|
||||
MOZ_DIAGNOSTIC_ASSERT(window);
|
||||
window->OnScaleChanged(/* aForce = */ true);
|
||||
window->OnScaleChanged(/* aNotify = */ true);
|
||||
}
|
||||
|
||||
static const struct wp_fractional_scale_v1_listener fractional_scale_listener =
|
||||
|
@ -827,12 +827,8 @@ double moz_container_wayland_get_fractional_scale(MozContainer* container) {
|
|||
}
|
||||
|
||||
double moz_container_wayland_get_scale(MozContainer* container) {
|
||||
double scale = moz_container_wayland_get_fractional_scale(container);
|
||||
if (scale != 0.0) {
|
||||
return scale;
|
||||
}
|
||||
nsWindow* window = moz_container_get_nsWindow(container);
|
||||
return window ? window->FractionalScaleFactor() : 1;
|
||||
return window ? window->FractionalScaleFactor() : 1.0;
|
||||
}
|
||||
|
||||
void moz_container_wayland_set_commit_to_parent(MozContainer* container) {
|
||||
|
|
|
@ -399,7 +399,6 @@ nsWindow::nsWindow()
|
|||
mCreated(false),
|
||||
mHandleTouchEvent(false),
|
||||
mIsDragPopup(false),
|
||||
mWindowScaleFactorChanged(true),
|
||||
mCompositedScreen(gdk_screen_is_composited(gdk_screen_get_default())),
|
||||
mIsAccelerated(false),
|
||||
mWindowShouldStartDragging(false),
|
||||
|
@ -4034,7 +4033,7 @@ gboolean nsWindow::OnConfigureEvent(GtkWidget* aWidget,
|
|||
// Don't fire configure event for scale changes, we handle that
|
||||
// OnScaleChanged event. Skip that for toplevel windows only.
|
||||
if (mGdkWindow && IsTopLevelWindowType()) {
|
||||
if (mWindowScaleFactor != gdk_window_get_scale_factor(mGdkWindow)) {
|
||||
if (mCeiledScaleFactor != gdk_window_get_scale_factor(mGdkWindow)) {
|
||||
LOG(" scale factor changed to %d,return early",
|
||||
gdk_window_get_scale_factor(mGdkWindow));
|
||||
return FALSE;
|
||||
|
@ -5285,30 +5284,39 @@ void nsWindow::OnCompositedChanged() {
|
|||
mCompositedScreen = gdk_screen_is_composited(gdk_screen_get_default());
|
||||
}
|
||||
|
||||
void nsWindow::OnScaleChanged(bool aForce) {
|
||||
// Force scale factor recalculation
|
||||
if (!mGdkWindow) {
|
||||
mWindowScaleFactorChanged = true;
|
||||
void nsWindow::OnScaleChanged(bool aNotify) {
|
||||
if (!IsTopLevelWindowType()) {
|
||||
return;
|
||||
}
|
||||
LOG("OnScaleChanged -> %d, frac=%f\n",
|
||||
gdk_window_get_scale_factor(mGdkWindow), FractionalScaleFactor());
|
||||
if (!mGdkWindow) {
|
||||
return; // We'll get there again when we configure the window.
|
||||
}
|
||||
gint newCeiled = gdk_window_get_scale_factor(mGdkWindow);
|
||||
double newFractional =
|
||||
GdkIsWaylandDisplay()
|
||||
? moz_container_wayland_get_fractional_scale(mContainer)
|
||||
: 0.0;
|
||||
LOG("OnScaleChanged %d, %f -> %d, %f\n", int(mCeiledScaleFactor),
|
||||
FractionalScaleFactor(), newCeiled, newFractional);
|
||||
|
||||
// Gtk supply us sometimes with doubled events so stay calm in such case.
|
||||
if (!aForce &&
|
||||
gdk_window_get_scale_factor(mGdkWindow) == mWindowScaleFactor) {
|
||||
if (mCeiledScaleFactor == newCeiled &&
|
||||
mFractionalScaleFactor == newFractional) {
|
||||
return;
|
||||
}
|
||||
|
||||
mCeiledScaleFactor = newCeiled;
|
||||
mFractionalScaleFactor = newFractional;
|
||||
|
||||
if (!aNotify) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We pause compositor to avoid rendering of obsoleted remote content which
|
||||
// produces flickering.
|
||||
// Re-enable compositor again when remote content is updated or
|
||||
// timeout happens.
|
||||
// Re-enable compositor again when remote content is updated or timeout
|
||||
// happens.
|
||||
PauseCompositorFlickering();
|
||||
|
||||
// Force scale factor recalculation
|
||||
mWindowScaleFactorChanged = true;
|
||||
|
||||
GtkAllocation allocation;
|
||||
gtk_widget_get_allocation(GTK_WIDGET(mContainer), &allocation);
|
||||
LayoutDeviceIntSize size = GdkRectToDevicePixels(allocation).Size();
|
||||
|
@ -5730,6 +5738,7 @@ void nsWindow::ConfigureGdkWindow() {
|
|||
LOG("nsWindow::ConfigureGdkWindow()");
|
||||
|
||||
EnsureGdkWindow();
|
||||
OnScaleChanged(/* aNotify = */ false);
|
||||
|
||||
#ifdef MOZ_X11
|
||||
if (GdkIsX11Display()) {
|
||||
|
@ -8367,7 +8376,7 @@ static void scale_changed_cb(GtkWidget* widget, GParamSpec* aPSpec,
|
|||
return;
|
||||
}
|
||||
|
||||
window->OnScaleChanged(/* aForce = */ false);
|
||||
window->OnScaleChanged(/* aNotify = */ true);
|
||||
}
|
||||
|
||||
static gboolean touch_event_cb(GtkWidget* aWidget, GdkEventTouch* aEvent) {
|
||||
|
@ -8922,56 +8931,29 @@ GtkWindow* nsWindow::GetCurrentTopmostWindow() const {
|
|||
return topmostParentWindow;
|
||||
}
|
||||
|
||||
// We're called from Renderer/Compositor thread where EGL Window size is set.
|
||||
// Just return what we have and keep scale update to main thread.
|
||||
gint nsWindow::GetCachedCeiledScaleFactor() const { return mWindowScaleFactor; }
|
||||
|
||||
gint nsWindow::GdkCeiledScaleFactor() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// We depend on notify::scale-factor callback which is reliable for toplevel
|
||||
// windows only, so don't use scale cache for popup windows.
|
||||
if (mWindowType == WindowType::TopLevel && !mWindowScaleFactorChanged) {
|
||||
return mWindowScaleFactor;
|
||||
if (IsTopLevelWindowType()) {
|
||||
return mCeiledScaleFactor;
|
||||
}
|
||||
|
||||
GdkWindow* scaledGdkWindow = nullptr;
|
||||
if (GdkIsWaylandDisplay()) {
|
||||
// For popup windows/dialogs with parent window we need to get scale factor
|
||||
// of the topmost window. Otherwise the scale factor of the popup is
|
||||
// not updated during it's hidden.
|
||||
if (mWindowType == WindowType::Popup || mWindowType == WindowType::Dialog) {
|
||||
// Get toplevel window for scale factor:
|
||||
GtkWindow* topmostParentWindow = GetCurrentTopmostWindow();
|
||||
if (topmostParentWindow) {
|
||||
scaledGdkWindow =
|
||||
gtk_widget_get_window(GTK_WIDGET(topmostParentWindow));
|
||||
} else {
|
||||
NS_WARNING("Popup/Dialog has no parent.");
|
||||
}
|
||||
}
|
||||
if (nsWindow* topmost = GetTopmostWindow()) {
|
||||
return topmost->mCeiledScaleFactor;
|
||||
}
|
||||
// Fallback for windows which parent has been unrealized.
|
||||
if (!scaledGdkWindow) {
|
||||
scaledGdkWindow = mGdkWindow;
|
||||
}
|
||||
if (scaledGdkWindow) {
|
||||
mWindowScaleFactor = gdk_window_get_scale_factor(scaledGdkWindow);
|
||||
mWindowScaleFactorChanged = false;
|
||||
} else {
|
||||
mWindowScaleFactor = ScreenHelperGTK::GetGTKMonitorScaleFactor();
|
||||
}
|
||||
return mWindowScaleFactor;
|
||||
return ScreenHelperGTK::GetGTKMonitorScaleFactor();
|
||||
}
|
||||
|
||||
double nsWindow::FractionalScaleFactor() {
|
||||
#ifdef MOZ_WAYLAND
|
||||
if (mContainer) {
|
||||
double fractional_scale =
|
||||
moz_container_wayland_get_fractional_scale(mContainer);
|
||||
if (fractional_scale != 0.0) {
|
||||
return fractional_scale;
|
||||
double fractional_scale = [&] {
|
||||
if (IsTopLevelWindowType()) {
|
||||
return mFractionalScaleFactor;
|
||||
}
|
||||
if (nsWindow* topmost = GetTopmostWindow()) {
|
||||
return topmost->mFractionalScaleFactor;
|
||||
}
|
||||
return 0.0;
|
||||
}();
|
||||
if (fractional_scale != 0.0) {
|
||||
return fractional_scale;
|
||||
}
|
||||
#endif
|
||||
return GdkCeiledScaleFactor();
|
||||
|
@ -9743,8 +9725,7 @@ void nsWindow::SetEGLNativeWindowSize(
|
|||
|
||||
// SetEGLNativeWindowSize() may be called from Renderer/Compositor thread.
|
||||
// In such case use cached scale factor.
|
||||
gint scale =
|
||||
NS_IsMainThread() ? GdkCeiledScaleFactor() : GetCachedCeiledScaleFactor();
|
||||
gint scale = GdkCeiledScaleFactor();
|
||||
LOG("nsWindow::SetEGLNativeWindowSize() %d x %d scale %d (unscaled %d x %d)",
|
||||
aEGLWindowSize.width, aEGLWindowSize.height, scale,
|
||||
aEGLWindowSize.width / scale, aEGLWindowSize.height / scale);
|
||||
|
|
|
@ -271,7 +271,7 @@ class nsWindow final : public nsBaseWidget {
|
|||
void OnDPIChanged();
|
||||
void OnCheckResize();
|
||||
void OnCompositedChanged();
|
||||
void OnScaleChanged(bool aForce);
|
||||
void OnScaleChanged(bool aNotify);
|
||||
void DispatchResized();
|
||||
|
||||
static guint32 sLastButtonPressTime;
|
||||
|
@ -374,7 +374,6 @@ class nsWindow final : public nsBaseWidget {
|
|||
|
||||
// HiDPI scale conversion
|
||||
gint GdkCeiledScaleFactor();
|
||||
gint GetCachedCeiledScaleFactor() const;
|
||||
double FractionalScaleFactor();
|
||||
|
||||
// To GDK
|
||||
|
@ -475,7 +474,8 @@ class nsWindow final : public nsBaseWidget {
|
|||
|
||||
nsCOMPtr<nsIWidget> mParent;
|
||||
PopupType mPopupHint{};
|
||||
mozilla::Atomic<int, mozilla::Relaxed> mWindowScaleFactor{1};
|
||||
mozilla::Atomic<int, mozilla::Relaxed> mCeiledScaleFactor{1};
|
||||
double mFractionalScaleFactor = 0.0;
|
||||
|
||||
void UpdateAlpha(mozilla::gfx::SourceSurface* aSourceSurface,
|
||||
nsIntRect aBoundsRect);
|
||||
|
@ -647,7 +647,6 @@ class nsWindow final : public nsBaseWidget {
|
|||
bool mHandleTouchEvent : 1;
|
||||
// true if this is a drag and drop feedback popup
|
||||
bool mIsDragPopup : 1;
|
||||
bool mWindowScaleFactorChanged : 1;
|
||||
bool mCompositedScreen : 1;
|
||||
bool mIsAccelerated : 1;
|
||||
bool mWindowShouldStartDragging : 1;
|
||||
|
|
Загрузка…
Ссылка в новой задаче