Change capture method for mouse moving 73/272273/3
authorJunkyeong, Kim <jk0430.kim@samsung.com>
Mon, 14 Mar 2022 03:03:41 +0000 (12:03 +0900)
committerJunkyeong, Kim <jk0430.kim@samsung.com>
Tue, 22 Mar 2022 08:47:37 +0000 (17:47 +0900)
If there is only mouse moving update, first erase previous cursor image from sent pixman image.
Second, update current cursor image to sent pixman image.
Then send this cursor updated pixman image to rdp client.

Change-Id: Ia34a4a4fec52c87b1bc61f65bfe51d37abb0f903
Signed-off-by: Junkyeong, Kim <jk0430.kim@samsung.com>
src/e_mod_rdp.c

index c44541e..a978c56 100644 (file)
@@ -102,6 +102,9 @@ struct _E_Rdp_Output
    Eina_Bool mouse_moved;
    Eina_Bool buffer_changed;
 
+   Eina_Bool buffer_reuse;
+   Eina_Rectangle cursor_crop_dst;
+
    int mouse_x;
    int mouse_y;
 
@@ -683,6 +686,11 @@ _e_rdp_pixman_output_image_composite_cursor(E_Rdp_Output *output, E_Hwc_Window *
    output->mouse_x = hwc_window->current.info.dst_pos.x;
    output->mouse_y = hwc_window->current.info.dst_pos.y;
 
+   output->cursor_crop_dst.x = dst_crop.x;
+   output->cursor_crop_dst.y = dst_crop.y;
+   output->cursor_crop_dst.w = dst_crop.w;
+   output->cursor_crop_dst.h = dst_crop.h;
+
    return EINA_TRUE;
 }
 
@@ -941,78 +949,171 @@ fail:
    return NULL;
 }
 
