// @copyright Copyright (c) 2022 Woven Alpha, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "view/flutter_view.h" #include #include #if defined(BUILD_BACKEND_WAYLAND_EGL) #include "backend/wayland_egl.h" #elif defined(BUILD_BACKEND_WAYLAND_VULKAN) #include "backend/wayland_vulkan.h" #endif #include "configuration/configuration.h" #include "engine.h" #ifdef ENABLE_PLUGIN_GSTREAMER_EGL #include "plugins/gstreamer_egl/gstreamer_egl.h" #endif #ifdef ENABLE_PLUGIN_COMP_SURF #include "view/compositor_surface.h" #endif #include "wayland/display.h" #include "wayland/window.h" FlutterView::FlutterView(Configuration::Config config, size_t index, const std::shared_ptr& display) : m_config(std::move(config)), m_index(index), m_wayland_display(display) #ifdef ENABLE_PLUGIN_TEXT_INPUT , m_text_input(std::make_shared()) #endif #ifdef ENABLE_PLUGIN_KEY_EVENT , m_key_event(std::make_shared()) #endif { /* Delete implementation */ } FlutterView::~FlutterView() = default; void FlutterView::Initialize() { } void FlutterView::RunTasks() { } // calc and output the FPS void FlutterView::DrawFps(long long end_time) { if (0 < m_fps.output) { m_fps.counter++; if (m_fps.period <= m_fps.counter) { auto fps_loop = (m_fps.counter * 1000) / (end_time - m_fps.pre_time); auto fps_redraw = (m_wayland_window->GetFpsCounter() * 1000) / (end_time - m_fps.pre_time); m_fps.counter = 0; m_fps.pre_time = end_time; if (0 < (m_fps.output & 0x01)) { if (0 < (m_fps.output & 0x01)) { spdlog::info("({}) FPS = {} {}", m_index, fps_loop, fps_redraw); } } } } } #ifdef ENABLE_PLUGIN_COMP_SURF size_t FlutterView::CreateSurface(void* h_module, const std::string& assets_path, const std::string& cache_folder, const std::string& misc_folder, CompositorSurface::PARAM_SURFACE_T type, CompositorSurface::PARAM_Z_ORDER_T z_order, CompositorSurface::PARAM_SYNC_T sync, int width, int height, int32_t x, int32_t y) { auto tStart = std::chrono::steady_clock::now(); auto index = static_cast(m_comp_surf.size()); m_comp_surf[index] = std::make_unique( index, m_wayland_display, m_wayland_window, h_module, assets_path, cache_folder, misc_folder, type, z_order, sync, width, height, x, y); m_comp_surf[index]->InitializePlugin(); auto tEnd = std::chrono::steady_clock::now(); auto tDiff = std::chrono::duration(tEnd - tStart).count(); spdlog::info("comp surf init: {}", static_cast(tDiff)); return static_cast(index); } void FlutterView::DisposeSurface(int64_t key) { m_comp_surf[key]->StopFrames(); m_comp_surf[key]->Dispose(m_comp_surf[key].get()); m_comp_surf[key].reset(); m_comp_surf.erase(key); } void* FlutterView::GetSurfaceContext(int64_t index) { void* res = nullptr; if (m_comp_surf.find(index) != m_comp_surf.end()) { res = m_comp_surf[index]->GetContext(); } return res; } #endif #ifdef ENABLE_PLUGIN_COMP_REGION void FlutterView::ClearRegion(const std::string& type) const { // A NULL wl_region causes the pending input/opaque region to be set to empty. if (type == "input") { wl_surface_set_input_region(m_wayland_window->GetBaseSurface(), nullptr); } else if (type == "opaque") { wl_surface_set_opaque_region(m_wayland_window->GetBaseSurface(), nullptr); } } void FlutterView::SetRegion( const std::string& type, const std::vector& regions) const { const auto compositor = m_wayland_display->GetCompositor(); const auto base_region = wl_compositor_create_region(compositor); for (auto const& region : regions) { SPDLOG_DEBUG("Set Region: type: {}, x: {}, y: {}, width: {}, height: {}", type, region.x, region.y, region.width, region.height); wl_region_add(base_region, region.x, region.y, region.width, region.height); } if (type == "input") { wl_surface_set_input_region(m_wayland_window->GetBaseSurface(), base_region); } else if (type == "opaque") { wl_surface_set_opaque_region(m_wayland_window->GetBaseSurface(), base_region); } // Setting the pending input/opaque region has copy semantics, // and the wl_region object can be destroyed immediately. wl_region_destroy(base_region); } #endif