typedef struct _tdm_vc4_output_data tdm_vc4_output_data;
typedef struct _tdm_vc4_layer_data tdm_vc4_layer_data;
+typedef struct _tdm_vc4_hwc_data tdm_vc4_hwc_data;
+
typedef struct _tdm_vc4_hwc_window_data tdm_vc4_hwc_window_data;
typedef struct _tdm_vc4_event_data tdm_vc4_event_data;
int crtc_enabled;
unsigned int crtc_fb_id;
- tdm_vc4_hwc_window_data *target_hwc_window;
-
- int need_validate;
- int need_target_buffer;
- int hw_layer_count;
- int need_set_crtc;
- int top_layer_idx;
+ /* hwc */
int hwc_enable;
-
- struct list_head hwc_window_list;
+ tdm_vc4_hwc_data *hwc_data;
};
struct _tdm_vc4_layer_data {
int display_buffer_changed;
};
+struct _tdm_vc4_hwc_data {
+ tdm_vc4_hwc_window_data *target_hwc_window;
+
+ int need_validate;
+ int need_target_buffer;
+ int hw_layer_count;
+ int need_set_crtc;
+ int top_layer_idx;
+
+ int target_window_zpos;
+
+ tdm_vc4_output_data *output_data;
+ struct list_head hwc_window_list;
+
+ tdm_hwc_commit_handler commit_func;
+};
struct _tdm_vc4_hwc_window_data {
struct list_head link;
/* data which are fixed at initializing */
- tdm_vc4_data *vc4_data;
- tdm_vc4_output_data *output_data;
+ tdm_vc4_hwc_data *hwc_data;
/* not fixed data below */
tdm_hwc_window_info info;
tdm_hwc_window_composition validated_type;
};
+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";
+
+ return "unknown";
+}
+
tdm_hwc_window *
-_vc4_output_hwc_window_create(tdm_output *output, tdm_hwc_window_info *info,
- tdm_error *error);
+_vc4_hwc_create_window(tdm_hwc *hwc, tdm_hwc_window_info *info, tdm_error *error)
+{
+ tdm_vc4_hwc_window_data *hwc_window_data = NULL;
+ tdm_vc4_hwc_data *hwc_data = hwc;
+
+ if (error)
+ *error = TDM_ERROR_NONE;
+
+ hwc_window_data = calloc(1, sizeof(tdm_vc4_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));
+
+ return hwc_window_data;
+}
+
static tdm_error
-_tdm_vc4_output_update_status(tdm_vc4_output_data *output_data,
- tdm_output_conn_status status);
+_vc4_hwc_initailize_target_window(tdm_vc4_hwc_data *hwc_data, int width, int height)
+{
+ tdm_hwc_window_info info = {0};
+ tdm_error ret = TDM_ERROR_NONE;
+ tdm_vc4_hwc_window_data *target_hwc_window;
+
+ 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 = _vc4_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)
+ vc4_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;
+}
+
+static tbm_surface_queue_h
+_vc4_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error)
+{
+ tdm_vc4_hwc_window_data *hwc_window_data = NULL;
+ tbm_surface_queue_h tqueue = NULL;
+ tbm_format format;
+
+ 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;
+
+ 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;
+
+}
static void
_tdm_vc4_display_buffer_destroy(void *user_data)
}
static tdm_error
+_tdm_vc4_output_update_status(tdm_vc4_output_data *output_data,
+ tdm_output_conn_status status)
+{
+ RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
+
+ if (output_data->status == status)
+ return TDM_ERROR_NONE;
+
+ output_data->status = status;
+
+ if (output_data->status_func)
+ output_data->status_func(output_data, status,
+ output_data->status_user_data);
+
+ return TDM_ERROR_NONE;
+}
+
+static tdm_error
_tdm_vc4_display_set_crtc(tdm_vc4_data *vc4_data, tdm_vc4_output_data *output_data, int set)
{
int ret;
}
static tdm_error
-_tdm_vc4_output_update_status(tdm_vc4_output_data *output_data,
- tdm_output_conn_status status)
-{
- RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
-
- if (output_data->status == status)
- return TDM_ERROR_NONE;
-
- output_data->status = status;
-
- if (output_data->status_func)
- output_data->status_func(output_data, status,
- output_data->status_user_data);
-
- return TDM_ERROR_NONE;
-}
-
-static tdm_error
_tdm_vc4_display_commit_layer(tdm_vc4_layer_data *layer_data)
{
tdm_vc4_data *vc4_data = layer_data->vc4_data;
}
#endif
+static int
+_get_primary_layer_index(tdm_vc4_output_data *output_data)
+{
+ int i = 0;
+ tdm_vc4_layer_data *layer = NULL;
+
+ LIST_FOR_EACH_ENTRY(layer, &output_data->layer_list, link) {
+ if (layer->capabilities & TDM_LAYER_CAPABILITY_PRIMARY)
+ return i;
+ i++;
+ }
+
+ return 0;
+}
+
+#if 0
+tdm_vc4_layer_data *
+_vc4_output_get_layer(tdm_vc4_output_data *output_data, int index)
+{
+ tdm_vc4_layer_data *l = NULL;
+ LIST_FOR_EACH_ENTRY(l, &output_data->layer_list, link)
+ if (l->zpos == index)
+ return l;
+
+ return NULL;
+}
+
+static tdm_error
+_vc4_layer_attach_window(tdm_vc4_layer_data *layer_data,
+ tdm_vc4_hwc_window_data *hwc_window_data)
+{
+ tdm_error ret;
+
+ if (hwc_window_data == NULL || !hwc_window_data->surface) {
+ ret = vc4_layer_unset_buffer(layer_data);
+ RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
+ } else {
+ ret = vc4_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->surface != NULL, TDM_ERROR_INVALID_PARAMETER);
+ ret = vc4_layer_set_buffer(layer_data, hwc_window_data->surface);
+ RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
+ }
+
+ return ret;
+}
+
+static tdm_error
+_tdm_vc4_display_prepare_commit(tdm_vc4_output_data *output_data) {
+
+ tdm_vc4_layer_data * layer = NULL;
+ tdm_vc4_hwc_window_data *hw = NULL;
+ int num_hw_layer = 0;
+ int i;
+ int fb_idx = 0;
+
+ RETURN_VAL_IF_FAIL(output_data->need_validate == 0, TDM_ERROR_OPERATION_FAILED);
+
+ i = output_data->top_layer_idx;
+ num_hw_layer = LIST_LENGTH(&output_data->layer_list);
+ fb_idx = _get_primary_layer_index(output_data);
+
+ //set target hwc window
+ if (output_data->need_target_buffer) {
+ layer = _vc4_output_get_layer(output_data, fb_idx);
+ _vc4_layer_attach_window(layer, output_data->target_hwc_window);
+ }
+
+ //set hwc windows
+ LIST_FOR_EACH_ENTRY_REV(hw, &output_data->hwc_window_list, link) {
+ if (output_data->need_target_buffer && i == fb_idx) {
+ i--;
+ }
+ if (hw->client_type != TDM_COMPOSITION_DEVICE)
+ continue;
+ RETURN_VAL_IF_FAIL(i >= 0, TDM_ERROR_OPERATION_FAILED);
+ layer = _vc4_output_get_layer(output_data, i--);
+ _vc4_layer_attach_window(layer, hw);
+ }
+
+ //disable unused layer
+ while (i >= 0) {
+ layer = _vc4_output_get_layer(output_data, i--);
+ _vc4_layer_attach_window(layer, NULL);
+ }
+
+ i = output_data->top_layer_idx + 1;
+ while (i < num_hw_layer) {
+ layer = _vc4_output_get_layer(output_data, i++);
+ _vc4_layer_attach_window(layer, NULL);
+ }
+
+ return TDM_ERROR_NONE;
+}
+#endif
+
+static int
+_get_primary_layer_zpos(tdm_vc4_output_data *output_data)
+{
+ tdm_vc4_layer_data *layer_data = NULL;
+
+ LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
+ if (layer_data->capabilities & TDM_LAYER_CAPABILITY_PRIMARY)
+ return layer_data->zpos;
+ }
+
+ return -1;
+}
+
+int
+_vc4_hwc_get_changed_number(tdm_vc4_hwc_data *hwc_data)
+{
+ int num = 0;
+ tdm_vc4_hwc_window_data *hw = NULL;
+
+ LIST_FOR_EACH_ENTRY(hw, &hwc_data->hwc_window_list, link) {
+ if (hw->client_type != hw->validated_type)
+ num++;
+ }
+
+ return num;
+}
+
tdm_error
tdm_vc4_display_create_layer_list(tdm_vc4_data *vc4_data)
{
tdm_vc4_display_destroy_output_list(tdm_vc4_data *vc4_data)
{
tdm_vc4_output_data *o = NULL, *oo = NULL;
+ tdm_vc4_hwc_data *hwc_data = NULL;
if (LIST_IS_EMPTY(&vc4_data->output_list))
return;
LIST_FOR_EACH_ENTRY_SAFE(o, oo, &vc4_data->output_list, link) {
-
- if (o->target_hwc_window)
- vc4_output_hwc_window_destroy(o, o->target_hwc_window);
+ hwc_data = o->hwc_data;
+ if (hwc_data && hwc_data->target_hwc_window)
+ vc4_hwc_window_destroy(hwc_data->target_hwc_window);
if (o->crtc_enabled) {
_tdm_vc4_display_set_crtc(vc4_data, o, 0);
&output_data->output_modes[j]);
}
- if (vc4_data->hwc_mode) {
+ if (vc4_data->hwc_mode)
output_data->hwc_enable = 1;
- output_data->target_hwc_window = NULL;
- LIST_INITHEAD(&output_data->hwc_window_list);
- }
LIST_ADDTAIL(&output_data->link, &vc4_data->output_list);
return TDM_ERROR_NONE;
}
-tdm_vc4_layer_data *
-_vc4_output_get_layer(tdm_vc4_output_data *output_data, int index)
-{
- tdm_vc4_layer_data *l = NULL;
- LIST_FOR_EACH_ENTRY(l, &output_data->layer_list, link)
- if (l->zpos == index)
- return l;
-
- return NULL;
-}
-
-static tdm_error
-_vc4_layer_attach_window(tdm_vc4_layer_data *layer_data,
- tdm_vc4_hwc_window_data *hwc_window_data)
-{
- tdm_error ret;
-
- if (hwc_window_data == NULL || !hwc_window_data->surface) {
- ret = vc4_layer_unset_buffer(layer_data);
- RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
- } else {
- ret = vc4_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->surface != NULL, TDM_ERROR_INVALID_PARAMETER);
- ret = vc4_layer_set_buffer(layer_data, hwc_window_data->surface);
- RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
- }
-
- return ret;
-}
-
-static int
-_get_primary_layer_index(tdm_vc4_output_data *vc4_output)
-{
- int i = 0;
- tdm_vc4_layer_data *layer = NULL;
-
- LIST_FOR_EACH_ENTRY(layer, &vc4_output->layer_list, link) {
- if (layer->capabilities & TDM_LAYER_CAPABILITY_PRIMARY)
- return i;
- i++;
- }
-
- return 0;
-}
-
-static tdm_error
-_tdm_vc4_display_prepare_commit(tdm_vc4_output_data *output_data) {
-
- tdm_vc4_layer_data * layer = NULL;
- tdm_vc4_hwc_window_data *hw = NULL;
- int num_hw_layer = 0;
- int i;
- int fb_idx = 0;
-
- RETURN_VAL_IF_FAIL(output_data->need_validate == 0, TDM_ERROR_OPERATION_FAILED);
-
- i = output_data->top_layer_idx;
- num_hw_layer = LIST_LENGTH(&output_data->layer_list);
- fb_idx = _get_primary_layer_index(output_data);
-
- //set target hwc window
- if (output_data->need_target_buffer) {
- layer = _vc4_output_get_layer(output_data, fb_idx);
- _vc4_layer_attach_window(layer, output_data->target_hwc_window);
- }
-
- //set hwc windows
- LIST_FOR_EACH_ENTRY_REV(hw, &output_data->hwc_window_list, link) {
- if (output_data->need_target_buffer && i == fb_idx) {
- i--;
- }
- if (hw->client_type != TDM_COMPOSITION_DEVICE)
- continue;
- RETURN_VAL_IF_FAIL(i >= 0, TDM_ERROR_OPERATION_FAILED);
- layer = _vc4_output_get_layer(output_data, i--);
- _vc4_layer_attach_window(layer, hw);
- }
-
- //disable unused layer
- while (i >= 0) {
- layer = _vc4_output_get_layer(output_data, i--);
- _vc4_layer_attach_window(layer, NULL);
- }
-
- i = output_data->top_layer_idx + 1;
- while (i < num_hw_layer) {
- layer = _vc4_output_get_layer(output_data, i++);
- _vc4_layer_attach_window(layer, NULL);
- }
-
- return TDM_ERROR_NONE;
-}
-
-tdm_error
-vc4_output_commit(tdm_output *output, int sync, void *user_data)
+tdm_error
+vc4_output_commit(tdm_output *output, int sync, void *user_data)
{
tdm_vc4_output_data *output_data = output;
tdm_vc4_data *vc4_data;
vc4_data = output_data->vc4_data;
+#if 0
if (output_data->hwc_enable) {
ret = _tdm_vc4_display_prepare_commit(output_data);
RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
}
+#endif
LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
ret = _tdm_vc4_display_commit_layer(layer_data);
vc4_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
{
tdm_vc4_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);
+ /* create or replace the target_window when the output mode is set */
if (output_data->hwc_enable) {
-
- tdm_hwc_window_info info = {0};
- tdm_error ret = TDM_ERROR_NONE;
- tdm_vc4_hwc_window_data *target_hwc_window;
-
- info.dst_pos.x = 0;
- info.dst_pos.y = 0;
- info.dst_pos.h = mode->vdisplay;;
- info.dst_pos.w = mode->hdisplay;
-
- info.src_config.pos.x = 0;
- info.src_config.pos.y = 0;
- 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 = _vc4_output_hwc_window_create(output_data, &info, &ret);
+ ret = _vc4_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)
- vc4_output_hwc_window_destroy(output, output_data->target_hwc_window);
-
- output_data->target_hwc_window = target_hwc_window;
- output_data->need_set_crtc = 1;
}
output_data->current_mode = mode;
return TDM_ERROR_NONE;
}
-static int
-_get_primary_layer_zpos(tdm_vc4_output_data *output_data)
-{
- tdm_vc4_layer_data *layer_data = NULL;
-
- LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
- if (layer_data->capabilities & TDM_LAYER_CAPABILITY_PRIMARY)
- return layer_data->zpos;
- }
-
- return -1;
-}
-
tdm_error
vc4_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps)
{
return TDM_ERROR_NONE;
}
-int
-_vc4_output_get_changed_number(tdm_vc4_output_data *vc4_output)
-{
- int num = 0;
- tdm_vc4_hwc_window_data *hw = NULL;
-
- LIST_FOR_EACH_ENTRY(hw, &vc4_output->hwc_window_list, link) {
- if (hw->client_type != hw->validated_type)
- num++;
- }
-
- return num;
-}
-
tdm_hwc_window *
-_vc4_output_hwc_window_create(tdm_output *output, tdm_hwc_window_info *info, tdm_error *error)
+vc4_hwc_create_window(tdm_hwc *hwc, tdm_error *error)
{
- tdm_vc4_hwc_window_data *vc4_hwc_window = NULL;
- tdm_vc4_output_data *vc4_output = output;
-
- if (error)
- *error = TDM_ERROR_NONE;
+ tdm_vc4_hwc_window_data *hwc_window_data = NULL;
+ tdm_vc4_hwc_data *hwc_data = hwc;
- if (!vc4_output) {
+ if (!hwc_data) {
TDM_ERR("invalid params");
if (error)
*error = TDM_ERROR_INVALID_PARAMETER;
return NULL;
}
- vc4_hwc_window = calloc(1, sizeof(tdm_vc4_hwc_window_data));
- if (!vc4_hwc_window) {
- TDM_ERR("alloc failed");
- if (error)
- *error = TDM_ERROR_OUT_OF_MEMORY;
+ hwc_window_data = _vc4_hwc_create_window(hwc_data, NULL, error);
+ if (hwc_window_data == NULL)
return NULL;
- }
-
- if ((vc4_hwc_window->vc4_data = vc4_output->vc4_data) == NULL) {
- TDM_ERR("invalid params");
- if (error)
- *error = TDM_ERROR_INVALID_PARAMETER;
- goto fail;
- }
- vc4_hwc_window->output_data = output;
-
- if (info)
- memcpy(&vc4_hwc_window->info, info, sizeof(tdm_hwc_window_info));
-
- return vc4_hwc_window;
-fail:
- if (vc4_hwc_window)
- free(vc4_hwc_window);
-
- return NULL;
-}
-
-tdm_hwc_window *
-vc4_output_hwc_window_create(tdm_output *output, tdm_error *error)
-{
- tdm_vc4_hwc_window_data *vc4_hwc_window = NULL;
- tdm_vc4_output_data *vc4_output = output;
+ LIST_ADDTAIL(&hwc_window_data->link, &hwc_data->hwc_window_list);
- vc4_hwc_window = _vc4_output_hwc_window_create(vc4_output, NULL, error);
- if (vc4_hwc_window == NULL)
- return NULL;
-
- LIST_ADDTAIL(&vc4_hwc_window->link, &vc4_output->hwc_window_list);
-
- TDM_DBG("hwc_window(%p) create", vc4_hwc_window);
+ TDM_DBG("hwc_window(%p) create", hwc_window_data);
if (error)
*error = TDM_ERROR_NONE;
- return vc4_hwc_window;
+ return hwc_window_data;
}
-tdm_error
-vc4_output_hwc_window_destroy(tdm_output *output, tdm_hwc_window *hwc_window)
+void
+vc4_hwc_window_destroy(tdm_hwc_window *hwc_window)
{
- tdm_vc4_hwc_window_data *vc4_hwc_window = hwc_window;
+ tdm_vc4_hwc_window_data *hwc_window_data = hwc_window;
- LIST_DEL(&vc4_hwc_window->link);
+ if (!hwc_window_data)
+ return;
- free(vc4_hwc_window);
+ LIST_DEL(&hwc_window_data->link);
- 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";
-
- return "unknown";
+ free(hwc_window_data);
}
tdm_error
-vc4_output_hwc_validate(tdm_output *output, tdm_hwc_window **composited_wnds,
+vc4_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds,
uint32_t num_wnds, uint32_t *num_types)
{
- tdm_vc4_output_data *vc4_output = output;
- tdm_vc4_data *vc4_data = NULL;
- RETURN_VAL_IF_FAIL(vc4_output != NULL, TDM_ERROR_INVALID_PARAMETER);
+ tdm_vc4_hwc_data *hwc_data = hwc;
+
+ RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
RETURN_VAL_IF_FAIL(num_types != NULL, TDM_ERROR_INVALID_PARAMETER);
+
tdm_vc4_hwc_window_data *hw = NULL;
int hw_layer_count = 0;
int need_target_buffer = 0;
- int max_hw_layer = LIST_LENGTH(&vc4_output->layer_list);
- int fb_index = _get_primary_layer_index(vc4_output);
+ int max_hw_layer = LIST_LENGTH(&hwc_data->output_data->layer_list);
+ int fb_index = _get_primary_layer_index(hwc_data->output_data);
int i = 0;
int top_layer_idx = fb_index;
- vc4_data = vc4_output->vc4_data;
- RETURN_VAL_IF_FAIL(vc4_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-
- if (vc4_output->need_set_crtc) {
+ if (hwc_data->need_set_crtc) {
need_target_buffer = 1;
- LIST_FOR_EACH_ENTRY(hw, &vc4_output->hwc_window_list, link) {
+ LIST_FOR_EACH_ENTRY(hw, &hwc_data->hwc_window_list, link) {
hw->validated_type = TDM_COMPOSITION_CLIENT;
}
} else {
int layer_idx;
- int num_hwc_windows = LIST_LENGTH(&vc4_output->hwc_window_list);
+ int num_hwc_windows = LIST_LENGTH(&hwc_data->hwc_window_list);
- LIST_FOR_EACH_ENTRY(hw, &vc4_output->hwc_window_list, link) {
+ LIST_FOR_EACH_ENTRY(hw, &hwc_data->hwc_window_list, link) {
hw->validated_type = TDM_COMPOSITION_CLIENT;
}
/* mark the top window */
if (num_hwc_windows > 1) {
layer_idx = max_hw_layer;
- LIST_FOR_EACH_ENTRY_REV(hw, &vc4_output->hwc_window_list, link) {
+ LIST_FOR_EACH_ENTRY_REV(hw, &hwc_data->hwc_window_list, link) {
layer_idx--;
if (hw->client_type == TDM_COMPOSITION_DEVICE && layer_idx != fb_index) {
//check format
/* mark the bottom windows */
layer_idx = -1;
- LIST_FOR_EACH_ENTRY(hw, &vc4_output->hwc_window_list, link) {
+ LIST_FOR_EACH_ENTRY(hw, &hwc_data->hwc_window_list, link) {
layer_idx++;
/* break if the remaining windows are already marked */
if (hw->validated_type == TDM_COMPOSITION_DEVICE)
}
}
- LIST_FOR_EACH_ENTRY(hw, &vc4_output->hwc_window_list, link) {
+ LIST_FOR_EACH_ENTRY(hw, &hwc_data->hwc_window_list, link) {
if (need_target_buffer && fb_index == i++)
- TDM_DBG(" window(%p) target", vc4_output->target_hwc_window);
+ TDM_DBG(" window(%p) target", hwc_data->target_hwc_window);
else
TDM_DBG(" window(%p) type: %s -> %s", hw,
_comp_to_str(hw->client_type), _comp_to_str(hw->validated_type));
if (need_target_buffer)
hw_layer_count++;
- vc4_output->need_target_buffer = need_target_buffer;
- vc4_output->hw_layer_count = hw_layer_count;
- vc4_output->top_layer_idx = top_layer_idx;
+ hwc_data->need_target_buffer = need_target_buffer;
+ hwc_data->hw_layer_count = hw_layer_count;
+ hwc_data->top_layer_idx = top_layer_idx;
- *num_types = _vc4_output_get_changed_number(vc4_output);
+ *num_types = _vc4_hwc_get_changed_number(hwc_data);
if (*num_types == 0)
- vc4_output->need_validate = 0;
+ hwc_data->need_validate = 0;
return TDM_ERROR_NONE;
}
tdm_error
-vc4_output_hwc_get_changed_composition_types(tdm_output *output,
+vc4_hwc_get_changed_composition_types(tdm_hwc *hwc,
uint32_t *num_elements,
tdm_hwc_window **hwc_window,
tdm_hwc_window_composition *composition_types)
{
- tdm_vc4_output_data *vc4_output = output;
+ tdm_vc4_hwc_data *hwc_data = hwc;
int num = 0;
- RETURN_VAL_IF_FAIL(vc4_output != 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 = _vc4_output_get_changed_number(vc4_output);
+ *num_elements = _vc4_hwc_get_changed_number(hwc_data);
return TDM_ERROR_NONE;
}
tdm_vc4_hwc_window_data *hw = NULL;
- LIST_FOR_EACH_ENTRY_REV(hw, &vc4_output->hwc_window_list, link) {
+ LIST_FOR_EACH_ENTRY_REV(hw, &hwc_data->hwc_window_list, link) {
if (num >= *num_elements)
break;
}
tdm_error
-vc4_output_hwc_accept_changes(tdm_output *output)
+vc4_hwc_accept_changes(tdm_hwc *hwc)
{
- tdm_vc4_output_data *vc4_output = output;
+ tdm_vc4_hwc_data *hwc_data = hwc;
- RETURN_VAL_IF_FAIL(vc4_output != NULL, TDM_ERROR_INVALID_PARAMETER);
+ RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
tdm_vc4_hwc_window_data *hw = NULL;
- LIST_FOR_EACH_ENTRY_REV(hw, &vc4_output->hwc_window_list, link)
+ LIST_FOR_EACH_ENTRY_REV(hw, &hwc_data->hwc_window_list, link)
hw->client_type = hw->validated_type;
- vc4_output->need_validate = 0;
+ hwc_data->need_validate = 0;
return TDM_ERROR_NONE;
}
tbm_surface_queue_h
-vc4_output_hwc_get_target_buffer_queue(tdm_output *output, tdm_error *error)
+vc4_hwc_get_client_target_buffer_queue(tdm_hwc *hwc, tdm_error *error)
{
- tdm_vc4_output_data *vc4_output = output;
+ tdm_vc4_hwc_data *hwc_data = hwc;
tbm_surface_queue_h tqueue = NULL;
if (error)
*error = TDM_ERROR_INVALID_PARAMETER;
- RETURN_VAL_IF_FAIL(vc4_output != NULL, NULL);
+ RETURN_VAL_IF_FAIL(hwc_data != NULL, NULL);
- if (vc4_output->target_hwc_window == NULL) {
+ if (hwc_data->target_hwc_window == NULL) {
if (error)
*error = TDM_ERROR_OPERATION_FAILED;
return NULL;
}
- tqueue = vc4_hwc_window_get_tbm_buffer_queue(vc4_output->target_hwc_window, error);
+ tqueue = _vc4_hwc_window_get_tbm_buffer_queue(hwc_data->target_hwc_window, error);
RETURN_VAL_IF_FAIL(tqueue, NULL);
if (error)
}
tdm_error
-vc4_output_hwc_set_client_target_buffer(tdm_output *output, tbm_surface_h buffer, tdm_hwc_region damage)
+vc4_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h buffer, tdm_region damage)
{
- tdm_vc4_output_data *vc4_output = output;
+ tdm_vc4_hwc_data *hwc_data = hwc;
tdm_error err;
- RETURN_VAL_IF_FAIL(vc4_output != NULL, TDM_ERROR_INVALID_PARAMETER);
- RETURN_VAL_IF_FAIL(vc4_output->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 = vc4_hwc_window_set_buffer(vc4_output->target_hwc_window, buffer);
+ err = vc4_hwc_window_set_buffer(hwc_data->target_hwc_window, buffer);
RETURN_VAL_IF_FAIL(err == TDM_ERROR_NONE, err);
- err = vc4_hwc_window_set_buffer_damage(vc4_output->target_hwc_window, damage);
+ err = vc4_hwc_window_set_buffer_damage(hwc_data->target_hwc_window, damage);
RETURN_VAL_IF_FAIL(err == TDM_ERROR_NONE, err);
return TDM_ERROR_NONE;
}
-
-tbm_surface_queue_h
-vc4_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error)
+tdm_error
+vc4_hwc_window_set_composition_type(tdm_hwc_window *hwc_window,
+ tdm_hwc_window_composition comp_type)
{
- tdm_vc4_hwc_window_data *vc4_hwc_window = NULL;
- tdm_vc4_output_data *vc4_output = NULL;
- tbm_surface_queue_h tqueue = NULL;
- tbm_format format;
+ tdm_vc4_hwc_window_data *hwc_window_data = hwc_window;
+ tdm_vc4_hwc_data *hwc_data = hwc_window_data->hwc_data;
- if (error)
- *error = TDM_ERROR_INVALID_PARAMETER;
+ RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+ RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
- RETURN_VAL_IF_FAIL(hwc_window != NULL, NULL);
- vc4_hwc_window = hwc_window;
- vc4_output = vc4_hwc_window->output_data;
- RETURN_VAL_IF_FAIL(vc4_output != NULL, NULL);
+ if (hwc_window_data->client_type == comp_type)
+ return TDM_ERROR_NONE;
- int wight = vc4_hwc_window->info.src_config.size.h;
- int hight = vc4_hwc_window->info.src_config.size.v;
+ hwc_window_data->client_type = comp_type;
+ hwc_data->need_validate = 1;
- format = vc4_hwc_window->info.src_config.format;
+ return TDM_ERROR_NONE;
- 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;
+tdm_error
+vc4_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_region damage)
+{
+ tdm_vc4_hwc_window_data *hwc_window_data = hwc_window;
+ tdm_vc4_hwc_data *hwc_data = hwc_window_data->hwc_data;
- return tqueue;
+ RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+ RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+ //TODO::
+ return TDM_ERROR_NONE;
}
tdm_error
-vc4_hwc_window_set_composition_type(tdm_hwc_window *hwc_window,
- tdm_hwc_window_composition comp_type)
+vc4_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info)
{
- tdm_vc4_hwc_window_data *vc4_hwc_window = hwc_window;
- tdm_vc4_output_data *vc4_output = vc4_hwc_window->output_data;
+ tdm_vc4_hwc_window_data *hwc_window_data = hwc_window;
+ tdm_vc4_hwc_data *hwc_data = hwc_window_data->hwc_data;
- RETURN_VAL_IF_FAIL(vc4_hwc_window != NULL, TDM_ERROR_INVALID_PARAMETER);
- RETURN_VAL_IF_FAIL(vc4_output != NULL, TDM_ERROR_INVALID_PARAMETER);
+ RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+ RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
- if (vc4_hwc_window->client_type == comp_type)
+ if (!memcmp(&hwc_window_data->info, info, sizeof(tdm_hwc_window_info)))
return TDM_ERROR_NONE;
- vc4_hwc_window->client_type = comp_type;
- vc4_output->need_validate = 1;
+ hwc_window_data->info = *info;
+ hwc_data->need_validate = 1;
return TDM_ERROR_NONE;
-
}
tdm_error
-vc4_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_hwc_region damage)
+vc4_hwc_window_get_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info)
{
- tdm_vc4_hwc_window_data *vc4_hwc_window = hwc_window;
- tdm_vc4_output_data *vc4_output = vc4_hwc_window->output_data;
+ tdm_vc4_hwc_window_data *hwc_window_data = hwc_window;
- RETURN_VAL_IF_FAIL(vc4_hwc_window != NULL, TDM_ERROR_INVALID_PARAMETER);
- RETURN_VAL_IF_FAIL(vc4_output != NULL, TDM_ERROR_INVALID_PARAMETER);
+ RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+ RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER);
- //TODO::
+ *info = hwc_window_data->info;
return TDM_ERROR_NONE;
}
tdm_error
-vc4_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info)
+vc4_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h surface)
{
- tdm_vc4_hwc_window_data *vc4_hwc_window = hwc_window;
- tdm_vc4_output_data *vc4_output = vc4_hwc_window->output_data;
+ tdm_vc4_hwc_window_data *hwc_window_data = hwc_window;
+ tdm_error err = TDM_ERROR_OPERATION_FAILED;
- RETURN_VAL_IF_FAIL(vc4_hwc_window != NULL, TDM_ERROR_INVALID_PARAMETER);
- RETURN_VAL_IF_FAIL(vc4_output != NULL, TDM_ERROR_INVALID_PARAMETER);
+ RETURN_VAL_IF_FAIL(hwc_window_data != NULL, err);
- if (!memcmp(&vc4_hwc_window->info, info, sizeof(tdm_hwc_window_info)))
+ if (hwc_window_data->surface == surface)
return TDM_ERROR_NONE;
- vc4_hwc_window->info = *info;
- vc4_output->need_validate = 1;
+ hwc_window_data->surface = surface;
return TDM_ERROR_NONE;
}
tdm_error
-vc4_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h surface)
+vc4_hwc_get_supported_formats(tdm_hwc *hwc, const tbm_format **formats, int *count)
+{
+ tdm_vc4_hwc_data *hwc_data = hwc;
+
+ RETURN_VAL_IF_FAIL(hwc_data != 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:
+
+ return TDM_ERROR_NONE;
+}
+
+tdm_error
+vc4_hwc_get_available_properties(tdm_hwc *hwc, const tdm_prop **props, int *count)
+{
+ tdm_vc4_hwc_data *hwc_data = hwc;
+
+ RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+ // TODO:
+
+ return TDM_ERROR_NONE;
+}
+
+tdm_error
+vc4_hwc_commit(tdm_hwc *hwc, int sync, void *user_data)
{
- tdm_vc4_hwc_window_data *vc4_hwc_window = hwc_window;
- tdm_vc4_output_data *vc4_output;
+// TODO:
+#if 0
+ tdm_vc4_output_data *output_data = output;
tdm_vc4_data *vc4_data;
- tdm_error err = TDM_ERROR_OPERATION_FAILED;
+ tdm_vc4_layer_data *layer_data = NULL;
+ tdm_error ret;
+ int do_waitvblank = 1;
- RETURN_VAL_IF_FAIL(vc4_hwc_window != NULL, err);
+ RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
- vc4_output = vc4_hwc_window->output_data;
- vc4_data = vc4_hwc_window->vc4_data;
+ vc4_data = output_data->vc4_data;
- RETURN_VAL_IF_FAIL(vc4_output != NULL, err);
- RETURN_VAL_IF_FAIL(vc4_data != NULL, err);
+ if (output_data->hwc_enable) {
+ ret = _vc4_output_hwc_prepare_commit(output_data);
+ RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
+ }
- if (vc4_hwc_window->surface == surface)
- return TDM_ERROR_NONE;
+ LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
+ if (layer_data == output_data->primary_layer) {
+ if (!layer_data->display_buffer ||
+ (output_data->current_mode->hdisplay == layer_data->info.src_config.pos.w &&
+ output_data->current_mode->vdisplay == layer_data->info.src_config.pos.h)) {
+ ret = _tdm_vc4_output_commit_primary_layer(layer_data, user_data,
+ &do_waitvblank);
+ output_data->need_set_crtc = 0;
+ } else
+ ret = _tdm_vc4_output_commit_layer(layer_data);
+
+ if (ret != TDM_ERROR_NONE)
+ return ret;
+ } else {
+ ret = _tdm_vc4_output_commit_layer(layer_data);
+ if (ret != TDM_ERROR_NONE)
+ return ret;
+ }
+ }
+
+ if (do_waitvblank == 1) {
+ tdm_vc4_event_data *event_data = calloc(1, sizeof(tdm_vc4_event_data));
+ uint target_msc;
+
+ if (!event_data) {
+ TDM_ERR("alloc failed");
+ return TDM_ERROR_OUT_OF_MEMORY;
+ }
+
+ ret = _tdm_vc4_output_get_cur_msc(vc4_data->drm_fd, output_data->pipe,
+ &target_msc);
+ if (ret != TDM_ERROR_NONE) {
+ free(event_data);
+ return ret;
+ }
+
+ target_msc++;
+
+ event_data->type = TDM_vc4_EVENT_TYPE_COMMIT;
+ event_data->output_data = output_data;
+ event_data->user_data = user_data;
- vc4_hwc_window->surface = surface;
+ ret = _tdm_vc4_output_wait_vblank(vc4_data->drm_fd, output_data->pipe,
+ &target_msc, event_data);
+ if (ret != TDM_ERROR_NONE) {
+ free(event_data);
+ return ret;
+ }
+ }
+#endif
+ return TDM_ERROR_NONE;
+}
+
+tdm_error
+vc4_hwc_set_commit_handler(tdm_hwc *hwc, tdm_hwc_commit_handler func)
+{
+ tdm_vc4_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
+vc4_hwc_window_set_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value value)
+{
+ tdm_vc4_hwc_window_data *hwc_window_data = hwc_window;
+
+ RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+#if 0
+ output_data = hwc_window_data->output_data;
+ RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+ layer_data = _vc4_output_get_layer(output_data, hwc_window_data->assigned_layer_zpos);
+
+ return vc4_layer_set_property(layer_data, id, value);
+#endif
+
+ return TDM_ERROR_NONE;
+}
+
+tdm_error
+vc4_hwc_window_get_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value *value)
+{
+ tdm_vc4_hwc_window_data *hwc_window_data = hwc_window;
+
+ RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+#if 0
+ output_data = hwc_window_data->output_data;
+ RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+ layer_data = _vc4_output_get_layer(output_data, hwc_window_data->assigned_layer_zpos);
+
+ return vc4_layer_get_property(layer_data, id, value);
+#endif
return TDM_ERROR_NONE;
}