struct list_head call_link;
} tdm_client_voutput_commit_handler_info;
+typedef enum {
+ VBLANK_WAIT_TYPE_INTERVAL,
+ VBLANK_WAIT_TYPE_SEQUENCE,
+} tdm_client_vblank_wait_type;
+
static unsigned int
_tdm_client_check_wl_error(tdm_private_client *private_client, const char *func, int line)
{
return TDM_ERROR_NONE;
}
-tdm_error
-tdm_client_vblank_wait(tdm_client_vblank *vblank, unsigned int interval, tdm_client_vblank_handler func, void *user_data)
+static tdm_error
+_tdm_client_vblank_wait(tdm_client_vblank *vblank, tdm_client_vblank_wait_type wait_type, unsigned int wait_value,
+ tdm_client_vblank_handler func, void *user_data)
{
tdm_private_client *private_client;
tdm_private_client_output *private_output;
unsigned int req_sec, req_usec;
int ret = 0;
- TDM_RETURN_VAL_IF_FAIL(vblank != NULL, TDM_ERROR_INVALID_PARAMETER);
- TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
- /* can't support "interval 0" and "getting current_msc" things because
- * there is a socket communication between TDM client and server. It's impossible
- * to return the current msc or sequence immediately.
- */
- TDM_RETURN_VAL_IF_FAIL(interval > 0, TDM_ERROR_INVALID_PARAMETER);
-
private_vblank = vblank;
private_output = private_vblank->private_output;
private_client = private_output->private_client;
w->req_time = TDM_TIME(req_sec, req_usec);
w->need_free = (private_vblank->sync) ? 0 : 1;
- wl_tdm_vblank_wait_vblank(private_vblank->vblank, interval, w->req_id, req_sec, req_usec);
+ if (wait_type == VBLANK_WAIT_TYPE_INTERVAL)
+ wl_tdm_vblank_wait_vblank(private_vblank->vblank, wait_value, w->req_id, req_sec, req_usec);
+ else
+ wl_tdm_vblank_wait_vblank_seq(private_vblank->vblank, wait_value, w->req_id, req_sec, req_usec);
if (private_vblank->enable_ttrace)
TDM_TRACE_ASYNC_BEGIN((int)w->req_time, "TDM_Client_Vblank:%u", private_vblank->stamp);
- TDM_DBG("vblank(%p) interval(%u) req_id(%d) req(%.6f)",
- vblank, interval, w->req_id, w->req_time);
+ TDM_DBG("vblank(%p) wait_type(%d) wait_value(%u) req_id(%d) req(%.6f)",
+ vblank, wait_type, wait_value, w->req_id, w->req_time);
private_vblank->req_time = w->req_time;
}
tdm_error
-tdm_client_vblank_wait_seq(tdm_client_vblank *vblank, unsigned int sequence,
- tdm_client_vblank_handler func, void *user_data)
+tdm_client_vblank_wait(tdm_client_vblank *vblank, unsigned int interval, tdm_client_vblank_handler func, void *user_data)
{
- tdm_private_client *private_client;
- tdm_private_client_output *private_output;
- tdm_private_client_vblank *private_vblank;
- tdm_client_wait_info *w;
- struct timespec tp;
- unsigned int req_sec, req_usec;
- int ret = 0;
-
TDM_RETURN_VAL_IF_FAIL(vblank != NULL, TDM_ERROR_INVALID_PARAMETER);
TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
- private_vblank = vblank;
- private_output = private_vblank->private_output;
- private_client = private_output->private_client;
-
- pthread_mutex_lock(&private_client->lock);
-
- if (CHECK_WL_PROTOCOL_ERROR(private_client)) {
- pthread_mutex_unlock(&private_client->lock);
- return TDM_ERROR_PROTOCOL_ERROR;
- }
-
- if (!private_vblank->started)
- private_vblank->started = 1;
-
- if (!private_vblank->enable_fake) {
- if (private_output->connection == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) {
- TDM_ERR("output disconnected");
- pthread_mutex_unlock(&private_client->lock);
- return TDM_ERROR_OUTPUT_DISCONNECTED;
- }
- if (TDM_OUTPUT_DPMS_VSYNC_IS_OFF(private_output->dpms)) {
- TDM_ERR("dpms %s", tdm_dpms_str(private_output->dpms));
- pthread_mutex_unlock(&private_client->lock);
- return TDM_ERROR_DPMS_OFF;
- }
- }
-
- w = calloc(1, sizeof *w);
- if (!w) {
- /* LCOV_EXCL_START */
-
- TDM_ERR("alloc failed");
- pthread_mutex_unlock(&private_client->lock);
- return TDM_ERROR_OUT_OF_MEMORY;
-
- /* LCOV_EXCL_STOP */
- }
-
- w->private_vblank = private_vblank;
- w->func = func;
- w->user_data = user_data;
-
- LIST_ADDTAIL(&w->link, &private_vblank->wait_list);
- LIST_INITHEAD(&w->call_link);
-
- clock_gettime(CLOCK_MONOTONIC, &tp);
- req_sec = (unsigned int)tp.tv_sec;
- req_usec = (unsigned int)(tp.tv_nsec / 1000);
-
- w->req_id = ++private_output->req_id;
- w->req_time = TDM_TIME(req_sec, req_usec);
- w->need_free = (private_vblank->sync) ? 0 : 1;
-
- wl_tdm_vblank_wait_vblank_seq(private_vblank->vblank, sequence, w->req_id, req_sec, req_usec);
-
- if (private_vblank->enable_ttrace)
- TDM_TRACE_ASYNC_BEGIN((int)w->req_time, "TDM_Client_Vblank:%u", private_vblank->stamp);
-
- TDM_DBG("vblank(%p) sequence(%u) req_id(%d) req(%.6f)",
- vblank, sequence, w->req_id, w->req_time);
-
- private_vblank->req_time = w->req_time;
-
- if (private_vblank->last_time >= w->req_time)
- TDM_ERR("'last(%.6f) < req(%.6f)' failed", private_vblank->last_time, w->req_time);
-
- if (!private_vblank->sync) {
- wl_display_flush(private_client->display);
- pthread_mutex_unlock(&private_client->lock);
- return TDM_ERROR_NONE;
- }
-
- /* LCOV_EXCL_START */
-
- while (ret != -1 && !w->need_free)
- ret = wl_display_dispatch(private_client->display);
-
- clock_gettime(CLOCK_MONOTONIC, &tp);
- TDM_DBG("block during %d us",
- ((unsigned int)(tp.tv_sec * 1000000) + (unsigned int)(tp.tv_nsec / 1000))
- - (req_sec * 1000000 + req_usec));
-
- LIST_DEL(&w->link);
- free(w);
-
- if (CHECK_WL_PROTOCOL_ERROR(private_client)) {
- pthread_mutex_unlock(&private_client->lock);
- return TDM_ERROR_PROTOCOL_ERROR;
- }
+ /* can't support "interval 0" and "getting current_msc" things because
+ * there is a socket communication between TDM client and server. It's impossible
+ * to return the current msc or sequence immediately.
+ */
+ TDM_RETURN_VAL_IF_FAIL(interval > 0, TDM_ERROR_INVALID_PARAMETER);
- pthread_mutex_unlock(&private_client->lock);
+ return _tdm_client_vblank_wait(vblank, VBLANK_WAIT_TYPE_INTERVAL, interval, func, user_data);
+}
- return TDM_ERROR_NONE;
+tdm_error
+tdm_client_vblank_wait_seq(tdm_client_vblank *vblank, unsigned int sequence,
+ tdm_client_vblank_handler func, void *user_data)
+{
+ TDM_RETURN_VAL_IF_FAIL(vblank != NULL, TDM_ERROR_INVALID_PARAMETER);
+ TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
- /* LCOV_EXCL_STOP */
+ return _tdm_client_vblank_wait(vblank, VBLANK_WAIT_TYPE_SEQUENCE, sequence, func, user_data);
}
unsigned int
return tbm_surface;
}
+
+static tdm_private_client_buffer *
+_tdm_client_voutput_create_buffer(tdm_private_client_voutput *private_voutput,
+ tbm_surface_h tbm_surface,
+ struct wl_buffer *wl_buffer)
+{
+ tdm_private_client_buffer *buffer = NULL;
+
+ buffer = calloc(1, sizeof *buffer);
+ TDM_RETURN_VAL_IF_FAIL(buffer != NULL, NULL);
+
+ tbm_surface_internal_ref(tbm_surface);
+ wl_buffer_set_user_data(wl_buffer, tbm_surface);
+
+ buffer->wl_buffer = wl_buffer;
+
+ LIST_ADDTAIL(&buffer->link, &private_voutput->buffer_list);
+
+ return buffer;
+}
+
static void
tdm_client_voutput_cb_buffer_import_with_id(void *data,
struct wl_tdm_voutput *wl_voutput,
TDM_RETURN_IF_FAIL(private_voutput != NULL);
- buffer = calloc(1, sizeof *buffer);
- TDM_RETURN_IF_FAIL(buffer != NULL);
-
tbm_surface = _tdm_client_voutput_create_surface_from_param(private_voutput->bufmgr, 0,
width, height, format, bpp, size,
num_plane,
buf0, buf1, buf2);
TDM_GOTO_IF_FAIL(tbm_surface != NULL, fail);
- tbm_surface_internal_ref(tbm_surface);
- wl_buffer_set_user_data(wl_buffer, tbm_surface);
-
- buffer->wl_buffer = wl_buffer;
-
- LIST_ADDTAIL(&buffer->link, &private_voutput->buffer_list);
+ buffer = _tdm_client_voutput_create_buffer(private_voutput, tbm_surface, wl_buffer);
+ TDM_GOTO_IF_FAIL(buffer != NULL, fail);
return;
fail:
- if (buffer)
- free(buffer);
-
if (wl_buffer)
wl_buffer_destroy(wl_buffer);
}
buf0, buf1, buf2);
TDM_GOTO_IF_FAIL(tbm_surface != NULL, fail);
- tbm_surface_internal_ref(tbm_surface);
- wl_buffer_set_user_data(wl_buffer, tbm_surface);
-
- buffer->wl_buffer = wl_buffer;
-
- LIST_ADDTAIL(&buffer->link, &private_voutput->buffer_list);
+ buffer = _tdm_client_voutput_create_buffer(private_voutput, tbm_surface, wl_buffer);
+ TDM_GOTO_IF_FAIL(buffer != NULL, fail);
return;
fail:
- if (buffer)
- free(buffer);
-
if (wl_buffer)
wl_buffer_destroy(wl_buffer);
}