Eina_Bool buffer_changed;
int buffer_changed_count;
- Eina_Bool buffer_reuse;
Eina_Rectangle cursor_crop_dst;
Eina_Rectangle cursor_damage_rect;
}
static void
-_e_rdp_output_image_showing_rect_get(Eina_Rectangle *out_rect, Eina_Rectangle *dst_rect, Eina_Rectangle *showing_rect)
+_e_rdp_cb_capture(E_Output *e_output, tbm_surface_h surface, void *user_data)
{
- showing_rect->x = dst_rect->x;
- showing_rect->y = dst_rect->y;
-
- if (dst_rect->x >= out_rect->w)
- showing_rect->w = 0;
- else if (dst_rect->x + dst_rect->w > out_rect->w)
- showing_rect->w = out_rect->w - dst_rect->x;
- else
- showing_rect->w = dst_rect->w;
-
- if (dst_rect->y >= out_rect->h)
- showing_rect->h = 0;
- else if (dst_rect->y + dst_rect->h > out_rect->h)
- showing_rect->h = out_rect->h - dst_rect->y;
- else
- showing_rect->h = dst_rect->h;
-}
-
-static void
-_e_rdp_output_image_src_crop_get(E_Hwc_Window *hwc_window, Eina_Rectangle *fit, Eina_Rectangle *showing_rect, int primary_w, int primary_h)
-{
- float ratio_x, ratio_y;
- Eina_Rectangle out_rect;
- Eina_Rectangle dst_rect;
-
- fit->x = 0;
- fit->y = 0;
- fit->w = 0;
- fit->h = 0;
-
- out_rect.x = 0;
- out_rect.y = 0;
- out_rect.w = primary_w;
- out_rect.h = primary_h;
-
- dst_rect.x = hwc_window->current.info.dst_pos.x;
- dst_rect.y = hwc_window->current.info.dst_pos.y;
- dst_rect.w = hwc_window->current.info.dst_pos.w;
- dst_rect.h = hwc_window->current.info.dst_pos.h;
-
- _e_rdp_output_image_showing_rect_get(&out_rect, &dst_rect, showing_rect);
-
- fit->x = hwc_window->current.info.src_config.pos.x;
- fit->y = hwc_window->current.info.src_config.pos.y;
-
- if (hwc_window->current.info.transform % 2 == 0)
- {
- ratio_x = (float)hwc_window->current.info.src_config.pos.w / dst_rect.w;
- ratio_y = (float)hwc_window->current.info.src_config.pos.h / dst_rect.h;
-
- fit->w = showing_rect->w * ratio_x;
- fit->h = showing_rect->h * ratio_y;
- }
- else
- {
- ratio_x = (float)hwc_window->current.info.src_config.pos.w / dst_rect.h;
- ratio_y = (float)hwc_window->current.info.src_config.pos.h / dst_rect.w;
-
- fit->w = showing_rect->h * ratio_x;
- fit->h = showing_rect->w * ratio_y;
- }
-}
-
-static Eina_Bool
-_e_rdp_output_center_rect_get (int src_w, int src_h, int dst_w, int dst_h, Eina_Rectangle *fit)
-{
- float rw, rh;
-
- if (src_w <= 0 || src_h <= 0 || dst_w <= 0 || dst_h <= 0 || !fit)
- return EINA_FALSE;
-
- rw = (float)src_w / dst_w;
- rh = (float)src_h / dst_h;
-
- if (rw > rh)
- {
- fit->w = dst_w;
- fit->h = src_h / rw;
- fit->x = 0;
- fit->y = (dst_h - fit->h) / 2;
- }
- else if (rw < rh)
- {
- fit->w = src_w / rh;
- fit->h = dst_h;
- fit->x = (dst_w - fit->w) / 2;
- fit->y = 0;
- }
- else
- {
- fit->w = dst_w;
- fit->h = dst_h;
- fit->x = 0;
- fit->y = 0;
- }
-
- if (fit->x % 2)
- fit->x = fit->x - 1;
-
- return EINA_TRUE;
-}
-
-static void
-_e_rdp_output_image_dst_crop_get(E_Hwc_Window *hwc_window, int src_w, int src_h, int w, int h,
- Eina_Rectangle *pos, Eina_Rectangle *showing_pos, Eina_Rectangle *dst_crop, int rotate)
-{
- dst_crop->x = 0;
- dst_crop->y = 0;
- dst_crop->w = 0;
- dst_crop->h = 0;
-
- if (hwc_window->current.info.src_config.pos.w == w && hwc_window->current.info.src_config.pos.h == h &&
- pos->x == 0 && pos->y == 0 && pos->w == src_w && pos->h == src_h)
- {
- dst_crop->x = pos->x;
- dst_crop->y = pos->y;
- dst_crop->w = pos->w;
- dst_crop->h = pos->h;
- }
- else if ((w == pos->w) && (h == pos->h) && (showing_pos->w == pos->w) && (showing_pos->h == pos->h))
- {
- dst_crop->x = hwc_window->current.info.dst_pos.x + pos->x;
- dst_crop->y = hwc_window->current.info.dst_pos.y + pos->y;
- dst_crop->w = hwc_window->current.info.dst_pos.w;
- dst_crop->h = hwc_window->current.info.dst_pos.h;
- }
- else if (rotate == 0)
- {
- dst_crop->x = showing_pos->x * pos->w / w + pos->x;
- dst_crop->y = showing_pos->y * pos->h / h + pos->y;
- dst_crop->w = showing_pos->w * pos->w / w;
- dst_crop->h = showing_pos->h * pos->h / h;
- }
- else
- {
- dst_crop->x = pos->x;
- dst_crop->y = pos->y;
- dst_crop->w = pos->w;
- dst_crop->h = pos->h;
- }
-}
-
-static void
-_e_rdp_output_image_composite(pixman_image_t *src_img, pixman_image_t *dst_img,
- int sx, int sy, int sw, int sh,
- int dx, int dy, int dw, int dh,
- Eina_Bool over, int rotate, int hflip, int vflip)
-{
- double scale_x, scale_y;
- int rotate_step;
- pixman_transform_t t;
- struct pixman_f_transform ft;
- pixman_op_t op;
-
- pixman_f_transform_init_identity(&ft);
-
- if (hflip)
- {
- pixman_f_transform_scale(&ft, NULL, -1, 1);
- pixman_f_transform_translate(&ft, NULL, dw, 0);
- }
-
- if (vflip)
- {
- pixman_f_transform_scale(&ft, NULL, 1, -1);
- pixman_f_transform_translate(&ft, NULL, 0, dh);
- }
-
- rotate_step = (rotate + 360) / 90 % 4;
- if (rotate_step > 0)
- {
- int c, s, tx = 0, ty = 0;
- switch (rotate_step)
- {
- case 1:
- c = 0, s = -1, tx = -dw;
- break;
- case 2:
- c = -1, s = 0, tx = -dw, ty = -dh;
- break;
- case 3:
- c = 0, s = 1, ty = -dh;
- break;
- }
- pixman_f_transform_translate(&ft, NULL, tx, ty);
- pixman_f_transform_rotate(&ft, NULL, c, s);
- }
-
- if (rotate_step % 2 == 0)
- {
- scale_x = (double)sw / dw;
- scale_y = (double)sh / dh;
- }
- else
- {
- scale_x = (double)sw / dh;
- scale_y = (double)sh / dw;
- }
-
- pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
- pixman_f_transform_translate(&ft, NULL, sx, sy);
- pixman_transform_from_pixman_f_transform(&t, &ft);
- pixman_image_set_transform(src_img, &t);
-
- if (!over) op = PIXMAN_OP_SRC;
- else op = PIXMAN_OP_OVER;
-
- pixman_image_composite(op, src_img, NULL, dst_img, 0, 0, 0, 0,
- dx, dy, dw, dh);
-}
-
-static Eina_Bool
-_e_rdp_pixman_output_image_composite(E_Rdp_Output *output, E_Hwc_Window *hwc_window, pixman_image_t *pix_surface, int pix_w, int pix_h, int primary_w, int primary_h)
-{
- Eina_Rectangle showing_pos = {0, };
- Eina_Rectangle dst_pos = {0, };
- Eina_Rectangle src_crop = {0, };
- Eina_Rectangle dst_crop = {0, };
- tbm_surface_h tbm_surface = NULL;
- tbm_surface_info_s info;
- pixman_image_t *pix_surface_src = NULL;
- pixman_format_code_t pix_format = 0;
-
- tbm_surface = hwc_window->display.buffer.tsurface;
- if (!tbm_surface)
- return EINA_FALSE;
-
- tbm_surface_internal_ref(tbm_surface);
-
- if (tbm_surface_map(tbm_surface, TBM_SURF_OPTION_READ, &info) != TBM_SURFACE_ERROR_NONE)
- {
- tbm_surface_internal_unref(tbm_surface);
- return EINA_FALSE;
- }
-
- pix_format = _e_rdp_pixman_format_get(info.format);
- if (pix_format == 0)
- {
- ERR("not supported format");
- goto error;
- }
-
- pix_surface_src = pixman_image_create_bits(pix_format, info.width, info.height, (uint32_t *)info.planes[0].ptr, info.planes[0].stride);
- if (pix_surface_src == NULL)
- {
- ERR("create pixman image failed");
- goto error;
- }
-
- _e_rdp_output_image_src_crop_get(hwc_window, &src_crop, &showing_pos, primary_w, primary_h);
- _e_rdp_output_center_rect_get(primary_w, primary_h, pix_w, pix_h, &dst_pos);
- if (_e_rdp_output_center_rect_get(primary_w, primary_h, pix_w, pix_h, &dst_pos) == EINA_FALSE)
- {
- pixman_image_unref(pix_surface_src);
- goto error;
- }
- _e_rdp_output_image_dst_crop_get(hwc_window, info.width, info.height, primary_w, primary_h, &dst_pos, &showing_pos, &dst_crop, 0);
-
- _e_rdp_output_image_composite(pix_surface_src, pix_surface,
- src_crop.x, src_crop.y, src_crop.w, src_crop.h,
- dst_crop.x, dst_crop.y, dst_crop.w, dst_crop.h,
- EINA_TRUE, 0, 0, 0);
-
- pixman_image_unref(pix_surface_src);
- tbm_surface_unmap(tbm_surface);
- tbm_surface_internal_unref(tbm_surface);
-
- return EINA_TRUE;
-
-error:
- tbm_surface_unmap(tbm_surface);
- tbm_surface_internal_unref(tbm_surface);
- return EINA_FALSE;
-}
-
-static int
-_e_rdp_cb_hwc_window_sort(const void *d1, const void *d2)
-{
- E_Hwc_Window *hwc_window1 = (E_Hwc_Window *)d1;
- E_Hwc_Window *hwc_window2 = (E_Hwc_Window *)d2;
- int zpos1 = 0, zpos2 = 0;
-
- if (!hwc_window1) return(1);
- if (!hwc_window2) return(-1);
-
- if (hwc_window1->state == E_HWC_WINDOW_STATE_NONE)
- zpos1 = -999;
- else
- zpos1 = hwc_window1->zpos;
-
- if (hwc_window2->state == E_HWC_WINDOW_STATE_NONE)
- zpos2 = -999;
- else
- zpos2 = hwc_window2->zpos;
-
- return (zpos1 - zpos2);
-}
-
-static void
-_e_rdp_tbm_surface_copy(tbm_surface_h src_tbm_surface, tbm_surface_info_s *src_info, tbm_surface_h dst_tbm_surface, tbm_surface_info_s *dst_info)
-{
-#if HAVE_LIBGOMP
-# define LIBGOMP_COPY_THREAD_NUM 4
-# define LIBGOMP_COPY_PAGE_SIZE getpagesize()
-# define PAGE_ALIGN(addr) ((addr)&(~((LIBGOMP_COPY_PAGE_SIZE)-1)))
- if (src_info->planes[0].size > (LIBGOMP_COPY_THREAD_NUM * LIBGOMP_COPY_PAGE_SIZE))
- {
- size_t step[2];
- step[0] = PAGE_ALIGN(src_info->planes[0].size / LIBGOMP_COPY_THREAD_NUM);
- step[1] = src_info->planes[0].size - (step[0] * (LIBGOMP_COPY_THREAD_NUM - 1));
-
- omp_set_num_threads(LIBGOMP_COPY_THREAD_NUM);
- #pragma omp parallel
- #pragma omp sections
- {
- #pragma omp section
- {
- memcpy(dst_info->planes[0].ptr,
- src_info->planes[0].ptr,
- step[0]);
- }
- #pragma omp section
- {
- memcpy(dst_info->planes[0].ptr + step[0],
- src_info->planes[0].ptr + step[0],
- step[0]);
- }
- #pragma omp section
- {
- memcpy(dst_info->planes[0].ptr + (step[0] * 2),
- src_info->planes[0].ptr + (step[0] * 2),
- step[0]);
- }
- #pragma omp section
- {
- memcpy(dst_info->planes[0].ptr + (step[0] * 3),
- src_info->planes[0].ptr + (step[0] * 3),
- step[1]);
- }
- }
- }
- else
- {
- memcpy(dst_info->planes[0].ptr, src_info->planes[0].ptr, src_info->planes[0].size);
- }
-
-#else /* HAVE_LIBGOMP */
- memcpy(dst_info->planes[0].ptr, src_info->planes[0].ptr, src_info->planes[0].size);
-#endif /* end of HAVE_LIBGOMP */
-}
-
-static void
-_e_rdp_backup_buffer_create(E_Rdp_Output *output, tbm_surface_h src_tbm_surface, tbm_surface_info_s *src_info)
-{
- tbm_surface_h new_tsurface = NULL;
- tbm_surface_info_s info;
- int ret = TBM_SURFACE_ERROR_NONE;
-
- new_tsurface = tbm_surface_create(src_info->width, src_info->height, src_info->format);
- if (!new_tsurface)
- {
- ERR("tbm_surface_create failed");
- return;
- }
-
- ret = tbm_surface_map(new_tsurface, TBM_SURF_OPTION_WRITE, &info);
- if (ret != TBM_SURFACE_ERROR_NONE)
- {
- ERR("tbm_surface_map failed");
- tbm_surface_destroy(new_tsurface);
- return;
- }
-
- _e_rdp_tbm_surface_copy(src_tbm_surface, src_info, new_tsurface, &info);
-
- tbm_surface_unmap(new_tsurface);
-
- if (output->backup_tbm_surface)
- tbm_surface_destroy(output->backup_tbm_surface);
- output->backup_tbm_surface = new_tsurface;
+ DBG("capture done");
}
static pixman_image_t *
-_e_rdp_pixman_output_image_get_all(E_Rdp_Output *output, Eina_List *visible_list, E_Hwc_Window *hwc_window_cursor, int e_output_w, int e_output_h)
+_e_rdp_pixman_output_image_get(E_Rdp_Output *output)
{
- tbm_surface_h tbm_surface = NULL;
- tbm_surface_info_s info;
pixman_image_t *pix_surface = NULL;
- pixman_format_code_t pix_format = 0;
- E_Hwc *hwc = NULL;
- E_Hwc_Window *hwc_window = NULL;
- Eina_Bool target_window = EINA_TRUE;
- Eina_List *l;
- int err;
+ Eina_Bool ret = EINA_FALSE;
+ tbm_surface_h tbm_surface;
EINA_SAFETY_ON_NULL_RETURN_VAL(output, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(output->primary_output, NULL);
- EINA_SAFETY_ON_NULL_RETURN_VAL(output->primary_output->hwc, NULL);
-
- hwc = output->primary_output->hwc;
tbm_surface = _e_rdp_tbm_image_create(output, output->w, output->h, 0x00000000);
if (tbm_surface == NULL)
output->prepare_tbm_surface = NULL;
return NULL;
}
-
- err = tbm_surface_map(tbm_surface, TBM_SURF_OPTION_READ | TBM_SURF_OPTION_WRITE, &info);
- if (err)
- {
- ERR("tbm_surface_map failed");
- 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");
- goto fail;
- }
-
- 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");
- goto fail;
- }
-
- EINA_LIST_FOREACH(visible_list, l, hwc_window)
+ ret = e_output_capture(output->primary_output, tbm_surface, EINA_FALSE, EINA_TRUE, _e_rdp_cb_capture, output);
+ if (ret == EINA_TRUE)
{
- if (hwc_window->accepted_state == E_HWC_WINDOW_STATE_CLIENT)
+ pix_surface = _e_rdp_pixman_image_create(tbm_surface);
+ if (pix_surface)
{
- if (target_window)
- {
- target_window = EINA_FALSE;
- _e_rdp_pixman_output_image_composite(output, (E_Hwc_Window *)hwc->target_hwc_window, pix_surface, info.width, info.height, e_output_w, e_output_h);
- }
- continue;
+ output->prepare_tbm_surface = tbm_surface;
}
-
- _e_rdp_pixman_output_image_composite(output, hwc_window, pix_surface, info.width, info.height, e_output_w, e_output_h);
- }
-
- if ((output->refresh_count == 0) || (output->buffer_changed_count == 0))
- _e_rdp_backup_buffer_create(output, tbm_surface, &info);
-
- tbm_surface_unmap(tbm_surface);
-
- output->prepare_tbm_surface = tbm_surface;
-
- return pix_surface;
-
-fail:
- tbm_surface_unmap(tbm_surface);
- tbm_surface_destroy(tbm_surface);
- output->prepare_tbm_surface = NULL;
- return NULL;
-}
-
-static pixman_image_t *
-_e_rdp_pixman_output_image_get(E_Rdp_Output *output)
-{
- E_Output *e_output = NULL;
- E_Hwc *hwc = NULL;
- E_Hwc_Window *hwc_window = NULL;
- E_Hwc_Window *hwc_window_cursor = NULL;
- Eina_List *l;
- Eina_List *visible_list = NULL;
- int e_output_w, e_output_h;
- pixman_image_t *pix_surface = NULL;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(output, NULL);
-
- e_output = output->primary_output;
- EINA_SAFETY_ON_NULL_RETURN_VAL(e_output, NULL);
-
- hwc = e_output->hwc;
- EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
-
- e_output_w = e_output->config.mode.w;
- e_output_h = e_output->config.mode.h;
-
- EINA_LIST_FOREACH(hwc->hwc_windows, l, hwc_window)
- {
- if (!hwc_window) continue;
- if (hwc_window->is_target) continue;
- if (hwc_window->is_video) continue;
- if (hwc_window->state == E_HWC_WINDOW_STATE_NONE || hwc_window->zpos == -999) continue;
- if (hwc_window->is_cursor) continue;
- if (hwc_window->accepted_state == E_HWC_WINDOW_STATE_CLIENT)
+ else
{
- visible_list = eina_list_append(visible_list, hwc_window);
- continue;
+ output->prepare_tbm_surface = NULL;
+ tbm_surface_destroy(tbm_surface);
}
-
- if (hwc_window->accepted_state == E_HWC_WINDOW_STATE_DEVICE)
- visible_list = eina_list_append(visible_list, hwc_window);
}
- if (eina_list_count(visible_list) == 0)
- {
- ERR("no visible hwc_window for capture");
- return pix_surface;
- }
- visible_list = eina_list_sort(visible_list, eina_list_count(visible_list), _e_rdp_cb_hwc_window_sort);
-
- pix_surface = _e_rdp_pixman_output_image_get_all(output, visible_list, hwc_window_cursor, e_output_w, e_output_h);
-
return pix_surface;
}
INF("pixman capture time: %.1f ms", (end_capture - start) * 1000);
#endif
- if (output->buffer_reuse)
- {
- box.x1 = output->cursor_damage_rect.x;
- box.y1 = output->cursor_damage_rect.y;
- box.x2 = output->cursor_damage_rect.x + output->cursor_damage_rect.w;
- box.y2 = output->cursor_damage_rect.y + output->cursor_damage_rect.h;
- }
- else
- {
- box.x1 = 0;
- box.y1 = 0;
- box.x2 = output->w;
- box.y2 = output->h;
- }
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = output->w;
+ box.y2 = output->h;
pixman_region32_init_with_extents(&damage, &box);
}
pixman_region32_fini(&damage);
- if (!output->buffer_reuse)
- {
- if (output->showing_surface)
- pixman_image_unref(output->showing_surface);
- output->showing_surface = pix_surface;
+ 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();
E_Rdp_Output *output = NULL;
E_Event_Client *ev = event;
E_Client *ec = NULL;
- E_Hwc *hwc = NULL;
- E_Hwc_Window *hwc_window = NULL;
- Eina_List *l;
- Eina_Bool find = EINA_FALSE;
EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
EINA_SAFETY_ON_NULL_RETURN_VAL(ev->ec, ECORE_CALLBACK_PASS_ON);
EINA_SAFETY_ON_NULL_RETURN_VAL(output, ECORE_CALLBACK_PASS_ON);
EINA_SAFETY_ON_NULL_RETURN_VAL(output->primary_output, ECORE_CALLBACK_PASS_ON);
- EINA_SAFETY_ON_NULL_RETURN_VAL(output->primary_output->hwc, ECORE_CALLBACK_PASS_ON);
-
- hwc = output->primary_output->hwc;
-
- EINA_LIST_FOREACH(hwc->hwc_windows, l, hwc_window)
- {
- if (!hwc_window) continue;
- if (hwc_window->is_target) continue;
- if (hwc_window->is_video) continue;
- if (hwc_window->state == E_HWC_WINDOW_STATE_NONE || hwc_window->zpos == -999) continue;
-
- if (hwc_window == ec->hwc_window)
- {
- find = EINA_TRUE;
- break;
- }
- }
-
- if (find == EINA_FALSE)
- return ECORE_CALLBACK_PASS_ON;
_e_rdp_set_refresh_timer(output, output->refresh_time);
output->buffer_changed_count = 4;
E_Rdp_Output *output = NULL;
E_Event_Client *ev = event;
E_Client *ec = NULL;
- E_Hwc *hwc = NULL;
- E_Hwc_Window *hwc_window = NULL;
- Eina_List *l;
- Eina_Bool find = EINA_FALSE;
EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
EINA_SAFETY_ON_NULL_RETURN_VAL(ev->ec, ECORE_CALLBACK_PASS_ON);
EINA_SAFETY_ON_NULL_RETURN_VAL(output, ECORE_CALLBACK_PASS_ON);
EINA_SAFETY_ON_NULL_RETURN_VAL(output->primary_output, ECORE_CALLBACK_PASS_ON);
- EINA_SAFETY_ON_NULL_RETURN_VAL(output->primary_output->hwc, ECORE_CALLBACK_PASS_ON);
-
- hwc = output->primary_output->hwc;
-
- EINA_LIST_FOREACH(hwc->hwc_windows, l, hwc_window)
- {
- if (!hwc_window) continue;
- if (hwc_window->is_target) continue;
- if (hwc_window->is_video) continue;
-
- if (hwc_window == ec->hwc_window)
- {
- find = EINA_TRUE;
- break;
- }
- }
-
- if (find == EINA_FALSE)
- return ECORE_CALLBACK_PASS_ON;
_e_rdp_set_refresh_timer(output, output->refresh_time);
output->buffer_changed_count = 4;