Update buffer_transport_benchmark to use DVR API

Use dynamically loaded DVR API from libdvr.so instead of statically
linking against libbufferhubqueue and libperformance.

Test: buffer_transport_benchmark
Bug: 72649062
Bug: 70046255
Change-Id: Ie10034db12bf157fb67b03302b9ba833b310a12c
diff --git a/libs/vr/libbufferhubqueue/Android.bp b/libs/vr/libbufferhubqueue/Android.bp
index 03cda02..eeec9ec 100644
--- a/libs/vr/libbufferhubqueue/Android.bp
+++ b/libs/vr/libbufferhubqueue/Android.bp
@@ -65,4 +65,4 @@
     },
 }
 
-subdirs = ["tests"]
+subdirs = ["benchmarks", "tests"]
diff --git a/libs/vr/libbufferhubqueue/benchmarks/Android.bp b/libs/vr/libbufferhubqueue/benchmarks/Android.bp
new file mode 100644
index 0000000..8ae7a0b
--- /dev/null
+++ b/libs/vr/libbufferhubqueue/benchmarks/Android.bp
@@ -0,0 +1,27 @@
+
+cc_benchmark {
+    srcs: ["buffer_transport_benchmark.cpp"],
+    shared_libs: [
+        "libbase",
+        "libbinder",
+        "libcutils",
+        "libdvr",
+        "libgui",
+        "liblog",
+        "libhardware",
+        "libui",
+        "libutils",
+        "libnativewindow",
+        "libbufferhubqueue",
+        "libpdx_default_transport",
+    ],
+    cflags: [
+        "-DLOG_TAG=\"buffer_transport_benchmark\"",
+        "-DTRACE=0",
+        "-O2",
+        "-Wall",
+        "-Werror",
+    ],
+    name: "buffer_transport_benchmark",
+    tags: ["optional"],
+}
diff --git a/libs/vr/libbufferhubqueue/tests/buffer_transport_benchmark.cpp b/libs/vr/libbufferhubqueue/benchmarks/buffer_transport_benchmark.cpp
similarity index 76%
rename from libs/vr/libbufferhubqueue/tests/buffer_transport_benchmark.cpp
rename to libs/vr/libbufferhubqueue/benchmarks/buffer_transport_benchmark.cpp
index 73932c2..4ca8671 100644
--- a/libs/vr/libbufferhubqueue/tests/buffer_transport_benchmark.cpp
+++ b/libs/vr/libbufferhubqueue/benchmarks/buffer_transport_benchmark.cpp
@@ -1,14 +1,13 @@
-#include <android/native_window.h>
 #include <android-base/logging.h>
+#include <android/native_window.h>
 #include <benchmark/benchmark.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 #include <dvr/dvr_api.h>
-#include <dvr/performance_client_api.h>
-#include <gui/BufferHubProducer.h>
 #include <gui/BufferItem.h>
 #include <gui/BufferItemConsumer.h>
 #include <gui/Surface.h>
+#include <private/dvr/epoll_file_descriptor.h>
 #include <utils/Trace.h>
 
 #include <chrono>
@@ -17,7 +16,9 @@
 #include <thread>
 #include <vector>
 
+#include <dlfcn.h>
 #include <poll.h>
+#include <sys/epoll.h>
 #include <sys/wait.h>
 
 // Use ALWAYS at the tag level. Control is performed manually during command
@@ -28,7 +29,6 @@
 #define ATRACE_TAG ATRACE_TAG_ALWAYS
 
 using namespace android;
-using namespace android::dvr;
 using ::benchmark::State;
 
 static const String16 kBinderService = String16("bufferTransport");
@@ -37,9 +37,11 @@
 static const uint32_t kBufferFormat = HAL_PIXEL_FORMAT_BLOB;
 static const uint64_t kBufferUsage =
     GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
+static const uint32_t kBufferLayer = 1;
 static const int kMaxAcquiredImages = 1;
 static const int kQueueDepth = 2;  // We are double buffering for this test.
 static const size_t kMaxQueueCounts = 128;
