diff --git a/wayland_adapter/framework/BUILD.gn b/wayland_adapter/framework/BUILD.gn index b8feb357f14efd10c284f6c3957d8f59daa68dd5..b4117363f1d38d50b922b6c07a560c22c7c3c379 100644 --- a/wayland_adapter/framework/BUILD.gn +++ b/wayland_adapter/framework/BUILD.gn @@ -44,6 +44,7 @@ ft_source_set("wayland_framewok_sources") { } deps = [ + "$window_manager_path/dm/ft_build:libdm", "$window_manager_path/wm/ft_build:libwm", "$display_server_root/rosen/modules/render_service_base/ft_build:librender_service_base", "$display_server_root/rosen/modules/render_service_client/ft_build:librender_service_client", diff --git a/wayland_adapter/framework/core/wayland_surface.cpp b/wayland_adapter/framework/core/wayland_surface.cpp index e9a4ad5b045a292c69e28a6bbb4eaae73787a36f..c4a8101f460f550020496cab92d392993bddf620 100644 --- a/wayland_adapter/framework/core/wayland_surface.cpp +++ b/wayland_adapter/framework/core/wayland_surface.cpp @@ -16,6 +16,8 @@ #include "wayland_surface.h" #include "wayland_objects_pool.h" +#include "ui/rs_surface_extractor.h" +#include "display_manager.h" namespace FT { namespace Wayland { @@ -123,31 +125,28 @@ void WaylandSurface::AddCommitCallback(SurfaceCommitCallback callback) commitCallbacks_.push_back(std::move(callback)); } -void WaylandSurface::AddAttachCallback(SurfaceAttachCallback callback) +void WaylandSurface::AddRectCallback(SurfaceRectCallback callback) { - attachCallbacks_.push_back(std::move(callback)); + rectCallbacks_.push_back(std::move(callback)); } void WaylandSurface::Attach(struct wl_resource *bufferResource, int32_t x, int32_t y) { - wl_shm_buffer *shm = wl_shm_buffer_get(bufferResource); - if (shm == nullptr) { - LOG_ERROR("wl_shm_buffer_get fail"); - return; - } - - wl_shm_buffer_begin_access(shm); - - for (auto &cb : attachCallbacks_) { - cb(shm); + if (new_.buffer != nullptr) { + wl_callback_send_done(new_.buffer, 0); } - wl_shm_buffer_end_access(shm); - wl_callback_send_done(bufferResource, 0); + new_.buffer = bufferResource; + new_.offsetX = x; + new_.offsetY = y; } void WaylandSurface::Damage(int32_t x, int32_t y, int32_t width, int32_t height) { + new_.damage.x = x; + new_.damage.y = y; + new_.damage.width = static_cast(width); + new_.damage.height = static_cast(height); } void WaylandSurface::Frame(uint32_t callback) @@ -173,6 +172,12 @@ void WaylandSurface::SetInputRegion(struct wl_resource *regionResource) void WaylandSurface::Commit() { + if (window_ == nullptr) { + CreateWindow(); + } else { + HandleCommit(); + } + for (auto &cb : commitCallbacks_) { cb(); } @@ -180,29 +185,143 @@ void WaylandSurface::Commit() void WaylandSurface::SetBufferTransform(int32_t transform) { + new_.transform = static_cast(transform); } void WaylandSurface::SetBufferScale(int32_t scale) { + new_.scale = scale; } void WaylandSurface::DamageBuffer(int32_t x, int32_t y, int32_t width, int32_t height) { + new_.damageBuffer.x = x; + new_.damageBuffer.y = y; + new_.damageBuffer.width = static_cast(width); + new_.damageBuffer.height = static_cast(height); } void WaylandSurface::Offset(int32_t x, int32_t y) { + new_.offsetX = x; + new_.offsetY = y; +} + +void WaylandSurface::HandleCommit() { + if (new_.buffer != nullptr) { + wl_shm_buffer *shm = wl_shm_buffer_get(new_.buffer); + if (shm == nullptr) { + LOG_ERROR("wl_shm_buffer_get fail"); + wl_callback_send_done(new_.buffer, 0); + return; + } + + wl_shm_buffer_begin_access(shm); + CopyBuffer(shm); + wl_shm_buffer_end_access(shm); + + wl_callback_send_done(new_.buffer, 0); + } + + old_ = new_; + new_.Reset(); } -OHOS::sptr WaylandSurface::FrameCallback::Create(struct wl_client *client, - uint32_t version, uint32_t callback) +void WaylandSurface::CreateWindow() { - return OHOS::sptr(new WaylandSurface::FrameCallback(client, version, callback)); + OHOS::sptr option(new OHOS::Rosen::WindowOption()); + if (rect_.width == 0 || rect_.height == 0) { + InitWindowRect(); + } + option->SetWindowRect({rect_.x, rect_.y, rect_.width, rect_.height}); + option->SetWindowType(OHOS::Rosen::WindowType::APP_MAIN_WINDOW_BASE); + option->SetWindowMode(OHOS::Rosen::WindowMode::WINDOW_MODE_FLOATING); + + static int count = 0; + std::string windowName = "WaylandWindow" + std::to_string(count++); + window_ = OHOS::Rosen::Window::Create(windowName, option); + if (window_ == nullptr) { + LOG_ERROR("Window::Create failed"); + return; + } + window_->Show(); + + surfaceNode_ = window_->GetSurfaceNode(); + if (surfaceNode_ == nullptr) { + LOG_ERROR("GetSurfaceNode failed"); + return; + } + + rsSurface_ = OHOS::Rosen::RSSurfaceExtractor::ExtractRSSurface(surfaceNode_); + if (rsSurface_ == nullptr) { + LOG_ERROR("ExtractRSSurface failed"); + return; + } + +#ifdef ENABLE_GPU + renderContext_ = std::make_unique(); + renderContext_->InitializeEglContext(); + rsSurface_->SetRenderContext(renderContext_.get()); +#endif } -WaylandSurface::FrameCallback::FrameCallback(struct wl_client *client, uint32_t version, uint32_t callback) - : WaylandResourceObject(client, &wl_callback_interface, version, callback, nullptr), serial_(callback) {} +void WaylandSurface::CopyBuffer(struct wl_shm_buffer *shm) +{ + if (rsSurface_ == nullptr) { + LOG_ERROR("rsSurface_ is nullptr"); + return; + } + + SkColorType format = ShmFormatToSkia(wl_shm_buffer_get_format(shm)); + if (format == SkColorType::kUnknown_SkColorType) { + LOG_ERROR("unsupported format %{public}d", wl_shm_buffer_get_format(shm)); + return; + } + + int32_t stride = wl_shm_buffer_get_stride(shm); + int32_t width = wl_shm_buffer_get_width(shm); + int32_t height = wl_shm_buffer_get_height(shm); + if (stride <= 0 || width <= 0 || height <= 0) { + LOG_ERROR("invalid, stride:%{public}d width:%{public}d height:%{public}d", stride, width, height); + return; + } + + void *data = wl_shm_buffer_get_data(shm); + if (data == nullptr) { + LOG_ERROR("wl_shm_buffer_get_data fail"); + return; + } -WaylandSurface::FrameCallback::~FrameCallback() noexcept {} + auto framePtr = rsSurface_->RequestFrame(width, height); + if (framePtr == nullptr) { + LOG_ERROR("RequestFrame failed"); + return; + } + + auto canvas = framePtr->GetCanvas(); + if (canvas == nullptr) { + LOG_ERROR("GetCanvas failed"); + return; + } + canvas->clear(SK_ColorTRANSPARENT); + + SkImageInfo imageInfo = SkImageInfo::Make(width, height, format, kUnpremul_SkAlphaType); + SkPixmap srcPixmap(imageInfo, data, stride); + SkBitmap srcBitmap; + srcBitmap.installPixels(srcPixmap); + canvas->drawBitmap(srcBitmap, 0, 0); + rsSurface_->FlushFrame(framePtr); +} + +void WaylandSurface::InitWindowRect() +{ + auto display = OHOS::Rosen::DisplayManager::GetInstance().GetDefaultDisplay(); + rect_.width = display->GetWidth(); + rect_.height = display->GetHeight(); + + for (auto &cb : rectCallbacks_) { + cb(rect_); + } +} } // namespace Wayland } // namespace FT diff --git a/wayland_adapter/framework/core/wayland_surface.h b/wayland_adapter/framework/core/wayland_surface.h index ed9b4d98e46c126b82e9ad4127fae721cdb5846d..e56b03f499fb15aa397c35de1cf4963f38f5c709 100644 --- a/wayland_adapter/framework/core/wayland_surface.h +++ b/wayland_adapter/framework/core/wayland_surface.h @@ -16,9 +16,13 @@ #pragma once #include - #include #include "wayland_resource_object.h" +#include "wayalnd_utils.h" + +#include "window.h" +#include "ui/rs_surface_node.h" +#include "render_context/render_context.h" namespace FT { namespace Wayland { @@ -49,10 +53,8 @@ public: uint32_t version, uint32_t id); ~WaylandSurface() noexcept override; - using SurfaceCommitCallback = std::function; void AddCommitCallback(SurfaceCommitCallback callback); - using SurfaceAttachCallback = std::function; - void AddAttachCallback(SurfaceAttachCallback callback); + void AddRectCallback(SurfaceRectCallback callback); private: WaylandSurface(struct wl_client *client, struct wl_resource *parent, uint32_t version, uint32_t id); @@ -67,23 +69,24 @@ private: void SetBufferScale(int32_t scale); void DamageBuffer(int32_t x, int32_t y, int32_t width, int32_t height); void Offset(int32_t x, int32_t y); - - class FrameCallback final : public WaylandResourceObject { - public: - static OHOS::sptr Create(struct wl_client *client, uint32_t version, uint32_t callback); - uint32_t Serial() const - { - return serial_; - } - private: - FrameCallback(struct wl_client *client, uint32_t version, uint32_t callback); - ~FrameCallback() noexcept override; - uint32_t serial_; - }; + void HandleCommit(); + void CreateWindow(); + void CopyBuffer(struct wl_shm_buffer *shm); + void InitWindowRect(); struct wl_resource *parent_ = nullptr; std::list commitCallbacks_; - std::list attachCallbacks_; + std::list rectCallbacks_; + Rect rect_; + SurfaceState old_; + SurfaceState new_; + +#ifdef ENABLE_GPU + std::unique_ptr renderContext_; +#endif + OHOS::sptr window_; + std::shared_ptr surfaceNode_; + std::shared_ptr rsSurface_; }; } // namespace Wayland } // namespace FT diff --git a/wayland_adapter/framework/stable/wayland_xdg_surface.cpp b/wayland_adapter/framework/stable/wayland_xdg_surface.cpp index 793a3184c96c0e99b0d494e499c5d1de06253a32..873d11eebfc86ba9136581e0f56934e9428f7dde 100644 --- a/wayland_adapter/framework/stable/wayland_xdg_surface.cpp +++ b/wayland_adapter/framework/stable/wayland_xdg_surface.cpp @@ -81,7 +81,7 @@ WaylandXdgSurface::WaylandXdgSurface(const OHOS::sptr &xdgWm surface_(surface) { surface->AddCommitCallback([this]() { OnSurfaceCommit(); }); - surface->AddAttachCallback([this](struct wl_shm_buffer *shm) { OnSurfaceAttach(shm); }); + surface->AddRectCallback([this](Rect rect) { OnSurfaceRect(rect); }); } WaylandXdgSurface::~WaylandXdgSurface() noexcept {} @@ -94,7 +94,7 @@ void WaylandXdgSurface::GetToplevel(uint32_t id) return; } - role_ = XdgSurfaceRole::TOPLEVEL; + role_ = SurfaceRole::XDG_TOPLEVEL; } void WaylandXdgSurface::GetPopup(uint32_t id, struct wl_resource *parent, struct wl_resource *positioner) @@ -111,33 +111,23 @@ void WaylandXdgSurface::AckConfigure(uint32_t serial) void WaylandXdgSurface::OnSurfaceCommit() { - switch (role_) { - case XdgSurfaceRole::TOPLEVEL: { - auto topLevel = toplevel_.promote(); - if (topLevel != nullptr) { - topLevel->HandleCommit(); - } - break; + if (role_ == SurfaceRole::XDG_TOPLEVEL) { + auto topLevel = toplevel_.promote(); + if (topLevel != nullptr) { + topLevel->HandleCommit(); } - default: - break; } xdg_surface_send_configure(WlResource(), wl_display_next_serial(WlDisplay())); } -void WaylandXdgSurface::OnSurfaceAttach(struct wl_shm_buffer *shm) +void WaylandXdgSurface::OnSurfaceRect(Rect rect) { - switch (role_) { - case XdgSurfaceRole::TOPLEVEL: { - auto topLevel = toplevel_.promote(); - if (topLevel != nullptr) { - topLevel->HandleAttach(shm); - } - break; + if (role_ == SurfaceRole::XDG_TOPLEVEL) { + auto topLevel = toplevel_.promote(); + if (topLevel != nullptr) { + topLevel->SetRect(rect); } - default: - break; } } } // namespace Wayland diff --git a/wayland_adapter/framework/stable/wayland_xdg_surface.h b/wayland_adapter/framework/stable/wayland_xdg_surface.h index f0487313037c94cda7626a53720a1a4d128cdec7..56d9ad43d169aa8db19aaa6b624f3a4ac3c23d4b 100644 --- a/wayland_adapter/framework/stable/wayland_xdg_surface.h +++ b/wayland_adapter/framework/stable/wayland_xdg_surface.h @@ -18,7 +18,7 @@ #include #include "wayland_resource_object.h" #include "wayland_surface.h" -#include "xdg_surface_utils.h" +#include "wayalnd_utils.h" namespace FT { namespace Wayland { @@ -49,9 +49,9 @@ private: void SetWindowGeometry(int32_t x, int32_t y, int32_t width, int32_t height); void AckConfigure(uint32_t serial); void OnSurfaceCommit(); - void OnSurfaceAttach(struct wl_shm_buffer *shm); + void OnSurfaceRect(Rect rect); - XdgSurfaceRole role_ = XdgSurfaceRole::NONE; + SurfaceRole role_ = SurfaceRole::NONE; OHOS::wptr xdgWm_; OHOS::wptr surface_; OHOS::wptr toplevel_; diff --git a/wayland_adapter/framework/stable/wayland_xdg_toplevel.cpp b/wayland_adapter/framework/stable/wayland_xdg_toplevel.cpp index 3c2d5bff2eb5c70d190387323ac67b266e11f48b..993aa5290f31fb931691fa446ee8371d5516547d 100644 --- a/wayland_adapter/framework/stable/wayland_xdg_toplevel.cpp +++ b/wayland_adapter/framework/stable/wayland_xdg_toplevel.cpp @@ -16,7 +16,6 @@ #include "wayland_xdg_toplevel.h" #include "wayland_objects_pool.h" -#include "ui/rs_surface_extractor.h" namespace FT { namespace Wayland { @@ -136,15 +135,10 @@ WaylandXdgToplevel::WaylandXdgToplevel(const OHOS::sptr &xdgS WaylandXdgToplevel::~WaylandXdgToplevel() noexcept { - if (window_ != nullptr) { - window_->Hide(); - window_->Destroy(); - } } void WaylandXdgToplevel::SetTitle(const char *title) { - pendingState_.title = title; } void WaylandXdgToplevel::Move(uint32_t serial) @@ -157,7 +151,6 @@ void WaylandXdgToplevel::Resize(uint32_t serial, uint32_t edges) void WaylandXdgToplevel::SetAppId(const char *appId) { - pendingState_.appId = appId; } void WaylandXdgToplevel::SetMaxSize(int32_t width, int32_t height) @@ -192,97 +185,13 @@ void WaylandXdgToplevel::SendConfigure() { struct wl_array states; wl_array_init(&states); - xdg_toplevel_send_configure(WlResource(), pendingState_.width, pendingState_.height, &states); + xdg_toplevel_send_configure(WlResource(), rect_.width, rect_.height, &states); wl_array_release(&states); } void WaylandXdgToplevel::HandleCommit() { - if (window_ == nullptr) { - CreateWindow(); - } SendConfigure(); } - -void WaylandXdgToplevel::HandleAttach(struct wl_shm_buffer *shm) -{ - if (rsSurface_ == nullptr) { - LOG_ERROR("rsSurface_ is nullptr"); - return; - } - - SkColorType format = ShmFormatToSkia(wl_shm_buffer_get_format(shm)); - if (format == SkColorType::kUnknown_SkColorType) { - LOG_ERROR("unsupported format %{public}d", wl_shm_buffer_get_format(shm)); - return; - } - - int32_t stride = wl_shm_buffer_get_stride(shm); - int32_t width = wl_shm_buffer_get_width(shm); - int32_t height = wl_shm_buffer_get_height(shm); - if (stride <= 0 || width <= 0 || height <= 0) { - LOG_ERROR("invalid, stride:%{public}d width:%{public}d height:%{public}d", stride, width, height); - return; - } - - void *data = wl_shm_buffer_get_data(shm); - if (data == nullptr) { - LOG_ERROR("wl_shm_buffer_get_data fail"); - return; - } - - auto framePtr = rsSurface_->RequestFrame(width, height); - if (framePtr == nullptr) { - LOG_ERROR("RequestFrame failed"); - return; - } - - auto canvas = framePtr->GetCanvas(); - if (canvas == nullptr) { - LOG_ERROR("GetCanvas failed"); - return; - } - canvas->clear(SK_ColorTRANSPARENT); - - SkImageInfo imageInfo = SkImageInfo::Make(width, height, format, kUnpremul_SkAlphaType); - SkPixmap srcPixmap(imageInfo, data, stride); - SkBitmap srcBitmap; - srcBitmap.installPixels(srcPixmap); - canvas->drawBitmap(srcBitmap, 0, 0); - rsSurface_->FlushFrame(framePtr); -} - -void WaylandXdgToplevel::CreateWindow() -{ - OHOS::sptr option(new OHOS::Rosen::WindowOption()); - option->SetWindowRect({0, 0, pendingState_.width, pendingState_.height}); - option->SetWindowType(OHOS::Rosen::WindowType::APP_MAIN_WINDOW_BASE); - option->SetWindowMode(OHOS::Rosen::WindowMode::WINDOW_MODE_FLOATING); - - window_ = OHOS::Rosen::Window::Create(pendingState_.appId, option); - if (window_ == nullptr) { - LOG_ERROR("Window::Create failed"); - return; - } - window_->Show(); - - surfaceNode_ = window_->GetSurfaceNode(); - if (surfaceNode_ == nullptr) { - LOG_ERROR("GetSurfaceNode failed"); - return; - } - - rsSurface_ = OHOS::Rosen::RSSurfaceExtractor::ExtractRSSurface(surfaceNode_); - if (rsSurface_ == nullptr) { - LOG_ERROR("ExtractRSSurface failed"); - return; - } - -#ifdef ENABLE_GPU - renderContext_ = std::make_unique(); - renderContext_->InitializeEglContext(); - rsSurface_->SetRenderContext(renderContext_.get()); -#endif -} } // namespace Wayland } // namespace FT diff --git a/wayland_adapter/framework/stable/wayland_xdg_toplevel.h b/wayland_adapter/framework/stable/wayland_xdg_toplevel.h index 02e7b40c36da1d7c3e95d50a7abc8bb3acc384f6..fa0f41766c0642b9097b37ce209fe62c8ad3d1ce 100644 --- a/wayland_adapter/framework/stable/wayland_xdg_toplevel.h +++ b/wayland_adapter/framework/stable/wayland_xdg_toplevel.h @@ -17,9 +17,6 @@ #include #include "wayland_xdg_surface.h" -#include "window.h" -#include "ui/rs_surface_node.h" -#include "render_context/render_context.h" namespace FT { namespace Wayland { @@ -61,21 +58,17 @@ public: void Resize(uint32_t serial, uint32_t edges); void SendConfigure(); void HandleCommit(); - void HandleAttach(struct wl_shm_buffer *shm); + void SetRect(Rect rect) + { + rect_ = rect; + } private: WaylandXdgToplevel(const OHOS::sptr &xdgSurface, uint32_t id); - void CreateWindow(); friend struct IWaylandXdgToplevel; OHOS::wptr xdgSurface_; - XdgSurfaceState pendingState_; -#ifdef ENABLE_GPU - std::unique_ptr renderContext_; -#endif - OHOS::sptr window_; - std::shared_ptr surfaceNode_; - std::shared_ptr rsSurface_; + Rect rect_; }; } // namespace Wayland } // namespace FT diff --git a/wayland_adapter/utils/include/xdg_surface_utils.h b/wayland_adapter/utils/include/wayalnd_utils.h similarity index 42% rename from wayland_adapter/utils/include/xdg_surface_utils.h rename to wayland_adapter/utils/include/wayalnd_utils.h index 85f23bf6d3a8bb7321d4715dabdf3d1655520cab..b84fda5ee08ef91e7a79df729cfe90583eb44a99 100644 --- a/wayland_adapter/utils/include/xdg_surface_utils.h +++ b/wayland_adapter/utils/include/wayalnd_utils.h @@ -22,19 +22,64 @@ namespace FT { namespace Wayland { -static constexpr uint32_t DEFAULT_WIDTH = 500; -static constexpr uint32_t DEFAULT_HEIGHT = 500; -struct XdgSurfaceState { - uint32_t width = DEFAULT_WIDTH; - uint32_t height = DEFAULT_HEIGHT; - std::string title; - std::string appId; +struct Rect { + int32_t x = 0; + int32_t y = 0; + uint32_t width = 0; + uint32_t height = 0; + void Reset() + { + x = 0; + y = 0; + width = 0; + height = 0; + } +}; + +using SurfaceCommitCallback = std::function; +using SurfaceRectCallback = std::function; + +struct SurfaceState { + struct wl_resource *buffer = nullptr; + Rect damage; + wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL; + int32_t scale = 0; + Rect damageBuffer; + int32_t offsetX = 0; + int32_t offsetY = 0; + void Reset() + { + buffer = nullptr; + damage.Reset(); + transform = WL_OUTPUT_TRANSFORM_NORMAL; + scale = 0; + damageBuffer.Reset(); + offsetX = 0; + offsetY = 0; + } }; -enum class XdgSurfaceRole : uint32_t { +enum class SurfaceRole : uint32_t { NONE = 0, - TOPLEVEL, - POPUP + XDG_TOPLEVEL, + 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)