-static pixman_image_t *
-_e_rdp_pixman_output_image_get_cursor(E_Rdp_Output *output, E_Hwc_Window *hwc_window_cursor, int e_output_w, int e_output_h)
+static Eina_Bool
+_e_rdp_pixman_output_image_erase_cursor(E_Rdp_Output *output)
 {
-   tbm_surface_h tbm_surface = NULL;
-   tbm_surface_info_s src_info, info;
-   pixman_image_t *pix_surface = NULL;
+   pixman_image_t *pix_backup = NULL;
+   tbm_surface_info_s info, dst_info;
    pixman_format_code_t pix_format = 0;
+   pixman_region32_t clip_region;
+   pixman_transform_t t;
+   struct pixman_f_transform ft;
    int err;
 
-   if ((output->mouse_x == hwc_window_cursor->current.info.dst_pos.x) &&
-       (output->mouse_y == hwc_window_cursor->current.info.dst_pos.y))
+   EINA_SAFETY_ON_NULL_RETURN_VAL(output->backup_tbm_surface, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(output->showing_tbm_surface, EINA_FALSE);
+   if (output->cursor_crop_dst.w == 0 && output->cursor_crop_dst.h == 0)
+     return EINA_FALSE;
+
+   err = tbm_surface_map(output->showing_tbm_surface, TBM_SURF_OPTION_WRITE, &dst_info);
+   if (err)
      {
-//        INF("same position. do not update. (%dx%d)", output->mouse_x, output->mouse_y);
-        return NULL;
+        ERR("tbm_surface_map failed");
+        return EINA_FALSE;
      }
 
-   err = tbm_surface_map(output->backup_tbm_surface, TBM_SURF_OPTION_READ, &src_info);
+   err = tbm_surface_map(output->backup_tbm_surface, TBM_SURF_OPTION_READ, &info);
    if (err)
      {
         ERR("tbm_surface_map failed");
-        return NULL;
+        tbm_surface_unmap(output->showing_tbm_surface);
+        return EINA_FALSE;
      }
 
-   tbm_surface = _e_rdp_tbm_image_create(output, output->w, output->h, 0x00000000);
-   if (tbm_surface == NULL)
+   pix_format = _e_rdp_pixman_format_get(info.format);
+   if (pix_format == 0)
      {
-        ERR("create tbm surface failed");
-        output->prepare_tbm_surface = NULL;
+        ERR("not supported format");
+        tbm_surface_unmap(output->showing_tbm_surface);
         tbm_surface_unmap(output->backup_tbm_surface);
-        return NULL;
+        return EINA_FALSE;
      }
 
-   err = tbm_surface_map(tbm_surface, TBM_SURF_OPTION_WRITE, &info);
-   if (err)
+   pix_backup = pixman_image_create_bits(pix_format, info.width, info.height, (uint32_t *)info.planes[0].ptr, info.planes[0].stride);
+   if (pix_backup == NULL)
      {
-        ERR("tbm_surface_map failed");
-        tbm_surface_destroy(tbm_surface);
-        output->prepare_tbm_surface = NULL;
+        ERR("create pixman image failed");
+        tbm_surface_unmap(output->showing_tbm_surface);
         tbm_surface_unmap(output->backup_tbm_surface);
-        return NULL;
+        return EINA_FALSE;
      }
 
-   _e_rdp_tbm_surface_copy(output->backup_tbm_surface, &src_info, tbm_surface, &info);
+   pixman_image_ref(output->showing_surface);
 
-   pix_format = _e_rdp_pixman_format_get(info.format);
-   if (pix_format == 0)
+   pixman_region32_init_rect(&clip_region, output->cursor_crop_dst.x, output->cursor_crop_dst.y, output->cursor_crop_dst.w, output->cursor_crop_dst.h);
+   pixman_image_set_clip_region32(pix_backup, &clip_region);
+   pixman_image_set_source_clipping(pix_backup, TRUE);
+   pixman_image_set_has_client_clip (pix_backup, TRUE);
+   pixman_f_transform_init_identity(&ft);
+   pixman_f_transform_scale(&ft, NULL, 1, 1);
+   pixman_f_transform_translate(&ft, NULL, 0, 0);
+   pixman_transform_from_pixman_f_transform(&t, &ft);
+   pixman_image_set_transform(pix_backup, &t);
+   pixman_image_composite(PIXMAN_OP_OVER, pix_backup, NULL, output->showing_surface, 0, 0, 0, 0, 0, 0, output->w, output->h);
+
+   pixman_image_unref(pix_backup);
+   pixman_image_unref(output->showing_surface);
+   tbm_surface_unmap(output->showing_tbm_surface);
+   tbm_surface_unmap(output->backup_tbm_surface);
+
+   return EINA_TRUE;
+}
+
+static pixman_image_t *
+_e_rdp_pixman_output_image_get_cursor(E_Rdp_Output *output, E_Hwc_Window *hwc_window_cursor, int e_output_w, int e_output_h)
+{
+   tbm_surface_h tbm_surface = NULL;
+   tbm_surface_info_s src_info, info;
+   pixman_image_t *pix_surface = NULL;
+   pixman_format_code_t pix_format = 0;
+   int err;
+   Eina_Bool ret = EINA_FALSE;
+
+   if ((output->mouse_x == hwc_window_cursor->current.info.dst_pos.x) &&
+       (output->mouse_y == hwc_window_cursor->current.info.dst_pos.y))
      {
-        ERR("not supported format");
-        goto fail;
+//        INF("same position. do not update. (%dx%d)", output->mouse_x, output->mouse_y);
+        return NULL;
      }
 
-   pix_surface = pixman_image_create_bits(pix_format, info.width, info.height, (uint32_t *)info.planes[0].ptr, info.planes[0].stride);
-   if (pix_surface == NULL)
+   if (_e_rdp_pixman_output_image_erase_cursor(output))
      {
-        ERR("create pixman image failed");
-        goto fail;
+        err = tbm_surface_map(output->showing_tbm_surface, TBM_SURF_OPTION_WRITE, &info);
+        if (err)
+          ERR("tbm_surface_map failed");
+        else
+          {
+             ret = _e_rdp_pixman_output_image_composite_cursor(output, hwc_window_cursor, output->showing_surface, info.width, info.height, e_output_w, e_output_h);
+             tbm_surface_unmap(output->showing_tbm_surface);
+          }
+
+        if (ret == EINA_TRUE)
+          {
+             output->buffer_reuse = EINA_TRUE;
+             pix_surface = output->showing_surface;
+             output->prepare_tbm_surface = output->showing_tbm_surface;
+          }
      }
 
-   _e_rdp_pixman_output_image_composite_cursor(output, hwc_window_cursor, pix_surface, info.width, info.height, e_output_w, e_output_h);
+   if (!output->buffer_reuse)
+     {
+        err = tbm_surface_map(output->backup_tbm_surface, TBM_SURF_OPTION_READ, &src_info);
+        if (err)
+          {
+             ERR("tbm_surface_map failed");
+             return NULL;
+          }
 
-   tbm_surface_unmap(tbm_surface);
-   tbm_surface_unmap(output->backup_tbm_surface);
+        tbm_surface = _e_rdp_tbm_image_create(output, output->w, output->h, 0x00000000);
+        if (tbm_surface == NULL)
+          {
+             ERR("create tbm surface failed");
+             output->prepare_tbm_surface = NULL;
+             tbm_surface_unmap(output->backup_tbm_surface);
+             return NULL;
+          }
 
-   output->prepare_tbm_surface = tbm_surface;
+       err = tbm_surface_map(tbm_surface, TBM_SURF_OPTION_WRITE, &info);
+       if (err)
+         {
+            ERR("tbm_surface_map failed");
+            tbm_surface_destroy(tbm_surface);
+            output->prepare_tbm_surface = NULL;
+            tbm_surface_unmap(output->backup_tbm_surface);
+            return NULL;
+         }
 
-   return pix_surface;
+        _e_rdp_tbm_surface_copy(output->backup_tbm_surface, &src_info, tbm_surface, &info);
 
-fail:
-   tbm_surface_unmap(tbm_surface);
-   tbm_surface_destroy(tbm_surface);
-   output->prepare_tbm_surface = NULL;
-   return NULL;
+        pix_format = _e_rdp_pixman_format_get(info.format);
+        if (pix_format == 0)
+          {
+             ERR("not supported format");
+             tbm_surface_unmap(tbm_surface);
+             tbm_surface_destroy(tbm_surface);
+             output->prepare_tbm_surface = NULL;
+             return NULL;
+          }
+
+        pix_surface = pixman_image_create_bits(pix_format, info.width, info.height, (uint32_t *)info.planes[0].ptr, info.planes[0].stride);
+        if (pix_surface == NULL)
+          {
+             ERR("create pixman image failed");
+             tbm_surface_unmap(tbm_surface);
+             tbm_surface_destroy(tbm_surface);
+             output->prepare_tbm_surface = NULL;
+             return NULL;
+          }
+
+        _e_rdp_pixman_output_image_composite_cursor(output, hwc_window_cursor, pix_surface, info.width, info.height, e_output_w, e_output_h);
+
+        tbm_surface_unmap(tbm_surface);
+        tbm_surface_unmap(output->backup_tbm_surface);
+
+        output->prepare_tbm_surface = tbm_surface;
+     }
+
+   return pix_surface;
 }
 
 static pixman_image_t *
@@ -1146,14 +1247,19 @@ _e_rdp_frame_timer(void *data)
      }
    pixman_region32_fini(&damage);
 
-   if (output->showing_surface)
-     pixman_image_unref(output->showing_surface);
-   output->showing_surface = pix_surface;
+   if (!output->buffer_reuse)
+     {
+        if (output->showing_surface)
+          pixman_image_unref(output->showing_surface);
+        output->showing_surface = pix_surface;
 
-   if (output->showing_tbm_surface)
-     tbm_surface_destroy(output->showing_tbm_surface);
+        if (output->showing_tbm_surface)
+          tbm_surface_destroy(output->showing_tbm_surface);
+
+     }
    output->showing_tbm_surface = output->prepare_tbm_surface;
    output->prepare_tbm_surface = NULL;
+   output->buffer_reuse = EINA_FALSE;
 
 #if RDP_DEBUG
    end_refresh = ecore_time_get();