summaryrefslogtreecommitdiffstats
path: root/libs/ui/Fence.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ui/Fence.cpp')
-rw-r--r--libs/ui/Fence.cpp63
1 files changed, 54 insertions, 9 deletions
diff --git a/libs/ui/Fence.cpp b/libs/ui/Fence.cpp
index d214b97..464ee86 100644
--- a/libs/ui/Fence.cpp
+++ b/libs/ui/Fence.cpp
@@ -18,6 +18,9 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
//#define LOG_NDEBUG 0
+ // This is needed for stdint.h to define INT64_MAX in C++
+ #define __STDC_LIMIT_MACROS
+
#include <sync/sync.h>
#include <ui/Fence.h>
#include <unistd.h>
@@ -26,7 +29,7 @@
namespace android {
-const sp<Fence> Fence::NO_FENCE = sp<Fence>();
+const sp<Fence> Fence::NO_FENCE = sp<Fence>(new Fence);
Fence::Fence() :
mFenceFd(-1) {
@@ -51,11 +54,12 @@ status_t Fence::wait(unsigned int timeout) {
return err < 0 ? -errno : status_t(NO_ERROR);
}
-status_t Fence::waitForever(unsigned int warningTimeout, const char* logname) {
+status_t Fence::waitForever(const char* logname) {
ATRACE_CALL();
if (mFenceFd == -1) {
return NO_ERROR;
}
+ unsigned int warningTimeout = 3000;
int err = sync_wait(mFenceFd, warningTimeout);
if (err < 0 && errno == ETIME) {
ALOGE("%s: fence %d didn't signal in %u ms", logname, mFenceFd,
@@ -68,7 +72,19 @@ status_t Fence::waitForever(unsigned int warningTimeout, const char* logname) {
sp<Fence> Fence::merge(const String8& name, const sp<Fence>& f1,
const sp<Fence>& f2) {
ATRACE_CALL();
- int result = sync_merge(name.string(), f1->mFenceFd, f2->mFenceFd);
+ int result;
+ // Merge the two fences. In the case where one of the fences is not a
+ // valid fence (e.g. NO_FENCE) we merge the one valid fence with itself so
+ // that a new fence with the given name is created.
+ if (f1->isValid() && f2->isValid()) {
+ result = sync_merge(name.string(), f1->mFenceFd, f2->mFenceFd);
+ } else if (f1->isValid()) {
+ result = sync_merge(name.string(), f1->mFenceFd, f1->mFenceFd);
+ } else if (f2->isValid()) {
+ result = sync_merge(name.string(), f2->mFenceFd, f2->mFenceFd);
+ } else {
+ return NO_FENCE;
+ }
if (result == -1) {
status_t err = -errno;
ALOGE("merge: sync_merge(\"%s\", %d, %d) returned an error: %s (%d)",
@@ -80,10 +96,34 @@ sp<Fence> Fence::merge(const String8& name, const sp<Fence>& f1,
}
int Fence::dup() const {
+ return ::dup(mFenceFd);
+}
+
+nsecs_t Fence::getSignalTime() const {
if (mFenceFd == -1) {
return -1;
}
- return ::dup(mFenceFd);
+
+ struct sync_fence_info_data* finfo = sync_fence_info(mFenceFd);
+ if (finfo == NULL) {
+ ALOGE("sync_fence_info returned NULL for fd %d", mFenceFd);
+ return -1;
+ }
+ if (finfo->status != 1) {
+ sync_fence_info_free(finfo);
+ return INT64_MAX;
+ }
+
+ struct sync_pt_info* pinfo = NULL;
+ uint64_t timestamp = 0;
+ while ((pinfo = sync_pt_info(finfo, pinfo)) != NULL) {
+ if (pinfo->timestamp_ns > timestamp) {
+ timestamp = pinfo->timestamp_ns;
+ }
+ }
+ sync_fence_info_free(finfo);
+
+ return nsecs_t(timestamp);
}
size_t Fence::getFlattenedSize() const {
@@ -91,22 +131,24 @@ size_t Fence::getFlattenedSize() const {
}
size_t Fence::getFdCount() const {
- return 1;
+ return isValid() ? 1 : 0;
}
status_t Fence::flatten(void* buffer, size_t size, int fds[],
size_t count) const {
- if (size != 0 || count != 1) {
+ if (size != getFlattenedSize() || count != getFdCount()) {
return BAD_VALUE;
}
- fds[0] = mFenceFd;
+ if (isValid()) {
+ fds[0] = mFenceFd;
+ }
return NO_ERROR;
}
status_t Fence::unflatten(void const* buffer, size_t size, int fds[],
size_t count) {
- if (size != 0 || count != 1) {
+ if (size != 0 || (count != 0 && count != 1)) {
return BAD_VALUE;
}
if (mFenceFd != -1) {
@@ -114,7 +156,10 @@ status_t Fence::unflatten(void const* buffer, size_t size, int fds[],
return INVALID_OPERATION;
}
- mFenceFd = fds[0];
+ if (count == 1) {
+ mFenceFd = fds[0];
+ }
+
return NO_ERROR;
}