aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.mk1
-rw-r--r--hwcomposer.cpp31
2 files changed, 27 insertions, 5 deletions
diff --git a/Android.mk b/Android.mk
index 6236c57..2a725f3 100644
--- a/Android.mk
+++ b/Android.mk
@@ -33,6 +33,7 @@ LOCAL_C_INCLUDES := \
external/libdrm/include/drm \
external/stlport/stlport \
system/core/include/utils \
+ system/core/libsync \
system/core/libsync/include \
LOCAL_CFLAGS :=
diff --git a/hwcomposer.cpp b/hwcomposer.cpp
index 0ae9381..ea60c36 100644
--- a/hwcomposer.cpp
+++ b/hwcomposer.cpp
@@ -32,6 +32,7 @@
#include <hardware/hwcomposer.h>
#include <sync/sync.h>
+#include <sw_sync.h>
#include "drm_hwcomposer.h"
@@ -70,6 +71,9 @@ struct hwc_drm_display {
std::queue<struct hwc_drm_bo> buf_queue;
struct hwc_drm_bo front;
+
+ int timeline_fd;
+ unsigned timeline_next;
};
struct hwc_context_t {
@@ -348,6 +352,10 @@ static void *hwc_set_worker(void *arg)
ret = hwc_wait_and_set(hd, &buf);
if (ret)
ALOGE("Failed to wait and set %d", ret);
+
+ ret = sw_sync_timeline_inc(hd->timeline_fd, 1);
+ if (ret)
+ ALOGE("Failed to increment sync timeline %d", ret);
} while (true);
out:
@@ -405,13 +413,23 @@ static int hwc_set_display(hwc_context_t *ctx, int display,
return ret;
}
buf.acquire_fence_fd = layer->acquireFenceFd;
- layer->releaseFenceFd = -1;
ret = pthread_mutex_lock(&hd->set_worker.lock);
if (ret) {
ALOGE("Failed to lock set lock in set() %d", ret);
return ret;
}
+
+ /*
+ * TODO: Retire and release can use the same sync point here b/c hwc is
+ * restricted to one layer. Once that is no longer true, this will need
+ * to change
+ */
+ hd->timeline_next++;
+ display_contents->retireFenceFd = sw_sync_fence_create(hd->timeline_fd,
+ "drm_hwc_retire", hd->timeline_next);
+ layer->releaseFenceFd = sw_sync_fence_create(hd->timeline_fd,
+ "drm_hwc_release", hd->timeline_next);
hd->buf_queue.push(buf);
ret = pthread_cond_signal(&hd->set_worker.cond);
@@ -441,11 +459,7 @@ static int hwc_set(hwc_composer_device_1_t *dev, size_t num_displays,
struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common;
int ret = 0, i;
- /* TODO: Handle acquire & release fences */
-
for (i = 0; i < (int)num_displays && i < MAX_NUM_DISPLAYS; i++) {
- display_contents[i]->retireFenceFd = -1; /* TODO: sync */
-
ret = hwc_set_display(ctx, i, display_contents[i]);
}
@@ -964,6 +978,13 @@ static int hwc_initialize_display(struct hwc_context_t *ctx, int display,
hd->active_config = -1;
hd->connector_id = connector_id;
+ ret = sw_sync_timeline_create();
+ if (ret < 0) {
+ ALOGE("Failed to create sw sync timeline %d", ret);
+ return ret;
+ }
+ hd->timeline_fd = ret;
+
ret = hwc_initialize_worker(hd, &hd->set_worker, hwc_set_worker);
if (ret) {
ALOGE("Failed to create set worker %d\n", ret);