Add shmem config buffer to libvrflinger
This allows VrCore to configure some tunable behaviors
of libvrflinger.
- Added dvrDisplayManagerDeleteNamedBuffer for testing config buffer
creation.
- Added tests for named buffers, including one for the config buffer.
- Added IsValid to broadcast_ring to avoid tracking redundant state
externally.
Bug: 38193993
Test: Run dvr_named_buffer-test
Change-Id: I52722dd314233b5bea1ca6377c14b5c856825746
diff --git a/libs/vr/libvrflinger/hardware_composer.cpp b/libs/vr/libvrflinger/hardware_composer.cpp
index 34474d9..88173ca 100644
--- a/libs/vr/libvrflinger/hardware_composer.cpp
+++ b/libs/vr/libvrflinger/hardware_composer.cpp
@@ -19,6 +19,7 @@
#include <chrono>
#include <functional>
#include <map>
+#include <tuple>
#include <dvr/dvr_display_types.h>
#include <dvr/performance_client_api.h>
@@ -37,17 +38,6 @@
namespace {
-// If the number of pending fences goes over this count at the point when we
-// are about to submit a new frame to HWC, we will drop the frame. This should
-// be a signal that the display driver has begun queuing frames. Note that with
-// smart displays (with RAM), the fence is signaled earlier than the next vsync,
-// at the point when the DMA to the display completes. Currently we use a smart
-// display and the EDS timing coincides with zero pending fences, so this is 0.
-constexpr int kAllowedPendingFenceCount = 0;
-
-// Offset before vsync to submit frames to hardware composer.
-constexpr int64_t kFramePostOffsetNs = 4000000; // 4ms
-
const char kBacklightBrightnessSysFile[] =
"/sys/class/leds/lcd-backlight/brightness";
@@ -397,8 +387,8 @@
}
const bool is_frame_pending = IsFramePendingInDriver();
- const bool is_fence_pending =
- retire_fence_fds_.size() > kAllowedPendingFenceCount;
+ const bool is_fence_pending = retire_fence_fds_.size() >
+ post_thread_config_.allowed_pending_fence_count;
if (is_fence_pending || is_frame_pending) {
ATRACE_INT("frame_skip_count", ++frame_skip_count_);
@@ -475,6 +465,62 @@
request_display_callback_(!display_idle);
}
+int HardwareComposer::OnNewGlobalBuffer(DvrGlobalBufferKey key,
+ IonBuffer& ion_buffer) {
+ if (key == kVrFlingerConfigBufferKey) {
+ return MapConfigBuffer(ion_buffer);
+ }
+
+ return 0;
+}
+
+void HardwareComposer::OnDeletedGlobalBuffer(DvrGlobalBufferKey key) {
+ if (key == kVrFlingerConfigBufferKey) {
+ ConfigBufferDeleted();
+ }
+}
+
+int HardwareComposer::MapConfigBuffer(IonBuffer& ion_buffer) {
+ std::lock_guard<std::mutex> lock(shared_config_mutex_);
+ shared_config_ring_ = DvrVrFlingerConfigRing();
+
+ if (ion_buffer.width() < DvrVrFlingerConfigRing::MemorySize()) {
+ ALOGE("HardwareComposer::MapConfigBuffer: invalid buffer size.");
+ return -EINVAL;
+ }
+
+ void* buffer_base = 0;
+ int result = ion_buffer.Lock(ion_buffer.usage(), 0, 0, ion_buffer.width(),
+ ion_buffer.height(), &buffer_base);
+ if (result != 0) {
+ ALOGE("HardwareComposer::MapConfigBuffer: Failed to map vrflinger config "
+ "buffer.");
+ return -EPERM;
+ }
+
+ shared_config_ring_ =
+ DvrVrFlingerConfigRing::Create(buffer_base, ion_buffer.width());
+ ion_buffer.Unlock();
+
+ return 0;
+}
+
+void HardwareComposer::ConfigBufferDeleted() {
+ std::lock_guard<std::mutex> lock(shared_config_mutex_);
+ shared_config_ring_ = DvrVrFlingerConfigRing();
+}
+
+void HardwareComposer::UpdateConfigBuffer() {
+ std::lock_guard<std::mutex> lock(shared_config_mutex_);
+ if (!shared_config_ring_.is_valid())
+ return;
+ // Copy from latest record in shared_config_ring_ to local copy.
+ DvrVrFlingerConfigBuffer record;
+ if (shared_config_ring_.GetNewest(&shared_config_ring_sequence_, &record)) {
+ post_thread_config_ = record;
+ }
+}
+
int HardwareComposer::PostThreadPollInterruptible(
const pdx::LocalHandle& event_fd, int requested_events) {
pollfd pfd[2] = {
@@ -744,6 +790,9 @@
while (1) {
ATRACE_NAME("HardwareComposer::PostThread");
+ // Check for updated config once per vsync.
+ UpdateConfigBuffer();
+
while (post_thread_quiescent_) {
std::unique_lock<std::mutex> lock(post_thread_mutex_);
ALOGI("HardwareComposer::PostThread: Entering quiescent state.");
@@ -823,9 +872,10 @@
const int64_t display_time_est_ns = vsync_timestamp + ns_per_frame;
const int64_t now_ns = GetSystemClockNs();
- const int64_t sleep_time_ns =
- display_time_est_ns - now_ns - kFramePostOffsetNs;
- const int64_t wakeup_time_ns = display_time_est_ns - kFramePostOffsetNs;
+ const int64_t sleep_time_ns = display_time_est_ns - now_ns -
+ post_thread_config_.frame_post_offset_ns;
+ const int64_t wakeup_time_ns =
+ display_time_est_ns - post_thread_config_.frame_post_offset_ns;
ATRACE_INT64("sleep_time_ns", sleep_time_ns);
if (sleep_time_ns > 0) {