typedef struct _tdm_sprd_output_data tdm_sprd_output_data;
typedef struct _tdm_sprd_layer_data tdm_sprd_layer_data;
+typedef struct _tdm_sprd_hwc_data tdm_sprd_hwc_data;
typedef struct _tdm_sprd_hwc_window_data tdm_sprd_hwc_window_data;
typedef struct _tdm_sprd_vblank_data_s tdm_sprd_vblank_data;
tdm_output_dpms dpms_value;
- tdm_sprd_hwc_window_data *target_hwc_window;
- tdm_sprd_hwc_window_data *video_hwc_window;
-
- int need_validate;
- int need_target_buffer;
-
struct list_head capture_list;
- struct list_head hwc_window_list;
+
+ /* hwc data */
+ tdm_sprd_hwc_data *hwc_data;
};
struct _tdm_sprd_layer_data {
int need_unset;
};
+struct _tdm_sprd_hwc_data {
+ tdm_sprd_hwc_window_data *target_hwc_window;
+
+ int need_validate;
+ int need_target_window;
+ int need_set_crtc;
+
+ int target_window_zpos;
+
+ tdm_sprd_output_data *output_data;
+ struct list_head hwc_window_list;
+
+ tdm_hwc_commit_handler commit_func;
+};
+
struct _tdm_sprd_hwc_window_data {
struct list_head link;
/* data which are fixed at initializing */
- tdm_sprd_data *sprd_data;
- tdm_sprd_output_data *output_data;
+ tdm_sprd_hwc_data *hwc_data;
/* not fixed data below */
tdm_hwc_window_info info;
TBM_FORMAT_YUV420
};
-tdm_hwc_window * _sprd_output_hwc_window_create(tdm_output *output, tdm_hwc_window_info *info, tdm_error *error);
+static const char *
+_comp_to_str(tdm_hwc_window_composition composition_type)
+{
+ if (composition_type == TDM_COMPOSITION_CLIENT)
+ return "CLIENT";
+ else if (composition_type == TDM_COMPOSITION_DEVICE_CANDIDATE)
+ return "DEVICE_CANDIDATE";
+ else if (composition_type == TDM_COMPOSITION_DEVICE)
+ return "DEVICE";
+ else if (composition_type == TDM_COMPOSITION_CURSOR)
+ return "CURSOR";
+ else if (composition_type == TDM_COMPOSITION_NONE)
+ return "NONE";
+
+ return "unknown";
+}
+
+static tbm_surface_queue_h
+_sprd_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error)
+{
+ tdm_sprd_hwc_window_data *hwc_window_data = NULL;
+ tbm_surface_queue_h tqueue = NULL;
+
+ if (error)
+ *error = TDM_ERROR_INVALID_PARAMETER;
+
+ RETURN_VAL_IF_FAIL(hwc_window != NULL, NULL);
+ hwc_window_data = hwc_window;
+
+ int wight = hwc_window_data->info.src_config.size.h;
+ int hight = hwc_window_data->info.src_config.size.v;
+ tbm_format format = hwc_window_data->info.src_config.format;
+ tqueue = tbm_surface_queue_create(3, wight, hight, format, TBM_BO_SCANOUT);
+ if (error)
+ *error = TDM_ERROR_OPERATION_FAILED;
+ RETURN_VAL_IF_FAIL(tqueue != NULL, NULL);
+
+ if (error)
+ *error = TDM_ERROR_NONE;
+
+ return tqueue;
+}
#if 0
static tdm_error
}
static tdm_error
-_sprd_layer_attach_window(tdm_sprd_layer_data *layer_data, tdm_sprd_hwc_window_data *hwc_window_data)
-{
- tdm_error ret = TDM_ERROR_NONE;
-
- RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_OPERATION_FAILED);
-
- if (hwc_window_data == NULL || hwc_window_data->display_buffer == NULL) {
- ret = sprd_layer_unset_buffer(layer_data);
- RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
- } else {
- ret = sprd_layer_set_info((tdm_layer *)layer_data, (tdm_info_layer *)&(hwc_window_data->info));
- RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
- RETURN_VAL_IF_FAIL(hwc_window_data->display_buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
- ret = sprd_layer_set_buffer(layer_data, hwc_window_data->display_buffer->buffer);
- RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
- }
- return ret;
-}
-
-static tdm_error
_tdm_sprd_display_do_commit(tdm_sprd_output_data *output_data)
{
tdm_error res = TDM_ERROR_NONE;
tdm_sprd_pp_handler(prop_id, buf_idx, tv_sec, tv_usec, user_data);
}
#endif
+
#if 0
static int
_tdm_sprd_display_events_handle(int fd, Drm_Event_Context *evctx)
free(output_data);
return NULL;
}
+
LIST_INITHEAD(&output_data->capture_list);
- if (sprd_data->hwc_mode)
- LIST_INITHEAD(&output_data->hwc_window_list);
+
return output_data;
}
-void
-tdm_sprd_display_destroy_output_list(tdm_sprd_data *sprd_data)
+tdm_sprd_layer_data *
+_sprd_output_get_layer(tdm_sprd_output_data *output_data, int index)
{
- tdm_sprd_output_data *o = NULL, *oo = NULL;
-
- if (LIST_IS_EMPTY(&sprd_data->output_list))
- return;
+ RETURN_VAL_IF_FAIL(output_data, NULL);
- LIST_FOR_EACH_ENTRY_SAFE(o, oo, &sprd_data->output_list, link) {
- LIST_DEL(&o->link);
- if (o->fb_fd > 0)
- close(o->fb_fd);
- if (!LIST_IS_EMPTY(&o->capture_list)) {
- tdm_sprd_output_capture_data *l = NULL, *ll = NULL;
- LIST_FOR_EACH_ENTRY_SAFE(l, ll, &o->capture_list, link) {
- sprd_capture_destroy(l->tdm_capture_p);
- }
- }
- if (!LIST_IS_EMPTY(&o->layer_list)) {
- tdm_sprd_layer_data *l = NULL, *ll = NULL;
- LIST_FOR_EACH_ENTRY_SAFE(l, ll, &o->layer_list, link) {
- LIST_DEL(&l->link);
- free(l);
- }
- }
- free(o->output_modes);
- free(o);
- }
+ tdm_sprd_layer_data *l = NULL;
+ LIST_FOR_EACH_ENTRY(l, &output_data->layer_list, link)
+ if (l->zpos == index)
+ return l;
+ return NULL;
}
-tdm_error
-tdm_sprd_display_create_output_list(tdm_sprd_data *sprd_data)
+#if 0
+static tdm_error
+_sprd_layer_attach_window(tdm_sprd_layer_data *layer_data, tdm_sprd_hwc_window_data *hwc_window_data)
{
- tdm_sprd_output_data *output_data = NULL;
-
- RETURN_VAL_IF_FAIL(LIST_IS_EMPTY(&sprd_data->output_list), TDM_ERROR_OPERATION_FAILED);
-
- //have only LCD output
- output_data = _tdm_sprd_display_create_output_LCD(sprd_data);
- RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_OPERATION_FAILED);
- LIST_ADDTAIL(&output_data->link, &sprd_data->output_list);
- sprd_data->output_count = 1;
+ tdm_error ret = TDM_ERROR_NONE;
- TDM_DBG("output count: %d", sprd_data->output_count);
+ RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_OPERATION_FAILED);
- return TDM_ERROR_NONE;
+ if (hwc_window_data == NULL || hwc_window_data->display_buffer == NULL) {
+ ret = sprd_layer_unset_buffer(layer_data);
+ RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
+ } else {
+ ret = sprd_layer_set_info((tdm_layer *)layer_data, (tdm_info_layer *)&(hwc_window_data->info));
+ RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
+ RETURN_VAL_IF_FAIL(hwc_window_data->display_buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
+ ret = sprd_layer_set_buffer(layer_data, hwc_window_data->display_buffer->buffer);
+ RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
+ }
+ return ret;
}
-void
-tdm_sprd_display_destroy_buffer_list(tdm_sprd_data *sprd_data)
+static int
+_get_number_of_visible_windows(tdm_sprd_output_data *output_data)
{
- tdm_sprd_display_buffer *b = NULL, *bb = NULL;
+ int number = 0;
+ tdm_sprd_hwc_window_data *window = NULL;
- LIST_FOR_EACH_ENTRY_SAFE(b, bb, &sprd_data->buffer_list, link) {
- tdm_buffer_remove_destroy_handler(b->buffer, _tdm_sprd_display_cb_destroy_buffer, sprd_data);
- _tdm_sprd_display_cb_destroy_buffer(b->buffer, sprd_data);
- }
-}
+ RETURN_VAL_IF_FAIL(output_data, 0);
-tdm_error
-sprd_display_get_capability(tdm_backend_data *bdata, tdm_caps_display *caps)
-{
- RETURN_VAL_IF_FAIL(caps, TDM_ERROR_INVALID_PARAMETER);
+ LIST_FOR_EACH_ENTRY(window, &output_data->hwc_window_list, link) {
+ if (window->client_type == TDM_COMPOSITION_NONE)
+ continue;
- caps->max_layer_count = -1; /* not defined */
+ number++;
+ }
- return TDM_ERROR_NONE;
+ return number;
}
-tdm_error
-sprd_display_get_pp_capability(tdm_backend_data *bdata, tdm_caps_pp *caps)
-{
- return tdm_sprd_pp_get_capability(bdata, caps);
-}
+static tdm_error
+_tdm_sprd_display_prepare_commit(tdm_sprd_output_data *output_data) {
-tdm_output **
-sprd_display_get_outputs(tdm_backend_data *bdata, int *count, tdm_error *error)
-{
- tdm_sprd_data *sprd_data = bdata;
- tdm_sprd_output_data *output_data = NULL;
- tdm_output **outputs;
- tdm_error ret;
- int i;
+ tdm_sprd_layer_data * layer = NULL;
+ int i = HW_LAYER_NUM-1;
+ tdm_sprd_hwc_window_data *hwc_window_data = NULL;
- RETURN_VAL_IF_FAIL(sprd_data, NULL);
- RETURN_VAL_IF_FAIL(count, NULL);
+ RETURN_VAL_IF_FAIL(output_data->need_validate == 0, TDM_ERROR_OPERATION_FAILED);
- *count = 0;
- LIST_FOR_EACH_ENTRY(output_data, &sprd_data->output_list, link)
- (*count)++;
+ if (!_get_number_of_visible_windows(output_data))
+ output_data->need_target_buffer = 1;
- if (*count == 0) {
- ret = TDM_ERROR_NONE;
- goto failed_get;
+ /* set target hwc window */
+ if (output_data->need_target_buffer) {
+ layer = _sprd_output_get_layer(output_data, i--);
+ _sprd_layer_attach_window(layer, output_data->target_hwc_window);
}
- /* will be freed in frontend */
- outputs = calloc(*count, sizeof(tdm_sprd_output_data *));
- if (!outputs) {
- TDM_ERR("failed: alloc memory");
- *count = 0;
- ret = TDM_ERROR_OUT_OF_MEMORY;
- goto failed_get;
+ /* set hwc windows */
+ LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &output_data->hwc_window_list, link) {
+ if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
+ continue;
+ if (hwc_window_data->client_type != TDM_COMPOSITION_DEVICE)
+ continue;
+ if (i < 0)
+ return TDM_ERROR_OPERATION_FAILED;
+ layer = _sprd_output_get_layer(output_data, i--);
+ _sprd_layer_attach_window(layer, hwc_window_data);
}
- i = 0;
- LIST_FOR_EACH_ENTRY(output_data, &sprd_data->output_list, link)
- outputs[i++] = output_data;
-
- if (error)
- *error = TDM_ERROR_NONE;
+ /* disable unused layer */
+ while (i >= 0) {
+ layer = _sprd_output_get_layer(output_data, i--);
+ _sprd_layer_attach_window(layer, NULL);
+ }
- return outputs;
-failed_get:
- if (error)
- *error = ret;
- return NULL;
+ return TDM_ERROR_NONE;
}
+#endif
-tdm_error
-sprd_display_get_fd(tdm_backend_data *bdata, int *fd)
+tdm_sprd_display_buffer *
+_tdm_sprd_display_creat_buffer(tdm_sprd_data *sprd_data, tbm_surface_h surface, tdm_error * err)
{
- tdm_sprd_data *sprd_data = bdata;
-
- RETURN_VAL_IF_FAIL(sprd_data, TDM_ERROR_INVALID_PARAMETER);
- RETURN_VAL_IF_FAIL(fd, TDM_ERROR_INVALID_PARAMETER);
-
- *fd = sprd_data->drm_fd;
+ int i, count;
+ int bw, bh;
+ tdm_sprd_display_buffer * display_buffer = NULL;
+ tdm_error res = TDM_ERROR_NONE;
- return TDM_ERROR_NONE;
-}
+ RETURN_VAL_IF_FAIL(sprd_data, NULL);
+ RETURN_VAL_IF_FAIL(surface, NULL);
-tdm_error
+ display_buffer = calloc(1, sizeof(tdm_sprd_display_buffer));
+ if (!display_buffer) {
+ if (err)
+ *err = TDM_ERROR_OUT_OF_MEMORY;
+ return NULL;
+ }
+
+ display_buffer->buffer = surface;
+
+ res = tdm_buffer_add_destroy_handler(surface, _tdm_sprd_display_cb_destroy_buffer, sprd_data);
+ if (res != TDM_ERROR_NONE) {
+ if (err)
+ *err = res;
+ TDM_ERR("add destroy handler fail");
+ free(display_buffer);
+ return NULL;
+ }
+
+ tdm_helper_get_buffer_full_size(surface, &bw, &bh);
+
+ display_buffer->width = bw;
+ display_buffer->height = bh;
+ display_buffer->format = tbm_surface_get_format(surface);
+ display_buffer->count = tbm_surface_internal_get_num_bos(surface);
+ count = tbm_surface_internal_get_num_planes(display_buffer->format);
+ TDM_DBG("create buffer: %dx%d %c%c%c%c bo_num:%d plane_num:%d",
+ display_buffer->width, display_buffer->height, FOURCC_STR(display_buffer->format),
+ display_buffer->count, count);
+
+ for (i = 0; i < display_buffer->count; i++) {
+ tbm_bo bo = tbm_surface_internal_get_bo(surface, i);
+ display_buffer->handles[i] = tbm_bo_get_handle(bo, TBM_DEVICE_DEFAULT).u32;
+ display_buffer->name[i] = tbm_bo_export(bo);
+ TDM_DBG(" create buffer: bo%d(name:%d handle:%d)", i, display_buffer->name[i],
+ display_buffer->handles[i]);
+ }
+ for (i = 0; i < count; i++) {
+ tbm_surface_internal_get_plane_data(surface, i, &display_buffer->size, &display_buffer->offsets[i],
+ &display_buffer->pitches[i]);
+ TDM_DBG(" create buffer: plane%d(size:%d offset:%d pitch:%d)", i, display_buffer->size,
+ display_buffer->offsets[i], display_buffer->pitches[i]);
+ }
+
+ if (IS_RGB(display_buffer->format))
+ display_buffer->width = display_buffer->pitches[0] >> 2;
+ else
+ display_buffer->width = display_buffer->pitches[0];
+
+ if (err)
+ *err = TDM_ERROR_NONE;
+
+ return display_buffer;
+}
+
+static int
+_sprd_drm_user_handler(struct drm_event *event)
+{
+ RETURN_VAL_IF_FAIL(event, -1);
+
+ TDM_DBG("got event %d\n", event->type);
+
+ if (event->type != DRM_SPRD_IPP_EVENT)
+ return -1;
+ tdm_sprd_pp_handler((struct drm_sprd_ipp_event *) event);
+
+ return 0;
+}
+
+static void
+_sprd_drm_vblank_event(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data)
+{
+ tdm_sprd_vblank_data *vblank_data = (tdm_sprd_vblank_data *) user_data;
+ tdm_sprd_output_data *output_data;
+ tdm_sprd_layer_data *layer_data = NULL;
+
+ if (!vblank_data) {
+ TDM_ERR("no vblank data");
+ return;
+ }
+
+ output_data = vblank_data->output_data;
+ if (!output_data) {
+ TDM_ERR("no output data");
+ return;
+ }
+ switch (vblank_data->type) {
+ case VBLANK_TYPE_WAIT:
+ if (output_data->vblank_func)
+ output_data->vblank_func(output_data, sequence, tv_sec, tv_usec, vblank_data->user_data);
+ break;
+ case VBLANK_TYPE_COMMIT:
+ LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
+ if (layer_data->need_unset) {
+ _tdm_sprd_display_layer_disable(layer_data);
+ layer_data->need_unset = 0;
+ }
+ }
+
+ if (output_data->commit_func)
+ output_data->commit_func(output_data, sequence, tv_sec, tv_usec, vblank_data->user_data);
+
+ break;
+ default:
+ break;
+ }
+ free(vblank_data);
+}
+
+static void
+_sprd_drm_flip_complete_event(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data)
+{
+ TDM_DBG("FLIP EVENT");
+}
+
+#if 0
+static int
+_sprd_layer_is_supported_format(tdm_sprd_layer_data *layer_data, tbm_format format)
+{
+ RETURN_VAL_IF_FAIL(layer_data, 0);
+ return IS_RGB(format);
+}
+
+static int
+_sprd_hwc_window_is_reserved_buffer(tdm_sprd_hwc_window_data *hwc_window_data) {
+ tbm_bo bo = NULL;
+ int falgs = 0;
+
+ RETURN_VAL_IF_FAIL(hwc_window_data != NULL, 0);
+ RETURN_VAL_IF_FAIL(hwc_window_data->display_buffer != NULL, 0);
+
+ bo = tbm_surface_internal_get_bo(hwc_window_data->display_buffer->buffer, 0);
+ RETURN_VAL_IF_FAIL(bo != NULL, 0);
+
+ falgs = tbm_bo_get_flags(bo);
+
+ return falgs & TBM_BO_SCANOUT;
+}
+#endif
+
+int
+_sprd_output_get_changed_number(tdm_sprd_hwc_data *hwc_data)
+{
+ int num = 0;
+ tdm_sprd_hwc_window_data *hwc_window_data = NULL;
+
+ LIST_FOR_EACH_ENTRY(hwc_window_data, &hwc_data->hwc_window_list, link) {
+ if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
+ continue;
+
+ if (hwc_window_data->client_type != hwc_window_data->validated_type)
+ num++;
+ }
+
+ return num;
+}
+
+static tdm_hwc_window *
+_sprd_hwc_create_window(tdm_sprd_hwc_data *hwc_data, tdm_hwc_window_info *info, tdm_error *error)
+{
+ tdm_sprd_hwc_window_data *hwc_window_data = NULL;
+
+ if (error)
+ *error = TDM_ERROR_NONE;
+
+ hwc_window_data = calloc(1, sizeof(tdm_sprd_hwc_window_data));
+ if (!hwc_window_data) {
+ TDM_ERR("alloc failed");
+ if (error)
+ *error = TDM_ERROR_OUT_OF_MEMORY;
+ return NULL;
+ }
+
+ hwc_window_data->hwc_data = hwc_data;
+
+ if (info)
+ memcpy(&hwc_window_data->info, info, sizeof(tdm_hwc_window_info));
+
+ LIST_INITHEAD(&hwc_window_data->link);
+
+ return hwc_window_data;
+}
+
+void
+tdm_sprd_display_destroy_output_list(tdm_sprd_data *sprd_data)
+{
+ tdm_sprd_output_data *o = NULL, *oo = NULL;
+
+ if (LIST_IS_EMPTY(&sprd_data->output_list))
+ return;
+
+ LIST_FOR_EACH_ENTRY_SAFE(o, oo, &sprd_data->output_list, link) {
+ LIST_DEL(&o->link);
+ if (o->fb_fd > 0)
+ close(o->fb_fd);
+ if (!LIST_IS_EMPTY(&o->capture_list)) {
+ tdm_sprd_output_capture_data *l = NULL, *ll = NULL;
+ LIST_FOR_EACH_ENTRY_SAFE(l, ll, &o->capture_list, link) {
+ sprd_capture_destroy(l->tdm_capture_p);
+ }
+ }
+ if (!LIST_IS_EMPTY(&o->layer_list)) {
+ tdm_sprd_layer_data *l = NULL, *ll = NULL;
+ LIST_FOR_EACH_ENTRY_SAFE(l, ll, &o->layer_list, link) {
+ LIST_DEL(&l->link);
+ free(l);
+ }
+ }
+ free(o->output_modes);
+ free(o);
+ }
+}
+
+tdm_error
+tdm_sprd_display_create_output_list(tdm_sprd_data *sprd_data)
+{
+ tdm_sprd_output_data *output_data = NULL;
+
+ RETURN_VAL_IF_FAIL(LIST_IS_EMPTY(&sprd_data->output_list), TDM_ERROR_OPERATION_FAILED);
+
+ //have only LCD output
+ output_data = _tdm_sprd_display_create_output_LCD(sprd_data);
+ RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_OPERATION_FAILED);
+ LIST_ADDTAIL(&output_data->link, &sprd_data->output_list);
+ sprd_data->output_count = 1;
+
+ TDM_DBG("output count: %d", sprd_data->output_count);
+
+ return TDM_ERROR_NONE;
+}
+
+void
+tdm_sprd_display_destroy_buffer_list(tdm_sprd_data *sprd_data)
+{
+ tdm_sprd_display_buffer *b = NULL, *bb = NULL;
+
+ LIST_FOR_EACH_ENTRY_SAFE(b, bb, &sprd_data->buffer_list, link) {
+ tdm_buffer_remove_destroy_handler(b->buffer, _tdm_sprd_display_cb_destroy_buffer, sprd_data);
+ _tdm_sprd_display_cb_destroy_buffer(b->buffer, sprd_data);
+ }
+}
+
+tdm_error
+sprd_display_get_capability(tdm_backend_data *bdata, tdm_caps_display *caps)
+{
+ RETURN_VAL_IF_FAIL(caps, TDM_ERROR_INVALID_PARAMETER);
+
+ caps->max_layer_count = -1; /* not defined */
+
+ return TDM_ERROR_NONE;
+}
+
+tdm_error
+sprd_display_get_pp_capability(tdm_backend_data *bdata, tdm_caps_pp *caps)
+{
+ return tdm_sprd_pp_get_capability(bdata, caps);
+}
+
+tdm_output **
+sprd_display_get_outputs(tdm_backend_data *bdata, int *count, tdm_error *error)
+{
+ tdm_sprd_data *sprd_data = bdata;
+ tdm_sprd_output_data *output_data = NULL;
+ tdm_output **outputs;
+ tdm_error ret;
+ int i;
+
+ RETURN_VAL_IF_FAIL(sprd_data, NULL);
+ RETURN_VAL_IF_FAIL(count, NULL);
+
+ *count = 0;
+ LIST_FOR_EACH_ENTRY(output_data, &sprd_data->output_list, link)
+ (*count)++;
+
+ if (*count == 0) {
+ ret = TDM_ERROR_NONE;
+ goto failed_get;
+ }
+
+ /* will be freed in frontend */
+ outputs = calloc(*count, sizeof(tdm_sprd_output_data *));
+ if (!outputs) {
+ TDM_ERR("failed: alloc memory");
+ *count = 0;
+ ret = TDM_ERROR_OUT_OF_MEMORY;
+ goto failed_get;
+ }
+
+ i = 0;
+ LIST_FOR_EACH_ENTRY(output_data, &sprd_data->output_list, link)
+ outputs[i++] = output_data;
+
+ if (error)
+ *error = TDM_ERROR_NONE;
+
+ return outputs;
+failed_get:
+ if (error)
+ *error = ret;
+ return NULL;
+}
+
+tdm_error
+sprd_display_get_fd(tdm_backend_data *bdata, int *fd)
+{
+ tdm_sprd_data *sprd_data = bdata;
+
+ RETURN_VAL_IF_FAIL(sprd_data, TDM_ERROR_INVALID_PARAMETER);
+ RETURN_VAL_IF_FAIL(fd, TDM_ERROR_INVALID_PARAMETER);
+
+ *fd = sprd_data->drm_fd;
+
+ return TDM_ERROR_NONE;
+}
+
+tdm_error
sprd_display_handle_events(tdm_backend_data *bdata)
{
tdm_sprd_data *sprd_data = bdata;
return tdm_sprd_pp_create(sprd_data, error);
}
-tdm_sprd_layer_data *
-_sprd_output_get_layer(tdm_sprd_output_data *output_data, int index)
-{
- RETURN_VAL_IF_FAIL(output_data, NULL);
-
- tdm_sprd_layer_data *l = NULL;
- LIST_FOR_EACH_ENTRY(l, &output_data->layer_list, link)
- if (l->zpos == index)
- return l;
- return NULL;
-}
-
-
tdm_error
sprd_output_get_capability(tdm_output *output, tdm_caps_output *caps)
{
if (output_data->sprd_data->hwc_mode)
caps->capabilities |= TDM_OUTPUT_CAPABILITY_HWC;
-
return TDM_ERROR_NONE;
}
return TDM_ERROR_NONE;
}
-static int
-_get_number_of_visible_windows(tdm_sprd_output_data *output_data)
-{
- int number = 0;
- tdm_sprd_hwc_window_data *window = NULL;
-
- RETURN_VAL_IF_FAIL(output_data, 0);
-
- LIST_FOR_EACH_ENTRY(window, &output_data->hwc_window_list, link) {
- if (window->client_type == TDM_COMPOSITION_NONE)
- continue;
-
- number++;
- }
-
- return number;
-}
-
-static tdm_error
-_tdm_sprd_display_prepare_commit(tdm_sprd_output_data *output_data) {
-
- tdm_sprd_layer_data * layer = NULL;
- int i = HW_LAYER_NUM-1;
- tdm_sprd_hwc_window_data *hwc_window_data = NULL;
-
- RETURN_VAL_IF_FAIL(output_data->need_validate == 0, TDM_ERROR_OPERATION_FAILED);
-
- if (!_get_number_of_visible_windows(output_data))
- output_data->need_target_buffer = 1;
-
- /* set target hwc window */
- if (output_data->need_target_buffer) {
- layer = _sprd_output_get_layer(output_data, i--);
- _sprd_layer_attach_window(layer, output_data->target_hwc_window);
- }
-
- if (output_data->video_hwc_window) {
- layer = _sprd_output_get_layer(output_data, 0);
- _sprd_layer_attach_window(layer, output_data->video_hwc_window);
- }
-
- /* set hwc windows */
- LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &output_data->hwc_window_list, link) {
- if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
- continue;
- if (hwc_window_data->client_type != TDM_COMPOSITION_DEVICE)
- continue;
- if (i < 0)
- return TDM_ERROR_OPERATION_FAILED;
- layer = _sprd_output_get_layer(output_data, i--);
- _sprd_layer_attach_window(layer, hwc_window_data);
- }
-
- /* disable unused layer */
- while (i >= 0) {
- if (i == 0 && output_data->video_hwc_window)
- break;
- layer = _sprd_output_get_layer(output_data, i--);
- _sprd_layer_attach_window(layer, NULL);
- }
-
- return TDM_ERROR_NONE;
-}
-
tdm_error
sprd_output_commit(tdm_output *output, int sync, void *user_data)
{
sprd_data = output_data->sprd_data;
- if (sprd_data->hwc_mode) {
- ret = _tdm_sprd_display_prepare_commit(output_data);
- RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
- }
-
_tdm_sprd_display_do_commit(output_data);
RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
sprd_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
{
tdm_sprd_output_data *output_data = output;
+ tdm_error ret = TDM_ERROR_NONE;
RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
RETURN_VAL_IF_FAIL(mode, TDM_ERROR_INVALID_PARAMETER);
RETURN_VAL_IF_FAIL(output_data->sprd_data, TDM_ERROR_INVALID_PARAMETER);
+ /* create or replace the target_window when the output mode is set */
if (output_data->sprd_data->hwc_mode) {
-
- tdm_hwc_window_info info = {0};
- tdm_error ret = TDM_ERROR_NONE;
- tdm_sprd_hwc_window_data * target_hwc_window;
-
- info.src_config.pos.h = mode->vdisplay;
- info.src_config.pos.w = mode->hdisplay;
- info.src_config.size.h = mode->hdisplay;
- info.src_config.size.v = mode->vdisplay;
- info.src_config.format = TBM_FORMAT_ARGB8888;
-
- target_hwc_window = _sprd_output_hwc_window_create(output_data, &info, &ret);
- if (ret != TDM_ERROR_NONE) {
+ ret = sprd_hwc_initailize_target_window(output_data->hwc_data, mode->hdisplay, mode->hdisplay);
+ if (ret != TDM_ERROR_NONE) {
TDM_ERR("create target hwc window failed (%d)", ret);
- return TDM_ERROR_OPERATION_FAILED;
+ return ret;
}
-
- if (output_data->target_hwc_window)
- sprd_output_hwc_window_destroy(output, output_data->target_hwc_window);
-
- output_data->target_hwc_window = target_hwc_window;
}
output_data->current_mode = mode;
return TDM_ERROR_NONE;
}
-tdm_sprd_display_buffer *
-_tdm_sprd_display_creat_buffer(tdm_sprd_data *sprd_data, tbm_surface_h surface, tdm_error * err)
-{
- int i, count;
- int bw, bh;
- tdm_sprd_display_buffer * display_buffer = NULL;
- tdm_error res = TDM_ERROR_NONE;
-
- RETURN_VAL_IF_FAIL(sprd_data, NULL);
- RETURN_VAL_IF_FAIL(surface, NULL);
-
- display_buffer = calloc(1, sizeof(tdm_sprd_display_buffer));
- if (!display_buffer) {
- if (err)
- *err = TDM_ERROR_OUT_OF_MEMORY;
- return NULL;
- }
-
- display_buffer->buffer = surface;
-
- res = tdm_buffer_add_destroy_handler(surface, _tdm_sprd_display_cb_destroy_buffer, sprd_data);
- if (res != TDM_ERROR_NONE) {
- if (err)
- *err = res;
- TDM_ERR("add destroy handler fail");
- free(display_buffer);
- return NULL;
- }
-
- tdm_helper_get_buffer_full_size(surface, &bw, &bh);
-
- display_buffer->width = bw;
- display_buffer->height = bh;
- display_buffer->format = tbm_surface_get_format(surface);
- display_buffer->count = tbm_surface_internal_get_num_bos(surface);
- count = tbm_surface_internal_get_num_planes(display_buffer->format);
- TDM_DBG("create buffer: %dx%d %c%c%c%c bo_num:%d plane_num:%d",
- display_buffer->width, display_buffer->height, FOURCC_STR(display_buffer->format),
- display_buffer->count, count);
-
- for (i = 0; i < display_buffer->count; i++) {
- tbm_bo bo = tbm_surface_internal_get_bo(surface, i);
- display_buffer->handles[i] = tbm_bo_get_handle(bo, TBM_DEVICE_DEFAULT).u32;
- display_buffer->name[i] = tbm_bo_export(bo);
- TDM_DBG(" create buffer: bo%d(name:%d handle:%d)", i, display_buffer->name[i],
- display_buffer->handles[i]);
- }
- for (i = 0; i < count; i++) {
- tbm_surface_internal_get_plane_data(surface, i, &display_buffer->size, &display_buffer->offsets[i],
- &display_buffer->pitches[i]);
- TDM_DBG(" create buffer: plane%d(size:%d offset:%d pitch:%d)", i, display_buffer->size,
- display_buffer->offsets[i], display_buffer->pitches[i]);
- }
-
- if (IS_RGB(display_buffer->format))
- display_buffer->width = display_buffer->pitches[0] >> 2;
- else
- display_buffer->width = display_buffer->pitches[0];
-
- if (err)
- *err = TDM_ERROR_NONE;
-
- return display_buffer;
-}
-
tdm_error
sprd_layer_set_buffer(tdm_layer *layer, tbm_surface_h surface)
{
_tdm_sprd_display_layer_disable(layer);
layer_data->display_buffer = NULL;
- return TDM_ERROR_NONE;
-}
-
-tdm_error
-sprd_layer_get_buffer_flags(tdm_layer *layer, unsigned int *flags)
-{
- tdm_sprd_layer_data *layer_data = layer;
-
- switch (layer_data->zpos) {
- case 0:
- case 1:
- *flags = TBM_BO_SCANOUT;
- break;
- default:
- return TDM_ERROR_INVALID_PARAMETER;
- }
-
- return TDM_ERROR_NONE;
-}
-
-static int
-_sprd_drm_user_handler(struct drm_event *event)
-{
- RETURN_VAL_IF_FAIL(event, -1);
-
- TDM_DBG("got event %d\n", event->type);
-
- if (event->type != DRM_SPRD_IPP_EVENT)
- return -1;
- tdm_sprd_pp_handler((struct drm_sprd_ipp_event *) event);
-
- return 0;
-}
-
-static void
-_sprd_drm_vblank_event(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data)
-{
- tdm_sprd_vblank_data *vblank_data = (tdm_sprd_vblank_data *) user_data;
- tdm_sprd_output_data *output_data;
- tdm_sprd_layer_data *layer_data = NULL;
-
- if (!vblank_data) {
- TDM_ERR("no vblank data");
- return;
- }
-
- output_data = vblank_data->output_data;
- if (!output_data) {
- TDM_ERR("no output data");
- return;
- }
- switch (vblank_data->type) {
- case VBLANK_TYPE_WAIT:
- if (output_data->vblank_func)
- output_data->vblank_func(output_data, sequence, tv_sec, tv_usec, vblank_data->user_data);
- break;
- case VBLANK_TYPE_COMMIT:
- LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
- if (layer_data->need_unset) {
- _tdm_sprd_display_layer_disable(layer_data);
- layer_data->need_unset = 0;
- }
- }
+ return TDM_ERROR_NONE;
+}
- if (output_data->commit_func)
- output_data->commit_func(output_data, sequence, tv_sec, tv_usec, vblank_data->user_data);
+tdm_error
+sprd_layer_get_buffer_flags(tdm_layer *layer, unsigned int *flags)
+{
+ tdm_sprd_layer_data *layer_data = layer;
+ switch (layer_data->zpos) {
+ case 0:
+ case 1:
+ *flags = TBM_BO_SCANOUT;
break;
default:
- break;
+ return TDM_ERROR_INVALID_PARAMETER;
}
- free(vblank_data);
-}
-static void
-_sprd_drm_flip_complete_event(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data)
-{
- TDM_DBG("FLIP EVENT");
+ return TDM_ERROR_NONE;
}
tdm_error
return TDM_ERROR_NONE;
}
-#if 0
-static int
-_sprd_layer_is_supported_format(tdm_sprd_layer_data *layer_data, tbm_format format)
-{
- RETURN_VAL_IF_FAIL(layer_data, 0);
- return IS_RGB(format);
-}
-
-static int
-_sprd_hwc_window_is_reserved_buffer(tdm_sprd_hwc_window_data *hwc_window_data) {
- tbm_bo bo = NULL;
- int falgs = 0;
-
- RETURN_VAL_IF_FAIL(hwc_window_data != NULL, 0);
- RETURN_VAL_IF_FAIL(hwc_window_data->display_buffer != NULL, 0);
-
- bo = tbm_surface_internal_get_bo(hwc_window_data->display_buffer->buffer, 0);
- RETURN_VAL_IF_FAIL(bo != NULL, 0);
-
- falgs = tbm_bo_get_flags(bo);
-
- return falgs & TBM_BO_SCANOUT;
-}
-#endif
-
-int
-_sprd_output_get_changed_number(tdm_sprd_output_data *output_data)
-{
- int num = 0;
- tdm_sprd_hwc_window_data *hwc_window_data = NULL;
-
- RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
-
- LIST_FOR_EACH_ENTRY(hwc_window_data, &output_data->hwc_window_list, link) {
- if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
- continue;
-
- if (hwc_window_data->client_type != hwc_window_data->validated_type)
- num++;
- }
- return num;
-}
-
-tdm_hwc_window *
-_sprd_output_hwc_window_create(tdm_output *output, tdm_hwc_window_info *info, tdm_error *error)
-{
- tdm_sprd_hwc_window_data *hwc_window_data = NULL;
- tdm_sprd_output_data *output_data = output;
-
- if (error)
- *error = TDM_ERROR_NONE;
-
- if (!output_data) {
- TDM_ERR("invalid params");
- if (error)
- *error = TDM_ERROR_INVALID_PARAMETER;
- return NULL;
- }
-
- hwc_window_data = calloc(1, sizeof(tdm_sprd_hwc_window_data));
- if (!hwc_window_data) {
- TDM_ERR("alloc failed");
- if (error)
- *error = TDM_ERROR_OUT_OF_MEMORY;
- return NULL;
- }
-
- if ((hwc_window_data->sprd_data = sprd_output_get_sprd_data(output)) == NULL) {
- TDM_ERR("invalid params");
- if (error)
- *error = TDM_ERROR_INVALID_PARAMETER;
- goto fail;
- }
-
- hwc_window_data->output_data = output;
-
- if (info)
- memcpy(&hwc_window_data->info, info, sizeof(tdm_hwc_window_info));
-
- LIST_INITHEAD(&hwc_window_data->link);
-
- return hwc_window_data;
-fail:
- if (hwc_window_data)
- free(hwc_window_data);
- return NULL;
-}
-
tdm_hwc_window *
-sprd_output_hwc_window_create(tdm_output *output, tdm_error *error)
+sprd_hwc_create_window(tdm_hwc *hwc, tdm_error *error)
{
tdm_sprd_hwc_window_data *hwc_window_data = NULL;
- tdm_sprd_output_data *output_data = output;
+ tdm_sprd_hwc_data *hwc_data = hwc;
- RETURN_VAL_IF_FAIL(output_data, NULL);
+ RETURN_VAL_IF_FAIL(hwc_data, NULL);
- hwc_window_data = _sprd_output_hwc_window_create(output_data, NULL, error);
+ hwc_window_data = _sprd_hwc_create_window(hwc_data, NULL, error);
RETURN_VAL_IF_FAIL(hwc_window_data, NULL);
- LIST_ADDTAIL(&hwc_window_data->link, &output_data->hwc_window_list);
+ LIST_ADDTAIL(&hwc_window_data->link, &hwc_data->hwc_window_list);
TDM_DBG("hwc_window(%p) create", hwc_window_data);
if (error)
return hwc_window_data;
}
-tdm_error
-sprd_output_hwc_window_destroy(tdm_output *output, tdm_hwc_window *hwc_window)
+void
+sprd_hwc_window_destroy(tdm_hwc_window *hwc_window)
{
- RETURN_VAL_IF_FAIL(output, TDM_ERROR_INVALID_PARAMETER);
- RETURN_VAL_IF_FAIL(hwc_window, TDM_ERROR_INVALID_PARAMETER);
-
tdm_sprd_hwc_window_data *hwc_window_data = hwc_window;
+ if (!hwc_window_data)
+ return;
+
LIST_DEL(&hwc_window_data->link);
free(hwc_window_data);
-
- return TDM_ERROR_NONE;
-}
-
-static const char *
-_comp_to_str(tdm_hwc_window_composition composition_type)
-{
- if (composition_type == TDM_COMPOSITION_CLIENT)
- return "CLIENT";
- else if (composition_type == TDM_COMPOSITION_DEVICE_CANDIDATE)
- return "DEVICE_CANDIDATE";
- else if (composition_type == TDM_COMPOSITION_DEVICE)
- return "DEVICE";
- else if (composition_type == TDM_COMPOSITION_CURSOR)
- return "CURSOR";
- else if (composition_type == TDM_COMPOSITION_NONE)
- return "NONE";
-
- return "unknown";
}
tdm_error
-sprd_output_hwc_validate(tdm_output *output, tdm_hwc_window **composited_wnds,
- uint32_t num_wnds, uint32_t *num_types)
+sprd_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types)
{
- tdm_sprd_output_data *output_data = output;
- tdm_sprd_data *sprd_data = NULL;
+ tdm_sprd_hwc_data *hwc_data = hwc;
tdm_sprd_hwc_window_data *hwc_window_data = NULL;
- RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+ RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
RETURN_VAL_IF_FAIL(num_types != NULL, TDM_ERROR_INVALID_PARAMETER);
- sprd_data = output_data->sprd_data;
- RETURN_VAL_IF_FAIL(sprd_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-
/* decide the validated_types with client_types */
- LIST_FOR_EACH_ENTRY(hwc_window_data, &output_data->hwc_window_list, link) {
+ LIST_FOR_EACH_ENTRY(hwc_window_data, &hwc_data->hwc_window_list, link) {
/* set the none to validated_type */
if (hwc_window_data->client_type == TDM_COMPOSITION_NONE &&
hwc_window_data->validated_type != TDM_COMPOSITION_NONE) {
continue;
}
- /* set the TDM_COMPOSITION_VIDEO type */
- if (hwc_window_data == output_data->video_hwc_window) {
- hwc_window_data->validated_type = TDM_COMPOSITION_DEVICE;
- continue;
- }
-
/* all hwc_windows make TDM_COMPOSITION_CLIENT */
if (hwc_window_data->client_type != TDM_COMPOSITION_CLIENT) {
hwc_window_data->validated_type = TDM_COMPOSITION_CLIENT;
}
/* debugging log */
- LIST_FOR_EACH_ENTRY(hwc_window_data, &output_data->hwc_window_list, link) {
+ LIST_FOR_EACH_ENTRY(hwc_window_data, &hwc_data->hwc_window_list, link) {
if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
continue;
}
/* The driver always needs the target_buffer */
- output_data->need_target_buffer = 1;
+ hwc_data->need_target_window = 1;
- *num_types = _sprd_output_get_changed_number(output_data);
+ *num_types = _sprd_output_get_changed_number(hwc_data);
if (*num_types == 0)
- output_data->need_validate = 0;
+ hwc_data->need_validate = 0;
return TDM_ERROR_NONE;
}
tdm_error
-sprd_output_hwc_get_changed_composition_types(tdm_output *output,
- uint32_t *num_elements,
- tdm_hwc_window **hwc_window,
- tdm_hwc_window_composition *composition_types)
+sprd_hwc_get_changed_composition_types(tdm_hwc *hwc, uint32_t *num_elements,
+ tdm_hwc_window **hwc_window, tdm_hwc_window_composition *composition_types)
{
- tdm_sprd_output_data *output_data = output;
+ tdm_sprd_hwc_data *hwc_data = hwc;
int num = 0;
- RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+ RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
RETURN_VAL_IF_FAIL(num_elements != NULL, TDM_ERROR_INVALID_PARAMETER);
if ((hwc_window == NULL) || (composition_types == NULL)) {
- *num_elements = _sprd_output_get_changed_number(output_data);
+ *num_elements = _sprd_output_get_changed_number(hwc_data);
return TDM_ERROR_NONE;
}
tdm_sprd_hwc_window_data *hwc_window_data = NULL;
- LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &output_data->hwc_window_list, link) {
+ LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) {
if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
continue;
}
tdm_error
-sprd_output_hwc_accept_changes(tdm_output *output)
+sprd_hwc_accept_changes(tdm_hwc *hwc)
{
- tdm_sprd_output_data *output_data = output;
+ tdm_sprd_hwc_data *hwc_data = hwc;
- RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+ RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
tdm_sprd_hwc_window_data *hwc_window_data = NULL;
- LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &output_data->hwc_window_list, link) {
+ LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) {
if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
continue;
hwc_window_data->client_type = hwc_window_data->validated_type;
}
- output_data->need_validate = 0;
+ hwc_data->need_validate = 0;
return TDM_ERROR_NONE;
}
tbm_surface_queue_h
-sprd_output_hwc_get_target_buffer_queue(tdm_output *output, tdm_error *error)
+sprd_hwc_get_client_target_buffer_queue(tdm_hwc *hwc, tdm_error *error)
{
- tdm_sprd_output_data *output_data = output;
+ tdm_sprd_hwc_data *hwc_data = hwc;
tbm_surface_queue_h tqueue = NULL;
if (error)
*error = TDM_ERROR_INVALID_PARAMETER;
- RETURN_VAL_IF_FAIL(output_data != NULL, NULL);
+ RETURN_VAL_IF_FAIL(hwc_data != NULL, NULL);
- if (output_data->target_hwc_window == NULL) {
+ if (hwc_data->target_hwc_window == NULL) {
if (error)
*error = TDM_ERROR_OPERATION_FAILED;
return NULL;
}
- tqueue = sprd_hwc_window_get_tbm_buffer_queue(output_data->target_hwc_window, error);
+ tqueue = _sprd_hwc_window_get_tbm_buffer_queue(hwc_data->target_hwc_window, error);
RETURN_VAL_IF_FAIL(tqueue, NULL);
if (error)
}
tdm_error
-sprd_output_hwc_set_client_target_buffer(tdm_output *output, tbm_surface_h buffer, tdm_hwc_region damage)
+sprd_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h buffer, tdm_region damage)
{
- tdm_sprd_output_data *output_data = output;
+ tdm_sprd_hwc_data *hwc_data = hwc;
tdm_error err;
/* TODO: as the sprd-driver currently doesn't support DEVICE to CLIENT transition.
* we silence skip 'composited_wnds' */
- RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
- RETURN_VAL_IF_FAIL(output_data->target_hwc_window != NULL, TDM_ERROR_OPERATION_FAILED);
+ RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+ RETURN_VAL_IF_FAIL(hwc_data->target_hwc_window != NULL, TDM_ERROR_OPERATION_FAILED);
- err = sprd_hwc_window_set_buffer(output_data->target_hwc_window, buffer);
+ err = sprd_hwc_window_set_buffer(hwc_data->target_hwc_window, buffer);
RETURN_VAL_IF_FAIL(err == TDM_ERROR_NONE, err);
- err = sprd_hwc_window_set_buffer_damage(output_data->target_hwc_window, damage);
+ err = sprd_hwc_window_set_buffer_damage(hwc_data->target_hwc_window, damage);
RETURN_VAL_IF_FAIL(err == TDM_ERROR_NONE, err);
return TDM_ERROR_NONE;
}
tdm_error
-sprd_output_hwc_get_video_supported_formats(tdm_output *output,
- const tbm_format **formats,
- int *count)
+sprd_hwc_get_supported_formats(tdm_hwc *hwc, const tbm_format **formats, int *count)
{
- RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER);
+ RETURN_VAL_IF_FAIL(hwc != NULL, TDM_ERROR_INVALID_PARAMETER);
RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
+ // TODO: fix these formats.
*formats = hwc_window_video_formats;
*count = sizeof(hwc_window_video_formats) / sizeof(tbm_format);
return TDM_ERROR_NONE;
}
-tdm_hwc_window *
-sprd_output_hwc_create_video_window(tdm_output *output, tdm_error *error)
-{
- tdm_sprd_hwc_window_data *hwc_window_data = NULL;
- tdm_sprd_output_data *output_data = output;
-
- if (error)
- *error = TDM_ERROR_INVALID_PARAMETER;
-
- RETURN_VAL_IF_FAIL(output_data != NULL, NULL);
-
- if (error)
- *error = TDM_ERROR_OPERATION_FAILED;
-
- if (output_data->video_hwc_window)
- return NULL;
-
- hwc_window_data = _sprd_output_hwc_window_create(output_data, NULL, error);
- if (hwc_window_data == NULL)
- return NULL;
-
- output_data->video_hwc_window = hwc_window_data;
-
- TDM_DBG("hwc_window(%p) video create", hwc_window_data);
- if (error)
- *error = TDM_ERROR_NONE;
-
- return hwc_window_data;
-}
-
-tbm_surface_queue_h
-sprd_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error)
+tdm_error
+sprd_hwc_get_available_properties(tdm_hwc *hwc, const tdm_prop **props, int *count)
{
- tdm_sprd_hwc_window_data *hwc_window_data = NULL;
- tdm_sprd_output_data *output_data = NULL;
- tbm_surface_queue_h tqueue = NULL;
-
- if (error)
- *error = TDM_ERROR_INVALID_PARAMETER;
-
- RETURN_VAL_IF_FAIL(hwc_window != NULL, NULL);
- hwc_window_data = hwc_window;
- output_data = hwc_window_data->output_data;
-
- RETURN_VAL_IF_FAIL(output_data != NULL, NULL);
-
- int wight = hwc_window_data->info.src_config.size.h;
- int hight = hwc_window_data->info.src_config.size.v;
- tbm_format format = hwc_window_data->info.src_config.format;
+ tdm_sprd_hwc_data *hwc_data = hwc;
- tqueue = tbm_surface_queue_create(3, wight, hight, format, TBM_BO_SCANOUT);
- if (error)
- *error = TDM_ERROR_OPERATION_FAILED;
- RETURN_VAL_IF_FAIL(tqueue != NULL, NULL);
+ RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
- if (error)
- *error = TDM_ERROR_NONE;
- return tqueue;
+ // TODO:
+ return TDM_ERROR_NONE;
}
tdm_error
tdm_hwc_window_composition comp_type)
{
tdm_sprd_hwc_window_data *hwc_window_data = hwc_window;
- tdm_sprd_output_data *output_data = hwc_window_data->output_data;
+ tdm_sprd_hwc_data *hwc_data = hwc_window_data->hwc_data;
RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
- RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+ RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
if (hwc_window_data->client_type == comp_type)
return TDM_ERROR_NONE;
hwc_window_data->client_type = comp_type;
- output_data->need_validate = 1;
+ hwc_data->need_validate = 1;
return TDM_ERROR_NONE;
}
tdm_error
-sprd_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_hwc_region damage)
+sprd_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_region damage)
{
tdm_sprd_hwc_window_data *hwc_window_data = hwc_window;
- tdm_sprd_output_data *output_data = hwc_window_data->output_data;
RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
- RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
//TODO::
sprd_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info)
{
tdm_sprd_hwc_window_data *hwc_window_data = hwc_window;
- tdm_sprd_output_data *output_data = hwc_window_data->output_data;
+ tdm_sprd_hwc_data *hwc_data = hwc_window_data->hwc_data;
RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
- RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+ RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
if (memcmp(&hwc_window_data->info, info, sizeof(tdm_hwc_window_info)) == 0)
return TDM_ERROR_NONE;
hwc_window_data->info = *info;
- output_data->need_validate = 1;
+ hwc_data->need_validate = 1;
+
+ return TDM_ERROR_NONE;
+}
+
+tdm_error
+sprd_hwc_window_get_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info)
+{
+ tdm_sprd_hwc_window_data *hwc_window_data = hwc_window;
+
+ RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+ RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER);
+
+ *info = hwc_window_data->info;
return TDM_ERROR_NONE;
}
sprd_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h surface)
{
tdm_sprd_hwc_window_data *hwc_window_data = hwc_window;
+ tdm_sprd_hwc_data *hwc_data;
tdm_sprd_output_data *output_data;
tdm_sprd_data *sprd_data;
tdm_error err = TDM_ERROR_OPERATION_FAILED;
tdm_sprd_display_buffer *display_buffer = NULL;
RETURN_VAL_IF_FAIL(hwc_window_data != NULL, err);
-
- output_data = hwc_window_data->output_data;
- sprd_data = hwc_window_data->sprd_data;
-
- RETURN_VAL_IF_FAIL(output_data != NULL, err);
+ hwc_data = hwc_window_data->hwc_data;
+ RETURN_VAL_IF_FAIL(hwc_data != NULL, err);
+ output_data = hwc_data->output_data;
+ RETURN_VAL_IF_FAIL(hwc_data != NULL, err);
+ sprd_data = output_data->sprd_data;
RETURN_VAL_IF_FAIL(sprd_data != NULL, err);
if (!surface) {
}
tdm_error
-sprd_hwc_window_set_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags)
+sprd_hwc_initailize_target_window(tdm_hwc *hwc, int width, int height)
{
- tdm_sprd_hwc_window_data *hwc_window_data = hwc_window;
+ tdm_hwc_window_info info = {0};
+ tdm_error ret = TDM_ERROR_NONE;
+ tdm_sprd_hwc_window_data *target_hwc_window;
+ tdm_sprd_hwc_data *hwc_data = hwc;
- RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+ RETURN_VAL_IF_FAIL(hwc_data, TDM_ERROR_INVALID_PARAMETER);
+
+ info.dst_pos.x = 0;
+ info.dst_pos.y = 0;
+ info.dst_pos.h = height;
+ info.dst_pos.w = width;
+
+ info.src_config.pos.x = 0;
+ info.src_config.pos.y = 0;
+ info.src_config.pos.h = height;
+ info.src_config.pos.w = width;
+
+ info.src_config.size.h = width;
+ info.src_config.size.v = height;
+ info.src_config.format = TBM_FORMAT_ARGB8888;
+
+ target_hwc_window = _sprd_hwc_create_window(hwc_data, &info, &ret);
+ if (ret != TDM_ERROR_NONE) {
+ TDM_ERR("create target hwc window failed (%d)", ret);
+ return TDM_ERROR_OPERATION_FAILED;
+ }
+
+ if (hwc_data->target_hwc_window)
+ sprd_hwc_window_destroy(hwc_data->target_hwc_window);
+
+ hwc_data->target_hwc_window = target_hwc_window;
+ hwc_data->need_set_crtc = 1;
+
+ return TDM_ERROR_NONE;
+}
+
+tdm_hwc *
+sprd_output_get_hwc(tdm_output *output, tdm_error *error)
+{
+ tdm_sprd_hwc_data *hwc_data = NULL;
+ tdm_sprd_output_data *output_data = output;
+
+ if (!output_data) {
+ TDM_ERR("invalid params");
+ if (error)
+ *error = TDM_ERROR_INVALID_PARAMETER;
+ return NULL;
+ }
+
+ if (output_data->hwc_data) {
+ TDM_INFO("hwc_data already exists");
+ if (error)
+ *error = TDM_ERROR_NONE;
+ return output_data->hwc_data;
+ }
+
+ hwc_data = calloc(1, sizeof(tdm_sprd_hwc_data));
+ if (!hwc_data) {
+ TDM_ERR("alloc failed");
+ if (error)
+ *error = TDM_ERROR_OUT_OF_MEMORY;
+ return NULL;
+ }
+ hwc_data->output_data = output_data;
+
+ LIST_INITHEAD(&hwc_data->hwc_window_list);
+
+ output_data->hwc_data = hwc_data;
+
+ if (error)
+ *error = TDM_ERROR_NONE;
- hwc_window_data->flags |= flags;
+ return hwc_data;
+}
+
+tdm_error
+sprd_hwc_commit(tdm_hwc *hwc, int sync, void *user_data)
+{
+// TODO:
+
+ return TDM_ERROR_NONE;
+}
+
+tdm_error
+sprd_hwc_set_commit_handler(tdm_hwc *hwc, tdm_hwc_commit_handler func)
+{
+ tdm_sprd_hwc_data *hwc_data = hwc;
+
+ RETURN_VAL_IF_FAIL(hwc_data, TDM_ERROR_INVALID_PARAMETER);
+ RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
+
+ hwc_data->commit_func = func;
return TDM_ERROR_NONE;
}
tdm_error
-sprd_hwc_window_unset_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags)
+sprd_hwc_window_get_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value *value)
{
tdm_sprd_hwc_window_data *hwc_window_data = hwc_window;
RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
- hwc_window_data->flags &= ~flags;
+ //TODO:
return TDM_ERROR_NONE;
}
tdm_error
-sprd_hwc_window_video_get_capability(tdm_hwc_window *hwc_window,
- tdm_hwc_window_video_capability *video_capability)
+sprd_hwc_window_set_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value value)
{
tdm_sprd_hwc_window_data *hwc_window_data = hwc_window;
- tdm_sprd_output_data *output_data;
- RETURN_VAL_IF_FAIL(hwc_window != NULL, TDM_ERROR_INVALID_PARAMETER);
- output_data = hwc_window_data->output_data;
- RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
- RETURN_VAL_IF_FAIL(video_capability != NULL, TDM_ERROR_INVALID_PARAMETER);
- RETURN_VAL_IF_FAIL(output_data->video_hwc_window == hwc_window_data, TDM_ERROR_INVALID_PARAMETER);
+ RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
- *video_capability = TDM_HWC_WINDOW_VIDEO_CAPABILITY_SCANOUT;
+ //TODO:
return TDM_ERROR_NONE;
-}
+}
\ No newline at end of file