e_plane_renderer: support hw cursor in rotation environment 76/157776/3
authorChangyeon Lee <cyeon.lee@samsung.com>
Thu, 26 Oct 2017 04:42:12 +0000 (13:42 +0900)
committerBoram Park <boram1288.park@samsung.com>
Mon, 30 Oct 2017 03:52:20 +0000 (03:52 +0000)
Change-Id: Ic59edc0fcdd945bf7e2d082101fc5c4f0830dccc

src/bin/e_plane.c
src/bin/e_plane_renderer.c
src/bin/e_plane_renderer.h
src/bin/e_pointer.c

index 3985289..0ab830f 100644 (file)
@@ -470,15 +470,10 @@ _e_plane_cursor_surface_acquire(E_Plane *plane)
 
    e_comp_object_hwc_update_set(ec->frame, EINA_FALSE);
 
-   tsurface = e_plane_renderer_cursor_surface_get(renderer);
-
-   if (plane->display_info.buffer_ref.buffer != buffer || !tsurface)
+   if (!e_plane_renderer_cursor_surface_refresh(renderer, ec))
      {
-        if (!e_plane_renderer_cursor_surface_refresh(renderer, ec))
-          {
-             ERR("Failed to e_plane_renderer_cursor_surface_refresh");
-             return NULL;
-          }
+        ERR("Failed to e_plane_renderer_cursor_surface_refresh");
+        return NULL;
      }
 
    tsurface = e_plane_renderer_cursor_surface_get(renderer);
index 81d7ddc..641741f 100644 (file)
@@ -10,6 +10,7 @@
 # include <Evas_Engine_GL_Tbm.h>
 # include <Evas_Engine_Software_Tbm.h>
 # include <sys/eventfd.h>
+# include <pixman.h>
 # if HAVE_LIBGOMP
 # include <omp.h>
 # endif
@@ -1027,20 +1028,91 @@ e_plane_renderer_new(E_Plane *plane)
    return renderer;
 }
 
