Improve output of multiple screen resolution 29/15929/1
authorTadao Tanikawa <tanikawa.tadao@jp.panasonic.com>
Wed, 1 Aug 2018 06:43:02 +0000 (06:43 +0000)
committerTadao Tanikawa <tanikawa.tadao@jp.panasonic.com>
Thu, 2 Aug 2018 07:24:34 +0000 (07:24 +0000)
To improve output on various monitor with various resolution,
the following items are introduced.

 * Abandon scaling by Weston/IVI-SHELL
   This is cause of huge memory consumption on AGL CES2018 Demo
   because all contents are designed and rendered with FullHD
   resolution.

 * Add parameter of 'scale' to WM API (getDisplayInfo)
   WM calculate scale factor from screen resolution from wayland
   compositor and parameter of layout from WM's configuration,
   area.db.

Bug-AGL: SPEC-1568, SPEC-1569, SPEC-1611

Change-Id: I5eac2da0106228c296550135c5200b2653864fdf
Signed-off-by: Tadao Tanikawa <tanikawa.tadao@jp.panasonic.com>
src/layers.cpp
src/layers.hpp
src/util.cpp
src/util.hpp
src/wayland_ivi_wm.hpp
src/window_manager.cpp
src/window_manager.hpp

index f73daf2..bbe7c09 100644 (file)
@@ -181,7 +181,7 @@ json layer_map::to_json() const
     return j;
 }
 
-void layer_map::setupArea(int output_w, int output_h)
+void layer_map::setupArea(double scaling)
 {
     compositor::rect rct;
 
@@ -191,6 +191,11 @@ void layer_map::setupArea(int output_w, int output_h)
 
     for (auto &i : this->area2size)
     {
+        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);
     }
index b6dd67f..f52886e 100644 (file)
@@ -114,7 +114,7 @@ struct layer_map
     }
 
     json to_json() const;
-    void setupArea(int output_w, int output_h);
+    void setupArea(double scaling);
     compositor::rect getAreaSize(const std::string &area);
     int loadAreaDb();
 
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 9d0c7a7..a430927 100644 (file)
@@ -256,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 862341a..c44210f 100644 (file)
@@ -50,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;
@@ -460,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
@@ -475,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);
 }
@@ -665,6 +666,21 @@ int WindowManager::init_layers()
     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();
 
@@ -674,9 +690,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, o->width, o->height);
+        c->layer_create(i.second.layer_id, dp_bg.width(), dp_bg.height());
         auto &l = layers[i.second.layer_id];
-        l->set_destination_rectangle(0, 0, o->width, o->height);
+        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());
@@ -687,8 +703,8 @@ int WindowManager::init_layers()
 
     this->layout_commit();
 
-    this->layers.loadAreaDb();
-    this->layers.setupArea(o->width, o->height);
+    c->scale = static_cast<double>(dp_bg.height()) / css_bg.h;
+    this->layers.setupArea(c->scale);
 
     return 0;
 }
index ebdf495..2358c5a 100644 (file)
@@ -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