diff --git a/libs/vr/libbufferhubqueue/tests/Android.bp b/libs/vr/libbufferhubqueue/tests/Android.bp
index 8bd1ef1..c4ffb41 100644
--- a/libs/vr/libbufferhubqueue/tests/Android.bp
+++ b/libs/vr/libbufferhubqueue/tests/Android.bp
@@ -12,6 +12,7 @@
     "libhardware",
     "libui",
     "libutils",
+    "libnativewindow",
 ]
 
 static_libraries = [
@@ -20,6 +21,7 @@
     "libchrome",
     "libdvrcommon",
     "libpdx_default_transport",
+    "libperformance",
 ]
 
 cc_test {
@@ -51,3 +53,17 @@
     name: "buffer_hub_queue_producer-test",
     tags: ["optional"],
 }
+
+cc_test {
+    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",
+    ],
+    name: "buffer_transport_benchmark",
+    tags: ["optional"],
+}
diff --git a/libs/vr/libbufferhubqueue/tests/buffer_transport_benchmark.cpp b/libs/vr/libbufferhubqueue/tests/buffer_transport_benchmark.cpp
new file mode 100644
index 0000000..5b580df
--- /dev/null
+++ b/libs/vr/libbufferhubqueue/tests/buffer_transport_benchmark.cpp
@@ -0,0 +1,619 @@
+#include <android/native_window.h>
+#include <base/logging.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <dvr/dvr_api.h>
+#include <dvr/performance_client_api.h>
+#include <gtest/gtest.h>
+#include <gui/BufferItem.h>
+#include <gui/BufferItemConsumer.h>
+#include <gui/Surface.h>
+#include <private/dvr/buffer_hub_queue_producer.h>
+#include <utils/Trace.h>
+
+#include <functional>
+#include <mutex>
+#include <thread>
+#include <vector>
+
+#include <poll.h>
+#include <sys/wait.h>
+#include <unistd.h>  // for pipe
+
+// Use ALWAYS at the tag level. Control is performed manually during command
+// line processing.
+#ifdef ATRACE_TAG
+#undef ATRACE_TAG
+#endif
+#define ATRACE_TAG ATRACE_TAG_ALWAYS
+
+using namespace android;
+using namespace android::dvr;
+
+static const String16 kBinderService = String16("bufferTransport");
+static const uint32_t kBufferWidth = 100;
+static const uint32_t kBufferHeight = 1;
+static const uint32_t kBufferLayerCount = 1;
+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 int kMaxAcquiredImages = 1;
+static const size_t kMaxQueueCounts = 128;
+
+static int gConcurrency = 1;  // 1 writer at a time
+static int gIterations = 1000;  // 1K times
+static int gSleepIntervalUs = 16 * 1000;  // 16ms
+
+enum BufferTransportServiceCode {
+  CREATE_BUFFER_QUEUE = IBinder::FIRST_CALL_TRANSACTION,
+};
+
+// A mininal cross process helper class based on a bidirectional pipe pair. This
+// is used to signal that Binder-based BufferTransportService has finished
+// initialization.
+class Pipe {
+ public:
+  static std::tuple<Pipe, Pipe> CreatePipePair() {
+    int a[2] = {-1, -1};
+    int b[2] = {-1, -1};
+
+    pipe(a);
+    pipe(b);
+
+    return std::make_tuple(Pipe(a[0], b[1]), Pipe(b[0], a[1]));
+  }
+
+  Pipe() = default;
+
+  Pipe(Pipe&& other) {
+    read_fd_ = other.read_fd_;
+    write_fd_ = other.write_fd_;
+    other.read_fd_ = 0;
+    other.write_fd_ = 0;
+  }
+
+  Pipe& operator=(Pipe&& other) {
+    Reset();
+    read_fd_ = other.read_fd_;
+    write_fd_ = other.write_fd_;
+    other.read_fd_ = 0;
+    other.write_fd_ = 0;
+    return *this;
+  }
+
+  ~Pipe() { Reset(); }
+
+  Pipe(const Pipe&) = delete;
+  Pipe& operator=(const Pipe&) = delete;
+  Pipe& operator=(const Pipe&&) = delete;
+
+  bool IsValid() { return read_fd_ > 0 && write_fd_ > 0; }
+
+  void Signal() {
+    bool val = true;
+    int error = write(write_fd_, &val, sizeof(val));
+    ASSERT_GE(error, 0);
+  };
+
+  void Wait() {
+    bool val = false;
+    int error = read(read_fd_, &val, sizeof(val));
+    ASSERT_GE(error, 0);
+  }
+
+  void Reset() {
+    if (read_fd_)
+      close(read_fd_);
+    if (write_fd_)
+      close(write_fd_);
+  }
+
+ private:
+  int read_fd_ = -1;
+  int write_fd_ = -1;
+  Pipe(int read_fd, int write_fd) : read_fd_{read_fd}, write_fd_{write_fd} {}
+};
+
+// A binder services that minics a compositor that consumes buffers. It provides
+// one Binder interface to create a new Surface for buffer producer to write
+// into; while itself will carry out no-op buffer consuming by acquiring then
+// releasing the buffer immediately.
+class BufferTransportService : public BBinder {
+ public:
+  BufferTransportService() = default;
+  ~BufferTransportService() = default;
+
+  virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
+                              uint32_t flags = 0) {
+    (void)flags;
+    (void)data;
+    switch (code) {
+      case CREATE_BUFFER_QUEUE: {
+        auto new_queue = std::make_shared<BufferQueueHolder>(this);
+        reply->writeStrongBinder(
+            IGraphicBufferProducer::asBinder(new_queue->producer_));
+        buffer_queues_.push_back(new_queue);
+        return NO_ERROR;
+      }
+      default:
+        return UNKNOWN_TRANSACTION;
+    };
+  }
+
+ private:
+  struct FrameListener : public ConsumerBase::FrameAvailableListener {
+   public:
+    FrameListener(BufferTransportService* service,
+                  sp<BufferItemConsumer> buffer_item_consumer)
+        : service_(service),
+          buffer_item_consumer_(buffer_item_consumer) {}
+
+    void onFrameAvailable(const BufferItem& /*item*/) override {
+      std::unique_lock<std::mutex> autolock(service_->reader_mutex_);
+
+      BufferItem buffer;
+      status_t ret = 0;
+      {
+        ATRACE_NAME("AcquireBuffer");
+        ret = buffer_item_consumer_->acquireBuffer(&buffer, /*presentWhen=*/0,
+                                                   /*waitForFence=*/false);
+      }
+
+      if (ret != NO_ERROR) {
+        LOG(ERROR) << "Failed to acquire next buffer.";
+        return;
+      }
+
+      {
+        ATRACE_NAME("ReleaseBuffer");
+        ret = buffer_item_consumer_->releaseBuffer(buffer);
+      }
+
+      if (ret != NO_ERROR) {
+        LOG(ERROR) << "Failed to release buffer.";
+        return;
+      }
+    }
+
+   private:
+    BufferTransportService* service_ = nullptr;
+    sp<BufferItemConsumer> buffer_item_consumer_;
+  };
+
+  struct BufferQueueHolder {
+    explicit BufferQueueHolder(BufferTransportService* service) {
+      BufferQueue::createBufferQueue(&producer_, &consumer_);
+
+      sp<BufferItemConsumer> buffer_item_consumer =
+          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<FrameListener> frame_listener_;
+  };
+
+  std::mutex reader_mutex_;
+  std::vector<std::shared_ptr<BufferQueueHolder>> buffer_queues_;
+};
+
+// A virtual interfaces that abstracts the common BufferQueue operations, so
+// that the test suite can use the same test case to drive different types of
+// transport backends.
+class BufferTransport {
+ public:
+  virtual ~BufferTransport() {}
+
+  virtual int Start() = 0;
+  virtual sp<Surface> CreateSurface() = 0;
+};
+
+// Binder-based buffer transport backend.
+//
+// On Start() a new process will be swapned to run a Binder server that
+// actually consumes the buffer.
+// On CreateSurface() a new Binder BufferQueue will be created, which the
+// service holds the concrete binder node of the IGraphicBufferProducer while
+// sending the binder proxy to the client. In another word, the producer side
+// operations are carried out process while the consumer side operations are
+// carried out within the BufferTransportService's own process.
+class BinderBufferTransport : public BufferTransport {
+ public:
+  BinderBufferTransport() {}
+
+  ~BinderBufferTransport() {
+    if (client_pipe_.IsValid()) {
+      client_pipe_.Signal();
+      LOG(INFO) << "Client signals service to shut down.";
+    }
+  }
+
+  int Start() override {
+    // Fork a process to run a binder server. The parent process will return
+    // a pipe here, and we use the pipe to signal the binder server to exit.
+    client_pipe_ = CreateBinderServer();
+
+    // Wait until service is ready.
+    LOG(INFO) << "Service is ready for client.";
+    client_pipe_.Wait();
+    return 0;
+  }
+
+  sp<Surface> CreateSurface() override {
+    sp<IServiceManager> sm = defaultServiceManager();
+    service_ = sm->getService(kBinderService);
+    if (service_ == nullptr) {
+      LOG(ERROR) << "Failed to set the benchmark service.";
+      return nullptr;
+    }
+
+    Parcel data;
+    Parcel reply;
+    int error = service_->transact(CREATE_BUFFER_QUEUE, data, &reply);
+    if (error != NO_ERROR) {
+      LOG(ERROR) << "Failed to get buffer queue over binder.";
+      return nullptr;
+    }
+
+    sp<IBinder> binder;
+    error = reply.readNullableStrongBinder(&binder);
+    if (error != NO_ERROR) {
+      LOG(ERROR) << "Failed to get IGraphicBufferProducer over binder.";
+      return nullptr;
+    }
+
+    auto producer = interface_cast<IGraphicBufferProducer>(binder);
+    if (producer == nullptr) {
+      LOG(ERROR) << "Failed to get IGraphicBufferProducer over binder.";
+      return nullptr;
+    }
+
+    sp<Surface> surface = new Surface(producer, /*controlledByApp=*/true);
+
+    // Set buffer dimension.
+    ANativeWindow* window = static_cast<ANativeWindow*>(surface.get());
+    ANativeWindow_setBuffersGeometry(window, kBufferWidth, kBufferHeight,
+                                     kBufferFormat);
+
+    return surface;
+  }
+
+ private:
+  static Pipe CreateBinderServer() {
+    std::tuple<Pipe, Pipe> pipe_pair = Pipe::CreatePipePair();
+    pid_t pid = fork();
+    if (pid) {
+      // parent, i.e. the client side.
+      ProcessState::self()->startThreadPool();
+      LOG(INFO) << "Binder server pid: " << pid;
+      return std::move(std::get<0>(pipe_pair));
+    } else {
+      // child, i.e. the service side.
+      Pipe service_pipe = std::move(std::get<1>(pipe_pair));
+
+      ProcessState::self()->startThreadPool();
+      sp<IServiceManager> sm = defaultServiceManager();
+      sp<BufferTransportService> service = new BufferTransportService;
+      sm->addService(kBinderService, service, false);
+
+      LOG(INFO) << "Binder Service Running...";
+
+      service_pipe.Signal();
+      service_pipe.Wait();
+
+      LOG(INFO) << "Service Exiting...";
+      exit(EXIT_SUCCESS);
+
+      /* never get here */
+      return {};
+    }
+  }
+
+  sp<IBinder> service_;
+  Pipe client_pipe_;
+};
+
+// BufferHub/PDX-based buffer transport.
+//
+// On Start() a new thread will be swapned to run an epoll polling thread which
+// minics the behavior of a compositor. Similar to Binder-based backend, the
+// buffer available handler is also a no-op: Buffer gets acquired and released
+// immediately.
+// On CreateSurface() a pair of dvr::ProducerQueue and dvr::ConsumerQueue will
+// be created. The epoll thread holds on the consumer queue and dequeues buffer
+// from it; while the producer queue will be wrapped in a Surface and returned
+// to test suite.
+class BufferHubTransport : public BufferTransport {
+ public:
+  virtual ~BufferHubTransport() {
+    stopped_.store(true);
+    if (reader_thread_.joinable()) {
+      reader_thread_.join();
+    }
+  }
+
+  int Start() override {
+    int ret = epoll_fd_.Create();
+    if (ret < 0) {
+      LOG(ERROR) << "Failed to create epoll fd: %s", strerror(-ret);
+      return -1;
+    }
+
+    // Create the reader thread.
+    reader_thread_ = std::thread([this]() {
+      int ret = dvrSetSchedulerClass(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";
+        return;
+      }
+
+      stopped_.store(false);
+      LOG(INFO) << "Reader Thread Running...";
+
+      while (!stopped_.load()) {
+        std::array<epoll_event, kMaxQueueCounts> events;
+
+        // Don't sleep forever so that we will have a chance to wake up.
+        const int ret = epoll_fd_.Wait(events.data(), events.size(),
+                                       /*timeout=*/100);
+        if (ret < 0) {
+          LOG(ERROR) << "Error polling consumer queues.";
+          continue;
+        }
+        if (ret == 0) {
+          continue;
+        }
+
+        const int num_events = ret;
+        for (int i = 0; i < num_events; i++) {
+          uint32_t surface_index = events[i].data.u32;
+          // LOG(INFO) << "!!! handle queue events index: " << surface_index;
+          buffer_queues_[surface_index]->consumer_queue_->HandleQueueEvents();
+        }
+      }
+
+      LOG(INFO) << "Reader Thread Exiting...";
+    });
+
+    return 0;
+  }
+
+  sp<Surface> CreateSurface() override {
+    std::lock_guard<std::mutex> autolock(queue_mutex_);
+
+    auto new_queue = std::make_shared<BufferQueueHolder>();
+    if (new_queue->producer_ == nullptr) {
+      LOG(ERROR) << "Failed to create buffer producer.";
+      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);
+
+    // 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);
+    if (ret < 0) {
+      LOG(ERROR) << "Failed to track consumer queue: " << strerror(-ret)
+                 << ", consumer queue fd: "
+                 << new_queue->consumer_queue_->queue_fd();
+      return nullptr;
+    }
+
+    new_queue->queue_index_ = index;
+    buffer_queues_.push_back(new_queue);
+    return surface;
+  }
+
+ 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;
+
+        {
+          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;
+        }
+
+        auto buffer = status.take();
+
+        if (buffer) {
+          ATRACE_NAME("ReleaseBuffer");
+          buffer->ReleaseAsync();
+        }
+      });
+
+      producer_ = BufferHubQueueProducer::Create(producer_queue_);
+    }
+
+    int count_ = 0;
+    int queue_index_;
+    std::shared_ptr<ProducerQueue> producer_queue_;
+    std::shared_ptr<ConsumerQueue> consumer_queue_;
+    sp<IGraphicBufferProducer> producer_;
+  };
+
+  std::atomic<bool> stopped_;
+  std::thread reader_thread_;
+
+  // Mutex to guard epoll_fd_ and buffer_queues_.
+  std::mutex queue_mutex_;
+  EpollFileDescriptor epoll_fd_;
+  std::vector<std::shared_ptr<BufferQueueHolder>> buffer_queues_;
+};
+
+enum TransportType {
+  kBinderBufferTransport,
+  kBufferHubTransport,
+};
+
+// Main test suite, which supports two transport backend: 1) BinderBufferQueue,
+// 2) BufferHubQueue. The test case drives the producer end of both transport
+// backend by queuing buffers into the buffer queue by using ANativeWindow API.
+class BufferTransportBenchmark
+    : public ::testing::TestWithParam<TransportType> {
+ public:
+  void SetUp() override {
+    switch (GetParam()) {
+      case kBinderBufferTransport:
+        transport_.reset(new BinderBufferTransport);
+        break;
+      case kBufferHubTransport:
+        transport_.reset(new BufferHubTransport);
+        break;
+      default:
+        FAIL() << "Unknown test case.";
+        break;
+    }
+  }
+
+ protected:
+  void ProduceBuffers(sp<Surface> surface, int iterations, int sleep_usec) {
+    ANativeWindow* window = static_cast<ANativeWindow*>(surface.get());
+    ANativeWindow_Buffer buffer;
+    int32_t error = 0;
+
+    for (int i = 0; i < iterations; i++) {
+      usleep(sleep_usec);
+
+      {
+        ATRACE_NAME("GainBuffer");
+        error = ANativeWindow_lock(window, &buffer,
+                                   /*inOutDirtyBounds=*/nullptr);
+      }
+      ASSERT_EQ(error, 0);
+
+      {
+        ATRACE_NAME("PostBuffer");
+        error = ANativeWindow_unlockAndPost(window);
+      }
+      ASSERT_EQ(error, 0);
+    }
+  }
+
+  std::unique_ptr<BufferTransport> transport_;
+};
+
+TEST_P(BufferTransportBenchmark, ContinuousLoad) {
+  ASSERT_NE(transport_, nullptr);
+  const int ret = transport_->Start();
+  ASSERT_EQ(ret, 0);
+
+  LOG(INFO) << "Start Running.";
+
+  std::vector<std::thread> writer_threads;
+  for (int i = 0; i < gConcurrency; i++) {
+    std::thread writer_thread = std::thread([this]() {
+      sp<Surface> surface = transport_->CreateSurface();
+      ASSERT_NE(surface, nullptr);
+
+      ASSERT_NO_FATAL_FAILURE(
+          ProduceBuffers(surface, gIterations, gSleepIntervalUs));
+
+      usleep(1000 * 100);
+    });
+
+    writer_threads.push_back(std::move(writer_thread));
+  }
+
+  for (auto& writer_thread : writer_threads) {
+    writer_thread.join();
+  }
+
+  LOG(INFO) << "All done.";
+};
+
+INSTANTIATE_TEST_CASE_P(BufferTransportBenchmarkInstance,
+                        BufferTransportBenchmark,
+                        ::testing::ValuesIn({kBinderBufferTransport,
+                                             kBufferHubTransport}));
+
+// To run binder-based benchmark, use:
+// adb shell buffer_transport_benchmark \
+//   --gtest_filter="BufferTransportBenchmark.ContinuousLoad/0"
+//
+// To run bufferhub-based benchmark, use:
+// adb shell buffer_transport_benchmark \
+//   --gtest_filter="BufferTransportBenchmark.ContinuousLoad/1"
+int main(int argc, char** argv) {
+  bool tracing_enabled = false;
+
+  // Parse arguments in addition to "--gtest_filter" paramters.
+  for (int i = 1; i < argc; i++) {
+    if (std::string(argv[i]) == "--help") {
+      std::cout << "Usage: binderThroughputTest [OPTIONS]" << std::endl;
+      std::cout << "\t-c N: Specify number of concurrent writer threads, "
+                   "(default: 1, max: 128)."
+                << std::endl;
+      std::cout << "\t-i N: Specify number of iterations, (default: 1000)."
+                << std::endl;
+      std::cout << "\t-s N: Specify sleep interval in usec, (default: 16000)."
+                << std::endl;
+      std::cout << "\t--trace: Enable systrace logging."
+                << std::endl;
+      return 0;
+    }
+    if (std::string(argv[i]) == "-c") {
+      gConcurrency = atoi(argv[i + 1]);
+      i++;
+      continue;
+    }
+    if (std::string(argv[i]) == "-s") {
+      gSleepIntervalUs = atoi(argv[i + 1]);
+      i++;
+      continue;
+    }
+    if (std::string(argv[i]) == "-i") {
+      gIterations = atoi(argv[i + 1]);
+      i++;
+      continue;
+    }
+    if (std::string(argv[i]) == "--trace") {
+      tracing_enabled = true;
+      continue;
+    }
+  }
+
+  // Setup ATRACE/systrace based on command line.
+  atrace_setup();
+  atrace_set_tracing_enabled(tracing_enabled);
+
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