+static void
+_e_plane_renderer_cursor_image_draw(E_Comp_Wl_Buffer *buffer, tbm_surface_info_s *tsurface_info, int rotation)
+{
+   int src_width, src_height, src_stride;
+   pixman_image_t *src_img = NULL, *dst_img = NULL;
+   pixman_transform_t t;
+   struct pixman_f_transform ft;
+   void *src_ptr = NULL, *dst_ptr = NULL;
+   int c = 0, s = 0, tx = 0, ty = 0;
+   int i, rotate;
+
+   src_width = wl_shm_buffer_get_width(buffer->shm_buffer);
+   src_height = wl_shm_buffer_get_height(buffer->shm_buffer);
+   src_stride = wl_shm_buffer_get_stride(buffer->shm_buffer);
+   src_ptr = wl_shm_buffer_get_data(buffer->shm_buffer);
+
+   dst_ptr = tsurface_info->planes[0].ptr;
+   memset(dst_ptr, 0, tsurface_info->planes[0].stride * tsurface_info->height);
+
+   if (rotation)
+     {
+        src_img = pixman_image_create_bits(PIXMAN_a8r8g8b8, src_width, src_height, (uint32_t*)src_ptr, src_stride);
+        EINA_SAFETY_ON_NULL_GOTO(src_img, error);
+
+        dst_img = pixman_image_create_bits(PIXMAN_a8r8g8b8, tsurface_info->width, tsurface_info->height,
+                                          (uint32_t*)dst_ptr, tsurface_info->planes[0].stride);
+        EINA_SAFETY_ON_NULL_GOTO(dst_img, error);
+
+        if (rotation == 90)
+           rotation = 270;
+        else if (rotation == 270)
+           rotation = 90;
+
+        rotate = (rotation + 360) / 90 % 4;
+        switch (rotate)
+          {
+           case 1:
+              c = 0, s = -1, tx = -tsurface_info->width;
+              break;
+           case 2:
+              c = -1, s = 0, tx = -tsurface_info->width, ty = -tsurface_info->height;
+              break;
+           case 3:
+              c = 0, s = 1, ty = -tsurface_info->width;
+              break;
+          }
+
+        pixman_f_transform_init_identity(&ft);
+        pixman_f_transform_translate(&ft, NULL, tx, ty);
+        pixman_f_transform_rotate(&ft, NULL, c, s);
+
+        pixman_transform_from_pixman_f_transform(&t, &ft);
+        pixman_image_set_transform(src_img, &t);
+
+        pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img, 0, 0, 0, 0, 0, 0,
+                               tsurface_info->width, tsurface_info->height);
+     }
+   else
+     {
+        for (i = 0 ; i < src_height ; i++)
+          {
+             memcpy(dst_ptr, src_ptr, src_stride);
+             dst_ptr += tsurface_info->planes[0].stride;
+             src_ptr += src_stride;
+          }
+     }
+
+error:
+   if (src_img) pixman_image_unref(src_img);
+   if (dst_img) pixman_image_unref(dst_img);
+}
+
 EINTERN Eina_Bool
 e_plane_renderer_cursor_surface_refresh(E_Plane_Renderer *renderer, E_Client *ec)
 {
    E_Plane *plane = NULL;
    E_Output *output = NULL;
-   int i = 0;
-   int stride, height, w, h;
+   int w, h, tw, th;
    int tsurface_w, tsurface_h;
    void *src_ptr = NULL;
-   void *dst_ptr = NULL;
    tbm_surface_h tsurface = NULL;
    E_Comp_Wl_Buffer *buffer = NULL;
    tbm_surface_error_e ret = TBM_SURFACE_ERROR_NONE;
    tbm_surface_info_s tsurface_info;
+   E_Pointer *pointer = NULL;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(renderer, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
@@ -1054,6 +1126,14 @@ e_plane_renderer_cursor_surface_refresh(E_Plane_Renderer *renderer, E_Client *ec
    buffer = ec->comp_data->buffer_ref.buffer;
    EINA_SAFETY_ON_NULL_RETURN_VAL(buffer, EINA_FALSE);
 
+   pointer = e_pointer_get(ec);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(pointer, EINA_FALSE);
+
+   if ((plane->display_info.buffer_ref.buffer == buffer) &&
+       (renderer->cursor_tsurface) &&
+       (renderer->cursor_rotation == pointer->rotation))
+     return EINA_TRUE;
+
    /* TODO: TBM TYPE, NATIVE_WL */
    if (buffer->type == E_COMP_WL_BUFFER_TYPE_SHM)
      {
@@ -1070,8 +1150,19 @@ e_plane_renderer_cursor_surface_refresh(E_Plane_Renderer *renderer, E_Client *ec
         return EINA_FALSE;
      }
 
-   w = (output->cursor_available.min_w > ec->w) ? output->cursor_available.min_w : ec->w;
-   h = (output->cursor_available.min_h > ec->h) ? output->cursor_available.min_h : ec->h;
+   if (pointer->rotation == 90)
+      tw = ec->h, th = ec->w;
+   else if (pointer->rotation == 180)
+      tw = ec->w, th = ec->h;
+   else if (pointer->rotation == 270)
+      tw = ec->h, th = ec->w;
+   else
+      tw = ec->w, th = ec->h;
+
+   renderer->cursor_rotation = pointer->rotation;
+
+   w = (output->cursor_available.min_w > tw) ? output->cursor_available.min_w : tw;
+   h = (output->cursor_available.min_h > th) ? output->cursor_available.min_h : th;
 
    if (e_comp->hwc_reuse_cursor_buffer)
      {
@@ -1114,18 +1205,7 @@ e_plane_renderer_cursor_surface_refresh(E_Plane_Renderer *renderer, E_Client *ec
         return EINA_FALSE;
      }
 
-   memset(tsurface_info.planes[0].ptr, 0, tsurface_info.planes[0].stride * tsurface_info.height);
-
-   stride = wl_shm_buffer_get_stride(buffer->shm_buffer);
-   height = wl_shm_buffer_get_height(buffer->shm_buffer);
-   dst_ptr = tsurface_info.planes[0].ptr;
-
-   for (i = 0 ; i < height ; i++)
-     {
-        memcpy(dst_ptr, src_ptr, stride);
-        dst_ptr += tsurface_info.planes[0].stride;
-        src_ptr += stride;
-     }
+   _e_plane_renderer_cursor_image_draw(buffer, &tsurface_info, pointer->rotation);
 
    tbm_surface_unmap(tsurface);
 
index c0258df..ce5c1f2 100644 (file)
@@ -25,8 +25,8 @@ struct _E_Plane_Renderer {
    int tqueue_height;
    int tqueue_size;
 
-   tbm_surface_h cursor_tsurface;
-
+   tbm_surface_h       cursor_tsurface;
+   int                 cursor_rotation;
    E_Client           *ec;
    E_Plane_Renderer_State    state;
 
index bad6c56..af4ad8d 100644 (file)
@@ -4,9 +4,6 @@
 static Eina_List *_ptrs = NULL;
 static Eina_Bool _initted = EINA_FALSE;
 
-/* temp variable */
-static Eina_Bool override = EINA_FALSE;
-
 /* move the cursor image with the calcaultion of the hot spot */
 static void
 _e_pointer_position_update(E_Pointer *ptr)
@@ -97,19 +94,6 @@ _e_pointer_object_rotation(E_Pointer *ptr)
    evas_map_free(map);
 }
 
-static void
-_e_pointer_hwc_rotation(E_Pointer *ptr)
-{
-   E_Client *ec;
-
-   if (!ptr->o_ptr) return;
-
-   ec = e_comp_object_client_get(ptr->o_ptr);
-   EINA_SAFETY_ON_NULL_RETURN(ec);
-
-   // TODO: roatation cursor buffer with pixman
-}
-
 // TODO: transform the cursor position with hot spot...!!!!!!
 static void
 _e_pointer_rotation_apply(E_Pointer *ptr)
@@ -117,9 +101,9 @@ _e_pointer_rotation_apply(E_Pointer *ptr)
    EINA_SAFETY_ON_NULL_RETURN(ptr);
 
    if (ptr->hwc)
-      _e_pointer_hwc_rotation(ptr);
+     e_comp_object_hwc_update_set(ptr->o_ptr, EINA_TRUE);
    else
-      _e_pointer_object_rotation(ptr);
+     _e_pointer_object_rotation(ptr);
 }
 
 static void
@@ -203,14 +187,6 @@ e_pointer_object_set(E_Pointer *ptr, Evas_Object *obj, int x, int y)
         evas_object_hide(ptr->o_ptr);
         ptr->o_ptr = NULL;
         ptr->device = E_POINTER_NONE;
-
-        /* Current if e_pointer set rotation, it can't' use hwc.
-            if it can use hwc, comp override will be removed. */
-        if (ptr->rotation !=0 && override)
-          {
-             e_comp_override_del();
-             override = EINA_FALSE;
-          }
      }
 
    /* update the hot spot of the cursor */
@@ -241,21 +217,6 @@ e_pointer_object_set(E_Pointer *ptr, Evas_Object *obj, int x, int y)
         /* apply the cursor obj rotation */
         _e_pointer_rotation_apply(ptr);
 
-        /* Current if e_pointer set rotation, it can't' use hwc.
-           if it can use hwc, comp override will be removed. */
-        switch(ptr->rotation)
-          {
-            case 90:
-            case 180:
-            case 270:
-              if (!override)
-                {
-                   e_comp_override_add();
-                   override = EINA_TRUE;
-                }
-               break;
-          }
-
         /* show cursor object */
         evas_object_show(obj);
      }
@@ -301,14 +262,6 @@ e_pointer_hide(E_Pointer *ptr)
    if (!evas_object_visible_get(ptr->o_ptr)) return;
 
    evas_object_hide(ptr->o_ptr);
-
-   /* Current if e_pointer set rotation, it can't' use hwc.
-      if it can use hwc, comp override will be removed. */
-   if (ptr->rotation !=0 && override)
-     {
-        e_comp_override_del();
-        override = EINA_FALSE;
-     }
 }
 
 E_API Eina_Bool
@@ -337,34 +290,6 @@ e_pointer_rotation_set(E_Pointer *ptr, int rotation)
 
    EINA_LIST_FOREACH(e_input_devices_get(), l, dev)
      e_input_device_pointer_rotation_set(dev, rotation);
-
-   /* ptr->rotation shouldn't include the screen rotation value */
-   if (e_comp->e_comp_screen->rotation > 0)
-      rotation = (e_comp->e_comp_screen->rotation + rotation) % 360;
-
-   /* Current if e_pointer set rotation, it can't' use hwc.
-      if it can use hwc, comp override will be removed. */
-   if ((!ptr->o_ptr) || (ptr->o_ptr && !evas_object_visible_get(ptr->o_ptr))) return;
-
-   switch(rotation)
-     {
-       case 0:
-          if (override)
-            {
-               e_comp_override_del();
-               override = EINA_FALSE;
-            }
-          break;
-       case 90:
-       case 180:
-       case 270:
-          if (!override)
-            {
-               e_comp_override_add();
-               override = EINA_TRUE;
-            }
-          break;
-     }
 }
 
 E_API void