From: Jan-Simon Moeller Date: Thu, 2 Aug 2018 16:14:39 +0000 (+0000) Subject: Merge changes from topic '15921' X-Git-Tag: flounder_5.99.3~4 X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=commitdiff_plain;h=a79b572a5f26d6ecdd97dff159c40bad330e1c4c;hp=40ec5ee486893ccb1d259c7980b077cb087494aa;p=apps%2Fagl-service-windowmanager-2017.git Merge changes from topic '15921' * changes: Fix WM attach layers to different screen. Fix source rectangle changes every state change --- diff --git a/conf/setting.json b/conf/setting.json deleted file mode 100644 index cfeb718..0000000 --- a/conf/setting.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "description": "Settings for window manager", - "settings" : - { - "scaling" : "aspect_fit", - "options@scaling" : "aspect_fit|display_fit|none" - } -} \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ee398e0..42b81b7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -36,7 +36,6 @@ add_library(${TARGETS_WM} MODULE layers.cpp wm_client.cpp wm_error.cpp - wm_config.cpp applist.cpp request.cpp) @@ -113,7 +112,6 @@ add_custom_command(TARGET ${TARGETS_WM} POST_BUILD COMMAND cp -f ${PROJECT_SOURCE_DIR}/layers.json ${PROJECT_BINARY_DIR}/package/root/etc COMMAND cp -f ${PROJECT_SOURCE_DIR}/src/db/old_roles.db ${PROJECT_BINARY_DIR}/package/root/etc COMMAND cp -f ${PROJECT_SOURCE_DIR}/src/db/areas.db ${PROJECT_BINARY_DIR}/package/root/etc - COMMAND cp -f ${PROJECT_SOURCE_DIR}/conf/setting.json ${PROJECT_BINARY_DIR}/package/root/etc ) add_custom_target(package DEPENDS ${PROJECT_BINARY_DIR}/package/root diff --git a/src/layers.cpp b/src/layers.cpp index b961157..bbe7c09 100644 --- a/src/layers.cpp +++ b/src/layers.cpp @@ -181,60 +181,29 @@ json layer_map::to_json() const return j; } -compositor::rect layer_map::getAreaSize(const std::string &area) -{ - return area2size[area]; -} - -const compositor::rect layer_map::getScaleDestRect( - int to_w, int to_h, const std::string &aspect_setting) +void layer_map::setupArea(double scaling) { compositor::rect rct; - rct.x = 0; - rct.y = 0; - rct.w = to_w; - rct.h = to_h; - HMI_NOTICE("wm:lm", - "Scaling:'%s'. Check 'fullscreen' is set.", aspect_setting.c_str()); - // Base is "fullscreen". Crash me if "fullscreen" is not set - compositor::rect base = this->area2size.at("fullscreen"); - HMI_DEBUG("wm:lm", "Output size, width: %d, height: %d / fullscreen width: %d, height: %d", - to_w, to_h, base.w, base.h); - // If full_rct.w or full_rct.h == 0, crash me on purpose - double scale_rate_w = double(to_w) / double(base.w); - double scale_rate_h = double(to_h) / double(base.h); - double scale; - if (scale_rate_h < scale_rate_w) - { - scale = scale_rate_h; - } - else - { - scale = scale_rate_w; - } - HMI_DEBUG("wm", "set scale: %5.2f", scale); - // Scaling - if (aspect_setting == "aspect_fit") - { - // offset - rct.x = (to_w - scale * base.w) / 2; - rct.y = (to_h - scale * base.h) / 2; + rct = this->area2size["normal.full"]; + this->area2size["normalfull"] = rct; + this->area2size["normal"] = rct; - // scaling - rct.w = base.w * scale; - rct.h = base.h * scale; - } - else if (aspect_setting == "display_fit") + for (auto &i : this->area2size) { - // offset is none - // scaling - rct.w = base.w * scale_rate_w; - rct.h = base.h * scale_rate_h; + i.second.x = static_cast(scaling * i.second.x + 0.5); + i.second.y = static_cast(scaling * i.second.y + 0.5); + i.second.w = static_cast(scaling * i.second.w + 0.5); + i.second.h = static_cast(scaling * i.second.h + 0.5); + + HMI_DEBUG("wm:lm", "area:%s size(after) : x:%d y:%d w:%d h:%d", + i.first.c_str(), i.second.x, i.second.y, i.second.w, i.second.h); } - HMI_DEBUG("wm:lm", "offset x: %d, y: %d", rct.x, rct.y); - HMI_DEBUG("wm:lm", "after scaling w: %d, h: %d", rct.w, rct.h); - return rct; +} + +compositor::rect layer_map::getAreaSize(const std::string &area) +{ + return area2size[area]; } int layer_map::loadAreaDb() diff --git a/src/layers.hpp b/src/layers.hpp index adfd733..f52886e 100644 --- a/src/layers.hpp +++ b/src/layers.hpp @@ -114,8 +114,8 @@ struct layer_map } json to_json() const; + void setupArea(double scaling); compositor::rect getAreaSize(const std::string &area); - const compositor::rect getScaleDestRect(int output_w, int output_h, const std::string &aspect_setting); int loadAreaDb(); private: diff --git a/src/util.cpp b/src/util.cpp index 19d590e..672b089 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -40,3 +40,56 @@ unique_fd::~unique_fd() close(this->fd); } } + +void rectangle::fit(unsigned long to_width, unsigned long to_height) +{ + // fit rect within (to_width x to_height) + + if (to_width <= width()) { + // scale to fit with + set_bottom(top() + (static_cast(to_width) * height() / width()) - 1); + set_right(left() + to_width - 1); + } else { + // scale to fit height + set_right(left() + (static_cast(to_height) * width () / height()) - 1); + set_bottom(top() + to_height - 1); + } +} + +void rectangle::center(unsigned long outer_w, unsigned long outer_h) +{ + long inner_w = width(); + long inner_h = height(); + + set_left((outer_w - inner_w) / 2); + set_right(left() + inner_w - 1); + set_top((outer_h - inner_h) / 2); + set_bottom(top() + inner_h - 1); +} + +void rectangle::set_aspect(double ratio) +{ + // aspect ratio is width:height (= width/height) + // e.g. Landscape of HD's ratio is 16:9 (= 1.777...) + // Portrait of HD's ratio is 9:16 (= 0.5625) + // + // width / height = ratio + // width * height = area + // + // width = sqrt(ratio * area) + // height = width / ratio + + long orig_w = width(); + long orig_h = height(); + + if (ratio >= 1) { + // width >= height + // try to keep width + set_right(left() + orig_w - 1); + set_bottom(top() + static_cast(orig_w / ratio + 0.5) - 1); + } else { + set_bottom(top() + orig_h - 1); + set_right(left() + static_cast(orig_h * ratio + 0.5) - 1); + } +} + diff --git a/src/util.hpp b/src/util.hpp index 78d2185..2f17845 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -109,4 +109,58 @@ struct unique_fd } }; +class rectangle +{ + public: + explicit rectangle(long wd, long ht) : _right(wd - 1), _bottom(ht - 1) {}; + + void set_left(long l) { + _left = l; + } + long left() const { return _left; }; + + void set_right(long r) { + _right = r; + } + long right() const { return _right; }; + + void set_top(long t) { + _top = t; + } + long top() const { return _top; }; + + void set_bottom(long b) { + _bottom = b; + } + long bottom() const { return _bottom; } + + long width() const { + if (is_valid()) + return 0; + else + return _right - _left + 1; + } + + long height() const { + if (is_valid()) + return 0; + else + return _bottom - _top + 1; + } + + void set_aspect(double ratio); + void fit(unsigned long to_width, unsigned long to_height); + void center(unsigned long outer_w, unsigned long outer_h); + + private: + bool is_valid() const { + return (_top > _bottom || _left > _right); + } + + long _left = 0; + long _top = 0; + long _right; + long _bottom; +}; + #endif // !WM_UTIL_HPP diff --git a/src/wayland_ivi_wm.cpp b/src/wayland_ivi_wm.cpp index 2a27d8c..8b04c64 100644 --- a/src/wayland_ivi_wm.cpp +++ b/src/wayland_ivi_wm.cpp @@ -435,11 +435,6 @@ void layer::set_visibility(uint32_t visibility) ivi_wm_set_layer_visibility(this->parent->proxy.get(), this->id, visibility); } -void layer::set_source_rectangle(int32_t x, int32_t y, int32_t width, int32_t height) -{ - ivi_wm_set_layer_source_rectangle(this->parent->proxy.get(), this->id, x, y, width, height); -} - void layer::set_destination_rectangle(int32_t x, int32_t y, int32_t width, int32_t height) { diff --git a/src/wayland_ivi_wm.hpp b/src/wayland_ivi_wm.hpp index d75caae..b515a06 100644 --- a/src/wayland_ivi_wm.hpp +++ b/src/wayland_ivi_wm.hpp @@ -197,7 +197,6 @@ struct layer : public controller_child // Requests void set_visibility(uint32_t visibility); - void set_source_rectangle(int32_t x, int32_t y, int32_t width, int32_t height); void set_destination_rectangle(int32_t x, int32_t y, int32_t width, int32_t height); void add_surface(uint32_t surface_id); @@ -257,6 +256,9 @@ struct controller : public wayland_proxy size output_size; // Display size[pixel] size physical_size; // Display size[mm] + // Scale for conversion CSS PX -> DP(Device Pixel) + double scale; + wm::controller_hooks *chooks; struct wl::display *display; diff --git a/src/window_manager.cpp b/src/window_manager.cpp index 76b5939..aa42d82 100644 --- a/src/window_manager.cpp +++ b/src/window_manager.cpp @@ -19,7 +19,6 @@ #include "window_manager.hpp" #include "json_helper.hpp" -#include "wm_config.hpp" #include "applist.hpp" extern "C" @@ -51,6 +50,7 @@ const char kKeyWidthPixel[] = "width_pixel"; const char kKeyHeightPixel[] = "height_pixel"; const char kKeyWidthMm[] = "width_mm"; const char kKeyHeightMm[] = "height_mm"; +const char kKeyScale[] = "scale"; const char kKeyIds[] = "ids"; static sd_event_source *g_timer_ev_src = nullptr; @@ -147,7 +147,6 @@ WindowManager::WindowManager(wl::display *d) int WindowManager::init() { - int ret; if (!this->display->ok()) { return -1; @@ -203,8 +202,7 @@ int WindowManager::init() // Third level objects this->display->roundtrip(); - ret = init_layers(); - return ret; + return init_layers(); } int WindowManager::dispatch_pending_events() @@ -463,10 +461,9 @@ void WindowManager::api_enddraw(char const *appid, char const *drawing_name) result WindowManager::api_get_display_info() { - // Check controller - if (!this->controller) + if (!this->display->ok()) { - return Err("ivi_controller global not available"); + return Err("Wayland compositor is not available"); } // Set display info @@ -478,6 +475,7 @@ result WindowManager::api_get_display_info() json_object_object_add(object, kKeyHeightPixel, json_object_new_int(o_size.h)); json_object_object_add(object, kKeyWidthMm, json_object_new_int(p_size.w)); json_object_object_add(object, kKeyHeightMm, json_object_new_int(p_size.h)); + json_object_object_add(object, kKeyScale, json_object_new_double(this->controller->scale)); return Ok(object); } @@ -659,27 +657,32 @@ int WindowManager::init_layers() return -1; } - WMConfig wm_config; - wm_config.loadConfigs(); - auto &c = this->controller; auto &o = this->outputs.front(); auto &s = c->screens.begin()->second; auto &layers = c->layers; - this->layers.loadAreaDb(); - const compositor::rect base = this->layers.getAreaSize("fullscreen"); - - const std::string aspect_setting = wm_config.getConfigAspect(); - const compositor::rect scale_rect = - this->layers.getScaleDestRect(o->width, o->height, aspect_setting); - // Write output dimensions to ivi controller... c->output_size = compositor::size{uint32_t(o->width), uint32_t(o->height)}; c->physical_size = compositor::size{uint32_t(o->physical_width), uint32_t(o->physical_height)}; + + HMI_DEBUG("wm", "SCALING: screen (%dx%d), physical (%dx%d)", + o->width, o->height, o->physical_width, o->physical_height); + + this->layers.loadAreaDb(); + + const compositor::rect css_bg = this->layers.getAreaSize("fullscreen"); + rectangle dp_bg(o->width, o->height); + + dp_bg.set_aspect(static_cast(css_bg.w) / css_bg.h); + dp_bg.fit(o->width, o->height); + dp_bg.center(o->width, o->height); + HMI_DEBUG("wm", "SCALING: CSS BG(%dx%d) -> DDP %dx%d,(%dx%d)", + css_bg.w, css_bg.h, dp_bg.left(), dp_bg.top(), dp_bg.width(), dp_bg.height()); + // Clear scene layers.clear(); @@ -689,11 +692,9 @@ int WindowManager::init_layers() // Quick and dirty setup of layers for (auto const &i : this->layers.mapping) { - c->layer_create(i.second.layer_id, scale_rect.w, scale_rect.h); + c->layer_create(i.second.layer_id, dp_bg.width(), dp_bg.height()); auto &l = layers[i.second.layer_id]; - l->set_source_rectangle(0, 0, base.w, base.h); - l->set_destination_rectangle( - scale_rect.x, scale_rect.y, scale_rect.w, scale_rect.h); + l->set_destination_rectangle(dp_bg.left(), dp_bg.top(), dp_bg.width(), dp_bg.height()); l->set_visibility(1); HMI_DEBUG("wm", "Setting up layer %s (%d) for surface role match \"%s\"", i.second.name.c_str(), i.second.layer_id, i.second.role.c_str()); @@ -704,6 +705,9 @@ int WindowManager::init_layers() this->layout_commit(); + c->scale = static_cast(dp_bg.height()) / css_bg.h; + this->layers.setupArea(c->scale); + return 0; } diff --git a/src/window_manager.hpp b/src/window_manager.hpp index 7f9a3b8..2358c5a 100644 --- a/src/window_manager.hpp +++ b/src/window_manager.hpp @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef WINDOW_MANAGER_HPP -#define WINDOW_MANAGER_HPP +#ifndef TMCAGLWM_APP_HPP +#define TMCAGLWM_APP_HPP #include #include @@ -65,6 +65,7 @@ extern const char kKeyWidthPixel[]; extern const char kKeyHeightPixel[]; extern const char kKeyWidthMm[]; extern const char kKeyHeightMm[]; +extern const char kKeyScale[]; extern const char kKeyIds[]; struct id_allocator @@ -283,4 +284,4 @@ class WindowManager } // namespace wm -#endif // WINDOW_MANAGER_HPP +#endif // TMCAGLWM_APP_HPP diff --git a/src/wm_config.cpp b/src/wm_config.cpp deleted file mode 100644 index f91fedd..0000000 --- a/src/wm_config.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2017 TOYOTA MOTOR CORPORATION - * - * 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 "../include/hmi-debug.h" -#include "json_helper.hpp" -#include "wm_config.hpp" - -using std::string; - -namespace wm -{ - -WMConfig::WMConfig(){} - -WMConfig::~WMConfig() -{ - json_object_put(j_setting_conf); -} - -WMError WMConfig::loadConfigs() -{ - WMError ret; - char const *pRoot = getenv("AFM_APP_INSTALL_DIR"); - string root_path = pRoot; - if (root_path.length() == 0) - { - HMI_ERROR("wm", "AFM_APP_INSTALL_DIR is not defined"); - } - ret = this->loadSetting(root_path); - - return ret; -} - -const string WMConfig::getConfigAspect() -{ - json_object *j; - string ret; - if (!json_object_object_get_ex(this->j_setting_conf, "settings", &j)) - { - ret = "aspect_fit"; - } - else - { - const char* scaling = jh::getStringFromJson(j, "scaling"); - if(scaling == nullptr) - { - ret = "aspect_fit"; - } - else - { - ret = scaling; - } - } - return ret; -} - -/* - ***** Private Functions ***** - */ - -WMError WMConfig::loadSetting(const string &path) -{ - string setting_path = path; - int iret = -1; - WMError ret = SUCCESS; - - if (setting_path.length() != 0) - { - setting_path = path + string("/etc/setting.json"); - iret = jh::inputJsonFilie(setting_path.c_str(), &this->j_setting_conf); - if (iret < 0) - ret = FAIL; - } - - return ret; -} - -} // namespace wm diff --git a/src/wm_config.hpp b/src/wm_config.hpp deleted file mode 100644 index 68051b4..0000000 --- a/src/wm_config.hpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2017 TOYOTA MOTOR CORPORATION - * - * 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. - */ - -#ifndef WM_CONFIG_HPP -#define WM_CONFIG_HPP -#include -#include "wm_error.hpp" - -struct json_object; - -namespace wm -{ - -class WMConfig { -public: - WMConfig(); - ~WMConfig(); - WMConfig(const WMConfig &) = delete; - WMConfig &operator=(const WMConfig &) = delete; - WMError loadConfigs(); - const std::string getConfigAspect(); - - private: - WMError loadSetting(const std::string &path); - // private variable - json_object *j_setting_conf; -}; - -} // namespace wm -#endif // WM_CONFIG_HPP \ No newline at end of file