private_output = private_layer->private_output; \
private_display = private_output->private_display
-static void _tdm_layer_committed(tdm_private_layer *private_layer);
+static void _tdm_layer_free_buffer(tdm_private_layer *private_layer, tdm_private_layer_buffer *layer_buffer);
+static void _tdm_layer_committed(tdm_private_layer *private_layer, tdm_private_layer_buffer **committed_buffer);
static void _tdm_layer_cb_wait_vblank(tdm_vblank *vblank, tdm_error error, unsigned int sequence,
unsigned int tv_sec, unsigned int tv_usec, void *user_data);
static void _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data);
}
if (tdm_debug_module & TDM_DEBUG_COMMIT)
- TDM_INFO("-----------------------------------------");
+ TDM_INFO("----------------------------------------- output(%d) got vblank", private_output->pipe);
_pthread_mutex_unlock(&private_display->lock);
LIST_FOR_EACH_ENTRY_SAFE(v, vv, &clone_list, link) {
if (tdm_debug_module & TDM_DEBUG_COMMIT)
- TDM_INFO("output(%d) got vblank: handler(%p)", private_output->pipe, v);
+ TDM_INFO("handler(%p)", v);
if (v->func)
v->func(v->private_output, sequence, tv_sec, tv_usec, v->user_data);
return;
}
+ if (tdm_debug_module & TDM_DEBUG_COMMIT) {
+ TDM_INFO("----------------------------------------- output(%d) committed", private_output->pipe);
+ TDM_INFO("handler(%p)", output_commit_handler);
+ }
+
if (private_display->commit_type == TDM_COMMIT_TYPE_OUTPUT) {
/* In case of layer commit, the below will be handled in the layer commit callback */
LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
- _tdm_layer_committed(private_layer);
+ if (private_layer->committed_buffer)
+ _tdm_layer_committed(private_layer, &private_layer->committed_buffer);
}
}
LIST_DEL(&output_commit_handler->link);
free(output_commit_handler);
+
+ if (tdm_debug_module & TDM_DEBUG_COMMIT)
+ TDM_INFO("-----------------------------------------...");
}
/* add_front: To distinguish between the user vblank handlers and the layer
{
tdm_func_output *func_output;
tdm_private_output_commit_handler *output_commit_handler = NULL;
+ tdm_private_layer *private_layer = NULL;
+
OUTPUT_FUNC_ENTRY();
func_output = &private_display->func_output;
TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed);
if (tdm_debug_module & TDM_DEBUG_COMMIT)
- TDM_INFO("output(%d) backend commit", private_output->pipe);
+ TDM_INFO("output(%d) backend commit: handle(%p)", private_output->pipe, output_commit_handler);
+
+ LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
+ if (!private_layer->waiting_buffer)
+ continue;
+
+ private_layer->committed_buffer = private_layer->waiting_buffer;
+ private_layer->waiting_buffer = NULL;
+ if (tdm_debug_module & TDM_DEBUG_BUFFER)
+ TDM_INFO("layer(%p) waiting_buffer(%p) committed_buffer(%p)",
+ private_layer, private_layer->waiting_buffer,
+ private_layer->committed_buffer->buffer);
+ }
return ret;
return;
}
+static void
+_tdm_layer_free_buffer(tdm_private_layer *private_layer, tdm_private_layer_buffer *layer_buffer)
+{
+ tdm_private_display *private_display;
+
+ if (!layer_buffer)
+ return;
+
+ private_display = private_layer->private_output->private_display;
+
+ LIST_DEL(&layer_buffer->link);
+ if (layer_buffer->buffer) {
+ _pthread_mutex_unlock(&private_display->lock);
+ tdm_buffer_unref_backend(layer_buffer->buffer);
+ if (private_layer->buffer_queue)
+ tbm_surface_queue_release(private_layer->buffer_queue, layer_buffer->buffer);
+ _pthread_mutex_lock(&private_display->lock);
+ }
+ free(layer_buffer);
+}
+
+static void
+_tdm_layer_free_all_buffers(tdm_private_layer *private_layer)
+{
+ tdm_private_output *private_output = private_layer->private_output;
+ tdm_private_layer_commit_handler *lm = NULL, *lmm = NULL;
+ struct list_head clone_list;
+
+ LIST_INITHEAD(&clone_list);
+
+ if (private_layer->waiting_buffer) {
+ _tdm_layer_free_buffer(private_layer, private_layer->waiting_buffer);
+ private_layer->waiting_buffer = NULL;
+
+ if (tdm_debug_module & TDM_DEBUG_BUFFER)
+ TDM_INFO("layer(%p) waiting_buffer(%p)",
+ private_layer, private_layer->waiting_buffer);
+ }
+
+ if (private_layer->committed_buffer) {
+ _tdm_layer_free_buffer(private_layer, private_layer->committed_buffer);
+ private_layer->committed_buffer = NULL;
+
+ if (tdm_debug_module & TDM_DEBUG_BUFFER)
+ TDM_INFO("layer(%p) committed_buffer(%p)",
+ private_layer, private_layer->committed_buffer);
+ }
+
+ if (private_layer->showing_buffer) {
+ _tdm_layer_free_buffer(private_layer, private_layer->showing_buffer);
+ private_layer->showing_buffer = NULL;
+
+ if (tdm_debug_module & TDM_DEBUG_BUFFER)
+ TDM_INFO("layer(%p) showing_buffer(%p)",
+ private_layer, private_layer->showing_buffer);
+ }
+
+ LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->layer_commit_handler_list, link) {
+ if (lm->private_layer != private_layer)
+ continue;
+ LIST_DEL(&lm->link);
+ LIST_ADDTAIL(&lm->link, &clone_list);
+ }
+
+ LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &clone_list, link) {
+ LIST_DEL(&lm->link);
+ _tdm_layer_free_buffer(private_layer, lm->committed_buffer);
+ free(lm);
+ }
+
+ LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->pending_commit_handler_list, link) {
+ if (lm->private_layer != private_layer)
+ continue;
+ LIST_DEL(&lm->link);
+ LIST_ADDTAIL(&lm->link, &clone_list);
+ }
+
+ LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &clone_list, link) {
+ LIST_DEL(&lm->link);
+ _tdm_layer_free_buffer(private_layer, lm->committed_buffer);
+ free(lm);
+ }
+
+ if (private_layer->buffer_queue) {
+ tbm_surface_queue_remove_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, private_layer);
+ tbm_surface_queue_remove_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, private_layer);
+ private_layer->buffer_queue = NULL;
+ }
+}
+
EXTERN tdm_error
tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
{
return TDM_ERROR_NOT_IMPLEMENTED;
}
- layer_buffer = calloc(1, sizeof * layer_buffer);
+ layer_buffer = calloc(1, sizeof(tdm_private_layer_buffer));
if (!layer_buffer) {
_pthread_mutex_unlock(&private_display->lock);
TDM_ERR("alloc failed");
return TDM_ERROR_OUT_OF_MEMORY;
}
+ LIST_INITHEAD(&layer_buffer->link);
ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
_tdm_layer_dump_buffer(layer, buffer);
if (ret == TDM_ERROR_NONE) {
- /* FIXME: should save to pending_buffer first. And after committing
- * successfully, need to move to waiting_buffer.
- */
- if (private_layer->waiting_buffer) {
- _pthread_mutex_unlock(&private_display->lock);
- tdm_buffer_unref_backend(private_layer->waiting_buffer->buffer);
- _pthread_mutex_lock(&private_display->lock);
- free(private_layer->waiting_buffer);
- }
+ if (private_layer->waiting_buffer)
+ _tdm_layer_free_buffer(private_layer, private_layer->waiting_buffer);
private_layer->waiting_buffer = layer_buffer;
private_layer->waiting_buffer->buffer = tdm_buffer_ref_backend(buffer);
TDM_INFO("layer(%p) waiting_buffer(%p)",
private_layer, private_layer->waiting_buffer->buffer);
} else
- free(layer_buffer);
+ _tdm_layer_free_buffer(private_layer, layer_buffer);
_pthread_mutex_unlock(&private_display->lock);
EXTERN tdm_error
tdm_layer_unset_buffer(tdm_layer *layer)
{
- tdm_private_layer_commit_handler *lm = NULL, *lmm = NULL;
tdm_func_layer *func_layer;
LAYER_FUNC_ENTRY();
func_layer = &private_display->func_layer;
- if (private_layer->buffer_queue) {
- if (private_layer->waiting_buffer)
- tbm_surface_queue_release(private_layer->buffer_queue, private_layer->waiting_buffer->buffer);
- if (private_layer->showing_buffer)
- tbm_surface_queue_release(private_layer->buffer_queue, private_layer->showing_buffer->buffer);
- tbm_surface_queue_remove_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, layer);
- tbm_surface_queue_remove_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, layer);
- private_layer->buffer_queue = NULL;
- }
-
- if (private_layer->waiting_buffer) {
- _pthread_mutex_unlock(&private_display->lock);
- tdm_buffer_unref_backend(private_layer->waiting_buffer->buffer);
- _pthread_mutex_lock(&private_display->lock);
- free(private_layer->waiting_buffer);
- private_layer->waiting_buffer = NULL;
-
- if (tdm_debug_module & TDM_DEBUG_BUFFER)
- TDM_INFO("layer(%p) waiting_buffer(%p)",
- private_layer, private_layer->waiting_buffer);
- }
-
- if (private_layer->showing_buffer) {
- _pthread_mutex_unlock(&private_display->lock);
- tdm_buffer_unref_backend(private_layer->showing_buffer->buffer);
- _pthread_mutex_lock(&private_display->lock);
- free(private_layer->showing_buffer);
- private_layer->showing_buffer = NULL;
-
- if (tdm_debug_module & TDM_DEBUG_BUFFER)
- TDM_INFO("layer(%p) showing_buffer(%p)",
- private_layer, private_layer->showing_buffer);
- }
-
- LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->layer_commit_handler_list, link) {
- if (lm->private_layer != private_layer)
- continue;
- LIST_DEL(&lm->link);
- free(lm);
- }
-
- LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->pending_commit_handler_list, link) {
- if (lm->private_layer != private_layer)
- continue;
- LIST_DEL(&lm->link);
- free(lm);
- }
+ _tdm_layer_free_all_buffers(private_layer);
private_layer->usable = 1;
}
static void
-_tdm_layer_committed(tdm_private_layer *private_layer)
+_tdm_layer_committed(tdm_private_layer *private_layer, tdm_private_layer_buffer **committed_buffer)
{
tdm_private_output *private_output = private_layer->private_output;
tdm_private_display *private_display = private_output->private_display;
- if (!private_layer->waiting_buffer)
- return;
-
if (private_display->print_fps) {
double curr = tdm_helper_get_time();
if (private_layer->fps_stamp == 0) {
private_layer->fps_count = 0;
}
- if (private_layer->showing_buffer) {
- _pthread_mutex_unlock(&private_display->lock);
- tdm_buffer_unref_backend(private_layer->showing_buffer->buffer);
- _pthread_mutex_lock(&private_display->lock);
-
- if (private_layer->buffer_queue) {
- _pthread_mutex_unlock(&private_display->lock);
- tbm_surface_queue_release(private_layer->buffer_queue,
- private_layer->showing_buffer->buffer);
- _pthread_mutex_lock(&private_display->lock);
- }
- }
+ if (private_layer->showing_buffer)
+ _tdm_layer_free_buffer(private_layer, private_layer->showing_buffer);
- private_layer->showing_buffer = private_layer->waiting_buffer;
- private_layer->waiting_buffer = NULL;
+ private_layer->showing_buffer = *committed_buffer;
+ *committed_buffer = NULL;
if (tdm_debug_module & TDM_DEBUG_BUFFER)
- TDM_INFO("layer(%p) waiting_buffer(%p) showing_buffer(%p)",
- private_layer, private_layer->waiting_buffer,
+ TDM_INFO("layer(%p) committed_buffer(%p) showing_buffer(%p)",
+ private_layer, *committed_buffer,
(private_layer->showing_buffer) ? private_layer->showing_buffer->buffer : NULL);
}
LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &clone_list, link) {
if (tdm_debug_module & TDM_DEBUG_COMMIT)
- TDM_INFO("layer(%p) committed. handle(%p)", lm->private_layer, (lm)?:NULL);
+ TDM_INFO("layer(%p) committed. handle(%p) commited_buffer(%p)",
+ lm->private_layer, lm, (lm->committed_buffer) ? lm->committed_buffer->buffer : NULL);
- _tdm_layer_committed(lm->private_layer);
+ LIST_DEL(&lm->link);
+ _tdm_layer_committed(lm->private_layer, &lm->committed_buffer);
_pthread_mutex_unlock(&private_display->lock);
if (lm->func)
lm->func(lm->private_layer, sequence, tv_sec, tv_usec, lm->user_data);
_pthread_mutex_lock(&private_display->lock);
- LIST_DEL(&lm->link);
+ if (lm->committed_buffer)
+ _tdm_layer_free_buffer(lm->private_layer, lm->committed_buffer);
free(lm);
}
wait_failed:
LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &pending_clone_list, link) {
LIST_DEL(&lm->link);
+ _tdm_layer_free_buffer(lm->private_layer, lm->committed_buffer);
free(lm);
}
return;
if (tdm_debug_module & TDM_DEBUG_COMMIT)
TDM_INFO("layer(%p) commit: output(%d) committed. handle(%p)",
- private_layer, private_output->pipe, (layer_commit_handler)?:NULL);
+ private_layer, private_output->pipe, layer_commit_handler);
_pthread_mutex_lock(&private_display->lock);
- _tdm_layer_committed(private_layer);
+ _tdm_layer_committed(private_layer, &layer_commit_handler->committed_buffer);
if (layer_commit_handler->func) {
_pthread_mutex_unlock(&private_display->lock);
layer_commit_handler->func = func;
layer_commit_handler->user_data = user_data;
+ layer_commit_handler->committed_buffer = private_layer->waiting_buffer;
+ private_layer->waiting_buffer = NULL;
+
+ if (tdm_debug_module & TDM_DEBUG_BUFFER)
+ TDM_INFO("layer(%p) waiting_buffer(%p) committed_buffer(%p)",
+ private_layer, private_layer->waiting_buffer,
+ (layer_commit_handler->committed_buffer) ? layer_commit_handler->committed_buffer->buffer : NULL);
+
if (!private_display->commit_per_vblank) {
TDM_GOTO_IF_FAIL(private_display->commit_type == TDM_COMMIT_TYPE_OUTPUT, commit_failed);
if (_tdm_layer_commit_possible(private_layer)) {
/* add to layer_commit_handler_list */
LIST_ADDTAIL(&layer_commit_handler->link, &private_output->layer_commit_handler_list);
-
ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed);
commit_failed:
if (layer_commit_handler) {
+ private_layer->waiting_buffer = layer_commit_handler->committed_buffer;
LIST_DEL(&layer_commit_handler->link);
free(layer_commit_handler);
}
return;
}
- layer_buffer = calloc(1, sizeof * layer_buffer);
+ layer_buffer = calloc(1, sizeof(tdm_private_layer_buffer));
if (!layer_buffer) {
_pthread_mutex_unlock(&private_display->lock);
TDM_ERR("alloc failed");
return;
}
+ LIST_INITHEAD(&layer_buffer->link);
if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(private_layer->buffer_queue, &surface) ||
surface == NULL) {
if (ret == TDM_ERROR_NONE) {
if (private_layer->waiting_buffer) {
TDM_DBG("layer(%p) drop waiting_buffer(%p)", private_layer, private_layer->waiting_buffer->buffer);
- _pthread_mutex_unlock(&private_display->lock);
- tdm_buffer_unref_backend(private_layer->waiting_buffer->buffer);
- tbm_surface_queue_release(private_layer->buffer_queue,
- private_layer->waiting_buffer->buffer);
- _pthread_mutex_lock(&private_display->lock);
- free(private_layer->waiting_buffer);
+ _tdm_layer_free_buffer(private_layer, private_layer->waiting_buffer);
}
private_layer->waiting_buffer = layer_buffer;
TDM_NEVER_GET_HERE();
}
} else
- free(layer_buffer);
+ _tdm_layer_free_buffer(private_layer, layer_buffer);
_pthread_mutex_unlock(&private_display->lock);
}
_pthread_mutex_lock(&private_display->lock);
- if (private_layer->waiting_buffer) {
- _pthread_mutex_unlock(&private_display->lock);
- tdm_buffer_unref_backend(private_layer->waiting_buffer->buffer);
- tbm_surface_queue_release(private_layer->buffer_queue,
- private_layer->waiting_buffer->buffer);
- _pthread_mutex_lock(&private_display->lock);
- free(private_layer->waiting_buffer);
- private_layer->waiting_buffer = NULL;
- }
-
private_layer->buffer_queue = NULL;
+ _tdm_layer_free_all_buffers(private_layer);
+
_pthread_mutex_unlock(&private_display->lock);
}
}
if (private_layer->waiting_buffer) {
- _pthread_mutex_unlock(&private_display->lock);
- tdm_buffer_unref_backend(private_layer->waiting_buffer->buffer);
- tbm_surface_queue_release(private_layer->buffer_queue,
- private_layer->waiting_buffer->buffer);
- free(private_layer->waiting_buffer);
+ _tdm_layer_free_buffer(private_layer, private_layer->waiting_buffer);
private_layer->waiting_buffer = NULL;
- _pthread_mutex_lock(&private_display->lock);
if (tdm_debug_module & TDM_DEBUG_BUFFER)
TDM_INFO("layer(%p) waiting_buffer(%p)",
private_layer->buffer_queue = buffer_queue;
tbm_surface_queue_add_acquirable_cb(private_layer->buffer_queue,
_tbm_layer_queue_acquirable_cb,
- layer);
+ private_layer);
tbm_surface_queue_add_destroy_cb(private_layer->buffer_queue,
_tbm_layer_queue_destroy_cb,
- layer);
+ private_layer);
_pthread_mutex_unlock(&private_display->lock);
return ret;