diff options
-rw-r--r-- | .ci/Makefile | 1 | ||||
-rw-r--r-- | Android.bp | 2 | ||||
-rw-r--r-- | compositor/LayerData.h | 4 | ||||
-rw-r--r-- | drm/DrmAtomicStateManager.cpp | 28 | ||||
-rw-r--r-- | drm/DrmAtomicStateManager.h | 4 | ||||
-rw-r--r-- | drm/DrmConnector.cpp | 6 | ||||
-rw-r--r-- | drm/DrmCrtc.cpp | 2 | ||||
-rw-r--r-- | drm/DrmDevice.cpp | 34 | ||||
-rw-r--r-- | drm/DrmDevice.h | 8 | ||||
-rw-r--r-- | drm/DrmEncoder.cpp | 2 | ||||
-rw-r--r-- | drm/DrmFbImporter.cpp | 13 | ||||
-rw-r--r-- | drm/DrmPlane.cpp | 4 | ||||
-rw-r--r-- | drm/VSyncWorker.cpp | 4 | ||||
-rw-r--r-- | drm/VSyncWorker.h | 2 | ||||
-rw-r--r-- | hwc2_device/HwcDisplay.cpp | 6 | ||||
-rw-r--r-- | hwc2_device/HwcDisplay.h | 2 | ||||
-rw-r--r-- | hwc2_device/HwcLayer.cpp | 2 | ||||
-rw-r--r-- | hwc2_device/HwcLayer.h | 3 | ||||
-rw-r--r-- | meson.build | 1 | ||||
-rw-r--r-- | utils/UEvent.h | 8 | ||||
-rw-r--r-- | utils/UniqueFd.h | 115 | ||||
-rw-r--r-- | utils/fd.cpp | 52 | ||||
-rw-r--r-- | utils/fd.h | 36 |
23 files changed, 157 insertions, 182 deletions
diff --git a/.ci/Makefile b/.ci/Makefile index de5196b..9c82fca 100644 --- a/.ci/Makefile +++ b/.ci/Makefile @@ -27,7 +27,6 @@ TIDY_FILES_OVERRIDE := \ hwc2_device/DrmHwcTwo.h:COARSE \ hwc2_device/HwcDisplay.cpp:COARSE \ hwc2_device/HwcDisplay.h:COARSE \ - utils/UniqueFd.h:FINE \ utils/log.h:FINE \ utils/properties.h:FINE \ @@ -83,6 +83,8 @@ filegroup { "hwc2_device/HwcDisplayConfigs.cpp", "hwc2_device/HwcLayer.cpp", "hwc2_device/hwc2_device.cpp", + + "utils/fd.cpp", ], } diff --git a/compositor/LayerData.h b/compositor/LayerData.h index 92d4da0..a7e14f9 100644 --- a/compositor/LayerData.h +++ b/compositor/LayerData.h @@ -27,7 +27,7 @@ #include "bufferinfo/BufferInfo.h" #include "drm/DrmFbImporter.h" -#include "utils/UniqueFd.h" +#include "utils/fd.h" namespace android { @@ -75,7 +75,7 @@ struct LayerData { std::optional<BufferInfo> bi; std::shared_ptr<DrmFbIdHandle> fb; PresentInfo pi; - UniqueFd acquire_fence; + SharedFd acquire_fence; }; } // namespace android diff --git a/drm/DrmAtomicStateManager.cpp b/drm/DrmAtomicStateManager.cpp index b5e4629..58a5523 100644 --- a/drm/DrmAtomicStateManager.cpp +++ b/drm/DrmAtomicStateManager.cpp @@ -141,7 +141,7 @@ auto DrmAtomicStateManager::CommitFrame(AtomicCommitArgs &args) -> int { uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET; if (args.test_only) { - return drmModeAtomicCommit(drm->GetFd(), pset.get(), + return drmModeAtomicCommit(*drm->GetFd(), pset.get(), flags | DRM_MODE_ATOMIC_TEST_ONLY, drm); } @@ -150,10 +150,10 @@ auto DrmAtomicStateManager::CommitFrame(AtomicCommitArgs &args) -> int { ATRACE_NAME("WaitPriorFramePresented"); constexpr int kTimeoutMs = 500; - const int err = sync_wait(last_present_fence_.Get(), kTimeoutMs); + const int err = sync_wait(*last_present_fence_, kTimeoutMs); if (err != 0) { - ALOGE("sync_wait(fd=%i) returned: %i (errno: %i)", - last_present_fence_.Get(), err, errno); + ALOGE("sync_wait(fd=%i) returned: %i (errno: %i)", *last_present_fence_, + err, errno); } CleanupPriorFrameResources(); @@ -163,17 +163,19 @@ auto DrmAtomicStateManager::CommitFrame(AtomicCommitArgs &args) -> int { flags |= DRM_MODE_ATOMIC_NONBLOCK; } - auto err = drmModeAtomicCommit(drm->GetFd(), pset.get(), flags, drm); + auto err = drmModeAtomicCommit(*drm->GetFd(), pset.get(), flags, drm); if (err != 0) { ALOGE("Failed to commit pset ret=%d\n", err); return err; } + args.out_fence = MakeSharedFd(out_fence); + if (nonblock) { { const std::unique_lock lock(mutex_); - last_present_fence_ = UniqueFd::Dup(out_fence); + last_present_fence_ = args.out_fence; staged_frame_state_ = std::move(new_frame_state); frames_staged_++; } @@ -182,8 +184,6 @@ auto DrmAtomicStateManager::CommitFrame(AtomicCommitArgs &args) -> int { active_frame_state_ = std::move(new_frame_state); } - args.out_fence = UniqueFd(out_fence); - return 0; } @@ -193,7 +193,7 @@ void DrmAtomicStateManager::ThreadFn( auto &main_mutex = pipe_->device->GetResMan().GetMainLock(); for (;;) { - UniqueFd present_fence; + SharedFd present_fence; { std::unique_lock lk(mutex_); @@ -207,7 +207,7 @@ void DrmAtomicStateManager::ThreadFn( tracking_at_the_moment = frames_staged_; - present_fence = UniqueFd::Dup(last_present_fence_.Get()); + present_fence = last_present_fence_; if (!present_fence) continue; } @@ -216,10 +216,10 @@ void DrmAtomicStateManager::ThreadFn( // NOLINTNEXTLINE(misc-const-correctness) ATRACE_NAME("AsyncWaitForBuffersSwap"); constexpr int kTimeoutMs = 500; - auto err = sync_wait(present_fence.Get(), kTimeoutMs); + auto err = sync_wait(*present_fence, kTimeoutMs); if (err != 0) { - ALOGE("sync_wait(fd=%i) returned: %i (errno: %i)", present_fence.Get(), - err, errno); + ALOGE("sync_wait(fd=%i) returned: %i (errno: %i)", *present_fence, err, + errno); } } @@ -272,7 +272,7 @@ auto DrmAtomicStateManager::ExecuteAtomicCommit(AtomicCommitArgs &args) -> int { } // namespace android auto DrmAtomicStateManager::ActivateDisplayUsingDPMS() -> int { - return drmModeConnectorSetProperty(pipe_->device->GetFd(), + return drmModeConnectorSetProperty(*pipe_->device->GetFd(), pipe_->connector->Get()->GetId(), pipe_->connector->Get() ->GetDpmsProperty() diff --git a/drm/DrmAtomicStateManager.h b/drm/DrmAtomicStateManager.h index 5f19bcc..e456a91 100644 --- a/drm/DrmAtomicStateManager.h +++ b/drm/DrmAtomicStateManager.h @@ -37,7 +37,7 @@ struct AtomicCommitArgs { std::shared_ptr<DrmKmsPlan> composition; /* out */ - UniqueFd out_fence; + SharedFd out_fence; /* helpers */ auto HasInputs() -> bool { @@ -95,7 +95,7 @@ class DrmAtomicStateManager { void CleanupPriorFrameResources(); KmsState staged_frame_state_; - UniqueFd last_present_fence_; + SharedFd last_present_fence_; int frames_staged_{}; int frames_tracked_{}; diff --git a/drm/DrmConnector.cpp b/drm/DrmConnector.cpp index 07c5d74..f625563 100644 --- a/drm/DrmConnector.cpp +++ b/drm/DrmConnector.cpp @@ -63,7 +63,7 @@ static bool GetConnectorProperty(const DrmDevice &dev, auto DrmConnector::CreateInstance(DrmDevice &dev, uint32_t connector_id, uint32_t index) -> std::unique_ptr<DrmConnector> { - auto conn = MakeDrmModeConnectorUnique(dev.GetFd(), connector_id); + auto conn = MakeDrmModeConnectorUnique(*dev.GetFd(), connector_id); if (!conn) { ALOGE("Failed to get connector %d", connector_id); return {}; @@ -109,7 +109,7 @@ auto DrmConnector::GetEdidBlob() -> DrmModePropertyBlobUnique { return {}; } - return MakeDrmModePropertyBlobUnique(drm_->GetFd(), *blob_id); + return MakeDrmModePropertyBlobUnique(*drm_->GetFd(), *blob_id); } bool DrmConnector::IsInternal() const { @@ -158,7 +158,7 @@ std::string DrmConnector::GetName() const { } int DrmConnector::UpdateModes() { - auto conn = MakeDrmModeConnectorUnique(drm_->GetFd(), GetId()); + auto conn = MakeDrmModeConnectorUnique(*drm_->GetFd(), GetId()); if (!conn) { ALOGE("Failed to get connector %d", GetId()); return -ENODEV; diff --git a/drm/DrmCrtc.cpp b/drm/DrmCrtc.cpp index b54f14b..3b749b1 100644 --- a/drm/DrmCrtc.cpp +++ b/drm/DrmCrtc.cpp @@ -35,7 +35,7 @@ static int GetCrtcProperty(const DrmDevice &dev, const DrmCrtc &crtc, auto DrmCrtc::CreateInstance(DrmDevice &dev, uint32_t crtc_id, uint32_t index) -> std::unique_ptr<DrmCrtc> { - auto crtc = MakeDrmModeCrtcUnique(dev.GetFd(), crtc_id); + auto crtc = MakeDrmModeCrtcUnique(*dev.GetFd(), crtc_id); if (!crtc) { ALOGE("Failed to get CRTC %d", crtc_id); return {}; diff --git a/drm/DrmDevice.cpp b/drm/DrmDevice.cpp index 33adf2a..1d6b62e 100644 --- a/drm/DrmDevice.cpp +++ b/drm/DrmDevice.cpp @@ -55,46 +55,46 @@ DrmDevice::DrmDevice(ResourceManager *res_man) : res_man_(res_man) { auto DrmDevice::Init(const char *path) -> int { /* TODO: Use drmOpenControl here instead */ - fd_ = UniqueFd(open(path, O_RDWR | O_CLOEXEC)); + fd_ = MakeSharedFd(open(path, O_RDWR | O_CLOEXEC)); if (!fd_) { // NOLINTNEXTLINE(concurrency-mt-unsafe): Fixme ALOGE("Failed to open dri %s: %s", path, strerror(errno)); return -ENODEV; } - int ret = drmSetClientCap(GetFd(), DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); + int ret = drmSetClientCap(*GetFd(), DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); if (ret != 0) { ALOGE("Failed to set universal plane cap %d", ret); return ret; } - ret = drmSetClientCap(GetFd(), DRM_CLIENT_CAP_ATOMIC, 1); + ret = drmSetClientCap(*GetFd(), DRM_CLIENT_CAP_ATOMIC, 1); if (ret != 0) { ALOGE("Failed to set atomic cap %d", ret); return ret; } #ifdef DRM_CLIENT_CAP_WRITEBACK_CONNECTORS - ret = drmSetClientCap(GetFd(), DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1); + ret = drmSetClientCap(*GetFd(), DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1); if (ret != 0) { ALOGI("Failed to set writeback cap %d", ret); } #endif uint64_t cap_value = 0; - if (drmGetCap(GetFd(), DRM_CAP_ADDFB2_MODIFIERS, &cap_value) != 0) { + if (drmGetCap(*GetFd(), DRM_CAP_ADDFB2_MODIFIERS, &cap_value) != 0) { ALOGW("drmGetCap failed. Fallback to no modifier support."); cap_value = 0; } HasAddFb2ModifiersSupport_ = cap_value != 0; - drmSetMaster(GetFd()); - if (drmIsMaster(GetFd()) == 0) { + drmSetMaster(*GetFd()); + if (drmIsMaster(*GetFd()) == 0) { ALOGE("DRM/KMS master access required"); return -EACCES; } - auto res = MakeDrmModeResUnique(GetFd()); + auto res = MakeDrmModeResUnique(*GetFd()); if (!res) { ALOGE("Failed to get DrmDevice resources"); return -ENODEV; @@ -136,7 +136,7 @@ auto DrmDevice::Init(const char *path) -> int { } } - auto plane_res = MakeDrmModePlaneResUnique(GetFd()); + auto plane_res = MakeDrmModePlaneResUnique(*GetFd()); if (!plane_res) { ALOGE("Failed to get plane resources"); return -ENOENT; @@ -161,7 +161,7 @@ auto DrmDevice::RegisterUserPropertyBlob(void *data, size_t length) const // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast) create_blob.data = (__u64)data; - auto ret = drmIoctl(GetFd(), DRM_IOCTL_MODE_CREATEPROPBLOB, &create_blob); + auto ret = drmIoctl(*GetFd(), DRM_IOCTL_MODE_CREATEPROPBLOB, &create_blob); if (ret != 0) { ALOGE("Failed to create mode property blob %d", ret); return {}; @@ -171,7 +171,7 @@ auto DrmDevice::RegisterUserPropertyBlob(void *data, size_t length) const new uint32_t(create_blob.blob_id), [this](const uint32_t *it) { struct drm_mode_destroy_blob destroy_blob {}; destroy_blob.blob_id = (__u32)*it; - auto err = drmIoctl(GetFd(), DRM_IOCTL_MODE_DESTROYPROPBLOB, + auto err = drmIoctl(*GetFd(), DRM_IOCTL_MODE_DESTROYPROPBLOB, &destroy_blob); if (err != 0) { ALOGE("Failed to destroy mode property blob %" PRIu32 "/%d", *it, @@ -186,7 +186,7 @@ int DrmDevice::GetProperty(uint32_t obj_id, uint32_t obj_type, const char *prop_name, DrmProperty *property) const { drmModeObjectPropertiesPtr props = nullptr; - props = drmModeObjectGetProperties(GetFd(), obj_id, obj_type); + props = drmModeObjectGetProperties(*GetFd(), obj_id, obj_type); if (props == nullptr) { ALOGE("Failed to get properties for %d/%x", obj_id, obj_type); return -ENODEV; @@ -195,7 +195,7 @@ int DrmDevice::GetProperty(uint32_t obj_id, uint32_t obj_type, bool found = false; for (int i = 0; !found && (size_t)i < props->count_props; ++i) { // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - drmModePropertyPtr p = drmModeGetProperty(GetFd(), props->props[i]); + drmModePropertyPtr p = drmModeGetProperty(*GetFd(), props->props[i]); if (strcmp(p->name, prop_name) == 0) { // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) property->Init(obj_id, p, props->prop_values[i]); @@ -209,9 +209,9 @@ int DrmDevice::GetProperty(uint32_t obj_id, uint32_t obj_type, } std::string DrmDevice::GetName() const { - auto *ver = drmGetVersion(GetFd()); + auto *ver = drmGetVersion(*GetFd()); if (ver == nullptr) { - ALOGW("Failed to get drm version for fd=%d", GetFd()); + ALOGW("Failed to get drm version for fd=%d", *GetFd()); return "generic"; } @@ -221,12 +221,12 @@ std::string DrmDevice::GetName() const { } auto DrmDevice::IsKMSDev(const char *path) -> bool { - auto fd = UniqueFd(open(path, O_RDWR | O_CLOEXEC)); + auto fd = MakeUniqueFd(open(path, O_RDWR | O_CLOEXEC)); if (!fd) { return false; } - auto res = MakeDrmModeResUnique(fd.Get()); + auto res = MakeDrmModeResUnique(*fd); if (!res) { return false; } diff --git a/drm/DrmDevice.h b/drm/DrmDevice.h index bb515e0..39d0c88 100644 --- a/drm/DrmDevice.h +++ b/drm/DrmDevice.h @@ -23,7 +23,7 @@ #include "DrmConnector.h" #include "DrmCrtc.h" #include "DrmEncoder.h" -#include "utils/UniqueFd.h" +#include "utils/fd.h" namespace android { @@ -38,8 +38,8 @@ class DrmDevice { static auto CreateInstance(std::string const &path, ResourceManager *res_man) -> std::unique_ptr<DrmDevice>; - auto GetFd() const { - return fd_.Get(); + auto &GetFd() const { + return fd_; } auto &GetResMan() { @@ -101,7 +101,7 @@ class DrmDevice { static auto IsKMSDev(const char *path) -> bool; - UniqueFd fd_; + SharedFd fd_; std::vector<std::unique_ptr<DrmConnector>> connectors_; std::vector<std::unique_ptr<DrmConnector>> writeback_connectors_; diff --git a/drm/DrmEncoder.cpp b/drm/DrmEncoder.cpp index eed5b5f..21ca693 100644 --- a/drm/DrmEncoder.cpp +++ b/drm/DrmEncoder.cpp @@ -29,7 +29,7 @@ namespace android { auto DrmEncoder::CreateInstance(DrmDevice &dev, uint32_t encoder_id, uint32_t index) -> std::unique_ptr<DrmEncoder> { - auto e = MakeDrmModeEncoderUnique(dev.GetFd(), encoder_id); + auto e = MakeDrmModeEncoderUnique(*dev.GetFd(), encoder_id); if (!e) { ALOGE("Failed to get encoder %d", encoder_id); return {}; diff --git a/drm/DrmFbImporter.cpp b/drm/DrmFbImporter.cpp index f0be32f..a91a52b 100644 --- a/drm/DrmFbImporter.cpp +++ b/drm/DrmFbImporter.cpp @@ -50,7 +50,7 @@ auto DrmFbIdHandle::CreateInstance(BufferInfo *bo, GemHandle first_gem_handle, for (size_t i = 1; i < local->gem_handles_.size(); i++) { if (bo->prime_fds[i] > 0) { if (bo->prime_fds[i] != bo->prime_fds[0]) { - err = drmPrimeFDToHandle(drm.GetFd(), bo->prime_fds[i], + err = drmPrimeFDToHandle(*drm.GetFd(), bo->prime_fds[i], &local->gem_handles_.at(i)); if (err != 0) { ALOGE("failed to import prime fd %d errno=%d", bo->prime_fds[i], @@ -74,11 +74,11 @@ auto DrmFbIdHandle::CreateInstance(BufferInfo *bo, GemHandle first_gem_handle, /* Create framebuffer object */ if (!has_modifiers) { - err = drmModeAddFB2(drm.GetFd(), bo->width, bo->height, bo->format, + err = drmModeAddFB2(*drm.GetFd(), bo->width, bo->height, bo->format, local->gem_handles_.data(), &bo->pitches[0], &bo->offsets[0], &local->fb_id_, 0); } else { - err = drmModeAddFB2WithModifiers(drm.GetFd(), bo->width, bo->height, + err = drmModeAddFB2WithModifiers(*drm.GetFd(), bo->width, bo->height, bo->format, local->gem_handles_.data(), &bo->pitches[0], &bo->offsets[0], &bo->modifiers[0], &local->fb_id_, @@ -97,7 +97,7 @@ DrmFbIdHandle::~DrmFbIdHandle() { ATRACE_NAME("Close FB and dmabufs"); /* Destroy framebuffer object */ - if (drmModeRmFB(drm_->GetFd(), fb_id_) != 0) { + if (drmModeRmFB(*drm_->GetFd(), fb_id_) != 0) { ALOGE("Failed to rm fb"); } @@ -118,7 +118,7 @@ DrmFbIdHandle::~DrmFbIdHandle() { continue; } gem_close.handle = gem_handles_[i]; - auto err = drmIoctl(drm_->GetFd(), DRM_IOCTL_GEM_CLOSE, &gem_close); + auto err = drmIoctl(*drm_->GetFd(), DRM_IOCTL_GEM_CLOSE, &gem_close); if (err != 0) { ALOGE("Failed to close gem handle %d, errno: %d", gem_handles_[i], errno); } @@ -129,7 +129,8 @@ auto DrmFbImporter::GetOrCreateFbId(BufferInfo *bo) -> std::shared_ptr<DrmFbIdHandle> { /* Lookup DrmFbIdHandle in cache first. First handle serves as a cache key. */ GemHandle first_handle = 0; - auto err = drmPrimeFDToHandle(drm_->GetFd(), bo->prime_fds[0], &first_handle); + auto err = drmPrimeFDToHandle(*drm_->GetFd(), bo->prime_fds[0], + &first_handle); if (err != 0) { ALOGE("Failed to import prime fd %d ret=%d", bo->prime_fds[0], err); diff --git a/drm/DrmPlane.cpp b/drm/DrmPlane.cpp index 4d03840..228e3dd 100644 --- a/drm/DrmPlane.cpp +++ b/drm/DrmPlane.cpp @@ -31,7 +31,7 @@ namespace android { auto DrmPlane::CreateInstance(DrmDevice &dev, uint32_t plane_id) -> std::unique_ptr<DrmPlane> { - auto p = MakeDrmModePlaneUnique(dev.GetFd(), plane_id); + auto p = MakeDrmModePlaneUnique(*dev.GetFd(), plane_id); if (!p) { ALOGE("Failed to get plane %d", plane_id); return {}; @@ -261,7 +261,7 @@ auto DrmPlane::AtomicSetState(drmModeAtomicReq &pset, LayerData &layer, } if (layer.acquire_fence && - !in_fence_fd_property_.AtomicSet(pset, layer.acquire_fence.Get())) { + !in_fence_fd_property_.AtomicSet(pset, *layer.acquire_fence)) { return -EINVAL; } diff --git a/drm/VSyncWorker.cpp b/drm/VSyncWorker.cpp index 77b9d98..8a251c7 100644 --- a/drm/VSyncWorker.cpp +++ b/drm/VSyncWorker.cpp @@ -40,7 +40,7 @@ auto VSyncWorker::CreateInstance(DrmDisplayPipeline *pipe, if (pipe != nullptr) { vsw->high_crtc_ = pipe->crtc->Get()->GetIndexInResArray() << DRM_VBLANK_HIGH_CRTC_SHIFT; - vsw->drm_fd_ = UniqueFd::Dup(pipe->device->GetFd()); + vsw->drm_fd_ = pipe->device->GetFd(); } std::thread(&VSyncWorker::ThreadFn, vsw.get(), vsw).detach(); @@ -143,7 +143,7 @@ void VSyncWorker::ThreadFn(const std::shared_ptr<VSyncWorker> &vsw) { DRM_VBLANK_HIGH_CRTC_MASK)); vblank.request.sequence = 1; - ret = drmWaitVBlank(drm_fd_.Get(), &vblank); + ret = drmWaitVBlank(*drm_fd_, &vblank); if (ret == -EINTR) continue; } diff --git a/drm/VSyncWorker.h b/drm/VSyncWorker.h index 2a0b084..031a561 100644 --- a/drm/VSyncWorker.h +++ b/drm/VSyncWorker.h @@ -52,7 +52,7 @@ class VSyncWorker { VSyncWorkerCallbacks callbacks_; - UniqueFd drm_fd_; + SharedFd drm_fd_; uint32_t high_crtc_ = 0; bool enabled_ = false; diff --git a/hwc2_device/HwcDisplay.cpp b/hwc2_device/HwcDisplay.cpp index 194889e..d957dc3 100644 --- a/hwc2_device/HwcDisplay.cpp +++ b/hwc2_device/HwcDisplay.cpp @@ -452,7 +452,7 @@ HWC2::Error HwcDisplay::GetReleaseFences(uint32_t *num_elements, } layers[num_layers - 1] = l.first; - fences[num_layers - 1] = UniqueFd::Dup(present_fence_.Get()).Release(); + fences[num_layers - 1] = DupFd(present_fence_); } *num_elements = num_layers; @@ -592,8 +592,8 @@ HWC2::Error HwcDisplay::PresentDisplay(int32_t *out_present_fence) { if (ret != HWC2::Error::None) return ret; - this->present_fence_ = UniqueFd::Dup(a_args.out_fence.Get()); - *out_present_fence = a_args.out_fence.Release(); + this->present_fence_ = a_args.out_fence; + *out_present_fence = DupFd(a_args.out_fence); ++frame_no_; return HWC2::Error::None; diff --git a/hwc2_device/HwcDisplay.h b/hwc2_device/HwcDisplay.h index 4ad57b7..6cac60f 100644 --- a/hwc2_device/HwcDisplay.h +++ b/hwc2_device/HwcDisplay.h @@ -200,7 +200,7 @@ class HwcDisplay { DrmHwcTwo *const hwc2_; - UniqueFd present_fence_; + SharedFd present_fence_; std::optional<DrmMode> staged_mode_; int64_t staged_mode_change_time_{}; diff --git a/hwc2_device/HwcLayer.cpp b/hwc2_device/HwcLayer.cpp index 589a0a7..d3936b3 100644 --- a/hwc2_device/HwcLayer.cpp +++ b/hwc2_device/HwcLayer.cpp @@ -53,7 +53,7 @@ HWC2::Error HwcLayer::SetLayerBlendMode(int32_t mode) { */ HWC2::Error HwcLayer::SetLayerBuffer(buffer_handle_t buffer, int32_t acquire_fence) { - acquire_fence_ = UniqueFd(acquire_fence); + acquire_fence_ = MakeUniqueFd(acquire_fence); buffer_handle_ = buffer; buffer_handle_updated_ = true; diff --git a/hwc2_device/HwcLayer.h b/hwc2_device/HwcLayer.h index 627d5ac..7f647a8 100644 --- a/hwc2_device/HwcLayer.h +++ b/hwc2_device/HwcLayer.h @@ -86,8 +86,7 @@ class HwcLayer { uint32_t z_order_ = 0; LayerData layer_data_; - /* Should be populated to layer_data_.acquire_fence only before presenting */ - UniqueFd acquire_fence_; + SharedFd acquire_fence_; /* The following buffer data can have 2 sources: * 1 - Mapper@4 metadata API diff --git a/meson.build b/meson.build index 266163e..4328a1e 100644 --- a/meson.build +++ b/meson.build @@ -14,6 +14,7 @@ src_common = files( 'backend/BackendManager.cpp', 'backend/Backend.cpp', 'backend/BackendClient.cpp', + 'utils/fd.cpp', ) deps = [ diff --git a/utils/UEvent.h b/utils/UEvent.h index 64992a1..5b9ecea 100644 --- a/utils/UEvent.h +++ b/utils/UEvent.h @@ -24,7 +24,7 @@ #include <optional> #include <string> -#include "UniqueFd.h" +#include "fd.h" #include "log.h" namespace android { @@ -32,7 +32,7 @@ namespace android { class UEvent { public: static auto CreateInstance() -> std::unique_ptr<UEvent> { - auto fd = UniqueFd( + auto fd = MakeUniqueFd( socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_KOBJECT_UEVENT)); if (!fd) { @@ -46,7 +46,7 @@ class UEvent { addr.nl_groups = UINT32_MAX; // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast) - const int ret = bind(fd.Get(), (struct sockaddr *)&addr, sizeof(addr)); + const int ret = bind(*fd, (struct sockaddr *)&addr, sizeof(addr)); if (ret != 0) { ALOGE("Failed to bind uevent socket: errno=%i", errno); return {}; @@ -59,7 +59,7 @@ class UEvent { constexpr int kUEventBufferSize = 1024; char buffer[kUEventBufferSize]; ssize_t ret = 0; - ret = read(fd_.Get(), &buffer, sizeof(buffer)); + ret = read(*fd_, &buffer, sizeof(buffer)); if (ret == 0) return {}; diff --git a/utils/UniqueFd.h b/utils/UniqueFd.h deleted file mode 100644 index f65bedc..0000000 --- a/utils/UniqueFd.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2015, 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <fcntl.h> -#include <unistd.h> - -#include <memory> -#include <utility> - -namespace android { - -/* - * Using UniqueFd: - * 1. Create UniqueFd object: - * auto fd_obj = UniqueFd(open("SomeFile", xxx)); - * - * 2. Check whether the fd_obj is empty: - * if (!fd_obj) { return -errno; } - * - * 3. Accessing the file descriptor: - * int ret = read(fd_obj.Get(), buf, buf_size); - * - * 4. Closing the file: - * FD will be closed once execution leaves fd_obj scope (on any return, - * exception, destruction of class/struct where object is member, etc.). - * User can also force closing the fd_obj by calling: - * fd_obj = UniqueFd(); - * // fd is closed and fd_obj is empty now. - * - * 5. File descriptor may be transferred to the code, which will close it after - * using. This can be done in 2 ways: - * a. Duplicate the fd, in this case both fds should be closed separately: - * int out_fd = dup(fd_obj.Get(); - * ... - * close(out_fd); - * b. Transfer ownership, use this method if you do not need the fd anymore. - * int out_fd = fd_obj.Release(); - * // fd_obj is empty now. - * ... - * close(out_fd); - * - * 6. Transferring fd into another UniqueFD object: - * UniqueFd fd_obj_2 = std::move(fd_obj); - * // fd_obj empty now - */ - -constexpr int kEmptyFd = -1; - -class UniqueFd { - public: - UniqueFd() = default; - explicit UniqueFd(int fd) : fd_(fd){}; - - auto Release [[nodiscard]] () -> int { - return std::exchange(fd_, kEmptyFd); - } - - auto Get [[nodiscard]] () const -> int { - return fd_; - } - - static auto Dup(int fd) { - // NOLINTNEXTLINE(android-cloexec-dup): fcntl has issue (see issue #63) - return UniqueFd(dup(fd)); - } - - explicit operator bool() const { - return fd_ != kEmptyFd; - } - - ~UniqueFd() { - Set(kEmptyFd); - } - - /* Allow move semantics */ - UniqueFd(UniqueFd &&rhs) noexcept { - Set(rhs.Release()); - } - - auto operator=(UniqueFd &&rhs) noexcept -> UniqueFd & { - Set(rhs.Release()); - return *this; - } - - /* Disable copy semantics */ - UniqueFd(const UniqueFd &) = delete; - auto operator=(const UniqueFd &) = delete; - - private: - void Set(int new_fd) { - if (fd_ != kEmptyFd) { - close(fd_); - } - fd_ = new_fd; - } - - int fd_ = kEmptyFd; -}; - -} // namespace android diff --git a/utils/fd.cpp b/utils/fd.cpp new file mode 100644 index 0000000..395d3b2 --- /dev/null +++ b/utils/fd.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "fd.h" + +namespace android { + +static void CloseFd(const int *fd) { + if (fd != nullptr) { + if (*fd >= 0) + close(*fd); + + // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) + delete fd; + } +} + +auto MakeUniqueFd(int fd) -> UniqueFd { + if (fd < 0) + return {nullptr, CloseFd}; + + return {new int(fd), CloseFd}; +} + +auto MakeSharedFd(int fd) -> SharedFd { + if (fd < 0) + return {}; + + return {new int(fd), CloseFd}; +} + +auto DupFd(SharedFd const &fd) -> int { + if (!fd) + return -1; + + return fcntl(*fd, F_DUPFD_CLOEXEC, 0); +} + +} // namespace android diff --git a/utils/fd.h b/utils/fd.h new file mode 100644 index 0000000..6bfd0fa --- /dev/null +++ b/utils/fd.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2015 - 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <fcntl.h> +#include <unistd.h> + +#include <memory> +#include <utility> + +namespace android { + +using UniqueFd = std::unique_ptr<int, void (*)(const int *)>; +using SharedFd = std::shared_ptr<int>; + +auto MakeUniqueFd(int fd) -> UniqueFd; + +auto MakeSharedFd(int fd) -> SharedFd; + +auto DupFd(SharedFd const &fd) -> int; + +} // namespace android |