+static const int kInvalidFence = -1;
 
 enum BufferTransportServiceCode {
   CREATE_BUFFER_QUEUE = IBinder::FIRST_CALL_TRANSACTION,
@@ -62,7 +64,7 @@
       case CREATE_BUFFER_QUEUE: {
         auto new_queue = std::make_shared<BufferQueueHolder>(this);
         reply->writeStrongBinder(
-            IGraphicBufferProducer::asBinder(new_queue->producer_));
+            IGraphicBufferProducer::asBinder(new_queue->producer));
         buffer_queues_.push_back(new_queue);
         return NO_ERROR;
       }
@@ -109,18 +111,20 @@
 
   struct BufferQueueHolder {
     explicit BufferQueueHolder(BufferTransportService* service) {
-      BufferQueue::createBufferQueue(&producer_, &consumer_);
+      BufferQueue::createBufferQueue(&producer, &consumer);
 
       sp<BufferItemConsumer> buffer_item_consumer =
-          new BufferItemConsumer(consumer_, kBufferUsage, kMaxAcquiredImages,
+          new BufferItemConsumer(consumer, kBufferUsage, kMaxAcquiredImages,
                                  /*controlledByApp=*/true);
       buffer_item_consumer->setName(String8("BinderBufferTransport"));
       frame_listener_ = new FrameListener(service, buffer_item_consumer);
       buffer_item_consumer->setFrameAvailableListener(frame_listener_);
     }
 
-    sp<IGraphicBufferProducer> producer_;
-    sp<IGraphicBufferConsumer> consumer_;
+    sp<IGraphicBufferProducer> producer;
+    sp<IGraphicBufferConsumer> consumer;
+
+   private:
     sp<FrameListener> frame_listener_;
   };
 
@@ -199,6 +203,28 @@
   sp<IBinder> service_;
 };
 
+class DvrApi {
+ public:
+  DvrApi() {
+    handle_ = dlopen("libdvr.so", RTLD_NOW | RTLD_LOCAL);
+    CHECK(handle_);
+
+    auto dvr_get_api =
+        reinterpret_cast<decltype(&dvrGetApi)>(dlsym(handle_, "dvrGetApi"));
+    int ret = dvr_get_api(&api_, sizeof(api_), /*version=*/1);
+
+    CHECK(ret == 0);
+  }
+
+  ~DvrApi() { dlclose(handle_); }
+
+  const DvrApi_v1& Api() { return api_; }
+
+ private:
+  void* handle_ = nullptr;
+  DvrApi_v1 api_;
+};
+
 // BufferHub/PDX-based buffer transport.
 //
 // On Start() a new thread will be swapned to run an epoll polling thread which
