Merge changes from topic '15921'
authorJan-Simon Moeller <jsmoeller@linuxfoundation.org>
Thu, 2 Aug 2018 16:14:39 +0000 (16:14 +0000)
committerGerrit Code Review <gerrit@automotivelinux.org>
Thu, 2 Aug 2018 16:14:39 +0000 (16:14 +0000)
* changes:
  Fix WM attach layers to different screen.
  Fix source rectangle changes every state change

12 files changed:
conf/setting.json [deleted file]
src/CMakeLists.txt
src/layers.cpp
src/layers.hpp
src/util.cpp
src/util.hpp
src/wayland_ivi_wm.cpp
src/wayland_ivi_wm.hpp
src/window_manager.cpp
src/window_manager.hpp
src/wm_config.cpp [deleted file]
src/wm_config.hpp [deleted file]

diff --git a/conf/setting.json b/conf/setting.json
deleted file mode 100644 (file)
index cfeb718..0000000
+++ /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
index ee398e0..42b81b7 100644 (file)
@@ -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
index b961157..bbe7c09 100644 (file)
@@ -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<int>(scaling * i.second.x + 0.5);
+        i.second.y = static_cast<int>(scaling * i.second.y + 0.5);
+        i.second.w = static_cast<int>(scaling * i.second.w + 0.5);
+        i.second.h = static_cast<int>(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()
index adfd733..f52886e 100644 (file)
@@ -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:
index 19d590e..672b089 100644 (file)
@@ -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<long>(to_width) * height() / width()) - 1);
+        set_right(left() + to_width - 1);
+    } else {
+        // scale to fit height
+        set_right(left() + (static_cast<long>(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<long>(orig_w / ratio + 0.5) - 1);
+    } else {
+        set_bottom(top() + orig_h - 1);
+        set_right(left() + static_cast<long>(orig_h * ratio + 0.5) - 1);
+    }
+}
+
index 78d2185..2f17845 100644 (file)
@@ -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
index 2a27d8c..8b04c64 100644 (file)
@@ -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)
 {
index d75caae..b515a06 100644 (file)
@@ -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<struct ivi_wm>
     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;
index 76b5939..aa42d82 100644 (file)
@@ -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<json_object *> WindowManager::api_get_display_info()
 {
-    // Check controller
-    if (!this->controller)
+    if (!this->display->ok())
     {
-        return Err<json_object *>("ivi_controller global not available");
+        return Err<json_object *>("Wayland compositor is not available");
     }
 
     // Set display info
@@ -478,6 +475,7 @@ result<json_object *> 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<json_object *>(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<double>(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<double>(dp_bg.height()) / css_bg.h;
+    this->layers.setupArea(c->scale);
+
     return 0;
 }
 
index 7f9a3b8..2358c5a 100644 (file)
@@ -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 <atomic>
 #include <memory>
@@ -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 (file)
index f91fedd..0000000
+++ /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 (file)
index 68051b4..0000000
+++ /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 <string>
-#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