pepper: Apply output transform and scale
authorTaekyun Kim <tkq.kim@samsung.com>
Tue, 10 Nov 2015 02:25:03 +0000 (11:25 +0900)
committerTaekyun Kim <tkq.kim@samsung.com>
Wed, 11 Nov 2015 05:25:54 +0000 (14:25 +0900)
Change-Id: I93afbd49c5d338f179aaa6f1951239527b23a669

15 files changed:
src/lib/drm/drm-output.c
src/lib/fbdev/fbdev-output.c
src/lib/pepper/Makefile.am
src/lib/pepper/misc.c [new file with mode: 0644]
src/lib/pepper/output.c
src/lib/pepper/pepper-internal.h
src/lib/pepper/pepper-output-backend.h
src/lib/pepper/plane.c
src/lib/pepper/view.c
src/lib/render/pixman-renderer.c
src/lib/wayland/wayland-output.c
src/lib/x11/pepper-x11.h
src/lib/x11/x11-internal.h
src/lib/x11/x11-output.c
src/samples/x11-backend.c

index 9a6292b..5e633b6 100644 (file)
@@ -648,7 +648,7 @@ drm_output_create(drm_connector_t *conn)
     output->mode = &conn->connector->modes[0];
 
     output->base = pepper_compositor_add_output(drm->compositor, &drm_output_backend,
-                                                conn->name, output);
+                                                conn->name, output, WL_OUTPUT_TRANSFORM_NORMAL, 1);
     PEPPER_CHECK(output->base, goto error, "pepper_compositor_add_output() failed.\n");
 
     if (render_env && strcmp(render_env, "gl") == 0)
