Commit 34090c0d authored by stransky's avatar stransky
Browse files

Bug 1716563 [Wayland] Reset WindowSurfaceWayland cache when mozcontainer is unmapped, r=rmader

parent 636c8d24
Loading
Loading
Loading
Loading
+19 −7
Original line number Diff line number Diff line
@@ -282,6 +282,12 @@ static void moz_container_wayland_unmap_internal(MozContainer* container) {
  MozContainerWayland* wl_container = &container->wl_container;
  MutexAutoLock lock(*wl_container->container_lock);

  LOGWAYLAND(("%s [%p]\n", __FUNCTION__, (void*)container));

  if (wl_container->window_surface) {
    wl_container->window_surface->Reset();
  }

  if (wl_container->opaque_region_used) {
    moz_gdk_wayland_window_remove_frame_callback_surface_locked(container);
  }
@@ -295,8 +301,6 @@ static void moz_container_wayland_unmap_internal(MozContainer* container) {
  wl_container->surface_needs_clear = true;
  wl_container->ready_to_draw = false;
  wl_container->buffer_scale = 1;

  LOGWAYLAND(("%s [%p]\n", __FUNCTION__, (void*)container));
}

static gboolean moz_container_wayland_map_event(GtkWidget* widget,
@@ -538,9 +542,10 @@ static bool moz_container_wayland_surface_create_locked(
}

struct wl_surface* moz_container_wayland_surface_lock(MozContainer* container) {
  LOGWAYLAND(("%s [%p] surface %p ready_to_draw %d\n", __FUNCTION__,
              (void*)container, (void*)container->wl_container.surface,
              container->wl_container.ready_to_draw));
  // Temporary disabled to avoid log noise
  //  LOGWAYLAND(("%s [%p] surface %p ready_to_draw %d\n", __FUNCTION__,
  //              (void*)container, (void*)container->wl_container.surface,
  //              container->wl_container.ready_to_draw));
  if (!container->wl_container.surface ||
      !container->wl_container.ready_to_draw) {
    return nullptr;
@@ -554,8 +559,9 @@ struct wl_surface* moz_container_wayland_surface_lock(MozContainer* container) {

void moz_container_wayland_surface_unlock(MozContainer* container,
                                          struct wl_surface** surface) {
  LOGWAYLAND(("%s [%p] surface %p\n", __FUNCTION__, (void*)container,
              (void*)container->wl_container.surface));
  // Temporary disabled to avoid log noise
  //  LOGWAYLAND(("%s [%p] surface %p\n", __FUNCTION__, (void*)container,
  //              (void*)container->wl_container.surface));
  if (*surface) {
    container->wl_container.container_lock->Unlock();
    *surface = nullptr;
@@ -632,3 +638,9 @@ struct wp_viewport* moz_container_wayland_get_viewport(
  }
  return wl_container->viewport;
}

void moz_container_wayland_set_window_surface(
    MozContainer* container, RefPtr<WindowSurface> window_surface) {
  MozContainerWayland* wl_container = &container->wl_container;
  wl_container->window_surface = window_surface;
}
+5 −1
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include <functional>
#include <vector>
#include "mozilla/Mutex.h"
#include "WindowSurface.h"

/*
 * MozContainer
@@ -45,6 +46,7 @@ struct MozContainerWayland {
  gboolean ready_to_draw;
  gboolean before_first_size_alloc;
  int buffer_scale;
  RefPtr<mozilla::widget::WindowSurface> window_surface;
  std::vector<std::function<void(void)>> initial_draw_cbs;
  // mozcontainer is used from Compositor and Rendering threads
  // so we need to control access to mozcontainer where wayland internals
@@ -80,5 +82,7 @@ void moz_container_wayland_update_opaque_region(MozContainer* container,
gboolean moz_container_wayland_can_draw(MozContainer* container);
double moz_container_wayland_get_scale(MozContainer* container);
struct wp_viewport* moz_container_wayland_get_viewport(MozContainer* container);

void moz_container_wayland_set_window_surface(
    MozContainer* container,
    RefPtr<mozilla::widget::WindowSurface> window_surface);
#endif /* __MOZ_CONTAINER_WAYLAND_H__ */
+4 −0
Original line number Diff line number Diff line
@@ -31,6 +31,10 @@ class WindowSurface {
  // Whether the window surface represents a fallback method.
  virtual bool IsFallback() const { return false; }

  // Reset internal states (stored surfaces etc.) as attached
  // Gtk widget was hidden/shown. Used on Wayland only.
  virtual void Reset() {}

 protected:
  virtual ~WindowSurface() = default;
};
+18 −0
Original line number Diff line number Diff line
@@ -171,16 +171,24 @@ WindowSurfaceWayland::WindowSurfaceWayland(nsWindow* aWindow)
      mSmoothRendering(StaticPrefs::widget_wayland_smooth_rendering()),
      mSurfaceReadyTimerID(),
      mSurfaceLock("WindowSurfaceWayland lock") {
  LOGWAYLAND(("WindowSurfaceWayland::WindowSurfaceWayland() [%p]\n", this));
  // Use slow compositing on KDE only.
  const char* currentDesktop = getenv("XDG_CURRENT_DESKTOP");
  if (currentDesktop && strstr(currentDesktop, "KDE") != nullptr) {
    mSmoothRendering = CACHE_NONE;
  }
  MozContainer* container = mWindow->GetMozContainer();
  moz_container_wayland_set_window_surface(container, this);
}

WindowSurfaceWayland::~WindowSurfaceWayland() {
  LOGWAYLAND(("WindowSurfaceWayland::~WindowSurfaceWayland() [%p]\n", this));

  MutexAutoLock lock(mSurfaceLock);

  MozContainer* container = mWindow->GetMozContainer();
  moz_container_wayland_set_window_surface(container, nullptr);

  if (mSurfaceReadyTimerID) {
    g_source_remove(mSurfaceReadyTimerID);
    mSurfaceReadyTimerID = 0;
@@ -805,4 +813,14 @@ void WindowSurfaceWayland::BufferReleaseCallbackHandler(void* aData,
  surface->BufferReleaseCallbackHandler(aBuffer);
}

void WindowSurfaceWayland::Reset() {
  LOGWAYLAND(("WindowSurfaceWayland::Reset [%p]\n", this));
  MutexAutoLock lock(mSurfaceLock);
  if (mFrameCallback) {
    wl_callback_destroy(mFrameCallback);
    mFrameCallback = nullptr;
  }
  mLastCommittedSurfaceID = -1;
}

}  // namespace mozilla::widget
+2 −0
Original line number Diff line number Diff line
@@ -57,6 +57,8 @@ class WindowSurfaceWayland : public WindowSurface {
      const LayoutDeviceIntRegion& aRegion) override;
  void Commit(const LayoutDeviceIntRegion& aInvalidRegion) final;

  void Reset() override;

  // Try to commit all queued drawings to Wayland compositor. This is usually
  // called from other routines but can be used to explicitly flush
  // all drawings as we do when wl_buffer is released