sdm: Enhance fence utility class
- Add scope reference for client to access native fd associated
with fence in limited scope.
- Assert if buffer sync handler is not set by the client.
- Add sync status enumeration.
CRs-Fixed: 2579548
Change-Id: Id91826cd9e2be5bcffd82fcc4a66f551fcdda70b
diff --git a/sdm/include/utils/fence.h b/sdm/include/utils/fence.h
index 94bb01b..acc381f 100644
--- a/sdm/include/utils/fence.h
+++ b/sdm/include/utils/fence.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2019, The Linux Foundation. All rights reserved.
+* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -35,6 +35,7 @@
#include <utility>
#include <memory>
#include <string>
+#include <vector>
namespace sdm {
@@ -43,8 +44,27 @@
class Fence {
public:
+ enum class Status : int32_t {
+ kSignaled = 0,
+ kPending
+ };
+
+ // This class methods allow client to get access to the native file descriptor of fence object
+ // during the scope of this class object. Underlying file descriptor is duped and returned to
+ // the client. Duped file descriptors are closed as soon as scope ends. Client can get access
+ // to multiple fences using the same scoped reference.
+ class ScopedRef {
+ public:
+ ~ScopedRef();
+ int Get(const shared_ptr<Fence> &fence);
+
+ private:
+ std::vector<int> dup_fds_ = {};
+ };
+
~Fence();
+ // Must be set once before using any other method of this class.
static void Set(BufferSyncHandler *buffer_sync_handler);
// Ownership of the file descriptor is transferred to this method.
@@ -56,8 +76,14 @@
static int Dup(const shared_ptr<Fence> &fence);
static shared_ptr<Fence> Merge(const shared_ptr<Fence> &fence1, const shared_ptr<Fence> &fence2);
+
+ // Wait on null fence will return success.
static DisplayError Wait(const shared_ptr<Fence> &fence);
static DisplayError Wait(const shared_ptr<Fence> &fence, int timeout);
+
+ // Status check on null fence will return signaled.
+ static Status GetStatus(const shared_ptr<Fence> &fence);
+
static string GetStr(const shared_ptr<Fence> &fence);
private:
diff --git a/sdm/libs/utils/fence.cpp b/sdm/libs/utils/fence.cpp
index 3cf26e4..bb0d541 100644
--- a/sdm/libs/utils/fence.cpp
+++ b/sdm/libs/utils/fence.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2019, The Linux Foundation. All rights reserved.
+* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -28,12 +28,15 @@
*/
#include <utils/fence.h>
+#include <assert.h>
#include <string>
#define __CLASS__ "Fence"
namespace sdm {
+#define ASSERT_IF_NO_BUFFER_SYNC(x) if (!x) { assert(false); }
+
BufferSyncHandler* Fence::buffer_sync_handler_ = nullptr;
Fence::Fence(int fd) : fd_(fd) {
@@ -62,18 +65,17 @@
}
int Fence::Dup(const shared_ptr<Fence> &fence) {
- if (!fence) {
- return -1;
- }
+ return (fence ? dup(fence->fd_) : -1);
+}
- return dup(fence->fd_);
+int Fence::Get(const shared_ptr<Fence> &fence) {
+ return (fence ? fence->fd_ : -1);
}
shared_ptr<Fence> Fence::Merge(const shared_ptr<Fence> &fence1, const shared_ptr<Fence> &fence2) {
- if (!buffer_sync_handler_) {
- return nullptr;
- }
+ ASSERT_IF_NO_BUFFER_SYNC(buffer_sync_handler_);
+ // Sync merge will return a new unique fd if source fds are same.
int fd1 = fence1 ? fence1->fd_ : -1;
int fd2 = fence2 ? fence2->fd_ : -1;
int merged = -1;
@@ -84,27 +86,46 @@
}
DisplayError Fence::Wait(const shared_ptr<Fence> &fence) {
- if (!buffer_sync_handler_) {
- return kErrorUndefined;
- }
+ ASSERT_IF_NO_BUFFER_SYNC(buffer_sync_handler_);
- return buffer_sync_handler_->SyncWait(Fence::Get(fence));
+ return buffer_sync_handler_->SyncWait(Fence::Get(fence), 1000);
}
DisplayError Fence::Wait(const shared_ptr<Fence> &fence, int timeout) {
- if (!buffer_sync_handler_) {
- return kErrorUndefined;
- }
+ ASSERT_IF_NO_BUFFER_SYNC(buffer_sync_handler_);
return buffer_sync_handler_->SyncWait(Fence::Get(fence), timeout);
}
+Fence::Status Fence::GetStatus(const shared_ptr<Fence> &fence) {
+ ASSERT_IF_NO_BUFFER_SYNC(buffer_sync_handler_);
+
+ if (!fence) {
+ return Fence::Status::kSignaled;
+ }
+
+ // Treat only timeout error as pending, assume other errors as signaled.
+ return (buffer_sync_handler_->SyncWait(Fence::Get(fence), 0) == kErrorTimeOut ?
+ Fence::Status::kPending : Fence::Status::kSignaled);
+}
+
string Fence::GetStr(const shared_ptr<Fence> &fence) {
return std::to_string(Fence::Get(fence));
}
-int Fence::Get(const shared_ptr<Fence> &fence) {
- return (fence ? fence->fd_ : -1);
+Fence::ScopedRef::~ScopedRef() {
+ for (int dup_fd : dup_fds_) {
+ close(dup_fd);
+ }
+}
+
+int Fence::ScopedRef::Get(const shared_ptr<Fence> &fence) {
+ int dup_fd = Fence::Dup(fence);
+ if (dup_fd >= 0) {
+ dup_fds_.push_back(dup_fd);
+ }
+
+ return dup_fd;
}
} // namespace sdm