E_Video_Hwc *evh; \
evh = container_of(iface, E_Video_Hwc, iface)
-static void _e_video_hwc_render(E_Video_Hwc *evh, const char *func);
+static Eina_Bool _e_video_hwc_render(E_Video_Hwc *evh, const char *func);
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 _e_video_hwc_del(E_Video_Hwc *evh);
static void
_coord_move_to_axis(int x_axis, int y_axis, int *ox, int *oy)
return NULL;
}
-static E_Comp_Wl_Video_Buf *
-_e_video_hwc_buffer_copy(E_Comp_Wl_Video_Buf *vbuf, int aligned_width, Eina_Bool scanout)
-{
- E_Comp_Wl_Video_Buf *temp = NULL;
-
- temp = e_comp_wl_video_buffer_alloc(aligned_width, vbuf->height, vbuf->tbmfmt, scanout);
- EINA_SAFETY_ON_NULL_RETURN_VAL(temp, NULL);
-
- temp->comp_buffer = vbuf->comp_buffer;
-
- VDB("copy vbuf(%d,%dx%d) => vbuf(%d,%dx%d)", NULL,
- MSTAMP(vbuf), vbuf->width_from_pitch, vbuf->height,
- MSTAMP(temp), temp->width_from_pitch, temp->height);
-
- e_comp_wl_video_buffer_copy(vbuf, temp);
-
-#ifdef DUMP_BUFFER
- char file[256];
- static int i;
- snprintf(file, sizeof file, "/tmp/dump/%s_%d.png", "cpy", i++);
- tdm_helper_dump_buffer(temp->tbm_surface, file);
-#endif
-
- return temp;
-}
-
static Eina_Bool
_e_video_hwc_video_buffer_scanout_check(E_Comp_Wl_Video_Buf *vbuf)
{
static E_Comp_Wl_Video_Buf *
_e_video_hwc_pp_input_buffer_get(E_Video_Hwc *evh, E_Comp_Wl_Buffer *comp_buffer)
{
- E_Comp_Wl_Video_Buf *vbuf, *temp;
+ E_Comp_Wl_Video_Buf *vbuf;
Eina_Bool input_buffer_scanout;
- int aligned_width;
vbuf = _e_video_hwc_vbuf_find_with_comp_buffer(evh->input_buffer_list, comp_buffer);
if (vbuf)
}
input_buffer_scanout = _e_video_hwc_video_buffer_scanout_check(vbuf);
+
if (((evh->pp->align != -1) && (vbuf->width_from_pitch % evh->pp->align != 0)) ||
((evh->pp->scanout) && (!input_buffer_scanout)))
{
- if ((evh->pp->align != -1) && (vbuf->width_from_pitch % evh->pp->align != 0))
- aligned_width = ROUNDUP(vbuf->width_from_pitch, evh->pp->align);
- else
- aligned_width = vbuf->width;
-
- temp = _e_video_hwc_buffer_copy(vbuf, aligned_width,
- (input_buffer_scanout || evh->pp->scanout));
+ VER("cannot use this input buffer as an source buffer for pp: "
+ "pp align(%d) bwidth(%d) pp scanout(%d) bscanout(%d)", evh->ec,
+ evh->pp->align, vbuf->width_from_pitch, evh->pp->scanout,
+ input_buffer_scanout);
e_comp_wl_video_buffer_unref(vbuf);
-
- if (!temp)
- return NULL;
-
- vbuf = temp;
+ return NULL;
}
DBG("Buffer(%p) created, refcnt:%d scanout:%d",
E_Video_Hwc *evh;
E_Client *topmost;
Eina_Bool render = EINA_FALSE;
+ Eina_Bool render_fail = EINA_FALSE;
+ Eina_Bool res;
evh = data;
+ evh->render.job = NULL;
+
if (evh->render.map)
{
evh->render.map = EINA_FALSE;
if ((render) || (evh->render.redraw))
{
evh->render.redraw = EINA_FALSE;
- _e_video_hwc_render(evh, __FUNCTION__);
+ render_fail = !_e_video_hwc_render(evh, __FUNCTION__);
}
- evh->render.job = NULL;
+ if ((render_fail) && (evh->render_fail_cb))
+ {
+ res = evh->render_fail_cb(evh->ecv);
+ if (res)
+ {
+ VIN("Delete HWC interface", evh->ec);
+ _e_video_hwc_del(evh);
+ }
+ }
}
static void
return EINA_TRUE;
}
-static void
+static Eina_Bool
_e_video_hwc_render(E_Video_Hwc *evh, const char *func)
{
E_Comp_Wl_Buffer *comp_buffer;
E_Comp_Wl_Video_Buf *input_buffer = NULL;
E_Client *topmost;
- EINA_SAFETY_ON_NULL_RETURN(evh->ec);
+ EINA_SAFETY_ON_NULL_GOTO(evh->ec, done);
/* buffer can be NULL when camera/video's mode changed. Do nothing and
* keep previous frame in this case.
*/
if (!evh->ec->pixmap)
- return;
+ goto done;
if (!_e_video_hwc_client_visible_get(evh->ec))
{
evh->need_force_render = EINA_TRUE;
_e_video_hwc_hide(evh);
- return;
+ goto done;
}
comp_buffer = e_pixmap_resource_get(evh->ec->pixmap);
- if (!comp_buffer) return;
+ if (!comp_buffer) goto done;
evh->tbmfmt = _e_video_hwc_comp_buffer_tbm_format_get(comp_buffer);
topmost = e_comp_wl_topmost_parent_get(evh->ec);
- EINA_SAFETY_ON_NULL_RETURN(topmost);
+ EINA_SAFETY_ON_NULL_GOTO(topmost, done);
if(e_comp_wl_viewport_is_changed(topmost))
{
VIN("need force render", evh->ec);
evh->need_force_render = EINA_TRUE;
}
- return;
+ goto done;
}
DBG("====================================== (%s)", func);
/* Try sending 'wl_surface.frame' in case client
* submitted same 'wl_buffer' */
e_pixmap_image_clear(evh->ec->pixmap, EINA_TRUE);
- return;
+ goto done;
}
evh->need_force_render = EINA_FALSE;
/* 1. non converting case */
input_buffer = _e_video_hwc_input_buffer_get(evh, comp_buffer);
if (!input_buffer)
- return;
+ goto done;
_e_video_hwc_buffer_show(evh, input_buffer, evh->geo.tdm.transform);
}
else
{
if (!_e_video_hwc_pp_render(evh, comp_buffer))
- return;
+ {
+ VER("Failed to PP render", evh->ec);
+ e_pixmap_image_clear(evh->ec->pixmap, EINA_TRUE);
+ goto render_fail;
+ }
}
evh->old_geo = evh->geo;
evh->old_comp_buffer = comp_buffer;
DBG("======================================.");
+
+done:
+ return EINA_TRUE;
+render_fail:
+ return EINA_FALSE;
}
static E_Client *
}
static void
-_e_video_hwc_iface_destroy(E_Video_Comp_Iface *iface)
+_e_video_hwc_del(E_Video_Hwc *evh)
{
E_Comp_Wl_Video_Buf *vbuf;
Eina_List *l = NULL, *ll = NULL;
- IFACE_ENTRY;
-
_e_video_hwc_hide(evh);
EINA_LIST_FOREACH_SAFE(evh->input_buffer_list, l, ll, vbuf)
evh->backend.destroy(evh);
}
+static void
+_e_video_hwc_iface_destroy(E_Video_Comp_Iface *iface)
+{
+ IFACE_ENTRY;
+
+ _e_video_hwc_del(evh);
+}
+
static Eina_Bool
_e_video_hwc_iface_property_get(E_Video_Comp_Iface *iface, unsigned int id, tdm_value *value)
{
}
}
}
+
+/* Sets render fail callback
+ *
+ * @in iface A instance of this composition mode
+ * @in func The function which will be called.
+ *
+ * This function will be called if rendering is failed.
+ * Once this callback funtion has been called, callee will try to replace its
+ * composition interface to another one. And then callee will return TRUE if
+ * the interface is changed successfully.
+ *
+ * @note For this reason described above, it has to free all of resources if
+ * it gets TRUE as a return value. */
+EINTERN void
+e_video_hwc_render_fail_callback_set(E_Video_Comp_Iface *iface, E_Video_Hwc_Render_Fail_Cb func)
+{
+ E_Video_Hwc *evh;
+
+ evh = container_of(iface, E_Video_Hwc, iface);
+ if (!evh)
+ return;
+
+ evh->render_fail_cb = func;
+}