if (fb_commit && (output->dpms == E_OUTPUT_DPMS_OFF))
e_plane_unfetch(fb_target);
- /* set planes */
- EINA_LIST_FOREACH(output->planes, l, plane)
+ if (output->zoom_set)
{
- /* skip the fb_target fetch because we do this previously */
- if (e_plane_is_fb_target(plane)) continue;
+ /* commit only primary */
+ if (!fb_commit)
+ {
+ ERR("fb_commit is failed.");
+ return EINA_FALSE;
+ }
- /* if the plane is the candidate to unset,
- set the plane to be unset_try */
- if (e_plane_is_unset_candidate(plane))
- e_plane_unset_try_set(plane, EINA_TRUE);
+ /* do not execute the tdm functions */
+ e_plane_activation_set(plane, EINA_FALSE);
- /* if the plane is trying to unset,
- 1. if fetching the fb is not available, continue.
- 2. if fetching the fb is available, verify the unset commit check. */
- if (e_plane_is_unset_try(plane))
+ if (!e_plane_fetch(plane))
{
- if (!fb_commit) continue;
- if (!e_plane_unset_commit_check(plane)) continue;
+// ERR("fail to fetch the plane.");
+ return EINA_FALSE;
}
- /* fetch the surface to the plane */
- if (!e_plane_fetch(plane)) continue;
-
- if (output->dpms == E_OUTPUT_DPMS_OFF)
- e_plane_unfetch(plane);
+ if (!e_plane_commit(plane))
+ ERR("fail to e_plane_commit");
- if (e_plane_is_unset_try(plane))
- e_plane_unset_try_set(plane, EINA_FALSE);
+ if (!e_plane_zoom_commit(plane))
+ ERR("fail to e_plane_zoom_commit");
}
+ else
+ {
+ /* set planes */
+ EINA_LIST_FOREACH(output->planes, l, plane)
+ {
+ /* skip the fb_target fetch because we do this previously */
+ if (e_plane_is_fb_target(plane)) continue;
- if (output->dpms == E_OUTPUT_DPMS_OFF) return EINA_TRUE;
+ /* execute the tdm functions */
+ e_plane_activation_set(plane, EINA_TRUE);
- EINA_LIST_FOREACH(output->planes, l, plane)
- {
- if (e_plane_is_unset_try(plane)) continue;
+ /* if the plane is the candidate to unset,
+ set the plane to be unset_try */
+ if (e_plane_is_unset_candidate(plane))
+ e_plane_unset_try_set(plane, EINA_TRUE);
- if (!e_plane_commit(plane))
- ERR("fail to e_plane_commit");
+ /* if the plane is trying to unset,
+ 1. if fetching the fb is not available, continue.
+ 2. if fetching the fb is available, verify the unset commit check. */
+ if (e_plane_is_unset_try(plane))
+ {
+ if (!fb_commit) continue;
+ if (!e_plane_unset_commit_check(plane)) continue;
+ }
- // TODO: to be fixed. check fps of fb_target currently.
- if (fb_commit) _e_output_update_fps();
- }
+ /* fetch the surface to the plane */
+ if (!e_plane_fetch(plane)) continue;
+
+ if (output->dpms == E_OUTPUT_DPMS_OFF)
+ e_plane_unfetch(plane);
+
+ if (e_plane_is_unset_try(plane))
+ e_plane_unset_try_set(plane, EINA_FALSE);
+ }
+
+ if (output->dpms == E_OUTPUT_DPMS_OFF) return EINA_TRUE;
+
+ EINA_LIST_FOREACH(output->planes, l, plane)
+ {
+ if (e_plane_is_unset_try(plane)) continue;
+
+ if (!e_plane_commit(plane))
+ ERR("fail to e_plane_commit");
+
+ // TODO: to be fixed. check fps of fb_target currently.
+ if (fb_commit) _e_output_update_fps();
+ }
+ }
return EINA_TRUE;
}
return NULL;
}
+
+#ifdef HAVE_ZOOM_PP
+#ifdef HAVE_TOUCH_TRANSFORM
+static Eina_Bool
+_e_output_zoom_touch_set(E_Plane *plane, Eina_Bool set)
+{
+ Ecore_Drm_Device *dev = NULL;
+ Eina_Bool ret = EINA_FALSE;
+ const Eina_List *l;
+ Ecore_Drm_Output *primary_output = NULL;
+ int w, h;
+
+ EINA_LIST_FOREACH(ecore_drm_devices_get(), l, dev)
+ {
+ primary_output = ecore_drm_output_primary_get(dev);
+ if (primary_output != NULL)
+ break;
+ }
+
+ if (!primary_output)
+ {
+ ERR("fail get primary_output");
+ return EINA_FALSE;
+ }
+
+ if (set)
+ ret = ecore_drm_device_touch_transformation_set(dev,
+ plane->zoom_rect.x, plane->zoom_rect.y,
+ plane->zoom_rect.w, plane->zoom_rect.h);
+ else
+ {
+ e_output_size_get(plane->output, &w, &h);
+ ret = ecore_drm_device_touch_transformation_set(dev, 0, 0, e_comp->w, e_comp->h);
+ }
+
+ if (ret != EINA_TRUE)
+ ERR("fail ecore_drm_device_touch_transformation_set");
+
+ return ret;
+}
+#endif //HAVE_TOUCH_TRANSFORM
+
+static void
+_e_output_zoom_scaled_rect_get(int out_w, int out_h, double zoomx, double zoomy, int cx, int cy, Eina_Rectangle *rect)
+{
+ double x, y;
+ double dx, dy;
+
+ rect->w = (int)((double)out_w / zoomx);
+ rect->h = (int)((double)out_h / zoomy);
+
+ x = 0 - cx;
+ y = 0 - cy;
+
+ x = (((double)x) * zoomx);
+ y = (((double)y) * zoomy);
+
+ x = x + cx;
+ y = y + cy;
+
+ if (x == 0)
+ dx = 0;
+ else
+ dx = 0 - x;
+
+ if (y == 0)
+ dy = 0;
+ else
+ dy = 0 - y;
+
+ rect->x = (int)(dx / zoomx);
+ rect->y = (int)(dy / zoomy);
+}
+
+EINTERN Eina_Bool
+e_output_zoom_set(E_Output *eout, double zoomx, double zoomy, int cx, int cy)
+{
+ E_Zone *zone = NULL;
+ E_Plane *ep = NULL;
+ Eina_List *l;
+ Eina_Rectangle rect = {0, };
+ int w, h;
+
+ if (!e_comp_screen_pp_support())
+ {
+ WRN("Comp Screen does not support the Zoom.");
+ return EINA_FALSE;
+ }
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(eout, EINA_FALSE);
+
+ e_output_size_get(eout, &w, &h);
+
+ EINA_SAFETY_ON_FALSE_RETURN_VAL((cx >= 0 || cy >= 0), EINA_FALSE);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL((cx < w || cy < h), EINA_FALSE);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL((zoomx > 0 || zoomy > 0), EINA_FALSE);
+
+ ep = e_output_fb_target_get(eout);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(ep, EINA_FALSE);
+
+#ifdef ENABLE_HWC_MULTI
+ e_comp_hwc_multi_plane_set(EINA_FALSE);
+#endif
+
+ DBG("set zoom (zoomx:%f,zoomy:%f) (w:%d,h:%d)", zoomx, zoomy, cx, cy);
+
+ /* get the scaled rect */
+ _e_output_zoom_scaled_rect_get(w, h, zoomx, zoomy, cx, cy, &rect);
+ DBG("zoom_rect (x:%d,y:%d) (w:%d,h:%d)", rect.x, rect.y, rect.w, rect.h);
+
+ if (!e_plane_zoom_set(ep, &rect))
+ {
+ ERR("e_plane_zoom_set failed.");
+#ifdef ENABLE_HWC_MULTI
+ e_comp_hwc_multi_plane_set(EINA_TRUE);
+#endif
+ return EINA_FALSE;
+ }
+
+#ifdef HAVE_TOUCH_TRANSFORM
+ //test position
+ if (!_e_output_zoom_touch_set(plane, EINA_TRUE))
+ ERR("fail _e_output_zoom_touch_set");
+#endif
+
+ if (!eout->zoom_set) eout->zoom_set = EINA_TRUE;
+ DBG("zoom set output:%s", eout->id);
+
+ return EINA_TRUE;
+}
+
+EINTERN void
+e_output_zoom_unset(E_Output *eout)
+{
+ E_Zone *zone = NULL;
+ E_Plane *ep = NULL;
+ Eina_List *l;
+ Eina_Bool ret = EINA_FALSE;
+
+ EINA_SAFETY_ON_NULL_RETURN(eout);
+
+ if (!eout->zoom_set) return;
+
+ ep = e_output_fb_target_get(eout);
+ EINA_SAFETY_ON_NULL_RETURN(ep);
+
+#ifdef HAVE_TOUCH_TRANSFORM
+ //test position
+ if (!_e_output_zoom_touch_set(plane, EINA_FALSE))
+ ERR("fail _e_output_zoom_touch_set");
+#endif
+
+ e_plane_zoom_unset(ep);
+
+ eout->zoom_set = EINA_FALSE;
+
+#ifdef ENABLE_HWC_MULTI
+ e_comp_hwc_multi_plane_set(EINA_TRUE);
+#endif
+
+ DBG("e_output_zoom_unset: output:%s", eout->id);
+}
+#endif
CLEAR(plane->info);
- error = tdm_layer_unset_buffer(tlayer);
- if (error != TDM_ERROR_NONE)
+ if (plane->activation)
{
- ERR("fail to tdm_layer_unset_buffer");
- return EINA_FALSE;
+ error = tdm_layer_unset_buffer(tlayer);
+ if (error != TDM_ERROR_NONE)
+ {
+ ERR("fail to tdm_layer_unset_buffer");
+ return EINA_FALSE;
+ }
}
return EINA_TRUE;
ep->need_ev = EINA_FALSE;
}
-static Eina_Bool
-_e_plane_surface_set(E_Plane *plane, tbm_surface_h tsurface)
+static unsigned int
+_e_plane_aligned_width_get(tbm_surface_h tsurface)
{
+ unsigned int aligned_width = 0;
tbm_surface_info_s surf_info;
- tdm_error error;
- tdm_layer *tlayer = plane->tlayer;
- E_Output *output = plane->output;
- E_Client *ec = plane->ec;
- int aligned_width;
- int dst_pos_x, dst_pos_y;
- /* set layer when the layer infomation is different from the previous one */
tbm_surface_get_info(tsurface, &surf_info);
switch (surf_info.format)
break;
default:
ERR("not supported format: %x", surf_info.format);
- return EINA_FALSE;
}
+ return aligned_width;
+}
+
+static Eina_Bool
+_e_plane_surface_set(E_Plane *plane, tbm_surface_h tsurface)
+{
+ tbm_surface_info_s surf_info;
+ tdm_error error;
+ tdm_layer *tlayer = plane->tlayer;
+ E_Output *output = plane->output;
+ E_Client *ec = plane->ec;
+ unsigned int aligned_width;
+ int dst_x, dst_y, dst_w, dst_h;
+
+ /* set layer when the layer infomation is different from the previous one */
+ tbm_surface_get_info(tsurface, &surf_info);
+
+ aligned_width = _e_plane_aligned_width_get(tsurface);
+ if (aligned_width == 0) return EINA_FALSE;
+
if (ec)
{
if (plane->role == E_PLANE_ROLE_CURSOR)
return EINA_FALSE;
}
- dst_pos_x = pointer->x - pointer->hot.x;
- dst_pos_y = pointer->y - pointer->hot.y;
+ dst_x = pointer->x - pointer->hot.x;
+ dst_y = pointer->y - pointer->hot.y;
}
else
{
- dst_pos_x = ec->x;
- dst_pos_y = ec->y;
+ dst_x = ec->x;
+ dst_y = ec->y;
}
/* if output is transformed, the position of a buffer on screen should be also
e_pixmap_size_get(ec->pixmap, &bw, &bh);
e_comp_wl_rect_convert(ec->zone->w, ec->zone->h,
output->config.rotation / 90, 1,
- dst_pos_x, dst_pos_y, bw, bh,
- &dst_pos_x, &dst_pos_y, NULL, NULL);
- }
-
- if (plane->info.src_config.size.h != aligned_width ||
- plane->info.src_config.size.v != surf_info.height ||
- plane->info.src_config.pos.x != 0 ||
- plane->info.src_config.pos.y != 0 ||
- plane->info.src_config.pos.w != surf_info.width ||
- plane->info.src_config.pos.h != surf_info.height ||
- plane->info.dst_pos.x != dst_pos_x ||
- plane->info.dst_pos.y != dst_pos_y ||
- plane->info.dst_pos.w != surf_info.width ||
- plane->info.dst_pos.h != surf_info.height ||
- plane->info.transform != TDM_TRANSFORM_NORMAL)
- {
- plane->info.src_config.size.h = aligned_width;
- plane->info.src_config.size.v = surf_info.height;
- plane->info.src_config.pos.x = 0;
- plane->info.src_config.pos.y = 0;
- plane->info.src_config.pos.w = surf_info.width;
- plane->info.src_config.pos.h = surf_info.height;
- plane->info.dst_pos.x = dst_pos_x;
- plane->info.dst_pos.y = dst_pos_y;
- plane->info.dst_pos.w = surf_info.width;
- plane->info.dst_pos.h = surf_info.height;
- plane->info.transform = TDM_TRANSFORM_NORMAL;
-
- error = tdm_layer_set_info(tlayer, &plane->info);
- if (error != TDM_ERROR_NONE)
- {
- ERR("fail to tdm_layer_set_info");
- return EINA_FALSE;
- }
+ dst_x, dst_y, bw, bh,
+ &dst_x, &dst_y, NULL, NULL);
}
+ dst_w = surf_info.width;
+ dst_h = surf_info.height;
}
else
{
- if (plane->info.src_config.size.h != aligned_width ||
- plane->info.src_config.size.v != surf_info.height ||
- plane->info.src_config.pos.x != 0 ||
- plane->info.src_config.pos.y != 0 ||
- plane->info.src_config.pos.w != surf_info.width ||
- plane->info.src_config.pos.h != surf_info.height ||
- plane->info.dst_pos.x != output->config.geom.x ||
- plane->info.dst_pos.y != output->config.geom.y ||
- plane->info.dst_pos.w != output->config.geom.w ||
- plane->info.dst_pos.h != output->config.geom.h ||
- plane->info.transform != TDM_TRANSFORM_NORMAL)
- {
- plane->info.src_config.size.h = aligned_width;
- plane->info.src_config.size.v = surf_info.height;
- plane->info.src_config.pos.x = 0;
- plane->info.src_config.pos.y = 0;
- plane->info.src_config.pos.w = surf_info.width;
- plane->info.src_config.pos.h = surf_info.height;
- plane->info.dst_pos.x = output->config.geom.x;
- plane->info.dst_pos.y = output->config.geom.y;
- plane->info.dst_pos.w = output->config.geom.w;
- plane->info.dst_pos.h = output->config.geom.h;
- plane->info.transform = TDM_TRANSFORM_NORMAL;
+ dst_x = output->config.geom.x;
+ dst_y = output->config.geom.y;
+ dst_w = output->config.geom.w;
+ dst_h = output->config.geom.h;
+ }
+ if (plane->info.src_config.size.h != aligned_width ||
+ plane->info.src_config.size.v != surf_info.height ||
+ plane->info.src_config.pos.x != 0 ||
+ plane->info.src_config.pos.y != 0 ||
+ plane->info.src_config.pos.w != surf_info.width ||
+ plane->info.src_config.pos.h != surf_info.height ||
+ plane->info.dst_pos.x != dst_x ||
+ plane->info.dst_pos.y != dst_y ||
+ plane->info.dst_pos.w != dst_w ||
+ plane->info.dst_pos.h != dst_h ||
+ plane->info.transform != TDM_TRANSFORM_NORMAL)
+ {
+ plane->info.src_config.size.h = aligned_width;
+ plane->info.src_config.size.v = surf_info.height;
+ plane->info.src_config.pos.x = 0;
+ plane->info.src_config.pos.y = 0;
+ plane->info.src_config.pos.w = surf_info.width;
+ plane->info.src_config.pos.h = surf_info.height;
+ plane->info.dst_pos.x = dst_x;
+ plane->info.dst_pos.y = dst_y;
+ plane->info.dst_pos.w = dst_w;
+ plane->info.dst_pos.h = dst_h;
+ plane->info.transform = TDM_TRANSFORM_NORMAL;
+
+ if (plane->activation)
+ {
error = tdm_layer_set_info(tlayer, &plane->info);
if (error != TDM_ERROR_NONE)
{
plane->info.dst_pos.w, plane->info.dst_pos.h);
}
- error = tdm_layer_set_buffer(tlayer, tsurface);
- if (error != TDM_ERROR_NONE)
+ if (plane->activation)
{
- ERR("fail to tdm_layer_set_buffer");
- return EINA_FALSE;
+ error = tdm_layer_set_buffer(tlayer, tsurface);
+ if (error != TDM_ERROR_NONE)
+ {
+ ERR("fail to tdm_layer_set_buffer");
+ return EINA_FALSE;
+ }
}
_e_plane_ev(plane, E_EVENT_PLANE_WIN_CHANGE);
tdm_layer_get_zpos(tlayer, &zpos);
plane->zpos = zpos;
plane->output = output;
+ plane->activation = EINA_TRUE;
tdm_err = tdm_layer_get_buffer_flags(plane->tlayer, &buffer_flags);
if (tdm_err == TDM_ERROR_NONE)
e_plane_commit_data_release(data);
}
+static void
+_e_plane_zoom_destroy(E_Plane *plane)
+{
+ if (plane->zoom_tqueue)
+ {
+ tbm_surface_queue_destroy(plane->zoom_tqueue);
+ plane->zoom_tqueue = NULL;
+ }
+ if (plane->tpp)
+ {
+ tdm_pp_destroy(plane->tpp);
+ plane->tpp = NULL;
+ }
+
+ ERR("_e_plane_zoom_destroy done");
+}
+
EINTERN Eina_Bool
e_plane_commit(E_Plane *plane)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(plane, EINA_FALSE);
+ if (plane->is_primary)
+ {
+ if (plane->zoom_tsurface)
+ {
+ if (!tbm_surface_queue_can_dequeue(plane->zoom_tqueue, 0))
+ return EINA_TRUE;
+ }
+ }
+
data = e_plane_commit_data_aquire(plane);
if (!data) return EINA_TRUE;
NULL, NULL, plane, plane->zpos, data->tsurface, plane->renderer ? plane->renderer->tqueue : NULL,
data->buffer_ref.buffer ? data->buffer_ref.buffer->resource : NULL, data);
- error = tdm_layer_commit(plane->tlayer, _e_plane_commit_hanler, data);
- if (error != TDM_ERROR_NONE)
+ if (plane->activation)
{
- ERR("fail to tdm_layer_commit plane:%p, zpos:%d", plane, plane->zpos);
- e_plane_commit_data_release(data);
- return EINA_FALSE;
- }
+ error = tdm_layer_commit(plane->tlayer, _e_plane_commit_hanler, data);
+ if (error != TDM_ERROR_NONE)
+ {
+ ERR("fail to tdm_layer_commit plane:%p, zpos:%d", plane, plane->zpos);
+ e_plane_commit_data_release(data);
+ return EINA_FALSE;
+ }
- error = tdm_output_wait_vblank(plane->output->toutput, 1, 0, _e_plane_vblank_handler, (void *)plane);
- if (error != TDM_ERROR_NONE)
- {
- ERR("fail to tdm_output_wait_vblank plane:%p, zpos:%d", plane, plane->zpos);
- return EINA_FALSE;
- }
+ error = tdm_output_wait_vblank(plane->output->toutput, 1, 0, _e_plane_vblank_handler, (void *)plane);
+ if (error != TDM_ERROR_NONE)
+ {
+ ERR("fail to tdm_output_wait_vblank plane:%p, zpos:%d", plane, plane->zpos);
+ return EINA_FALSE;
+ }
- /* send frame event enlightenment dosen't send frame evnet in nocomp */
- if (plane->ec)
- e_pixmap_image_clear(plane->ec->pixmap, 1);
+ /* send frame event enlightenment dosen't send frame evnet in nocomp */
+ if (plane->ec)
+ e_pixmap_image_clear(plane->ec->pixmap, 1);
+
+ if (plane->zoom_unset)
+ {
+ if (plane->is_primary)
+ {
+ if (plane->zoom_tsurface)
+ {
+ tbm_surface_queue_release(plane->zoom_tqueue, plane->zoom_tsurface);
+ tbm_surface_internal_unref(plane->zoom_tsurface);
+
+ plane->zoom_tsurface = NULL;
+ }
+ if (eina_list_count(plane->pending_commit_zoom_data_list) == 0)
+ {
+ _e_plane_zoom_destroy(plane);
+ plane->zoom_unset = EINA_FALSE;
+ }
+ }
+ }
+ }
plane->wait_commit = EINA_TRUE;
if (plane->renderer)
e_plane_renderer_show_state(plane->renderer);
}
+
+EINTERN void
+e_plane_activation_set(E_Plane *plane, Eina_Bool set)
+{
+ EINA_SAFETY_ON_NULL_RETURN(plane);
+
+ if (plane->activation == set) return;
+
+ plane->activation = set;
+
+ ELOGF("E_PLANE", "Plane(%p) activation set to be %s",
+ NULL, NULL, plane, set?"True":"False");
+}
+
+static Eina_Bool
+_e_plane_tdm_info_changed_check(E_Plane *plane, unsigned int size_w, unsigned int size_h,
+ unsigned int src_x, unsigned int src_y, unsigned int src_w, unsigned int src_h,
+ unsigned int dst_x, unsigned int dst_y, unsigned int dst_w, unsigned int dst_h,
+ tdm_transform transform)
+{
+ if (plane->info.src_config.size.h != size_w ||
+ plane->info.src_config.size.v != size_h ||
+ plane->info.src_config.pos.x != src_x ||
+ plane->info.src_config.pos.y != src_y ||
+ plane->info.src_config.pos.w != src_w ||
+ plane->info.src_config.pos.h != src_h ||
+ plane->info.dst_pos.x != dst_x ||
+ plane->info.dst_pos.y != dst_y ||
+ plane->info.dst_pos.w != dst_w ||
+ plane->info.dst_pos.h != dst_h ||
+ plane->info.transform != transform)
+ return EINA_TRUE;
+
+ return EINA_FALSE;
+}
+
+static void
+_e_plane_tdm_info_set(E_Plane *plane, unsigned int size_w, unsigned int size_h,
+ unsigned int src_x, unsigned int src_y, unsigned int src_w, unsigned int src_h,
+ unsigned int dst_x, unsigned int dst_y, unsigned int dst_w, unsigned int dst_h,
+ tdm_transform transform)
+{
+ plane->info.src_config.size.h = size_w;
+ plane->info.src_config.size.v = size_h;
+ plane->info.src_config.pos.x = src_x;
+ plane->info.src_config.pos.y = src_y;
+ plane->info.src_config.pos.w = src_w;
+ plane->info.src_config.pos.h = src_h;
+ plane->info.dst_pos.x = dst_x;
+ plane->info.dst_pos.y = dst_y;
+ plane->info.dst_pos.w = dst_w;
+ plane->info.dst_pos.h = dst_h;
+ plane->info.transform = transform;
+}
+
+static void
+_e_plane_zoom_commit_data_release(E_Plane_Pp_Data *data)
+{
+ E_Plane *plane = NULL;
+ tbm_surface_h zoom_tsurface = NULL;
+
+ EINA_SAFETY_ON_NULL_RETURN(data);
+
+ plane = data->plane;
+ zoom_tsurface = data->zoom_tsurface;
+
+ if (plane->zoom_tsurface)
+ {
+ tbm_surface_queue_release(plane->zoom_tqueue, plane->zoom_tsurface);
+
+ tbm_surface_internal_unref(plane->zoom_tsurface);
+ }
+ plane->zoom_tsurface = zoom_tsurface;
+// plane->zoom_commit = EINA_FALSE;
+#if 0
+ if (plane->zoom_need_unset)
+ {
+ plane->zoom_set = EINA_FALSE;
+ plane->zoom_set_prepare = EINA_FALSE;
+ plane->zoom_need_unset = EINA_FALSE;
+ }
+#endif
+ plane->pending_commit_zoom_data_list = eina_list_remove(plane->pending_commit_zoom_data_list, data);
+
+ free(data);
+}
+
+static void
+_e_plane_zoom_commit_handler(tdm_layer *layer, unsigned int sequence,
+ unsigned int tv_sec, unsigned int tv_usec,
+ void *user_data)
+{
+ E_Plane_Pp_Data *data = (E_Plane_Pp_Data *)user_data;
+
+ EINA_SAFETY_ON_NULL_RETURN(data);
+
+ TRACE_DS_ASYNC_END((unsigned int)layer, [PLANE:COMMIT~HANDLER]);
+
+ _e_plane_zoom_commit_data_release(data);
+}
+
+static void
+_e_plane_zoom_pp_cb(tdm_pp *pp, tbm_surface_h tsurface_src, tbm_surface_h tsurface_dst, void *user_data)
+{
+ E_Plane_Pp_Data *pp_data = NULL;
+ E_Plane_Commit_Data *data = NULL;
+ E_Plane *plane = NULL;
+ tbm_surface_info_s surf_info;
+ tbm_surface_h zoom_tsurface;
+ tbm_error_e tbm_err;
+ tdm_error tdm_err;
+ tdm_layer *tlayer = NULL;
+ E_Output *output = NULL;
+ unsigned int aligned_width;
+
+ pp_data = (E_Plane_Pp_Data *)user_data;
+ if (!pp_data)
+ {
+ ERR("_e_plane_zoom_pp_cb: fail no pp_data");
+ return;
+ }
+
+ data = pp_data->data;
+ if (!data)
+ ERR("_e_plane_zoom_pp_cb: fail no data");
+
+ plane = pp_data->plane;
+ if (!plane)
+ {
+ ERR("_e_plane_zoom_pp_cb: fail no plane");
+ return;
+ }
+
+ if (data)
+ {
+ if (data->ec)
+ e_pixmap_image_clear(data->ec->pixmap, 1);
+ e_plane_commit_data_release(data);
+ pp_data->data = NULL;
+ }
+
+ plane->pending_commit = EINA_FALSE;
+ if (plane->zoom_unset)
+ {
+ tbm_surface_queue_release(plane->zoom_tqueue, tsurface_dst);
+ tbm_surface_internal_unref(tsurface_dst);
+
+ plane->pending_commit_zoom_data_list = eina_list_remove(plane->pending_commit_zoom_data_list, pp_data);
+
+ free(pp_data);
+
+ return;
+ }
+
+#if 0
+ plane->zoom_converting = EINA_FALSE;
+ if (plane->zoom_show_current)
+ plane->zoom_show_current = EINA_FALSE;
+#endif
+ tlayer = plane->tlayer;
+ output = plane->output;
+
+ /* set layer when the layer infomation is different from the previous one */
+ tbm_surface_get_info(tsurface_dst, &surf_info);
+
+ aligned_width = _e_plane_aligned_width_get(tsurface_dst);
+ if (aligned_width == 0)
+ {
+ ERR("_e_plane_zoom_pp_cb: aligned_width 0");
+ _e_plane_zoom_commit_data_release(pp_data);
+ return;
+ }
+
+ if (_e_plane_tdm_info_changed_check(plane, aligned_width, surf_info.height, 0, 0, surf_info.width, surf_info.height,
+ output->config.geom.x, output->config.geom.y, output->config.geom.w, output->config.geom.h,
+ TDM_TRANSFORM_NORMAL))
+ {
+ _e_plane_tdm_info_set(plane, aligned_width, surf_info.height, 0, 0, surf_info.width, surf_info.height,
+ output->config.geom.x, output->config.geom.y, output->config.geom.w, output->config.geom.h,
+ TDM_TRANSFORM_NORMAL);
+
+ tdm_err = tdm_layer_set_info(tlayer, &plane->info);
+ if (tdm_err != TDM_ERROR_NONE)
+ {
+ ERR("_e_plane_zoom_pp_cb: fail tdm_layer_set_info");
+ _e_plane_zoom_commit_data_release(pp_data);
+ return;
+ }
+ }
+
+ if (plane_trace_debug)
+ {
+ ELOGF("E_PLANE", "Set Plane(%p) tsurface(%p) (%dx%d,[%d,%d,%d,%d]=>[%d,%d,%d,%d])",
+ NULL, NULL, plane, tsurface_dst,
+ plane->info.src_config.size.h, plane->info.src_config.size.h,
+ plane->info.src_config.pos.x, plane->info.src_config.pos.y,
+ plane->info.src_config.pos.w, plane->info.src_config.pos.h,
+ plane->info.dst_pos.x, plane->info.dst_pos.y,
+ plane->info.dst_pos.w, plane->info.dst_pos.h);
+ }
+
+ tbm_err = tbm_surface_queue_enqueue(plane->zoom_tqueue, tsurface_dst);
+ if (tbm_err != TBM_ERROR_NONE)
+ {
+ ERR("_e_plane_zoom_pp_cb : fail tbm_surface_queue_enqueue");
+ _e_plane_zoom_commit_data_release(pp_data);
+ return;
+ }
+
+ tbm_err = tbm_surface_queue_acquire(plane->zoom_tqueue, &zoom_tsurface);
+ if (tbm_err != TBM_ERROR_NONE)
+ {
+ ERR("_e_plane_zoom_pp_cb : fail tbm_surface_queue_acquire");
+ _e_plane_zoom_commit_data_release(pp_data);
+ return;
+ }
+
+ tdm_err = tdm_layer_set_buffer(tlayer, zoom_tsurface);
+ if (tdm_err != TDM_ERROR_NONE)
+ {
+ ERR("fail to tdm_layer_set_buffer");
+ _e_plane_zoom_commit_data_release(pp_data);
+ return;
+ }
+
+ pp_data->zoom_tsurface = zoom_tsurface;
+ pp_data->plane = plane;
+
+// _e_plane_ev(plane, E_EVENT_PLANE_WIN_CHANGE);
+
+#ifdef HAVE_TOUCH_TRANSFORM
+ //coreect position
+// if (!_e_plane_zoom_set_touch(plane))
+// ERR("_e_plane_zoom_pp_cb: fail _e_plane_zoom_set_touch");
+#endif
+
+ tdm_err = tdm_layer_commit(tlayer, _e_plane_zoom_commit_handler, pp_data);
+ if (tdm_err != TDM_ERROR_NONE)
+ {
+ ERR("_e_plane_zoom_pp_cb: fail to tdm_layer_commit plane:%p, zpos:%d", plane, plane->zpos);
+ _e_plane_zoom_commit_data_release(pp_data);
+ return;
+ }
+#if 0
+ tdm_err = tdm_output_wait_vblank(output->toutput, 1, 0, _e_plane_zoom_vblank_handler, (void *)plane);
+ if (tdm_err != TDM_ERROR_NONE)
+ {
+ ERR("_e_plane_zoom_pp_cb: fail to tdm_output_wait_vblank plane:%p, zpos:%d", plane, plane->zpos);
+ return;
+ }
+#endif
+ return;
+}
+
+static Eina_Bool
+_e_plane_zoom_set_pp_info(E_Plane *plane)
+{
+ tdm_info_pp pp_info;
+ tdm_error ret = TDM_ERROR_NONE;
+ unsigned int aligned_width = 0;
+ tbm_surface_info_s surf_info;
+ tbm_surface_h tsurface = plane->tsurface;
+ int dst_w, dst_h;
+
+ tbm_surface_get_info(tsurface, &surf_info);
+
+ aligned_width = _e_plane_aligned_width_get(tsurface);
+ if (aligned_width == 0) return EINA_FALSE;
+
+ e_output_size_get(plane->output, &dst_w, &dst_h);
+
+ pp_info.src_config.size.h = aligned_width;
+ pp_info.src_config.size.v = surf_info.height;
+ pp_info.src_config.pos.x = plane->zoom_rect_temp.x;
+ pp_info.src_config.pos.y = plane->zoom_rect_temp.y;
+ pp_info.src_config.pos.w = plane->zoom_rect_temp.w;
+ pp_info.src_config.pos.h = plane->zoom_rect_temp.h;
+ pp_info.src_config.format = TBM_FORMAT_ARGB8888;
+
+ pp_info.dst_config.size.h = aligned_width;
+ pp_info.dst_config.size.v = surf_info.height;
+ pp_info.dst_config.pos.x = 0;
+ pp_info.dst_config.pos.y = 0;
+ pp_info.dst_config.pos.w = dst_w;
+ pp_info.dst_config.pos.h = dst_h;
+ pp_info.dst_config.format = TBM_FORMAT_ARGB8888;
+
+ pp_info.transform = TDM_TRANSFORM_NORMAL;
+ pp_info.sync = 0;
+ pp_info.flags = 0;
+
+ ret = tdm_pp_set_info(plane->tpp, &pp_info);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(ret == TDM_ERROR_NONE, EINA_FALSE);
+
+ plane->zoom_rect.x = plane->zoom_rect_temp.x;
+ plane->zoom_rect.y = plane->zoom_rect_temp.y;
+ plane->zoom_rect.w = plane->zoom_rect_temp.w;
+ plane->zoom_rect.h = plane->zoom_rect_temp.h;
+
+ DBG("_e_plane_zoom_set_pp_info success(src x:%d,y:%d,w:%d,h:%d)",
+ plane->zoom_rect.x, plane->zoom_rect.y, plane->zoom_rect.w, plane->zoom_rect.h);
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_e_plane_zoom_find_data(E_Plane *plane, E_Plane_Commit_Data *data)
+{
+ Eina_List *l = NULL;
+ E_Plane_Pp_Data *pp_data = NULL;
+
+ EINA_LIST_FOREACH(plane->pending_commit_zoom_data_list, l, pp_data)
+ {
+ if (!pp_data) continue;
+ if (!pp_data->data) continue;
+ if (pp_data->data == data) return EINA_TRUE;
+ }
+
+ return EINA_FALSE;
+}
+
+EINTERN Eina_Bool
+e_plane_zoom_commit(E_Plane *plane)
+{
+ tbm_surface_h tsurface = plane->tsurface;
+ tbm_surface_info_s surf_info;
+ E_Plane_Commit_Data *data = NULL;
+ E_Plane_Pp_Data *pp_data = NULL;
+ int count = 0;
+ tbm_error_e tbm_err = TBM_ERROR_NONE;
+ tbm_surface_h zoom_tsurface = NULL;
+ tdm_error tdm_err = TDM_ERROR_NONE;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(plane, EINA_FALSE);
+
+ count = eina_list_count(plane->pending_commit_data_list);
+ if (count == 0) return EINA_TRUE;
+
+ data = eina_list_nth(plane->pending_commit_data_list, count - 1);
+ if (!data)
+ {
+ ERR("e_plane_zoom_commit: fail E_Plane_Commit_Data get");
+ return EINA_FALSE;
+ }
+ if (_e_plane_zoom_find_data(plane, data)) return EINA_TRUE;
+
+ tbm_err = tbm_surface_queue_dequeue(plane->zoom_tqueue, &zoom_tsurface);
+ if (tbm_err != TBM_ERROR_NONE)
+ {
+ ERR("e_plane_zoom_commit: fail tbm_surface_queue_dequeue");
+ return EINA_FALSE;
+ }
+ tbm_surface_internal_ref(zoom_tsurface);
+
+ pp_data = E_NEW(E_Plane_Pp_Data, 1);
+ pp_data->zoom_tsurface = zoom_tsurface;
+ pp_data->data = data;
+ pp_data->plane = plane;
+
+ plane->pending_commit_zoom_data_list = eina_list_append(plane->pending_commit_zoom_data_list, pp_data);
+
+ if (plane->zoom_rect.x != plane->zoom_rect_temp.x || plane->zoom_rect.y != plane->zoom_rect_temp.y ||
+ plane->zoom_rect.w != plane->zoom_rect_temp.w || plane->zoom_rect.h != plane->zoom_rect_temp.h)
+ {
+ if (!_e_plane_zoom_set_pp_info(plane))
+ {
+ ERR("e_plane_zoom_commit: fail _e_plane_zoom_set_pp_info");
+ goto pp_fail;
+ }
+ }
+
+ tdm_err = tdm_pp_set_done_handler(plane->tpp, _e_plane_zoom_pp_cb, pp_data);
+ EINA_SAFETY_ON_FALSE_GOTO(tdm_err == TDM_ERROR_NONE, pp_fail);
+
+ tdm_err = tdm_pp_attach(plane->tpp, tsurface, zoom_tsurface);
+ EINA_SAFETY_ON_FALSE_GOTO(tdm_err == TDM_ERROR_NONE, pp_fail);
+
+ tdm_err = tdm_pp_commit(plane->tpp);
+ EINA_SAFETY_ON_FALSE_GOTO(tdm_err == TDM_ERROR_NONE, pp_fail);
+
+ return EINA_TRUE;
+
+pp_fail:
+ plane->pending_commit_zoom_data_list = eina_list_remove(plane->pending_commit_zoom_data_list, pp_data);
+
+ if (data)
+ e_plane_commit_data_release(data);
+
+ if (pp_data)
+ free(pp_data);
+
+ return EINA_FALSE;
+}
+
+static void
+_e_plane_zoom_set_show(E_Plane *plane)
+{
+ E_Plane_Pp_Data *pp_data = NULL;
+ tbm_surface_h zoom_tsurface = NULL;
+ tbm_error_e tbm_err = TBM_ERROR_NONE;
+ tdm_error tdm_err = TDM_ERROR_NONE;
+
+ if (!plane->tsurface)
+ return;
+
+ if (eina_list_count(plane->pending_commit_zoom_data_list) != 0)
+ return;
+
+ if (plane->pending_commit)
+ return;
+
+ plane->pending_commit = EINA_TRUE;
+
+ tbm_err = tbm_surface_queue_dequeue(plane->zoom_tqueue, &zoom_tsurface);
+ if (tbm_err != TBM_ERROR_NONE)
+ {
+ plane->pending_commit = EINA_FALSE;
+ ERR("_e_plane_zoom_set_show: fail tbm_surface_queue_dequeue");
+ return;
+ }
+ tbm_surface_internal_ref(zoom_tsurface);
+
+ pp_data = E_NEW(E_Plane_Pp_Data, 1);
+ pp_data->zoom_tsurface = zoom_tsurface;
+ pp_data->data = NULL;
+ pp_data->plane = plane;
+
+ plane->pending_commit_zoom_data_list = eina_list_append(plane->pending_commit_zoom_data_list, pp_data);
+
+ if (plane->zoom_rect.x != plane->zoom_rect_temp.x || plane->zoom_rect.y != plane->zoom_rect_temp.y ||
+ plane->zoom_rect.w != plane->zoom_rect_temp.w || plane->zoom_rect.h != plane->zoom_rect_temp.h)
+ {
+ if (!_e_plane_zoom_set_pp_info(plane))
+ {
+ ERR("e_plane_zoom_commit: fail _e_plane_zoom_set_pp_info");
+ goto pp_fail;
+ }
+ }
+
+ tdm_err = tdm_pp_set_done_handler(plane->tpp, _e_plane_zoom_pp_cb, pp_data);
+ EINA_SAFETY_ON_FALSE_GOTO(tdm_err == TDM_ERROR_NONE, pp_fail);
+
+ tdm_err = tdm_pp_attach(plane->tpp, plane->tsurface, zoom_tsurface);
+ EINA_SAFETY_ON_FALSE_GOTO(tdm_err == TDM_ERROR_NONE, pp_fail);
+
+ tdm_err = tdm_pp_commit(plane->tpp);
+ EINA_SAFETY_ON_FALSE_GOTO(tdm_err == TDM_ERROR_NONE, pp_fail);
+
+ DBG("_e_plane_zoom_set_show: done pp_data:%p", pp_data);
+
+ return;
+
+pp_fail:
+ plane->pending_commit = EINA_FALSE;
+ plane->pending_commit_zoom_data_list = eina_list_remove(plane->pending_commit_zoom_data_list, pp_data);
+ tbm_surface_queue_release(plane->zoom_tqueue, zoom_tsurface);
+ tbm_surface_internal_unref(zoom_tsurface);
+ free(pp_data);
+ ERR("_e_plane_zoom_set_show: fail");
+}
+
+static void
+_e_plane_zoom_unset_show(E_Plane *plane)
+{
+ E_Plane_Pp_Data *pp_data = NULL;
+ tbm_surface_info_s src_info, dst_info;
+ tbm_surface_h zoom_tsurface = NULL;
+ tbm_surface_h dst_tsurface = NULL;
+ tbm_error_e tbm_err = TBM_ERROR_NONE;
+ tdm_error tdm_err = TDM_ERROR_NONE;
+ tdm_layer *tlayer = NULL;
+
+ if (!plane->tsurface)
+ return;
+
+ if (eina_list_count(plane->pending_commit_zoom_data_list) != 0)
+ return;
+
+ if (plane->pending_commit)
+ return;
+
+ tbm_err = tbm_surface_queue_dequeue(plane->zoom_tqueue, &zoom_tsurface);
+ if (tbm_err != TBM_ERROR_NONE)
+ {
+ ERR("_e_plane_zoom_unset_show: fail tbm_surface_queue_dequeue");
+ return;
+ }
+ tbm_surface_internal_ref(zoom_tsurface);
+
+ pp_data = E_NEW(E_Plane_Pp_Data, 1);
+ pp_data->zoom_tsurface = zoom_tsurface;
+ pp_data->data = NULL;
+ pp_data->plane = plane;
+
+ plane->pending_commit_zoom_data_list = eina_list_append(plane->pending_commit_zoom_data_list, pp_data);
+
+ tbm_err = tbm_surface_map(plane->tsurface, TBM_SURF_OPTION_READ, &src_info);
+ if (tbm_err != TBM_SURFACE_ERROR_NONE)
+ {
+ ERR("_e_plane_zoom_unset_show: fail to map the src_tsurface.");
+ goto map_fail;
+ }
+
+ tbm_err = tbm_surface_map(zoom_tsurface, TBM_SURF_OPTION_WRITE, &dst_info);
+ if (tbm_err != TBM_SURFACE_ERROR_NONE)
+ {
+ tbm_surface_unmap(plane->tsurface);
+ ERR("_e_plane_zoom_unset_show: fail to map the dst_tsurface.");
+ goto map_fail;
+ }
+ memcpy(dst_info.planes[0].ptr, src_info.planes[0].ptr, src_info.planes[0].size);
+
+ tbm_surface_unmap(zoom_tsurface);
+ tbm_surface_unmap(plane->tsurface);
+
+ _e_plane_zoom_pp_cb(plane->tpp, plane->tsurface, zoom_tsurface, pp_data);
+
+ DBG("_e_plane_zoom_unset_show: done pp_data:%p", pp_data);
+
+ return;
+
+map_fail:
+ plane->pending_commit_zoom_data_list = eina_list_remove(plane->pending_commit_zoom_data_list, pp_data);
+ tbm_surface_queue_release(plane->zoom_tqueue, zoom_tsurface);
+ tbm_surface_internal_unref(zoom_tsurface);
+ free(pp_data);
+ ERR("_e_plane_zoom_unset_show: fail");
+}
+
+EINTERN Eina_Bool
+e_plane_zoom_set(E_Plane *plane, Eina_Rectangle *rect)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(plane, EINA_FALSE);
+
+ E_Comp_Screen *e_comp_screen = NULL;
+ tdm_error ret = TDM_ERROR_NONE;
+ int w, h;
+
+ if (plane->zoom_unset)
+ plane->zoom_unset = EINA_FALSE;
+
+ e_comp_screen = e_comp->e_comp_screen;
+ e_output_size_get(plane->output, &w, &h);
+
+ if (!plane->tpp)
+ {
+ plane->tpp = tdm_display_create_pp(e_comp_screen->tdisplay, &ret);
+ if (ret != TDM_ERROR_NONE)
+ {
+ ERR("fail tdm pp create");
+ goto fail;
+ }
+ }
+
+ if (!plane->zoom_tqueue)
+ {
+ plane->zoom_tqueue = tbm_surface_queue_create(3, w, h, TBM_FORMAT_ARGB8888, plane->buffer_flags | TBM_BO_SCANOUT);
+ if (!plane->zoom_tqueue)
+ {
+ ERR("fail tbm_surface_queue_create");
+ goto fail;
+ }
+ }
+
+ if ((plane->zoom_rect_temp.x == rect->x) && (plane->zoom_rect_temp.y == rect->y) &&
+ (plane->zoom_rect_temp.w == rect->w) && (plane->zoom_rect_temp.h == rect->h))
+ return EINA_TRUE;
+
+ plane->zoom_rect_temp.x = rect->x;
+ plane->zoom_rect_temp.y = rect->y;
+ plane->zoom_rect_temp.w = rect->w;
+ plane->zoom_rect_temp.h = rect->h;
+
+ _e_plane_zoom_set_show(plane);
+
+ return EINA_TRUE;
+
+fail:
+ if (plane->tpp)
+ {
+ tdm_pp_destroy(plane->tpp);
+ plane->tpp = NULL;
+ }
+
+ return EINA_FALSE;
+}
+
+EINTERN void
+e_plane_zoom_unset(E_Plane *plane)
+{
+ EINA_SAFETY_ON_NULL_RETURN(plane);
+
+ plane->zoom_rect.x = plane->zoom_rect_temp.x = 0;
+ plane->zoom_rect.y = plane->zoom_rect_temp.y = 0;
+ plane->zoom_rect.w = plane->zoom_rect_temp.w = 0;
+ plane->zoom_rect.h = plane->zoom_rect_temp.h = 0;
+
+ _e_plane_zoom_unset_show(plane);
+
+ plane->zoom_unset = EINA_TRUE;
+}