index f259334..35e52d9 100644 (file)
@@ -402,7 +402,8 @@ pepper_fbdev_output_create(pepper_fbdev_t *fbdev, const char *renderer)
     }
 
     output->base = pepper_compositor_add_output(output->fbdev->compositor,
-                                                &fbdev_output_backend, "fbdev", output);
+                                                &fbdev_output_backend, "fbdev", output,
+                                                WL_OUTPUT_TRANSFORM_NORMAL, 1);
     if (!output->base)
     {
         PEPPER_ERROR("Failed to add output to compositor in %s\n", __FUNCTION__);
index 3084a0b..5ac27d3 100644 (file)
@@ -28,4 +28,5 @@ libpepper_la_SOURCES = pepper.h                 \
                        utils-log.c              \
                        utils-vt.c               \
                        subcompositor.c          \
-                       subsurface.c
+                       subsurface.c             \
+                       misc.c
diff --git a/src/lib/pepper/misc.c b/src/lib/pepper/misc.c
new file mode 100644 (file)
index 0000000..efaef39
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+* Copyright © 2008-2012 Kristian Høgsberg
+* Copyright © 2010-2012 Intel Corporation
+* Copyright © 2011 Benjamin Franzke
+* Copyright © 2012 Collabora, Ltd.
+* Copyright © 2015 S-Core Corporation
+* Copyright © 2015-2016 Samsung Electronics co., Ltd. All Rights Reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice (including the next
+* paragraph) shall be included in all copies or substantial portions of the
+* Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+* DEALINGS IN THE SOFTWARE.
+*/
+
+#include "pepper-internal.h"
+
+void
+pepper_pixman_region_global_to_output(pixman_region32_t *region, pepper_output_t *output)
+{
+    pixman_box32_t *box, b;
+    int             num_rects, i;
+    int32_t         scale = output->scale;
+    int32_t         w = output->geometry.w;
+    int32_t         h = output->geometry.h;
+
+    /* Transform into output geometry origin. */
+    pixman_region32_translate(region, output->geometry.x, output->geometry.y);
+
+    if (output->geometry.transform == WL_OUTPUT_TRANSFORM_NORMAL && scale == 1)
+        return;
+
+    box = pixman_region32_rectangles(region, &num_rects);
+
+    switch (output->geometry.transform)
+    {
+    case WL_OUTPUT_TRANSFORM_NORMAL:
+        break;
+    case WL_OUTPUT_TRANSFORM_90:
+        for (i = 0; i < num_rects; i++)
+        {
+            b.x1 = h - box[i].y2;
+            b.y1 = box[i].x1;
+            b.x2 = h - box[i].y1;
+            b.y2 = box[i].x2;
+
+            box[i] = b;
+        }
+        break;
+    case WL_OUTPUT_TRANSFORM_180:
+        for (i = 0; i < num_rects; i++)
+        {
+            b.x1 = w - box[i].x2;
+            b.y1 = h - box[i].y2;
+            b.x2 = w - box[i].x1;
+            b.y2 = h - box[i].y1;
+
+            box[i] = b;
+        }
+        break;
+    case WL_OUTPUT_TRANSFORM_270:
+        for (i = 0; i < num_rects; i++)
+        {
+            b.x1 = box[i].y1;
+            b.y1 = w - box[i].x2;
+            b.x2 = box[i].y2;
+            b.y2 = w - box[i].x1;
+
+            box[i] = b;
+        }
+        break;
+    case WL_OUTPUT_TRANSFORM_FLIPPED:
+        for (i = 0; i < num_rects; i++)
+        {
+            b.x1 = w - box[i].x2;
+            b.y1 = box[i].y1;
+            b.x2 = w - box[i].x1;
+            b.y2 = box[i].y2;
+
+            box[i] = b;
+        }
+        break;
+    case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+        for (i = 0; i < num_rects; i++)
+        {
+            b.x1 = h - box[i].y2;
+            b.y1 = w - box[i].x2;
+            b.x2 = h - box[i].y1;
+            b.y2 = w - box[i].x1;
+
+            box[i] = b;
+        }
+        break;
+    case WL_OUTPUT_TRANSFORM_FLIPPED_180:
+        for (i = 0; i < num_rects; i++)
+        {
+            b.x1 = box[i].x1;
+            b.y1 = h - box[i].y2;
+            b.x2 = box[i].x2;
+            b.y2 = h - box[i].y1;
+
+            box[i] = b;
+        }
+        break;
+    case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+        for (i = 0; i < num_rects; i++)
+        {
+            b.x1 = box[i].y1;
+            b.y1 = box[i].x1;
+            b.x2 = box[i].y2;
+            b.y2 = box[i].x2;
+
+            box[i] = b;
+        }
+        break;
+    }
+
+    if (scale != 1)
+    {
+        for (i = 0; i < num_rects; i++)
+        {
+            box[i].x1 *= scale;
+            box[i].y1 *= scale;
+            box[i].x2 *= scale;
+            box[i].y2 *= scale;
+        }
+    }
+}
+
+/* Calculate a matrix which transforms vertices into the output local space,
+ * so that output backends can simply use the matrix to transform a view
+ * into the frame buffer space.
+ *
+ * view space -> global space -> output space
+ *
+ * global to output space.
+ *
+ * 1. Translate to output geometry origin. (denote T)
+ * 2. Apply output transform. (denote X)
+ * 3. Apply output scale. (denote S)
+ *
+ * P' = S * X * T * G * P
+ *
+ * Given a global matrix G, we should calculate matrix M where
+ * M = S * X * T * G
+ *
+ * S can be represented as a single scale term.
+ * X can be represented using 6 values (a, b, c, d, e, f) where
+ *   x' = a * x + b * y + e;
+ *   y' = c * x + b * y + f;
+ * T can be represented using 2 translation term (x, y)
+ */
+static inline void
+make_output_transform(pepper_mat4_t *mat,
+                      double s, /* scale */
+                      double a, double b, double c, double d, double e, double f, /* transform */
+                      double x, double y /* translate */)
+{
+    double *m = &mat->m[0];
+
+    m[ 0] = s * a;
+    m[ 1] = s * c;
+    m[ 4] = s * b;
+    m[ 5] = s * d;
+    m[12] = s * (a * x + b * y + e);
+    m[13] = s * (c * x + d * y + f);
+
+    if (s != 1.0)
+        mat->flags |= PEPPER_MATRIX_SCALE;
+
+    if (x != 0.0 || y != 0.0)
+        mat->flags |= PEPPER_MATRIX_TRANSLATE;
+
+    if (a != 1.0 || d != 1.0)
+        mat->flags |= PEPPER_MATRIX_ROTATE;
+}
+
+void
+pepper_transform_global_to_output(pepper_mat4_t *transform, pepper_output_t *output)
+{
+    pepper_mat4_t   mat;
+    double          x = output->geometry.x;
+    double          y = output->geometry.y;
+    double          w = output->geometry.w;
+    double          h = output->geometry.h;
+
+    pepper_mat4_init_identity(&mat);
+
+    switch (output->geometry.transform)
+    {
+    default:
+    case WL_OUTPUT_TRANSFORM_NORMAL:
+        make_output_transform(&mat, (double)output->scale, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, x, y);
+        break;
+    case WL_OUTPUT_TRANSFORM_FLIPPED:
+        make_output_transform(&mat, (double)output->scale, -1.0, 0.0, 0.0, 1.0, w, 0.0, x, y);
+        break;
+    case WL_OUTPUT_TRANSFORM_90:
+        make_output_transform(&mat, (double)output->scale, 0.0, -1.0, 1.0, 0.0, h, 0.0, x, y);
+        break;
+    case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+        make_output_transform(&mat, (double)output->scale, 0.0, -1.0, -1.0, 0.0, h, w, x, y);
+        break;
+    case WL_OUTPUT_TRANSFORM_180:
+        make_output_transform(&mat, (double)output->scale, -1.0, 0.0, 0.0, -1.0, w, h, x, y);
+        break;
+    case WL_OUTPUT_TRANSFORM_FLIPPED_180:
+        make_output_transform(&mat, (double)output->scale, 1.0, 0.0, 0.0, -1.0, 0.0, h, x, y);
+        break;
+    case WL_OUTPUT_TRANSFORM_270:
+        make_output_transform(&mat, (double)output->scale, 0.0, 1.0, -1.0, 0.0, 0.0,  w, x, y);
+        break;
+    case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+        make_output_transform(&mat, (double)output->scale, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, x, y);
+        break;
+    }
+
+    pepper_mat4_multiply(transform, &mat, transform);
+}
index 77d37ba..b300b39 100644 (file)
@@ -123,7 +123,7 @@ output_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
 }
 
 static void
-output_accumulate_damage(pepper_output_t *output)
+output_update_planes(pepper_output_t *output)
 {
     pepper_plane_t     *plane;
     pixman_region32_t   clip;
@@ -131,7 +131,7 @@ output_accumulate_damage(pepper_output_t *output)
     pixman_region32_init(&clip);
 
     pepper_list_for_each_reverse(plane, &output->plane_list, link)
-        pepper_plane_accumulate_damage(plane, &clip);
+        pepper_plane_update(plane, &output->view_list, &clip);
 
     pixman_region32_fini(&clip);
 }
@@ -140,7 +140,6 @@ static void
 output_repaint(pepper_output_t *output)
 {
     pepper_view_t  *view;
-    pepper_plane_t *plane;
 
     pepper_list_for_each(view, &output->compositor->view_list, compositor_link)
         pepper_view_update(view);
@@ -161,11 +160,7 @@ output_repaint(pepper_output_t *output)
     }
 
     output->backend->assign_planes(output->data, &output->view_list);
-
-    pepper_list_for_each(plane, &output->plane_list, link)
-        pepper_plane_update(plane, &output->view_list);
-
-    output_accumulate_damage(output);
+    output_update_planes(output);
     output->backend->repaint(output->data, &output->plane_list);
 
     output->frame.pending = PEPPER_TRUE;
