static void _e_video_hwc_buffer_show(E_Video_Hwc *evh, E_Comp_Wl_Video_Buf *vbuf, unsigned int transform);
static void _e_video_hwc_buffer_commit(E_Video_Hwc *evh, E_Comp_Wl_Video_Buf *vbuf);
-static void
-_coord_move_to_axis(int x_axis, int y_axis, int *ox, int *oy)
-{
- *ox = *ox - x_axis;
- *oy = *oy - y_axis;
-}
-
-static void
-_rectangle_to_coord(Eina_Rectangle *rect, Evas_Point p[2])
-{
- p[0].x = rect->x;
- p[0].y = rect->y;
- p[1].x = rect->x + rect->w;
- p[1].y = rect->y + rect->h;
-}
-
-static void
-_coord_to_rectangle(Evas_Point p[2], Eina_Rectangle *rect)
-{
- rect->x = MIN(p[0].x, p[1].x);
- rect->y = MIN(p[0].y, p[1].y);
- rect->w = MAX(p[0].x, p[1].x) - rect->x;
- rect->h = MAX(p[0].y, p[1].y) - rect->y;
-}
-
static E_Client *
_e_video_hwc_client_offscreen_parent_get(E_Client *ec)
{
e_comp_wl_video_buffer_set_use(vbuf, EINA_FALSE);
}
-/* Translate sx/sy position of src_rect-local coordinates to
- * new position of dst_rect-local coordinates. */
+static Eina_Rectangle
+_screen_rect_get(E_Zone *zone, enum wl_output_transform transform)
+{
+ Eina_Rectangle ret;
+
+ switch (transform & 0x3)
+ {
+ case WL_OUTPUT_TRANSFORM_90:
+ case WL_OUTPUT_TRANSFORM_270:
+ EINA_RECTANGLE_SET(&ret, zone->x, zone->y, zone->h, zone->w);
+ break;
+ default:
+ EINA_RECTANGLE_SET(&ret, zone->x, zone->y, zone->w, zone->h);
+ break;
+ }
+
+ return ret;
+}
+
static void
-_e_video_hwc_coord_transform(Eina_Rectangle *src_rect, Eina_Rectangle *dst_rect, uint transform, int sx, int sy, int *dx, int *dy)
+_point_translate(Evas_Point *point, int x_axis, int y_axis)
+{
+ point->x -= x_axis;
+ point->y -= y_axis;
+}
+
+static void
+_rect_to_points(Eina_Rectangle *rect, Evas_Point points[2])
+{
+ points[0].x = rect->x;
+ points[0].y = rect->y;
+ points[1].x = rect->x + rect->w;
+ points[1].y = rect->y + rect->h;
+}
+
+static void
+_points_to_rect(Evas_Point points[2], Eina_Rectangle *rect)
+{
+ rect->x = MIN(points[0].x, points[1].x);
+ rect->y = MIN(points[0].y, points[1].y);
+ rect->w = MAX(points[0].x, points[1].x) - rect->x;
+ rect->h = MAX(points[0].y, points[1].y) - rect->y;
+}
+
+/* Translate ox/oy position of output_rect-local coordinates to
+ * new position of buffer_rect-local coordinates. */
+static void
+_output_to_buffer_point(Eina_Rectangle *output_rect, Eina_Rectangle *buffer_rect, enum wl_output_transform buffer_transform, int ox, int oy, int *bx, int *by)
{
float ratio_w, ratio_h;
- switch (transform)
+ switch (buffer_transform)
{
case WL_OUTPUT_TRANSFORM_NORMAL:
default:
- *dx = sx, *dy = sy;
+ *bx = ox, *by = oy;
break;
case WL_OUTPUT_TRANSFORM_90:
- *dx = sy, *dy = src_rect->w - sx;
+ *bx = oy, *by = output_rect->w - ox;
break;
case WL_OUTPUT_TRANSFORM_180:
- *dx = src_rect->w - sx, *dy = src_rect->h - sy;
+ *bx = output_rect->w - ox, *by = output_rect->h - oy;
break;
case WL_OUTPUT_TRANSFORM_270:
- *dx = src_rect->h - sy, *dy = sx;
+ *bx = output_rect->h - oy, *by = ox;
break;
case WL_OUTPUT_TRANSFORM_FLIPPED:
- *dx = src_rect->w - sx, *dy = sy;
+ *bx = output_rect->w - ox, *by = oy;
break;
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
- *dx = sy, *dy = sx;
+ *bx = oy, *by = ox;
break;
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
- *dx = sx, *dy = src_rect->h - sy;
+ *bx = ox, *by = output_rect->h - oy;
break;
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
- *dx = src_rect->h - sy, *dy = src_rect->w - sx;
+ *bx = output_rect->h - oy, *by = output_rect->w - ox;
break;
}
- if (transform & 0x1)
+ if (buffer_transform & 0x1)
{
- ratio_w = (float)dst_rect->w / src_rect->h;
- ratio_h = (float)dst_rect->h / src_rect->w;
+ ratio_w = (float)buffer_rect->w / output_rect->h;
+ ratio_h = (float)buffer_rect->h / output_rect->w;
}
else
{
- ratio_w = (float)dst_rect->w / src_rect->w;
- ratio_h = (float)dst_rect->h / src_rect->h;
+ ratio_w = (float)buffer_rect->w / output_rect->w;
+ ratio_h = (float)buffer_rect->h / output_rect->h;
}
- *dx = (*dx) * ratio_w + dst_rect->x;
- *dy = (*dy) * ratio_h + dst_rect->y;
+ *bx = (*bx) * ratio_w + buffer_rect->x;
+ *by = (*by) * ratio_h + buffer_rect->y;
}
-/* Clipping source/destination of viewport.
+/* Cropping source/destination of viewport.
* @in zone A E_Zone instance to be used to get screen rectangle.
* @inout input_r A Source of viewport to be set to tdm_info.src_config
* tdm.output_r A Destination of viewport to be set to tdm_info.dst_pos
- * tdm.output_r will be clipped by given region of zone, and then input_r will be
- * clipped accordingly.
+ * tdm.output_r will be cropped by given region of zone, and then input_r will be
+ * cropped accordingly.
*/
static void
-_e_video_hwc_tdm_viewport_clip(E_Video_Hwc_Geometry *in_out, E_Zone *zone, int transform)
+_e_video_hwc_viewport_crop_by_screen(E_Video_Hwc_Geometry *in_out, E_Zone *zone, enum wl_output_transform output_transform)
{
- Eina_Rectangle *dst_rect, *src_rect;
- Eina_Rectangle new_dst_rect, clip_rect;
- Evas_Point p[2];
-
- switch (transform & 0x3)
- {
- case WL_OUTPUT_TRANSFORM_90:
- case WL_OUTPUT_TRANSFORM_270:
- EINA_RECTANGLE_SET(&clip_rect, zone->x, zone->y, zone->h, zone->w);
- break;
- default:
- EINA_RECTANGLE_SET(&clip_rect, zone->x, zone->y, zone->w, zone->h);
- break;
- }
+ Eina_Rectangle *output_rect, *buffer_rect;
+ Eina_Rectangle cropped_output_rect, screen_rect;
+ Evas_Point points[2];
- src_rect = &in_out->input_r;
- dst_rect = &in_out->tdm.output_r;
+ buffer_rect = &in_out->input_r;
+ output_rect = &in_out->tdm.output_r;
+ screen_rect = _screen_rect_get(zone, output_transform);
- /* No need to clip in case clip_rect contains dst_rect. */
- if (E_CONTAINS(clip_rect.x, clip_rect.y, clip_rect.w, clip_rect.h,
- dst_rect->x, dst_rect->y, dst_rect->w, dst_rect->h))
+ /* No need to crop in case output region doesn't stick out of screen region. */
+ if (E_CONTAINS(screen_rect.x, screen_rect.y,
+ screen_rect.w, screen_rect.h,
+ output_rect->x, output_rect->y,
+ output_rect->w, output_rect->h))
return;
- EINA_RECTANGLE_SET(&new_dst_rect,
- dst_rect->x, dst_rect->y, dst_rect->w, dst_rect->h);
- if (eina_rectangle_intersection(&new_dst_rect, &clip_rect) == EINA_FALSE)
- {
- VER("Warning! Video will not be displayed."
- "No intersection between dst rect and clip rect.\n"
- "dst(%d,%d %dx%d) clip(%d,%d %dx%d) => intersect(%d,%d %dx%d)",
- NULL, EINA_RECTANGLE_ARGS(dst_rect),
- EINA_RECTANGLE_ARGS(&clip_rect),
- EINA_RECTANGLE_ARGS(&new_dst_rect));
- EINA_RECTANGLE_SET(dst_rect, 0, 0, 0, 0);
- /* NOTE: Does src_rect need to be handled as well? */
+ EINA_RECTANGLE_SET(&cropped_output_rect,
+ output_rect->x, output_rect->y,
+ output_rect->w, output_rect->h);
+ if (!eina_rectangle_intersection(&cropped_output_rect, &screen_rect))
+ {
+ VER("Video won't be displayed because there is no intersection between "
+ "screen region and output region.\n"
+ "\toutput(%d,%d %dx%d) screen(%d,%d %dx%d)",
+ NULL, EINA_RECTANGLE_ARGS(output_rect),
+ EINA_RECTANGLE_ARGS(&screen_rect));
+ EINA_RECTANGLE_SET(output_rect, 0, 0, 0, 0);
+ /* NOTE: Does buffer_rect need to be handled as well? */
return;
}
- VDB("Clipping viewport in order to set it to tdm", NULL);
- VDB("Screen region %d,%d %dx%d", NULL, EINA_RECTANGLE_ARGS(&clip_rect));
- VDB("Viewport src(%d,%d %dx%d) dst(%d,%d %dx%d)", NULL,
- EINA_RECTANGLE_ARGS(src_rect), EINA_RECTANGLE_ARGS(dst_rect));
+ VIN("Crop video viewport by screen", NULL);
+ VIN("Screen(%d,%d %dx%d)", NULL, EINA_RECTANGLE_ARGS(&screen_rect));
+ VIN("Viewport: source of buffer(%d,%d %dx%d) destination of screen(%d,%d %dx%d)",
+ NULL, EINA_RECTANGLE_ARGS(buffer_rect), EINA_RECTANGLE_ARGS(output_rect));
+
+ _rect_to_points(&cropped_output_rect, points);
- _rectangle_to_coord(&new_dst_rect, p);
+ /* Get points of cropped rectangle mapped on output_rect-local coordinates. */
+ _point_translate(&points[0], output_rect->x, output_rect->y);
+ _point_translate(&points[1], output_rect->x, output_rect->y);
- /* Move coordinates of cropped rectangle into dst_rect-local coordinates. */
- _coord_move_to_axis(dst_rect->x, dst_rect->y, &p[0].x, &p[0].y);
- _coord_move_to_axis(dst_rect->x, dst_rect->y, &p[1].x, &p[1].y);
+ /* Calculate new points of source buffer for cropped output */
+ _output_to_buffer_point(output_rect, buffer_rect,
+ in_out->transform,
+ points[0].x, points[0].y,
+ &points[0].x, &points[0].y);
+ _output_to_buffer_point(output_rect, buffer_rect,
+ in_out->transform,
+ points[1].x, points[1].y,
+ &points[1].x, &points[1].y);
- /* Calculate new coordinates of src according to cropping dst */
- _e_video_hwc_coord_transform(dst_rect, src_rect, in_out->transform,
- p[0].x, p[0].y, &p[0].x, &p[0].y);
- _e_video_hwc_coord_transform(dst_rect, src_rect, in_out->transform,
- p[1].x, p[1].y, &p[1].x, &p[1].y);
+ _points_to_rect(points, buffer_rect);
- _coord_to_rectangle(p, src_rect);
- EINA_RECTANGLE_SET(dst_rect,
- new_dst_rect.x, new_dst_rect.y,
- new_dst_rect.w, new_dst_rect.h);
+ EINA_RECTANGLE_SET(output_rect,
+ cropped_output_rect.x, cropped_output_rect.y,
+ cropped_output_rect.w, cropped_output_rect.h);
- VDB("Result source region %d,%d %dx%d", NULL, EINA_RECTANGLE_ARGS(src_rect));
- VDB("Result output region %d,%d %dx%d", NULL, EINA_RECTANGLE_ARGS(dst_rect));
+ VIN("Cropped source of buffer(%d,%d %dx%d)",
+ NULL, EINA_RECTANGLE_ARGS(buffer_rect));
+ VIN("Cropped destination of screen(%d,%d %dx%d)",
+ NULL, EINA_RECTANGLE_ARGS(output_rect));
}
static void
ec, EINA_RECTANGLE_ARGS(&out->output_r), out->transform, transform,
EINA_RECTANGLE_ARGS(&out->tdm.output_r), out->tdm.transform);
- _e_video_hwc_tdm_viewport_clip(out, zone, output->transform);
+ _e_video_hwc_viewport_crop_by_screen(out, zone, output->transform);
return;
normal: