diff --git a/wayland_adapter/framework/core/wayland_surface.cpp b/wayland_adapter/framework/core/wayland_surface.cpp index c4a8101f460f550020496cab92d392993bddf620..4f09be3eb2c16b4fe732fa2cbbbd6f719a5d331e 100644 --- a/wayland_adapter/framework/core/wayland_surface.cpp +++ b/wayland_adapter/framework/core/wayland_surface.cpp @@ -151,6 +151,11 @@ void WaylandSurface::Damage(int32_t x, int32_t y, int32_t width, int32_t height) void WaylandSurface::Frame(uint32_t callback) { + if (new_.cb != nullptr) { + LOG_WARN("duplicate frame request"); + return; + } + auto cb = FrameCallback::Create(WlClient(), WAYLAND_VERSION_MAJOR, callback); if (cb == nullptr) { LOG_ERROR("no memory"); @@ -158,8 +163,7 @@ void WaylandSurface::Frame(uint32_t callback) } WaylandObjectsPool::GetInstance().AddObject(ObjectId(cb->WlClient(), cb->Id()), cb); - wl_callback_send_done(cb->WlResource(), 0); - wl_resource_destroy(cb->WlResource()); + new_.cb = cb; } void WaylandSurface::SetOpaqueRegion(struct wl_resource *regionResource) @@ -221,6 +225,13 @@ void WaylandSurface::HandleCommit() { wl_shm_buffer_end_access(shm); wl_callback_send_done(new_.buffer, 0); + new_.buffer = nullptr; + } + + if (new_.cb != nullptr) { + wl_callback_send_done(new_.cb->WlResource(), 0); + wl_resource_destroy(new_.cb->WlResource()); + new_.cb = nullptr; } old_ = new_; diff --git a/wayland_adapter/utils/include/wayalnd_utils.h b/wayland_adapter/utils/include/wayalnd_utils.h index b84fda5ee08ef91e7a79df729cfe90583eb44a99..99e2f41876080cdb83dbf1b63922832b3fb59774 100644 --- a/wayland_adapter/utils/include/wayalnd_utils.h +++ b/wayland_adapter/utils/include/wayalnd_utils.h @@ -39,6 +39,23 @@ struct Rect { using SurfaceCommitCallback = std::function; using SurfaceRectCallback = std::function; +class FrameCallback final : public WaylandResourceObject { +public: + static OHOS::sptr Create(struct wl_client *client, uint32_t version, uint32_t callback) + { + return OHOS::sptr(new FrameCallback(client, version, callback)); + } + uint32_t Serial() const + { + return serial_; + } +private: + FrameCallback(struct wl_client *client, uint32_t version, uint32_t callback) + : WaylandResourceObject(client, &wl_callback_interface, version, callback, nullptr), serial_(callback) {} + ~FrameCallback() noexcept override {} + uint32_t serial_; +}; + struct SurfaceState { struct wl_resource *buffer = nullptr; Rect damage; @@ -47,9 +64,9 @@ struct SurfaceState { Rect damageBuffer; int32_t offsetX = 0; int32_t offsetY = 0; + OHOS::sptr cb; void Reset() { - buffer = nullptr; damage.Reset(); transform = WL_OUTPUT_TRANSFORM_NORMAL; scale = 0; @@ -65,23 +82,6 @@ enum class SurfaceRole : uint32_t { XDG_POPUP }; -class FrameCallback final : public WaylandResourceObject { -public: - static OHOS::sptr Create(struct wl_client *client, uint32_t version, uint32_t callback) - { - return OHOS::sptr(new FrameCallback(client, version, callback)); - } - uint32_t Serial() const - { - return serial_; - } -private: - FrameCallback(struct wl_client *client, uint32_t version, uint32_t callback) - : WaylandResourceObject(client, &wl_callback_interface, version, callback, nullptr), serial_(callback) {} - ~FrameCallback() noexcept override {} - uint32_t serial_; -}; - static SkColorType ShmFormatToSkia(const uint32_t& shmFormat) { switch (shmFormat) {