@@ -272,7 +267,8 @@ pepper_output_update_mode(pepper_output_t *output)
 
 PEPPER_API pepper_output_t *
 pepper_compositor_add_output(pepper_compositor_t *compositor,
-                             const pepper_output_backend_t *backend, const char *name, void *data)
+                             const pepper_output_backend_t *backend, const char *name, void *data,
+                             int transform, int scale)
 {
     pepper_output_t    *output;
     uint32_t            id;
@@ -318,18 +314,29 @@ pepper_compositor_add_output(pepper_compositor_t *compositor,
     /* Initialize output modes. */
     output_update_mode(output);
 
-    /* TODO: Set scale value according to the config or something. */
-    output->scale = 1;
-
-    /* Initialize geometry. TODO: Calculate position and size of the output. */
-    output->geometry.transform = WL_OUTPUT_TRANSFORM_NORMAL;
+    /* Initialize geometry. */
+    output->geometry.transform = transform;
+    output->scale = scale;
     output->geometry.subpixel = backend->get_subpixel_order(data);
     output->geometry.maker = backend->get_maker_name(data);
     output->geometry.model = backend->get_model_name(data);
     output->geometry.x = 0;
     output->geometry.y = 0;
-    output->geometry.w = output->current_mode.w;
-    output->geometry.h = output->current_mode.h;
+
+    switch (transform)
+    {
+    case WL_OUTPUT_TRANSFORM_90:
+    case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+    case WL_OUTPUT_TRANSFORM_270:
+    case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+        output->geometry.w = output->current_mode.h / scale;
+        output->geometry.h = output->current_mode.w / scale;
+        break;
+    default:
+        output->geometry.w = output->current_mode.w / scale;
+        output->geometry.h = output->current_mode.h / scale;
+        break;
+    }
 
     pepper_list_insert(&compositor->output_list, &output->link);
     pepper_list_init(&output->plane_list);
index 603e566..f404842 100644 (file)
@@ -483,6 +483,7 @@ struct pepper_plane_entry
 
     pepper_plane_t             *plane;
     pepper_bool_t               need_damage;
+    pepper_bool_t               need_transform_update;
 
     pepper_list_t               link;
 };
@@ -566,12 +567,16 @@ void
 pepper_plane_add_damage_region(pepper_plane_t *plane, pixman_region32_t *region);
 
 void
-pepper_plane_accumulate_damage(pepper_plane_t *plane, pixman_region32_t *clip);
+pepper_plane_update(pepper_plane_t *plane, const pepper_list_t *view_list, pixman_region32_t *clip);
 
 void
-pepper_plane_update(pepper_plane_t *plane, const pepper_list_t *view_list);
+pepper_surface_flush_damage(pepper_surface_t *surface);
 
+/* Misc. */
 void
-pepper_surface_flush_damage(pepper_surface_t *surface);
+pepper_pixman_region_global_to_output(pixman_region32_t *region, pepper_output_t *output);
+
+void
+pepper_transform_global_to_output(pepper_mat4_t *transform, pepper_output_t *output);
 
 #endif /* PEPPER_INTERNAL_H */
index c6f0118..6abc4e2 100644 (file)
@@ -60,7 +60,8 @@ struct pepper_output_backend
 
 PEPPER_API pepper_output_t *
 pepper_compositor_add_output(pepper_compositor_t *compositor,
-                             const pepper_output_backend_t *backend, const char *name, void *data);
+                             const pepper_output_backend_t *backend, const char *name, void *data,
+                             int transform, int scale);
 
 struct pepper_render_item
 {
index 40ba5e8..a274ddb 100644 (file)
 #include "pepper-internal.h"
 
 void
-pepper_plane_update(pepper_plane_t *plane, const pepper_list_t *view_list)
+pepper_plane_update(pepper_plane_t *plane, const pepper_list_t *view_list, pixman_region32_t *clip)
 {
-    pepper_view_t  *view;
-    double          output_x = plane->output->geometry.x;
-    double          output_y = plane->output->geometry.y;
+    int                 x = plane->output->geometry.x;
+    int                 y = plane->output->geometry.y;
+    int                 w = plane->output->geometry.w;
+    int                 h = plane->output->geometry.h;
+    pixman_region32_t   plane_clip;
+    pepper_view_t      *view;
 
+    pixman_region32_init(&plane_clip);
     pepper_list_init(&plane->entry_list);
 
     pepper_list_for_each(view, view_list, link)
     {
-        pepper_plane_entry_t   *entry = &view->plane_entries[plane->output->id];
+        pepper_plane_entry_t *entry = &view->plane_entries[plane->output->id];
 
         if (entry->plane == plane)
         {
             pepper_list_insert(plane->entry_list.prev, &entry->link);
 
-            /* Calculate view transform on output local coordinate space. */
-            pepper_mat4_init_translate(&entry->base.transform, -output_x, -output_y, 0.0);
-            pepper_mat4_multiply(&entry->base.transform,
-                                 &entry->base.transform, &view->global_transform);
-        }
-    }
-}
-
-void
-pepper_plane_accumulate_damage(pepper_plane_t *plane, pixman_region32_t *clip)
-{
-    int                     x = plane->output->geometry.x;
-    int                     y = plane->output->geometry.y;
-    int                     w = plane->output->geometry.w;
-    int                     h = plane->output->geometry.h;
-    pepper_plane_entry_t   *entry;
-    pixman_region32_t       plane_clip;
-
-    pixman_region32_init(&plane_clip);
-
-    pepper_list_for_each(entry, &plane->entry_list, link)
-    {
-        pepper_view_t *view = (pepper_view_t *)entry->base.view;
-
-        pixman_region32_subtract(&entry->base.visible_region, &view->bounding_region, &plane_clip);
-        pixman_region32_translate(&entry->base.visible_region, -x, -y);
-        pixman_region32_intersect_rect(&entry->base.visible_region,
-                                       &entry->base.visible_region, 0, 0, w, h);
-
-        /* Accumulate opaque region of this plane on plane_clip. */
-        pixman_region32_union(&plane_clip, &plane_clip, &view->opaque_region);
-
-        if (entry->need_damage)
-        {
-            pepper_plane_add_damage_region(plane, &entry->base.visible_region);
-            entry->need_damage = PEPPER_FALSE;
+            if (entry->need_transform_update)
+            {
+                entry->base.transform = view->global_transform;
+                pepper_transform_global_to_output(&entry->base.transform, plane->output);
+                entry->need_transform_update = PEPPER_FALSE;
+            }
+
+            /* Calculate visible region (output space). */
+            pixman_region32_subtract(&entry->base.visible_region,
+                                     &view->bounding_region, &plane_clip);
+            pixman_region32_intersect_rect(&entry->base.visible_region,
+                                           &entry->base.visible_region, x, y, w, h);
+            pepper_pixman_region_global_to_output(&entry->base.visible_region, plane->output);
+
+            /* Accumulate opaque region of this view (global space). */
+            pixman_region32_union(&plane_clip, &plane_clip, &view->opaque_region);
+
+            /* Add damage for the new visible region. */
+            if (entry->need_damage)
+            {
+                pepper_plane_add_damage_region(plane, &entry->base.visible_region);
+                entry->need_damage = PEPPER_FALSE;
+            }
+
+            /* Flush surface damage. (eg. texture upload) */
+            if (view->surface)
+                pepper_surface_flush_damage(view->surface);
         }
-
-        if (view->surface)
-            pepper_surface_flush_damage(view->surface);
     }
 
-    /* Transform plane_clip to output local coordinate space. */
-    pixman_region32_translate(&plane_clip, -x, -y);
-    pixman_region32_intersect_rect(&plane_clip, &plane_clip, 0, 0, w, h);
-
-    /* Copy accumulated clip region obsecured by opaque regions of views in front of this plane. */
+    /* Copy clip region of this plane. */
     pixman_region32_copy(&plane->clip_region, clip);
 
-    /* Accumulate clip region for the below plane. */
+    /* Accumulate clip region obsecured by this plane. */
+    pepper_pixman_region_global_to_output(&plane_clip, plane->output);
     pixman_region32_union(clip, clip, &plane_clip);
     pixman_region32_fini(&plane_clip);
 }
index bc99373..cdd7a4e 100644 (file)
@@ -32,7 +32,8 @@
 void
 pepper_view_mark_dirty(pepper_view_t *view, uint32_t flag)
 {
-    pepper_view_t *child;
+    pepper_view_t  *child;
+    int             i;
 
     if (view->dirty & flag)
         return;
@@ -44,6 +45,9 @@ pepper_view_mark_dirty(pepper_view_t *view, uint32_t flag)
     {
         pepper_list_for_each(child, &view->children_list, parent_link)
             pepper_view_mark_dirty(child, PEPPER_VIEW_GEOMETRY_DIRTY);
+
+        for (i = 0; i < PEPPER_MAX_OUTPUT_COUNT; i++)
+            view->plane_entries[i].need_transform_update = PEPPER_TRUE;
     }
 
     /* Mark entire subtree's active as dirty. */
index 1885a23..8126b46 100644 (file)
@@ -305,8 +305,8 @@ repaint_view(pepper_renderer_t *renderer, pepper_render_item_t *node, pixman_reg
         }
         else
         {
-            pepper_mat4_inverse(&node->transform, &node->transform);    /* FIXME */
             pixman_transform_from_pepper_mat4(&trans, &node->transform);
+            pixman_transform_invert(&trans, &trans);
             filter = PIXMAN_FILTER_BILINEAR;
         }
 
index c46b411..2479f64 100644 (file)
@@ -379,7 +379,7 @@ pepper_wayland_output_create(pepper_wayland_t *conn, int32_t w, int32_t h, const
 
     /* Add compositor base class output object for this output. */
     output->base = pepper_compositor_add_output(conn->pepper, &wayland_output_backend,
-                                                output->name, output);
+                                                output->name, output, WL_OUTPUT_TRANSFORM_NORMAL, 1);
     if (!output->base)
     {
         wayland_output_destroy(output);
index ef711c5..ee91809 100644 (file)
@@ -44,7 +44,8 @@ PEPPER_API void
 pepper_x11_destroy(pepper_x11_connection_t *conn);
 
 PEPPER_API pepper_output_t *
-pepper_x11_output_create(pepper_x11_connection_t *connection, int32_t w, int32_t h,
+pepper_x11_output_create(pepper_x11_connection_t *connection,
+                         int x, int y, int w, int h, int transform, int scale,
                          const char *renderer);
 
 PEPPER_API pepper_bool_t
index 191387b..5014b31 100644 (file)
@@ -70,7 +70,6 @@ struct x11_output
     int32_t                  x, y;
     int32_t                  w, h;
     uint32_t                 subpixel;
-    uint32_t                 scale;
     uint8_t                  depth;
     uint8_t                  bpp;
 
index c71a730..73fac37 100644 (file)
@@ -409,8 +409,8 @@ x11_output_set_mode(void *o, const pepper_output_mode_t *mode)
             /* set hints for window */
             memset(&hints, 0, sizeof(hints));
             hints.flags = WM_NORMAL_HINTS_MAX_SIZE | WM_NORMAL_HINTS_MIN_SIZE;
-            hints.min_width  = hints.max_width  = output->w*output->scale;
-            hints.min_height = hints.max_height = output->h*output->scale;
+            hints.min_width  = hints.max_width  = output->w;
+            hints.min_height = hints.max_height = output->h;
             xcb_change_property(conn,
                                 XCB_PROP_MODE_REPLACE,
                                 output->window,
@@ -500,8 +500,8 @@ x11_output_repaint(void *o, const pepper_list_t *plane_list)
                 cookie = xcb_shm_put_image_checked(output->connection->xcb_connection,
                                                    output->window,
                                                    output->gc,
-                                                   output->w * output->scale,   /* total_width  */
-                                                   output->h * output->scale,   /* total_height */
+                                                   output->w,
+                                                   output->h,
                                                    0,   /* src_x */
                                                    0,   /* src_y */
                                                    output->shm.w,  /* src_w */
@@ -564,8 +564,7 @@ static const pepper_output_backend_t x11_output_backend =
 
 PEPPER_API pepper_output_t *
 pepper_x11_output_create(pepper_x11_connection_t *connection,
-                         int32_t w,
-                         int32_t h,
+                         int w, int h, int transform, int scale,
                          const char *renderer)
 {
     static const char       *window_name = "PePPer Compositor";
@@ -591,9 +590,6 @@ pepper_x11_output_create(pepper_x11_connection_t *connection,
     /* Hard-Coded: subpixel order to horizontal RGB. */
     output->subpixel = WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB;
 
-    /* Hard-Coded: scale value to 1. */
-    output->scale = 1;
-
     /* Create X11 window */
     {
         uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
@@ -609,11 +605,7 @@ pepper_x11_output_create(pepper_x11_connection_t *connection,
                           XCB_COPY_FROM_PARENT,
                           output->window,
                           connection->screen->root,
-                          0,    /* X position of top-left corner of window */
-                          0,    /* Y position of top-left corner of window */
-                          w*output->scale,
-                          h*output->scale,
-                          0,    /* width of windows' border */
+                          0, 0, w, h, 0,
                           XCB_WINDOW_CLASS_INPUT_OUTPUT,
                           connection->screen->root_visual,
                           mask,
@@ -622,8 +614,8 @@ pepper_x11_output_create(pepper_x11_connection_t *connection,
         /* cannot resize */
         memset(&hints, 0, sizeof(hints));
         hints.flags = WM_NORMAL_HINTS_MAX_SIZE | WM_NORMAL_HINTS_MIN_SIZE;
-        hints.min_width  = hints.max_width  = w*output->scale;
-        hints.min_height = hints.max_height = h*output->scale;
+        hints.min_width  = hints.max_width  = w;
+        hints.min_height = hints.max_height = h;
         xcb_change_property(connection->xcb_connection,
                             XCB_PROP_MODE_REPLACE,
                             output->window,
@@ -675,7 +667,8 @@ pepper_x11_output_create(pepper_x11_connection_t *connection,
     /* Register output object */
     snprintf(&output->name[0], 32, "x11-%p", output);
     base = pepper_compositor_add_output(connection->compositor,
-                                        &x11_output_backend, output->name, output);
+                                        &x11_output_backend, output->name, output,
+                                        transform, scale);
     if (!base)
     {
         PEPPER_ERROR("pepper_compositor_add_output failed\n");
index 7563a32..3eed2ee 100644 (file)
@@ -65,7 +65,8 @@ main(int argc, char **argv)
     conn = pepper_x11_connect(compositor, NULL);
     PEPPER_ASSERT(conn);
 
-    output = pepper_x11_output_create(conn, 1024, 768, renderer);
+    output = pepper_x11_output_create(conn, 0, 0, 1024, 768,
+                                      WL_OUTPUT_TRANSFORM_90, 1, renderer);
     PEPPER_ASSERT(output);
 
     if (!pepper_x11_input_create(conn))