return target;
}
+static const pepper_list_t *
+__tdm_output_get_render_list(pepper_tdm_output_t *output)
+{
+ const pepper_list_t *render_list;
+
+ if (output->hwc)
+ render_list = pepper_hwc_get_render_list(output->hwc->base);
+ else
+ render_list = pepper_plane_get_render_list(output->primary_plane->base);
+
+ return render_list;
+}
+
+static pepper_region_t *
+__tdm_output_get_damage_region(pepper_tdm_output_t *output)
+{
+ pepper_region_t *damage;
+
+ if (output->hwc)
+ damage = pepper_hwc_get_damage_region(output->hwc->base);
+ else
+ damage = pepper_plane_get_damage_region(output->primary_plane->base);
+
+ return damage;
+}
+
+static void
+__tdm_output_clear_damage_region(pepper_tdm_output_t *output)
+{
+ if (output->hwc)
+ pepper_hwc_clear_damage_region(output->hwc->base);
+ else
+ pepper_plane_clear_damage_region(output->primary_plane->base);
+}
+
static void
__tdm_renderer_pixman_render(pepper_tdm_output_t *output)
{
PEPPER_INFO("\n");
- const pepper_list_t *render_list = pepper_plane_get_render_list(
- output->primary_plane->base);
- pepper_region_t *damage = pepper_plane_get_damage_region(
- output->primary_plane->base);
- pepper_region_t total_damage;
- tbm_surface_h back;
+ const pepper_list_t *render_list;
+ pepper_region_t *damage;
+ pepper_region_t total_damage;
+ tbm_surface_h back;
pepper_render_target_t *target;
-
int ret;
+ render_list = __tdm_output_get_render_list(output);
+ damage = __tdm_output_get_damage_region(output);
+
/*Set render target*/
ret = tbm_surface_queue_dequeue(output->tbm_surface_queue, &back);
PEPPER_CHECK(ret == TBM_SURFACE_QUEUE_ERROR_NONE, return,
&total_damage);
pepper_region_fini(&total_damage);
- pepper_plane_clear_damage_region(output->primary_plane->base);
+
+ __tdm_output_clear_damage_region(output);
+
+#if 0 // for debugging
+ static int dump_cnt = 0;
+ char filename[256];
+ snprintf(filename, sizeof filename, "/tmp/pixman_render_%d.png", dump_cnt++);
+ tdm_helper_dump_buffer(back, (const char*)filename);
+#endif
output->back = back;
}
if (output->render_target)
pepper_render_target_destroy(output->render_target);
- if (output->tbm_surface_queue)
- tbm_surface_queue_destroy(output->tbm_surface_queue);
+ if (output->tbm_surface_queue) {
+ // DO NOT destroy tbm_surface_queue_h
+ if (output->hwc)
+ output->tbm_surface_queue = NULL;
+ else
+ tbm_surface_queue_destroy(output->tbm_surface_queue);
+ }
output->renderer = NULL;
output->render_target = NULL;
static void
__tdm_renderer_pixman_init(pepper_tdm_output_t *output)
{
- pepper_tdm_t *tdm = output->tdm;
+ pepper_tdm_t *tdm = output->tdm;
+ pepper_tdm_hwc_t *hwc = output->hwc;
+
const tdm_output_mode *mode;
tdm_error err = TDM_ERROR_NONE;
err = tdm_output_get_mode(output->toutput, &mode);
PEPPER_CHECK(err == TDM_ERROR_NONE, goto error,
- "tdm_output_get_mode() failed.\n");
- output->tbm_surface_queue = tbm_surface_queue_create(3,
- mode->hdisplay, mode->vdisplay,
- TBM_FORMAT_XBGR8888, TBM_BO_SCANOUT);
- PEPPER_CHECK(output->tbm_surface_queue, goto error,
- "tbm_surface_queue_create() failed.\n");
+ "tdm_output_get_mode() failed.\n");
+
+ if (output->hwc) {
+ output->tbm_surface_queue = tdm_hwc_get_client_target_buffer_queue(hwc->thwc, &err);
+ PEPPER_CHECK(output->tbm_surface_queue, goto error,
+ "tdm_hwc_get_client_target_buffer_queue() failed.\n");
+ } else {
+ output->tbm_surface_queue = tbm_surface_queue_create(3,
+ mode->hdisplay, mode->vdisplay,
+ TBM_FORMAT_XBGR8888, TBM_BO_SCANOUT);
+ PEPPER_CHECK(output->tbm_surface_queue, goto error,
+ "tbm_surface_queue_create() failed.\n");
+ }
pepper_region_init(&output->previous_damage);
output->render_type = TDM_RENDER_TYPE_PIXMAN;
PEPPER_INFO("\n");
int ret;
+ const pepper_list_t *render_list;
+ pepper_region_t *damage;
- const pepper_list_t *render_list = pepper_plane_get_render_list(
- output->primary_plane->base);
- pepper_region_t *damage = pepper_plane_get_damage_region(
- output->primary_plane->base);
+ render_list = __tdm_output_get_render_list(output);
+ damage = __tdm_output_get_damage_region(output);
pepper_renderer_repaint_output(output->renderer, output->base, render_list,
- damage);
+ damage);
ret = tbm_surface_queue_can_acquire(output->tbm_surface_queue, 1);
PEPPER_CHECK(ret > 0, return, "tbm_surface_queue_can_acquire() failed.\n");
PEPPER_CHECK(ret == TBM_SURFACE_QUEUE_ERROR_NONE, return,
"tbm_surface_queue_acquire() failed.\n");
- pepper_plane_clear_damage_region(output->primary_plane->base);
+ __tdm_output_clear_damage_region(output);
}
static void
if (output->render_target)
pepper_render_target_destroy(output->render_target);
- if (output->tbm_surface_queue)
- tbm_surface_queue_destroy(output->tbm_surface_queue);
+ if (output->tbm_surface_queue) {
+ // DO NOT destroy tbm_surface_queue_h
+ if (output->hwc)
+ output->tbm_surface_queue = NULL;
+ else
+ tbm_surface_queue_destroy(output->tbm_surface_queue);
+ }
output->renderer = NULL;
output->render_target = NULL;
{
PEPPER_INFO("\n");
- pepper_tdm_t *tdm = output->tdm;
+ pepper_tdm_t *tdm = output->tdm;
+ pepper_tdm_hwc_t *hwc = output->hwc;
const tdm_output_mode *mode;
- uint32_t native_visual_id = TBM_FORMAT_XRGB8888;
- tdm_error err = TDM_ERROR_NONE;
+ uint32_t native_visual_id = TBM_FORMAT_XRGB8888;
+ tdm_error err = TDM_ERROR_NONE;
if (!tdm->gl_renderer) {
tdm->gl_renderer = pepper_gl_renderer_create(tdm->compositor, tdm->bufmgr,
PEPPER_CHECK(err == TDM_ERROR_NONE, goto error,
"tdm_output_get_mode() failed.\n");
- output->tbm_surface_queue = tbm_surface_queue_create(3,
- mode->hdisplay, mode->vdisplay,
- TBM_FORMAT_XRGB8888,
- TBM_BO_SCANOUT);
- PEPPER_CHECK(output->tbm_surface_queue, goto error,
- "tbm_surface_queue_create() failed.\n");
-
- output->render_target = pepper_gl_renderer_create_target(tdm->gl_renderer,
- output->tbm_surface_queue,
- PEPPER_FORMAT_XRGB8888,
- &native_visual_id,
- mode->hdisplay, mode->vdisplay);
+ if (output->hwc) {
+ output->tbm_surface_queue = tdm_hwc_get_client_target_buffer_queue(hwc->thwc, &err);
+ PEPPER_CHECK(err == TDM_ERROR_NONE, goto error,
+ "tdm_hwc_get_client_target_buffer_queue() failed.\n");
+ output->render_target = pepper_gl_renderer_create_target(tdm->gl_renderer,
+ output->tbm_surface_queue,
+ PEPPER_FORMAT_XRGB8888,
+ &native_visual_id,
+ mode->hdisplay, mode->vdisplay);
+ } else {
+ output->tbm_surface_queue = tbm_surface_queue_create(3,
+ mode->hdisplay, mode->vdisplay,
+ TBM_FORMAT_XRGB8888,
+ TBM_BO_SCANOUT);
+ PEPPER_CHECK(output->tbm_surface_queue, goto error,
+ "tbm_surface_queue_create() failed.\n");
+
+ output->render_target = pepper_gl_renderer_create_target(tdm->gl_renderer,
+ output->tbm_surface_queue,
+ PEPPER_FORMAT_XRGB8888,
+ &native_visual_id,
+ mode->hdisplay, mode->vdisplay);
+ }
PEPPER_CHECK(output->render_target, goto error,
"pepper_gl_renderer_create_target() failed.\n");
output->render_type = TDM_RENDER_TYPE_GL;
}
static void
+__tdm_hwc_destroy(pepper_event_listener_t *listener, pepper_object_t *object,
+ uint32_t id, void *info, void *data)
+{
+ PEPPER_INFO("\n");
+
+ free(data);
+}
+
+static int
+__tdm_output_hwc_init(pepper_tdm_output_t *output)
+{
+ pepper_tdm_hwc_t *hwc;
+ tdm_hwc *thwc;
+ tdm_error err;
+
+ PEPPER_INFO("\n");
+
+ hwc = (pepper_tdm_hwc_t *)calloc(1, sizeof(pepper_tdm_hwc_t));
+ PEPPER_CHECK(hwc, return PEPPER_FALSE, "calloc failed\n");
+ hwc->output = output;
+
+ thwc = tdm_output_get_hwc(output->toutput, &err);
+ PEPPER_CHECK(thwc, goto error, "Failed to get tdm_hwc\n");
+ hwc->thwc = thwc;
+
+ err = tdm_hwc_get_capabilities(hwc->thwc, &hwc->caps);
+ PEPPER_CHECK(err == TDM_ERROR_NONE, goto error,
+ "tdm_hwc_get_capabilities failed err:%d\n", err);
+
+ // TODO: check and save the video capabiliites. initialize the video capabilities.
+ /* for examples below.
+ // hwc video capabilities
+ if (hwc_caps & TDM_HWC_CAPABILITY_VIDEO_STREAM)
+ hwc->tdm_hwc_video_stream = EINA_TRUE;
+ if (hwc_caps & TDM_HWC_CAPABILITY_VIDEO_SCALE)
+ hwc->tdm_hwc_video_scale = EINA_TRUE;
+ if (hwc_caps & TDM_HWC_CAPABILITY_VIDEO_TRANSFORM)
+ hwc->tdm_hwc_video_transform = EINA_TRUE;
+ if (hwc_caps & TDM_HWC_CAPABILITY_VIDEO_SCANOUT)
+ hwc->tdm_hwc_video_scanout = EINA_TRUE;
+ if (hwc_caps & TDM_HWC_CAPABILITY_FENCE)
+ hwc->tdm_hwc_fence = EINA_TRUE;
+ */
+
+ // initialize a hwc_window list.
+ pepper_list_init(&hwc->window_list);
+
+ // Add pepper_hwc of pepper_output and set it to hwc->base
+ hwc->base = pepper_output_initialize_hwc(output->base);
+ PEPPER_CHECK(hwc->base, goto error, "pepper_output_initialize_hwc() failed\n");
+
+ // add destory handler for pepper_hwc object
+ pepper_object_add_event_listener((pepper_object_t *)hwc->base,
+ PEPPER_EVENT_OBJECT_DESTROY,
+ 0,
+ __tdm_hwc_destroy, hwc);
+
+ output->hwc = hwc;
+
+ return PEPPER_TRUE;
+
+error:
+ if (hwc->base)
+ pepper_hwc_destroy(hwc->base);
+
+ if (hwc)
+ free(hwc);
+
+ return PEPPER_FALSE;
+}
+
+static void
__tdm_plane_destroy(pepper_event_listener_t *listener, pepper_object_t *object,
uint32_t id, void *info, void *data)
{
/* TODO: */
+ if (output->hwc)
+ pepper_hwc_destroy(output->hwc->base);
+
free(output);
}
PEPPER_INFO("\n");
- pepper_list_for_each_list(l, view_list) {
- pepper_view_t *view = l->item;
- pepper_plane_t *plane = NULL;
+ if (output->hwc) {
+ // update info, buffer, compostiion type of hwc_windows
+ if (!pepper_tdm_hwc_update_changes(output->hwc, view_list))
+ return;
- plane = output->primary_plane->base;
+ if (!pepper_tdm_hwc_evaluate(output->hwc, view_list))
+ return;
+ } else {
+ pepper_list_for_each_list(l, view_list) {
+ pepper_view_t *view = l->item;
+ pepper_plane_t *plane = NULL;
- pepper_view_assign_plane(view, output->base, plane);
+ plane = output->primary_plane->base;
+
+ pepper_view_assign_plane(view, output->base, plane);
+ }
}
}
PEPPER_INFO("\n");
pepper_tdm_output_t *output = (pepper_tdm_output_t *)o;
- struct timespec ts;
+ struct timespec ts;
pepper_compositor_get_time(output->tdm->compositor, &ts);
pepper_output_finish_frame(output->base, &ts);
PEPPER_INFO("\n");
pepper_tdm_output_t *output = (pepper_tdm_output_t *)o;
- tdm_error err;
+ tdm_error terror;
+ // render
if (!output->back) {
if (output->render_type == TDM_RENDER_TYPE_GL)
__tdm_renderer_gl_render(output);
}
}
- if (output->back) {
- err = tdm_layer_set_buffer((tdm_layer *)output->primary_plane->layer,
- output->back);
- PEPPER_CHECK(err == TDM_ERROR_NONE, return, "tdm_layer_set_buffer() failed");
+ // TODO: fix this...
+ if (!output->back)
+ return;
+
+ if (output->hwc) {
+ // set back buffer as a client_target_buffer
+ pepper_tdm_hwc_set_client_target_buffer(output->hwc, output->back);
+
+ if (!pepper_tdm_hwc_commit(output->hwc))
+ return;
+
+ output->page_flip_pending = PEPPER_TRUE;
+ } else {
+ terror = tdm_layer_set_buffer((tdm_layer *)output->primary_plane->layer,
+ output->back);
+ PEPPER_CHECK(terror == TDM_ERROR_NONE, return, "tdm_layer_set_buffer() failed");
- err = tdm_output_commit(output->toutput, 0, __tdm_output_commit_cb, output);
- PEPPER_CHECK(err == TDM_ERROR_NONE, return, "tdm_output_commit() failed");
+ terror = tdm_output_commit(output->toutput, 0, __tdm_output_commit_cb, output);
+ PEPPER_CHECK(terror == TDM_ERROR_NONE, return, "tdm_output_commit() failed");
output->page_flip_pending = PEPPER_TRUE;
}
PEPPER_INFO("\n");
pepper_tdm_output_t *output = (pepper_tdm_output_t *)o;
+
+ if (output->hwc)
+ pepper_tdm_hwc_attach_surface(output->hwc, surface);
+
pepper_renderer_attach_surface(output->renderer, surface, w, h);
}
static void
pepper_tdm_output_flush_surface_damage(void *o, pepper_surface_t *surface,
- pepper_bool_t *keep_buffer)
+ pepper_bool_t *keep_buffer)
{
PEPPER_INFO("\n");
} else {
*keep_buffer = PEPPER_TRUE;
}
+
+ // HWC :
}
struct pepper_output_backend tdm_output_backend = {
pepper_tdm_output_init(pepper_tdm_t *tdm)
{
pepper_tdm_output_t *output;
+ tdm_hwc *thwc;
tdm_error err;
int i;
"tdm_output_set_mode() failed err:%d\n", err);
}
+ /*Add pepper_output to compositor*/
+ output->base = pepper_compositor_add_output(tdm->compositor,
+ &tdm_output_backend,
+ "tdm_output",
+ output,
+ WL_OUTPUT_TRANSFORM_NORMAL, 1);
+ PEPPER_CHECK(err == TDM_ERROR_NONE, goto error,
+ "pepper_compositor_add_output() failed err:%d\n", err);
+
+ // check if tdm_output has tdm_hwc.
+ thwc = tdm_output_get_hwc(output->toutput, &err);
+ if (thwc && err == TDM_ERROR_NONE)
+ PEPPER_CHECK(PEPPER_TRUE == __tdm_output_hwc_init(output), goto error,
+ "pepper_tdm_hwc_init() failed\n");
+ else
+ PEPPER_CHECK(PEPPER_TRUE == __tdm_output_plane_init(output), goto error,
+ "pepper_tdm_plane_init() failed\n");
+
/*Setup renderer*/
if (render_env && !strcmp(render_env, "gl")) {
__tdm_renderer_gl_init(output);
PEPPER_CHECK(output->renderer, goto error,
"Failed to initialize pixman_renderer.\n");
}
-
- /*Add pepper_output to compositor*/
- output->base = pepper_compositor_add_output(tdm->compositor,
- &tdm_output_backend,
- "tdm_output",
- output,
- WL_OUTPUT_TRANSFORM_NORMAL, 1);
- PEPPER_CHECK(err == TDM_ERROR_NONE, goto error,
- "pepper_compositor_add_output() failed err:%d\n", err);
-
- PEPPER_CHECK(PEPPER_TRUE == __tdm_output_plane_init(output), goto error,
- "pepper_tdm_plane_init() failed\n");
}
return PEPPER_TRUE;