/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim:expandtab:shiftwidth=2:tabstop=2:
*/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * MozContainerWayland is a wrapper over MozContainer which manages * WaylandSurface for nsWindow. * * The widget scheme looks like: * * --------------------------------------------------------- * | mShell Gtk widget (contains wl_surface owned by Gtk+) | * | | * | --------------------------------------------------- | * | | mContainer (contains wl_surface owned by Gtk+) | | * | | | | * | | --------------------------------------------- | | * | | | wl_subsurface (owned by WaylandSurface) | | | * | | | | | | * | | | | | | * | | | | | | * | | --------------------------------------------- | | * | --------------------------------------------------- | * --------------------------------------------------------- * * We draw to wl_subsurface managed by WaylandSurface/MozContainerWayland. * We need to wait until wl_surface of mContainer is created * and then we create and attach our wl_subsurface to it. * * First wl_subsurface creation has these steps: * * 1) moz_container_wayland_size_allocate() handler is called when * mContainer size/position is known. * It calls moz_container_wayland_surface_create_locked(), registers * a frame callback handler * moz_container_wayland_frame_callback_handler(). * * 2) moz_container_wayland_frame_callback_handler() is called * when wl_surface owned by mozContainer is ready. * We call initial_draw_cbs() handler and we can create our wl_subsurface * on top of wl_surface owned by mozContainer. * * When MozContainer hides/show again, moz_container_wayland_size_allocate() * handler may not be called as MozContainer size is set. So after first * show/hide sequence use moz_container_wayland_map_event() to create * wl_subsurface of MozContainer.
*/
// This is called from layout/compositor code only with // size equal to GL rendering context.
// Return false if scale factor doesn't match buffer size. // We need to skip painting in such case do avoid Wayland compositor freaking. bool moz_container_wayland_egl_window_set_size(MozContainer* container,
nsIntSize aScaledSize) { return MOZ_WL_SURFACE(container)->SetEGLWindowSize(aScaledSize);
}
WaylandSurface* surface = MOZ_WL_SURFACE(MOZ_CONTAINER(widget)); // MozContainer map/unmap is processed on main thread only // so we don't need to lock WaylandSurface here. if (surface->IsMapped()) {
surface->RunUnmapCallback();
}
WaylandSurfaceLock lock(surface); if (surface->IsPendingGdkCleanup()) {
surface->GdkCleanUpLocked(lock);
}
surface->UnmapLocked(lock);
}
// Return early if we're not mapped. Gtk may send bogus map_event signal // to unmapped widgets (see Bug 1875369). if (!gtk_widget_get_mapped(widget)) { returnfalse;
}
// Make sure we're on main thread as we can't lock mozContainer here // due to moz_container_wayland_add_or_fire_initial_draw_callback() call // below.
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
// Set waiting_to_show flag. It means the mozcontainer is cofigured/mapped // and it's supposed to be visible. *But* it's really visible when we get // moz_container_wayland_add_or_fire_initial_draw_callback() which means // wayland compositor makes it live.
MOZ_WL_CONTAINER(widget)->waiting_to_show = true;
MozContainer* container = MOZ_CONTAINER(widget);
MOZ_WL_SURFACE(container)->AddOrFireReadyToDrawCallback(
[container]() -> void {
LOGCONTAINER( "[%p] moz_container_wayland_add_or_fire_initial_draw_callback set " "visible",
moz_container_get_nsWindow(container));
moz_container_wayland_clear_waiting_to_show_flag(container);
});
// Don't create wl_subsurface in map_event when it's already created or // if we create it for the first time. if (MOZ_WL_SURFACE(container)->IsMapped() ||
MOZ_WL_CONTAINER(container)->before_first_size_alloc) { returnfalse;
}
/* short circuit if you can */
gtk_widget_get_allocation(widget, &tmp_allocation); if (tmp_allocation.x == allocation->x && tmp_allocation.y == allocation->y &&
tmp_allocation.width == allocation->width &&
tmp_allocation.height == allocation->height) { return;
}
gtk_widget_set_allocation(widget, allocation);
if (gtk_widget_get_has_window(widget) && gtk_widget_get_realized(widget)) {
gdk_window_move_resize(gtk_widget_get_window(widget), allocation->x,
allocation->y, allocation->width,
allocation->height); // We need to position our subsurface according to GdkWindow // when offset changes (GdkWindow is maximized for instance). // see gtk-clutter-embed.c for reference.
gfx::IntPoint position(allocation->x, allocation->y);
moz_container_wayland_ensure_surface(MOZ_CONTAINER(widget), &position);
MOZ_WL_CONTAINER(widget)->before_first_size_alloc = false;
}
}
if (!MOZ_WL_SURFACE(container)->IsMapped()) { return nullptr;
}
// TODO: Get size from bounds instead of GdkWindow? // We may be in rendering/compositor thread here.
GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(container));
nsIntSize unscaledSize(gdk_window_get_width(window),
gdk_window_get_height(window)); return MOZ_WL_SURFACE(container)->GetEGLWindow(unscaledSize);
}
// When GL compositor / WebRender is used, // moz_container_wayland_get_egl_window() is called only once when window // is created or resized so update opaque region now. if (MOZ_WL_SURFACE(container)->HasEGLWindow()) {
MOZ_WL_CONTAINER(container)->opaque_region_needs_updates = false;
nsWindow* window = moz_container_get_nsWindow(container);
MOZ_WL_SURFACE(container)->SetOpaqueRegion(
window->GetOpaqueRegion().ToUnknownRegion());
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.