@@ -227,16 +253,9 @@
 
     // Create the reader thread.
     reader_thread_ = std::thread([this]() {
-      int ret = dvrSetSchedulerClass(0, "graphics");
+      int ret = dvr_.Api().PerformanceSetSchedulerPolicy(0, "graphics");
       if (ret < 0) {
-        LOG(ERROR) << "Failed to set thread priority";
-        return;
-      }
-
-
-      ret = dvrSetCpuPartition(0, "/system/performance");
-      if (ret < 0) {
-        LOG(ERROR) << "Failed to set thread cpu partition";
+        LOG(ERROR) << "Failed to set scheduler policy, ret=" << ret;
         return;
       }
 
@@ -259,8 +278,9 @@
 
         const int num_events = ret;
         for (int i = 0; i < num_events; i++) {
-          uint32_t surface_index = events[i].data.u32;
-          buffer_queues_[surface_index]->consumer_queue_->HandleQueueEvents();
+          uint32_t index = events[i].data.u32;
+          dvr_.Api().ReadBufferQueueHandleEvents(
+              buffer_queues_[index]->GetReadQueue());
         }
       }
 
@@ -272,89 +292,123 @@
 
   sp<Surface> CreateSurface() override {
     auto new_queue = std::make_shared<BufferQueueHolder>();
-    if (new_queue->producer_ == nullptr) {
-      LOG(ERROR) << "Failed to create buffer producer.";
+    if (!new_queue->IsReady()) {
+      LOG(ERROR) << "Failed to create BufferHub-based BufferQueue.";
       return nullptr;
     }
 
-    sp<Surface> surface =
-        new Surface(new_queue->producer_, /*controlledByApp=*/true);
-
     // Set buffer dimension.
-    ANativeWindow* window = static_cast<ANativeWindow*>(surface.get());
-    ANativeWindow_setBuffersGeometry(window, kBufferWidth, kBufferHeight,
-                                     kBufferFormat);
+    ANativeWindow_setBuffersGeometry(new_queue->GetSurface(), kBufferWidth,
+                                     kBufferHeight, kBufferFormat);
 
     // Use the next position as buffer_queue index.
     uint32_t index = buffer_queues_.size();
     epoll_event event = {.events = EPOLLIN | EPOLLET, .data = {.u32 = index}};
-    const int ret = epoll_fd_.Control(
-        EPOLL_CTL_ADD, new_queue->consumer_queue_->queue_fd(), &event);
+    int queue_fd =
+        dvr_.Api().ReadBufferQueueGetEventFd(new_queue->GetReadQueue());
+    const int ret = epoll_fd_.Control(EPOLL_CTL_ADD, queue_fd, &event);
     if (ret < 0) {
       LOG(ERROR) << "Failed to track consumer queue: " << strerror(-ret)
-                 << ", consumer queue fd: "
-                 << new_queue->consumer_queue_->queue_fd();
+                 << ", consumer queue fd: " << queue_fd;
       return nullptr;
     }
 
-    new_queue->queue_index_ = index;
     buffer_queues_.push_back(new_queue);
-    return surface;
+    ANativeWindow_acquire(new_queue->GetSurface());
+    return static_cast<Surface*>(new_queue->GetSurface());
   }
 
  private:
   struct BufferQueueHolder {
     BufferQueueHolder() {
-      ProducerQueueConfigBuilder config_builder;
-      producer_queue_ =
-          ProducerQueue::Create(config_builder.SetDefaultWidth(kBufferWidth)
-                                    .SetDefaultHeight(kBufferHeight)
-                                    .SetDefaultFormat(kBufferFormat)
-                                    .SetMetadata<DvrNativeBufferMetadata>()
-                                    .Build(),
-                                UsagePolicy{});
-      consumer_queue_ = producer_queue_->CreateConsumerQueue();
-      consumer_queue_->SetBufferAvailableCallback([this]() {
-        size_t index = 0;
-        pdx::LocalHandle fence;
-        DvrNativeBufferMetadata meta;
-        pdx::Status<std::shared_ptr<BufferConsumer>> status;
+      int ret = 0;
+      ret = dvr_.Api().WriteBufferQueueCreate(
+          kBufferWidth, kBufferHeight, kBufferFormat, kBufferLayer,
+          kBufferUsage, 0, sizeof(DvrNativeBufferMetadata), &write_queue_);
+      if (ret < 0) {
+        LOG(ERROR) << "Failed to create write buffer queue, ret=" << ret;
+        return;
+      }
 
-        {
-          ATRACE_NAME("AcquireBuffer");
-          status = consumer_queue_->Dequeue(0, &index, &meta, &fence);
-        }
-        if (!status.ok()) {
-          LOG(ERROR) << "Failed to dequeue consumer buffer, error: "
-                     << status.GetErrorMessage().c_str();
-          return;
-        }
+      ret = dvr_.Api().WriteBufferQueueCreateReadQueue(write_queue_,
+                                                       &read_queue_);
+      if (ret < 0) {
+        LOG(ERROR) << "Failed to create read buffer queue, ret=" << ret;
+        return;
+      }
 
-        auto buffer = status.take();
+      ret = dvr_.Api().ReadBufferQueueSetBufferAvailableCallback(
+          read_queue_, BufferAvailableCallback, this);
+      if (ret < 0) {
+        LOG(ERROR) << "Failed to create buffer available callback, ret=" << ret;
+        return;
+      }
 
-        if (buffer) {
-          ATRACE_NAME("ReleaseBuffer");
-          buffer->ReleaseAsync();
-        }
-      });
-
-      producer_ = BufferHubProducer::Create(producer_queue_);
+      ret =
+          dvr_.Api().WriteBufferQueueGetANativeWindow(write_queue_, &surface_);
+      if (ret < 0) {
+        LOG(ERROR) << "Failed to create surface, ret=" << ret;
+        return;
+      }
     }
 
-    int count_ = 0;
-    int queue_index_;
-    std::shared_ptr<ProducerQueue> producer_queue_;
-    std::shared_ptr<ConsumerQueue> consumer_queue_;
-    sp<IGraphicBufferProducer> producer_;
+    static void BufferAvailableCallback(void* context) {
+      BufferQueueHolder* thiz = static_cast<BufferQueueHolder*>(context);
+      thiz->HandleBufferAvailable();
+    }
+
+    DvrReadBufferQueue* GetReadQueue() { return read_queue_; }
+
+    ANativeWindow* GetSurface() { return surface_; }
+
+    bool IsReady() {
+      return write_queue_ != nullptr && read_queue_ != nullptr &&
+             surface_ != nullptr;
+    }
+
+    void HandleBufferAvailable() {
+      int ret = 0;
+      DvrNativeBufferMetadata meta;
+      DvrReadBuffer* buffer = nullptr;
+      DvrNativeBufferMetadata metadata;
+      int acquire_fence = kInvalidFence;
+
+      {
+        ATRACE_NAME("AcquireBuffer");
+        ret = dvr_.Api().ReadBufferQueueAcquireBuffer(
+            read_queue_, 0, &buffer, &metadata, &acquire_fence);
+      }
+      if (ret < 0) {
+        LOG(ERROR) << "Failed to acquire consumer buffer, error: " << ret;
+        return;
+      }
+
+      if (buffer != nullptr) {
+        ATRACE_NAME("ReleaseBuffer");
+        ret = dvr_.Api().ReadBufferQueueReleaseBuffer(read_queue_, buffer,
+                                                      &meta, kInvalidFence);
+      }
+      if (ret < 0) {
+        LOG(ERROR) << "Failed to release consumer buffer, error: " << ret;
+      }
+    }
+
+   private:
+    DvrWriteBufferQueue* write_queue_ = nullptr;
+    DvrReadBufferQueue* read_queue_ = nullptr;
+    ANativeWindow* surface_ = nullptr;
   };
 
+  static DvrApi dvr_;
   std::atomic<bool> stopped_;
   std::thread reader_thread_;
 
-  EpollFileDescriptor epoll_fd_;
+  dvr::EpollFileDescriptor epoll_fd_;
   std::vector<std::shared_ptr<BufferQueueHolder>> buffer_queues_;
 };
 
+DvrApi BufferHubTransport::dvr_ = {};
+
 enum TransportType {
   kBinderBufferTransport,
   kBufferHubTransport,
@@ -508,8 +562,7 @@
   for (int i = 1; i < argc; i++) {
     if (std::string(argv[i]) == "--help") {
       std::cout << "Usage: binderThroughputTest [OPTIONS]" << std::endl;
-      std::cout << "\t--trace: Enable systrace logging."
-                << std::endl;
+      std::cout << "\t--trace: Enable systrace logging." << std::endl;
       return 0;
     }
     if (std::string(argv[i]) == "--trace") {
@@ -524,7 +577,7 @@
 
   pid_t pid = fork();
   if (pid == 0) {
-    // parent, i.e. the client side.
+    // Child, i.e. the client side.
     ProcessState::self()->startThreadPool();
 
     ::benchmark::Initialize(&argc, argv);
diff --git a/libs/vr/libbufferhubqueue/tests/Android.bp b/libs/vr/libbufferhubqueue/tests/Android.bp
index de6340a..ca1e7bd 100644
--- a/libs/vr/libbufferhubqueue/tests/Android.bp
+++ b/libs/vr/libbufferhubqueue/tests/Android.bp
@@ -57,19 +57,3 @@
     name: "buffer_hub_queue_producer-test",
     tags: ["optional"],
 }
-
-cc_benchmark {
-    srcs: ["buffer_transport_benchmark.cpp"],
-    static_libs: static_libraries,
-    shared_libs: shared_libraries,
-    header_libs: header_libraries,
-    cflags: [
-        "-DLOG_TAG=\"buffer_transport_benchmark\"",
-        "-DTRACE=0",
-        "-O2",
-        "-Wall",
-        "-Werror",
-    ],
-    name: "buffer_transport_benchmark",
-    tags: ["optional"],
-}