OSDN Git Service

Remove the VR compositor from the framework.
authorCorey Tabaka <eieio@google.com>
Thu, 20 Apr 2017 23:04:07 +0000 (16:04 -0700)
committerCorey Tabaka <eieio@google.com>
Fri, 5 May 2017 01:47:15 +0000 (18:47 -0700)
Remove the VR compositor framework and enable out-of-process VR composition
in VrCore.

This CL seems large due to the ripple effect of changing the VrFlinger
API and protocol types. There are three major modules that require
concurrent changes:
  1. Protocol definitions and low-level VrFlinger API in libdisplay.
     * Additional changes needed to keep old interfaces working for
       a short time while replacing the dependent code (dvrGraphics*).
  2. VrFlinger service implementation changes to support VrCore compositor
     and the removal of the internal compositor.
  3. Changes to libdvr platform library API due to changes in #1 and #2.

Because of the nature of the interdependence of types and other defs it is
difficult to break this CL into smaller chunks. However, review of the three
major modules (libdisplay, libdvr, and libvrflinger) may be done separately
to ease the mental burden on reviewers.

Change Summary:
- Remove obsolete screenshot service. VR screenshots will be implemented
  by VrCore.
- Update display protocol definitions for changes in VrFlinger service
  requirements. The majority of the changes in libdisplay are a
  consequence of these protocol and service changes.
- Update VrFlinger to support two kinds of surfaces:
    1. Application - use by VR apps.
    2. Direct - used by VrCore (protected by permission check).
- Remove VrFlinger internal compositor and GL context.
- Remove obsolete debug console.
- Update VrFlinger hardware composer interface to handle direct
  surfaces only, removing the concept of GPU (compositor) layers.
- Update display manager to expose access to application surface info
  to VrCore (protected by permission check).
- Update libdvr platform library interfaces for changes to VrFlinger
  API / protocol.
- Clean up libdvr API struct setup using a common include.
- Add C++ header-only helpers for DVR platform library opaque types.

Bug: 36401174
Test: Build; run VrFlinger display test tool.
Change-Id: I15abfde5f72dbb3725a3f58621486afba6b64902

80 files changed:
cmds/vr/vrscreencap/Android.mk [deleted file]
cmds/vr/vrscreencap/vrscreencap.cpp [deleted file]
libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h
libs/vr/libdisplay/Android.bp
libs/vr/libdisplay/display_client.cpp
libs/vr/libdisplay/display_manager_client.cpp
libs/vr/libdisplay/display_protocol.cpp
libs/vr/libdisplay/graphics.cpp
libs/vr/libdisplay/include/dvr/dvr_display_types.h [new file with mode: 0644]
libs/vr/libdisplay/include/dvr/graphics.h
libs/vr/libdisplay/include/private/dvr/display_client.h
libs/vr/libdisplay/include/private/dvr/display_manager_client.h
libs/vr/libdisplay/include/private/dvr/display_protocol.h
libs/vr/libdisplay/include/private/dvr/display_types.h [deleted file]
libs/vr/libdisplay/include/private/dvr/graphics_private.h
libs/vr/libdisplay/include/private/dvr/late_latch.h
libs/vr/libdisplay/include/private/dvr/native_buffer_queue.h
libs/vr/libdisplay/native_buffer_queue.cpp
libs/vr/libdisplay/tests/graphics_app_tests.cpp
libs/vr/libdisplay/vsync_client.cpp
libs/vr/libdvr/Android.mk
libs/vr/libdvr/display_manager_client.cpp [deleted file]
libs/vr/libdvr/dvr_api.cpp
libs/vr/libdvr/dvr_buffer.cpp
libs/vr/libdvr/dvr_buffer_queue.cpp
libs/vr/libdvr/dvr_display_manager.cpp [new file with mode: 0644]
libs/vr/libdvr/dvr_internal.h [new file with mode: 0644]
libs/vr/libdvr/dvr_surface.cpp
libs/vr/libdvr/dvr_vsync.cpp [new file with mode: 0644]
libs/vr/libdvr/include/dvr/display_manager_client.h [deleted file]
libs/vr/libdvr/include/dvr/dvr_api.h
libs/vr/libdvr/include/dvr/dvr_api_entries.h [new file with mode: 0644]
libs/vr/libdvr/include/dvr/dvr_buffer.h
libs/vr/libdvr/include/dvr/dvr_buffer_queue.h
libs/vr/libdvr/include/dvr/dvr_deleter.h [new file with mode: 0644]
libs/vr/libdvr/include/dvr/dvr_display_manager.h [new file with mode: 0644]
libs/vr/libdvr/include/dvr/dvr_surface.h
libs/vr/libdvr/include/dvr/dvr_vsync.h [new file with mode: 0644]
libs/vr/libdvr/include/dvr/vsync_client_api.h [deleted file]
libs/vr/libdvr/tests/Android.mk
libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
libs/vr/libdvr/tests/dvr_display_manager-test.cpp [new file with mode: 0644]
libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
libs/vr/libdvr/vsync_client_api.cpp [deleted file]
libs/vr/libvrflinger/Android.bp
libs/vr/libvrflinger/acquired_buffer.cpp
libs/vr/libvrflinger/acquired_buffer.h
libs/vr/libvrflinger/compositor.cpp [deleted file]
libs/vr/libvrflinger/compositor.h [deleted file]
libs/vr/libvrflinger/debug_hud_data.cpp [deleted file]
libs/vr/libvrflinger/debug_hud_data.h [deleted file]
libs/vr/libvrflinger/debug_hud_view.cpp [deleted file]
libs/vr/libvrflinger/debug_hud_view.h [deleted file]
libs/vr/libvrflinger/display_manager_service.cpp
libs/vr/libvrflinger/display_manager_service.h
libs/vr/libvrflinger/display_service.cpp
libs/vr/libvrflinger/display_service.h
libs/vr/libvrflinger/display_surface.cpp
libs/vr/libvrflinger/display_surface.h
libs/vr/libvrflinger/epoll_event_dispatcher.cpp [new file with mode: 0644]
libs/vr/libvrflinger/epoll_event_dispatcher.h [new file with mode: 0644]
libs/vr/libvrflinger/hardware_composer.cpp
libs/vr/libvrflinger/hardware_composer.h
libs/vr/libvrflinger/hwc_types.h [new file with mode: 0644]
libs/vr/libvrflinger/screenshot_service.cpp [deleted file]
libs/vr/libvrflinger/screenshot_service.h [deleted file]
libs/vr/libvrflinger/surface_channel.cpp [deleted file]
libs/vr/libvrflinger/surface_channel.h [deleted file]
libs/vr/libvrflinger/video_compositor.cpp [deleted file]
libs/vr/libvrflinger/video_compositor.h [deleted file]
libs/vr/libvrflinger/video_mesh_surface.cpp [deleted file]
libs/vr/libvrflinger/video_mesh_surface.h [deleted file]
libs/vr/libvrflinger/vr_flinger.cpp
libs/vr/libvrflinger/vsync_service.cpp
libs/vr/libvrflinger/vsync_service.h
services/surfaceflinger/SurfaceFlinger.cpp
services/surfaceflinger/surfaceflinger.rc
services/vr/hardware_composer/impl/vr_hwc.cpp
services/vr/vr_window_manager/shell_view.cpp
services/vr/vr_window_manager/shell_view.h

diff --git a/cmds/vr/vrscreencap/Android.mk b/cmds/vr/vrscreencap/Android.mk
deleted file mode 100644 (file)
index 804afc9..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-       vrscreencap.cpp
-
-LOCAL_STATIC_LIBRARIES := \
-       libbufferhub \
-       libdisplay \
-       libimageio \
-       libpdx_default_transport \
-
-LOCAL_SHARED_LIBRARIES := \
-       libcutils \
-       liblog \
-       libpng \
-       libsync \
-       libui \
-
-LOCAL_MODULE := vrscreencap
-
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_EXECUTABLE)
diff --git a/cmds/vr/vrscreencap/vrscreencap.cpp b/cmds/vr/vrscreencap/vrscreencap.cpp
deleted file mode 100644 (file)
index 3d0d112..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-// screencap is a tool for taking screenshots using the screenshot service.
-
-#include <fstream>
-#include <iostream>
-#include <string>
-#include <vector>
-
-#include <private/dvr/image_io.h>
-#include <private/dvr/screenshot_client.h>
-
-namespace {
-
-// Attempt to take a screenshot and save it to |filename|.
-// Returns zero on success, or a non-zero exit code otherwise.
-int TakeScreenshot(const std::string& app_name, const std::string& filename,
-                   int index) {
-  auto error_out = [app_name]() -> std::ostream& {
-    return std::cerr << app_name << ": ";
-  };
-
-  auto info_out = [app_name]() -> std::ostream& {
-    return std::cout << app_name << ": ";
-  };
-
-  auto client = android::dvr::ScreenshotClient::Create();
-
-  if (client->format() != HAL_PIXEL_FORMAT_RGB_888) {
-    error_out() << "The screenshot format for this device is not supported."
-                << std::endl;
-    return 1;
-  }
-
-  std::vector<uint8_t> image;
-  int width = 0;
-  int height = 0;
-  if (client->Take(&image, index, &width, &height) != 0) {
-    error_out() << "Failed to take screenshot." << std::endl;
-    return 1;
-  }
-
-  info_out() << "Got " << width << "x" << height << " screenshot." << std::endl;
-
-  if (!image_io_write_rgb888(filename.c_str(), width, height, image.data())) {
-    error_out() << "Failed to write image to output file " << filename
-                << std::endl;
-    return 1;
-  }
-
-  return 0;
-}
-
-}  // namespace
-
-int main(int argc, char** argv) {
-  // Parse arguments
-  if (argc != 2 && argc != 3) {
-    std::cerr
-        << "Usage: " << argv[0]
-        << " filename.[" DVR_IMAGE_IO_SUPPORTED_WRITE
-           "] [INDEX]\n"
-           "INDEX: specify 1..n to grab hw_composer layers by index.\n"
-           "       specify -n to grab pre-warp layers (-1 is base layer).\n"
-           "       the default is 1 (the base hw_composer layer).\n"
-           "       an invalid index will result in an error.\n";
-    return 1;
-  }
-  const std::string filename(argv[1]);
-  int index = 1;
-  if (argc > 2)
-    index = atoi(argv[2]);
-
-  // Perform the actual screenshot.
-  return TakeScreenshot(argv[0], filename, index);
-}
index 2a37cfb..c5dbbde 100644 (file)
@@ -453,23 +453,4 @@ class ConsumerQueue : public BufferHubQueue {
 }  // namespace dvr
 }  // namespace android
 
-// Concrete C type definition for DVR API.
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct DvrWriteBufferQueue {
-  std::shared_ptr<android::dvr::ProducerQueue> producer_queue_;
-  ANativeWindow* native_window_{nullptr};
-};
-
-struct DvrReadBufferQueue {
-  std::shared_ptr<android::dvr::ConsumerQueue> consumer_queue_;
-};
-
-#ifdef __cplusplus
-}  // extern "C"
-#endif
-
 #endif  // ANDROID_DVR_BUFFER_HUB_QUEUE_CLIENT_H_
index b79c8ba..41baef8 100644 (file)
@@ -18,11 +18,11 @@ sourceFiles = [
     "display_manager_client.cpp",
     "display_protocol.cpp",
     "dummy_native_window.cpp",
+    "frame_history.cpp",
     "gl_fenced_flush.cpp",
     "graphics.cpp",
     "late_latch.cpp",
     "vsync_client.cpp",
-    "frame_history.cpp",
 ]
 
 localIncludeFiles = [
index 494514d..dbee9f2 100644 (file)
@@ -12,6 +12,7 @@
 #include <private/dvr/late_latch.h>
 #include <private/dvr/native_buffer.h>
 
+using android::pdx::ErrorStatus;
 using android::pdx::LocalHandle;
 using android::pdx::LocalChannelHandle;
 using android::pdx::Status;
@@ -20,99 +21,61 @@ using android::pdx::rpc::IfAnyOf;
 
 namespace android {
 namespace dvr {
+namespace display {
 
-SurfaceClient::SurfaceClient(LocalChannelHandle channel_handle,
-                             SurfaceType type)
-    : Client{pdx::default_transport::ClientChannel::Create(
-          std::move(channel_handle))},
-      type_(type) {}
-
-SurfaceClient::SurfaceClient(const std::string& endpoint_path, SurfaceType type)
-    : Client{pdx::default_transport::ClientChannelFactory::Create(
-                 endpoint_path),
-             kInfiniteTimeout},
-      type_(type) {}
-
-int SurfaceClient::GetMetadataBufferFd(LocalHandle* out_fd) {
-  auto buffer_producer = GetMetadataBuffer();
-  if (!buffer_producer)
-    return -ENOMEM;
-
-  *out_fd = buffer_producer->GetBlobFd();
-  return 0;
-}
-
-std::shared_ptr<BufferProducer> SurfaceClient::GetMetadataBuffer() {
-  if (!metadata_buffer_) {
-    auto status = InvokeRemoteMethod<DisplayRPC::GetMetadataBuffer>();
-    if (!status) {
-      ALOGE(
-          "SurfaceClient::AllocateMetadataBuffer: Failed to allocate buffer: "
-          "%s",
+Surface::Surface(LocalChannelHandle channel_handle, int* error)
+    : BASE{pdx::default_transport::ClientChannel::Create(
+          std::move(channel_handle))} {
+  auto status = InvokeRemoteMethod<DisplayProtocol::GetSurfaceInfo>();
+  if (!status) {
+    ALOGE("Surface::Surface: Failed to get surface info: %s",
           status.GetErrorMessage().c_str());
-      return nullptr;
-    }
-
-    metadata_buffer_ = BufferProducer::Import(status.take());
+    Close(status.error());
+    if (error)
+      *error = status.error();
   }
 
-  return metadata_buffer_;
+  surface_id_ = status.get().surface_id;
+  z_order_ = status.get().z_order;
+  visible_ = status.get().visible;
 }
 
-DisplaySurfaceClient::DisplaySurfaceClient(int width, int height, int format,
-                                           int usage, int flags)
-    : BASE(DisplayRPC::kClientPath, SurfaceTypeEnum::Normal),
-      width_(width),
-      height_(height),
-      format_(format),
-      usage_(usage),
-      flags_(flags),
-      z_order_(0),
-      visible_(true),
-      exclude_from_blur_(false),
-      blur_behind_(true),
-      mapped_metadata_buffer_(nullptr) {
-  auto status = InvokeRemoteMethod<DisplayRPC::CreateSurface>(
-      width, height, format, usage, flags);
+Surface::Surface(const SurfaceAttributes& attributes, int* error)
+    : BASE{pdx::default_transport::ClientChannelFactory::Create(
+               DisplayProtocol::kClientPath),
+           kInfiniteTimeout} {
+  auto status = InvokeRemoteMethod<DisplayProtocol::CreateSurface>(attributes);
   if (!status) {
-    ALOGE(
-        "DisplaySurfaceClient::DisplaySurfaceClient: Failed to create display "
-        "surface: %s",
-        status.GetErrorMessage().c_str());
+    ALOGE("Surface::Surface: Failed to create display surface: %s",
+          status.GetErrorMessage().c_str());
     Close(status.error());
+    if (error)
+      *error = status.error();
   }
-}
-
-void DisplaySurfaceClient::SetVisible(bool visible) {
-  SetAttributes({{DisplaySurfaceAttributeEnum::Visible,
-                  DisplaySurfaceAttributeValue{visible}}});
-}
 
-void DisplaySurfaceClient::SetZOrder(int z_order) {
-  SetAttributes({{DisplaySurfaceAttributeEnum::ZOrder,
-                  DisplaySurfaceAttributeValue{z_order}}});
+  surface_id_ = status.get().surface_id;
+  z_order_ = status.get().z_order;
+  visible_ = status.get().visible;
 }
 
-void DisplaySurfaceClient::SetExcludeFromBlur(bool exclude_from_blur) {
-  SetAttributes({{DisplaySurfaceAttributeEnum::ExcludeFromBlur,
-                  DisplaySurfaceAttributeValue{exclude_from_blur}}});
+Status<void> Surface::SetVisible(bool visible) {
+  return SetAttributes(
+      {{SurfaceAttribute::Visible, SurfaceAttributeValue{visible}}});
 }
 
-void DisplaySurfaceClient::SetBlurBehind(bool blur_behind) {
-  SetAttributes({{DisplaySurfaceAttributeEnum::BlurBehind,
-                  DisplaySurfaceAttributeValue{blur_behind}}});
+Status<void> Surface::SetZOrder(int z_order) {
+  return SetAttributes(
+      {{SurfaceAttribute::ZOrder, SurfaceAttributeValue{z_order}}});
 }
 
-void DisplaySurfaceClient::SetAttributes(
-    const DisplaySurfaceAttributes& attributes) {
-  Status<int> status =
-      InvokeRemoteMethod<DisplayRPC::SetAttributes>(attributes);
+Status<void> Surface::SetAttributes(const SurfaceAttributes& attributes) {
+  auto status = InvokeRemoteMethod<DisplayProtocol::SetAttributes>(attributes);
   if (!status) {
     ALOGE(
-        "DisplaySurfaceClient::SetAttributes: Failed to set display surface "
+        "Surface::SetAttributes: Failed to set display surface "
         "attributes: %s",
         status.GetErrorMessage().c_str());
-    return;
+    return status.error_status();
   }
 
   // Set the local cached copies of the attributes we care about from the full
@@ -122,159 +85,130 @@ void DisplaySurfaceClient::SetAttributes(
     const auto* variant = &attribute.second;
     bool invalid_value = false;
     switch (key) {
-      case DisplaySurfaceAttributeEnum::Visible:
+      case SurfaceAttribute::Visible:
         invalid_value =
             !IfAnyOf<int32_t, int64_t, bool>::Get(variant, &visible_);
         break;
-      case DisplaySurfaceAttributeEnum::ZOrder:
+      case SurfaceAttribute::ZOrder:
         invalid_value = !IfAnyOf<int32_t>::Get(variant, &z_order_);
         break;
-      case DisplaySurfaceAttributeEnum::ExcludeFromBlur:
-        invalid_value =
-            !IfAnyOf<int32_t, int64_t, bool>::Get(variant, &exclude_from_blur_);
-        break;
-      case DisplaySurfaceAttributeEnum::BlurBehind:
-        invalid_value =
-            !IfAnyOf<int32_t, int64_t, bool>::Get(variant, &blur_behind_);
-        break;
     }
 
     if (invalid_value) {
       ALOGW(
-          "DisplaySurfaceClient::SetAttributes: Failed to set display "
-          "surface attribute '%s' because of incompatible type: %d",
-          DisplaySurfaceAttributeEnum::ToString(key).c_str(), variant->index());
+          "Surface::SetAttributes: Failed to set display surface "
+          "attribute %d because of incompatible type: %d",
+          key, variant->index());
     }
   }
+
+  return {};
 }
 
-std::shared_ptr<ProducerQueue> DisplaySurfaceClient::GetProducerQueue() {
-  if (producer_queue_ == nullptr) {
-    // Create producer queue through DisplayRPC
-    auto status = InvokeRemoteMethod<DisplayRPC::CreateBufferQueue>();
-    if (!status) {
-      ALOGE(
-          "DisplaySurfaceClient::GetProducerQueue: failed to create producer "
-          "queue: %s",
+Status<std::unique_ptr<ProducerQueue>> Surface::CreateQueue() {
+  ALOGD_IF(TRACE, "Surface::CreateQueue: Creating empty queue.");
+  auto status = InvokeRemoteMethod<DisplayProtocol::CreateQueue>(0);
+  if (!status) {
+    ALOGE("Surface::CreateQueue: Failed to create queue: %s",
           status.GetErrorMessage().c_str());
-      return nullptr;
-    }
-
-    producer_queue_ = ProducerQueue::Import(status.take());
+    return status.error_status();
   }
-  return producer_queue_;
-}
 
-volatile DisplaySurfaceMetadata* DisplaySurfaceClient::GetMetadataBufferPtr() {
-  if (!mapped_metadata_buffer_) {
-    if (auto buffer_producer = GetMetadataBuffer()) {
-      void* addr = nullptr;
-      const int ret = buffer_producer->GetBlobReadWritePointer(
-          sizeof(DisplaySurfaceMetadata), &addr);
-      if (ret < 0) {
-        ALOGE(
-            "DisplaySurfaceClient::GetMetadataBufferPtr: Failed to map surface "
-            "metadata: %s",
-            strerror(-ret));
-        return nullptr;
-      }
-      mapped_metadata_buffer_ = static_cast<DisplaySurfaceMetadata*>(addr);
-    }
+  auto producer_queue = ProducerQueue::Import(status.take());
+  if (!producer_queue) {
+    ALOGE("Surface::CreateQueue: Failed to import producer queue!");
+    return ErrorStatus(ENOMEM);
   }
 
-  return mapped_metadata_buffer_;
+  return {std::move(producer_queue)};
 }
 
-LocalChannelHandle DisplaySurfaceClient::CreateVideoMeshSurface() {
-  auto status = InvokeRemoteMethod<DisplayRPC::CreateVideoMeshSurface>();
-  if (!status) {
-    ALOGE(
-        "DisplaySurfaceClient::CreateVideoMeshSurface: Failed to create "
-        "video mesh surface: %s",
-        status.GetErrorMessage().c_str());
+Status<std::unique_ptr<ProducerQueue>> Surface::CreateQueue(uint32_t width,
+                                                            uint32_t height,
+                                                            uint32_t format,
+                                                            uint64_t usage,
+                                                            size_t capacity) {
+  ALOGD_IF(TRACE,
+           "Surface::CreateQueue: width=%u height=%u format=%u usage=%" PRIx64
+           " capacity=%zu",
+           width, height, format, usage, capacity);
+  auto status = CreateQueue();
+  if (!status)
+    return status.error_status();
+
+  auto producer_queue = status.take();
+
+  ALOGD_IF(TRACE, "Surface::CreateQueue: Allocating %zu buffers...", capacity);
+  for (size_t i = 0; i < capacity; i++) {
+    size_t slot;
+    const size_t kSliceCount = 1;
+    const int ret = producer_queue->AllocateBuffer(width, height, format, usage,
+                                                   kSliceCount, &slot);
+    if (ret < 0) {
+      ALOGE(
+          "Surface::CreateQueue: Failed to allocate buffer on queue_id=%d: %s",
+          producer_queue->id(), strerror(-ret));
+      return ErrorStatus(ENOMEM);
+    }
+    ALOGD_IF(
+        TRACE,
+        "Surface::CreateQueue: Allocated buffer at slot=%zu of capacity=%zu",
+        slot, capacity);
   }
-  return status.take();
+
+  return {std::move(producer_queue)};
 }
 
 DisplayClient::DisplayClient(int* error)
     : BASE(pdx::default_transport::ClientChannelFactory::Create(
-               DisplayRPC::kClientPath),
+               DisplayProtocol::kClientPath),
            kInfiniteTimeout) {
   if (error)
     *error = Client::error();
 }
 
-int DisplayClient::GetDisplayMetrics(SystemDisplayMetrics* metrics) {
-  auto status = InvokeRemoteMethod<DisplayRPC::GetMetrics>();
-  if (!status) {
-    ALOGE("DisplayClient::GetDisplayMetrics: Failed to get metrics: %s",
-          status.GetErrorMessage().c_str());
-    return -status.error();
-  }
-
-  *metrics = status.get();
-  return 0;
+Status<Metrics> DisplayClient::GetDisplayMetrics() {
+  return InvokeRemoteMethod<DisplayProtocol::GetMetrics>();
 }
 
-pdx::Status<void> DisplayClient::SetViewerParams(
-    const ViewerParams& viewer_params) {
-  auto status = InvokeRemoteMethod<DisplayRPC::SetViewerParams>(viewer_params);
-  if (!status) {
-    ALOGE("DisplayClient::SetViewerParams: Failed to set viewer params: %s",
-          status.GetErrorMessage().c_str());
-  }
-  return status;
+Status<std::unique_ptr<Surface>> DisplayClient::CreateSurface(
+    const SurfaceAttributes& attributes) {
+  int error;
+  if (auto client = Surface::Create(attributes, &error))
+    return {std::move(client)};
+  else
+    return ErrorStatus(error);
 }
 
-int DisplayClient::GetLastFrameEdsTransform(LateLatchOutput* ll_out) {
-  auto status = InvokeRemoteMethod<DisplayRPC::GetEdsCapture>();
-  if (!status) {
-    ALOGE(
-        "DisplayClient::GetLastFrameLateLatch: Failed to get most recent late"
-        " latch: %s",
-        status.GetErrorMessage().c_str());
-    return -status.error();
-  }
-
-  if (status.get().size() != sizeof(LateLatchOutput)) {
-    ALOGE(
-        "DisplayClient::GetLastFrameLateLatch: Error expected to receive %zu "
-        "bytes but received %zu",
-        sizeof(LateLatchOutput), status.get().size());
-    return -EIO;
-  }
-
-  *ll_out = *reinterpret_cast<const LateLatchOutput*>(status.get().data());
-  return 0;
-}
-
-std::unique_ptr<DisplaySurfaceClient> DisplayClient::CreateDisplaySurface(
-    int width, int height, int format, int usage, int flags) {
-  return DisplaySurfaceClient::Create(width, height, format, usage, flags);
-}
-
-std::unique_ptr<IonBuffer> DisplayClient::GetNamedBuffer(
+Status<std::unique_ptr<IonBuffer>> DisplayClient::GetNamedBuffer(
     const std::string& name) {
-  auto status = InvokeRemoteMethod<DisplayRPC::GetNamedBuffer>(name);
+  auto status = InvokeRemoteMethod<DisplayProtocol::GetNamedBuffer>(name);
   if (!status) {
     ALOGE(
-        "DisplayClient::GetNamedBuffer: Failed to get pose buffer. name=%s, "
+        "DisplayClient::GetNamedBuffer: Failed to get named buffer: name=%s; "
         "error=%s",
         name.c_str(), status.GetErrorMessage().c_str());
-    return nullptr;
+    return status.error_status();
   }
 
   auto ion_buffer = std::make_unique<IonBuffer>();
-  status.take().Import(ion_buffer.get());
-  return ion_buffer;
+  auto native_buffer_handle = status.take();
+  const int ret = native_buffer_handle.Import(ion_buffer.get());
+  if (ret < 0) {
+    ALOGE(
+        "DisplayClient::GetNamedBuffer: Failed to import named buffer: "
+        "name=%s; error=%s",
+        name.c_str(), strerror(-ret));
+    return ErrorStatus(-ret);
+  }
+
+  return {std::move(ion_buffer)};
 }
 
-bool DisplayClient::IsVrAppRunning() {
-  auto status = InvokeRemoteMethod<DisplayRPC::IsVrAppRunning>();
-  if (!status)
-    return 0;
-  return static_cast<bool>(status.get());
+Status<bool> DisplayClient::IsVrAppRunning() {
+  return InvokeRemoteMethod<DisplayProtocol::IsVrAppRunning>();
 }
 
+}  // namespace display
 }  // namespace dvr
 }  // namespace android
index ca51ab6..82dacf7 100644 (file)
@@ -2,51 +2,77 @@
 
 #include <pdx/default_transport/client_channel_factory.h>
 #include <private/dvr/buffer_hub_client.h>
+#include <private/dvr/buffer_hub_queue_client.h>
 #include <private/dvr/display_protocol.h>
 #include <utils/Log.h>
 
+using android::pdx::ErrorStatus;
 using android::pdx::LocalChannelHandle;
 using android::pdx::Transaction;
 
 namespace android {
 namespace dvr {
+namespace display {
 
 DisplayManagerClient::DisplayManagerClient()
     : BASE(pdx::default_transport::ClientChannelFactory::Create(
-          DisplayManagerRPC::kClientPath)) {}
+          DisplayManagerProtocol::kClientPath)) {}
 
 DisplayManagerClient::~DisplayManagerClient() {}
 
-int DisplayManagerClient::GetSurfaceList(
-    std::vector<DisplaySurfaceInfo>* surface_list) {
-  auto status = InvokeRemoteMethod<DisplayManagerRPC::GetSurfaceList>();
+pdx::Status<std::vector<display::SurfaceState>>
+DisplayManagerClient::GetSurfaceState() {
+  auto status = InvokeRemoteMethod<DisplayManagerProtocol::GetSurfaceState>();
   if (!status) {
     ALOGE(
-        "DisplayManagerClient::GetSurfaceList: Failed to get surface info: %s",
+        "DisplayManagerClient::GetSurfaceState: Failed to get surface info: %s",
         status.GetErrorMessage().c_str());
-    return -status.error();
   }
 
-  *surface_list = status.take();
-  return 0;
+  return status;
 }
 
-std::unique_ptr<IonBuffer> DisplayManagerClient::SetupNamedBuffer(
+pdx::Status<std::unique_ptr<IonBuffer>> DisplayManagerClient::SetupNamedBuffer(
     const std::string& name, size_t size, uint64_t usage) {
-  auto status = InvokeRemoteMethod<DisplayManagerRPC::SetupNamedBuffer>(
+  auto status = InvokeRemoteMethod<DisplayManagerProtocol::SetupNamedBuffer>(
       name, size, usage);
   if (!status) {
     ALOGE(
-        "DisplayManagerClient::SetupNamedBuffer: Failed to create the named "
-        "buffer: name=%s, error=%s",
-        name.c_str(), status.GetErrorMessage().c_str());
-    return {};
+        "DisplayManagerClient::SetupPoseBuffer: Failed to create the named "
+        "buffer %s",
+        status.GetErrorMessage().c_str());
+    return status.error_status();
   }
 
   auto ion_buffer = std::make_unique<IonBuffer>();
-  status.take().Import(ion_buffer.get());
-  return ion_buffer;
+  auto native_buffer_handle = status.take();
+  const int ret = native_buffer_handle.Import(ion_buffer.get());
+  if (ret < 0) {
+    ALOGE(
+        "DisplayClient::GetNamedBuffer: Failed to import named buffer: "
+        "name=%s; error=%s",
+        name.c_str(), strerror(-ret));
+    return ErrorStatus(-ret);
+  }
+
+  return {std::move(ion_buffer)};
+}
+
+pdx::Status<std::unique_ptr<ConsumerQueue>>
+DisplayManagerClient::GetSurfaceQueue(int surface_id, int queue_id) {
+  auto status = InvokeRemoteMethod<DisplayManagerProtocol::GetSurfaceQueue>(
+      surface_id, queue_id);
+  if (!status) {
+    ALOGE(
+        "DisplayManagerClient::GetSurfaceQueue: Failed to get queue for "
+        "surface_id=%d queue_id=%d: %s",
+        surface_id, queue_id, status.GetErrorMessage().c_str());
+    return status.error_status();
+  }
+
+  return {ConsumerQueue::Import(status.take())};
 }
 
+}  // namespace display
 }  // namespace dvr
 }  // namespace android
index e96394c..773f9a5 100644 (file)
@@ -2,11 +2,12 @@
 
 namespace android {
 namespace dvr {
+namespace display {
 
-constexpr char DisplayRPC::kClientPath[];
-constexpr char DisplayManagerRPC::kClientPath[];
-constexpr char DisplayScreenshotRPC::kClientPath[];
-constexpr char DisplayVSyncRPC::kClientPath[];
+constexpr char DisplayProtocol::kClientPath[];
+constexpr char DisplayManagerProtocol::kClientPath[];
+constexpr char VSyncProtocol::kClientPath[];
 
-} // namespace dvr
-} // namespace android
+}  // namespace display
+}  // namespace dvr
+}  // namespace android
index bd3ed7e..f0e37f8 100644 (file)
 #endif
 #include <vulkan/vulkan.h>
 
+#include <dvr/dvr_display_types.h>
 #include <pdx/file_handle.h>
 #include <private/dvr/clock_ns.h>
 #include <private/dvr/debug.h>
-#include <private/dvr/display_types.h>
 #include <private/dvr/frame_history.h>
 #include <private/dvr/gl_fenced_flush.h>
 #include <private/dvr/graphics/vr_gl_extensions.h>
 #include <private/dvr/graphics_private.h>
 #include <private/dvr/late_latch.h>
 #include <private/dvr/native_buffer_queue.h>
+#include <private/dvr/platform_defines.h>
 #include <private/dvr/sensor_constants.h>
 #include <private/dvr/vsync_client.h>
-#include <private/dvr/platform_defines.h>
 
 #include <android/native_window.h>
 
 #define EGL_CONTEXT_MINOR_VERSION 0x30FB
 #endif
 
+using android::pdx::ErrorStatus;
 using android::pdx::LocalHandle;
 using android::pdx::LocalChannelHandle;
+using android::pdx::Status;
 
-using android::dvr::DisplaySurfaceAttributeEnum;
-using android::dvr::DisplaySurfaceAttributeValue;
+using android::dvr::display::DisplayClient;
+using android::dvr::display::Metrics;
+using android::dvr::display::NativeBufferQueue;
+using android::dvr::display::Surface;
+using android::dvr::display::SurfaceAttribute;
+using android::dvr::display::SurfaceAttributes;
+using android::dvr::display::SurfaceAttributeValue;
+using android::dvr::VSyncClient;
 
 namespace {
 
 // TODO(urbanus): revisit once we have per-platform usage config in place.
-constexpr int kDefaultDisplaySurfaceUsage =
-    GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE |
-    GRALLOC_USAGE_QCOM_FRAMEBUFFER_COMPRESSION;
-constexpr int kDefaultDisplaySurfaceFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+constexpr uint64_t kDefaultDisplaySurfaceUsage =
+    GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET |
+    GRALLOC1_PRODUCER_USAGE_PRIVATE_1 | GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET |
+    GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE;
+constexpr uint32_t kDefaultDisplaySurfaceFormat = HAL_PIXEL_FORMAT_RGBA_8888;
 // TODO(alexst): revisit this count when HW encode is available for casting.
-constexpr int kDefaultBufferCount = 4;
+constexpr size_t kDefaultBufferCount = 4;
 
 // Use with dvrBeginRenderFrame to disable EDS for the current frame.
 constexpr float32x4_t DVR_POSE_NO_EDS = {10.0f, 0.0f, 0.0f, 0.0f};
@@ -278,51 +287,119 @@ int CreateEglContext(EGLDisplay egl_display, DvrSurfaceParameter* parameters,
   return 0;
 }
 
+// Utility structure to hold info related to creating a surface.
+struct SurfaceResult {
+  std::shared_ptr<Surface> surface;
+  Metrics metrics;
+  uint32_t width;
+  uint32_t height;
+  uint32_t format;
+  uint64_t usage;
+  size_t capacity;
+  int geometry;
+  bool direct_surface;
+};
+
+Status<std::tuple<std::shared_ptr<android::dvr::ProducerQueue>,
+                  std::shared_ptr<android::dvr::BufferProducer>,
+                  volatile DisplaySurfaceMetadata*>>
+CreateMetadataBuffer(const std::shared_ptr<Surface>& surface,
+                     bool direct_surface) {
+  std::shared_ptr<android::dvr::ProducerQueue> queue;
+  std::shared_ptr<android::dvr::BufferProducer> buffer;
+
+  if (!direct_surface) {
+    auto queue_status = surface->CreateQueue(
+        sizeof(DisplaySurfaceMetadata), 1, HAL_PIXEL_FORMAT_BLOB,
+        GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET |
+            GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN |
+            GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER,
+        1);
+    if (!queue_status) {
+      ALOGE("CreateMetadataBuffer: Failed to create queue: %s",
+            queue_status.GetErrorMessage().c_str());
+      return queue_status.error_status();
+    }
+
+    queue = queue_status.take();
+    LocalHandle fence;
+    size_t slot;
+    auto buffer_status = queue->Dequeue(-1, &slot, &fence);
+    if (!buffer_status) {
+      ALOGE("CreateMetadataBuffer: Failed to dequeue buffer: %s",
+            buffer_status.GetErrorMessage().c_str());
+      return buffer_status.error_status();
+    }
+    buffer = buffer_status.take();
+  } else {
+    buffer = android::dvr::BufferProducer::CreateUncachedBlob(
+        sizeof(DisplaySurfaceMetadata));
+    if (!buffer) {
+      ALOGE("CreateMetadataBuffer: Failed to create stand-in buffer!");
+      return ErrorStatus(ENOMEM);
+    }
+  }
+
+  void* address = nullptr;
+  int ret =
+      buffer->GetBlobReadWritePointer(sizeof(DisplaySurfaceMetadata), &address);
+
+  if (ret < 0) {
+    ALOGE("CreateMetadataBuffer: Failed to map buffer: %s", strerror(-ret));
+    return ErrorStatus(-ret);
+  }
+
+  // Post the buffer so that the compositor can retrieve it from the consumer
+  // queue.
+  ret = buffer->Post<void>(LocalHandle{});
+  if (ret < 0) {
+    ALOGE("CreateMetadataBuffer: Failed to post buffer: %s", strerror(-ret));
+    return ErrorStatus(-ret);
+  }
+
+  ALOGD_IF(TRACE, "CreateMetadataBuffer: queue_id=%d buffer_id=%d address=%p",
+           queue ? queue->id() : -1, buffer->id(), address);
+  return {{std::move(queue), std::move(buffer),
+           static_cast<DisplaySurfaceMetadata*>(address)}};
+}
+
 }  // anonymous namespace
 
-// TODO(hendrikw): When we remove the calls to this in native_window.cpp, move
-// this back into the anonymous namespace
-std::shared_ptr<android::dvr::DisplaySurfaceClient> CreateDisplaySurfaceClient(
-    struct DvrSurfaceParameter* parameters,
-    /*out*/ android::dvr::SystemDisplayMetrics* metrics) {
-  auto client = android::dvr::DisplayClient::Create();
+Status<SurfaceResult> CreateSurface(struct DvrSurfaceParameter* parameters) {
+  int error;
+  auto client = DisplayClient::Create(&error);
   if (!client) {
-    ALOGE("Failed to create display client!");
-    return nullptr;
+    ALOGE("CreateApplicationSurface: Failed to create display client!");
+    return ErrorStatus(error);
   }
 
-  const int ret = client->GetDisplayMetrics(metrics);
-  if (ret < 0) {
-    ALOGE("Failed to get display metrics: %s", strerror(-ret));
-    return nullptr;
+  auto metrics_status = client->GetDisplayMetrics();
+  if (!metrics_status) {
+    ALOGE("CreateApplicationSurface: Failed to get display metrics: %s",
+          metrics_status.GetErrorMessage().c_str());
+    return metrics_status.error_status();
   }
 
   // Parameters that may be modified by the parameters array. Some of these are
   // here for future expansion.
-  int request_width = -1;
-  int request_height = -1;
-  int request_flags = 0;
+
+  uint32_t request_width = metrics_status.get().display_width;
+  uint32_t request_height = metrics_status.get().display_width;
+  uint32_t request_format = kDefaultDisplaySurfaceFormat;
+  uint64_t request_usage = kDefaultDisplaySurfaceUsage;
+  size_t request_capacity = kDefaultBufferCount;
+  int request_geometry = DVR_SURFACE_GEOMETRY_SINGLE;
   bool disable_distortion = false;
   bool disable_stabilization = false;
   bool disable_cac = false;
-  bool request_visible = true;
+  bool request_visible = false;
   bool vertical_flip = false;
+  bool direct_surface = false;
   int request_z_order = 0;
-  bool request_exclude_from_blur = false;
-  bool request_blur_behind = true;
-  int request_format = kDefaultDisplaySurfaceFormat;
-  int request_usage = kDefaultDisplaySurfaceUsage;
-  int geometry_type = DVR_SURFACE_GEOMETRY_SINGLE;
 
   // Handle parameter inputs.
   for (auto p = parameters; p && p->key != DVR_SURFACE_PARAMETER_NONE; ++p) {
     switch (p->key) {
-      case DVR_SURFACE_PARAMETER_WIDTH_IN:
-        request_width = p->value;
-        break;
-      case DVR_SURFACE_PARAMETER_HEIGHT_IN:
-        request_height = p->value;
-        break;
       case DVR_SURFACE_PARAMETER_DISABLE_DISTORTION_IN:
         disable_distortion = !!p->value;
         break;
@@ -338,20 +415,23 @@ std::shared_ptr<android::dvr::DisplaySurfaceClient> CreateDisplaySurfaceClient(
       case DVR_SURFACE_PARAMETER_Z_ORDER_IN:
         request_z_order = p->value;
         break;
-      case DVR_SURFACE_PARAMETER_EXCLUDE_FROM_BLUR_IN:
-        request_exclude_from_blur = !!p->value;
-        break;
-      case DVR_SURFACE_PARAMETER_BLUR_BEHIND_IN:
-        request_blur_behind = !!p->value;
-        break;
       case DVR_SURFACE_PARAMETER_VERTICAL_FLIP_IN:
         vertical_flip = !!p->value;
         break;
-      case DVR_SURFACE_PARAMETER_GEOMETRY_IN:
-        geometry_type = p->value;
+      case DVR_SURFACE_PARAMETER_DIRECT_IN:
+        direct_surface = !!p->value;
+        break;
+      case DVR_SURFACE_PARAMETER_WIDTH_IN:
+        request_width = p->value;
+        break;
+      case DVR_SURFACE_PARAMETER_HEIGHT_IN:
+        request_height = p->value;
         break;
       case DVR_SURFACE_PARAMETER_FORMAT_IN:
-        request_format = DvrToHalSurfaceFormat(p->value);
+        request_format = p->value;
+        break;
+      case DVR_SURFACE_PARAMETER_GEOMETRY_IN:
+        request_geometry = p->value;
         break;
       case DVR_SURFACE_PARAMETER_ENABLE_LATE_LATCH_IN:
       case DVR_SURFACE_PARAMETER_CREATE_GL_CONTEXT_IN:
@@ -375,113 +455,90 @@ std::shared_ptr<android::dvr::DisplaySurfaceClient> CreateDisplaySurfaceClient(
       case DVR_SURFACE_PARAMETER_VK_SWAPCHAIN_IMAGE_FORMAT_OUT:
         break;
       default:
-        ALOGE("Invalid display surface parameter: key=%d value=%" PRId64,
-              p->key, p->value);
-        return nullptr;
+        ALOGE(
+            "CreateSurface: Invalid display surface parameter: key=%d "
+            "value=%" PRId64,
+            p->key, p->value);
+        return ErrorStatus(EINVAL);
     }
   }
 
-  request_flags |= disable_distortion
-                       ? DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION
-                       : 0;
-  request_flags |=
-      disable_stabilization ? DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_EDS : 0;
-  request_flags |=
-      disable_cac ? DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_CAC : 0;
-  request_flags |= vertical_flip ? DVR_DISPLAY_SURFACE_FLAGS_VERTICAL_FLIP : 0;
-  request_flags |= (geometry_type == DVR_SURFACE_GEOMETRY_SEPARATE_2)
-                       ? DVR_DISPLAY_SURFACE_FLAGS_GEOMETRY_SEPARATE_2
-                       : 0;
-
-  if (request_width == -1) {
-    request_width = disable_distortion ? metrics->display_native_width
-                                       : metrics->distorted_width;
-    if (!disable_distortion &&
-        geometry_type == DVR_SURFACE_GEOMETRY_SEPARATE_2) {
-      // The metrics always return the single wide buffer resolution.
-      // When split between eyes, we need to halve the width of the surface.
-      request_width /= 2;
-    }
-  }
-  if (request_height == -1) {
-    request_height = disable_distortion ? metrics->display_native_height
-                                        : metrics->distorted_height;
+  // TODO(eieio): Setup a "surface flags" attribute based on the surface
+  // parameters gathered above.
+  SurfaceAttributes surface_attributes;
+
+  surface_attributes[SurfaceAttribute::Direct] = direct_surface;
+  surface_attributes[SurfaceAttribute::Visible] = request_visible;
+  surface_attributes[SurfaceAttribute::ZOrder] = request_z_order;
+
+  auto surface_status = Surface::CreateSurface(surface_attributes);
+  if (!surface_status) {
+    ALOGE("CreateSurface: Failed to create surface: %s",
+          surface_status.GetErrorMessage().c_str());
+    return surface_status.error_status();
   }
 
-  std::shared_ptr<android::dvr::DisplaySurfaceClient> surface =
-      client->CreateDisplaySurface(request_width, request_height,
-                                   request_format, request_usage,
-                                   request_flags);
-  surface->SetAttributes(
-      {{DisplaySurfaceAttributeEnum::Visible,
-        DisplaySurfaceAttributeValue{request_visible}},
-       {DisplaySurfaceAttributeEnum::ZOrder,
-        DisplaySurfaceAttributeValue{request_z_order}},
-       {DisplaySurfaceAttributeEnum::ExcludeFromBlur,
-        DisplaySurfaceAttributeValue{request_exclude_from_blur}},
-       {DisplaySurfaceAttributeEnum::BlurBehind,
-        DisplaySurfaceAttributeValue{request_blur_behind}}});
+  return {{surface_status.take(), metrics_status.get(), request_width,
+           request_height, request_format, request_usage, request_capacity,
+           request_geometry, direct_surface}};
+}
+
+// TODO(hendrikw): When we remove the calls to this in native_window.cpp, move
+// this back into the anonymous namespace
+Status<SurfaceResult> CreateApplicationSurface(
+    struct DvrSurfaceParameter* parameters) {
+  auto surface_status = CreateSurface(parameters);
+  if (!surface_status)
+    return surface_status;
 
   // Handle parameter output requests down here so we can return surface info.
   for (auto p = parameters; p && p->key != DVR_SURFACE_PARAMETER_NONE; ++p) {
     switch (p->key) {
       case DVR_SURFACE_PARAMETER_DISPLAY_WIDTH_OUT:
-        *static_cast<int32_t*>(p->value_out) = metrics->display_native_width;
+        *static_cast<int32_t*>(p->value_out) =
+            surface_status.get().metrics.display_width;
         break;
       case DVR_SURFACE_PARAMETER_DISPLAY_HEIGHT_OUT:
-        *static_cast<int32_t*>(p->value_out) = metrics->display_native_height;
+        *static_cast<int32_t*>(p->value_out) =
+            surface_status.get().metrics.display_height;
+        break;
+      case DVR_SURFACE_PARAMETER_VSYNC_PERIOD_OUT:
+        *static_cast<uint64_t*>(p->value_out) =
+            surface_status.get().metrics.vsync_period_ns;
         break;
       case DVR_SURFACE_PARAMETER_SURFACE_WIDTH_OUT:
-        *static_cast<int32_t*>(p->value_out) = surface->width();
+        *static_cast<uint32_t*>(p->value_out) = surface_status.get().width;
         break;
       case DVR_SURFACE_PARAMETER_SURFACE_HEIGHT_OUT:
-        *static_cast<int32_t*>(p->value_out) = surface->height();
-        break;
-      case DVR_SURFACE_PARAMETER_INTER_LENS_METERS_OUT:
-        *static_cast<float*>(p->value_out) = metrics->inter_lens_distance_m;
-        break;
-      case DVR_SURFACE_PARAMETER_LEFT_FOV_LRBT_OUT:
-        for (int i = 0; i < 4; ++i) {
-          float* float_values_out = static_cast<float*>(p->value_out);
-          float_values_out[i] = metrics->left_fov_lrbt[i];
-        }
-        break;
-      case DVR_SURFACE_PARAMETER_RIGHT_FOV_LRBT_OUT:
-        for (int i = 0; i < 4; ++i) {
-          float* float_values_out = static_cast<float*>(p->value_out);
-          float_values_out[i] = metrics->right_fov_lrbt[i];
-        }
-        break;
-      case DVR_SURFACE_PARAMETER_VSYNC_PERIOD_OUT:
-        *static_cast<uint64_t*>(p->value_out) = metrics->vsync_period_ns;
+        *static_cast<uint32_t*>(p->value_out) = surface_status.get().height;
         break;
+
       default:
         break;
     }
   }
 
-  return surface;
+  return surface_status;
 }
 
-extern "C" int dvrGetNativeDisplayDimensions(int* native_width,
-                                             int* native_height) {
+extern "C" int dvrGetNativeDisplayDimensions(int* display_width,
+                                             int* display_height) {
   int error = 0;
-  auto client = android::dvr::DisplayClient::Create(&error);
+  auto client = DisplayClient::Create(&error);
   if (!client) {
-    ALOGE("Failed to create display client!");
-    return error;
+    ALOGE("dvrGetNativeDisplayDimensions: Failed to create display client!");
+    return -error;
   }
 
-  android::dvr::SystemDisplayMetrics metrics;
-  const int ret = client->GetDisplayMetrics(&metrics);
-
-  if (ret != 0) {
-    ALOGE("Failed to get display metrics!");
-    return ret;
+  auto metrics_status = client->GetDisplayMetrics();
+  if (!metrics_status) {
+    ALOGE("dvrGetNativeDisplayDimensions: Failed to get display metrics: %s",
+          metrics_status.GetErrorMessage().c_str());
+    return -metrics_status.error();
   }
 
-  *native_width = static_cast<int>(metrics.display_native_width);
-  *native_height = static_cast<int>(metrics.display_native_height);
+  *display_width = static_cast<int>(metrics_status.get().display_width);
+  *display_height = static_cast<int>(metrics_status.get().display_height);
   return 0;
 }
 
@@ -523,9 +580,12 @@ struct DvrGraphicsContext : public android::ANativeObjectBase<
   } vk;
 
   // Display surface, metrics, and buffer management members.
-  std::shared_ptr<android::dvr::DisplaySurfaceClient> display_surface;
-  android::dvr::SystemDisplayMetrics display_metrics;
-  std::unique_ptr<android::dvr::NativeBufferQueue> buffer_queue;
+  std::shared_ptr<Surface> display_surface;
+  uint32_t width;
+  uint32_t height;
+  uint32_t format;
+  Metrics display_metrics;
+  std::unique_ptr<NativeBufferQueue> buffer_queue;
   android::dvr::NativeBufferProducer* current_buffer;
   bool buffer_already_posted;
 
@@ -535,8 +595,13 @@ struct DvrGraphicsContext : public android::ANativeObjectBase<
 
   android::dvr::FrameHistory frame_history;
 
+  // Metadata queue and buffer.
+  // TODO(eieio): Remove the queue once one-off buffers are supported as a
+  // surface primitive element.
+  std::shared_ptr<android::dvr::ProducerQueue> metadata_queue;
+  std::shared_ptr<android::dvr::BufferProducer> metadata_buffer;
   // Mapped surface metadata (ie: for pose delivery with presented frames).
-  volatile android::dvr::DisplaySurfaceMetadata* surface_metadata;
+  volatile DisplaySurfaceMetadata* surface_metadata;
 
   // LateLatch support.
   std::unique_ptr<android::dvr::LateLatch> late_latch;
@@ -611,7 +676,7 @@ DvrGraphicsContext::~DvrGraphicsContext() {
 
 int dvrGraphicsContextCreate(struct DvrSurfaceParameter* parameters,
                              DvrGraphicsContext** return_graphics_context) {
-  std::unique_ptr<DvrGraphicsContext> context(new DvrGraphicsContext);
+  auto context = std::make_unique<DvrGraphicsContext>();
 
   // See whether we're using GL or Vulkan
   for (auto p = parameters; p && p->key != DVR_SURFACE_PARAMETER_NONE; ++p) {
@@ -676,46 +741,66 @@ int dvrGraphicsContextCreate(struct DvrSurfaceParameter* parameters,
     return -EINVAL;
   }
 
-  context->display_surface =
-      CreateDisplaySurfaceClient(parameters, &context->display_metrics);
-  if (!context->display_surface) {
-    ALOGE("Error: failed to create display surface client");
-    return -ECOMM;
+  auto surface_status = CreateApplicationSurface(parameters);
+  if (!surface_status) {
+    ALOGE("dvrGraphicsContextCreate: Failed to create surface: %s",
+          surface_status.GetErrorMessage().c_str());
+    return -surface_status.error();
   }
 
-  context->buffer_queue.reset(new android::dvr::NativeBufferQueue(
-      context->gl.egl_display, context->display_surface, kDefaultBufferCount));
+  auto surface_result = surface_status.take();
+
+  context->display_surface = surface_result.surface;
+  context->display_metrics = surface_result.metrics;
+  context->width = surface_result.width;
+  context->height = surface_result.height;
+  context->format = surface_result.format;
+
+  // Create an empty queue. NativeBufferQueue allocates the buffers for this
+  // queue.
+  auto queue_status = context->display_surface->CreateQueue();
+  if (!queue_status) {
+    ALOGE("dvrGraphicsContextCreate: Failed to create queue: %s",
+          queue_status.GetErrorMessage().c_str());
+    return -queue_status.error();
+  }
+
+  context->buffer_queue.reset(new NativeBufferQueue(
+      context->gl.egl_display, queue_status.take(), surface_result.width,
+      surface_result.height, surface_result.format, surface_result.usage,
+      surface_result.capacity));
+
+  // Create the metadata buffer.
+  auto metadata_status = CreateMetadataBuffer(context->display_surface,
+                                              surface_result.direct_surface);
+  if (!metadata_status) {
+    ALOGE("dvrGraphicsContextCreate: Failed to create metadata buffer: %s",
+          metadata_status.GetErrorMessage().c_str());
+    return -metadata_status.error();
+  }
+  std::tie(context->metadata_queue, context->metadata_buffer,
+           context->surface_metadata) = metadata_status.take();
 
   // The way the call sequence works we need 1 more than the buffer queue
   // capacity to store data for all pending frames
-  context->frame_history.Reset(context->buffer_queue->GetQueueCapacity() + 1);
+  context->frame_history.Reset(context->buffer_queue->capacity() + 1);
 
-  context->vsync_client = android::dvr::VSyncClient::Create();
+  context->vsync_client = VSyncClient::Create();
   if (!context->vsync_client) {
-    ALOGE("Error: failed to create vsync client");
+    ALOGE("dvrGraphicsContextCreate: failed to create vsync client");
     return -ECOMM;
   }
 
   context->timerfd.Reset(timerfd_create(CLOCK_MONOTONIC, 0));
   if (!context->timerfd) {
-    ALOGE("Error: timerfd_create failed because: %s", strerror(errno));
+    ALOGE("dvrGraphicsContextCreate: timerfd_create failed because: %s",
+          strerror(errno));
     return -EPERM;
   }
 
-  context->surface_metadata = context->display_surface->GetMetadataBufferPtr();
-  if (!context->surface_metadata) {
-    ALOGE("Error: surface metadata allocation failed");
-    return -ENOMEM;
-  }
-
-  ALOGI("buffer: %d x %d\n", context->display_surface->width(),
-        context->display_surface->height());
-
   if (context->graphics_api == DVR_GRAPHICS_API_GLES) {
-    context->gl.texture_count = (context->display_surface->flags() &
-                                 DVR_DISPLAY_SURFACE_FLAGS_GEOMETRY_SEPARATE_2)
-                                    ? 2
-                                    : 1;
+    context->gl.texture_count =
+        (surface_result.geometry == DVR_SURFACE_GEOMETRY_SEPARATE_2) ? 2 : 1;
 
     // Create the GL textures.
     glGenTextures(context->gl.texture_count, context->gl.texture_id);
@@ -756,14 +841,9 @@ int dvrGraphicsContextCreate(struct DvrSurfaceParameter* parameters,
 
     // Initialize late latch.
     if (is_late_latch) {
-      LocalHandle fd;
-      int ret = context->display_surface->GetMetadataBufferFd(&fd);
-      if (ret == 0) {
-        context->late_latch.reset(
-            new android::dvr::LateLatch(true, std::move(fd)));
-      } else {
-        ALOGE("Error: failed to get surface metadata buffer fd for late latch");
-      }
+      LocalHandle fd = context->metadata_buffer->GetBlobFd();
+      context->late_latch.reset(
+          new android::dvr::LateLatch(true, std::move(fd)));
     }
   } else if (context->graphics_api == DVR_GRAPHICS_API_VULKAN) {
     VkResult result = VK_SUCCESS;
@@ -963,7 +1043,7 @@ int DvrGraphicsContext::DequeueBuffer(ANativeWindow* window,
   std::lock_guard<std::mutex> autolock(self->lock_);
 
   if (!self->current_buffer) {
-    self->current_buffer = self->buffer_queue.get()->Dequeue();
+    self->current_buffer = self->buffer_queue->Dequeue();
   }
   ATRACE_ASYNC_BEGIN("BufferDraw", self->current_buffer->buffer()->id());
   *fence_fd = self->current_buffer->ClaimReleaseFence().Release();
@@ -1030,7 +1110,7 @@ int DvrGraphicsContext::CancelBuffer(ANativeWindow* window,
     }
   }
   if (do_enqueue) {
-    self->buffer_queue.get()->Enqueue(native_buffer);
+    self->buffer_queue->Enqueue(native_buffer);
   }
   if (fence_fd >= 0)
     close(fence_fd);
@@ -1048,13 +1128,13 @@ int DvrGraphicsContext::Query(const ANativeWindow* window, int what,
 
   switch (what) {
     case NATIVE_WINDOW_WIDTH:
-      *value = self->display_surface->width();
+      *value = self->width;
       return android::NO_ERROR;
     case NATIVE_WINDOW_HEIGHT:
-      *value = self->display_surface->height();
+      *value = self->height;
       return android::NO_ERROR;
     case NATIVE_WINDOW_FORMAT:
-      *value = self->display_surface->format();
+      *value = self->format;
       return android::NO_ERROR;
     case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
       *value = 1;
@@ -1066,10 +1146,10 @@ int DvrGraphicsContext::Query(const ANativeWindow* window, int what,
       *value = 1;
       return android::NO_ERROR;
     case NATIVE_WINDOW_DEFAULT_WIDTH:
-      *value = self->display_surface->width();
+      *value = self->width;
       return android::NO_ERROR;
     case NATIVE_WINDOW_DEFAULT_HEIGHT:
-      *value = self->display_surface->height();
+      *value = self->height;
       return android::NO_ERROR;
     case NATIVE_WINDOW_TRANSFORM_HINT:
       *value = 0;
@@ -1196,8 +1276,7 @@ int dvrSetEdsPose(DvrGraphicsContext* graphics_context,
   // we don't touch it here.
   float32x4_t is_late_latch = DVR_POSE_LATE_LATCH;
   if (render_pose_orientation[0] != is_late_latch[0]) {
-    volatile android::dvr::DisplaySurfaceMetadata* data =
-        graphics_context->surface_metadata;
+    volatile DisplaySurfaceMetadata* data = graphics_context->surface_metadata;
     uint32_t buffer_index =
         graphics_context->current_buffer->surface_buffer_index();
     ALOGE_IF(TRACE, "write pose index %d %f %f", buffer_index,
@@ -1244,6 +1323,7 @@ int dvrBeginRenderFrameEds(DvrGraphicsContext* graphics_context,
   CHECK_GL();
   return 0;
 }
+
 int dvrBeginRenderFrameEdsVk(DvrGraphicsContext* graphics_context,
                              float32x4_t render_pose_orientation,
                              float32x4_t render_pose_translation,
@@ -1421,7 +1501,7 @@ extern "C" void dvrGraphicsPostEarly(DvrGraphicsContext* graphics_context) {
 
     auto buffer = graphics_context->current_buffer->buffer().get();
     ATRACE_ASYNC_BEGIN("BufferPost", buffer->id());
-    int result = buffer->Post<uint64_t>(LocalHandle(), 0);
+    int result = buffer->Post<void>(LocalHandle());
     if (result < 0)
       ALOGE("Buffer post failed: %d (%s)", result, strerror(-result));
   }
@@ -1452,7 +1532,7 @@ int dvrPresent(DvrGraphicsContext* graphics_context) {
   ATRACE_ASYNC_END("BufferDraw", buffer->id());
   if (!graphics_context->buffer_already_posted) {
     ATRACE_ASYNC_BEGIN("BufferPost", buffer->id());
-    int result = buffer->Post<uint64_t>(fence_fd, 0);
+    int result = buffer->Post<void>(fence_fd);
     if (result < 0)
       ALOGE("Buffer post failed: %d (%s)", result, strerror(-result));
   }
@@ -1515,7 +1595,7 @@ extern "C" void dvrGraphicsSurfaceSetVisible(
 
 extern "C" int dvrGraphicsSurfaceGetVisible(
     DvrGraphicsContext* graphics_context) {
-  return graphics_context->display_surface->visible() ? 1 : 0;
+  return !!graphics_context->display_surface->visible();
 }
 
 extern "C" void dvrGraphicsSurfaceSetZOrder(
@@ -1527,4 +1607,3 @@ extern "C" int dvrGraphicsSurfaceGetZOrder(
     DvrGraphicsContext* graphics_context) {
   return graphics_context->display_surface->z_order();
 }
-
diff --git a/libs/vr/libdisplay/include/dvr/dvr_display_types.h b/libs/vr/libdisplay/include/dvr/dvr_display_types.h
new file mode 100644 (file)
index 0000000..25364d8
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef ANDROID_DVR_DISPLAY_TYPES_H_
+#define ANDROID_DVR_DISPLAY_TYPES_H_
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+// Define types used in pose buffer fields. These types have atomicity
+// guarantees that are useful in lock-free shared memory ring buffers.
+#ifdef __ARM_NEON
+#include <arm_neon.h>
+#else
+#ifndef __FLOAT32X4T_86
+#define __FLOAT32X4T_86
+typedef float float32x4_t __attribute__((__vector_size__(16)));
+typedef struct float32x4x4_t { float32x4_t val[4]; };
+#endif
+#endif
+
+// VrFlinger display manager surface state snapshots per surface flags
+// indicating what changed since the last snapshot.
+enum {
+  // No changes.
+  DVR_SURFACE_UPDATE_FLAGS_NONE = 0,
+  // This surface is new.
+  DVR_SURFACE_UPDATE_FLAGS_NEW_SURFACE = (1 << 0),
+  // Buffer queues added/removed.
+  DVR_SURFACE_UPDATE_FLAGS_BUFFERS_CHANGED = (1 << 1),
+  // Visibility/z-order changed.
+  DVR_SURFACE_UPDATE_FLAGS_VISIBILITY_CHANGED = (1 << 2),
+  // Generic attributes changed.
+  DVR_SURFACE_UPDATE_FLAGS_ATTRIBUTES_CHANGED = (1 << 3),
+};
+
+// Surface attribute keys. VrFlinger defines keys in the negative integer space.
+// The compositor is free to use keys in the positive integer space for
+// implementation-defined purposes.
+enum {
+  // DIRECT: bool
+  // Determines whether a direct surface is created (compositor output) or an
+  // application surface. Defaults to false (application surface). May only be
+  // set to true by a process with either UID=root or UID validated with
+  // IsTrustedUid() (VrCore).
+  DVR_SURFACE_ATTRIBUTE_DIRECT = -3,
+  // Z_ORDER: int32_t
+  // Interpreted by VrFlinger only on direct surfaces to order the corresponding
+  // hardware layers. More positive values render on top of more negative
+  // values.
+  DVR_SURFACE_ATTRIBUTE_Z_ORDER = -2,
+  // VISIBLE: bool
+  // Interpreted by VrFlinger only on direct surfaces to determine whether a
+  // surface is assigned to a hardware layer or ignored.
+  DVR_SURFACE_ATTRIBUTE_VISIBLE = -1,
+  // INVALID
+  // Invalid key. No attributes should have this key.
+  DVR_SURFACE_ATTRIBUTE_INVALID = 0,
+  // FIRST_USER_KEY
+  // VrFlinger ingores any keys with this value or greater, passing them to the
+  // compositor through surface state query results.
+  DVR_SURFACE_ATTRIBUTE_FIRST_USER_KEY = 1,
+};
+
+__END_DECLS
+
+#endif  // ANDROID_DVR_DISPLAY_TYPES_H_
index ac8b27f..c83a698 100644 (file)
@@ -9,7 +9,7 @@
 #else
 #ifndef __FLOAT32X4T_86
 #define __FLOAT32X4T_86
-typedef float float32x4_t __attribute__ ((__vector_size__ (16)));
+typedef float float32x4_t __attribute__((__vector_size__(16)));
 typedef struct float32x4x4_t { float32x4_t val[4]; };
 #endif
 #endif
@@ -112,6 +112,10 @@ enum {
   // VK_SWAPCHAIN_IMAGE_FORMAT: In Vulkan mode, the VkFormat of the swapchain
   // images will be returned here.
   DVR_SURFACE_PARAMETER_VK_SWAPCHAIN_IMAGE_FORMAT_OUT,
+  // DIRECT: Whether the surface goes directly to the display or to the
+  // compositor. Default is 0 (compositor). Only processes with either uid=root
+  // (test tools) or uid validated by IsTrustedUid() may set this to 1.
+  DVR_SURFACE_PARAMETER_DIRECT_IN,
 };
 
 enum {
@@ -439,8 +443,7 @@ void dvrGraphicsVideoMeshSurfaceDestroy(DvrVideoMeshSurface* surface);
 // Present a VideoMeshSurface with the current video mesh transfromation matrix.
 void dvrGraphicsVideoMeshSurfacePresent(DvrGraphicsContext* graphics_context,
                                         DvrVideoMeshSurface* surface,
-                                        const int eye,
-                                        const float* transform);
+                                        const int eye, const float* transform);
 
 __END_DECLS
 
index cec62af..668532d 100644 (file)
 
 namespace android {
 namespace dvr {
+namespace display {
 
-struct LateLatchOutput;
-
-// Abstract base class for all surface types maintained in DVR's display
-// service.
-// TODO(jwcai) Explain more, surface is a channel...
-class SurfaceClient : public pdx::Client {
+class Surface : public pdx::ClientBase<Surface> {
  public:
-  using LocalChannelHandle = pdx::LocalChannelHandle;
-  SurfaceType type() const { return type_; }
-
-  // Get the shared memory metadata buffer fd for this display surface. If it is
-  // not yet allocated, this will allocate it.
-  int GetMetadataBufferFd(pdx::LocalHandle* out_fd);
-
-  // Allocate the single metadata buffer for providing metadata associated with
-  // posted buffers for this surface. This can be used to provide rendered poses
-  // for EDS, for example. The buffer format is defined by the struct
-  // DisplaySurfaceMetadata.
-  // The first call to this method will allocate the buffer in via IPC to the
-  // display surface.
-  std::shared_ptr<BufferProducer> GetMetadataBuffer();
-
- protected:
-  SurfaceClient(LocalChannelHandle channel_handle, SurfaceType type);
-  SurfaceClient(const std::string& endpoint_path, SurfaceType type);
-
- private:
-  SurfaceType type_;
-  std::shared_ptr<BufferProducer> metadata_buffer_;
-};
-
-// DisplaySurfaceClient represents the client interface to a displayd display
-// surface.
-class DisplaySurfaceClient
-    : public pdx::ClientBase<DisplaySurfaceClient, SurfaceClient> {
- public:
-  using LocalHandle = pdx::LocalHandle;
-
-  int width() const { return width_; }
-  int height() const { return height_; }
-  int format() const { return format_; }
-  int usage() const { return usage_; }
-  int flags() const { return flags_; }
+  // Utility named constructor. This can be removed once ClientBase::Create is
+  // refactored to return Status<T> types.
+  static pdx::Status<std::unique_ptr<Surface>> CreateSurface(
+      const SurfaceAttributes& attributes) {
+    int error;
+    pdx::Status<std::unique_ptr<Surface>> status;
+    if (auto surface = Create(attributes, &error))
+      status.SetValue(std::move(surface));
+    else
+      status.SetError(error);
+    return status;
+  }
+
+  int surface_id() const { return surface_id_; }
   int z_order() const { return z_order_; }
   bool visible() const { return visible_; }
 
-  void SetVisible(bool visible);
-  void SetZOrder(int z_order);
-  void SetExcludeFromBlur(bool exclude_from_blur);
-  void SetBlurBehind(bool blur_behind);
-  void SetAttributes(const DisplaySurfaceAttributes& attributes);
+  pdx::Status<void> SetVisible(bool visible);
+  pdx::Status<void> SetZOrder(int z_order);
+  pdx::Status<void> SetAttributes(const SurfaceAttributes& attributes);
 
-  // Get the producer end of the buffer queue that transports graphics buffer
-  // from the application side to the compositor side.
-  std::shared_ptr<ProducerQueue> GetProducerQueue();
+  // Creates an empty queue.
+  pdx::Status<std::unique_ptr<ProducerQueue>> CreateQueue();
 
-  // Get the shared memory metadata buffer for this display surface. If it is
-  // not yet allocated, this will allocate it.
-  volatile DisplaySurfaceMetadata* GetMetadataBufferPtr();
-
-  // Create a VideoMeshSurface that is attached to the display sruface.
-  LocalChannelHandle CreateVideoMeshSurface();
+  // Creates a queue and populates it with |capacity| buffers of the specified
+  // parameters.
+  pdx::Status<std::unique_ptr<ProducerQueue>> CreateQueue(uint32_t width,
+                                                          uint32_t height,
+                                                          uint32_t format,
+                                                          uint64_t usage,
+                                                          size_t capacity);
 
  private:
   friend BASE;
 
-  DisplaySurfaceClient(int width, int height, int format, int usage, int flags);
-
-  int width_;
-  int height_;
-  int format_;
-  int usage_;
-  int flags_;
-  int z_order_;
-  bool visible_;
-  bool exclude_from_blur_;
-  bool blur_behind_;
-  DisplaySurfaceMetadata* mapped_metadata_buffer_;
+  int surface_id_ = -1;
+  int z_order_ = 0;
+  bool visible_ = false;
 
-  // TODO(jwcai) Add support for multiple queues.
-  std::shared_ptr<ProducerQueue> producer_queue_;
+  // TODO(eieio,avakulenko): Remove error param once pdx::ClientBase::Create()
+  // returns Status<T>.
+  explicit Surface(const SurfaceAttributes& attributes, int* error = nullptr);
+  explicit Surface(pdx::LocalChannelHandle channel_handle,
+                   int* error = nullptr);
 
-  DisplaySurfaceClient(const DisplaySurfaceClient&) = delete;
-  void operator=(const DisplaySurfaceClient&) = delete;
+  Surface(const Surface&) = delete;
+  void operator=(const Surface&) = delete;
 };
 
 class DisplayClient : public pdx::ClientBase<DisplayClient> {
  public:
-  int GetDisplayMetrics(SystemDisplayMetrics* metrics);
-  pdx::Status<void> SetViewerParams(const ViewerParams& viewer_params);
-
-  // Pull the latest eds pose data from the display service renderer
-  int GetLastFrameEdsTransform(LateLatchOutput* ll_out);
-
-  std::unique_ptr<DisplaySurfaceClient> CreateDisplaySurface(
-      int width, int height, int format, int usage, int flags);
-
-  std::unique_ptr<IonBuffer> GetNamedBuffer(const std::string& name);
+  pdx::Status<Metrics> GetDisplayMetrics();
+  pdx::Status<std::unique_ptr<IonBuffer>> GetNamedBuffer(
+      const std::string& name);
+  pdx::Status<std::unique_ptr<Surface>> CreateSurface(
+      const SurfaceAttributes& attributes);
 
   // Temporary query for current VR status. Will be removed later.
-  bool IsVrAppRunning();
+  pdx::Status<bool> IsVrAppRunning();
 
  private:
   friend BASE;
@@ -122,6 +83,7 @@ class DisplayClient : public pdx::ClientBase<DisplayClient> {
   void operator=(const DisplayClient&) = delete;
 };
 
+}  // namespace display
 }  // namespace dvr
 }  // namespace android
 
index fb2abeb..fea8415 100644 (file)
@@ -1,28 +1,39 @@
 #ifndef ANDROID_DVR_DISPLAY_MANAGER_CLIENT_H_
 #define ANDROID_DVR_DISPLAY_MANAGER_CLIENT_H_
 
+#include <string>
 #include <vector>
 
 #include <pdx/client.h>
+#include <pdx/status.h>
 #include <private/dvr/display_protocol.h>
 
 namespace android {
 namespace dvr {
 
-class BufferProducer;
+class IonBuffer;
+class ConsumerQueue;
+
+namespace display {
 
 class DisplayManagerClient : public pdx::ClientBase<DisplayManagerClient> {
  public:
   ~DisplayManagerClient() override;
 
-  int GetSurfaceList(std::vector<DisplaySurfaceInfo>* surface_list);
-
-  std::unique_ptr<IonBuffer> SetupNamedBuffer(const std::string& name,
-                                              size_t size,
-                                              uint64_t usage);
+  pdx::Status<std::vector<SurfaceState>> GetSurfaceState();
+  pdx::Status<std::unique_ptr<IonBuffer>> SetupNamedBuffer(
+      const std::string& name, size_t size, uint64_t usage);
+  pdx::Status<std::unique_ptr<ConsumerQueue>> GetSurfaceQueue(int surface_id,
+                                                              int queue_id);
 
   using Client::event_fd;
-  using Client::GetChannel;
+
+  pdx::Status<int> GetEventMask(int events) {
+    if (auto* client_channel = GetChannel())
+      return client_channel->GetEventMask(events);
+    else
+      return pdx::ErrorStatus(EINVAL);
+  }
 
  private:
   friend BASE;
@@ -33,6 +44,7 @@ class DisplayManagerClient : public pdx::ClientBase<DisplayManagerClient> {
   void operator=(const DisplayManagerClient&) = delete;
 };
 
+}  // namespace display
 }  // namespace dvr
 }  // namespace android
 
index d0b57e4..f34d61f 100644 (file)
 #include <array>
 #include <map>
 
+#include <dvr/dvr_display_types.h>
+
 #include <pdx/rpc/remote_method.h>
 #include <pdx/rpc/serializable.h>
 #include <pdx/rpc/variant.h>
 #include <private/dvr/bufferhub_rpc.h>
-#include <private/dvr/display_types.h>
+
+// RPC protocol definitions for DVR display services (VrFlinger).
 
 namespace android {
 namespace dvr {
+namespace display {
 
-struct SystemDisplayMetrics {
-  uint32_t display_native_width;
-  uint32_t display_native_height;
+// Native display metrics.
+struct Metrics {
+  // Basic display properties.
+  uint32_t display_width;
+  uint32_t display_height;
   uint32_t display_x_dpi;
   uint32_t display_y_dpi;
+  uint32_t vsync_period_ns;
+
+  // HMD metrics.
+  // TODO(eieio): Determine how these fields should be populated. On phones
+  // these values are determined at runtime by VrCore based on which headset the
+  // phone is in. On dedicated hardware this needs to come from somewhere else.
+  // Perhaps these should be moved to a separate structure that is returned by a
+  // separate runtime call.
   uint32_t distorted_width;
   uint32_t distorted_height;
-  uint32_t vsync_period_ns;
   uint32_t hmd_ipd_mm;
   float inter_lens_distance_m;
   std::array<float, 4> left_fov_lrbt;
   std::array<float, 4> right_fov_lrbt;
 
  private:
-  PDX_SERIALIZABLE_MEMBERS(SystemDisplayMetrics, display_native_width,
-                           display_native_height, display_x_dpi, display_y_dpi,
-                           distorted_width, distorted_height, vsync_period_ns,
-                           hmd_ipd_mm, inter_lens_distance_m, left_fov_lrbt,
+  PDX_SERIALIZABLE_MEMBERS(Metrics, display_width, display_height,
+                           display_x_dpi, display_y_dpi, vsync_period_ns,
+                           distorted_width, distorted_height, hmd_ipd_mm,
+                           inter_lens_distance_m, left_fov_lrbt,
                            right_fov_lrbt);
 };
 
-using SurfaceType = uint32_t;
-struct SurfaceTypeEnum {
-  enum : SurfaceType {
-    Normal = DVR_SURFACE_TYPE_NORMAL,
-    VideoMesh = DVR_SURFACE_TYPE_VIDEO_MESH,
-    Overlay = DVR_SURFACE_TYPE_OVERLAY,
-  };
-};
-
-using DisplaySurfaceFlags = uint32_t;
-enum class DisplaySurfaceFlagsEnum : DisplaySurfaceFlags {
-  DisableSystemEds = DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_EDS,
-  DisableSystemDistortion = DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION,
-  VerticalFlip = DVR_DISPLAY_SURFACE_FLAGS_VERTICAL_FLIP,
-  SeparateGeometry = DVR_DISPLAY_SURFACE_FLAGS_GEOMETRY_SEPARATE_2,
-  DisableSystemCac = DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_CAC,
-};
+// Serializable base type for enum structs. Enum structs are easier to use than
+// enum classes, especially for bitmasks. This base type provides common
+// utilities for flags types.
+template <typename Integer>
+class Flags {
+ public:
+  using Base = Flags<Integer>;
+  using Type = Integer;
 
-using DisplaySurfaceInfoFlags = uint32_t;
-enum class DisplaySurfaceInfoFlagsEnum : DisplaySurfaceInfoFlags {
-  BuffersChanged = DVR_DISPLAY_SURFACE_ITEM_FLAGS_BUFFERS_CHANGED,
-};
+  Flags(const Integer& value) : value_{value} {}
+  Flags(const Flags&) = default;
+  Flags& operator=(const Flags&) = default;
 
-using DisplaySurfaceAttributeValue =
-    pdx::rpc::Variant<int32_t, int64_t, bool, float, std::array<float, 2>,
-                      std::array<float, 3>, std::array<float, 4>,
-                      std::array<float, 16>>;
-using DisplaySurfaceAttribute = uint32_t;
-struct DisplaySurfaceAttributeEnum {
-  enum : DisplaySurfaceAttribute {
-    ZOrder = DVR_DISPLAY_SURFACE_ATTRIBUTE_Z_ORDER,
-    Visible = DVR_DISPLAY_SURFACE_ATTRIBUTE_VISIBLE,
-    // Manager only.
-    Blur = DVR_DISPLAY_SURFACE_ATTRIBUTE_BLUR,
-    // Client only.
-    ExcludeFromBlur = DVR_DISPLAY_SURFACE_ATTRIBUTE_EXCLUDE_FROM_BLUR,
-    BlurBehind = DVR_DISPLAY_SURFACE_ATTRIBUTE_BLUR_BEHIND,
-  };
+  Integer value() const { return value_; }
+  operator Integer() const { return value_; }
 
-  static std::string ToString(DisplaySurfaceAttribute attribute) {
-    switch (attribute) {
-      case ZOrder:
-        return "z-order";
-      case Visible:
-        return "visible";
-      case Blur:
-        return "blur";
-      case ExcludeFromBlur:
-        return "exclude-from-blur";
-      case BlurBehind:
-        return "blur-behind";
-      default:
-        return "unknown";
-    }
-  }
-};
+  bool IsSet(Integer bits) const { return (value_ & bits) == bits; }
+  bool IsClear(Integer bits) const { return (value_ & bits) == 0; }
 
-using DisplaySurfaceAttributes =
-    std::map<DisplaySurfaceAttribute, DisplaySurfaceAttributeValue>;
+  void Set(Integer bits) { value_ |= bits; }
+  void Clear(Integer bits) { value_ &= ~bits; }
 
-struct DisplaySurfaceInfo {
-  int surface_id;
-  int process_id;
-  SurfaceType type;
-  DisplaySurfaceFlags flags;
-  DisplaySurfaceInfoFlags info_flags;
-  DisplaySurfaceAttributes client_attributes;
-  DisplaySurfaceAttributes manager_attributes;
+  Integer operator|(Integer bits) const { return value_ | bits; }
+  Integer operator&(Integer bits) const { return value_ & bits; }
 
-  // Convenience accessors.
-  bool IsClientVisible() const {
-    const auto* variant =
-        FindClientAttribute(DisplaySurfaceAttributeEnum::Visible);
-    bool bool_value;
-    if (variant && pdx::rpc::IfAnyOf<int32_t, int64_t, bool, float>::Get(
-                       variant, &bool_value))
-      return bool_value;
-    else
-      return false;
+  Flags& operator|=(Integer bits) {
+    value_ |= bits;
+    return *this;
   }
-
-  int ClientZOrder() const {
-    const auto* variant =
-        FindClientAttribute(DisplaySurfaceAttributeEnum::ZOrder);
-    int int_value;
-    if (variant &&
-        pdx::rpc::IfAnyOf<int32_t, int64_t, float>::Get(variant, &int_value))
-      return int_value;
-    else
-      return 0;
+  Flags& operator&=(Integer bits) {
+    value_ &= bits;
+    return *this;
   }
 
  private:
-  const DisplaySurfaceAttributeValue* FindClientAttribute(
-      DisplaySurfaceAttribute key) const {
-    auto search = client_attributes.find(key);
-    return (search != client_attributes.end()) ? &search->second : nullptr;
-  }
+  Integer value_;
 
-  PDX_SERIALIZABLE_MEMBERS(DisplaySurfaceInfo, surface_id, process_id, type,
-                           flags, info_flags, client_attributes,
-                           manager_attributes);
+  PDX_SERIALIZABLE_MEMBERS(Flags<Integer>, value_);
 };
 
-struct AlignmentMarker {
- public:
-  float horizontal;
-  float vertical;
+// Flags indicating what changed since last update.
+struct SurfaceUpdateFlags : public Flags<uint32_t> {
+  enum : Type {
+    None = DVR_SURFACE_UPDATE_FLAGS_NONE,
+    NewSurface = DVR_SURFACE_UPDATE_FLAGS_NEW_SURFACE,
+    BuffersChanged = DVR_SURFACE_UPDATE_FLAGS_BUFFERS_CHANGED,
+    VisibilityChanged = DVR_SURFACE_UPDATE_FLAGS_VISIBILITY_CHANGED,
+    AttributesChanged = DVR_SURFACE_UPDATE_FLAGS_ATTRIBUTES_CHANGED,
+  };
 
-  PDX_SERIALIZABLE_MEMBERS(AlignmentMarker, horizontal, vertical);
+  SurfaceUpdateFlags() : Base{None} {}
+  using Base::Base;
 };
 
-struct DaydreamInternalParams {
- public:
-  int32_t version;
-  std::vector<AlignmentMarker> alignment_markers;
+// Surface attribute key/value types.
+using SurfaceAttributeKey = int32_t;
+using SurfaceAttributeValue =
+    pdx::rpc::Variant<int32_t, int64_t, bool, float, std::array<float, 2>,
+                      std::array<float, 3>, std::array<float, 4>,
+                      std::array<float, 8>, std::array<float, 16>>;
+
+// Defined surface attribute keys.
+struct SurfaceAttribute : public Flags<SurfaceAttributeKey> {
+  enum : Type {
+    // Keys in the negative integer space are interpreted by VrFlinger for
+    // direct surfaces.
+    Direct = DVR_SURFACE_ATTRIBUTE_DIRECT,
+    ZOrder = DVR_SURFACE_ATTRIBUTE_Z_ORDER,
+    Visible = DVR_SURFACE_ATTRIBUTE_VISIBLE,
+
+    // Invalid key. May be used to terminate C style lists in public API code.
+    Invalid = DVR_SURFACE_ATTRIBUTE_INVALID,
+
+    // Positive keys are interpreted by the compositor only.
+    FirstUserKey = DVR_SURFACE_ATTRIBUTE_FIRST_USER_KEY,
+  };
 
-  PDX_SERIALIZABLE_MEMBERS(DaydreamInternalParams, version, alignment_markers);
+  SurfaceAttribute() : Base{Invalid} {}
+  using Base::Base;
 };
 
-struct ViewerParams {
- public:
-  // TODO(hendrikw): Do we need viewer_vendor_name and viewer_model_name?
-  float screen_to_lens_distance;
-  float inter_lens_distance;
-  float screen_center_to_lens_distance;
-  std::vector<float> left_eye_field_of_view_angles;
-
-  enum VerticalAlignmentType : int32_t {
-    BOTTOM = 0,  // phone rests against a fixed bottom tray
-    CENTER = 1,  // phone screen assumed to be centered w.r.t. lenses
-    TOP = 2      // phone rests against a fixed top tray
-  };
+// Collection of surface attribute key/value pairs.
+using SurfaceAttributes = std::map<SurfaceAttributeKey, SurfaceAttributeValue>;
 
-  enum EyeOrientation : int32_t {
-    kCCW0Degrees = 0,
-    kCCW90Degrees = 1,
-    kCCW180Degrees = 2,
-    kCCW270Degrees = 3,
-    kCCW0DegreesMirrored = 4,
-    kCCW90DegreesMirrored = 5,
-    kCCW180DegreesMirrored = 6,
-    kCCW270DegreesMirrored = 7
-  };
+struct SurfaceState {
+  int32_t surface_id;
+  int32_t process_id;
+  int32_t user_id;
 
-  VerticalAlignmentType vertical_alignment;
-  std::vector<EyeOrientation> eye_orientations;
+  SurfaceAttributes surface_attributes;
+  SurfaceUpdateFlags update_flags;
+  std::vector<int32_t> queue_ids;
 
-  float tray_to_lens_distance;
+  // Convenience accessors.
+  bool GetVisible() const {
+    bool bool_value = false;
+    GetAttribute(SurfaceAttribute::Visible, &bool_value,
+                 ValidTypes<int32_t, int64_t, bool, float>{});
+    return bool_value;
+  }
+
+  int GetZOrder() const {
+    int int_value = 0;
+    GetAttribute(SurfaceAttribute::ZOrder, &int_value,
+                 ValidTypes<int32_t, int64_t, float>{});
+    return int_value;
+  }
+
+ private:
+  template <typename... Types>
+  struct ValidTypes {};
+
+  template <typename ReturnType, typename... Types>
+  bool GetAttribute(SurfaceAttributeKey key, ReturnType* out_value,
+                    ValidTypes<Types...>) const {
+    auto search = surface_attributes.find(key);
+    if (search != surface_attributes.end())
+      return pdx::rpc::IfAnyOf<Types...>::Get(&search->second, out_value);
+    else
+      return false;
+  }
 
-  std::vector<float> distortion_coefficients_r;
-  std::vector<float> distortion_coefficients_g;
-  std::vector<float> distortion_coefficients_b;
+  PDX_SERIALIZABLE_MEMBERS(SurfaceState, surface_id, process_id,
+                           surface_attributes, update_flags, queue_ids);
+};
 
-  DaydreamInternalParams daydream_internal;
+struct SurfaceInfo {
+  int surface_id;
+  bool visible;
+  int z_order;
 
-  PDX_SERIALIZABLE_MEMBERS(ViewerParams, screen_to_lens_distance,
-                           inter_lens_distance, screen_center_to_lens_distance,
-                           left_eye_field_of_view_angles, vertical_alignment,
-                           eye_orientations, tray_to_lens_distance,
-                           distortion_coefficients_r, distortion_coefficients_g,
-                           distortion_coefficients_b, daydream_internal);
+ private:
+  PDX_SERIALIZABLE_MEMBERS(SurfaceInfo, surface_id, visible, z_order);
 };
 
-struct DisplayRPC {
+struct DisplayProtocol {
   // Service path.
   static constexpr char kClientPath[] = "system/vr/display/client";
 
   // Op codes.
   enum {
     kOpGetMetrics = 0,
-    kOpGetEdsCapture,
-    kOpCreateSurface,
-    kOpCreateBufferQueue,
-    kOpSetAttributes,
-    kOpGetMetadataBuffer,
-    kOpCreateVideoMeshSurface,
-    kOpVideoMeshSurfaceCreateProducerQueue,
-    kOpSetViewerParams,
     kOpGetNamedBuffer,
     kOpIsVrAppRunning,
+    kOpCreateSurface,
+    kOpGetSurfaceInfo,
+    kOpCreateQueue,
+    kOpSetAttributes,
   };
 
   // Aliases.
-  using ByteBuffer = pdx::rpc::BufferWrapper<std::vector<uint8_t>>;
   using LocalChannelHandle = pdx::LocalChannelHandle;
   using Void = pdx::rpc::Void;
 
   // Methods.
-  PDX_REMOTE_METHOD(GetMetrics, kOpGetMetrics, SystemDisplayMetrics(Void));
-  PDX_REMOTE_METHOD(GetEdsCapture, kOpGetEdsCapture, ByteBuffer(Void));
+  PDX_REMOTE_METHOD(GetMetrics, kOpGetMetrics, Metrics(Void));
+  PDX_REMOTE_METHOD(GetNamedBuffer, kOpGetNamedBuffer,
+                    LocalNativeBufferHandle(std::string name));
+  PDX_REMOTE_METHOD(IsVrAppRunning, kOpIsVrAppRunning, bool(Void));
   PDX_REMOTE_METHOD(CreateSurface, kOpCreateSurface,
-                    int(int width, int height, int format, int usage,
-                        DisplaySurfaceFlags flags));
-  PDX_REMOTE_METHOD(CreateBufferQueue, kOpCreateBufferQueue,
-                    LocalChannelHandle(Void));
+                    SurfaceInfo(const SurfaceAttributes& attributes));
+  PDX_REMOTE_METHOD(GetSurfaceInfo, kOpGetSurfaceInfo, SurfaceInfo(Void));
+  PDX_REMOTE_METHOD(CreateQueue, kOpCreateQueue,
+                    LocalChannelHandle(size_t meta_size_bytes));
   PDX_REMOTE_METHOD(SetAttributes, kOpSetAttributes,
-                    int(const DisplaySurfaceAttributes& attributes));
-  PDX_REMOTE_METHOD(GetMetadataBuffer, kOpGetMetadataBuffer,
-                    LocalChannelHandle(Void));
-  // VideoMeshSurface methods
-  PDX_REMOTE_METHOD(CreateVideoMeshSurface, kOpCreateVideoMeshSurface,
-                    LocalChannelHandle(Void));
-  PDX_REMOTE_METHOD(VideoMeshSurfaceCreateProducerQueue,
-                    kOpVideoMeshSurfaceCreateProducerQueue,
-                    LocalChannelHandle(Void));
-  PDX_REMOTE_METHOD(SetViewerParams, kOpSetViewerParams,
-                    void(const ViewerParams& viewer_params));
-  PDX_REMOTE_METHOD(GetNamedBuffer, kOpGetNamedBuffer,
-                    LocalNativeBufferHandle(const std::string& name));
-  PDX_REMOTE_METHOD(IsVrAppRunning, kOpIsVrAppRunning, int(Void));
+                    void(const SurfaceAttributes& attributes));
 };
 
-struct DisplayManagerRPC {
+struct DisplayManagerProtocol {
   // Service path.
   static constexpr char kClientPath[] = "system/vr/display/manager";
 
   // Op codes.
   enum {
-    kOpGetSurfaceList = 0,
-    kOpUpdateSurfaces,
+    kOpGetSurfaceState = 0,
+    kOpGetSurfaceQueue,
     kOpSetupNamedBuffer,
   };
 
@@ -265,42 +233,15 @@ struct DisplayManagerRPC {
   using Void = pdx::rpc::Void;
 
   // Methods.
-  PDX_REMOTE_METHOD(GetSurfaceList, kOpGetSurfaceList,
-                    std::vector<DisplaySurfaceInfo>(Void));
-  PDX_REMOTE_METHOD(
-      UpdateSurfaces, kOpUpdateSurfaces,
-      int(const std::map<int, DisplaySurfaceAttributes>& updates));
+  PDX_REMOTE_METHOD(GetSurfaceState, kOpGetSurfaceState,
+                    std::vector<SurfaceState>(Void));
+  PDX_REMOTE_METHOD(GetSurfaceQueue, kOpGetSurfaceQueue,
+                    LocalChannelHandle(int surface_id, int queue_id));
   PDX_REMOTE_METHOD(SetupNamedBuffer, kOpSetupNamedBuffer,
                     LocalNativeBufferHandle(const std::string& name,
                                             size_t size, uint64_t usage));
 };
 
-struct ScreenshotData {
-  int width;
-  int height;
-  std::vector<uint8_t> buffer;
-
- private:
-  PDX_SERIALIZABLE_MEMBERS(ScreenshotData, width, height, buffer);
-};
-
-struct DisplayScreenshotRPC {
-  // Service path.
-  static constexpr char kClientPath[] = "system/vr/display/screenshot";
-
-  // Op codes.
-  enum {
-    kOpGetFormat = 0,
-    kOpTakeScreenshot,
-  };
-
-  using Void = pdx::rpc::Void;
-
-  PDX_REMOTE_METHOD(GetFormat, kOpGetFormat, int(Void));
-  PDX_REMOTE_METHOD(TakeScreenshot, kOpTakeScreenshot,
-                    ScreenshotData(int layer_index));
-};
-
 struct VSyncSchedInfo {
   int64_t vsync_period_ns;
   int64_t timestamp_ns;
@@ -311,7 +252,7 @@ struct VSyncSchedInfo {
                            next_vsync_count);
 };
 
-struct DisplayVSyncRPC {
+struct VSyncProtocol {
   // Service path.
   static constexpr char kClientPath[] = "system/vr/display/vsync";
 
@@ -332,9 +273,10 @@ struct DisplayVSyncRPC {
   PDX_REMOTE_METHOD(Wait, kOpWait, Timestamp(Void));
   PDX_REMOTE_METHOD(GetLastTimestamp, kOpGetLastTimestamp, Timestamp(Void));
   PDX_REMOTE_METHOD(GetSchedInfo, kOpGetSchedInfo, VSyncSchedInfo(Void));
-  PDX_REMOTE_METHOD(Acknowledge, kOpAcknowledge, int(Void));
+  PDX_REMOTE_METHOD(Acknowledge, kOpAcknowledge, void(Void));
 };
 
+}  // namespace display
 }  // namespace dvr
 }  // namespace android
 
diff --git a/libs/vr/libdisplay/include/private/dvr/display_types.h b/libs/vr/libdisplay/include/private/dvr/display_types.h
deleted file mode 100644 (file)
index 2bd02bd..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-#ifndef ANDROID_DVR_DISPLAY_TYPES_H_
-#define ANDROID_DVR_DISPLAY_TYPES_H_
-
-#ifdef __ARM_NEON
-#include <arm_neon.h>
-#else
-#ifndef __FLOAT32X4T_86
-#define __FLOAT32X4T_86
-typedef float float32x4_t __attribute__ ((__vector_size__ (16)));
-typedef struct float32x4x4_t { float32x4_t val[4]; };
-#endif
-#endif
-
-#include <cutils/native_handle.h>
-
-// DVR display-related data types.
-
-enum dvr_display_surface_type {
-  // Normal display surface meant to be used by applications' GL context to
-  // render into.
-  DVR_SURFACE_TYPE_NORMAL = 0,
-
-  // VideoMeshSurface is used to composite video frames into the 3D world.
-  DVR_SURFACE_TYPE_VIDEO_MESH,
-
-  // System overlay surface type. This is not currently in use.
-  DVR_SURFACE_TYPE_OVERLAY,
-};
-
-enum dvr_display_surface_flags {
-  DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_EDS = (1 << 0),
-  DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION = (1 << 1),
-  DVR_DISPLAY_SURFACE_FLAGS_VERTICAL_FLIP = (1 << 2),
-  DVR_DISPLAY_SURFACE_FLAGS_GEOMETRY_SEPARATE_2 = (1 << 3),
-  DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_CAC = (1 << 4),
-};
-
-enum dvr_display_surface_item_flags {
-  DVR_DISPLAY_SURFACE_ITEM_FLAGS_BUFFERS_CHANGED = (1 << 0),
-};
-
-enum dvr_display_surface_attribute {
-  DVR_DISPLAY_SURFACE_ATTRIBUTE_Z_ORDER = (1<<0),
-  DVR_DISPLAY_SURFACE_ATTRIBUTE_VISIBLE = (1<<1),
-  DVR_DISPLAY_SURFACE_ATTRIBUTE_BLUR = (1<<2),
-  DVR_DISPLAY_SURFACE_ATTRIBUTE_EXCLUDE_FROM_BLUR = (1<<3),
-  DVR_DISPLAY_SURFACE_ATTRIBUTE_BLUR_BEHIND = (1<<4),
-};
-
-// Maximum number of buffers for a surface. Each buffer represents a single
-// frame and may actually be a buffer array if multiview rendering is in use.
-// Define so that it can be used in shader code.
-#define kSurfaceBufferMaxCount 4
-
-// Maximum number of views per surface. Each eye is a view, for example.
-#define kSurfaceViewMaxCount 4
-
-namespace android {
-namespace dvr {
-
-struct __attribute__((packed, aligned(16))) DisplaySurfaceMetadata {
-  // Array of orientations and translations corresponding with surface buffers.
-  // The index is associated with each allocated buffer by DisplaySurface and
-  // communicated to clients.
-  // The maximum number of buffers is hard coded here as 4 so that we can bind
-  // this data structure in GPU shaders.
-  float32x4_t orientation[kSurfaceBufferMaxCount];
-  float32x4_t translation[kSurfaceBufferMaxCount];
-};
-
-struct __attribute__((packed, aligned(16))) VideoMeshSurfaceMetadata {
-  // Array of transform matrices corresponding with surface buffers.
-  // Note that The index is associated with each allocated buffer by
-  // DisplaySurface instead of VideoMeshSurface due to the fact that the
-  // metadata here is interpreted as video mesh's transformation in each
-  // application's rendering frame.
-  float32x4x4_t transform[4][2];
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_DISPLAY_TYPES_H_
index 57c99da..a08b0df 100644 (file)
@@ -17,6 +17,19 @@ typedef struct float32x4x4_t { float32x4_t val[4]; };
 
 __BEGIN_DECLS
 
+#define kSurfaceBufferMaxCount 4
+#define kSurfaceViewMaxCount 4
+
+struct __attribute__((packed, aligned(16))) DisplaySurfaceMetadata {
+  // Array of orientations and translations corresponding with surface buffers.
+  // The index is associated with each allocated buffer by DisplaySurface and
+  // communicated to clients.
+  // The maximum number of buffers is hard coded here as 4 so that we can bind
+  // this data structure in GPU shaders.
+  float32x4_t orientation[kSurfaceBufferMaxCount];
+  float32x4_t translation[kSurfaceBufferMaxCount];
+};
+
 // Sets the pose used by the system for EDS. If dvrBeginRenderFrameEds() or
 // dvrBeginRenderFrameLateLatch() are called instead of dvrBeginRenderFrame()
 // it's not necessary to call this function. If this function is used, the call
index b7c5e4f..c91d15c 100644 (file)
@@ -5,11 +5,12 @@
 #include <thread>
 #include <vector>
 
+#include <dvr/dvr_display_types.h>
 #include <dvr/pose_client.h>
 #include <pdx/file_handle.h>
-#include <private/dvr/display_types.h>
 #include <private/dvr/graphics/shader_program.h>
 #include <private/dvr/graphics/vr_gl_extensions.h>
+#include <private/dvr/graphics_private.h>
 #include <private/dvr/types.h>
 
 struct DvrPose;
index 4b1fa98..a260f17 100644 (file)
 
 namespace android {
 namespace dvr {
+namespace display {
 
 // A wrapper over dvr::ProducerQueue that caches EGLImage.
 class NativeBufferQueue {
  public:
-  // Create a queue with the given number of free buffers.
   NativeBufferQueue(EGLDisplay display,
-                    const std::shared_ptr<DisplaySurfaceClient>& surface,
-                    size_t capacity);
+                    const std::shared_ptr<ProducerQueue>& producer_queue,
+                    uint32_t width, uint32_t height, uint32_t format,
+                    uint64_t usage, size_t capacity);
 
-  size_t GetQueueCapacity() const { return producer_queue_->capacity(); }
+  uint32_t width() const { return width_; }
+  uint32_t height() const { return height_; }
+  uint32_t format() const { return format_; }
+  uint64_t usage() const { return usage_; }
+  size_t capacity() const { return producer_queue_->capacity(); }
 
   // Dequeue a buffer from the free queue, blocking until one is available.
   NativeBufferProducer* Dequeue();
 
   // An noop here to keep Vulkan path in GraphicsContext happy.
   // TODO(jwcai, cort) Move Vulkan path into GVR/Google3.
-  void Enqueue(NativeBufferProducer* buffer) {}
+  void Enqueue(NativeBufferProducer* /*buffer*/) {}
 
  private:
   EGLDisplay display_;
+  uint32_t width_;
+  uint32_t height_;
+  uint32_t format_;
+  uint64_t usage_;
   std::shared_ptr<ProducerQueue> producer_queue_;
   std::vector<sp<NativeBufferProducer>> buffers_;
+
+  NativeBufferQueue(const NativeBufferQueue&) = delete;
+  void operator=(const NativeBufferQueue&) = delete;
 };
 
+}  // namespace display
 }  // namespace dvr
 }  // namespace android
 
index d516d63..762db32 100644 (file)
@@ -7,58 +7,59 @@
 
 #include <array>
 
-#include <private/dvr/display_types.h>
+#include <dvr/dvr_display_types.h>
 
 namespace android {
 namespace dvr {
+namespace display {
 
 NativeBufferQueue::NativeBufferQueue(
-    EGLDisplay display, const std::shared_ptr<DisplaySurfaceClient>& surface,
+    EGLDisplay display, const std::shared_ptr<ProducerQueue>& producer_queue,
+    uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
     size_t capacity)
-    : display_(display), buffers_(capacity) {
-  std::shared_ptr<ProducerQueue> queue = surface->GetProducerQueue();
-
+    : display_(display),
+      width_(width),
+      height_(height),
+      format_(format),
+      usage_(usage),
+      producer_queue_(producer_queue),
+      buffers_(capacity) {
   for (size_t i = 0; i < capacity; i++) {
     size_t slot;
     // TODO(jwcai) Should change to use BufferViewPort's spec to config.
-    int ret =
-        queue->AllocateBuffer(surface->width(), surface->height(),
-                              surface->format(), surface->usage(), 1, &slot);
+    const int ret = producer_queue_->AllocateBuffer(width_, height_, format_,
+                                                    usage_, 1, &slot);
     if (ret < 0) {
       ALOGE(
-          "NativeBufferQueue::NativeBufferQueue: Failed to allocate buffer, "
-          "error=%d",
-          ret);
+          "NativeBufferQueue::NativeBufferQueue: Failed to allocate buffer: %s",
+          strerror(-ret));
       return;
     }
 
-    ALOGD_IF(TRACE,
-             "NativeBufferQueue::NativeBufferQueue: New buffer allocated at "
-             "slot=%zu",
-             slot);
+    ALOGD_IF(TRACE, "NativeBufferQueue::NativeBufferQueue: slot=%zu", slot);
   }
-
-  producer_queue_ = std::move(queue);
 }
 
 NativeBufferProducer* NativeBufferQueue::Dequeue() {
   ATRACE_NAME("NativeBufferQueue::Dequeue");
-
-  // This never times out.
   size_t slot;
   pdx::LocalHandle fence;
-  std::shared_ptr<BufferProducer> buffer =
-      producer_queue_->Dequeue(-1, &slot, &fence);
-
-  if (buffers_[slot] == nullptr) {
-    buffers_[slot] = new NativeBufferProducer(buffer, display_, slot);
+  auto buffer_status = producer_queue_->Dequeue(-1, &slot, &fence);
+  if (!buffer_status) {
+    ALOGE("NativeBufferQueue::Dequeue: Failed to dequeue buffer: %s",
+          buffer_status.GetErrorMessage().c_str());
+    return nullptr;
   }
 
-  ALOGD_IF(TRACE,
-           "NativeBufferQueue::Dequeue: dequeue buffer at slot=%zu, buffer=%p",
-           slot, buffers_[slot].get());
+  if (buffers_[slot] == nullptr)
+    buffers_[slot] =
+        new NativeBufferProducer(buffer_status.take(), display_, slot);
+
+  ALOGD_IF(TRACE, "NativeBufferQueue::Dequeue: slot=%zu buffer=%p", slot,
+           buffers_[slot].get());
   return buffers_[slot].get();
 }
 
+}  // namespace display
 }  // namespace dvr
 }  // namespace android
index f51dd8a..c592ba9 100644 (file)
@@ -57,6 +57,8 @@ TEST(GraphicsAppTests, GraphicsContext) {
   dvrGraphicsContextCreate(surface_params, &context);
   EXPECT_NE(nullptr, context);
 
+  dvrGraphicsSurfaceSetVisible(context, 1);
+
   DvrFrameSchedule schedule;
   int wait_result = dvrGraphicsWaitNextFrame(context, 0, &schedule);
   EXPECT_EQ(wait_result, 0);
@@ -64,10 +66,10 @@ TEST(GraphicsAppTests, GraphicsContext) {
 
   dvrBeginRenderFrame(context);
 
-  // Check range of vsync period from 70fps to 100fps.
+  // Check range of vsync period from 60fps to 100fps.
   // TODO(jbates) Once we have stable hardware, clamp this range down further.
-  EXPECT_LT(vsync_period, 1000000000ul / 70ul);
-  EXPECT_GT(vsync_period, 1000000000ul / 100ul);
+  EXPECT_LE(vsync_period, 1000000000ul / 60ul);
+  EXPECT_GE(vsync_period, 1000000000ul / 100ul);
 
   dvrPresent(context);
   dvrGraphicsContextDestroy(context);
@@ -103,15 +105,3 @@ TEST(GraphicsAppTests, CustomSurfaceSize) {
   dvrGraphicsContextDestroy(context);
 }
 
-TEST(GraphicsAppTests, CreateVideoMeshSurface) {
-  DvrSurfaceParameter surface_params[] = {DVR_SURFACE_PARAMETER_LIST_END};
-  DvrGraphicsContext* context = nullptr;
-  int result = dvrGraphicsContextCreate(surface_params, &context);
-  EXPECT_NE(nullptr, context);
-  EXPECT_EQ(result, 0);
-
-  DvrVideoMeshSurface* surface = dvrGraphicsVideoMeshSurfaceCreate(context);
-  EXPECT_NE(nullptr, surface);
-
-  dvrGraphicsVideoMeshSurfaceDestroy(surface);
-}
index 2f6320c..bc6cf6c 100644 (file)
@@ -5,6 +5,7 @@
 #include <pdx/default_transport/client_channel_factory.h>
 #include <private/dvr/display_protocol.h>
 
+using android::dvr::display::VSyncProtocol;
 using android::pdx::Transaction;
 
 namespace android {
@@ -12,15 +13,15 @@ namespace dvr {
 
 VSyncClient::VSyncClient(long timeout_ms)
     : BASE(pdx::default_transport::ClientChannelFactory::Create(
-               DisplayVSyncRPC::kClientPath),
+               VSyncProtocol::kClientPath),
            timeout_ms) {}
 
 VSyncClient::VSyncClient()
     : BASE(pdx::default_transport::ClientChannelFactory::Create(
-          DisplayVSyncRPC::kClientPath)) {}
+          VSyncProtocol::kClientPath)) {}
 
 int VSyncClient::Wait(int64_t* timestamp_ns) {
-  auto status = InvokeRemoteMethod<DisplayVSyncRPC::Wait>();
+  auto status = InvokeRemoteMethod<VSyncProtocol::Wait>();
   if (!status) {
     ALOGE("VSyncClient::Wait: Failed to wait for vsync: %s",
           status.GetErrorMessage().c_str());
@@ -36,7 +37,7 @@ int VSyncClient::Wait(int64_t* timestamp_ns) {
 int VSyncClient::GetFd() { return event_fd(); }
 
 int VSyncClient::GetLastTimestamp(int64_t* timestamp_ns) {
-  auto status = InvokeRemoteMethod<DisplayVSyncRPC::GetLastTimestamp>();
+  auto status = InvokeRemoteMethod<VSyncProtocol::GetLastTimestamp>();
   if (!status) {
     ALOGE("VSyncClient::GetLastTimestamp: Failed to get vsync timestamp: %s",
           status.GetErrorMessage().c_str());
@@ -51,7 +52,7 @@ int VSyncClient::GetSchedInfo(int64_t* vsync_period_ns, int64_t* timestamp_ns,
   if (!vsync_period_ns || !timestamp_ns || !next_vsync_count)
     return -EINVAL;
 
-  auto status = InvokeRemoteMethod<DisplayVSyncRPC::GetSchedInfo>();
+  auto status = InvokeRemoteMethod<VSyncProtocol::GetSchedInfo>();
   if (!status) {
     ALOGE("VSyncClient::GetSchedInfo:: Failed to get warp timestamp: %s",
           status.GetErrorMessage().c_str());
@@ -65,7 +66,7 @@ int VSyncClient::GetSchedInfo(int64_t* vsync_period_ns, int64_t* timestamp_ns,
 }
 
 int VSyncClient::Acknowledge() {
-  auto status = InvokeRemoteMethod<DisplayVSyncRPC::Acknowledge>();
+  auto status = InvokeRemoteMethod<VSyncProtocol::Acknowledge>();
   ALOGE_IF(!status, "VSuncClient::Acknowledge: Failed to ack vsync because: %s",
            status.GetErrorMessage().c_str());
   return ReturnStatusOrError(status);
index aa4513e..2375b5a 100644 (file)
@@ -20,6 +20,7 @@ LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 
 LOCAL_CFLAGS += \
     -fvisibility=hidden \
+    -DLOG_TAG=\"libdvr\" \
     -D DVR_EXPORT='__attribute__ ((visibility ("default")))'
 
 LOCAL_C_INCLUDES := \
@@ -29,13 +30,13 @@ LOCAL_EXPORT_C_INCLUDE_DIRS := \
     $(LOCAL_PATH)/include \
 
 LOCAL_SRC_FILES := \
-    display_manager_client.cpp \
     dvr_api.cpp \
     dvr_buffer.cpp \
     dvr_buffer_queue.cpp \
+    dvr_display_manager.cpp \
     dvr_hardware_composer_client.cpp \
     dvr_surface.cpp \
-    vsync_client_api.cpp \
+    dvr_vsync.cpp \
 
 LOCAL_STATIC_LIBRARIES := \
     libbufferhub \
diff --git a/libs/vr/libdvr/display_manager_client.cpp b/libs/vr/libdvr/display_manager_client.cpp
deleted file mode 100644 (file)
index 5bed815..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-#include "include/dvr/display_manager_client.h"
-
-#include <dvr/dvr_buffer.h>
-#include <grallocusage/GrallocUsageConversion.h>
-#include <private/android/AHardwareBufferHelpers.h>
-#include <private/dvr/buffer_hub_client.h>
-#include <private/dvr/display_manager_client.h>
-
-using android::dvr::DisplaySurfaceAttributeEnum;
-
-extern "C" {
-
-struct DvrDisplayManagerClient {
-  DvrDisplayManagerClient()
-      : client(android::dvr::DisplayManagerClient::Create()) {}
-  ~DvrDisplayManagerClient() {}
-
-  std::unique_ptr<android::dvr::DisplayManagerClient> client;
-};
-
-struct DvrDisplayManagerClientSurfaceList {
-  DvrDisplayManagerClientSurfaceList(
-      std::vector<android::dvr::DisplaySurfaceInfo> surface_list)
-      : list(std::move(surface_list)) {}
-  ~DvrDisplayManagerClientSurfaceList() {}
-
-  std::vector<android::dvr::DisplaySurfaceInfo> list;
-};
-
-struct DvrDisplayManagerClientSurfaceBuffers {
-  DvrDisplayManagerClientSurfaceBuffers(
-      std::vector<std::unique_ptr<android::dvr::BufferConsumer>> buffer_list)
-      : list(std::move(buffer_list)) {}
-  ~DvrDisplayManagerClientSurfaceBuffers() {}
-
-  std::vector<std::unique_ptr<android::dvr::BufferConsumer>> list;
-};
-
-DvrDisplayManagerClient* dvrDisplayManagerClientCreate() {
-  return new DvrDisplayManagerClient();
-}
-
-void dvrDisplayManagerClientDestroy(DvrDisplayManagerClient* client) {
-  delete client;
-}
-
-DvrBuffer* dvrDisplayManagerSetupNamedBuffer(DvrDisplayManagerClient* client,
-                                             const char* name, size_t size,
-                                             uint64_t hardware_buffer_usage,
-                                             uint64_t unused) {
-  uint64_t producer_usage = 0;
-  uint64_t consumer_usage = 0;
-
-  // Note: AHardwareBuffer no longer uses usage0/usage1
-  uint64_t gralloc_usage =
-      android::AHardwareBuffer_convertToGrallocUsageBits(hardware_buffer_usage);
-
-  // Note: split producer/consumer usage is deprecated, grallocV2 uses single
-  // 64-bits usage
-  // And, currently, 64-bits gralloc usage flags can safely be truncated to
-  // 32-bits
-  android_convertGralloc0To1Usage((uint32_t)gralloc_usage, &producer_usage,
-                                  &consumer_usage);
-
-  auto ion_buffer = client->client->SetupNamedBuffer(
-      name, size, (producer_usage | consumer_usage));
-  if (ion_buffer) {
-    return CreateDvrBufferFromIonBuffer(std::move(ion_buffer));
-  }
-  return nullptr;
-}
-
-int dvrDisplayManagerClientGetEventFd(DvrDisplayManagerClient* client) {
-  return client->client->event_fd();
-}
-
-int dvrDisplayManagerClientTranslateEpollEventMask(
-    DvrDisplayManagerClient* client, int in_events, int* out_events) {
-  auto result = client->client->GetChannel()->GetEventMask(in_events);
-
-  if (!result) {
-    return -EIO;
-  }
-
-  *out_events = result.get();
-
-  return 0;
-}
-
-int dvrDisplayManagerClientGetSurfaceList(
-    DvrDisplayManagerClient* client,
-    DvrDisplayManagerClientSurfaceList** surface_list) {
-  std::vector<android::dvr::DisplaySurfaceInfo> list;
-  int ret = client->client->GetSurfaceList(&list);
-  if (ret < 0)
-    return ret;
-
-  *surface_list = new DvrDisplayManagerClientSurfaceList(std::move(list));
-  return ret;
-}
-
-void dvrDisplayManagerClientSurfaceListDestroy(
-    DvrDisplayManagerClientSurfaceList* surface_list) {
-  delete surface_list;
-}
-
-size_t dvrDisplayManagerClientSurfaceListGetSize(
-    DvrDisplayManagerClientSurfaceList* surface_list) {
-  return surface_list->list.size();
-}
-
-int dvrDisplayManagerClientSurfaceListGetSurfaceId(
-    DvrDisplayManagerClientSurfaceList* surface_list, size_t index) {
-  return surface_list->list[index].surface_id;
-}
-
-int dvrDisplayManagerClientSurfaceListGetClientZOrder(
-    DvrDisplayManagerClientSurfaceList* surface_list, size_t index) {
-  return surface_list->list[index].ClientZOrder();
-}
-
-bool dvrDisplayManagerClientSurfaceListGetClientIsVisible(
-    DvrDisplayManagerClientSurfaceList* surface_list, size_t index) {
-  return surface_list->list[index].IsClientVisible();
-}
-
-int dvrDisplayManagerClientGetSurfaceBuffers(
-    DvrDisplayManagerClient* /* client */, int /* surface_id */,
-    DvrDisplayManagerClientSurfaceBuffers** /* surface_buffers */) {
-  // TODO(jwcai, hendrikw) Remove this after we replacing
-  // dvrDisplayManagerClientGetSurfaceBuffers is dvr_api.
-  return -1;
-}
-
-void dvrDisplayManagerClientSurfaceBuffersDestroy(
-    DvrDisplayManagerClientSurfaceBuffers* surface_buffers) {
-  delete surface_buffers;
-}
-
-size_t dvrDisplayManagerClientSurfaceBuffersGetSize(
-    DvrDisplayManagerClientSurfaceBuffers* surface_buffers) {
-  return surface_buffers->list.size();
-}
-
-int dvrDisplayManagerClientSurfaceBuffersGetFd(
-    DvrDisplayManagerClientSurfaceBuffers* surface_buffers, size_t index) {
-  return surface_buffers->list[index]->event_fd();
-}
-
-}  // extern "C"
index c4634b1..4d7e1a6 100644 (file)
@@ -1,13 +1,14 @@
 #include "include/dvr/dvr_api.h"
 
 #include <errno.h>
+#include <utils/Log.h>
 
 // Headers from libdvr
-#include <dvr/display_manager_client.h>
 #include <dvr/dvr_buffer.h>
 #include <dvr/dvr_buffer_queue.h>
+#include <dvr/dvr_display_manager.h>
 #include <dvr/dvr_surface.h>
-#include <dvr/vsync_client_api.h>
+#include <dvr/dvr_vsync.h>
 
 // Headers not yet moved into libdvr.
 // TODO(jwcai) Move these once their callers are moved into Google3.
 extern "C" {
 
 DVR_EXPORT int dvrGetApi(void* api, size_t struct_size, int version) {
+  ALOGI("dvrGetApi: api=%p struct_size=%zu version=%d", api, struct_size,
+        version);
   if (version == 1) {
     if (struct_size != sizeof(DvrApi_v1)) {
+      ALOGE("dvrGetApi: Size mismatch: expected %zu; actual %zu",
+            sizeof(DvrApi_v1), struct_size);
       return -EINVAL;
     }
     DvrApi_v1* dvr_api = static_cast<DvrApi_v1*>(api);
 
-    // display_manager_client.h
-    dvr_api->display_manager_client_create = dvrDisplayManagerClientCreate;
-    dvr_api->display_manager_client_destroy = dvrDisplayManagerClientDestroy;
-    dvr_api->display_manager_client_get_surface_list =
-        dvrDisplayManagerClientGetSurfaceList;
-    dvr_api->display_manager_client_surface_list_destroy =
-        dvrDisplayManagerClientSurfaceListDestroy;
-    dvr_api->display_manager_setup_named_buffer =
-        dvrDisplayManagerSetupNamedBuffer;
-    dvr_api->display_manager_client_surface_list_get_size =
-        dvrDisplayManagerClientSurfaceListGetSize;
-    dvr_api->display_manager_client_surface_list_get_surface_id =
-        dvrDisplayManagerClientSurfaceListGetSurfaceId;
-    dvr_api->display_manager_client_get_surface_buffer_list =
-        dvrDisplayManagerClientGetSurfaceBuffers;
-    dvr_api->display_manager_client_surface_buffer_list_destroy =
-        dvrDisplayManagerClientSurfaceBuffersDestroy;
-    dvr_api->display_manager_client_surface_buffer_list_get_size =
-        dvrDisplayManagerClientSurfaceBuffersGetSize;
-    dvr_api->display_manager_client_surface_buffer_list_get_fd =
-        dvrDisplayManagerClientSurfaceBuffersGetFd;
+// Defines an API entry for V1 (no version suffix).
+#define DVR_V1_API_ENTRY(name) dvr_api->name = dvr##name
 
-    // dvr_buffer.h
-    dvr_api->write_buffer_destroy = dvrWriteBufferDestroy;
-    dvr_api->write_buffer_get_ahardwarebuffer =
-        dvrWriteBufferGetAHardwareBuffer;
-    dvr_api->write_buffer_post = dvrWriteBufferPost;
-    dvr_api->write_buffer_gain = dvrWriteBufferGain;
-    dvr_api->write_buffer_gain_async = dvrWriteBufferGainAsync;
-    dvr_api->write_buffer_get_native_handle = dvrWriteBufferGetNativeHandle;
+#include "include/dvr/dvr_api_entries.h"
 
-    dvr_api->read_buffer_destroy = dvrReadBufferDestroy;
-    dvr_api->read_buffer_get_ahardwarebuffer = dvrReadBufferGetAHardwareBuffer;
-    dvr_api->read_buffer_acquire = dvrReadBufferAcquire;
-    dvr_api->read_buffer_release = dvrReadBufferRelease;
-    dvr_api->read_buffer_release_async = dvrReadBufferReleaseAsync;
-    dvr_api->read_buffer_get_native_handle = dvrReadBufferGetNativeHandle;
-
-    dvr_api->buffer_destroy = dvrBufferDestroy;
-    dvr_api->buffer_get_ahardwarebuffer = dvrBufferGetAHardwareBuffer;
-    dvr_api->buffer_get_native_handle = dvrBufferGetNativeHandle;
-
-    // dvr_buffer_queue.h
-    dvr_api->write_buffer_queue_destroy = dvrWriteBufferQueueDestroy;
-    dvr_api->write_buffer_queue_get_capacity = dvrWriteBufferQueueGetCapacity;
-    dvr_api->write_buffer_queue_get_external_surface =
-        dvrWriteBufferQueueGetExternalSurface;
-    dvr_api->write_buffer_queue_create_read_queue =
-        dvrWriteBufferQueueCreateReadQueue;
-    dvr_api->write_buffer_queue_dequeue = dvrWriteBufferQueueDequeue;
-    dvr_api->read_buffer_queue_destroy = dvrReadBufferQueueDestroy;
-    dvr_api->read_buffer_queue_get_capacity = dvrReadBufferQueueGetCapacity;
-    dvr_api->read_buffer_queue_create_read_queue =
-        dvrReadBufferQueueCreateReadQueue;
-    dvr_api->read_buffer_queue_dequeue = dvrReadBufferQueueDequeue;
-
-    // dvr_surface.h
-    dvr_api->get_named_buffer = dvrGetNamedBuffer;
-    dvr_api->surface_create = dvrSurfaceCreate;
-    dvr_api->surface_get_write_buffer_queue = dvrSurfaceGetWriteBufferQueue;
-
-    // vsync_client_api.h
-    dvr_api->vsync_client_create = dvr_vsync_client_create;
-    dvr_api->vsync_client_destroy = dvr_vsync_client_destroy;
-    dvr_api->vsync_client_get_sched_info = dvr_vsync_client_get_sched_info;
-
-    // pose_client.h
-    dvr_api->pose_client_create = dvrPoseCreate;
-    dvr_api->pose_client_destroy = dvrPoseDestroy;
-    dvr_api->pose_get = dvrPoseGet;
-    dvr_api->pose_get_vsync_count = dvrPoseGetVsyncCount;
-    dvr_api->pose_get_controller = dvrPoseGetController;
-
-    // virtual_touchpad_client.h
-    dvr_api->virtual_touchpad_create = dvrVirtualTouchpadCreate;
-    dvr_api->virtual_touchpad_destroy = dvrVirtualTouchpadDestroy;
-    dvr_api->virtual_touchpad_attach = dvrVirtualTouchpadAttach;
-    dvr_api->virtual_touchpad_detach = dvrVirtualTouchpadDetach;
-    dvr_api->virtual_touchpad_touch = dvrVirtualTouchpadTouch;
-    dvr_api->virtual_touchpad_button_state = dvrVirtualTouchpadButtonState;
-
-    // dvr_hardware_composer_client.h
-    dvr_api->hwc_client_create = dvrHwcClientCreate;
-    dvr_api->hwc_client_destroy = dvrHwcClientDestroy;
-    dvr_api->hwc_frame_destroy = dvrHwcFrameDestroy;
-    dvr_api->hwc_frame_get_display_id = dvrHwcFrameGetDisplayId;
-    dvr_api->hwc_frame_get_display_width = dvrHwcFrameGetDisplayWidth;
-    dvr_api->hwc_frame_get_display_height = dvrHwcFrameGetDisplayHeight;
-    dvr_api->hwc_frame_get_display_removed = dvrHwcFrameGetDisplayRemoved;
-    dvr_api->hwc_frame_get_active_config = dvrHwcFrameGetActiveConfig;
-    dvr_api->hwc_frame_get_color_mode = dvrHwcFrameGetColorMode;
-    dvr_api->hwc_frame_get_color_transform = dvrHwcFrameGetColorTransform;
-    dvr_api->hwc_frame_get_power_mode = dvrHwcFrameGetPowerMode;
-    dvr_api->hwc_frame_get_vsync_enabled = dvrHwcFrameGetVsyncEnabled;
-    dvr_api->hwc_frame_get_layer_count = dvrHwcFrameGetLayerCount;
-    dvr_api->hwc_frame_get_layer_id = dvrHwcFrameGetLayerId;
-    dvr_api->hwc_frame_get_layer_buffer = dvrHwcFrameGetLayerBuffer;
-    dvr_api->hwc_frame_get_layer_fence = dvrHwcFrameGetLayerFence;
-    dvr_api->hwc_frame_get_layer_display_frame =
-        dvrHwcFrameGetLayerDisplayFrame;
-    dvr_api->hwc_frame_get_layer_crop = dvrHwcFrameGetLayerCrop;
-    dvr_api->hwc_frame_get_layer_blend_mode = dvrHwcFrameGetLayerBlendMode;
-    dvr_api->hwc_frame_get_layer_alpha = dvrHwcFrameGetLayerAlpha;
-    dvr_api->hwc_frame_get_layer_type = dvrHwcFrameGetLayerType;
-    dvr_api->hwc_frame_get_layer_application_id =
-        dvrHwcFrameGetLayerApplicationId;
-    dvr_api->hwc_frame_get_layer_z_order = dvrHwcFrameGetLayerZOrder;
-    dvr_api->hwc_frame_get_layer_cursor = dvrHwcFrameGetLayerCursor;
-    dvr_api->hwc_frame_get_layer_transform = dvrHwcFrameGetLayerTransform;
-    dvr_api->hwc_frame_get_layer_dataspace = dvrHwcFrameGetLayerDataspace;
-    dvr_api->hwc_frame_get_layer_color = dvrHwcFrameGetLayerColor;
-    dvr_api->hwc_frame_get_layer_num_visible_regions =
-        dvrHwcFrameGetLayerNumVisibleRegions;
-    dvr_api->hwc_frame_get_layer_visible_region =
-        dvrHwcFrameGetLayerVisibleRegion;
-    dvr_api->hwc_frame_get_layer_num_damaged_regions =
-        dvrHwcFrameGetLayerNumDamagedRegions;
-    dvr_api->hwc_frame_get_layer_damaged_region =
-        dvrHwcFrameGetLayerDamagedRegion;
+// Undefine macro definitions to play nice with Google3 style rules.
+#undef DVR_V1_API_ENTRY
 
     return 0;
   }
+
+  ALOGE("dvrGetApi: Unknown API version=%d", version);
   return -EINVAL;
 }
 
index 28820e7..82469b8 100644 (file)
@@ -4,37 +4,13 @@
 #include <private/dvr/buffer_hub_client.h>
 #include <ui/GraphicBuffer.h>
 
-using namespace android;
-
-struct DvrWriteBuffer {
-  std::shared_ptr<dvr::BufferProducer> write_buffer;
-};
+#include "dvr_internal.h"
 
-struct DvrReadBuffer {
-  std::shared_ptr<dvr::BufferConsumer> read_buffer;
-};
-
-struct DvrBuffer {
-  std::shared_ptr<dvr::IonBuffer> buffer;
-};
+using namespace android;
 
 namespace android {
 namespace dvr {
 
-DvrWriteBuffer* CreateDvrWriteBufferFromBufferProducer(
-    const std::shared_ptr<dvr::BufferProducer>& buffer_producer) {
-  if (!buffer_producer)
-    return nullptr;
-  return new DvrWriteBuffer{std::move(buffer_producer)};
-}
-
-DvrReadBuffer* CreateDvrReadBufferFromBufferConsumer(
-    const std::shared_ptr<dvr::BufferConsumer>& buffer_consumer) {
-  if (!buffer_consumer)
-    return nullptr;
-  return new DvrReadBuffer{std::move(buffer_consumer)};
-}
-
 DvrBuffer* CreateDvrBufferFromIonBuffer(
     const std::shared_ptr<IonBuffer>& ion_buffer) {
   if (!ion_buffer)
@@ -47,14 +23,6 @@ DvrBuffer* CreateDvrBufferFromIonBuffer(
 
 namespace {
 
-void InitializeGraphicBuffer(const dvr::BufferHubBuffer* buffer,
-                             sp<GraphicBuffer>* graphic_buffer) {
-  *graphic_buffer = sp<GraphicBuffer>(new GraphicBuffer(
-      buffer->width(), buffer->height(), buffer->format(), 1, /* layer count */
-      buffer->usage(), buffer->stride(), buffer->native_handle(),
-      false /* keep ownership */));
-}
-
 int ConvertToAHardwareBuffer(GraphicBuffer* graphic_buffer,
                              AHardwareBuffer** hardware_buffer) {
   if (!hardware_buffer || !graphic_buffer) {
@@ -69,28 +37,57 @@ int ConvertToAHardwareBuffer(GraphicBuffer* graphic_buffer,
 
 extern "C" {
 
+void dvrWriteBufferCreateEmpty(DvrWriteBuffer** write_buffer) {
+  if (write_buffer)
+    *write_buffer = new DvrWriteBuffer;
+}
+
 void dvrWriteBufferDestroy(DvrWriteBuffer* write_buffer) {
   delete write_buffer;
 }
 
+int dvrWriteBufferIsValid(DvrWriteBuffer* write_buffer) {
+  return write_buffer && write_buffer->write_buffer;
+}
+
+int dvrWriteBufferClear(DvrWriteBuffer* write_buffer) {
+  if (!write_buffer)
+    return -EINVAL;
+
+  write_buffer->write_buffer = nullptr;
+  return 0;
+}
+
 int dvrWriteBufferGetId(DvrWriteBuffer* write_buffer) {
+  if (!write_buffer || !write_buffer->write_buffer)
+    return -EINVAL;
+
   return write_buffer->write_buffer->id();
 }
 
 int dvrWriteBufferGetAHardwareBuffer(DvrWriteBuffer* write_buffer,
                                      AHardwareBuffer** hardware_buffer) {
+  if (!write_buffer || !write_buffer->write_buffer)
+    return -EINVAL;
+
   return ConvertToAHardwareBuffer(
       write_buffer->write_buffer->buffer()->buffer().get(), hardware_buffer);
 }
 
 int dvrWriteBufferPost(DvrWriteBuffer* write_buffer, int ready_fence_fd,
                        const void* meta, size_t meta_size_bytes) {
+  if (!write_buffer || !write_buffer->write_buffer)
+    return -EINVAL;
+
   pdx::LocalHandle fence(ready_fence_fd);
   int result = write_buffer->write_buffer->Post(fence, meta, meta_size_bytes);
   return result;
 }
 
 int dvrWriteBufferGain(DvrWriteBuffer* write_buffer, int* release_fence_fd) {
+  if (!write_buffer || !write_buffer->write_buffer || !release_fence_fd)
+    return -EINVAL;
+
   pdx::LocalHandle release_fence;
   int result = write_buffer->write_buffer->Gain(&release_fence);
   *release_fence_fd = release_fence.Release();
@@ -98,23 +95,52 @@ int dvrWriteBufferGain(DvrWriteBuffer* write_buffer, int* release_fence_fd) {
 }
 
 int dvrWriteBufferGainAsync(DvrWriteBuffer* write_buffer) {
+  if (!write_buffer || !write_buffer->write_buffer)
+    return -EINVAL;
+
   return write_buffer->write_buffer->GainAsync();
 }
 
+void dvrReadBufferCreateEmpty(DvrReadBuffer** read_buffer) {
+  if (read_buffer)
+    *read_buffer = new DvrReadBuffer;
+}
+
 void dvrReadBufferDestroy(DvrReadBuffer* read_buffer) { delete read_buffer; }
 
+int dvrReadBufferIsValid(DvrReadBuffer* read_buffer) {
+  return read_buffer && read_buffer->read_buffer;
+}
+
+int dvrReadBufferClear(DvrReadBuffer* read_buffer) {
+  if (!read_buffer)
+    return -EINVAL;
+
+  read_buffer->read_buffer = nullptr;
+  return 0;
+}
+
 int dvrReadBufferGetId(DvrReadBuffer* read_buffer) {
+  if (!read_buffer || !read_buffer->read_buffer)
+    return -EINVAL;
+
   return read_buffer->read_buffer->id();
 }
 
 int dvrReadBufferGetAHardwareBuffer(DvrReadBuffer* read_buffer,
                                     AHardwareBuffer** hardware_buffer) {
+  if (!read_buffer || !read_buffer->read_buffer)
+    return -EINVAL;
+
   return ConvertToAHardwareBuffer(
       read_buffer->read_buffer->buffer()->buffer().get(), hardware_buffer);
 }
 
 int dvrReadBufferAcquire(DvrReadBuffer* read_buffer, int* ready_fence_fd,
                          void* meta, size_t meta_size_bytes) {
+  if (!read_buffer || !read_buffer->read_buffer)
+    return -EINVAL;
+
   pdx::LocalHandle ready_fence;
   int result =
       read_buffer->read_buffer->Acquire(&ready_fence, meta, meta_size_bytes);
@@ -123,12 +149,18 @@ int dvrReadBufferAcquire(DvrReadBuffer* read_buffer, int* ready_fence_fd,
 }
 
 int dvrReadBufferRelease(DvrReadBuffer* read_buffer, int release_fence_fd) {
+  if (!read_buffer || !read_buffer->read_buffer)
+    return -EINVAL;
+
   pdx::LocalHandle fence(release_fence_fd);
   int result = read_buffer->read_buffer->Release(fence);
   return result;
 }
 
 int dvrReadBufferReleaseAsync(DvrReadBuffer* read_buffer) {
+  if (!read_buffer || !read_buffer->read_buffer)
+    return -EINVAL;
+
   return read_buffer->read_buffer->ReleaseAsync();
 }
 
@@ -136,21 +168,34 @@ void dvrBufferDestroy(DvrBuffer* buffer) { delete buffer; }
 
 int dvrBufferGetAHardwareBuffer(DvrBuffer* buffer,
                                 AHardwareBuffer** hardware_buffer) {
+  if (!buffer || !buffer->buffer || !hardware_buffer) {
+    return -EINVAL;
+  }
+
   return ConvertToAHardwareBuffer(buffer->buffer->buffer().get(),
                                   hardware_buffer);
 }
 
 const struct native_handle* dvrWriteBufferGetNativeHandle(
     DvrWriteBuffer* write_buffer) {
+  if (!write_buffer || !write_buffer->write_buffer)
+    return nullptr;
+
   return write_buffer->write_buffer->native_handle();
 }
 
 const struct native_handle* dvrReadBufferGetNativeHandle(
     DvrReadBuffer* read_buffer) {
+  if (!read_buffer || !read_buffer->read_buffer)
+    return nullptr;
+
   return read_buffer->read_buffer->native_handle();
 }
 
 const struct native_handle* dvrBufferGetNativeHandle(DvrBuffer* buffer) {
+  if (!buffer || !buffer->buffer)
+    return nullptr;
+
   return buffer->buffer->handle();
 }
 
index 50c94cb..95c0e26 100644 (file)
@@ -6,45 +6,77 @@
 #include <private/dvr/buffer_hub_queue_client.h>
 #include <private/dvr/buffer_hub_queue_producer.h>
 
+#include "dvr_internal.h"
+
 #define CHECK_PARAM(param)                                               \
   LOG_ALWAYS_FATAL_IF(param == nullptr, "%s: " #param "cannot be NULL.", \
                       __FUNCTION__)
 
 using namespace android;
 
+namespace android {
+namespace dvr {
+
+DvrWriteBufferQueue* CreateDvrWriteBufferQueueFromProducerQueue(
+    const std::shared_ptr<dvr::ProducerQueue>& producer_queue) {
+  return new DvrWriteBufferQueue{std::move(producer_queue)};
+}
+
+DvrReadBufferQueue* CreateDvrReadBufferQueueFromConsumerQueue(
+    const std::shared_ptr<dvr::ConsumerQueue>& consumer_queue) {
+  return new DvrReadBufferQueue{std::move(consumer_queue)};
+}
+
+dvr::ProducerQueue* GetProducerQueueFromDvrWriteBufferQueue(
+    DvrWriteBufferQueue* write_queue) {
+  return write_queue->producer_queue.get();
+}
+
+}  // namespace dvr
+}  // namespace android
+
 extern "C" {
 
 void dvrWriteBufferQueueDestroy(DvrWriteBufferQueue* write_queue) {
-  if (write_queue != nullptr && write_queue->native_window_ != nullptr) {
-    ANativeWindow_release(write_queue->native_window_);
-  }
+  if (write_queue != nullptr && write_queue->native_window != nullptr)
+    ANativeWindow_release(write_queue->native_window);
+
   delete write_queue;
 }
 
-size_t dvrWriteBufferQueueGetCapacity(DvrWriteBufferQueue* write_queue) {
-  CHECK_PARAM(write_queue);
-  return write_queue->producer_queue_->capacity();
+ssize_t dvrWriteBufferQueueGetCapacity(DvrWriteBufferQueue* write_queue) {
+  if (!write_queue || !write_queue->producer_queue)
+    return -EINVAL;
+
+  return write_queue->producer_queue->capacity();
+}
+
+int dvrWriteBufferQueueGetId(DvrWriteBufferQueue* write_queue) {
+  if (!write_queue)
+    return -EINVAL;
+
+  return write_queue->producer_queue->id();
 }
 
 int dvrWriteBufferQueueGetExternalSurface(DvrWriteBufferQueue* write_queue,
                                           ANativeWindow** out_window) {
-  CHECK_PARAM(write_queue);
-  CHECK_PARAM(out_window);
+  if (!write_queue || !out_window)
+    return -EINVAL;
 
-  if (write_queue->producer_queue_->metadata_size() !=
+  if (write_queue->producer_queue->metadata_size() !=
       sizeof(DvrNativeBufferMetadata)) {
     ALOGE(
-        "The size of buffer metadata (%u) of the write queue does not match of "
-        "size of DvrNativeBufferMetadata (%u).",
-        write_queue->producer_queue_->metadata_size(),
+        "The size of buffer metadata (%zu) of the write queue does not match "
+        "of size of DvrNativeBufferMetadata (%zu).",
+        write_queue->producer_queue->metadata_size(),
         sizeof(DvrNativeBufferMetadata));
     return -EINVAL;
   }
 
-  // Lazy creation of |native_window_|.
-  if (write_queue->native_window_ == nullptr) {
+  // Lazy creation of |native_window|.
+  if (write_queue->native_window == nullptr) {
     std::shared_ptr<dvr::BufferHubQueueCore> core =
-        dvr::BufferHubQueueCore::Create(write_queue->producer_queue_);
+        dvr::BufferHubQueueCore::Create(write_queue->producer_queue);
     if (core == nullptr) {
       ALOGE(
           "dvrWriteBufferQueueGetExternalSurface: Failed to create native "
@@ -54,24 +86,23 @@ int dvrWriteBufferQueueGetExternalSurface(DvrWriteBufferQueue* write_queue,
 
     sp<IGraphicBufferProducer> gbp = new dvr::BufferHubQueueProducer(core);
     sp<Surface> surface = new Surface(gbp, true);
-    write_queue->native_window_ = static_cast<ANativeWindow*>(surface.get());
-    ANativeWindow_acquire(write_queue->native_window_);
+    write_queue->native_window = static_cast<ANativeWindow*>(surface.get());
+    ANativeWindow_acquire(write_queue->native_window);
   }
 
-  *out_window = write_queue->native_window_;
+  *out_window = write_queue->native_window;
   return 0;
 }
 
 int dvrWriteBufferQueueCreateReadQueue(DvrWriteBufferQueue* write_queue,
                                        DvrReadBufferQueue** out_read_queue) {
-  CHECK_PARAM(write_queue);
-  CHECK_PARAM(write_queue->producer_queue_);
-  CHECK_PARAM(out_read_queue);
+  if (!write_queue || !write_queue->producer_queue || !out_read_queue)
+    return -EINVAL;
 
   auto read_queue = std::make_unique<DvrReadBufferQueue>();
-  read_queue->consumer_queue_ =
-      write_queue->producer_queue_->CreateConsumerQueue();
-  if (read_queue->consumer_queue_ == nullptr) {
+  read_queue->consumer_queue =
+      write_queue->producer_queue->CreateConsumerQueue();
+  if (read_queue->consumer_queue == nullptr) {
     ALOGE(
         "dvrWriteBufferQueueCreateReadQueue: Failed to create consumer queue "
         "from DvrWriteBufferQueue[%p].",
@@ -84,23 +115,25 @@ int dvrWriteBufferQueueCreateReadQueue(DvrWriteBufferQueue* write_queue,
 }
 
 int dvrWriteBufferQueueDequeue(DvrWriteBufferQueue* write_queue, int timeout,
-                                  DvrWriteBuffer** out_buffer,
-                                  int* out_fence_fd) {
-  CHECK_PARAM(write_queue);
-  CHECK_PARAM(write_queue->producer_queue_);
-  CHECK_PARAM(out_buffer);
-  CHECK_PARAM(out_fence_fd);
+                               DvrWriteBuffer* write_buffer,
+                               int* out_fence_fd) {
+  if (!write_queue || !write_queue->producer_queue || !write_buffer ||
+      !out_fence_fd) {
+    return -EINVAL;
+  }
 
   size_t slot;
   pdx::LocalHandle release_fence;
-  std::shared_ptr<dvr::BufferProducer> buffer =
-      write_queue->producer_queue_->Dequeue(timeout, &slot, &release_fence);
-  if (buffer == nullptr) {
-    ALOGE("dvrWriteBufferQueueDequeue: Failed to dequeue buffer.");
-    return -ENOMEM;
+  auto buffer_status =
+      write_queue->producer_queue->Dequeue(timeout, &slot, &release_fence);
+  if (!buffer_status) {
+    ALOGE_IF(buffer_status.error() != ETIMEDOUT,
+             "dvrWriteBufferQueueDequeue: Failed to dequeue buffer: %s",
+             buffer_status.GetErrorMessage().c_str());
+    return -buffer_status.error();
   }
 
-  *out_buffer = CreateDvrWriteBufferFromBufferProducer(buffer);
+  write_buffer->write_buffer = buffer_status.take();
   *out_fence_fd = release_fence.Release();
   return 0;
 }
@@ -110,22 +143,29 @@ void dvrReadBufferQueueDestroy(DvrReadBufferQueue* read_queue) {
   delete read_queue;
 }
 
-size_t dvrReadBufferQueueGetCapacity(DvrReadBufferQueue* read_queue) {
-  CHECK_PARAM(read_queue);
+ssize_t dvrReadBufferQueueGetCapacity(DvrReadBufferQueue* read_queue) {
+  if (!read_queue)
+    return -EINVAL;
+
+  return read_queue->consumer_queue->capacity();
+}
+
+int dvrReadBufferQueueGetId(DvrReadBufferQueue* read_queue) {
+  if (!read_queue)
+    return -EINVAL;
 
-  return read_queue->consumer_queue_->capacity();
+  return read_queue->consumer_queue->id();
 }
 
 int dvrReadBufferQueueCreateReadQueue(DvrReadBufferQueue* read_queue,
                                       DvrReadBufferQueue** out_read_queue) {
-  CHECK_PARAM(read_queue);
-  CHECK_PARAM(read_queue->consumer_queue_);
-  CHECK_PARAM(out_read_queue);
+  if (!read_queue || !read_queue->consumer_queue || !out_read_queue)
+    return -EINVAL;
 
   auto new_read_queue = std::make_unique<DvrReadBufferQueue>();
-  new_read_queue->consumer_queue_ =
-      read_queue->consumer_queue_->CreateConsumerQueue();
-  if (new_read_queue->consumer_queue_ == nullptr) {
+  new_read_queue->consumer_queue =
+      read_queue->consumer_queue->CreateConsumerQueue();
+  if (new_read_queue->consumer_queue == nullptr) {
     ALOGE(
         "dvrReadBufferQueueCreateReadQueue: Failed to create consumer queue "
         "from DvrReadBufferQueue[%p].",
@@ -138,34 +178,33 @@ int dvrReadBufferQueueCreateReadQueue(DvrReadBufferQueue* read_queue,
 }
 
 int dvrReadBufferQueueDequeue(DvrReadBufferQueue* read_queue, int timeout,
-                              DvrReadBuffer** out_buffer, int* out_fence_fd,
+                              DvrReadBuffer* read_buffer, int* out_fence_fd,
                               void* out_meta, size_t meta_size_bytes) {
-  CHECK_PARAM(read_queue);
-  CHECK_PARAM(read_queue->consumer_queue_);
-  CHECK_PARAM(out_buffer);
-  CHECK_PARAM(out_fence_fd);
-  CHECK_PARAM(out_meta);
+  if (!read_queue || !read_queue->consumer_queue || !read_buffer ||
+      !out_fence_fd || !out_meta) {
+    return -EINVAL;
+  }
 
-  if (meta_size_bytes != read_queue->consumer_queue_->metadata_size()) {
+  if (meta_size_bytes != read_queue->consumer_queue->metadata_size()) {
     ALOGE(
         "dvrReadBufferQueueDequeue: Invalid metadata size, expected (%zu), "
         "but actual (%zu).",
-        read_queue->consumer_queue_->metadata_size(), meta_size_bytes);
+        read_queue->consumer_queue->metadata_size(), meta_size_bytes);
     return -EINVAL;
   }
 
   size_t slot;
   pdx::LocalHandle acquire_fence;
-  std::shared_ptr<dvr::BufferConsumer> buffer =
-      read_queue->consumer_queue_->Dequeue(timeout, &slot, out_meta,
-                                           meta_size_bytes, &acquire_fence);
-
-  if (buffer == nullptr) {
-    ALOGE("dvrReadBufferQueueGainBuffer: Failed to dequeue buffer.");
-    return -ENOMEM;
+  auto buffer_status = read_queue->consumer_queue->Dequeue(
+      timeout, &slot, out_meta, meta_size_bytes, &acquire_fence);
+  if (!buffer_status) {
+    ALOGE_IF(buffer_status.error() != ETIMEDOUT,
+             "dvrReadBufferQueueDequeue: Failed to dequeue buffer: %s",
+             buffer_status.GetErrorMessage().c_str());
+    return -buffer_status.error();
   }
 
-  *out_buffer = CreateDvrReadBufferFromBufferConsumer(buffer);
+  read_buffer->read_buffer = buffer_status.take();
   *out_fence_fd = acquire_fence.Release();
   return 0;
 }
diff --git a/libs/vr/libdvr/dvr_display_manager.cpp b/libs/vr/libdvr/dvr_display_manager.cpp
new file mode 100644 (file)
index 0000000..87636ec
--- /dev/null
@@ -0,0 +1,304 @@
+#include "include/dvr/dvr_display_manager.h"
+
+#include <dvr/dvr_buffer.h>
+#include <pdx/rpc/variant.h>
+#include <private/android/AHardwareBufferHelpers.h>
+#include <private/dvr/buffer_hub_client.h>
+#include <private/dvr/buffer_hub_queue_client.h>
+#include <private/dvr/display_manager_client.h>
+
+#include "dvr_internal.h"
+
+using android::AHardwareBuffer_convertToGrallocUsageBits;
+using android::dvr::BufferConsumer;
+using android::dvr::display::DisplayManagerClient;
+using android::dvr::display::SurfaceAttributes;
+using android::dvr::display::SurfaceAttribute;
+using android::dvr::display::SurfaceState;
+using android::dvr::CreateDvrReadBufferQueueFromConsumerQueue;
+using android::pdx::rpc::EmptyVariant;
+
+namespace {
+
+// Extracts type and value from the attribute Variant and writes them into the
+// respective fields of DvrSurfaceAttribute.
+struct AttributeVisitor {
+  DvrSurfaceAttribute* attribute;
+
+  void operator()(int32_t value) {
+    attribute->value.int32_value = value;
+    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32;
+  }
+  void operator()(int64_t value) {
+    attribute->value.int64_value = value;
+    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT64;
+  }
+  void operator()(bool value) {
+    attribute->value.bool_value = value;
+    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL;
+  }
+  void operator()(float value) {
+    attribute->value.float_value = value;
+    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT;
+  }
+  void operator()(const std::array<float, 2>& value) {
+    std::copy(value.cbegin(), value.cend(), attribute->value.float2_value);
+    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2;
+  }
+  void operator()(const std::array<float, 3>& value) {
+    std::copy(value.cbegin(), value.cend(), attribute->value.float3_value);
+    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3;
+  }
+  void operator()(const std::array<float, 4>& value) {
+    std::copy(value.cbegin(), value.cend(), attribute->value.float4_value);
+    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4;
+  }
+  void operator()(const std::array<float, 8>& value) {
+    std::copy(value.cbegin(), value.cend(), attribute->value.float8_value);
+    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8;
+  }
+  void operator()(const std::array<float, 16>& value) {
+    std::copy(value.cbegin(), value.cend(), attribute->value.float16_value);
+    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16;
+  }
+  void operator()(EmptyVariant) {
+    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_NONE;
+  }
+};
+
+size_t ConvertSurfaceAttributes(const SurfaceAttributes& surface_attributes,
+                                DvrSurfaceAttribute* attributes,
+                                size_t max_count) {
+  size_t count = 0;
+  for (const auto& attribute : surface_attributes) {
+    if (count >= max_count)
+      break;
+
+    // Copy the key and extract the Variant value using a visitor.
+    attributes[count].key = attribute.first;
+    attribute.second.Visit(AttributeVisitor{&attributes[count]});
+    count++;
+  }
+
+  return count;
+}
+
+}  // anonymous namespace
+
+extern "C" {
+
+struct DvrDisplayManager {
+  std::unique_ptr<DisplayManagerClient> client;
+};
+
+struct DvrSurfaceState {
+  std::vector<SurfaceState> state;
+};
+
+int dvrDisplayManagerCreate(DvrDisplayManager** client_out) {
+  if (!client_out)
+    return -EINVAL;
+
+  auto client = DisplayManagerClient::Create();
+  if (!client) {
+    ALOGE("dvrDisplayManagerCreate: Failed to create display manager client!");
+    return -EIO;
+  }
+
+  *client_out = new DvrDisplayManager{std::move(client)};
+  return 0;
+}
+
+void dvrDisplayManagerDestroy(DvrDisplayManager* client) { delete client; }
+
+int dvrDisplayManagerSetupNamedBuffer(DvrDisplayManager* client,
+                                      const char* name, size_t size,
+                                      uint64_t usage, DvrBuffer** buffer_out) {
+  if (!client || !name || !buffer_out)
+    return -EINVAL;
+
+  uint64_t gralloc_usage = AHardwareBuffer_convertToGrallocUsageBits(usage);
+
+  auto buffer_status =
+      client->client->SetupNamedBuffer(name, size, gralloc_usage);
+  if (!buffer_status) {
+    ALOGE("dvrDisplayManagerSetupPoseBuffer: Failed to setup named buffer: %s",
+          buffer_status.GetErrorMessage().c_str());
+    return -buffer_status.error();
+  }
+
+  *buffer_out = CreateDvrBufferFromIonBuffer(buffer_status.take());
+  return 0;
+}
+
+int dvrDisplayManagerGetEventFd(DvrDisplayManager* client) {
+  if (!client)
+    return -EINVAL;
+
+  return client->client->event_fd();
+}
+
+int dvrDisplayManagerTranslateEpollEventMask(DvrDisplayManager* client,
+                                             int in_events, int* out_events) {
+  if (!client || !out_events)
+    return -EINVAL;
+
+  auto status = client->client->GetEventMask(in_events);
+  if (!status)
+    return -status.error();
+
+  *out_events = status.get();
+  return 0;
+}
+
+int dvrDisplayManagerGetSurfaceState(DvrDisplayManager* client,
+                                     DvrSurfaceState* state) {
+  if (!client || !state)
+    return -EINVAL;
+
+  auto status = client->client->GetSurfaceState();
+  if (!status)
+    return -status.error();
+
+  state->state = status.take();
+  return 0;
+}
+
+int dvrDisplayManagerGetReadBufferQueue(DvrDisplayManager* client,
+                                        int surface_id, int queue_id,
+                                        DvrReadBufferQueue** queue_out) {
+  if (!client || !queue_out)
+    return -EINVAL;
+
+  auto status = client->client->GetSurfaceQueue(surface_id, queue_id);
+  if (!status) {
+    ALOGE("dvrDisplayManagerGetReadBufferQueue: Failed to get queue: %s",
+          status.GetErrorMessage().c_str());
+    return -status.error();
+  }
+
+  *queue_out = CreateDvrReadBufferQueueFromConsumerQueue(status.take());
+  return 0;
+}
+
+int dvrSurfaceStateCreate(DvrSurfaceState** surface_state_out) {
+  if (!surface_state_out)
+    return -EINVAL;
+
+  *surface_state_out = new DvrSurfaceState{};
+  return 0;
+}
+
+void dvrSurfaceStateDestroy(DvrSurfaceState* surface_state) {
+  delete surface_state;
+}
+
+int dvrSurfaceStateGetSurfaceCount(DvrSurfaceState* surface_state,
+                                   size_t* count_out) {
+  if (!surface_state)
+    return -EINVAL;
+
+  *count_out = surface_state->state.size();
+  return 0;
+}
+
+int dvrSurfaceStateGetUpdateFlags(DvrSurfaceState* surface_state,
+                                  size_t surface_index,
+                                  DvrSurfaceUpdateFlags* flags_out) {
+  if (!surface_state || surface_index >= surface_state->state.size())
+    return -EINVAL;
+
+  *flags_out = surface_state->state[surface_index].update_flags;
+  return 0;
+}
+
+int dvrSurfaceStateGetSurfaceId(DvrSurfaceState* surface_state,
+                                size_t surface_index, int* surface_id_out) {
+  if (!surface_state || surface_index >= surface_state->state.size())
+    return -EINVAL;
+
+  *surface_id_out = surface_state->state[surface_index].surface_id;
+  return 0;
+}
+
+int dvrSurfaceStateGetProcessId(DvrSurfaceState* surface_state,
+                                size_t surface_index, int* process_id_out) {
+  if (!surface_state || surface_index >= surface_state->state.size())
+    return -EINVAL;
+
+  *process_id_out = surface_state->state[surface_index].process_id;
+  return 0;
+}
+
+int dvrSurfaceStateGetQueueCount(DvrSurfaceState* surface_state,
+                                 size_t surface_index, size_t* count_out) {
+  if (!surface_state || surface_index >= surface_state->state.size())
+    return -EINVAL;
+
+  *count_out = surface_state->state[surface_index].queue_ids.size();
+  return 0;
+}
+
+ssize_t dvrSurfaceStateGetQueueIds(DvrSurfaceState* surface_state,
+                                   size_t surface_index, int* queue_ids,
+                                   size_t max_count) {
+  if (!surface_state || surface_index >= surface_state->state.size())
+    return -EINVAL;
+
+  size_t i;
+  const auto& state = surface_state->state[surface_index];
+  for (i = 0; i < std::min(max_count, state.queue_ids.size()); i++) {
+    queue_ids[i] = state.queue_ids[i];
+  }
+
+  return i;
+}
+
+int dvrSurfaceStateGetZOrder(DvrSurfaceState* surface_state,
+                             size_t surface_index, int* z_order_out) {
+  if (!surface_state || surface_index >= surface_state->state.size() ||
+      !z_order_out) {
+    return -EINVAL;
+  }
+
+  *z_order_out = surface_state->state[surface_index].GetZOrder();
+  return 0;
+}
+
+int dvrSurfaceStateGetVisible(DvrSurfaceState* surface_state,
+                              size_t surface_index, bool* visible_out) {
+  if (!surface_state || surface_index >= surface_state->state.size() ||
+      !visible_out) {
+    return -EINVAL;
+  }
+
+  *visible_out = surface_state->state[surface_index].GetVisible();
+  return 0;
+}
+
+int dvrSurfaceStateGetAttributeCount(DvrSurfaceState* surface_state,
+                                     size_t surface_index, size_t* count_out) {
+  if (!surface_state || surface_index >= surface_state->state.size() ||
+      !count_out) {
+    return -EINVAL;
+  }
+
+  *count_out = surface_state->state[surface_index].surface_attributes.size();
+  return 0;
+}
+
+ssize_t dvrSurfaceStateGetAttributes(DvrSurfaceState* surface_state,
+                                     size_t surface_index,
+                                     DvrSurfaceAttribute* attributes,
+                                     size_t max_count) {
+  if (!surface_state || surface_index >= surface_state->state.size() ||
+      !attributes) {
+    return -EINVAL;
+  }
+
+  return ConvertSurfaceAttributes(
+      surface_state->state[surface_index].surface_attributes, attributes,
+      max_count);
+}
+
+}  // extern "C"
diff --git a/libs/vr/libdvr/dvr_internal.h b/libs/vr/libdvr/dvr_internal.h
new file mode 100644 (file)
index 0000000..89bef09
--- /dev/null
@@ -0,0 +1,70 @@
+#ifndef ANDROID_DVR_INTERNAL_H_
+#define ANDROID_DVR_INTERNAL_H_
+
+#include <sys/cdefs.h>
+
+#include <memory>
+
+extern "C" {
+
+typedef struct DvrBuffer DvrBuffer;
+typedef struct DvrReadBuffer DvrReadBuffer;
+typedef struct DvrWriteBuffer DvrWriteBuffer;
+typedef struct DvrWriteBufferQueue DvrWriteBufferQueue;
+typedef struct DvrReadBufferQueue DvrReadBufferQueue;
+
+}  // extern "C"
+
+namespace android {
+namespace dvr {
+
+class BufferProducer;
+class BufferConsumer;
+class ConsumerQueue;
+class IonBuffer;
+class ProducerQueue;
+
+DvrBuffer* CreateDvrBufferFromIonBuffer(
+    const std::shared_ptr<IonBuffer>& ion_buffer);
+
+DvrReadBuffer* CreateDvrReadBufferFromBufferConsumer(
+    const std::shared_ptr<BufferConsumer>& buffer_consumer);
+DvrWriteBuffer* CreateDvrWriteBufferFromBufferProducer(
+    const std::shared_ptr<BufferProducer>& buffer_producer);
+
+DvrReadBufferQueue* CreateDvrReadBufferQueueFromConsumerQueue(
+    const std::shared_ptr<ConsumerQueue>& consumer_queue);
+DvrWriteBufferQueue* CreateDvrWriteBufferQueueFromProducerQueue(
+    const std::shared_ptr<ProducerQueue>& producer_queue);
+ProducerQueue* GetProducerQueueFromDvrWriteBufferQueue(
+    DvrWriteBufferQueue* write_queue);
+
+}  // namespace dvr
+}  // namespace android
+
+extern "C" {
+
+struct DvrWriteBuffer {
+  std::shared_ptr<android::dvr::BufferProducer> write_buffer;
+};
+
+struct DvrReadBuffer {
+  std::shared_ptr<android::dvr::BufferConsumer> read_buffer;
+};
+
+struct DvrBuffer {
+  std::shared_ptr<android::dvr::IonBuffer> buffer;
+};
+
+struct DvrWriteBufferQueue {
+  std::shared_ptr<android::dvr::ProducerQueue> producer_queue;
+  ANativeWindow* native_window{nullptr};
+};
+
+struct DvrReadBufferQueue {
+  std::shared_ptr<android::dvr::ConsumerQueue> consumer_queue;
+};
+
+}  // extern "C"
+
+#endif  // ANDROID_DVR_INTERNAL_H_
index a04ed50..b70f726 100644 (file)
 #include "include/dvr/dvr_surface.h"
 
+#include <inttypes.h>
+
 #include <private/dvr/display_client.h>
 
-using namespace android;
+#include "dvr_internal.h"
 
-struct DvrSurface {
-  std::unique_ptr<dvr::DisplaySurfaceClient> display_surface_;
-};
+using android::dvr::display::DisplayClient;
+using android::dvr::display::Surface;
+using android::dvr::display::SurfaceAttributes;
+using android::dvr::display::SurfaceAttributeValue;
+using android::dvr::CreateDvrReadBufferFromBufferConsumer;
+using android::dvr::CreateDvrWriteBufferQueueFromProducerQueue;
+
+namespace {
+
+bool ConvertSurfaceAttributes(const DvrSurfaceAttribute* attributes,
+                              size_t attribute_count,
+                              SurfaceAttributes* surface_attributes,
+                              size_t* error_index) {
+  for (size_t i = 0; i < attribute_count; i++) {
+    SurfaceAttributeValue value;
+    switch (attributes[i].value.type) {
+      case DVR_SURFACE_ATTRIBUTE_TYPE_INT32:
+        value = attributes[i].value.int32_value;
+        break;
+      case DVR_SURFACE_ATTRIBUTE_TYPE_INT64:
+        value = attributes[i].value.int64_value;
+        break;
+      case DVR_SURFACE_ATTRIBUTE_TYPE_BOOL:
+        value = attributes[i].value.bool_value;
+        break;
+      case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT:
+        value = attributes[i].value.float_value;
+        break;
+      case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2:
+        value = attributes[i].value.float2_value;
+        break;
+      case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3:
+        value = attributes[i].value.float3_value;
+        break;
+      case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4:
+        value = attributes[i].value.float4_value;
+        break;
+      case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8:
+        value = attributes[i].value.float8_value;
+        break;
+      case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16:
+        value = attributes[i].value.float16_value;
+        break;
+      default:
+        *error_index = i;
+        return false;
+    }
+
+    surface_attributes->emplace(attributes[i].key, value);
+  }
+
+  return true;
+}
+
+}  // anonymous namespace
 
 extern "C" {
 
-int dvrSurfaceCreate(int width, int height, int format, uint64_t usage0,
-                     uint64_t usage1, int flags, DvrSurface** out_surface) {
+struct DvrSurface {
+  std::unique_ptr<Surface> surface;
+};
+
+int dvrSurfaceCreate(const DvrSurfaceAttribute* attributes,
+                     size_t attribute_count, DvrSurface** out_surface) {
   if (out_surface == nullptr) {
-    ALOGE("dvrSurfaceCreate: invalid inputs: out_surface=%p.", out_surface);
+    ALOGE("dvrSurfaceCreate: Invalid inputs: out_surface=%p.", out_surface);
     return -EINVAL;
   }
 
-  int error;
-  auto client = dvr::DisplayClient::Create(&error);
-  if (!client) {
-    ALOGE("Failed to create display client!");
-    return error;
+  size_t error_index;
+  SurfaceAttributes surface_attributes;
+  if (!ConvertSurfaceAttributes(attributes, attribute_count,
+                                &surface_attributes, &error_index)) {
+    ALOGE("dvrSurfaceCreate: Invalid surface attribute type: %" PRIu64,
+          attributes[error_index].value.type);
+    return -EINVAL;
+  }
+
+  auto status = Surface::CreateSurface(surface_attributes);
+  if (!status) {
+    ALOGE("dvrSurfaceCreate:: Failed to create display surface: %s",
+          status.GetErrorMessage().c_str());
+    return -status.error();
   }
 
-  // TODO(hendrikw): When we move to gralloc1, pass both usage0 and usage1 down.
-  std::unique_ptr<dvr::DisplaySurfaceClient> surface =
-      client->CreateDisplaySurface(
-          width, height, static_cast<int>(usage0 | usage1), format, flags);
+  *out_surface = new DvrSurface{status.take()};
+  return 0;
+}
+
+void dvrSurfaceDestroy(DvrSurface* surface) { delete surface; }
+
+int dvrSurfaceGetId(DvrSurface* surface) {
+  return surface->surface->surface_id();
+}
+
+int dvrSurfaceSetAttributes(DvrSurface* surface,
+                            const DvrSurfaceAttribute* attributes,
+                            size_t attribute_count) {
+  if (surface == nullptr || attributes == nullptr) {
+    ALOGE(
+        "dvrSurfaceSetAttributes: Invalid inputs: surface=%p attributes=%p "
+        "attribute_count=%zu",
+        surface, attributes, attribute_count);
+    return -EINVAL;
+  }
+
+  size_t error_index;
+  SurfaceAttributes surface_attributes;
+  if (!ConvertSurfaceAttributes(attributes, attribute_count,
+                                &surface_attributes, &error_index)) {
+    ALOGE("dvrSurfaceSetAttributes: Invalid surface attribute type: %" PRIu64,
+          attributes[error_index].value.type);
+    return -EINVAL;
+  }
+
+  auto status = surface->surface->SetAttributes(surface_attributes);
+  if (!status) {
+    ALOGE("dvrSurfaceSetAttributes: Failed to set attributes: %s",
+          status.GetErrorMessage().c_str());
+    return -status.error();
+  }
 
-  DvrSurface* dvr_surface = new DvrSurface;
-  dvr_surface->display_surface_ = std::move(surface);
-  *out_surface = dvr_surface;
   return 0;
 }
 
-int dvrSurfaceGetWriteBufferQueue(DvrSurface* surface,
-                                  DvrWriteBufferQueue** out_writer) {
+int dvrSurfaceCreateWriteBufferQueue(DvrSurface* surface, uint32_t width,
+                                     uint32_t height, uint32_t format,
+                                     uint64_t usage, size_t capacity,
+                                     DvrWriteBufferQueue** out_writer) {
   if (surface == nullptr || out_writer == nullptr) {
     ALOGE(
-        "dvrSurfaceGetWriteBufferQueue: Invalid inputs: surface=%p, "
+        "dvrSurfaceCreateWriteBufferQueue: Invalid inputs: surface=%p, "
         "out_writer=%p.",
         surface, out_writer);
     return -EINVAL;
   }
-  DvrWriteBufferQueue* buffer_writer = new DvrWriteBufferQueue;
-  buffer_writer->producer_queue_ =
-      surface->display_surface_->GetProducerQueue();
-  if (buffer_writer->producer_queue_ == nullptr) {
-    ALOGE(
-        "dvrSurfaceGetWriteBufferQueue: Failed to get producer queue from "
-        "display surface.");
-    return -ENOMEM;
+
+  auto status =
+      surface->surface->CreateQueue(width, height, format, usage, capacity);
+  if (!status) {
+    ALOGE("dvrSurfaceCreateWriteBufferQueue: Failed to create queue: %s",
+          status.GetErrorMessage().c_str());
+    return -status.error();
   }
 
-  *out_writer = buffer_writer;
+  *out_writer = CreateDvrWriteBufferQueueFromProducerQueue(status.take());
   return 0;
 }
 
 int dvrGetNamedBuffer(const char* name, DvrBuffer** out_buffer) {
-  auto client = android::dvr::DisplayClient::Create();
+  auto client = DisplayClient::Create();
   if (!client) {
     ALOGE("dvrGetNamedBuffer: Failed to create display client!");
     return -ECOMM;
@@ -71,12 +168,13 @@ int dvrGetNamedBuffer(const char* name, DvrBuffer** out_buffer) {
     return -EINVAL;
   }
 
-  auto named_buffer = client->GetNamedBuffer(name);
-  if (!named_buffer) {
-    ALOGE("dvrGetNamedBuffer: Failed to find named buffer: %s.", name);
-    return -EINVAL;
+  auto status = client->GetNamedBuffer(name);
+  if (!status) {
+    ALOGE("dvrGetNamedBuffer: Failed to find named buffer name=%s: %s", name,
+          status.GetErrorMessage().c_str());
+    return -status.error();
   }
-  *out_buffer = CreateDvrBufferFromIonBuffer(std::move(named_buffer));
+  *out_buffer = CreateDvrBufferFromIonBuffer(status.take());
   return 0;
 }
 
diff --git a/libs/vr/libdvr/dvr_vsync.cpp b/libs/vr/libdvr/dvr_vsync.cpp
new file mode 100644 (file)
index 0000000..099240e
--- /dev/null
@@ -0,0 +1,33 @@
+#include "include/dvr/dvr_vsync.h"
+
+#include <utils/Log.h>
+
+#include <private/dvr/vsync_client.h>
+
+extern "C" {
+
+struct DvrVSyncClient {
+  std::unique_ptr<android::dvr::VSyncClient> client;
+};
+
+int dvrVSyncClientCreate(DvrVSyncClient** client_out) {
+  auto client = android::dvr::VSyncClient::Create();
+  if (!client) {
+    ALOGE("dvrVSyncClientCreate: Failed to create vsync client!");
+    return -EIO;
+  }
+
+  *client_out = new DvrVSyncClient{std::move(client)};
+  return 0;
+}
+
+void dvrVSyncClientDestroy(DvrVSyncClient* client) { delete client; }
+
+int dvrVSyncClientGetSchedInfo(DvrVSyncClient* client, int64_t* vsync_period_ns,
+                               int64_t* next_timestamp_ns,
+                               uint32_t* next_vsync_count) {
+  return client->client->GetSchedInfo(vsync_period_ns, next_timestamp_ns,
+                                      next_vsync_count);
+}
+
+}  // extern "C"
diff --git a/libs/vr/libdvr/include/dvr/display_manager_client.h b/libs/vr/libdvr/include/dvr/display_manager_client.h
deleted file mode 100644 (file)
index 8cd948c..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-#ifndef DVR_DISPLAY_MANAGER_CLIENT_H_
-#define DVR_DISPLAY_MANAGER_CLIENT_H_
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct DvrDisplayManagerClient DvrDisplayManagerClient;
-typedef struct DvrDisplayManagerClientSurfaceList
-    DvrDisplayManagerClientSurfaceList;
-typedef struct DvrDisplayManagerClientSurfaceBuffers
-    DvrDisplayManagerClientSurfaceBuffers;
-typedef struct DvrBuffer DvrBuffer;
-
-DvrDisplayManagerClient* dvrDisplayManagerClientCreate();
-
-void dvrDisplayManagerClientDestroy(DvrDisplayManagerClient* client);
-
-DvrBuffer* dvrDisplayManagerSetupNamedBuffer(DvrDisplayManagerClient* client,
-                                             const char* name, size_t size,
-                                             uint64_t usage0, uint64_t usage1);
-
-// Return an event fd for checking if there was an event on the server
-// Note that the only event which will be flagged is POLLIN. You must use
-// dvrDisplayManagerClientTranslateEpollEventMask in order to get the real
-// event flags.
-// @return the fd
-int dvrDisplayManagerClientGetEventFd(DvrDisplayManagerClient* client);
-
-// Once you have received an epoll event, you must translate it to its true
-// flags. This is a workaround for working with UDS.
-// @param in_events pass in the epoll revents that were initially returned
-// @param on success, this value will be overwritten with the true epoll values
-// @return 0 on success, non-zero otherwise
-int dvrDisplayManagerClientTranslateEpollEventMask(
-    DvrDisplayManagerClient* client, int in_events, int* out_events);
-
-// If successful, populates |surface_list| with a list of application
-// surfaces the display is currently using.
-//
-// @return 0 on success. Otherwise it returns a negative error value.
-int dvrDisplayManagerClientGetSurfaceList(
-    DvrDisplayManagerClient* client,
-    DvrDisplayManagerClientSurfaceList** surface_list);
-
-void dvrDisplayManagerClientSurfaceListDestroy(
-    DvrDisplayManagerClientSurfaceList* surface_list);
-
-// @return Returns the number of surfaces in the list.
-size_t dvrDisplayManagerClientSurfaceListGetSize(
-    DvrDisplayManagerClientSurfaceList* surface_list);
-
-// @return Return a unique identifier for a client surface. The identifier can
-// be used to query for other surface properties.
-int dvrDisplayManagerClientSurfaceListGetSurfaceId(
-    DvrDisplayManagerClientSurfaceList* surface_list, size_t index);
-
-// @return Returns the stacking order of the client surface at |index|.
-int dvrDisplayManagerClientSurfaceListGetClientZOrder(
-    DvrDisplayManagerClientSurfaceList* surface_list, size_t index);
-
-// @return Returns true if the client surface is visible, false otherwise.
-bool dvrDisplayManagerClientSurfaceListGetClientIsVisible(
-    DvrDisplayManagerClientSurfaceList* surface_list, size_t index);
-
-// TODO(jwcai, hendrikw) Remove this after we replacing
-// dvrDisplayManagerClientGetSurfaceBuffers is dvr_api.
-int dvrDisplayManagerClientGetSurfaceBuffers(
-    DvrDisplayManagerClient* client, int surface_id,
-    DvrDisplayManagerClientSurfaceBuffers** surface_buffers);
-
-void dvrDisplayManagerClientSurfaceBuffersDestroy(
-    DvrDisplayManagerClientSurfaceBuffers* surface_buffers);
-
-// @return Returns the number of buffers.
-size_t dvrDisplayManagerClientSurfaceBuffersGetSize(
-    DvrDisplayManagerClientSurfaceBuffers* surface_buffers);
-
-// @return Returns the file descriptor for the buffer consumer at |index|.
-int dvrDisplayManagerClientSurfaceBuffersGetFd(
-    DvrDisplayManagerClientSurfaceBuffers* surface_buffers, size_t index);
-
-#ifdef __cplusplus
-}  // extern "C"
-#endif
-
-#endif  // DVR_DISPLAY_MANAGER_CLIENT_H_
index 3cd401d..7124bee 100644 (file)
 #include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
+#include <sys/cdefs.h>
+#include <unistd.h>
 
 #include <dvr/dvr_hardware_composer_defs.h>
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 typedef struct ANativeWindow ANativeWindow;
 
 typedef struct DvrPoseAsync DvrPoseAsync;
 
-typedef struct DvrDisplayManagerClient DvrDisplayManagerClient;
-typedef struct DvrDisplayManagerClientSurfaceList
-    DvrDisplayManagerClientSurfaceList;
-typedef struct DvrDisplayManagerClientSurfaceBuffers
-    DvrDisplayManagerClientSurfaceBuffers;
+typedef uint64_t DvrSurfaceUpdateFlags;
+typedef struct DvrDisplayManager DvrDisplayManager;
+typedef struct DvrSurfaceState DvrSurfaceState;
 typedef struct DvrPose DvrPose;
-typedef struct dvr_vsync_client dvr_vsync_client;
+typedef struct DvrVSyncClient DvrVSyncClient;
 typedef struct DvrVirtualTouchpad DvrVirtualTouchpad;
 
-typedef DvrDisplayManagerClient* (*DvrDisplayManagerClientCreatePtr)(void);
-typedef void (*DvrDisplayManagerClientDestroyPtr)(
-    DvrDisplayManagerClient* client);
-
+typedef struct DvrBuffer DvrBuffer;
 typedef struct DvrWriteBuffer DvrWriteBuffer;
 typedef struct DvrReadBuffer DvrReadBuffer;
-typedef struct DvrBuffer DvrBuffer;
 typedef struct AHardwareBuffer AHardwareBuffer;
 
-typedef struct DvrWriteBufferQueue DvrWriteBufferQueue;
 typedef struct DvrReadBufferQueue DvrReadBufferQueue;
+typedef struct DvrWriteBufferQueue DvrWriteBufferQueue;
 
 typedef struct DvrSurface DvrSurface;
+typedef uint64_t DvrSurfaceAttributeType;
+typedef int32_t DvrSurfaceAttributeKey;
+
+typedef struct DvrSurfaceAttributeValue DvrSurfaceAttributeValue;
+typedef struct DvrSurfaceAttribute DvrSurfaceAttribute;
 
 struct native_handle;
 
-// display_manager_client.h
-typedef int (*DvrDisplayManagerClientGetSurfaceListPtr)(
-    DvrDisplayManagerClient* client,
-    DvrDisplayManagerClientSurfaceList** surface_list);
-typedef void (*DvrDisplayManagerClientSurfaceListDestroyPtr)(
-    DvrDisplayManagerClientSurfaceList* surface_list);
-typedef DvrBuffer* (*DvrDisplayManagerSetupNamedBufferPtr)(
-    DvrDisplayManagerClient* client, const char* name, size_t size,
-    uint64_t usage0, uint64_t usage1);
-typedef size_t (*DvrDisplayManagerClientSurfaceListGetSizePtr)(
-    DvrDisplayManagerClientSurfaceList* surface_list);
-typedef int (*DvrDisplayManagerClientSurfaceListGetSurfaceIdPtr)(
-    DvrDisplayManagerClientSurfaceList* surface_list, size_t index);
-typedef int (*DvrDisplayManagerClientGetSurfaceBufferListPtr)(
-    DvrDisplayManagerClient* client, int surface_id,
-    DvrDisplayManagerClientSurfaceBuffers** surface_buffers);
-typedef void (*DvrDisplayManagerClientSurfaceBufferListDestroyPtr)(
-    DvrDisplayManagerClientSurfaceBuffers* surface_buffers);
-typedef size_t (*DvrDisplayManagerClientSurfaceBufferListGetSizePtr)(
-    DvrDisplayManagerClientSurfaceBuffers* surface_buffers);
-typedef int (*DvrDisplayManagerClientSurfaceBufferListGetFdPtr)(
-    DvrDisplayManagerClientSurfaceBuffers* surface_buffers, size_t index);
+// dvr_display_manager.h
+typedef int (*DvrDisplayManagerCreatePtr)(DvrDisplayManager** client_out);
+typedef void (*DvrDisplayManagerDestroyPtr)(DvrDisplayManager* client);
+typedef int (*DvrDisplayManagerSetupNamedBufferPtr)(DvrDisplayManager* client,
+                                                    const char* name,
+                                                    size_t size, uint64_t usage,
+                                                    DvrBuffer** buffer_out);
+typedef int (*DvrDisplayManagerGetEventFdPtr)(DvrDisplayManager* client);
+typedef int (*DvrDisplayManagerTranslateEpollEventMaskPtr)(
+    DvrDisplayManager* client, int in_events, int* out_events);
+typedef int (*DvrDisplayManagerGetSurfaceStatePtr)(
+    DvrDisplayManager* client, DvrSurfaceState* surface_state);
+typedef int (*DvrDisplayManagerGetReadBufferQueuePtr)(
+    DvrDisplayManager* client, int surface_id, int queue_id,
+    DvrReadBufferQueue** queue_out);
+typedef int (*DvrSurfaceStateCreatePtr)(DvrSurfaceState** surface_state);
+typedef void (*DvrSurfaceStateDestroyPtr)(DvrSurfaceState* surface_state);
+typedef int (*DvrSurfaceStateGetSurfaceCountPtr)(DvrSurfaceState* surface_state,
+                                                 size_t* count_out);
+typedef int (*DvrSurfaceStateGetUpdateFlagsPtr)(
+    DvrSurfaceState* surface_state, size_t surface_index,
+    DvrSurfaceUpdateFlags* flags_out);
+typedef int (*DvrSurfaceStateGetSurfaceIdPtr)(DvrSurfaceState* surface_state,
+                                              size_t surface_index,
+                                              int* surface_id_out);
+typedef int (*DvrSurfaceStateGetProcessIdPtr)(DvrSurfaceState* surface_state,
+                                              size_t surface_index,
+                                              int* process_id_out);
+typedef int (*DvrSurfaceStateGetQueueCountPtr)(DvrSurfaceState* surface_state,
+                                               size_t surface_index,
+                                               size_t* count_out);
+typedef ssize_t (*DvrSurfaceStateGetQueueIdsPtr)(DvrSurfaceState* surface_state,
+                                                 size_t surface_index,
+                                                 int* queue_ids,
+                                                 size_t max_count);
+typedef int (*DvrSurfaceStateGetZOrderPtr)(DvrSurfaceState* surface_state,
+                                           size_t surface_index,
+                                           int* z_order_out);
+typedef int (*DvrSurfaceStateGetVisiblePtr)(DvrSurfaceState* surface_state,
+                                            size_t surface_index,
+                                            bool* visible_out);
+typedef int (*DvrSurfaceStateGetAttributeCountPtr)(
+    DvrSurfaceState* surface_state, size_t surface_index, size_t* count_out);
+typedef ssize_t (*DvrSurfaceStateGetAttributesPtr)(
+    DvrSurfaceState* surface_state, size_t surface_index,
+    DvrSurfaceAttribute* attributes, size_t max_attribute_count);
 
 // dvr_buffer.h
-typedef void (*DvrWriteBufferDestroyPtr)(DvrWriteBuffer* client);
+typedef void (*DvrWriteBufferCreateEmptyPtr)(DvrWriteBuffer** write_buffer_out);
+typedef void (*DvrWriteBufferDestroyPtr)(DvrWriteBuffer* write_buffer);
+typedef int (*DvrWriteBufferIsValidPtr)(DvrWriteBuffer* write_buffer);
+typedef int (*DvrWriteBufferClearPtr)(DvrWriteBuffer* write_buffer);
+typedef int (*DvrWriteBufferGetIdPtr)(DvrWriteBuffer* write_buffer);
 typedef int (*DvrWriteBufferGetAHardwareBufferPtr)(
-    DvrWriteBuffer* client, AHardwareBuffer** hardware_buffer);
-typedef int (*DvrWriteBufferPostPtr)(DvrWriteBuffer* client, int ready_fence_fd,
-                                     const void* meta, size_t meta_size_bytes);
-typedef int (*DvrWriteBufferGainPtr)(DvrWriteBuffer* client,
+    DvrWriteBuffer* write_buffer, AHardwareBuffer** hardware_buffer);
+typedef int (*DvrWriteBufferPostPtr)(DvrWriteBuffer* write_buffer,
+                                     int ready_fence_fd, const void* meta,
+                                     size_t meta_size_bytes);
+typedef int (*DvrWriteBufferGainPtr)(DvrWriteBuffer* write_buffer,
                                      int* release_fence_fd);
-typedef int (*DvrWriteBufferGainAsyncPtr)(DvrWriteBuffer* client);
-typedef const struct native_handle* (*DvrWriteBufferGetNativeHandle)(
+typedef int (*DvrWriteBufferGainAsyncPtr)(DvrWriteBuffer* write_buffer);
+typedef const struct native_handle* (*DvrWriteBufferGetNativeHandlePtr)(
     DvrWriteBuffer* write_buffer);
 
-typedef void (*DvrReadBufferDestroyPtr)(DvrReadBuffer* client);
+typedef void (*DvrReadBufferCreateEmptyPtr)(DvrReadBuffer** read_buffer_out);
+typedef void (*DvrReadBufferDestroyPtr)(DvrReadBuffer* read_buffer);
+typedef int (*DvrReadBufferIsValidPtr)(DvrReadBuffer* read_buffer);
+typedef int (*DvrReadBufferClearPtr)(DvrReadBuffer* read_buffer);
+typedef int (*DvrReadBufferGetIdPtr)(DvrReadBuffer* read_buffer);
 typedef int (*DvrReadBufferGetAHardwareBufferPtr)(
-    DvrReadBuffer* client, AHardwareBuffer** hardware_buffer);
-typedef int (*DvrReadBufferAcquirePtr)(DvrReadBuffer* client,
+    DvrReadBuffer* read_buffer, AHardwareBuffer** hardware_buffer);
+typedef int (*DvrReadBufferAcquirePtr)(DvrReadBuffer* read_buffer,
                                        int* ready_fence_fd, void* meta,
                                        size_t meta_size_bytes);
-typedef int (*DvrReadBufferReleasePtr)(DvrReadBuffer* client,
+typedef int (*DvrReadBufferReleasePtr)(DvrReadBuffer* read_buffer,
                                        int release_fence_fd);
-typedef int (*DvrReadBufferReleaseAsyncPtr)(DvrReadBuffer* client);
-typedef const struct native_handle* (*DvrReadBufferGetNativeHandle)(
+typedef int (*DvrReadBufferReleaseAsyncPtr)(DvrReadBuffer* read_buffer);
+typedef const struct native_handle* (*DvrReadBufferGetNativeHandlePtr)(
     DvrReadBuffer* read_buffer);
 
-typedef void (*DvrBufferDestroy)(DvrBuffer* buffer);
-typedef int (*DvrBufferGetAHardwareBuffer)(DvrBuffer* buffer,
-                                           AHardwareBuffer** hardware_buffer);
-typedef const struct native_handle* (*DvrBufferGetNativeHandle)(
+typedef void (*DvrBufferDestroyPtr)(DvrBuffer* buffer);
+typedef int (*DvrBufferGetAHardwareBufferPtr)(
+    DvrBuffer* buffer, AHardwareBuffer** hardware_buffer);
+typedef const struct native_handle* (*DvrBufferGetNativeHandlePtr)(
     DvrBuffer* buffer);
 
 // dvr_buffer_queue.h
 typedef void (*DvrWriteBufferQueueDestroyPtr)(DvrWriteBufferQueue* write_queue);
-typedef size_t (*DvrWriteBufferQueueGetCapacityPtr)(
+typedef ssize_t (*DvrWriteBufferQueueGetCapacityPtr)(
     DvrWriteBufferQueue* write_queue);
+typedef int (*DvrWriteBufferQueueGetIdPtr)(DvrWriteBufferQueue* write_queue);
 typedef int (*DvrWriteBufferQueueGetExternalSurfacePtr)(
     DvrWriteBufferQueue* write_queue, ANativeWindow** out_window);
 typedef int (*DvrWriteBufferQueueCreateReadQueuePtr)(
     DvrWriteBufferQueue* write_queue, DvrReadBufferQueue** out_read_queue);
 typedef int (*DvrWriteBufferQueueDequeuePtr)(DvrWriteBufferQueue* write_queue,
                                              int timeout,
-                                             DvrWriteBuffer** out_buffer,
+                                             DvrWriteBuffer* out_buffer,
                                              int* out_fence_fd);
 typedef void (*DvrReadBufferQueueDestroyPtr)(DvrReadBufferQueue* read_queue);
-typedef size_t (*DvrReadBufferQueueGetCapacityPtr)(
+typedef ssize_t (*DvrReadBufferQueueGetCapacityPtr)(
     DvrReadBufferQueue* read_queue);
+typedef int (*DvrReadBufferQueueGetIdPtr)(DvrReadBufferQueue* read_queue);
 typedef int (*DvrReadBufferQueueCreateReadQueuePtr)(
     DvrReadBufferQueue* read_queue, DvrReadBufferQueue** out_read_queue);
 typedef int (*DvrReadBufferQueueDequeuePtr)(DvrReadBufferQueue* read_queue,
                                             int timeout,
-                                            DvrReadBuffer** out_buffer,
+                                            DvrReadBuffer* out_buffer,
                                             int* out_fence_fd, void* out_meta,
                                             size_t meta_size_bytes);
 
 // dvr_surface.h
 typedef int (*DvrGetNamedBufferPtr)(const char* name, DvrBuffer** out_buffer);
-typedef int (*DvrSurfaceCreatePtr)(int width, int height, int format,
-                                   uint64_t usage0, uint64_t usage1, int flags,
-                                   DvrSurface** out_surface);
-typedef int (*DvrSurfaceGetWriteBufferQueuePtr)(
-    DvrSurface* surface, DvrWriteBufferQueue** out_writer);
+typedef int (*DvrSurfaceCreatePtr)(const DvrSurfaceAttribute* attributes,
+                                   size_t attribute_count,
+                                   DvrSurface** surface_out);
+typedef void (*DvrSurfaceDestroyPtr)(DvrSurface* surface);
+typedef int (*DvrSurfaceGetIdPtr)(DvrSurface* surface);
+typedef int (*DvrSurfaceSetAttributesPtr)(DvrSurface* surface,
+                                          const DvrSurfaceAttribute* attributes,
+                                          size_t attribute_count);
+typedef int (*DvrSurfaceCreateWriteBufferQueuePtr)(
+    DvrSurface* surface, uint32_t width, uint32_t height, uint32_t format,
+    uint64_t usage, size_t capacity, DvrWriteBufferQueue** queue_out);
 
 // vsync_client_api.h
-typedef dvr_vsync_client* (*DvrVSyncClientCreatePtr)();
-typedef void (*DvrVSyncClientDestroyPtr)(dvr_vsync_client* client);
-typedef int (*DvrVSyncClientGetSchedInfoPtr)(dvr_vsync_client* client,
+typedef int (*DvrVSyncClientCreatePtr)(DvrVSyncClient** client_out);
+typedef void (*DvrVSyncClientDestroyPtr)(DvrVSyncClient* client);
+typedef int (*DvrVSyncClientGetSchedInfoPtr)(DvrVSyncClient* client,
                                              int64_t* vsync_period_ns,
                                              int64_t* next_timestamp_ns,
                                              uint32_t* next_vsync_count);
 
 // pose_client.h
-typedef DvrPose* (*DvrPoseClientCreatePtr)(void);
-typedef void (*DvrPoseClientDestroyPtr)(DvrPose* client);
+typedef DvrPose* (*DvrPoseCreatePtr)(void);
+typedef void (*DvrPoseDestroyPtr)(DvrPose* client);
 typedef int (*DvrPoseGetPtr)(DvrPose* client, uint32_t vsync_count,
                              DvrPoseAsync* out_pose);
 typedef uint32_t (*DvrPoseGetVsyncCountPtr)(DvrPose* client);
@@ -226,8 +266,8 @@ typedef DvrHwcRecti (*DvrHwcFrameGetLayerDamagedRegionPtr)(DvrHwcFrame* frame,
 // reorder existing data members. If new fields need to be added, please take
 // extra care to make sure that new data field is padded properly the size of
 // the struct stays same.
-// TODO(b/37578558) Move |dvr_api.h| into a header library so that this structure
-// won't be copied between |dvr_api.h| and |buffer_hub_qeue_core.h|.
+// TODO(b/37578558) Move |dvr_api.h| into a header library so that this
+// structure won't be copied between |dvr_api.h| and |buffer_hub_qeue_core.h|.
 struct DvrNativeBufferMetadata {
   // Timestamp of the frame.
   int64_t timestamp;
@@ -257,127 +297,18 @@ struct DvrNativeBufferMetadata {
 };
 
 struct DvrApi_v1 {
-  // Display manager client
-  DvrDisplayManagerClientCreatePtr display_manager_client_create;
-  DvrDisplayManagerClientDestroyPtr display_manager_client_destroy;
-  DvrDisplayManagerClientGetSurfaceListPtr
-      display_manager_client_get_surface_list;
-  DvrDisplayManagerClientSurfaceListDestroyPtr
-      display_manager_client_surface_list_destroy;
-  DvrDisplayManagerSetupNamedBufferPtr display_manager_setup_named_buffer;
-  DvrDisplayManagerClientSurfaceListGetSizePtr
-      display_manager_client_surface_list_get_size;
-  DvrDisplayManagerClientSurfaceListGetSurfaceIdPtr
-      display_manager_client_surface_list_get_surface_id;
-  DvrDisplayManagerClientGetSurfaceBufferListPtr
-      display_manager_client_get_surface_buffer_list;
-  DvrDisplayManagerClientSurfaceBufferListDestroyPtr
-      display_manager_client_surface_buffer_list_destroy;
-  DvrDisplayManagerClientSurfaceBufferListGetSizePtr
-      display_manager_client_surface_buffer_list_get_size;
-  DvrDisplayManagerClientSurfaceBufferListGetFdPtr
-      display_manager_client_surface_buffer_list_get_fd;
-
-  // Write buffer
-  DvrWriteBufferDestroyPtr write_buffer_destroy;
-  DvrWriteBufferGetAHardwareBufferPtr write_buffer_get_ahardwarebuffer;
-  DvrWriteBufferPostPtr write_buffer_post;
-  DvrWriteBufferGainPtr write_buffer_gain;
-  DvrWriteBufferGainAsyncPtr write_buffer_gain_async;
-  DvrWriteBufferGetNativeHandle write_buffer_get_native_handle;
-
-  // Read buffer
-  DvrReadBufferDestroyPtr read_buffer_destroy;
-  DvrReadBufferGetAHardwareBufferPtr read_buffer_get_ahardwarebuffer;
-  DvrReadBufferAcquirePtr read_buffer_acquire;
-  DvrReadBufferReleasePtr read_buffer_release;
-  DvrReadBufferReleaseAsyncPtr read_buffer_release_async;
-  DvrReadBufferGetNativeHandle read_buffer_get_native_handle;
-
-  // Buffer
-  DvrBufferDestroy buffer_destroy;
-  DvrBufferGetAHardwareBuffer buffer_get_ahardwarebuffer;
-  DvrBufferGetNativeHandle buffer_get_native_handle;
-
-  // Write buffer queue
-  DvrWriteBufferQueueDestroyPtr write_buffer_queue_destroy;
-  DvrWriteBufferQueueGetCapacityPtr write_buffer_queue_get_capacity;
-  DvrWriteBufferQueueGetExternalSurfacePtr
-      write_buffer_queue_get_external_surface;
-  DvrWriteBufferQueueCreateReadQueuePtr write_buffer_queue_create_read_queue;
-  DvrWriteBufferQueueDequeuePtr write_buffer_queue_dequeue;
-
-  // Read buffer queue
-  DvrReadBufferQueueDestroyPtr read_buffer_queue_destroy;
-  DvrReadBufferQueueGetCapacityPtr read_buffer_queue_get_capacity;
-  DvrReadBufferQueueCreateReadQueuePtr read_buffer_queue_create_read_queue;
-  DvrReadBufferQueueDequeuePtr read_buffer_queue_dequeue;
-
-  // V-Sync client
-  DvrVSyncClientCreatePtr vsync_client_create;
-  DvrVSyncClientDestroyPtr vsync_client_destroy;
-  DvrVSyncClientGetSchedInfoPtr vsync_client_get_sched_info;
-
-  // Display surface
-  DvrGetNamedBufferPtr get_named_buffer;
-  DvrSurfaceCreatePtr surface_create;
-  DvrSurfaceGetWriteBufferQueuePtr surface_get_write_buffer_queue;
-
-  // Pose client
-  DvrPoseClientCreatePtr pose_client_create;
-  DvrPoseClientDestroyPtr pose_client_destroy;
-  DvrPoseGetPtr pose_get;
-  DvrPoseGetVsyncCountPtr pose_get_vsync_count;
-  DvrPoseGetControllerPtr pose_get_controller;
-
-  // Virtual touchpad client
-  DvrVirtualTouchpadCreatePtr virtual_touchpad_create;
-  DvrVirtualTouchpadDestroyPtr virtual_touchpad_destroy;
-  DvrVirtualTouchpadAttachPtr virtual_touchpad_attach;
-  DvrVirtualTouchpadDetachPtr virtual_touchpad_detach;
-  DvrVirtualTouchpadTouchPtr virtual_touchpad_touch;
-  DvrVirtualTouchpadButtonStatePtr virtual_touchpad_button_state;
-
-  // VR HWComposer client
-  DvrHwcClientCreatePtr hwc_client_create;
-  DvrHwcClientDestroyPtr hwc_client_destroy;
-  DvrHwcFrameDestroyPtr hwc_frame_destroy;
-  DvrHwcFrameGetDisplayIdPtr hwc_frame_get_display_id;
-  DvrHwcFrameGetDisplayWidthPtr hwc_frame_get_display_width;
-  DvrHwcFrameGetDisplayHeightPtr hwc_frame_get_display_height;
-  DvrHwcFrameGetDisplayRemovedPtr hwc_frame_get_display_removed;
-  DvrHwcFrameGetActiveConfigPtr hwc_frame_get_active_config;
-  DvrHwcFrameGetColorModePtr hwc_frame_get_color_mode;
-  DvrHwcFrameGetColorTransformPtr hwc_frame_get_color_transform;
-  DvrHwcFrameGetPowerModePtr hwc_frame_get_power_mode;
-  DvrHwcFrameGetVsyncEnabledPtr hwc_frame_get_vsync_enabled;
-  DvrHwcFrameGetLayerCountPtr hwc_frame_get_layer_count;
-  DvrHwcFrameGetLayerIdPtr hwc_frame_get_layer_id;
-  DvrHwcFrameGetLayerBufferPtr hwc_frame_get_layer_buffer;
-  DvrHwcFrameGetLayerFencePtr hwc_frame_get_layer_fence;
-  DvrHwcFrameGetLayerDisplayFramePtr hwc_frame_get_layer_display_frame;
-  DvrHwcFrameGetLayerCropPtr hwc_frame_get_layer_crop;
-  DvrHwcFrameGetLayerBlendModePtr hwc_frame_get_layer_blend_mode;
-  DvrHwcFrameGetLayerAlphaPtr hwc_frame_get_layer_alpha;
-  DvrHwcFrameGetLayerTypePtr hwc_frame_get_layer_type;
-  DvrHwcFrameGetLayerApplicationIdPtr hwc_frame_get_layer_application_id;
-  DvrHwcFrameGetLayerZOrderPtr hwc_frame_get_layer_z_order;
-  DvrHwcFrameGetLayerCursorPtr hwc_frame_get_layer_cursor;
-  DvrHwcFrameGetLayerTransformPtr hwc_frame_get_layer_transform;
-  DvrHwcFrameGetLayerDataspacePtr hwc_frame_get_layer_dataspace;
-  DvrHwcFrameGetLayerColorPtr hwc_frame_get_layer_color;
-  DvrHwcFrameGetLayerNumVisibleRegionsPtr
-      hwc_frame_get_layer_num_visible_regions;
-  DvrHwcFrameGetLayerVisibleRegionPtr hwc_frame_get_layer_visible_region;
-  DvrHwcFrameGetLayerNumDamagedRegionsPtr
-      hwc_frame_get_layer_num_damaged_regions;
-  DvrHwcFrameGetLayerDamagedRegionPtr hwc_frame_get_layer_damaged_region;
+// Defines an API entry for V1 (no version suffix).
+#define DVR_V1_API_ENTRY(name) Dvr##name##Ptr name
+
+// Include file with API entries.
+#include "dvr_api_entries.h"
+
+// Undefine macro definitions to play nice with Google3 style rules.
+#undef DVR_V1_API_ENTRY
 };
 
 int dvrGetApi(void* api, size_t struct_size, int version);
 
-#ifdef __cplusplus
-}  // extern "C"
-#endif
+__END_DECLS
 
 #endif  // ANDROID_DVR_API_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_api_entries.h b/libs/vr/libdvr/include/dvr/dvr_api_entries.h
new file mode 100644 (file)
index 0000000..09568fd
--- /dev/null
@@ -0,0 +1,135 @@
+// dvr_api_entries.h
+//
+// Defines the DVR platform library API entries.
+//
+// Do not include this header directly.
+
+#ifndef DVR_V1_API_ENTRY
+#error Do not include this header directly.
+#endif
+
+// Display manager client
+DVR_V1_API_ENTRY(DisplayManagerCreate);
+DVR_V1_API_ENTRY(DisplayManagerDestroy);
+DVR_V1_API_ENTRY(DisplayManagerSetupNamedBuffer);
+DVR_V1_API_ENTRY(DisplayManagerGetEventFd);
+DVR_V1_API_ENTRY(DisplayManagerTranslateEpollEventMask);
+DVR_V1_API_ENTRY(DisplayManagerGetSurfaceState);
+DVR_V1_API_ENTRY(DisplayManagerGetReadBufferQueue);
+DVR_V1_API_ENTRY(SurfaceStateCreate);
+DVR_V1_API_ENTRY(SurfaceStateDestroy);
+DVR_V1_API_ENTRY(SurfaceStateGetSurfaceCount);
+DVR_V1_API_ENTRY(SurfaceStateGetUpdateFlags);
+DVR_V1_API_ENTRY(SurfaceStateGetSurfaceId);
+DVR_V1_API_ENTRY(SurfaceStateGetProcessId);
+DVR_V1_API_ENTRY(SurfaceStateGetQueueCount);
+DVR_V1_API_ENTRY(SurfaceStateGetQueueIds);
+DVR_V1_API_ENTRY(SurfaceStateGetZOrder);
+DVR_V1_API_ENTRY(SurfaceStateGetVisible);
+DVR_V1_API_ENTRY(SurfaceStateGetAttributeCount);
+DVR_V1_API_ENTRY(SurfaceStateGetAttributes);
+
+// Write buffer
+DVR_V1_API_ENTRY(WriteBufferCreateEmpty);
+DVR_V1_API_ENTRY(WriteBufferDestroy);
+DVR_V1_API_ENTRY(WriteBufferIsValid);
+DVR_V1_API_ENTRY(WriteBufferClear);
+DVR_V1_API_ENTRY(WriteBufferGetId);
+DVR_V1_API_ENTRY(WriteBufferGetAHardwareBuffer);
+DVR_V1_API_ENTRY(WriteBufferPost);
+DVR_V1_API_ENTRY(WriteBufferGain);
+DVR_V1_API_ENTRY(WriteBufferGainAsync);
+DVR_V1_API_ENTRY(WriteBufferGetNativeHandle);
+
+// Read buffer
+DVR_V1_API_ENTRY(ReadBufferCreateEmpty);
+DVR_V1_API_ENTRY(ReadBufferDestroy);
+DVR_V1_API_ENTRY(ReadBufferIsValid);
+DVR_V1_API_ENTRY(ReadBufferClear);
+DVR_V1_API_ENTRY(ReadBufferGetId);
+DVR_V1_API_ENTRY(ReadBufferGetAHardwareBuffer);
+DVR_V1_API_ENTRY(ReadBufferAcquire);
+DVR_V1_API_ENTRY(ReadBufferRelease);
+DVR_V1_API_ENTRY(ReadBufferReleaseAsync);
+DVR_V1_API_ENTRY(ReadBufferGetNativeHandle);
+
+// Buffer
+DVR_V1_API_ENTRY(BufferDestroy);
+DVR_V1_API_ENTRY(BufferGetAHardwareBuffer);
+DVR_V1_API_ENTRY(BufferGetNativeHandle);
+
+// Write buffer queue
+DVR_V1_API_ENTRY(WriteBufferQueueDestroy);
+DVR_V1_API_ENTRY(WriteBufferQueueGetCapacity);
+DVR_V1_API_ENTRY(WriteBufferQueueGetId);
+DVR_V1_API_ENTRY(WriteBufferQueueGetExternalSurface);
+DVR_V1_API_ENTRY(WriteBufferQueueCreateReadQueue);
+DVR_V1_API_ENTRY(WriteBufferQueueDequeue);
+
+// Read buffer queue
+DVR_V1_API_ENTRY(ReadBufferQueueDestroy);
+DVR_V1_API_ENTRY(ReadBufferQueueGetCapacity);
+DVR_V1_API_ENTRY(ReadBufferQueueGetId);
+DVR_V1_API_ENTRY(ReadBufferQueueCreateReadQueue);
+DVR_V1_API_ENTRY(ReadBufferQueueDequeue);
+
+// V-Sync client
+DVR_V1_API_ENTRY(VSyncClientCreate);
+DVR_V1_API_ENTRY(VSyncClientDestroy);
+DVR_V1_API_ENTRY(VSyncClientGetSchedInfo);
+
+// Display surface
+DVR_V1_API_ENTRY(SurfaceCreate);
+DVR_V1_API_ENTRY(SurfaceDestroy);
+DVR_V1_API_ENTRY(SurfaceGetId);
+DVR_V1_API_ENTRY(SurfaceSetAttributes);
+DVR_V1_API_ENTRY(SurfaceCreateWriteBufferQueue);
+DVR_V1_API_ENTRY(GetNamedBuffer);
+
+// Pose client
+DVR_V1_API_ENTRY(PoseCreate);
+DVR_V1_API_ENTRY(PoseDestroy);
+DVR_V1_API_ENTRY(PoseGet);
+DVR_V1_API_ENTRY(PoseGetVsyncCount);
+DVR_V1_API_ENTRY(PoseGetController);
+
+// Virtual touchpad client
+DVR_V1_API_ENTRY(VirtualTouchpadCreate);
+DVR_V1_API_ENTRY(VirtualTouchpadDestroy);
+DVR_V1_API_ENTRY(VirtualTouchpadAttach);
+DVR_V1_API_ENTRY(VirtualTouchpadDetach);
+DVR_V1_API_ENTRY(VirtualTouchpadTouch);
+DVR_V1_API_ENTRY(VirtualTouchpadButtonState);
+
+// VR HWComposer client
+DVR_V1_API_ENTRY(HwcClientCreate);
+DVR_V1_API_ENTRY(HwcClientDestroy);
+DVR_V1_API_ENTRY(HwcFrameDestroy);
+DVR_V1_API_ENTRY(HwcFrameGetDisplayId);
+DVR_V1_API_ENTRY(HwcFrameGetDisplayWidth);
+DVR_V1_API_ENTRY(HwcFrameGetDisplayHeight);
+DVR_V1_API_ENTRY(HwcFrameGetDisplayRemoved);
+DVR_V1_API_ENTRY(HwcFrameGetActiveConfig);
+DVR_V1_API_ENTRY(HwcFrameGetColorMode);
+DVR_V1_API_ENTRY(HwcFrameGetColorTransform);
+DVR_V1_API_ENTRY(HwcFrameGetPowerMode);
+DVR_V1_API_ENTRY(HwcFrameGetVsyncEnabled);
+DVR_V1_API_ENTRY(HwcFrameGetLayerCount);
+DVR_V1_API_ENTRY(HwcFrameGetLayerId);
+DVR_V1_API_ENTRY(HwcFrameGetLayerBuffer);
+DVR_V1_API_ENTRY(HwcFrameGetLayerFence);
+DVR_V1_API_ENTRY(HwcFrameGetLayerDisplayFrame);
+DVR_V1_API_ENTRY(HwcFrameGetLayerCrop);
+DVR_V1_API_ENTRY(HwcFrameGetLayerBlendMode);
+DVR_V1_API_ENTRY(HwcFrameGetLayerAlpha);
+DVR_V1_API_ENTRY(HwcFrameGetLayerType);
+DVR_V1_API_ENTRY(HwcFrameGetLayerApplicationId);
+DVR_V1_API_ENTRY(HwcFrameGetLayerZOrder);
+DVR_V1_API_ENTRY(HwcFrameGetLayerCursor);
+DVR_V1_API_ENTRY(HwcFrameGetLayerTransform);
+DVR_V1_API_ENTRY(HwcFrameGetLayerDataspace);
+DVR_V1_API_ENTRY(HwcFrameGetLayerColor);
+DVR_V1_API_ENTRY(HwcFrameGetLayerNumVisibleRegions);
+DVR_V1_API_ENTRY(HwcFrameGetLayerVisibleRegion);
+DVR_V1_API_ENTRY(HwcFrameGetLayerNumDamagedRegions);
+DVR_V1_API_ENTRY(HwcFrameGetLayerDamagedRegion);
index 3e8357c..af55698 100644 (file)
@@ -3,11 +3,10 @@
 
 #include <stdbool.h>
 #include <stdint.h>
+#include <sys/cdefs.h>
 #include <memory>
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 typedef struct DvrWriteBuffer DvrWriteBuffer;
 typedef struct DvrReadBuffer DvrReadBuffer;
@@ -15,58 +14,91 @@ typedef struct DvrBuffer DvrBuffer;
 typedef struct AHardwareBuffer AHardwareBuffer;
 struct native_handle;
 
-// Write buffer
+// Creates an empty write buffer that may be filled with an acutal buffer by
+// other functions.
+void dvrWriteBufferCreateEmpty(DvrWriteBuffer** write_buffer);
+
+// Destroys the write buffer.
 void dvrWriteBufferDestroy(DvrWriteBuffer* write_buffer);
+
+// Returns 1 if the given write buffer object contains a buffer, 0 otherwise.
+int dvrWriteBufferIsValid(DvrWriteBuffer* write_buffer);
+
+// Clears the contents of the buffer object. After a call to this function
+// dvrWriteBufferIsValid on the same buffer object returns 0.
+int dvrWriteBufferClear(DvrWriteBuffer* write_buffer);
+
+// Returns the global BufferHub id of this buffer.
 int dvrWriteBufferGetId(DvrWriteBuffer* write_buffer);
+
+// Returns an AHardwareBuffer for the underlying buffer.
 // Caller must call AHardwareBuffer_release on hardware_buffer.
 int dvrWriteBufferGetAHardwareBuffer(DvrWriteBuffer* write_buffer,
                                      AHardwareBuffer** hardware_buffer);
+
+// Posts the buffer, notifying any connected read buffers. Takes ownership of
+// |ready_fence_fd|.
 int dvrWriteBufferPost(DvrWriteBuffer* write_buffer, int ready_fence_fd,
                        const void* meta, size_t meta_size_bytes);
+
+// Gains a buffer that has been released by all connected read buffers.
 int dvrWriteBufferGain(DvrWriteBuffer* write_buffer, int* release_fence_fd);
 int dvrWriteBufferGainAsync(DvrWriteBuffer* write_buffer);
+
+// TODO(eieio): Switch to return int and take an out parameter for the native
+// handle.
 const struct native_handle* dvrWriteBufferGetNativeHandle(
     DvrWriteBuffer* write_buffer);
 
-// Read buffer
+// Creates an empty read buffer that may be filled with and actual buffer by
+// other functions.
+void dvrReadBufferCreateEmpty(DvrReadBuffer** read_buffer);
+
+// Destroys the read buffer.
 void dvrReadBufferDestroy(DvrReadBuffer* read_buffer);
+
+// Returns 1 if the given write buffer object contains a buffer, 0 otherwise.
+int dvrReadBufferIsValid(DvrReadBuffer* read_buffer);
+
+// Clears the contents of the buffer object. After a call to this function
+// dvrReadBufferIsValid on the same buffer object returns 0.
+int dvrReadBufferClear(DvrReadBuffer* read_buffer);
+
+// Returns the global BufferHub id of this buffer.
 int dvrReadBufferGetId(DvrReadBuffer* read_buffer);
+
+// Returns an AHardwareBuffer for the underlying buffer.
 // Caller must call AHardwareBuffer_release on hardware_buffer.
 int dvrReadBufferGetAHardwareBuffer(DvrReadBuffer* read_buffer,
                                     AHardwareBuffer** hardware_buffer);
+
+// Acquires the read buffer after it has been posted by the write buffer it is
+// connected to.
 int dvrReadBufferAcquire(DvrReadBuffer* read_buffer, int* ready_fence_fd,
                          void* meta, size_t meta_size_bytes);
+
+// Releases the read buffer, notifying the write buffer it is connected to.
+// Takes ownership of |release_fence_fd|.
 int dvrReadBufferRelease(DvrReadBuffer* read_buffer, int release_fence_fd);
 int dvrReadBufferReleaseAsync(DvrReadBuffer* read_buffer);
+
+// TODO(eieio): Switch to return int and take an out parameter for the native
+// handle.
 const struct native_handle* dvrReadBufferGetNativeHandle(
     DvrReadBuffer* read_buffer);
 
-// Buffer
+// Destroys the buffer.
 void dvrBufferDestroy(DvrBuffer* buffer);
+
+// Gets an AHardwareBuffer from the buffer.
 // Caller must call AHardwareBuffer_release on hardware_buffer.
 int dvrBufferGetAHardwareBuffer(DvrBuffer* buffer,
                                 AHardwareBuffer** hardware_buffer);
-const struct native_handle* dvrBufferGetNativeHandle(DvrBuffer* buffer);
-
-#ifdef __cplusplus
-}  // extern "C"
-#endif
-
-namespace android {
-namespace dvr {
 
-class BufferProducer;
-class BufferConsumer;
-class IonBuffer;
-
-DvrWriteBuffer* CreateDvrWriteBufferFromBufferProducer(
-    const std::shared_ptr<BufferProducer>& buffer_producer);
-DvrReadBuffer* CreateDvrReadBufferFromBufferConsumer(
-    const std::shared_ptr<BufferConsumer>& buffer_consumer);
-DvrBuffer* CreateDvrBufferFromIonBuffer(
-    const std::shared_ptr<IonBuffer>& ion_buffer);
+// TODO(eieio): Switch to return int and take an out parameter for the native
+// handle.
+const struct native_handle* dvrBufferGetNativeHandle(DvrBuffer* buffer);
 
-}  // namespace dvr
-}  // namespace android
+__END_DECLS
 
 #endif  // ANDROID_DVR_BUFFER_H_
index ba39513..dd669dc 100644 (file)
@@ -1,11 +1,11 @@
 #ifndef ANDROID_DVR_BUFFER_QUEUE_H_
 #define ANDROID_DVR_BUFFER_QUEUE_H_
 
+#include <sys/cdefs.h>
+
 #include <dvr/dvr_buffer.h>
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 typedef struct ANativeWindow ANativeWindow;
 
@@ -14,7 +14,8 @@ typedef struct DvrReadBufferQueue DvrReadBufferQueue;
 
 // WriteBufferQueue
 void dvrWriteBufferQueueDestroy(DvrWriteBufferQueue* write_queue);
-size_t dvrWriteBufferQueueGetCapacity(DvrWriteBufferQueue* write_queue);
+ssize_t dvrWriteBufferQueueGetCapacity(DvrWriteBufferQueue* write_queue);
+int dvrWriteBufferQueueGetId(DvrWriteBufferQueue* write_queue);
 
 // Returns ANativeWindow. Can be casted to a Java Surface using
 // ANativeWindow_toSurface NDK API. Note that this method does not acquire an
@@ -26,19 +27,18 @@ int dvrWriteBufferQueueGetExternalSurface(DvrWriteBufferQueue* write_queue,
 int dvrWriteBufferQueueCreateReadQueue(DvrWriteBufferQueue* write_queue,
                                        DvrReadBufferQueue** out_read_queue);
 int dvrWriteBufferQueueDequeue(DvrWriteBufferQueue* write_queue, int timeout,
-                               DvrWriteBuffer** out_buffer, int* out_fence_fd);
+                               DvrWriteBuffer* out_buffer, int* out_fence_fd);
 
 // ReadeBufferQueue
 void dvrReadBufferQueueDestroy(DvrReadBufferQueue* read_queue);
-size_t dvrReadBufferQueueGetCapacity(DvrReadBufferQueue* read_queue);
+ssize_t dvrReadBufferQueueGetCapacity(DvrReadBufferQueue* read_queue);
+int dvrReadBufferQueueGetId(DvrReadBufferQueue* read_queue);
 int dvrReadBufferQueueCreateReadQueue(DvrReadBufferQueue* read_queue,
                                       DvrReadBufferQueue** out_read_queue);
 int dvrReadBufferQueueDequeue(DvrReadBufferQueue* read_queue, int timeout,
-                              DvrReadBuffer** out_buffer, int* out_fence_fd,
+                              DvrReadBuffer* out_buffer, int* out_fence_fd,
                               void* out_meta, size_t meta_size_bytes);
 
-#ifdef __cplusplus
-}  // extern "C"
-#endif
+__END_DECLS
 
 #endif  // ANDROID_DVR_BUFFER_QUEUE_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_deleter.h b/libs/vr/libdvr/include/dvr/dvr_deleter.h
new file mode 100644 (file)
index 0000000..943384f
--- /dev/null
@@ -0,0 +1,86 @@
+#ifndef ANDROID_DVR_DELETER_H_
+#define ANDROID_DVR_DELETER_H_
+
+#include <sys/cdefs.h>
+
+#include <memory>
+
+// Header-only C++ helper to delete opaque DVR objects.
+
+__BEGIN_DECLS
+
+// Use forward declarations to avoid dependency on other headers.
+typedef struct DvrBuffer DvrBuffer;
+typedef struct DvrReadBuffer DvrReadBuffer;
+typedef struct DvrWriteBuffer DvrWriteBuffer;
+typedef struct DvrReadBufferQueue DvrReadBufferQueue;
+typedef struct DvrWriteBufferQueue DvrWriteBufferQueue;
+typedef struct DvrDisplayManager DvrDisplayManager;
+typedef struct DvrSurfaceState DvrSurfaceState;
+typedef struct DvrSurface DvrSurface;
+typedef struct DvrHwcClient DvrHwcClient;
+typedef struct DvrHwcFrame DvrHwcFrame;
+typedef struct DvrVSyncClient DvrVSyncClient;
+
+void dvrBufferDestroy(DvrBuffer* buffer);
+void dvrReadBufferDestroy(DvrReadBuffer* read_buffer);
+void dvrWriteBufferDestroy(DvrWriteBuffer* write_buffer);
+void dvrReadBufferQueueDestroy(DvrReadBufferQueue* read_queue);
+void dvrWriteBufferQueueDestroy(DvrWriteBufferQueue* write_queue);
+void dvrDisplayManagerDestroy(DvrDisplayManager* client);
+void dvrSurfaceStateDestroy(DvrSurfaceState* surface_state);
+void dvrSurfaceDestroy(DvrSurface* surface);
+void dvrHwcClientDestroy(DvrHwcClient* client);
+void dvrHwcFrameDestroy(DvrHwcFrame* frame);
+void dvrVSyncClientDestroy(DvrVSyncClient* client);
+
+__END_DECLS
+
+// Avoid errors if this header is included in C code.
+#if defined(__cplusplus)
+
+namespace android {
+namespace dvr {
+
+// Universal DVR object deleter. May be passed to smart pointer types to handle
+// deletion of DVR API objects.
+struct DvrObjectDeleter {
+  void operator()(DvrBuffer* p) { dvrBufferDestroy(p); }
+  void operator()(DvrReadBuffer* p) { dvrReadBufferDestroy(p); }
+  void operator()(DvrWriteBuffer* p) { dvrWriteBufferDestroy(p); }
+  void operator()(DvrReadBufferQueue* p) { dvrReadBufferQueueDestroy(p); }
+  void operator()(DvrWriteBufferQueue* p) { dvrWriteBufferQueueDestroy(p); }
+  void operator()(DvrDisplayManager* p) { dvrDisplayManagerDestroy(p); }
+  void operator()(DvrSurfaceState* p) { dvrSurfaceStateDestroy(p); }
+  void operator()(DvrSurface* p) { dvrSurfaceDestroy(p); }
+  void operator()(DvrHwcClient* p) { dvrHwcClientDestroy(p); }
+  void operator()(DvrHwcFrame* p) { dvrHwcFrameDestroy(p); }
+  void operator()(DvrVSyncClient* p) { dvrVSyncClientDestroy(p); }
+};
+
+// Helper to define unique pointers for DVR object types.
+template <typename T>
+using MakeUniqueDvrPointer = std::unique_ptr<T, DvrObjectDeleter>;
+
+// Unique pointer types for DVR objects.
+using UniqueDvrBuffer = MakeUniqueDvrPointer<DvrBuffer>;
+using UniqueDvrReadBuffer = MakeUniqueDvrPointer<DvrReadBuffer>;
+using UniqueDvrWriteBuffer = MakeUniqueDvrPointer<DvrWriteBuffer>;
+using UniqueDvrReadBufferQueue = MakeUniqueDvrPointer<DvrReadBufferQueue>;
+using UniqueDvrWriteBufferQueue = MakeUniqueDvrPointer<DvrWriteBufferQueue>;
+using UniqueDvrDisplayManager = MakeUniqueDvrPointer<DvrDisplayManager>;
+using UniqueDvrSurfaceState = MakeUniqueDvrPointer<DvrSurfaceState>;
+using UniqueDvrSurface = MakeUniqueDvrPointer<DvrSurface>;
+using UniqueDvrHwcClient = MakeUniqueDvrPointer<DvrHwcClient>;
+using UniqueDvrHwcFrame = MakeUniqueDvrPointer<DvrHwcFrame>;
+using UniqueDvrVSyncClient = MakeUniqueDvrPointer<DvrVSyncClient>;
+
+// TODO(eieio): Add an adapter for std::shared_ptr that injects the deleter into
+// the relevant constructors.
+
+}  // namespace dvr
+}  // namespace android
+
+#endif // defined(__cplusplus)
+
+#endif  // ANDROID_DVR_DELETER_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_display_manager.h b/libs/vr/libdvr/include/dvr/dvr_display_manager.h
new file mode 100644 (file)
index 0000000..d5aef8b
--- /dev/null
@@ -0,0 +1,140 @@
+#ifndef DVR_DISPLAY_MANAGER_CLIENT_H_
+#define DVR_DISPLAY_MANAGER_CLIENT_H_
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/cdefs.h>
+
+#include <dvr/dvr_display_types.h>
+#include <dvr/dvr_surface.h>
+
+__BEGIN_DECLS
+
+typedef struct DvrBuffer DvrBuffer;
+typedef struct DvrDisplayManager DvrDisplayManager;
+typedef struct DvrSurfaceState DvrSurfaceState;
+typedef struct DvrReadBufferQueue DvrReadBufferQueue;
+
+typedef uint64_t DvrSurfaceUpdateFlags;
+
+// Attempts to connect to the display manager service.
+// @return 0 on success. Otherwise returns a negative error value.
+int dvrDisplayManagerCreate(DvrDisplayManager** client_out);
+
+// Destroys the display manager client object.
+void dvrDisplayManagerDestroy(DvrDisplayManager* client);
+
+// Sets up a named buffer for shared memory data transfer between display
+// clients and the display manager.
+// @return 0 on success. Otherwise returns a negative error value.
+int dvrDisplayManagerSetupNamedBuffer(DvrDisplayManager* client,
+                                      const char* name, size_t size,
+                                      uint64_t usage, DvrBuffer** buffer_out);
+
+// Returns an fd used to signal when surface updates occur. Note that depending
+// on the underlying transport, only a subset of the real event bits may be
+// supported. Use dvrDisplayManagerClientTranslateEpollEventMask to get the real
+// event flags.
+// @return the fd on success. Otherwise returns a negative error value.
+int dvrDisplayManagerGetEventFd(DvrDisplayManager* client);
+
+// @param in_events pass in the epoll revents that were initially returned by
+// poll/epoll.
+// @param on success, this value will be overwritten with the true poll/epoll
+// values.
+// @return 0 on success. Otherwise returns a negative error value.
+int dvrDisplayManagerTranslateEpollEventMask(DvrDisplayManager* client,
+                                             int in_events, int* out_events);
+
+// Queries the display manager service for the current state of the display
+// surfaces and stores the results in the given surface state object.
+// @return 0 on success. Otherwise returns a negative error value.
+int dvrDisplayManagerGetSurfaceState(DvrDisplayManager* client,
+                                     DvrSurfaceState* surface_state);
+
+// Gets a read buffer queue from the surface |surface_id| named |queue_id|. Each
+// call returns a different read buffer queue connected to the same write buffer
+// queue. Callers should cache these instead of requesting new ones when
+// possible.
+int dvrDisplayManagerGetReadBufferQueue(DvrDisplayManager* client,
+                                        int surface_id, int queue_id,
+                                        DvrReadBufferQueue** queue_out);
+
+// Creates a new surface state object. This object may be used to receive the
+// results of a surface state query. More than one state object may be created
+// to keep multiple snapshots, if desired.
+// @return 0 on success. Otherwise returns a negative error value.
+int dvrSurfaceStateCreate(DvrSurfaceState** surface_state);
+
+// Destorys the surface state object.
+void dvrSurfaceStateDestroy(DvrSurfaceState* surface_state);
+
+// Writes the number of surfaces described in the state object into |count_out|.
+// @return 0 on success. Otherwise returns a negative error value.
+int dvrSurfaceStateGetSurfaceCount(DvrSurfaceState* surface_state,
+                                   size_t* count_out);
+
+// Returns the update flags for the surface at |surface_index| in the state
+// object. The flags may be used to determine what changes, if any, occured to
+// the surface since the last state update.
+// @return 0 on success. Otherwise returns a negative error value.
+int dvrSurfaceStateGetUpdateFlags(DvrSurfaceState* surface_state,
+                                  size_t surface_index,
+                                  DvrSurfaceUpdateFlags* flags_out);
+
+// Returns the unique identifier of surface at |surface_index| in the state
+// object. The identifier may be used to distinguish between surfaces.
+// @return 0 on success. Otherwise returns a negative error value.
+int dvrSurfaceStateGetSurfaceId(DvrSurfaceState* surface_state,
+                                size_t surface_index, int* surface_id_out);
+
+// Returns the process id of surface at |surface_index| in the state object.
+// @return 0 on success. Otherwise returns a negative error value.
+int dvrSurfaceStateGetProcessId(DvrSurfaceState* surface_state,
+                                size_t surface_index, int* process_id_out);
+
+// Writes the number of queues in the surface at |surface_index| in the state
+// object into |count_out|.
+// @return 0 on success. Otherwise returns a negative error value.
+int dvrSurfaceStateGetQueueCount(DvrSurfaceState* surface_state,
+                                 size_t surface_index, size_t* count_out);
+
+// Returns up to |max_count| queue ids for the queues belonging to the surface
+// at |surface_index| in the state object.
+// @return The number of queue ids written on success. Otherwise returns a
+// negative error value.
+ssize_t dvrSurfaceStateGetQueueIds(DvrSurfaceState* surface_state,
+                                   size_t surface_index, int* queue_ids,
+                                   size_t max_count);
+
+// Writes the z-order of the surface at |surface_index| in surface state object
+// into |z_order_out|.
+// @return 0 on success. Otherwise returns a negative error value.
+int dvrSurfaceStateGetZOrder(DvrSurfaceState* surface_state,
+                             size_t surface_index, int* z_order_out);
+
+// Writes the visible state of the surface at |surface_index| in the surface
+// state object into |visible_out|.
+// @return 0 on success. Otherwise it returns a negative error value.
+int dvrSurfaceStateGetVisible(DvrSurfaceState* surface_state,
+                              size_t surface_index, bool* visible_out);
+
+// Writes the number of attributes on the surface at |surface_index| in the
+// state object into |count_out|.
+// @return 0 on success. Otherwise it returns a negative error value.
+int dvrSurfaceStateGetAttributeCount(DvrSurfaceState* surface_state,
+                                     size_t surface_index, size_t* count_out);
+
+// Writes the list of attribute key/value pairs for the surface at
+// |surface_index| in the surface state object into |attributes|.
+// @return The number of attributes written on success. Otherwise returns a
+// negative error value.
+ssize_t dvrSurfaceStateGetAttributes(DvrSurfaceState* surface_state,
+                                     size_t surface_index,
+                                     DvrSurfaceAttribute* attributes,
+                                     size_t max_count);
+
+__END_DECLS
+
+#endif  // DVR_DISPLAY_MANAGER_CLIENT_H_
index e5228d6..58f2a10 100644 (file)
@@ -1,28 +1,90 @@
 #ifndef ANDROID_DVR_SURFACE_H_
 #define ANDROID_DVR_SURFACE_H_
 
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/cdefs.h>
+
 #include <dvr/dvr_buffer.h>
 #include <dvr/dvr_buffer_queue.h>
+#include <dvr/dvr_display_types.h>
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+__BEGIN_DECLS
 
+typedef struct DvrBuffer DvrBuffer;
 typedef struct DvrSurface DvrSurface;
-typedef struct DvrSurfaceParameter DvrSurfaceParameter;
+typedef struct DvrWriteBufferQueue DvrWriteBufferQueue;
 
-// Get a pointer to the global pose buffer.
-int dvrGetNamedBuffer(const char* name, DvrBuffer** out_buffer);
+// Attribute types. The values are one-hot encoded to support singluar types or
+// masks of supported types.
+enum {
+  DVR_SURFACE_ATTRIBUTE_TYPE_NONE = 0,
+  DVR_SURFACE_ATTRIBUTE_TYPE_INT32 = (1 << 0),
+  DVR_SURFACE_ATTRIBUTE_TYPE_INT64 = (1 << 1),
+  DVR_SURFACE_ATTRIBUTE_TYPE_BOOL = (1 << 2),
+  DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT = (1 << 3),
+  DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2 = (1 << 4),
+  DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3 = (1 << 5),
+  DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4 = (1 << 6),
+  DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8 = (1 << 7),
+  DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16 = (1 << 8),
+};
+
+typedef uint64_t DvrSurfaceAttributeType;
+typedef int32_t DvrSurfaceAttributeKey;
+
+typedef struct DvrSurfaceAttributeValue {
+  DvrSurfaceAttributeType type;
+  union {
+    int32_t int32_value;
+    int64_t int64_value;
+    bool bool_value;
+    float float_value;
+    float float2_value[2];
+    float float3_value[3];
+    float float4_value[4];
+    float float8_value[8];
+    float float16_value[16];
+  };
+} DvrSurfaceAttributeValue;
+
+typedef struct DvrSurfaceAttribute {
+  DvrSurfaceAttributeKey key;
+  DvrSurfaceAttributeValue value;
+} DvrSurfaceAttribute;
 
-int dvrSurfaceCreate(int width, int height, int format, uint64_t usage0,
-                     uint64_t usage1, int flags, DvrSurface** out_surface);
+// Creates a new display surface with the given attributes.
+// @return 0 on success. Otherwise returns a negative error value.
+int dvrSurfaceCreate(const DvrSurfaceAttribute* attributes,
+                     size_t attribute_count, DvrSurface** surface_out);
 
-// TODO(eieio, jwcai) Change this once we have multiple buffer queue support.
-int dvrSurfaceGetWriteBufferQueue(DvrSurface* surface,
-                                  DvrWriteBufferQueue** out_writer);
+// Destroys the display surface.
+void dvrSurfaceDestroy(DvrSurface* surface);
+
+// Gets the DisplayService global id for this surface.
+int dvrSurfaceGetId(DvrSurface* surface);
+
+// Sets attributes on the given display surface.
+// @return 0 on success. Otherwise returns a negative error value.
+int dvrSurfaceSetAttributes(DvrSurface* surface,
+                            const DvrSurfaceAttribute* attributes,
+                            size_t attribute_count);
+
+// Creates a new write-side buffer queue on the given surface. Direct surfaces
+// may only have one queue, the latest call replacing any prior queue. Replaced
+// queues are still referenced and should be destryoed using the queue destroy
+// API.
+// @return 0 on success. Otherwise returns a negative error value.
+int dvrSurfaceCreateWriteBufferQueue(DvrSurface* surface, uint32_t width,
+                                     uint32_t height, uint32_t format,
+                                     uint64_t usage, size_t capacity,
+                                     DvrWriteBufferQueue** queue_out);
+
+// Get a named buffer from the display service.
+// @return 0 on success. Otherwise returns a negative error value.
+int dvrGetNamedBuffer(const char* name, DvrBuffer** out_buffer);
 
-#ifdef __cplusplus
-}  // extern "C"
-#endif
+__END_DECLS
 
 #endif  // ANDROID_DVR_SURFACE_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_vsync.h b/libs/vr/libdvr/include/dvr/dvr_vsync.h
new file mode 100644 (file)
index 0000000..1eea3d9
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef ANDROID_DVR_VSYNC_H_
+#define ANDROID_DVR_VSYNC_H_
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+typedef struct DvrVSyncClient DvrVSyncClient;
+
+// Creates a new client to the system vsync service.
+int dvrVSyncClientCreate(DvrVSyncClient** client_out);
+
+// Destroys the vsync client.
+void dvrVSyncClientDestroy(DvrVSyncClient* client);
+
+// Get the estimated timestamp of the next GPU lens warp preemption event in/
+// ns. Also returns the corresponding vsync count that the next lens warp
+// operation will target.
+int dvrVSyncClientGetSchedInfo(DvrVSyncClient* client, int64_t* vsync_period_ns,
+                               int64_t* next_timestamp_ns,
+                               uint32_t* next_vsync_count);
+
+__END_DECLS
+
+#endif  // ANDROID_DVR_VSYNC_H_
diff --git a/libs/vr/libdvr/include/dvr/vsync_client_api.h b/libs/vr/libdvr/include/dvr/vsync_client_api.h
deleted file mode 100644 (file)
index 0ae5cd5..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef ANDROID_DVR_VSYNC_CLIENT_API_H_
-#define ANDROID_DVR_VSYNC_CLIENT_API_H_
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// A client of the vsync service.
-//
-// The "dvr_vsync_client" structure wraps a client connection to the
-// system vsync service. It is used to synchronize application drawing
-// with the scanout of the display.
-typedef struct dvr_vsync_client dvr_vsync_client;
-
-// Creates a new client to the system vsync service.
-dvr_vsync_client* dvr_vsync_client_create();
-
-// Destroys the vsync client.
-void dvr_vsync_client_destroy(dvr_vsync_client* client);
-
-// Get the estimated timestamp of the next GPU lens warp preemption event in
-// ns. Also returns the corresponding vsync count that the next lens warp
-// operation will target. This call has the same side effect on events as
-// Acknowledge, which saves an IPC message.
-int dvr_vsync_client_get_sched_info(dvr_vsync_client* client,
-                                    int64_t* vsync_period_ns,
-                                    int64_t* next_timestamp_ns,
-                                    uint32_t* next_vsync_count);
-
-#ifdef __cplusplus
-}  // extern "C"
-#endif
-
-#endif  // ANDROID_DVR_VSYNC_CLIENT_API_H_
index 29cdc13..d6ce99b 100644 (file)
@@ -23,6 +23,7 @@ static_libraries := \
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := \
     dvr_buffer_queue-test.cpp \
+    dvr_display_manager-test.cpp \
     dvr_named_buffer-test.cpp \
 
 LOCAL_STATIC_LIBRARIES := $(static_libraries)
index ea1273e..5f7f1bf 100644 (file)
@@ -6,6 +6,8 @@
 #include <base/logging.h>
 #include <gtest/gtest.h>
 
+#include "../dvr_internal.h"
+
 namespace android {
 namespace dvr {
 
@@ -23,9 +25,9 @@ typedef uint64_t TestMeta;
 class DvrBufferQueueTest : public ::testing::Test {
  protected:
   void SetUp() override {
-    write_queue_ = new DvrWriteBufferQueue;
-    write_queue_->producer_queue_ = ProducerQueue::Create<TestMeta>(0, 0, 0, 0);
-    ASSERT_NE(nullptr, write_queue_->producer_queue_);
+    write_queue_ = CreateDvrWriteBufferQueueFromProducerQueue(
+        ProducerQueue::Create<TestMeta>(0, 0, 0, 0));
+    ASSERT_NE(nullptr, write_queue_);
   }
 
   void TearDown() override {
@@ -38,9 +40,10 @@ class DvrBufferQueueTest : public ::testing::Test {
   void AllocateBuffers(size_t buffer_count) {
     size_t out_slot;
     for (size_t i = 0; i < buffer_count; i++) {
-      int ret = write_queue_->producer_queue_->AllocateBuffer(
-          kBufferWidth, kBufferHeight, kBufferFormat, kBufferUsage,
-          kBufferSliceCount, &out_slot);
+      int ret =
+          GetProducerQueueFromDvrWriteBufferQueue(write_queue_)
+              ->AllocateBuffer(kBufferWidth, kBufferHeight, kBufferFormat,
+                               kBufferUsage, kBufferSliceCount, &out_slot);
       ASSERT_EQ(0, ret);
     }
   }
@@ -88,6 +91,39 @@ TEST_F(DvrBufferQueueTest, TestCreateReadQueueFromReadQueue) {
   dvrReadBufferQueueDestroy(read_queue2);
 }
 
+TEST_F(DvrBufferQueueTest, CreateEmptyBuffer) {
+  AllocateBuffers(3);
+
+  DvrReadBuffer* read_buffer = nullptr;
+  DvrWriteBuffer* write_buffer = nullptr;
+
+  EXPECT_FALSE(dvrReadBufferIsValid(read_buffer));
+  EXPECT_FALSE(dvrWriteBufferIsValid(write_buffer));
+
+  dvrReadBufferCreateEmpty(&read_buffer);
+  ASSERT_NE(nullptr, read_buffer);
+
+  dvrWriteBufferCreateEmpty(&write_buffer);
+  ASSERT_NE(nullptr, write_buffer);
+
+  EXPECT_FALSE(dvrReadBufferIsValid(read_buffer));
+  EXPECT_FALSE(dvrWriteBufferIsValid(write_buffer));
+
+  DvrReadBufferQueue* read_queue = nullptr;
+
+  ASSERT_EQ(0, dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue));
+
+  const int kTimeoutMs = 0;
+  int fence_fd = -1;
+  ASSERT_EQ(0, dvrWriteBufferQueueDequeue(write_queue_, kTimeoutMs,
+                                          write_buffer, &fence_fd));
+  EXPECT_EQ(-1, fence_fd);
+  EXPECT_TRUE(dvrWriteBufferIsValid(write_buffer));
+
+  ASSERT_EQ(0, dvrWriteBufferClear(write_buffer));
+  EXPECT_FALSE(dvrWriteBufferIsValid(write_buffer));
+}
+
 TEST_F(DvrBufferQueueTest, TestDequeuePostDequeueRelease) {
   static constexpr int kTimeout = 0;
   DvrReadBufferQueue* read_queue = nullptr;
@@ -100,12 +136,18 @@ TEST_F(DvrBufferQueueTest, TestDequeuePostDequeueRelease) {
   ASSERT_EQ(0, ret);
   ASSERT_NE(nullptr, read_queue);
 
+  dvrWriteBufferCreateEmpty(&wb);
+  ASSERT_NE(nullptr, wb);
+
+  dvrReadBufferCreateEmpty(&rb);
+  ASSERT_NE(nullptr, rb);
+
   AllocateBuffers(kQueueCapacity);
 
   // Gain buffer for writing.
-  ret = dvrWriteBufferQueueDequeue(write_queue_, kTimeout, &wb, &fence_fd);
+  ret = dvrWriteBufferQueueDequeue(write_queue_, kTimeout, wb, &fence_fd);
   ASSERT_EQ(0, ret);
-  ASSERT_NE(nullptr, wb);
+  ASSERT_TRUE(dvrWriteBufferIsValid(wb));
   ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, gain buffer %p, fence_fd=%d",
            wb, fence_fd);
   pdx::LocalHandle release_fence(fence_fd);
@@ -119,10 +161,10 @@ TEST_F(DvrBufferQueueTest, TestDequeuePostDequeueRelease) {
 
   // Acquire buffer for reading.
   TestMeta acquired_seq = 0U;
-  ret = dvrReadBufferQueueDequeue(read_queue, kTimeout, &rb, &fence_fd,
+  ret = dvrReadBufferQueueDequeue(read_queue, kTimeout, rb, &fence_fd,
                                   &acquired_seq, sizeof(acquired_seq));
   ASSERT_EQ(0, ret);
-  ASSERT_NE(nullptr, rb);
+  ASSERT_TRUE(dvrReadBufferIsValid(rb));
   ASSERT_EQ(seq, acquired_seq);
   ALOGD_IF(TRACE,
            "TestDequeuePostDequeueRelease, acquire buffer %p, fence_fd=%d", rb,
@@ -156,10 +198,11 @@ TEST_F(DvrBufferQueueTest, TestGetExternalSurface) {
 
   // A write queue with DvrNativeBufferMetadata should work fine.
   std::unique_ptr<DvrWriteBufferQueue, decltype(&dvrWriteBufferQueueDestroy)>
-      write_queue(new DvrWriteBufferQueue, dvrWriteBufferQueueDestroy);
-  write_queue->producer_queue_ =
-      ProducerQueue::Create<DvrNativeBufferMetadata>(0, 0, 0, 0);
-  ASSERT_NE(nullptr, write_queue->producer_queue_);
+      write_queue(
+          CreateDvrWriteBufferQueueFromProducerQueue(
+              ProducerQueue::Create<DvrNativeBufferMetadata>(0, 0, 0, 0)),
+          dvrWriteBufferQueueDestroy);
+  ASSERT_NE(nullptr, write_queue.get());
 
   ret = dvrWriteBufferQueueGetExternalSurface(write_queue.get(), &window);
   ASSERT_EQ(0, ret);
diff --git a/libs/vr/libdvr/tests/dvr_display_manager-test.cpp b/libs/vr/libdvr/tests/dvr_display_manager-test.cpp
new file mode 100644 (file)
index 0000000..0150984
--- /dev/null
@@ -0,0 +1,539 @@
+#include <base/logging.h>
+#include <gtest/gtest.h>
+#include <poll.h>
+
+#include <android/hardware_buffer.h>
+
+#include <algorithm>
+#include <set>
+#include <thread>
+#include <vector>
+
+#include <dvr/dvr_deleter.h>
+#include <dvr/dvr_display_manager.h>
+#include <dvr/dvr_surface.h>
+
+#include <pdx/status.h>
+
+using android::pdx::ErrorStatus;
+using android::pdx::Status;
+
+namespace android {
+namespace dvr {
+
+namespace {
+
+DvrSurfaceAttribute GetAttribute(DvrSurfaceAttributeKey key, bool value) {
+  DvrSurfaceAttribute attribute;
+  attribute.key = key;
+  attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL;
+  attribute.value.bool_value = value;
+  return attribute;
+}
+
+DvrSurfaceAttribute GetAttribute(DvrSurfaceAttributeKey key, int32_t value) {
+  DvrSurfaceAttribute attribute;
+  attribute.key = key;
+  attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32;
+  attribute.value.bool_value = value;
+  return attribute;
+}
+
+Status<UniqueDvrSurface> CreateApplicationSurface(bool visible = false,
+                                                  int32_t z_order = 0) {
+  DvrSurface* surface = nullptr;
+  DvrSurfaceAttribute attributes[] = {
+      GetAttribute(DVR_SURFACE_ATTRIBUTE_Z_ORDER, z_order),
+      GetAttribute(DVR_SURFACE_ATTRIBUTE_VISIBLE, visible)};
+
+  const int ret = dvrSurfaceCreate(
+      attributes, std::extent<decltype(attributes)>::value, &surface);
+  if (ret < 0)
+    return ErrorStatus(-ret);
+  else
+    return {UniqueDvrSurface(surface)};
+}
+
+Status<UniqueDvrWriteBufferQueue> CreateSurfaceQueue(
+    const UniqueDvrSurface& surface, uint32_t width, uint32_t height,
+    uint32_t format, uint64_t usage, size_t capacity) {
+  DvrWriteBufferQueue* queue;
+  const int ret = dvrSurfaceCreateWriteBufferQueue(
+      surface.get(), width, height, format, usage, capacity, &queue);
+  if (ret < 0)
+    return ErrorStatus(-ret);
+  else
+    return {UniqueDvrWriteBufferQueue(queue)};
+}
+
+class TestDisplayManager {
+ public:
+  TestDisplayManager(UniqueDvrDisplayManager display_manager,
+                     UniqueDvrSurfaceState surface_state)
+      : display_manager_(std::move(display_manager)),
+        surface_state_(std::move(surface_state)) {
+    const int fd = dvrDisplayManagerGetEventFd(display_manager_.get());
+    LOG_IF(INFO, fd < 0) << "Failed to get event fd: " << strerror(-fd);
+    display_manager_event_fd_ = fd;
+  }
+
+  Status<UniqueDvrReadBufferQueue> GetReadBufferQueue(int surface_id,
+                                                      int queue_id) {
+    DvrReadBufferQueue* queue;
+    const int ret = dvrDisplayManagerGetReadBufferQueue(
+        display_manager_.get(), surface_id, queue_id, &queue);
+    if (ret < 0)
+      return ErrorStatus(-ret);
+    else
+      return {UniqueDvrReadBufferQueue(queue)};
+  }
+
+  Status<void> UpdateSurfaceState() {
+    const int ret = dvrDisplayManagerGetSurfaceState(display_manager_.get(),
+                                                     surface_state_.get());
+    if (ret < 0)
+      return ErrorStatus(-ret);
+    else
+      return {};
+  }
+
+  Status<void> WaitForUpdate() {
+    if (display_manager_event_fd_ < 0)
+      return ErrorStatus(-display_manager_event_fd_);
+
+    const int kTimeoutMs = 10000;  // 10s
+    pollfd pfd = {display_manager_event_fd_, POLLIN, 0};
+    const int count = poll(&pfd, 1, kTimeoutMs);
+    if (count < 0)
+      return ErrorStatus(errno);
+    else if (count == 0)
+      return ErrorStatus(ETIMEDOUT);
+
+    int events;
+    const int ret = dvrDisplayManagerTranslateEpollEventMask(
+        display_manager_.get(), pfd.revents, &events);
+    if (ret < 0)
+      return ErrorStatus(-ret);
+    else if (events & POLLIN)
+      return UpdateSurfaceState();
+    else
+      return ErrorStatus(EPROTO);
+  }
+
+  Status<size_t> GetSurfaceCount() {
+    size_t count = 0;
+    const int ret =
+        dvrSurfaceStateGetSurfaceCount(surface_state_.get(), &count);
+    if (ret < 0)
+      return ErrorStatus(-ret);
+    else
+      return {count};
+  }
+
+  Status<DvrSurfaceUpdateFlags> GetUpdateFlags(size_t surface_index) {
+    DvrSurfaceUpdateFlags update_flags;
+    const int ret = dvrSurfaceStateGetUpdateFlags(surface_state_.get(),
+                                                  surface_index, &update_flags);
+    if (ret < 0)
+      return ErrorStatus(-ret);
+    else
+      return {update_flags};
+  }
+
+  Status<int> GetSurfaceId(size_t surface_index) {
+    int surface_id;
+    const int ret = dvrSurfaceStateGetSurfaceId(surface_state_.get(),
+                                                surface_index, &surface_id);
+    if (ret < 0)
+      return ErrorStatus(-ret);
+    else
+      return {surface_id};
+  }
+
+  Status<int> GetProcessId(size_t surface_index) {
+    int process_id;
+    const int ret = dvrSurfaceStateGetProcessId(surface_state_.get(),
+                                                surface_index, &process_id);
+    if (ret < 0)
+      return ErrorStatus(-ret);
+    else
+      return {process_id};
+  }
+
+  Status<std::vector<DvrSurfaceAttribute>> GetAttributes(size_t surface_index) {
+    std::vector<DvrSurfaceAttribute> attributes;
+    size_t count = 0;
+    const int ret = dvrSurfaceStateGetAttributeCount(surface_state_.get(),
+                                                     surface_index, &count);
+    if (ret < 0)
+      return ErrorStatus(-ret);
+
+    attributes.resize(count);
+    const ssize_t return_count = dvrSurfaceStateGetAttributes(
+        surface_state_.get(), surface_index, attributes.data(), count);
+    if (return_count < 0)
+      return ErrorStatus(-return_count);
+
+    attributes.resize(return_count);
+    return {std::move(attributes)};
+  }
+
+  Status<std::vector<int>> GetQueueIds(size_t surface_index) {
+    std::vector<int> queue_ids;
+    size_t count = 0;
+    const int ret = dvrSurfaceStateGetQueueCount(surface_state_.get(),
+                                                 surface_index, &count);
+    if (ret < 0)
+      return ErrorStatus(-ret);
+
+    if (count > 0) {
+      queue_ids.resize(count);
+      const ssize_t return_count = dvrSurfaceStateGetQueueIds(
+          surface_state_.get(), surface_index, queue_ids.data(), count);
+      if (return_count < 0)
+        return ErrorStatus(-return_count);
+
+      queue_ids.resize(return_count);
+    }
+
+    return {std::move(queue_ids)};
+  }
+
+ private:
+  UniqueDvrDisplayManager display_manager_;
+  UniqueDvrSurfaceState surface_state_;
+
+  // Owned by object in display_manager_, do not explicitly close.
+  int display_manager_event_fd_;
+
+  TestDisplayManager(const TestDisplayManager&) = delete;
+  void operator=(const TestDisplayManager&) = delete;
+};
+
+class DvrDisplayManagerTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    int ret;
+    DvrDisplayManager* display_manager;
+    DvrSurfaceState* surface_state;
+
+    ret = dvrDisplayManagerCreate(&display_manager);
+    ASSERT_EQ(0, ret) << "Failed to create display manager client";
+    ASSERT_NE(nullptr, display_manager);
+
+    ret = dvrSurfaceStateCreate(&surface_state);
+    ASSERT_EQ(0, ret) << "Failed to create surface state object";
+    ASSERT_NE(nullptr, surface_state);
+
+    manager_.reset(
+        new TestDisplayManager(UniqueDvrDisplayManager(display_manager),
+                               UniqueDvrSurfaceState(surface_state)));
+  }
+  void TearDown() override {}
+
+  std::unique_ptr<TestDisplayManager> manager_;
+};
+
+// TODO(eieio): Consider moving these somewhere more central because they are
+// broadly useful.
+
+template <typename T>
+testing::AssertionResult StatusOk(const char* status_expression,
+                                  const Status<T>& status) {
+  if (!status.ok()) {
+    return testing::AssertionFailure()
+           << "(" << status_expression
+           << ") expected to indicate success but actually contains error ("
+           << status.error() << ")";
+  } else {
+    return testing::AssertionSuccess();
+  }
+}
+
+template <typename T>
+testing::AssertionResult StatusError(const char* status_expression,
+                                     const Status<T>& status) {
+  if (status.ok()) {
+    return testing::AssertionFailure()
+           << "(" << status_expression
+           << ") expected to indicate error but instead indicates success.";
+  } else {
+    return testing::AssertionSuccess();
+  }
+}
+
+template <typename T>
+testing::AssertionResult StatusHasError(const char* status_expression,
+                                        const char* /*error_code_expression*/,
+                                        const Status<T>& status,
+                                        int error_code) {
+  if (status.ok()) {
+    return StatusError(status_expression, status);
+  } else if (status.error() != error_code) {
+    return testing::AssertionFailure()
+           << "(" << status_expression << ") expected to indicate error ("
+           << error_code << ") but actually indicates error (" << status.error()
+           << ")";
+  } else {
+    return testing::AssertionSuccess();
+  }
+}
+
+template <typename T, typename U>
+testing::AssertionResult StatusHasValue(const char* status_expression,
+                                        const char* /*value_expression*/,
+                                        const Status<T>& status,
+                                        const U& value) {
+  if (!status.ok()) {
+    return StatusOk(status_expression, status);
+  } else if (status.get() != value) {
+    return testing::AssertionFailure()
+           << "(" << status_expression << ") expected to contain value ("
+           << testing::PrintToString(value) << ") but actually contains value ("
+           << testing::PrintToString(status.get()) << ")";
+  } else {
+    return testing::AssertionSuccess();
+  }
+}
+
+template <typename T, typename Op>
+testing::AssertionResult StatusPred(const char* status_expression,
+                                    const char* pred_expression,
+                                    const Status<T>& status, Op pred) {
+  if (!status.ok()) {
+    return StatusOk(status_expression, status);
+  } else if (!pred(status.get())) {
+    return testing::AssertionFailure()
+           << status_expression << " value ("
+           << testing::PrintToString(status.get())
+           << ") failed to pass predicate " << pred_expression;
+  } else {
+    return testing::AssertionSuccess();
+  }
+}
+
+#define ASSERT_STATUS_OK(status) ASSERT_PRED_FORMAT1(StatusOk, status)
+#define ASSERT_STATUS_ERROR(status) ASSERT_PRED_FORMAT1(StatusError, status)
+
+#define ASSERT_STATUS_ERROR_VALUE(value, status) \
+  ASSERT_PRED_FORMAT2(StatusHasError, status, value)
+
+#define ASSERT_STATUS_EQ(value, status) \
+  ASSERT_PRED_FORMAT2(StatusHasValue, status, value)
+
+#define EXPECT_STATUS_OK(status) EXPECT_PRED_FORMAT1(StatusOk, status)
+#define EXPECT_STATUS_ERROR(status) EXPECT_PRED_FORMAT1(StatusError, status)
+
+#define EXPECT_STATUS_ERROR_VALUE(value, status) \
+  EXPECT_PRED_FORMAT2(StatusHasError, status, value)
+
+#define EXPECT_STATUS_EQ(value, status) \
+  EXPECT_PRED_FORMAT2(StatusHasValue, status, value)
+
+#define EXPECT_STATUS_PRED(pred, status) \
+  EXPECT_PRED_FORMAT2(StatusPred, status, pred)
+
+#if 0
+// Verify utility predicate/macro functionality. This section is commented out
+// because it is designed to fail in some cases to validate the helpers.
+TEST_F(DvrDisplayManagerTest, ExpectVoid) {
+  Status<void> status_error{ErrorStatus{EINVAL}};
+  Status<void> status_ok{};
+
+  EXPECT_STATUS_ERROR(status_error);
+  EXPECT_STATUS_ERROR(status_ok);
+  EXPECT_STATUS_OK(status_error);
+  EXPECT_STATUS_OK(status_ok);
+
+  EXPECT_STATUS_ERROR_VALUE(EINVAL, status_error);
+  EXPECT_STATUS_ERROR_VALUE(ENOMEM, status_error);
+  EXPECT_STATUS_ERROR_VALUE(EINVAL, status_ok);
+  EXPECT_STATUS_ERROR_VALUE(ENOMEM, status_ok);
+}
+
+TEST_F(DvrDisplayManagerTest, ExpectInt) {
+  Status<int> status_error{ErrorStatus{EINVAL}};
+  Status<int> status_ok{10};
+
+  EXPECT_STATUS_ERROR(status_error);
+  EXPECT_STATUS_ERROR(status_ok);
+  EXPECT_STATUS_OK(status_error);
+  EXPECT_STATUS_OK(status_ok);
+
+  EXPECT_STATUS_ERROR_VALUE(EINVAL, status_error);
+  EXPECT_STATUS_ERROR_VALUE(ENOMEM, status_error);
+  EXPECT_STATUS_ERROR_VALUE(EINVAL, status_ok);
+  EXPECT_STATUS_ERROR_VALUE(ENOMEM, status_ok);
+
+  EXPECT_STATUS_EQ(10, status_error);
+  EXPECT_STATUS_EQ(20, status_error);
+  EXPECT_STATUS_EQ(10, status_ok);
+  EXPECT_STATUS_EQ(20, status_ok);
+
+  auto pred1 = [](const auto& value) { return value < 15; };
+  auto pred2 = [](const auto& value) { return value > 5; };
+  auto pred3 = [](const auto& value) { return value > 15; };
+  auto pred4 = [](const auto& value) { return value < 5; };
+
+  EXPECT_STATUS_PRED(pred1, status_error);
+  EXPECT_STATUS_PRED(pred2, status_error);
+  EXPECT_STATUS_PRED(pred3, status_error);
+  EXPECT_STATUS_PRED(pred4, status_error);
+  EXPECT_STATUS_PRED(pred1, status_ok);
+  EXPECT_STATUS_PRED(pred2, status_ok);
+  EXPECT_STATUS_PRED(pred3, status_ok);
+  EXPECT_STATUS_PRED(pred4, status_ok);
+}
+#endif
+
+TEST_F(DvrDisplayManagerTest, SurfaceCreateEvent) {
+  // Get surface state and verify there are no surfaces.
+  ASSERT_STATUS_OK(manager_->UpdateSurfaceState());
+  ASSERT_STATUS_EQ(0u, manager_->GetSurfaceCount());
+
+  // Get flags for invalid surface index.
+  EXPECT_STATUS_ERROR_VALUE(EINVAL, manager_->GetUpdateFlags(0));
+
+  // Create an application surface.
+  auto surface_status = CreateApplicationSurface();
+  ASSERT_STATUS_OK(surface_status);
+  UniqueDvrSurface surface = surface_status.take();
+  ASSERT_NE(nullptr, surface.get());
+
+  const int surface_id = dvrSurfaceGetId(surface.get());
+  ASSERT_GE(surface_id, 0);
+
+  // Now there should be one new surface.
+  ASSERT_STATUS_OK(manager_->WaitForUpdate());
+  EXPECT_STATUS_EQ(1u, manager_->GetSurfaceCount());
+
+  // Verify the new surface flag is set.
+  auto check_flags = [](const auto& value) {
+    return value & DVR_SURFACE_UPDATE_FLAGS_NEW_SURFACE;
+  };
+  EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0));
+
+  // Verify the surface id matches.
+  EXPECT_STATUS_EQ(surface_id, manager_->GetSurfaceId(0));
+
+  // Verify the owning process of the surface.
+  EXPECT_STATUS_EQ(getpid(), manager_->GetProcessId(0));
+
+  surface.reset();
+
+  ASSERT_STATUS_OK(manager_->WaitForUpdate());
+  EXPECT_STATUS_EQ(0u, manager_->GetSurfaceCount());
+}
+
+TEST_F(DvrDisplayManagerTest, SurfaceAttributeEvent) {
+  // Get surface state and verify there are no surfaces.
+  ASSERT_STATUS_OK(manager_->UpdateSurfaceState());
+  ASSERT_STATUS_EQ(0u, manager_->GetSurfaceCount());
+
+  // Get attributes for an invalid surface index.
+  EXPECT_STATUS_ERROR_VALUE(EINVAL, manager_->GetAttributes(0));
+
+  const bool kInitialVisibility = true;
+  const int32_t kInitialZOrder = 10;
+  auto surface_status =
+      CreateApplicationSurface(kInitialVisibility, kInitialZOrder);
+  ASSERT_STATUS_OK(surface_status);
+  auto surface = surface_status.take();
+  ASSERT_NE(nullptr, surface.get());
+
+  ASSERT_STATUS_OK(manager_->WaitForUpdate());
+  ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount());
+
+  // Check the initial attribute values.
+  auto attribute_status = manager_->GetAttributes(0);
+  ASSERT_STATUS_OK(attribute_status);
+  auto attributes = attribute_status.take();
+  EXPECT_GE(attributes.size(), 2u);
+
+  const std::set<int32_t> expected_keys = {DVR_SURFACE_ATTRIBUTE_Z_ORDER,
+                                           DVR_SURFACE_ATTRIBUTE_VISIBLE};
+
+  // Collect all the keys in attributes that match the expected keys.
+  std::set<int32_t> actual_keys;
+  std::for_each(attributes.begin(), attributes.end(),
+                [&expected_keys, &actual_keys](const auto& attribute) {
+                  if (expected_keys.find(attribute.key) != expected_keys.end())
+                    actual_keys.emplace(attribute.key);
+                });
+
+  // If the sets match then attributes contained at least the expected keys,
+  // even if other keys were also present.
+  EXPECT_EQ(expected_keys, actual_keys);
+}
+
+TEST_F(DvrDisplayManagerTest, SurfaceQueueEvent) {
+  // Create an application surface.
+  auto surface_status = CreateApplicationSurface();
+  ASSERT_STATUS_OK(surface_status);
+  UniqueDvrSurface surface = surface_status.take();
+  ASSERT_NE(nullptr, surface.get());
+
+  const int surface_id = dvrSurfaceGetId(surface.get());
+  ASSERT_GE(surface_id, 0);
+  // Get surface state and verify there is one surface.
+  ASSERT_STATUS_OK(manager_->WaitForUpdate());
+  ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount());
+
+  // Verify there are no queues for the surface recorded in the state snapshot.
+  EXPECT_STATUS_EQ(std::vector<int>{}, manager_->GetQueueIds(0));
+
+  // Create a new queue in the surface.
+  auto write_queue_status = CreateSurfaceQueue(
+      surface, 320, 240, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
+      AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, 1);
+  ASSERT_STATUS_OK(write_queue_status);
+  UniqueDvrWriteBufferQueue write_queue = write_queue_status.take();
+  ASSERT_NE(nullptr, write_queue.get());
+
+  const int queue_id = dvrWriteBufferQueueGetId(write_queue.get());
+  ASSERT_GE(queue_id, 0);
+
+  // Update surface state.
+  ASSERT_STATUS_OK(manager_->WaitForUpdate());
+  ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount());
+
+  // Verify the buffers changed flag is set.
+  auto check_flags = [](const auto& value) {
+    return value & DVR_SURFACE_UPDATE_FLAGS_BUFFERS_CHANGED;
+  };
+  EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0));
+
+  auto queue_ids_status = manager_->GetQueueIds(0);
+  ASSERT_STATUS_OK(queue_ids_status);
+
+  auto queue_ids = queue_ids_status.take();
+  ASSERT_EQ(1u, queue_ids.size());
+  EXPECT_EQ(queue_id, queue_ids[0]);
+
+  auto read_queue_status = manager_->GetReadBufferQueue(surface_id, queue_id);
+  ASSERT_STATUS_OK(read_queue_status);
+  UniqueDvrReadBufferQueue read_queue = read_queue_status.take();
+  ASSERT_NE(nullptr, read_queue.get());
+  EXPECT_EQ(queue_id, dvrReadBufferQueueGetId(read_queue.get()));
+
+  write_queue.reset();
+
+  // Verify that destroying the queue generates a surface update event.
+  ASSERT_STATUS_OK(manager_->WaitForUpdate());
+  ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount());
+
+  // Verify that the buffers changed flag is set.
+  EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0));
+
+  // Verify that the queue ids reflect the change.
+  queue_ids_status = manager_->GetQueueIds(0);
+  ASSERT_STATUS_OK(queue_ids_status);
+
+  queue_ids = queue_ids_status.take();
+  ASSERT_EQ(0u, queue_ids.size());
+}
+
+}  // namespace
+
+}  // namespace dvr
+}  // namespace android
index 6a02342..e65f6d5 100644 (file)
@@ -1,6 +1,6 @@
 #include <android/hardware_buffer.h>
-#include <dvr/display_manager_client.h>
 #include <dvr/dvr_buffer.h>
+#include <dvr/dvr_display_manager.h>
 #include <dvr/dvr_surface.h>
 #include <system/graphics.h>
 
@@ -15,28 +15,31 @@ namespace {
 class DvrNamedBufferTest : public ::testing::Test {
  protected:
   void SetUp() override {
-    client_ = dvrDisplayManagerClientCreate();
+    const int ret = dvrDisplayManagerCreate(&client_);
+    ASSERT_EQ(0, ret);
     ASSERT_NE(nullptr, client_);
   }
 
   void TearDown() override {
-    if (client_ != nullptr) {
-      dvrDisplayManagerClientDestroy(client_);
-      client_ = nullptr;
-    }
+    dvrDisplayManagerDestroy(client_);
+    client_ = nullptr;
   }
 
-  DvrDisplayManagerClient* client_ = nullptr;
+  DvrDisplayManager* client_ = nullptr;
 };
 
 TEST_F(DvrNamedBufferTest, TestNamedBuffersSameName) {
   const char* buffer_name = "same_name";
-  DvrBuffer* buffer1 =
-      dvrDisplayManagerSetupNamedBuffer(client_, buffer_name, 10, 0, 0);
+  DvrBuffer* buffer1 = nullptr;
+  int ret1 =
+      dvrDisplayManagerSetupNamedBuffer(client_, buffer_name, 10, 0, &buffer1);
+  ASSERT_EQ(0, ret1);
   ASSERT_NE(nullptr, buffer1);
 
-  DvrBuffer* buffer2 =
-      dvrDisplayManagerSetupNamedBuffer(client_, buffer_name, 10, 0, 0);
+  DvrBuffer* buffer2 = nullptr;
+  int ret2 =
+      dvrDisplayManagerSetupNamedBuffer(client_, buffer_name, 10, 0, &buffer2);
+  ASSERT_EQ(0, ret1);
   ASSERT_NE(nullptr, buffer2);
 
   AHardwareBuffer* hardware_buffer1 = nullptr;
@@ -95,13 +98,17 @@ TEST_F(DvrNamedBufferTest, TestNamedBuffersSameName) {
 TEST_F(DvrNamedBufferTest, TestMultipleNamedBuffers) {
   const char* buffer_name1 = "test1";
   const char* buffer_name2 = "test2";
-  DvrBuffer* setup_buffer1 =
-      dvrDisplayManagerSetupNamedBuffer(client_, buffer_name1, 10, 0, 0);
+  DvrBuffer* setup_buffer1 = nullptr;
+  int ret1 = dvrDisplayManagerSetupNamedBuffer(client_, buffer_name1, 10, 0,
+                                               &setup_buffer1);
+  ASSERT_EQ(0, ret1);
   ASSERT_NE(nullptr, setup_buffer1);
   dvrBufferDestroy(setup_buffer1);
 
-  DvrBuffer* setup_buffer2 =
-      dvrDisplayManagerSetupNamedBuffer(client_, buffer_name2, 10, 0, 0);
+  DvrBuffer* setup_buffer2 = nullptr;
+  int ret2 = dvrDisplayManagerSetupNamedBuffer(client_, buffer_name2, 10, 0,
+                                               &setup_buffer2);
+  ASSERT_EQ(0, ret2);
   ASSERT_NE(nullptr, setup_buffer2);
   dvrBufferDestroy(setup_buffer2);
 
@@ -126,11 +133,13 @@ TEST_F(DvrNamedBufferTest, TestNamedBufferUsage) {
   // GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, and these two values are different.
   // If all is good, when we get the AHardwareBuffer, it should be converted
   // back to AHARDWAREBUFFER_USAGE_VIDEO_ENCODE.
-  const int64_t usage = AHARDWAREBUFFER_USAGE_VIDEO_ENCODE;
+  const uint64_t usage = AHARDWAREBUFFER_USAGE_VIDEO_ENCODE;
 
-  DvrBuffer* setup_buffer =
-      dvrDisplayManagerSetupNamedBuffer(client_, buffer_name, 10, usage, 0);
+  DvrBuffer* setup_buffer = nullptr;
+  int e1 = dvrDisplayManagerSetupNamedBuffer(client_, buffer_name, 10, usage,
+                                             &setup_buffer);
   ASSERT_NE(nullptr, setup_buffer);
+  ASSERT_EQ(0, e1);
 
   AHardwareBuffer* hardware_buffer = nullptr;
   int e2 = dvrBufferGetAHardwareBuffer(setup_buffer, &hardware_buffer);
@@ -139,14 +148,12 @@ TEST_F(DvrNamedBufferTest, TestNamedBufferUsage) {
 
   AHardwareBuffer_Desc desc = {};
   AHardwareBuffer_describe(hardware_buffer, &desc);
-
-  ASSERT_EQ(desc.usage, AHARDWAREBUFFER_USAGE_VIDEO_ENCODE);
+  ASSERT_EQ(usage, desc.usage);
 
   dvrBufferDestroy(setup_buffer);
   AHardwareBuffer_release(hardware_buffer);
 }
 
-
 }  // namespace
 
 }  // namespace dvr
diff --git a/libs/vr/libdvr/vsync_client_api.cpp b/libs/vr/libdvr/vsync_client_api.cpp
deleted file mode 100644 (file)
index dbddd3d..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#include "include/dvr/vsync_client_api.h"
-
-#include <private/dvr/vsync_client.h>
-
-extern "C" {
-
-dvr_vsync_client* dvr_vsync_client_create() {
-  auto client = android::dvr::VSyncClient::Create();
-  return static_cast<dvr_vsync_client*>(client.release());
-}
-
-void dvr_vsync_client_destroy(dvr_vsync_client* client) {
-  delete static_cast<android::dvr::VSyncClient*>(client);
-}
-
-int dvr_vsync_client_get_sched_info(dvr_vsync_client* client,
-                                    int64_t* vsync_period_ns,
-                                    int64_t* next_timestamp_ns,
-                                    uint32_t* next_vsync_count) {
-  return static_cast<android::dvr::VSyncClient*>(client)->GetSchedInfo(
-      vsync_period_ns, next_timestamp_ns, next_vsync_count);
-}
-
-}  // extern "C"
index 632978b..dc81c60 100644 (file)
 
 sourceFiles = [
     "acquired_buffer.cpp",
-    "compositor.cpp",
-    "debug_hud_data.cpp",
-    "debug_hud_view.cpp",
+    "epoll_event_dispatcher.cpp",
     "display_manager_service.cpp",
     "display_service.cpp",
     "display_surface.cpp",
     "hardware_composer.cpp",
-    "screenshot_service.cpp",
-    "surface_channel.cpp",
-    "video_compositor.cpp",
-    "video_mesh_surface.cpp",
     "vr_flinger.cpp",
     "vsync_service.cpp",
 ]
index 5a3aa7f..7932a9c 100644 (file)
@@ -9,7 +9,7 @@ namespace android {
 namespace dvr {
 
 AcquiredBuffer::AcquiredBuffer(const std::shared_ptr<BufferConsumer>& buffer,
-                               LocalHandle acquire_fence, uint64_t /*sequence*/)
+                               LocalHandle acquire_fence)
     : buffer_(buffer), acquire_fence_(std::move(acquire_fence)) {}
 
 AcquiredBuffer::AcquiredBuffer(const std::shared_ptr<BufferConsumer>& buffer,
index 1d14a38..dd4fcc5 100644 (file)
@@ -21,7 +21,7 @@ class AcquiredBuffer {
   // this constructor; the constructor does not attempt to ACQUIRE the buffer
   // itself.
   AcquiredBuffer(const std::shared_ptr<BufferConsumer>& buffer,
-                 pdx::LocalHandle acquire_fence, uint64_t sequence);
+                 pdx::LocalHandle acquire_fence);
 
   // Constructs an AcquiredBuffer from a BufferConsumer. The BufferConsumer MUST
   // be in the POSTED state prior to calling this constructor, as this
diff --git a/libs/vr/libvrflinger/compositor.cpp b/libs/vr/libvrflinger/compositor.cpp
deleted file mode 100644 (file)
index d1d4f45..0000000
+++ /dev/null
@@ -1,878 +0,0 @@
-#include "compositor.h"
-
-#include <EGL/eglext.h>
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-#include <GLES2/gl2.h>
-
-#include <memory>
-
-#include <cutils/properties.h>
-
-#include <dvr/graphics.h>
-#include <private/dvr/buffer_hub_client.h>
-#include <private/dvr/clock_ns.h>
-#include <private/dvr/debug.h>
-#include <private/dvr/device_metrics.h>
-#include <private/dvr/display_types.h>
-#include <private/dvr/dummy_native_window.h>
-#include <private/dvr/gl_fenced_flush.h>
-#include <private/dvr/graphics/blur.h>
-#include <private/dvr/graphics/gpu_profiler.h>
-#include <private/dvr/native_buffer.h>
-#include <private/dvr/platform_defines.h>
-#include <utils/Log.h>
-#include <utils/Trace.h>
-
-#include "debug_hud_data.h"
-#include "debug_hud_view.h"
-#include "display_surface.h"
-
-#define BINNING_CONTROL_HINT_QCOM 0x8FB0
-
-// Accepted by the <hint> parameter of glHint:
-#define BINNING_QCOM 0x8FB1
-#define VISIBILITY_OPTIMIZED_BINNING_QCOM 0x8FB2
-#define RENDER_DIRECT_TO_FRAMEBUFFER_QCOM 0x8FB3
-
-#ifndef EGL_CONTEXT_MAJOR_VERSION
-#define EGL_CONTEXT_MAJOR_VERSION 0x3098
-#define EGL_CONTEXT_MINOR_VERSION 0x30FB
-#endif
-
-using android::pdx::LocalHandle;
-
-static const int kDistortionMeshResolution = 40;
-
-static std::shared_ptr<int64_t> eds_gpu_duration_ns =
-    std::make_shared<int64_t>(0);
-
-static constexpr char kDisableLensDistortionProp[] =
-    "persist.dvr.disable_distort";
-
-static constexpr char kEnableEdsPoseSaveProp[] =
-    "persist.dvr.save_eds_pose";
-
-namespace android {
-namespace dvr {
-
-namespace {
-
-// An implementation of ANativeWindowBuffer backed by a temporary IonBuffer.
-// Do not hold on to this kind of object, because the IonBuffer may become
-// invalid in other scopes.
-class TemporaryNativeBuffer
-    : public ANativeObjectBase<ANativeWindowBuffer, TemporaryNativeBuffer,
-                               LightRefBase<TemporaryNativeBuffer>> {
- public:
-  explicit TemporaryNativeBuffer(const IonBuffer* buffer) : BASE() {
-    ANativeWindowBuffer::width = buffer->width();
-    ANativeWindowBuffer::height = buffer->height();
-    ANativeWindowBuffer::stride = buffer->stride();
-    ANativeWindowBuffer::format = buffer->format();
-    ANativeWindowBuffer::usage = buffer->usage();
-    // TODO(eieio): Update NYC to support layer_count.
-    // ANativeWindowBuffer::layer_count = 1;
-    handle = buffer->handle();
-  }
-
- private:
-  friend class android::LightRefBase<TemporaryNativeBuffer>;
-
-  TemporaryNativeBuffer(const TemporaryNativeBuffer&) = delete;
-  void operator=(TemporaryNativeBuffer&) = delete;
-};
-
-std::vector<uint8_t> ReadTextureRGBA(GLuint texture_id, int width, int height) {
-  std::vector<uint8_t> data(width * height * 4);
-  GLuint fbo;
-  glGenFramebuffers(1, &fbo);
-  glBindFramebuffer(GL_FRAMEBUFFER, fbo);
-  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-                         texture_id, 0);
-  // Using default GL_PACK_ALIGNMENT of 4 for the 4 byte source data.
-  glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data.data());
-  glBindFramebuffer(GL_FRAMEBUFFER, 0);
-  glDeleteFramebuffers(1, &fbo);
-  CHECK_GL();
-  return data;
-}
-
-}  // namespace
-
-class Compositor::Texture {
- public:
-  Texture(std::shared_ptr<BufferConsumer> consumer, EGLDisplay display,
-          int index);
-  ~Texture();
-
-  std::shared_ptr<BufferConsumer> consumer() const { return consumer_; }
-  GLuint texture_id() const { return texture_id_; }
-  vec2i size() const {
-    return vec2i(native_buffer_.get()->width, native_buffer_.get()->height);
-  }
-  int index() const { return index_; }
-
-  bool Initialize();
-
- private:
-  Texture(const Texture&) = delete;
-  void operator=(const Texture&) = delete;
-
-  std::shared_ptr<BufferConsumer> consumer_;
-
-  android::sp<NativeBufferConsumer> native_buffer_;
-
-  EGLDisplay display_;
-  EGLImageKHR image_;
-  GLuint texture_id_;
-  int index_;
-};
-
-Compositor::Texture::Texture(std::shared_ptr<BufferConsumer> consumer,
-                             EGLDisplay display, int index)
-    : consumer_(consumer),
-      display_(display),
-      image_(nullptr),
-      texture_id_(0),
-      index_(index) {}
-
-Compositor::Texture::~Texture() {
-  glDeleteTextures(1, &texture_id_);
-  eglDestroyImageKHR(display_, image_);
-}
-
-bool Compositor::Texture::Initialize() {
-  native_buffer_ = new NativeBufferConsumer(consumer_, index_);
-
-  CHECK_GL();
-  image_ = eglCreateImageKHR(
-      display_, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
-      static_cast<ANativeWindowBuffer*>(native_buffer_.get()), nullptr);
-  if (!image_) {
-    ALOGE("Failed to create EGLImage\n");
-    return false;
-  }
-
-  glGenTextures(1, &texture_id_);
-  glActiveTexture(GL_TEXTURE0);
-  glBindTexture(GL_TEXTURE_2D, texture_id_);
-  glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image_);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-  CHECK_GL();
-  return true;
-}
-
-Compositor::RenderTarget::RenderTarget()
-    : buffer_texture_id_(0),
-      buffer_framebuffer_id_(0),
-      buffer_image_(nullptr) {}
-
-Compositor::RenderTarget::~RenderTarget() { Destroy(); }
-
-void Compositor::RenderTarget::Destroy() {
-  glDeleteFramebuffers(1, &buffer_framebuffer_id_);
-  glDeleteTextures(1, &buffer_texture_id_);
-  eglDestroyImageKHR(eglGetDisplay(EGL_DEFAULT_DISPLAY), buffer_image_);
-  buffer_texture_id_ = 0;
-  buffer_framebuffer_id_ = 0;
-  buffer_image_ = nullptr;
-}
-
-void Compositor::RenderTarget::Initialize(int width, int height) {
-  LOG_ALWAYS_FATAL_IF(buffer_texture_id_ || buffer_framebuffer_id_ ||
-                      buffer_image_);
-  constexpr int usage = GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_COMPOSER |
-                        GRALLOC_USAGE_HW_RENDER |
-                        GRALLOC_USAGE_QCOM_FRAMEBUFFER_COMPRESSION;
-  buffer_ = std::make_shared<IonBuffer>(width, height,
-                                        HAL_PIXEL_FORMAT_RGBA_8888, usage);
-
-  native_buffer_ = new NativeBuffer(buffer_);
-
-  buffer_image_ = eglCreateImageKHR(
-      eglGetDisplay(EGL_DEFAULT_DISPLAY), EGL_NO_CONTEXT,
-      EGL_NATIVE_BUFFER_ANDROID,
-      static_cast<ANativeWindowBuffer*>(native_buffer_.get()), nullptr);
-
-  glGenTextures(1, &buffer_texture_id_);
-  glBindTexture(GL_TEXTURE_2D, buffer_texture_id_);
-  CHECK_GL();
-
-  glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, buffer_image_);
-  CHECK_GL();
-
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-  glBindTexture(GL_TEXTURE_2D, 0);
-
-  // Generate a framebuffer.
-  glGenFramebuffers(1, &buffer_framebuffer_id_);
-  glBindFramebuffer(GL_FRAMEBUFFER, buffer_framebuffer_id_);
-  CHECK_GL();
-
-  // Attach the color buffer
-  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-                         buffer_texture_id_, 0);
-  CHECK_GL();
-  GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
-  CHECK_GL();
-  if (result != GL_FRAMEBUFFER_COMPLETE) {
-    ALOGE("Framebuffer incomplete: %d", result);
-  }
-
-  // Clear the render target to black once. In direct render mode we never draw
-  // the corner pixels.
-  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-  glClear(GL_COLOR_BUFFER_BIT);
-  glFlush();
-
-  glBindFramebuffer(GL_FRAMEBUFFER, 0);
-  CHECK_GL();
-}
-
-void Compositor::RenderTarget::BindFramebuffer() {
-  glBindFramebuffer(GL_FRAMEBUFFER, buffer_framebuffer_id_);
-}
-
-void Compositor::RenderTarget::DiscardColorAttachment() {
-  GLenum attachment = GL_COLOR_ATTACHMENT0;
-  glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, &attachment);
-  CHECK_GL();
-}
-
-class Compositor::RenderPoseBufferObject {
- public:
-  RenderPoseBufferObject(LocalHandle&& render_pose_buffer_fd) :
-      fd_(std::move(render_pose_buffer_fd)) {
-    // Create new pose tracking buffer for this surface.
-    glGenBuffers(1, &render_pose_buffer_object_);
-    glBindBuffer(GL_UNIFORM_BUFFER, render_pose_buffer_object_);
-    if (fd_) {
-      LOG_ALWAYS_FATAL_IF(!glBindSharedBufferQCOM);
-      if (glBindSharedBufferQCOM)
-        glBindSharedBufferQCOM(GL_UNIFORM_BUFFER,
-                               sizeof(DisplaySurfaceMetadata),
-                               fd_.Get());
-      else
-        ALOGE("Error: Missing gralloc buffer extension");
-      CHECK_GL();
-    }
-    glBindBuffer(GL_UNIFORM_BUFFER, 0);
-  }
-
-  ~RenderPoseBufferObject() { glDeleteBuffers(1, &render_pose_buffer_object_); }
-
-  GLuint object_id() const { return render_pose_buffer_object_; }
-
- private:
-  // Render pose buffer object. This contains an array of poses that corresponds
-  // with the surface buffers.
-  GLuint render_pose_buffer_object_;
-  LocalHandle fd_;
-
-  RenderPoseBufferObject(const RenderPoseBufferObject&) = delete;
-  void operator=(const RenderPoseBufferObject&) = delete;
-};
-
-HeadMountMetrics CreateDefaultHeadMountMetrics() {
-  const bool enable_distortion =
-      property_get_bool(kDisableLensDistortionProp, 0) == 0;
-  return enable_distortion ? CreateHeadMountMetrics()
-                           : CreateUndistortedHeadMountMetrics();
-}
-
-Compositor::Compositor()
-    : head_mount_metrics_(CreateDefaultHeadMountMetrics()),
-      display_(0),
-      config_(0),
-      surface_(0),
-      context_(0),
-      active_render_target_(0),
-      is_render_direct_(false),
-      compute_fbo_(0),
-      compute_fbo_texture_(0),
-      hmd_metrics_requires_update_(false),
-      eds_pose_capture_enabled_(false) {}
-
-Compositor::~Compositor() {}
-
-bool Compositor::Initialize(const DisplayMetrics& display_metrics) {
-  ATRACE_NAME("Compositor::Initialize");
-  if (!InitializeEGL())
-    return false;
-
-  display_metrics_ = display_metrics;
-  const int width = display_metrics_.GetSizePixels().x();
-  const int height = display_metrics_.GetSizePixels().y();
-
-  render_target_[0].Initialize(width, height);
-  render_target_[1].Initialize(width, height);
-
-  // EDS:
-  GpuProfiler::Get()->SetEnableGpuTracing(true);
-
-  eds_pose_capture_enabled_ = property_get_bool(kEnableEdsPoseSaveProp, 0) == 1;
-
-  CheckAndUpdateHeadMountMetrics(true);
-
-  debug_hud_.reset(new DebugHudView(*composite_hmd_.get()));
-  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
-  return true;
-}
-
-void Compositor::UpdateHeadMountMetrics(
-    const HeadMountMetrics& head_mount_metrics) {
-  // Recalculating the mesh must be done in the draw loop, defer until then.
-  std::lock_guard<std::mutex> _lock(mutex_);
-  head_mount_metrics_ = head_mount_metrics;
-  hmd_metrics_requires_update_ = true;
-}
-
-void Compositor::CheckAndUpdateHeadMountMetrics(bool force_update) {
-  std::lock_guard<std::mutex> _lock(mutex_);
-  if (hmd_metrics_requires_update_ || force_update) {
-    hmd_metrics_requires_update_ = false;
-    composite_hmd_.reset(
-        new CompositeHmd(head_mount_metrics_, display_metrics_));
-    CHECK_GL();
-    eds_renderer_.reset(new DistortionRenderer(
-        *composite_hmd_.get(), display_metrics_.GetSizePixels(),
-        kDistortionMeshResolution, true, false, false, true, true));
-  }
-}
-
-bool Compositor::InitializeEGL() {
-  ATRACE_NAME("Compositor::InitializeEGL");
-  display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-  if (!display_) {
-    ALOGE("Failed to get egl display\n");
-    return false;
-  }
-
-  eglInitialize(display_, nullptr, nullptr);
-
-  EGLint attribs[] = {
-      EGL_BUFFER_SIZE,
-      32,
-      EGL_ALPHA_SIZE,
-      0,
-      EGL_BLUE_SIZE,
-      8,
-      EGL_RED_SIZE,
-      8,
-      EGL_GREEN_SIZE,
-      8,
-      EGL_DEPTH_SIZE,
-      0,
-      EGL_SURFACE_TYPE,
-      EGL_WINDOW_BIT,
-      EGL_RENDERABLE_TYPE,
-      EGL_OPENGL_ES2_BIT,
-      EGL_NONE,
-  };
-
-  EGLint num_configs;
-  if (!eglChooseConfig(display_, attribs, &config_, 1, &num_configs)) {
-    ALOGE("Couldn't find config");
-    return false;
-  }
-
-  std::unique_ptr<DummyNativeWindow> window(new DummyNativeWindow());
-
-  surface_ = eglCreateWindowSurface(display_, config_, window.get(), nullptr);
-  if (surface_ == EGL_NO_SURFACE) {
-    ALOGE("Failed to create egl surface");
-    return false;
-  }
-  window.release();
-
-  EGLint context_attribs[] = {EGL_CONTEXT_MAJOR_VERSION,
-                              3,
-                              EGL_CONTEXT_MINOR_VERSION,
-                              1,
-                              EGL_CONTEXT_PRIORITY_LEVEL_IMG,
-                              EGL_CONTEXT_PRIORITY_HIGH_IMG,
-                              EGL_NONE};
-  context_ = eglCreateContext(display_, config_, nullptr, context_attribs);
-  if (!eglMakeCurrent(display_, surface_, surface_, context_)) {
-    ALOGE("Unable to create GLESv2 context");
-    return false;
-  }
-
-  load_gl_extensions();
-  GpuProfiler::Get()->OnGlContextCreated();
-
-  glEnable(BINNING_CONTROL_HINT_QCOM);
-  glHint(BINNING_CONTROL_HINT_QCOM, RENDER_DIRECT_TO_FRAMEBUFFER_QCOM);
-  is_render_direct_ = true;
-  CHECK_GL();
-
-  // Initialize the placeholder 1x1 framebuffer that we bind during compute
-  // shader instances to avoid accesses to other framebuffers.
-  glGenFramebuffers(1, &compute_fbo_);
-  glGenTextures(1, &compute_fbo_texture_);
-  glBindFramebuffer(GL_FRAMEBUFFER, compute_fbo_);
-  glBindTexture(GL_TEXTURE_2D, compute_fbo_texture_);
-  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-               nullptr);
-  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-                         compute_fbo_texture_, 0);
-  CHECK_GL();
-  CHECK_GL_FBO();
-  glBindTexture(GL_TEXTURE_2D, 0);
-  glBindFramebuffer(GL_FRAMEBUFFER, 0);
-
-  return true;
-}
-
-void Compositor::Shutdown() {
-  glFinish();
-  render_target_[0].Destroy();
-  render_target_[1].Destroy();
-  layers_.clear();
-  glDeleteFramebuffers(1, &compute_fbo_);
-  glDeleteTextures(1, &compute_fbo_texture_);
-
-  debug_hud_.reset();
-  eds_renderer_.reset();
-
-  if (context_) {
-    GpuProfiler::Get()->OnGlContextDestroyed();
-    eglDestroyContext(display_, context_);
-    context_ = 0;
-  }
-
-  if (surface_ != EGL_NO_SURFACE) {
-    eglDestroySurface(display_, surface_);
-    surface_ = EGL_NO_SURFACE;
-  }
-}
-
-void Compositor::RemoveAllBuffers() { layers_.clear(); }
-
-void Compositor::UpdateSurfaces(
-    const std::vector<std::shared_ptr<DisplaySurface>>& surfaces) {
-  // Delete the removed surfaces.
-  layers_.erase(
-      std::remove_if(layers_.begin(), layers_.end(),
-                     [&surfaces](const AppFrame& layer) {
-                       for (const auto& surface : surfaces)
-                         if (surface->surface_id() == layer.surface_id())
-                           return false;
-                       return true;
-                     }),
-      layers_.end());
-  // New surfaces are added on-demand as buffers are posted.
-}
-
-Compositor::AppFrame::AppFrame()
-    : surface_id_(-1),
-      blur_(0.0f),
-      z_order_(0),
-      vertical_flip_(false),
-      enable_cac_(true),
-      render_buffer_index_(0) {}
-
-Compositor::AppFrame::~AppFrame() {}
-
-const Compositor::Texture* Compositor::AppFrame::GetGlTextureId(
-    EGLDisplay display, int index) {
-  auto buffer_consumer = buffer_.buffer();
-  if (!buffer_consumer) {
-    return nullptr;
-  }
-  auto texture_it = std::find_if(
-      textures_.begin(), textures_.end(),
-      [buffer_consumer, index](const std::shared_ptr<Texture>& t) {
-        return t->consumer() == buffer_consumer && t->index() == index;
-      });
-
-  if (texture_it != textures_.end()) {
-    return (*texture_it).get();
-  }
-
-  textures_.push_back(
-      std::make_shared<Texture>(buffer_consumer, display, index));
-  if (!textures_.back()->Initialize()) {
-    textures_.pop_back();
-    return nullptr;
-  }
-  return textures_.back().get();
-}
-
-bool Compositor::AppFrame::UpdateSurface(
-    const std::shared_ptr<DisplaySurface>& surface) {
-  int surface_id = surface->surface_id();
-  float blur = surface->manager_blur();
-  bool need_sort = false;
-  if (z_order_ != surface->layer_order()) {
-    need_sort = true;
-    z_order_ = surface->layer_order();
-  }
-
-  surface_id_ = surface_id;
-  if (!render_pose_buffer_object_) {
-    render_pose_buffer_object_.reset(
-        new RenderPoseBufferObject(surface->GetMetadataBufferFd()));
-  }
-
-  blur_ = blur;
-  vertical_flip_ =
-      !!(surface->flags() & DVR_DISPLAY_SURFACE_FLAGS_VERTICAL_FLIP);
-  enable_cac_ =
-      !(surface->flags() & DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_CAC);
-
-  AcquiredBuffer skipped_buffer;
-  AcquiredBuffer buffer =
-      surface->AcquireNewestAvailableBuffer(&skipped_buffer);
-  if (!skipped_buffer.IsEmpty()) {
-    DebugHudData::data.SkipLayerFrame(z_order_);
-    ATRACE_NAME("DropToCatchUp");
-    ATRACE_ASYNC_END("BufferPost", skipped_buffer.buffer()->id());
-  }
-  if (!buffer.IsEmpty()) {
-    DebugHudData::data.AddLayerFrame(z_order_);
-    // Buffer was already ready, so we don't need to wait on the fence.
-    buffer.ClaimAcquireFence().Close();
-    ATRACE_ASYNC_END("BufferPost", buffer.buffer()->id());
-
-    render_buffer_index_ = surface->GetRenderBufferIndex(buffer.buffer()->id());
-
-#ifdef TRACE
-    const volatile DisplaySurfaceMetadata* data =
-        surface->GetMetadataBufferPtr();
-#endif
-    ALOGE_IF(TRACE, "read pose index %d %f %f", render_buffer_index_,
-             data->orientation[render_buffer_index_][0],
-             data->orientation[render_buffer_index_][1]);
-
-    // Move the new buffer over the old. AcquiredBuffer releases the old one.
-    buffer_ = std::move(buffer);
-  }
-  return need_sort;
-}
-
-void Compositor::AppFrame::UpdateVideoMeshSurface(
-    const std::shared_ptr<DisplaySurface>& surface) {
-  // Update |video_compositors_| with |video_surface|. Note that
-  // |UpdateVideoMeshSurface| should only be called on the PostThread before
-  // |DrawFrame| is called. Thus, no synchronization is required for
-  // |video_compositors_|.
-  if (!surface->video_mesh_surfaces_updated())
-    return;
-
-  // TODO(jwcai) The following loop handles adding new surfaces; video mesh
-  // removal logic shall be handled by listening to |OnChannelClose| event from
-  // DisplayService.
-  for (const auto& video_surface : surface->GetVideoMeshSurfaces()) {
-    // Here we assume number of |video_surface|s is relatively small, thus, the
-    // merge should be efficient enough.
-    auto video_compositor_it = std::find_if(
-        video_compositors_.begin(), video_compositors_.end(),
-        [video_surface](const std::shared_ptr<VideoCompositor>& c) {
-          return c->surface_id() == video_surface->surface_id();
-        });
-
-    if (video_compositor_it == video_compositors_.end()) {
-      // This video surface is new, create a new VideoCompositor.
-      video_compositors_.push_back(std::make_shared<VideoCompositor>(
-          video_surface, surface->GetMetadataBufferPtr()));
-    } else {
-      // There is a compositor in |video_compositors_| is already set up for
-      // this |video_surface|.
-      ALOGW("Duplicated video_mesh_surface: surface_id=%d",
-            video_surface->surface_id());
-    }
-  }
-}
-
-void Compositor::AppFrame::ResetBlurrers() { blurrers_.clear(); }
-
-void Compositor::AppFrame::AddBlurrer(Blur* blurrer) {
-  blurrers_.emplace_back(blurrer);
-}
-
-void Compositor::PostBuffer(const std::shared_ptr<DisplaySurface>& surface) {
-  int surface_id = surface->surface_id();
-
-  ALOGD_IF(TRACE, "Post surface %d", surface_id);
-
-  auto layer_it = std::find_if(layers_.begin(), layers_.end(),
-                               [surface_id](const AppFrame& frame) {
-                                 return frame.surface_id() == surface_id;
-                               });
-
-  bool need_sort = false;
-  if (layer_it == layers_.end()) {
-    layers_.push_back(AppFrame());
-    layer_it = layers_.end() - 1;
-    need_sort = true;
-  }
-
-  need_sort |= layer_it->UpdateSurface(surface);
-  layer_it->UpdateVideoMeshSurface(surface);
-
-  if (need_sort) {
-    std::stable_sort(layers_.begin(), layers_.end());
-  }
-}
-
-std::vector<uint8_t> Compositor::ReadLayerPixels(size_t index, int* width,
-                                                 int* height) {
-  if (index >= layers_.size()) {
-    return {};
-  }
-
-  const Texture* texture = layers_[index].GetGlTextureId(display_, 0);
-  if (!texture) {
-    return {};
-  }
-
-  *width = texture->size()[0];
-  *height = texture->size()[1];
-  return ReadTextureRGBA(texture->texture_id(), *width, *height);
-}
-
-std::vector<uint8_t> Compositor::ReadBufferPixels(const IonBuffer* buffer) {
-  android::sp<TemporaryNativeBuffer> native_buffer =
-      new TemporaryNativeBuffer(buffer);
-
-  // Finish to make sure the GL driver has completed drawing of prior FBOs.
-  // Since we are creating an EGL image here, the driver will not know that
-  // there is a dependency on earlier GL draws.
-  glFinish();
-
-  EGLImageKHR image = eglCreateImageKHR(
-      display_, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
-      static_cast<ANativeWindowBuffer*>(native_buffer.get()), nullptr);
-  if (!image) {
-    ALOGE("Failed to create EGLImage\n");
-    return {};
-  }
-
-  GLuint texture_id;
-  glGenTextures(1, &texture_id);
-  glActiveTexture(GL_TEXTURE0);
-  glBindTexture(GL_TEXTURE_2D, texture_id);
-  glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
-
-  int width = buffer->width();
-  int height = buffer->height();
-  std::vector<uint8_t> data = ReadTextureRGBA(texture_id, width, height);
-
-  glBindTexture(GL_TEXTURE_2D, 0);
-  glDeleteTextures(1, &texture_id);
-  eglDestroyImageKHR(display_, image);
-  return data;
-}
-
-bool Compositor::DrawFrame(uint32_t target_vsync_count,
-                           LocalHandle* buffer_fence_fd) {
-  CheckAndUpdateHeadMountMetrics(false);
-
-  ATRACE_NAME("Compositor::DrawFrame");
-  GpuProfiler::Get()->PollGlTimerQueries();
-
-  if (buffer_fence_fd)
-    buffer_fence_fd->Close();
-
-  int num_layers = 0;
-  const int kMaxLayers = 4;
-  GLuint texture_id[2][kMaxLayers] = {{0}};
-  GLuint render_pose_buffer_id[kMaxLayers] = {0};
-  uint32_t render_buffer_index[kMaxLayers] = {0};
-  bool vertical_flip[kMaxLayers] = {false};
-  bool separate_eye_textures[kMaxLayers] = {false};
-  bool enable_cac[kMaxLayers] = {};
-  CHECK_GL();
-  for (auto& layer : layers_) {
-    if (!layer.buffer().buffer()) {
-      ATRACE_NAME("no_buffer");
-      continue;
-    }
-
-    // Extract surface parameters.
-    render_buffer_index[num_layers] = layer.render_buffer_index();
-    render_pose_buffer_id[num_layers] =
-        layer.render_pose_buffer_object()->object_id();
-    vertical_flip[num_layers] = layer.vertical_flip();
-    enable_cac[num_layers] =
-        head_mount_metrics_.supports_chromatic_aberration_correction() &&
-        layer.enable_cac();
-
-    // Extract per-eye textures. These may be separate or joined (atlased).
-    vec2i size(0, 0);
-    int view_count = layer.buffer().buffer()->slice_count();
-    ALOGE_IF(view_count > 2, "Error: more than 2 views not supported");
-    view_count = std::min(2, view_count);
-    separate_eye_textures[num_layers] = (view_count > 1);
-    bool is_missing_texture = false;
-    for (int eye = 0; eye < 2; ++eye) {
-      // If view_count is 1, each eye texture is the 0th.
-      int view_index = (view_count == 2) ? eye : 0;
-      const Texture* texture = layer.GetGlTextureId(display_, view_index);
-      // Texture will be null if the EGL image creation fails (hopefully never).
-      if (!texture) {
-        is_missing_texture = true;
-        break;
-      }
-      // All views are currently expected to have the same size.
-      size = texture->size();
-      texture_id[eye][num_layers] = texture->texture_id();
-    }
-    if (is_missing_texture) {
-      continue;
-    }
-
-    // Perform blur if requested.
-    if (fabs(layer.blur()) > 0.001f) {
-      // No need for CAC on blurred layers.
-      enable_cac[num_layers] = false;
-      if (layer.blurrer_count() < 1 || layer.blurrer(0)->width() != size[0] ||
-          layer.blurrer(0)->height() != size[1]) {
-        // Blur is created with the left eye texture, but the same instance
-        // can be used for the right eye as well.
-        layer.ResetBlurrers();
-        layer.AddBlurrer(new Blur(size[0], size[1], texture_id[0][num_layers],
-                                  GL_TEXTURE_2D, GL_TEXTURE_2D, true, display_,
-                                  view_count));
-      }
-      // Reset blur instances to prepare for drawing.
-      layer.blurrer(0)->StartFrame();
-      layer.blurrer(0)->set_scale(layer.blur());
-      // Perform blur and replace source texture with blurred output texture.
-      if (view_count == 1) {
-        // Single wide buffer for both eyes, blur both eyes in one operation.
-        texture_id[0][num_layers] = texture_id[1][num_layers] =
-            layer.blurrer(0)->DrawBlur(texture_id[0][num_layers]);
-      } else {
-        // Split eye buffers in a single frame, blur each framebuffer.
-        texture_id[0][num_layers] =
-            layer.blurrer(0)->DrawBlur(texture_id[0][num_layers]);
-        texture_id[1][num_layers] =
-            layer.blurrer(0)->DrawBlur(texture_id[1][num_layers]);
-      }
-    }
-
-    ++num_layers;
-    if (num_layers >= kMaxLayers)
-      break;
-  }
-
-  CHECK_GL();
-  // Set appropriate binning mode for the number of layers.
-  if (num_layers > 1 && is_render_direct_) {
-    is_render_direct_ = false;
-    glDisable(BINNING_CONTROL_HINT_QCOM);
-  } else if (num_layers <= 1 && !is_render_direct_) {
-    is_render_direct_ = true;
-    glEnable(BINNING_CONTROL_HINT_QCOM);
-    glHint(BINNING_CONTROL_HINT_QCOM, RENDER_DIRECT_TO_FRAMEBUFFER_QCOM);
-  }
-
-  // Workaround for GL driver bug that causes the currently bound FBO to be
-  // accessed during a compute shader pass (DoLateLatch below). Based on an
-  // analysis with systrace, the best pattern here was to run the compute shader
-  // with a *different* FBO than what will be drawn to afterward. So we bind
-  // a dummy 1x1 FBO here and discard it. If instead, the current render target
-  // is bound during the compute shader, the following draw calls will be forced
-  // into direct mode rendering.
-  glBindFramebuffer(GL_FRAMEBUFFER, compute_fbo_);
-  GLenum attachment = GL_COLOR_ATTACHMENT0;
-  glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, &attachment);
-
-  // Double buffer the render target.  Get the render target we're drawing into,
-  // and update the active buffer to the next buffer.
-  RenderTarget& render_target = GetRenderTarget();
-  SetNextRenderTarget();
-
-  if (num_layers > 0) {
-    // This trace prints the EDS+Warp GPU overhead and prints every 5 seconds:
-    TRACE_GPU_PRINT("GPU EDS+Warp", 5 * 60);
-    CHECK_GL();
-    eds_renderer_->DoLateLatch(target_vsync_count, render_buffer_index,
-                               render_pose_buffer_id, vertical_flip,
-                               separate_eye_textures, num_layers);
-
-    render_target.BindFramebuffer();
-
-    // Discard to avoid unresolving the framebuffer during tiled rendering.
-    render_target.DiscardColorAttachment();
-
-    // For tiled mode rendering, we clear every frame to avoid garbage showing
-    // up in the parts of tiles that are not rendered.
-    if (!is_render_direct_) {
-      glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-      glClear(GL_COLOR_BUFFER_BIT);
-    }
-
-    for (int eye = kLeftEye; eye <= kRightEye; ++eye) {
-      eds_renderer_->PrepGlState(static_cast<EyeType>(eye));
-      for (int layer_i = 0; layer_i < num_layers; ++layer_i) {
-        bool blend_with_previous = layer_i > 0;
-        uint32_t current_buffer_index = render_buffer_index[layer_i];
-
-        // Render video mesh in the background of each graphics layer.
-        layers_[layer_i].ForEachVideoCompositor([this, eye, layer_i,
-                                                 current_buffer_index,
-                                                 &blend_with_previous](
-            const std::shared_ptr<VideoCompositor>& video_compositor) mutable {
-          eds_renderer_->DrawVideoQuad(
-              static_cast<EyeType>(eye), layer_i,
-              video_compositor->GetActiveTextureId(display_),
-              video_compositor->GetTransform(eye, current_buffer_index));
-          blend_with_previous = true;
-        });
-
-        // Apply distortion to frame submitted from the app's GL context.
-        eds_renderer_->SetChromaticAberrationCorrectionEnabled(
-            enable_cac[layer_i]);
-        eds_renderer_->ApplyDistortionCorrectionToTexture(
-            static_cast<EyeType>(eye), &texture_id[eye][layer_i],
-            &vertical_flip[layer_i], &separate_eye_textures[layer_i], &layer_i,
-            1, blend_with_previous, false);
-      }
-    }
-    eds_renderer_->ResetGlState(1);
-    CHECK_GL();
-  } else {
-    ALOGI("No buffers for compositing, clearing to black.");
-    render_target.BindFramebuffer();
-    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-    glClear(GL_COLOR_BUFFER_BIT);
-  }
-
-  debug_hud_->Update();
-  debug_hud_->Draw();
-
-  LocalHandle fence_fd = CreateGLSyncAndFlush(display_);
-
-  if (buffer_fence_fd)
-    *buffer_fence_fd = std::move(fence_fd);
-
-  if (eds_pose_capture_enabled_) {
-    std::lock_guard<std::mutex> _lock(mutex_);
-    eds_renderer_->GetLastEdsPose(&eds_pose_capture_);
-  }
-
-  return true;
-}
-
-bool Compositor::GetLastEdsPose(LateLatchOutput* out_data) {
-  if (eds_pose_capture_enabled_) {
-    std::lock_guard<std::mutex> _lock(mutex_);
-    *out_data = eds_pose_capture_;
-    return true;
-  } else {
-    ALOGE("Eds pose capture is not enabled.");
-    return false;
-  }
-}
-
-}  // namespace dvr
-}  // namespace android
diff --git a/libs/vr/libvrflinger/compositor.h b/libs/vr/libvrflinger/compositor.h
deleted file mode 100644 (file)
index be26d31..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-#ifndef ANDROID_DVR_SERVICES_DISPLAYD_COMPOSITOR_H_
-#define ANDROID_DVR_SERVICES_DISPLAYD_COMPOSITOR_H_
-
-#include <EGL/egl.h>
-#include <log/log.h>
-#include <utils/StrongPointer.h>
-
-#include <memory>
-#include <mutex>
-#include <queue>
-#include <vector>
-
-#include <pdx/file_handle.h>
-#include <private/dvr/clock_ns.h>
-#include <private/dvr/composite_hmd.h>
-#include <private/dvr/display_metrics.h>
-#include <private/dvr/distortion_renderer.h>
-#include <private/dvr/frame_time_history.h>
-#include <private/dvr/ion_buffer.h>
-#include <private/dvr/native_buffer.h>
-
-#include "acquired_buffer.h"
-#include "video_compositor.h"
-struct DvrPose;
-
-namespace android {
-namespace dvr {
-
-class Blur;
-class BufferConsumer;
-class CompositeHmd;
-class DebugHudView;
-class DisplaySurface;
-
-// This is a GPU compositor for software EDS and lens warp on buffers provided
-// by HardwareComposer.
-class Compositor {
- public:
-  Compositor();
-  ~Compositor();
-
-  bool Initialize(const DisplayMetrics& display_metrics);
-  void UpdateHeadMountMetrics(const HeadMountMetrics& head_mount_metrics);
-  void Shutdown();
-
-  // Renders a frame with the latest buffers with EDS and warp applied.
-  // buffer_fence_fd can be used to get a fence for the rendered frame. It can
-  // be set to null if the fence isn't needed.
-  bool DrawFrame(uint32_t target_vsync_count,
-                 pdx::LocalHandle* buffer_fence_fd);
-
-  // Remove all buffers.
-  void RemoveAllBuffers();
-
-  // Synchronize compositor layers with in given surfaces.
-  void UpdateSurfaces(
-      const std::vector<std::shared_ptr<DisplaySurface>>& surfaces);
-
-  // This must be called for each surface before DrawFrame is called.
-  void PostBuffer(const std::shared_ptr<DisplaySurface>& surface);
-
-  std::shared_ptr<IonBuffer> GetBuffer() const {
-    return render_target_[active_render_target_].buffer();
-  }
-
-  // Returns the number of layers being rendered by the compositor.
-  size_t GetLayerCount() const { return layers_.size(); }
-
-  // Returns the source buffer at the given layer index or nullptr if none is
-  // available.
-  std::shared_ptr<BufferConsumer> PeekAtLayer(size_t index) const {
-    if (index >= GetLayerCount())
-      return nullptr;
-    return layers_[index].buffer().buffer();
-  }
-
-  // Expensive operation to transfer the pixels of the given layer index into
-  // unformatted memory and return as a RGBA buffer.
-  // On success, returns non-zero sized vector and sets width and height.
-  // On failure, returns empty vector.
-  std::vector<uint8_t> ReadLayerPixels(size_t index, int* width, int* height);
-
-  // Expensive operation to transfer the pixels of the given buffer into
-  // unformatted memory and return as a RGBA buffer.
-  // On success, returns non-zero sized vector.
-  // On failure, returns empty vector.
-  std::vector<uint8_t> ReadBufferPixels(const IonBuffer* buffer);
-
-  bool GetLastEdsPose(LateLatchOutput* out_data);
-
-  const HeadMountMetrics& head_mount_metrics() const {
-    return head_mount_metrics_;
-  }
-
- private:
-  class Texture;
-  class RenderPoseBufferObject;
-
-  // A rendered frame from an application.
-  class AppFrame {
-   public:
-    AppFrame();
-    ~AppFrame();
-
-    AppFrame(AppFrame&& other) = default;
-    AppFrame& operator=(AppFrame&&) = default;
-
-    // Gets a GL texture object for the current buffer. The resulting texture
-    // object will be cached for future calls. Returns a pointer for temporary
-    // access - not meant to hold on to.
-    const Texture* GetGlTextureId(EGLDisplay display, int index);
-
-    bool operator<(const AppFrame& rhs) const {
-      return z_order_ < rhs.z_order_;
-    }
-    int z_order() const { return z_order_; }
-    // Return true if this surface z order has been changed.
-    bool UpdateSurface(const std::shared_ptr<DisplaySurface>& surface);
-    void UpdateVideoMeshSurface(const std::shared_ptr<DisplaySurface>& surface);
-    void ResetBlurrers();
-    void AddBlurrer(Blur* blurrer);
-
-    const AcquiredBuffer& buffer() const { return buffer_; }
-    int surface_id() const { return surface_id_; }
-    float blur() const { return blur_; }
-    bool vertical_flip() const { return vertical_flip_; }
-    bool enable_cac() const { return enable_cac_; }
-    size_t blurrer_count() const { return blurrers_.size(); }
-    Blur* blurrer(size_t i) {
-      return blurrers_.size() < i ? nullptr : blurrers_[i].get();
-    }
-    uint32_t render_buffer_index() const { return render_buffer_index_; }
-    const RenderPoseBufferObject* render_pose_buffer_object() const {
-      return render_pose_buffer_object_.get();
-    }
-
-    template <class A>
-    void ForEachVideoCompositor(A action) const {
-      for (auto& c : video_compositors_) {
-        action(c);
-      }
-    }
-
-   private:
-    int surface_id_;
-    float blur_;
-    int z_order_;
-    bool vertical_flip_;
-    bool enable_cac_;
-    std::vector<std::unique_ptr<Blur>> blurrers_;
-    AcquiredBuffer buffer_;
-    std::vector<std::shared_ptr<Texture>> textures_;
-    uint32_t render_buffer_index_;
-    std::unique_ptr<RenderPoseBufferObject> render_pose_buffer_object_;
-
-    // Active video mesh compositors
-    std::vector<std::shared_ptr<VideoCompositor>> video_compositors_;
-
-    AppFrame(const AppFrame& other) = delete;
-    AppFrame& operator=(const AppFrame&) = delete;
-  };
-
-  class RenderTarget {
-   public:
-    RenderTarget();
-    ~RenderTarget();
-
-    void Initialize(int width, int height);
-    void Destroy();
-    void BindFramebuffer();
-    void DiscardColorAttachment();
-
-    std::shared_ptr<IonBuffer> buffer() const { return buffer_; }
-
-   private:
-    std::shared_ptr<IonBuffer> buffer_;
-    android::sp<NativeBuffer> native_buffer_;
-
-    GLuint buffer_texture_id_;
-    GLuint buffer_framebuffer_id_;
-    EGLImageKHR buffer_image_;
-  };
-
-  Compositor(const Compositor&) = delete;
-  void operator=(const Compositor&) = delete;
-
-  bool InitializeEGL();
-
-  void UpdateHudToggle();
-  void PrintStatsHud();
-  void CheckAndUpdateHeadMountMetrics(bool force_update);
-
-  RenderTarget& GetRenderTarget() {
-    return render_target_[active_render_target_];
-  }
-
-  void SetNextRenderTarget() {
-    active_render_target_ = (active_render_target_ + 1) & 1;
-  }
-
-  std::vector<AppFrame> layers_;
-
-  DisplayMetrics display_metrics_;
-  HeadMountMetrics head_mount_metrics_;
-
-  EGLDisplay display_;
-  EGLConfig config_;
-  EGLSurface surface_;
-  EGLContext context_;
-  int active_render_target_;
-  RenderTarget render_target_[2];
-  bool is_render_direct_;
-
-  // FBO for compute shader.
-  GLuint compute_fbo_;
-  GLuint compute_fbo_texture_;
-
-  std::unique_ptr<DebugHudView> debug_hud_;
-
-  // EDS:
-  std::unique_ptr<CompositeHmd> composite_hmd_;
-  bool hmd_metrics_requires_update_;
-  std::unique_ptr<DistortionRenderer> eds_renderer_;
-
-  bool eds_pose_capture_enabled_;
-  std::mutex mutex_;
-  LateLatchOutput eds_pose_capture_;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_SERVICES_DISPLAYD_COMPOSITOR_H_
diff --git a/libs/vr/libvrflinger/debug_hud_data.cpp b/libs/vr/libvrflinger/debug_hud_data.cpp
deleted file mode 100644 (file)
index d387bba..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "debug_hud_data.h"
-
-namespace android {
-namespace dvr {
-
-DebugHudData DebugHudData::data;
-
-}  // namespace dvr
-}  // namespace android
diff --git a/libs/vr/libvrflinger/debug_hud_data.h b/libs/vr/libvrflinger/debug_hud_data.h
deleted file mode 100644 (file)
index 778169d..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-#ifndef ANDROID_DVR_SERVICES_DISPLAYD_DEBUG_HUD_DATA_H_
-#define ANDROID_DVR_SERVICES_DISPLAYD_DEBUG_HUD_DATA_H_
-
-#include <stdint.h>
-
-#include <private/dvr/clock_ns.h>
-#include <private/dvr/frame_time_history.h>
-
-namespace android {
-namespace dvr {
-
-// Tracks debug stats for the displayd debug HUD. Unless otherwise noted,
-// there is no synchronization of data accesses to avoid performance impact.
-// All accesses to this data are on the displayd HWC post thread. Accesses from
-// other threads will need to be duly protected from races.
-// This is a lightweight struct to make it easy to add and remove
-// tracking data.
-struct DebugHudData {
-  // Maximum supported layers for the debug HUD.
-  enum { kMaxLayers = 4 };
-
-  // The global singleton HUD data instance.
-  static DebugHudData data;
-
-  // Tracks framerate and skipped frames.
-  struct FrameStats {
-    void AddFrame() {
-      int64_t now = GetSystemClockNs();
-      frame_time.AddSample(now - last_frame_ts);
-      last_frame_ts = now;
-    }
-
-    void SkipFrame() {
-      AddFrame();
-      ++drops;
-    }
-
-    int drops = 0;
-    int64_t last_frame_ts = 0;
-    FrameTimeHistory frame_time;
-  };
-
-  // Debug data for compositor layers (applications, system UI, etc).
-  struct LayerData {
-    void Reset() {
-      ResetStats();
-      width = 0;
-      height = 0;
-      is_separate = false;
-    }
-
-    void ResetStats() { frame_stats.drops = 0; }
-
-    FrameStats frame_stats;
-    int width = 0;
-    int height = 0;
-    bool is_separate = false;
-  };
-
-  // Resets the stats.
-  void ResetStats() {
-    hwc_frame_stats.drops = 0;
-    hwc_latency = 0;
-    for (auto& l : layer_data)
-      l.ResetStats();
-  }
-
-  // Resets the layer configuration.
-  void ResetLayers() {
-    num_layers = 0;
-    for (auto& l : layer_data)
-      l.Reset();
-  }
-
-  // Tracks a frame arrival for the given layer.
-  void AddLayerFrame(size_t layer) {
-    if (layer < kMaxLayers) {
-      num_layers = std::max(layer + 1, num_layers);
-      layer_data[layer].frame_stats.AddFrame();
-    }
-  }
-
-  // Tracks a frame skip/drop for the given layer.
-  void SkipLayerFrame(size_t layer) {
-    if (layer < kMaxLayers) {
-      num_layers = std::max(layer + 1, num_layers);
-      layer_data[layer].frame_stats.SkipFrame();
-    }
-  }
-
-  // Sets the resolution and other details of the layer.
-  void SetLayerInfo(size_t layer, int width, int height, bool is_separate) {
-    if (layer < kMaxLayers) {
-      num_layers = std::max(layer + 1, num_layers);
-      layer_data[layer].width = width;
-      layer_data[layer].height = height;
-      layer_data[layer].is_separate = is_separate;
-    }
-  }
-
-  FrameStats hwc_frame_stats;
-  int64_t hwc_latency = 0;
-  size_t num_layers = 0;
-  LayerData layer_data[kMaxLayers];
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_SERVICES_DISPLAYD_DEBUG_HUD_DATA_H_
diff --git a/libs/vr/libvrflinger/debug_hud_view.cpp b/libs/vr/libvrflinger/debug_hud_view.cpp
deleted file mode 100644 (file)
index 4936ac6..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-#include "debug_hud_view.h"
-
-#include <dvr/pose_client.h>
-
-#include "debug_hud_data.h"
-
-namespace android {
-namespace dvr {
-
-DebugHudView::DebugHudView(const CompositeHmd& hmd) {
-  pose_client_ = dvrPoseCreate();
-
-  display_size_ = hmd.GetDisplayMetrics().GetSizePixels();
-  vec2 display_size_meters = hmd.GetDisplayMetrics().GetSizeMeters();
-  inter_lens_dist_screen_space_ =
-      2.0f * hmd.GetHeadMountMetrics().GetInterLensDistance() /
-      std::max(display_size_meters[0], display_size_meters[1]);
-}
-
-DebugHudView::~DebugHudView() {
-  if (pose_client_)
-    dvrPoseDestroy(pose_client_);
-  pose_client_ = nullptr;
-}
-
-void DebugHudView::Update() {
-  // Check for gesture that enables the debug stats HUD.
-  if (!pose_client_)
-    return;
-  DvrPoseAsync pose;
-  dvrPoseGet(pose_client_, 0, &pose);
-  float32x4_t q = pose.orientation;
-  quat orientation(q[3], q[0], q[1], q[2]);
-  vec3 up = orientation * vec3(0, 1, 0);
-  if (up[1] < -0.8f) {
-    ++switch_timer_;
-  } else {
-    switch_timer_ = 0;
-  }
-  // A few seconds upside down => toggle stats HUD.
-  if (switch_timer_ > 200) {
-    switch_timer_ = 0;
-    enabled_ = !enabled_;
-    DebugHudData::data.ResetStats();
-    ALOGE("Toggle debug stats HUD: %s", enabled_ ? "ON" : "OFF");
-  }
-}
-
-void DebugHudView::Draw() {
-  if (!enabled_)
-    return;
-  if (!debug_text_)
-    debug_text_.reset(new DebugText(400, display_size_[0], display_size_[1]));
-
-  const DebugHudData& data = DebugHudData::data;
-  const size_t layer_char_count = 50;
-  char layer_data[DebugHudData::kMaxLayers][layer_char_count];
-  for (size_t i = 0; i < data.num_layers; ++i) {
-    float fps = data.layer_data[i].frame_stats.frame_time.GetAverageFps();
-    snprintf(layer_data[i], layer_char_count,
-             "Layer %d %dx%d%s FPS: %.2f Drops: %d\n", static_cast<int>(i),
-             data.layer_data[i].width, data.layer_data[i].height,
-             data.layer_data[i].is_separate ? "x2" : "", fps,
-             data.layer_data[i].frame_stats.drops);
-  }
-
-  float hwc_fps = data.hwc_frame_stats.frame_time.GetAverageFps();
-
-  char text[400];
-  float hwc_latency_ms = static_cast<float>(data.hwc_latency) / 1000000.0f;
-  snprintf(text, sizeof(text), "HWC FPS: %.2f Latency: %.3f ms Skips: %d\n",
-           hwc_fps, hwc_latency_ms, data.hwc_frame_stats.drops);
-
-  for (size_t i = 0; i < data.num_layers; ++i) {
-    strncat(text, layer_data[i], sizeof(text) - strlen(text) - 1);
-  }
-
-  // Ensure text termination.
-  text[sizeof(text) - 1] = '\0';
-
-  glViewport(0, 0, display_size_[0], display_size_[1]);
-  glEnable(GL_BLEND);
-  // No stereo, because you can see the HUD OK in one eye. Stereo actually
-  // makes it more difficult to focus sometimes. To enable stereo:
-  // replace the second to last parameter with inter_lens_dist_screen_space_.
-  debug_text_->Draw(0.0f, -0.7f * inter_lens_dist_screen_space_, text, 0.0f, 1);
-  glDisable(GL_BLEND);
-}
-
-}  // namespace dvr
-}  // namespace android
diff --git a/libs/vr/libvrflinger/debug_hud_view.h b/libs/vr/libvrflinger/debug_hud_view.h
deleted file mode 100644 (file)
index 50f38a8..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-#ifndef ANDROID_DVR_SERVICES_DISPLAYD_DEBUG_HUD_VIEW_H_
-#define ANDROID_DVR_SERVICES_DISPLAYD_DEBUG_HUD_VIEW_H_
-
-#include <stdint.h>
-
-#include <utils/Log.h>
-
-#include <private/dvr/composite_hmd.h>
-#include <private/dvr/graphics/debug_text.h>
-
-struct DvrPose;
-
-namespace android {
-namespace dvr {
-
-class CompositeHmd;
-
-// The view and the controller for the displayd debug HUD.
-// The HUD is enabled and disabled by internally tracking the head pose.
-// When the head pose is upside down for ~3 seconds, the enabled state toggles.
-// See DebugHudData for the data that is reported.
-class DebugHudView {
- public:
-  DebugHudView(const CompositeHmd& hmd);
-  ~DebugHudView();
-
-  // Updates HUD state.
-  void Update();
-
-  // Draws HUD into the current framebuffer if it is currently enabled.
-  void Draw();
-
- private:
-  DebugHudView(const DebugHudView&) = delete;
-  DebugHudView& operator=(const DebugHudView&) = delete;
-
-  DvrPose* pose_client_ = nullptr;
-  vec2i display_size_;
-  bool enabled_ = false;
-  int switch_timer_ = 0;
-  float inter_lens_dist_screen_space_ = 0.0f;
-  std::unique_ptr<DebugText> debug_text_;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_SERVICES_DISPLAYD_DEBUG_HUD_VIEW_H_
index 61bb71c..a0b3efe 100644 (file)
@@ -9,26 +9,15 @@
 
 #include <array>
 
+using android::dvr::display::DisplayManagerProtocol;
 using android::pdx::Channel;
 using android::pdx::LocalChannelHandle;
 using android::pdx::Message;
 using android::pdx::default_transport::Endpoint;
+using android::pdx::ErrorStatus;
 using android::pdx::rpc::DispatchRemoteMethod;
 using android::pdx::rpc::IfAnyOf;
-
-namespace {
-
-// As a first line of defense, the display manager endpoint is only accessible
-// to the user and group.
-
-// TODO(dnicoara): Remove read/write permission for others. This is in here just
-// to allow us to experiment with cast functionality from a plain old app.
-constexpr mode_t kDisplayManagerEndpointFileMode =
-    S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
-
-constexpr size_t kMaxSurfacesPerRequest = 32;
-
-}  // anonymous namespace
+using android::pdx::rpc::RemoteMethodError;
 
 namespace android {
 namespace dvr {
@@ -45,8 +34,7 @@ void DisplayManager::SetNotificationsPending(bool pending) {
 DisplayManagerService::DisplayManagerService(
     const std::shared_ptr<DisplayService>& display_service)
     : BASE("DisplayManagerService",
-           Endpoint::Create(DisplayManagerRPC::kClientPath,
-                            kDisplayManagerEndpointFileMode)),
+           Endpoint::Create(DisplayManagerProtocol::kClientPath)),
       display_service_(display_service) {
   display_service_->SetDisplayConfigurationUpdateNotifier(
       std::bind(&DisplayManagerService::OnDisplaySurfaceChange, this));
@@ -54,9 +42,15 @@ DisplayManagerService::DisplayManagerService(
 
 std::shared_ptr<pdx::Channel> DisplayManagerService::OnChannelOpen(
     pdx::Message& message) {
-  // Prevent more than one display manager from registering at a time.
-  if (display_manager_)
-    REPLY_ERROR_RETURN(message, EPERM, nullptr);
+  const int user_id = message.GetEffectiveUserId();
+  const bool trusted = user_id == AID_ROOT || IsTrustedUid(user_id);
+
+  // Prevent more than one display manager from registering at a time or
+  // untrusted UIDs from connecting.
+  if (display_manager_ || !trusted) {
+    RemoteMethodError(message, EPERM);
+    return nullptr;
+  }
 
   display_manager_ =
       std::make_shared<DisplayManager>(this, message.GetChannelId());
@@ -74,18 +68,18 @@ pdx::Status<void> DisplayManagerService::HandleMessage(pdx::Message& message) {
   auto channel = std::static_pointer_cast<DisplayManager>(message.GetChannel());
 
   switch (message.GetOp()) {
-    case DisplayManagerRPC::GetSurfaceList::Opcode:
-      DispatchRemoteMethod<DisplayManagerRPC::GetSurfaceList>(
-          *this, &DisplayManagerService::OnGetSurfaceList, message);
+    case DisplayManagerProtocol::GetSurfaceState::Opcode:
+      DispatchRemoteMethod<DisplayManagerProtocol::GetSurfaceState>(
+          *this, &DisplayManagerService::OnGetSurfaceState, message);
       return {};
 
-    case DisplayManagerRPC::UpdateSurfaces::Opcode:
-      DispatchRemoteMethod<DisplayManagerRPC::UpdateSurfaces>(
-          *this, &DisplayManagerService::OnUpdateSurfaces, message);
+    case DisplayManagerProtocol::GetSurfaceQueue::Opcode:
+      DispatchRemoteMethod<DisplayManagerProtocol::GetSurfaceQueue>(
+          *this, &DisplayManagerService::OnGetSurfaceQueue, message);
       return {};
 
-    case DisplayManagerRPC::SetupNamedBuffer::Opcode:
-      DispatchRemoteMethod<DisplayManagerRPC::SetupNamedBuffer>(
+    case DisplayManagerProtocol::SetupNamedBuffer::Opcode:
+      DispatchRemoteMethod<DisplayManagerProtocol::SetupNamedBuffer>(
           *this, &DisplayManagerService::OnSetupNamedBuffer, message);
       return {};
 
@@ -94,128 +88,67 @@ pdx::Status<void> DisplayManagerService::HandleMessage(pdx::Message& message) {
   }
 }
 
-std::vector<DisplaySurfaceInfo> DisplayManagerService::OnGetSurfaceList(
-    pdx::Message& /*message*/) {
-  std::vector<DisplaySurfaceInfo> items;
+pdx::Status<std::vector<display::SurfaceState>>
+DisplayManagerService::OnGetSurfaceState(pdx::Message& /*message*/) {
+  std::vector<display::SurfaceState> items;
 
   display_service_->ForEachDisplaySurface(
+      SurfaceType::Application,
       [&items](const std::shared_ptr<DisplaySurface>& surface) mutable {
-        DisplaySurfaceInfo item;
-
-        item.surface_id = surface->surface_id();
-        item.process_id = surface->process_id();
-        item.type = surface->type();
-        item.flags = 0;  // TODO(eieio)
-        item.client_attributes = DisplaySurfaceAttributes{
-            {DisplaySurfaceAttributeEnum::Visible,
-             DisplaySurfaceAttributeValue{surface->client_visible()}},
-            {DisplaySurfaceAttributeEnum::ZOrder,
-             DisplaySurfaceAttributeValue{surface->client_z_order()}},
-            {DisplaySurfaceAttributeEnum::Blur,
-             DisplaySurfaceAttributeValue{0.f}}};
-        item.manager_attributes = DisplaySurfaceAttributes{
-            {DisplaySurfaceAttributeEnum::Visible,
-             DisplaySurfaceAttributeValue{surface->manager_visible()}},
-            {DisplaySurfaceAttributeEnum::ZOrder,
-             DisplaySurfaceAttributeValue{surface->manager_z_order()}},
-            {DisplaySurfaceAttributeEnum::Blur,
-             DisplaySurfaceAttributeValue{surface->manager_blur()}}};
-
-        items.push_back(item);
+        items.push_back({surface->surface_id(), surface->process_id(),
+                         surface->user_id(), surface->attributes(),
+                         surface->update_flags(), surface->GetQueueIds()});
+        surface->ClearUpdate();
       });
 
   // The fact that we're in the message handler implies that display_manager_ is
   // not nullptr. No check required, unless this service becomes multi-threaded.
   display_manager_->SetNotificationsPending(false);
-
   return items;
 }
 
-int DisplayManagerService::OnUpdateSurfaces(
-    pdx::Message& /*message*/,
-    const std::map<int, DisplaySurfaceAttributes>& updates) {
-  for (const auto& surface_update : updates) {
-    const int surface_id = surface_update.first;
-    const DisplaySurfaceAttributes& attributes = surface_update.second;
-
-    std::shared_ptr<DisplaySurface> surface =
-        display_service_->GetDisplaySurface(surface_id);
-
-    if (!surface)
-      return -ENOENT;
-
-    for (const auto& attribute : attributes) {
-      const auto& key = attribute.first;
-      const auto* variant = &attribute.second;
-      bool invalid_value = false;
-      switch (key) {
-        case DisplaySurfaceAttributeEnum::ZOrder:
-          invalid_value =
-              !IfAnyOf<int32_t>::Call(variant, [&surface](const auto& value) {
-                surface->ManagerSetZOrder(value);
-              });
-          break;
-        case DisplaySurfaceAttributeEnum::Visible:
-          invalid_value = !IfAnyOf<int32_t, int64_t, bool>::Call(
-              variant, [&surface](const auto& value) {
-                surface->ManagerSetVisible(value);
-              });
-          break;
-        case DisplaySurfaceAttributeEnum::Blur:
-          invalid_value = !IfAnyOf<int32_t, int64_t, float>::Call(
-              variant, [&surface](const auto& value) {
-                surface->ManagerSetBlur(value);
-              });
-          break;
-        default:
-          ALOGW(
-              "DisplayManagerService::OnUpdateSurfaces: Attempt to set invalid "
-              "attribute %u on surface %d",
-              key, surface_id);
-          break;
-      }
-
-      if (invalid_value) {
-        ALOGW(
-            "DisplayManagerService::OnUpdateSurfaces: Failed to set display "
-            "surface attribute '%s' because of incompatible type: %d",
-            DisplaySurfaceAttributeEnum::ToString(key).c_str(),
-            variant->index());
-      }
-    }
-  }
-
-  // Reconfigure the display layers for any active surface changes.
-  display_service_->UpdateActiveDisplaySurfaces();
-  return 0;
+pdx::Status<pdx::LocalChannelHandle> DisplayManagerService::OnGetSurfaceQueue(
+    pdx::Message& /*message*/, int surface_id, int queue_id) {
+  auto surface = display_service_->GetDisplaySurface(surface_id);
+  if (!surface || surface->surface_type() != SurfaceType::Application)
+    return ErrorStatus(EINVAL);
+
+  auto queue =
+      std::static_pointer_cast<ApplicationDisplaySurface>(surface)->GetQueue(
+          queue_id);
+  if (!queue)
+    return ErrorStatus(EINVAL);
+
+  auto status = queue->CreateConsumerQueueHandle();
+  ALOGE_IF(
+      !status,
+      "DisplayManagerService::OnGetSurfaceQueue: Failed to create consumer "
+      "queue for queue_id=%d: %s",
+      queue->id(), status.GetErrorMessage().c_str());
+
+  return status;
 }
 
 pdx::Status<BorrowedNativeBufferHandle>
 DisplayManagerService::OnSetupNamedBuffer(pdx::Message& message,
                                           const std::string& name, size_t size,
                                           uint64_t usage) {
-  if (message.GetEffectiveUserId() != AID_ROOT &&
-      !IsTrustedUid(message.GetEffectiveUserId())) {
-    // Only trusted users can setup named buffers.
-    ALOGE("DisplayService::SetupNamedBuffer: Called by untrusted user: uid=%d.",
-          message.GetEffectiveUserId());
-    return {};
+  const int user_id = message.GetEffectiveUserId();
+  const bool trusted = user_id == AID_ROOT || IsTrustedUid(user_id);
+
+  if (!trusted) {
+    ALOGE(
+        "DisplayService::SetupNamedBuffer: Named buffers may only be created "
+        "by trusted UIDs: user_id=%d",
+        user_id);
+    return ErrorStatus(EPERM);
   }
   return display_service_->SetupNamedBuffer(name, size, usage);
 }
 
 void DisplayManagerService::OnDisplaySurfaceChange() {
-  if (display_manager_) {
+  if (display_manager_)
     display_manager_->SetNotificationsPending(true);
-  } else {
-    // If there isn't a display manager registered, default all display surfaces
-    // to visible.
-    display_service_->ForEachDisplaySurface(
-        [](const std::shared_ptr<DisplaySurface>& surface) {
-          surface->ManagerSetVisible(true);
-        });
-    display_service_->UpdateActiveDisplaySurfaces();
-  }
 }
 
 }  // namespace dvr
index f59520c..0857eb5 100644 (file)
@@ -1,7 +1,8 @@
-#ifndef ANDROID_DVR_SERVICES_DISPLAYD_DISPLAY_MANAGER_SERVICE_H_
-#define ANDROID_DVR_SERVICES_DISPLAYD_DISPLAY_MANAGER_SERVICE_H_
+#ifndef ANDROID_DVR_SERVICES_VRFLINGER_DISPLAY_MANAGER_SERVICE_H_
+#define ANDROID_DVR_SERVICES_VRFLINGER_DISPLAY_MANAGER_SERVICE_H_
 
 #include <pdx/service.h>
+#include <pdx/status.h>
 #include <private/dvr/display_protocol.h>
 
 #include "display_service.h"
@@ -50,10 +51,11 @@ class DisplayManagerService : public pdx::ServiceBase<DisplayManagerService> {
   explicit DisplayManagerService(
       const std::shared_ptr<DisplayService>& display_service);
 
-  std::vector<DisplaySurfaceInfo> OnGetSurfaceList(pdx::Message& message);
-  int OnUpdateSurfaces(pdx::Message& message,
-                       const std::map<int, DisplaySurfaceAttributes>& updates);
-
+  pdx::Status<std::vector<display::SurfaceState>> OnGetSurfaceState(
+      pdx::Message& message);
+  pdx::Status<pdx::LocalChannelHandle> OnGetSurfaceQueue(pdx::Message& message,
+                                                         int surface_id,
+                                                         int queue_id);
   pdx::Status<BorrowedNativeBufferHandle> OnSetupNamedBuffer(
       pdx::Message& message, const std::string& name, size_t size,
       uint64_t usage);
@@ -72,4 +74,4 @@ class DisplayManagerService : public pdx::ServiceBase<DisplayManagerService> {
 }  // namespace dvr
 }  // namespace android
 
-#endif  // ANDROID_DVR_SERVICES_DISPLAYD_DISPLAY_MANAGER_SERVICE_H_
+#endif  // ANDROID_DVR_SERVICES_VRFLINGER_DISPLAY_MANAGER_SERVICE_H_
index f56bc02..47efa76 100644 (file)
@@ -3,30 +3,30 @@
 #include <unistd.h>
 #include <vector>
 
+#include <dvr/dvr_display_types.h>
 #include <pdx/default_transport/service_endpoint.h>
 #include <pdx/rpc/remote_method.h>
-#include <private/dvr/composite_hmd.h>
-#include <private/dvr/device_metrics.h>
 #include <private/dvr/display_protocol.h>
-#include <private/dvr/display_types.h>
 #include <private/dvr/numeric.h>
-#include <private/dvr/polynomial_radial_distortion.h>
 #include <private/dvr/types.h>
 
+using android::dvr::display::DisplayProtocol;
 using android::pdx::Channel;
+using android::pdx::ErrorStatus;
 using android::pdx::Message;
+using android::pdx::Status;
 using android::pdx::default_transport::Endpoint;
 using android::pdx::rpc::DispatchRemoteMethod;
-using android::pdx::rpc::WrapBuffer;
 
 namespace android {
 namespace dvr {
 
-DisplayService::DisplayService() : DisplayService(nullptr) {}
-
-DisplayService::DisplayService(Hwc2::Composer* hidl)
-    : BASE("DisplayService", Endpoint::Create(DisplayRPC::kClientPath)),
-      hardware_composer_(hidl) {
+DisplayService::DisplayService(Hwc2::Composer* hidl,
+                               RequestDisplayCallback request_display_callback)
+    : BASE("DisplayService",
+           Endpoint::Create(display::DisplayProtocol::kClientPath)),
+      hardware_composer_(hidl, request_display_callback),
+      request_display_callback_(request_display_callback) {
   hardware_composer_.Initialize();
 }
 
@@ -34,68 +34,51 @@ bool DisplayService::IsInitialized() const {
   return BASE::IsInitialized() && hardware_composer_.IsInitialized();
 }
 
-std::string DisplayService::DumpState(size_t max_length) {
-  std::vector<char> buffer(max_length);
-  uint32_t max_len_p = static_cast<uint32_t>(max_length);
-  hardware_composer_.Dump(buffer.data(), &max_len_p);
-  return std::string(buffer.data());
+std::string DisplayService::DumpState(size_t /*max_length*/) {
+  return hardware_composer_.Dump();
 }
 
-void DisplayService::OnChannelClose(pdx::Message& /*message*/,
+void DisplayService::OnChannelClose(pdx::Message& message,
                                     const std::shared_ptr<Channel>& channel) {
-  auto surface = std::static_pointer_cast<SurfaceChannel>(channel);
-  if (surface && surface->type() == SurfaceTypeEnum::Normal) {
-    auto display_surface = std::static_pointer_cast<DisplaySurface>(surface);
-    display_surface->ManagerSetVisible(false);
-    display_surface->ClientSetVisible(false);
-    NotifyDisplayConfigurationUpdate();
+  if (auto surface = std::static_pointer_cast<DisplaySurface>(channel)) {
+    surface->OnSetAttributes(message,
+                             {{display::SurfaceAttribute::Visible,
+                               display::SurfaceAttributeValue{false}}});
+    SurfaceUpdated(surface->surface_type(),
+                   display::SurfaceUpdateFlags::VisibilityChanged);
   }
-  // TODO(jwcai) Handle ChannelClose of VideoMeshSurface.
 }
 
 // First-level dispatch for display service messages. Directly handles messages
 // that are independent of the display surface (metrics, creation) and routes
 // surface-specific messages to the per-instance handlers.
-pdx::Status<void> DisplayService::HandleMessage(pdx::Message& message) {
-  auto channel = message.GetChannel<SurfaceChannel>();
-
+Status<void> DisplayService::HandleMessage(pdx::Message& message) {
+  ALOGD_IF(TRACE, "DisplayService::HandleMessage: opcode=%d", message.GetOp());
   switch (message.GetOp()) {
-    case DisplayRPC::GetMetrics::Opcode:
-      DispatchRemoteMethod<DisplayRPC::GetMetrics>(
+    case DisplayProtocol::GetMetrics::Opcode:
+      DispatchRemoteMethod<DisplayProtocol::GetMetrics>(
           *this, &DisplayService::OnGetMetrics, message);
       return {};
 
-    case DisplayRPC::GetEdsCapture::Opcode:
-      DispatchRemoteMethod<DisplayRPC::GetEdsCapture>(
-          *this, &DisplayService::OnGetEdsCapture, message);
-      return {};
-
-    case DisplayRPC::CreateSurface::Opcode:
-      DispatchRemoteMethod<DisplayRPC::CreateSurface>(
+    case DisplayProtocol::CreateSurface::Opcode:
+      DispatchRemoteMethod<DisplayProtocol::CreateSurface>(
           *this, &DisplayService::OnCreateSurface, message);
       return {};
 
-    case DisplayRPC::SetViewerParams::Opcode:
-      DispatchRemoteMethod<DisplayRPC::SetViewerParams>(
-          *this, &DisplayService::OnSetViewerParams, message);
-      return {};
-
-    case DisplayRPC::GetNamedBuffer::Opcode:
-      DispatchRemoteMethod<DisplayRPC::GetNamedBuffer>(
+    case DisplayProtocol::GetNamedBuffer::Opcode:
+      DispatchRemoteMethod<DisplayProtocol::GetNamedBuffer>(
           *this, &DisplayService::OnGetNamedBuffer, message);
       return {};
 
-    case DisplayRPC::IsVrAppRunning::Opcode:
-      DispatchRemoteMethod<DisplayRPC::IsVrAppRunning>(
+    case DisplayProtocol::IsVrAppRunning::Opcode:
+      DispatchRemoteMethod<DisplayProtocol::IsVrAppRunning>(
           *this, &DisplayService::IsVrAppRunning, message);
       return {};
 
     // Direct the surface specific messages to the surface instance.
-    case DisplayRPC::CreateBufferQueue::Opcode:
-    case DisplayRPC::SetAttributes::Opcode:
-    case DisplayRPC::GetMetadataBuffer::Opcode:
-    case DisplayRPC::CreateVideoMeshSurface::Opcode:
-    case DisplayRPC::VideoMeshSurfaceCreateProducerQueue::Opcode:
+    case DisplayProtocol::SetAttributes::Opcode:
+    case DisplayProtocol::CreateQueue::Opcode:
+    case DisplayProtocol::GetSurfaceInfo::Opcode:
       return HandleSurfaceMessage(message);
 
     default:
@@ -103,49 +86,29 @@ pdx::Status<void> DisplayService::HandleMessage(pdx::Message& message) {
   }
 }
 
-SystemDisplayMetrics DisplayService::OnGetMetrics(pdx::Message& message) {
-  const Compositor* compositor = hardware_composer_.GetCompositor();
-  if (compositor == nullptr)
-    REPLY_ERROR_RETURN(message, EINVAL, {});
-
-  HeadMountMetrics head_mount = compositor->head_mount_metrics();
-  CompositeHmd hmd(head_mount, hardware_composer_.GetHmdDisplayMetrics());
-  vec2i distorted_render_size = hmd.GetRecommendedRenderTargetSize();
-  FieldOfView left_fov = hmd.GetEyeFov(kLeftEye);
-  FieldOfView right_fov = hmd.GetEyeFov(kRightEye);
-
-  SystemDisplayMetrics metrics;
-
-  metrics.display_native_width = GetDisplayMetrics().width;
-  metrics.display_native_height = GetDisplayMetrics().height;
-  metrics.display_x_dpi = GetDisplayMetrics().dpi.x;
-  metrics.display_y_dpi = GetDisplayMetrics().dpi.y;
-  metrics.distorted_width = distorted_render_size[0];
-  metrics.distorted_height = distorted_render_size[1];
-  metrics.vsync_period_ns =
-      hardware_composer_.native_display_metrics().vsync_period_ns;
-  metrics.hmd_ipd_mm = 0;
-  metrics.inter_lens_distance_m = head_mount.GetInterLensDistance();
-  metrics.left_fov_lrbt[0] = left_fov.GetLeft();
-  metrics.left_fov_lrbt[1] = left_fov.GetRight();
-  metrics.left_fov_lrbt[2] = left_fov.GetBottom();
-  metrics.left_fov_lrbt[3] = left_fov.GetTop();
-  metrics.right_fov_lrbt[0] = right_fov.GetLeft();
-  metrics.right_fov_lrbt[1] = right_fov.GetRight();
-  metrics.right_fov_lrbt[2] = right_fov.GetBottom();
-  metrics.right_fov_lrbt[3] = right_fov.GetTop();
-
-  return metrics;
+Status<display::Metrics> DisplayService::OnGetMetrics(
+    pdx::Message& /*message*/) {
+  return {{static_cast<uint32_t>(GetDisplayMetrics().width),
+           static_cast<uint32_t>(GetDisplayMetrics().height),
+           static_cast<uint32_t>(GetDisplayMetrics().dpi.x),
+           static_cast<uint32_t>(GetDisplayMetrics().dpi.y),
+           static_cast<uint32_t>(
+               hardware_composer_.native_display_metrics().vsync_period_ns),
+           0,
+           0,
+           0,
+           0.0,
+           {},
+           {}}};
 }
 
 // Creates a new DisplaySurface and associates it with this channel. This may
 // only be done once per channel.
-int DisplayService::OnCreateSurface(pdx::Message& message, int width,
-                                    int height, int format, int usage,
-                                    DisplaySurfaceFlags flags) {
+Status<display::SurfaceInfo> DisplayService::OnCreateSurface(
+    pdx::Message& message, const display::SurfaceAttributes& attributes) {
   // A surface may only be created once per channel.
   if (message.GetChannel())
-    return -EINVAL;
+    return ErrorStatus(EINVAL);
 
   ALOGI_IF(TRACE, "DisplayService::OnCreateSurface: cid=%d",
            message.GetChannelId());
@@ -153,119 +116,66 @@ int DisplayService::OnCreateSurface(pdx::Message& message, int width,
   // Use the channel id as the unique surface id.
   const int surface_id = message.GetChannelId();
   const int process_id = message.GetProcessId();
+  const int user_id = message.GetEffectiveUserId();
 
   ALOGI_IF(TRACE,
-           "DisplayService::OnCreateSurface: surface_id=%d process_id=%d "
-           "width=%d height=%d format=%x usage=%x flags=%x",
-           surface_id, process_id, width, height, format, usage, flags);
-
-  // TODO(eieio,jbates): Validate request parameters.
-  auto channel = std::make_shared<DisplaySurface>(
-      this, surface_id, process_id, width, height, format, usage, flags);
-
-  message.SetChannel(channel);
-  NotifyDisplayConfigurationUpdate();
-  return 0;
-}
-
-DisplayRPC::ByteBuffer DisplayService::OnGetEdsCapture(pdx::Message& message) {
-  Compositor* compositor = hardware_composer_.GetCompositor();
-  if (compositor == nullptr)
-    REPLY_ERROR_RETURN(message, EINVAL, {});
-
-  std::vector<std::uint8_t> buffer(sizeof(LateLatchOutput));
-
-  if (!compositor->GetLastEdsPose(
-          reinterpret_cast<LateLatchOutput*>(buffer.data()))) {
-    REPLY_ERROR_RETURN(message, EPERM, {});
+           "DisplayService::OnCreateSurface: surface_id=%d process_id=%d",
+           surface_id, process_id);
+
+  auto surface_status =
+      DisplaySurface::Create(this, surface_id, process_id, user_id, attributes);
+  if (!surface_status) {
+    ALOGE("DisplayService::OnCreateSurface: Failed to create surface: %s",
+          surface_status.GetErrorMessage().c_str());
+    return ErrorStatus(surface_status.error());
   }
 
-  return WrapBuffer(std::move(buffer));
-}
-
-void DisplayService::OnSetViewerParams(pdx::Message& message,
-                                       const ViewerParams& view_params) {
-  Compositor* compositor = hardware_composer_.GetCompositor();
-  if (compositor == nullptr)
-    REPLY_ERROR_RETURN(message, EINVAL);
-
-  FieldOfView left(55.0f, 55.0f, 55.0f, 55.0f);
-  FieldOfView right(55.0f, 55.0f, 55.0f, 55.0f);
-  if (view_params.left_eye_field_of_view_angles.size() >= 4) {
-    left = FieldOfView(ToRad(view_params.left_eye_field_of_view_angles[0]),
-                       ToRad(view_params.left_eye_field_of_view_angles[1]),
-                       ToRad(view_params.left_eye_field_of_view_angles[2]),
-                       ToRad(view_params.left_eye_field_of_view_angles[3]));
-    right = FieldOfView(ToRad(view_params.left_eye_field_of_view_angles[1]),
-                        ToRad(view_params.left_eye_field_of_view_angles[0]),
-                        ToRad(view_params.left_eye_field_of_view_angles[2]),
-                        ToRad(view_params.left_eye_field_of_view_angles[3]));
-  }
+  SurfaceType surface_type = surface_status.get()->surface_type();
+  display::SurfaceUpdateFlags update_flags =
+      surface_status.get()->update_flags();
+  display::SurfaceInfo surface_info{surface_status.get()->surface_id(),
+                                    surface_status.get()->visible(),
+                                    surface_status.get()->z_order()};
 
-  std::shared_ptr<ColorChannelDistortion> red_distortion;
-  std::shared_ptr<ColorChannelDistortion> green_distortion;
-  std::shared_ptr<ColorChannelDistortion> blue_distortion;
+  message.SetChannel(surface_status.take());
 
-  // We should always have a red distortion.
-  LOG_FATAL_IF(view_params.distortion_coefficients_r.empty());
-  red_distortion = std::make_shared<PolynomialRadialDistortion>(
-      view_params.distortion_coefficients_r);
-
-  if (!view_params.distortion_coefficients_g.empty()) {
-    green_distortion = std::make_shared<PolynomialRadialDistortion>(
-        view_params.distortion_coefficients_g);
-  }
-
-  if (!view_params.distortion_coefficients_b.empty()) {
-    blue_distortion = std::make_shared<PolynomialRadialDistortion>(
-        view_params.distortion_coefficients_b);
-  }
-
-  HeadMountMetrics::EyeOrientation left_orientation =
-      HeadMountMetrics::EyeOrientation::kCCW0Degrees;
-  HeadMountMetrics::EyeOrientation right_orientation =
-      HeadMountMetrics::EyeOrientation::kCCW0Degrees;
+  SurfaceUpdated(surface_type, update_flags);
+  return {surface_info};
+}
 
-  if (view_params.eye_orientations.size() > 1) {
-    left_orientation = static_cast<HeadMountMetrics::EyeOrientation>(
-        view_params.eye_orientations[0]);
-    right_orientation = static_cast<HeadMountMetrics::EyeOrientation>(
-        view_params.eye_orientations[1]);
+void DisplayService::SurfaceUpdated(SurfaceType surface_type,
+                                    display::SurfaceUpdateFlags update_flags) {
+  ALOGD_IF(TRACE, "DisplayService::SurfaceUpdated: update_flags=%x",
+           update_flags.value());
+  if (update_flags.value() != 0) {
+    if (surface_type == SurfaceType::Application)
+      NotifyDisplayConfigurationUpdate();
+    else
+      UpdateActiveDisplaySurfaces();
   }
-
-  HeadMountMetrics head_mount_metrics(
-      view_params.inter_lens_distance, view_params.tray_to_lens_distance,
-      view_params.screen_to_lens_distance,
-      static_cast<HeadMountMetrics::VerticalAlignment>(
-          view_params.vertical_alignment),
-      left, right, red_distortion, green_distortion, blue_distortion,
-      left_orientation, right_orientation,
-      view_params.screen_center_to_lens_distance);
-
-  compositor->UpdateHeadMountMetrics(head_mount_metrics);
 }
 
 pdx::Status<BorrowedNativeBufferHandle> DisplayService::OnGetNamedBuffer(
     pdx::Message& /* message */, const std::string& name) {
+  ALOGD_IF(TRACE, "displayService::OnGetNamedBuffer: name=%s", name.c_str());
   auto named_buffer = named_buffers_.find(name);
-  if (named_buffer != named_buffers_.end()) {
+  if (named_buffer != named_buffers_.end())
     return {BorrowedNativeBufferHandle(*named_buffer->second, 0)};
-  }
-
-  return pdx::ErrorStatus(EINVAL);
+  else
+    return pdx::ErrorStatus(EINVAL);
 }
 
 // Calls the message handler for the DisplaySurface associated with this
 // channel.
-pdx::Status<void> DisplayService::HandleSurfaceMessage(pdx::Message& message) {
-  auto surface = std::static_pointer_cast<SurfaceChannel>(message.GetChannel());
+Status<void> DisplayService::HandleSurfaceMessage(pdx::Message& message) {
+  auto surface = std::static_pointer_cast<DisplaySurface>(message.GetChannel());
   ALOGW_IF(!surface,
            "DisplayService::HandleSurfaceMessage: surface is nullptr!");
 
   if (surface)
     return surface->HandleMessage(message);
   else
-    REPLY_ERROR_RETURN(message, EINVAL, {});
+    return ErrorStatus(EINVAL);
 }
 
 std::shared_ptr<DisplaySurface> DisplayService::GetDisplaySurface(
@@ -278,14 +188,18 @@ DisplayService::GetDisplaySurfaces() const {
   return GetChannels<DisplaySurface>();
 }
 
-std::vector<std::shared_ptr<DisplaySurface>>
+std::vector<std::shared_ptr<DirectDisplaySurface>>
 DisplayService::GetVisibleDisplaySurfaces() const {
-  std::vector<std::shared_ptr<DisplaySurface>> visible_surfaces;
+  std::vector<std::shared_ptr<DirectDisplaySurface>> visible_surfaces;
 
   ForEachDisplaySurface(
+      SurfaceType::Direct,
       [&](const std::shared_ptr<DisplaySurface>& surface) mutable {
-        if (surface->IsVisible())
-          visible_surfaces.push_back(surface);
+        if (surface->visible()) {
+          visible_surfaces.push_back(
+              std::static_pointer_cast<DirectDisplaySurface>(surface));
+          surface->ClearUpdate();
+        }
       });
 
   return visible_surfaces;
@@ -294,40 +208,21 @@ DisplayService::GetVisibleDisplaySurfaces() const {
 void DisplayService::UpdateActiveDisplaySurfaces() {
   auto visible_surfaces = GetVisibleDisplaySurfaces();
 
-  // Sort the surfaces based on manager z order first, then client z order.
   std::sort(visible_surfaces.begin(), visible_surfaces.end(),
             [](const std::shared_ptr<DisplaySurface>& a,
                const std::shared_ptr<DisplaySurface>& b) {
-              return a->manager_z_order() != b->manager_z_order()
-                         ? a->manager_z_order() < b->manager_z_order()
-                         : a->client_z_order() < b->client_z_order();
+              return a->z_order() < b->z_order();
             });
 
   ALOGD_IF(TRACE,
            "DisplayService::UpdateActiveDisplaySurfaces: %zd visible surfaces",
            visible_surfaces.size());
 
-  // TODO(jbates) Have the shell manage blurred layers.
-  bool blur_requested = false;
-  auto end = visible_surfaces.crend();
-  for (auto it = visible_surfaces.crbegin(); it != end; ++it) {
-    auto surface = *it;
-    // Surfaces with exclude_from_blur==true are not blurred
-    // and are excluded from blur computation of other layers.
-    if (surface->client_exclude_from_blur()) {
-      surface->ManagerSetBlur(0.0f);
-      continue;
-    }
-    surface->ManagerSetBlur(blur_requested ? 1.0f : 0.0f);
-    if (surface->client_blur_behind())
-      blur_requested = true;
-  }
-
   hardware_composer_.SetDisplaySurfaces(std::move(visible_surfaces));
 }
 
 pdx::Status<BorrowedNativeBufferHandle> DisplayService::SetupNamedBuffer(
-    const std::string& name, size_t size, int usage) {
+    const std::string& name, size_t size, uint64_t usage) {
   auto named_buffer = named_buffers_.find(name);
   if (named_buffer == named_buffers_.end()) {
     auto ion_buffer = std::make_unique<IonBuffer>(static_cast<int>(size), 1,
@@ -354,15 +249,16 @@ void DisplayService::NotifyDisplayConfigurationUpdate() {
     update_notifier_();
 }
 
-int DisplayService::IsVrAppRunning(pdx::Message& message) {
+Status<bool> DisplayService::IsVrAppRunning(pdx::Message& /*message*/) {
   bool visible = false;
   ForEachDisplaySurface(
+      SurfaceType::Application,
       [&visible](const std::shared_ptr<DisplaySurface>& surface) {
-        if (surface->client_z_order() == 0 && surface->IsVisible())
+        if (surface->visible())
           visible = true;
       });
 
-  REPLY_SUCCESS_RETURN(message, visible, 0);
+  return {visible};
 }
 
 }  // namespace dvr
index 3b0d07e..bb4eeef 100644 (file)
@@ -2,10 +2,10 @@
 #define ANDROID_DVR_SERVICES_DISPLAYD_DISPLAY_SERVICE_H_
 
 #include <pdx/service.h>
+#include <pdx/status.h>
 #include <private/dvr/buffer_hub_client.h>
 #include <private/dvr/bufferhub_rpc.h>
 #include <private/dvr/display_protocol.h>
-#include <private/dvr/late_latch.h>
 
 #include <functional>
 #include <iterator>
 
 #include "acquired_buffer.h"
 #include "display_surface.h"
+#include "epoll_event_dispatcher.h"
 #include "hardware_composer.h"
 
 namespace android {
 namespace dvr {
 
-// DisplayService implements the displayd display service over ServiceFS.
+// DisplayService implements the display service component of VrFlinger.
 class DisplayService : public pdx::ServiceBase<DisplayService> {
  public:
   bool IsInitialized() const override;
@@ -32,7 +33,7 @@ class DisplayService : public pdx::ServiceBase<DisplayService> {
 
   std::shared_ptr<DisplaySurface> GetDisplaySurface(int surface_id) const;
   std::vector<std::shared_ptr<DisplaySurface>> GetDisplaySurfaces() const;
-  std::vector<std::shared_ptr<DisplaySurface>> GetVisibleDisplaySurfaces()
+  std::vector<std::shared_ptr<DirectDisplaySurface>> GetVisibleDisplaySurfaces()
       const;
 
   // Updates the list of actively displayed surfaces. This must be called after
@@ -40,14 +41,15 @@ class DisplayService : public pdx::ServiceBase<DisplayService> {
   void UpdateActiveDisplaySurfaces();
 
   pdx::Status<BorrowedNativeBufferHandle> SetupNamedBuffer(
-      const std::string& name, size_t size, int usage);
+      const std::string& name, size_t size, uint64_t usage);
 
   template <class A>
-  void ForEachDisplaySurface(A action) const {
-    ForEachChannel([action](const ChannelIterator::value_type& pair) mutable {
-      auto surface = std::static_pointer_cast<SurfaceChannel>(pair.second);
-      if (surface->type() == SurfaceTypeEnum::Normal)
-        action(std::static_pointer_cast<DisplaySurface>(surface));
+  void ForEachDisplaySurface(SurfaceType surface_type, A action) const {
+    ForEachChannel([surface_type,
+                    action](const ChannelIterator::value_type& pair) mutable {
+      auto surface = std::static_pointer_cast<DisplaySurface>(pair.second);
+      if (surface->surface_type() == surface_type)
+        action(surface);
     });
   }
 
@@ -75,22 +77,30 @@ class DisplayService : public pdx::ServiceBase<DisplayService> {
 
   friend class VrDisplayStateService;
 
-  DisplayService();
-  DisplayService(android::Hwc2::Composer* hidl);
+  using RequestDisplayCallback = std::function<void(bool)>;
 
-  SystemDisplayMetrics OnGetMetrics(pdx::Message& message);
-  int OnCreateSurface(pdx::Message& message, int width, int height, int format,
-                      int usage, DisplaySurfaceFlags flags);
+  DisplayService(android::Hwc2::Composer* hidl,
+                 RequestDisplayCallback request_display_callback);
 
-  DisplayRPC::ByteBuffer OnGetEdsCapture(pdx::Message& message);
-
-  void OnSetViewerParams(pdx::Message& message,
-                         const ViewerParams& view_params);
   pdx::Status<BorrowedNativeBufferHandle> OnGetNamedBuffer(
       pdx::Message& message, const std::string& name);
+  pdx::Status<display::Metrics> OnGetMetrics(pdx::Message& message);
+  pdx::Status<display::SurfaceInfo> OnCreateSurface(
+      pdx::Message& message, const display::SurfaceAttributes& attributes);
 
   // Temporary query for current VR status. Will be removed later.
-  int IsVrAppRunning(pdx::Message& message);
+  pdx::Status<bool> IsVrAppRunning(pdx::Message& message);
+
+  pdx::Status<void> AddEventHandler(int fd, int events,
+                                    EpollEventDispatcher::Handler handler) {
+    return dispatcher_.AddEventHandler(fd, events, handler);
+  }
+  pdx::Status<void> RemoveEventHandler(int fd) {
+    return dispatcher_.RemoveEventHandler(fd);
+  }
+
+  void SurfaceUpdated(SurfaceType surface_type,
+                      display::SurfaceUpdateFlags update_flags);
 
   // Called by DisplaySurface to signal that a surface property has changed and
   // the display manager should be notified.
@@ -98,13 +108,15 @@ class DisplayService : public pdx::ServiceBase<DisplayService> {
 
   pdx::Status<void> HandleSurfaceMessage(pdx::Message& message);
 
-  DisplayService(const DisplayService&) = delete;
-  void operator=(const DisplayService&) = delete;
-
   HardwareComposer hardware_composer_;
+  RequestDisplayCallback request_display_callback_;
+  EpollEventDispatcher dispatcher_;
   DisplayConfigurationUpdateNotifier update_notifier_;
 
   std::unordered_map<std::string, std::unique_ptr<IonBuffer>> named_buffers_;
+
+  DisplayService(const DisplayService&) = delete;
+  void operator=(const DisplayService&) = delete;
 };
 
 }  // namespace dvr
index a7220fe..5829788 100644 (file)
@@ -1,16 +1,21 @@
 #include "display_surface.h"
 
+#include <private/android_filesystem_config.h>
 #include <utils/Trace.h>
 
 #include <private/dvr/platform_defines.h>
+#include <private/dvr/trusted_uids.h>
 
 #include "display_service.h"
 #include "hardware_composer.h"
 
 #define LOCAL_TRACE 1
 
+using android::dvr::display::DisplayProtocol;
 using android::pdx::BorrowedChannelHandle;
+using android::pdx::ErrorStatus;
 using android::pdx::LocalChannelHandle;
+using android::pdx::LocalHandle;
 using android::pdx::Message;
 using android::pdx::RemoteChannelHandle;
 using android::pdx::Status;
@@ -20,104 +25,320 @@ using android::pdx::rpc::IfAnyOf;
 namespace android {
 namespace dvr {
 
-DisplaySurface::DisplaySurface(DisplayService* service, int surface_id,
-                               int process_id, int width, int height,
-                               int format, int usage, int flags)
-    : SurfaceChannel(service, surface_id, SurfaceTypeEnum::Normal,
-                     sizeof(DisplaySurfaceMetadata)),
+DisplaySurface::DisplaySurface(DisplayService* service,
+                               SurfaceType surface_type, int surface_id,
+                               int process_id, int user_id,
+                               const display::SurfaceAttributes& attributes)
+    : service_(service),
+      surface_type_(surface_type),
+      surface_id_(surface_id),
       process_id_(process_id),
-      acquired_buffers_(kMaxPostedBuffers),
-      video_mesh_surfaces_updated_(false),
-      width_(width),
-      height_(height),
-      format_(format),
-      usage_(usage),
-      flags_(flags),
-      client_visible_(false),
-      client_z_order_(0),
-      client_exclude_from_blur_(false),
-      client_blur_behind_(false),
-      manager_visible_(false),
-      manager_z_order_(0),
-      manager_blur_(0.0f),
-      layer_order_(0),
-      allocated_buffer_index_(0) {}
+      user_id_(user_id),
+      attributes_(attributes),
+      update_flags_(display::SurfaceUpdateFlags::NewSurface) {}
 
 DisplaySurface::~DisplaySurface() {
   ALOGD_IF(LOCAL_TRACE,
            "DisplaySurface::~DisplaySurface: surface_id=%d process_id=%d",
-           surface_id(), process_id_);
+           surface_id(), process_id());
 }
 
-void DisplaySurface::ManagerSetVisible(bool visible) {
-  std::lock_guard<std::mutex> autolock(lock_);
-  manager_visible_ = visible;
+Status<void> DisplaySurface::HandleMessage(pdx::Message& message) {
+  switch (message.GetOp()) {
+    case DisplayProtocol::SetAttributes::Opcode:
+      DispatchRemoteMethod<DisplayProtocol::SetAttributes>(
+          *this, &DisplaySurface::OnSetAttributes, message);
+      break;
+
+    case DisplayProtocol::GetSurfaceInfo::Opcode:
+      DispatchRemoteMethod<DisplayProtocol::GetSurfaceInfo>(
+          *this, &DisplaySurface::OnGetSurfaceInfo, message);
+      break;
+
+    case DisplayProtocol::CreateQueue::Opcode:
+      DispatchRemoteMethod<DisplayProtocol::CreateQueue>(
+          *this, &DisplaySurface::OnCreateQueue, message);
+      break;
+  }
+
+  return {};
 }
 
-void DisplaySurface::ManagerSetZOrder(int z_order) {
-  std::lock_guard<std::mutex> autolock(lock_);
-  manager_z_order_ = z_order;
+Status<void> DisplaySurface::OnSetAttributes(
+    pdx::Message& /*message*/, const display::SurfaceAttributes& attributes) {
+  display::SurfaceUpdateFlags update_flags;
+
+  for (const auto& attribute : attributes) {
+    const auto& key = attribute.first;
+    const auto* variant = &attribute.second;
+    bool invalid_value = false;
+    bool visibility_changed = false;
+
+    // Catch attributes that have significance to the display service.
+    switch (key) {
+      case display::SurfaceAttribute::ZOrder:
+        invalid_value = !IfAnyOf<int32_t, int64_t, float>::Call(
+            variant, [&](const auto& value) {
+              if (z_order_ != value) {
+                visibility_changed = true;
+                z_order_ = value;
+              }
+            });
+        break;
+      case display::SurfaceAttribute::Visible:
+        invalid_value = !IfAnyOf<int32_t, int64_t, bool>::Call(
+            variant, [&](const auto& value) {
+              if (visible_ != value) {
+                visibility_changed = true;
+                visible_ = value;
+              }
+            });
+        break;
+    }
+
+    if (invalid_value) {
+      ALOGW(
+          "DisplaySurface::OnClientSetAttributes: Failed to set display "
+          "surface attribute '%d' because of incompatible type: %d",
+          key, variant->index());
+    } else {
+      // Only update the attribute map with valid values.
+      attributes_[attribute.first] = attribute.second;
+
+      // All attribute changes generate a notification, even if the value
+      // doesn't change. Visibility attributes set a flag only if the value
+      // changes.
+      update_flags.Set(display::SurfaceUpdateFlags::AttributesChanged);
+      if (visibility_changed)
+        update_flags.Set(display::SurfaceUpdateFlags::VisibilityChanged);
+    }
+  }
+
+  SurfaceUpdated(update_flags);
+  return {};
 }
 
-void DisplaySurface::ManagerSetBlur(float blur) {
-  std::lock_guard<std::mutex> autolock(lock_);
-  manager_blur_ = blur;
+void DisplaySurface::SurfaceUpdated(display::SurfaceUpdateFlags update_flags) {
+  ALOGD_IF(TRACE,
+           "DisplaySurface::SurfaceUpdated: surface_id=%d update_flags=0x%x",
+           surface_id(), update_flags.value());
+
+  update_flags_.Set(update_flags);
+  service()->SurfaceUpdated(surface_type(), update_flags_);
+}
+
+void DisplaySurface::ClearUpdate() {
+  ALOGD_IF(TRACE, "DisplaySurface::ClearUpdate: surface_id=%d", surface_id());
+  update_flags_ = display::SurfaceUpdateFlags::None;
 }
 
-void DisplaySurface::ClientSetVisible(bool visible) {
+Status<display::SurfaceInfo> DisplaySurface::OnGetSurfaceInfo(
+    Message& /*message*/) {
+  ALOGD_IF(
+      TRACE,
+      "DisplaySurface::OnGetSurfaceInfo: surface_id=%d visible=%d z_order=%d",
+      surface_id(), visible(), z_order());
+  return {{surface_id(), visible(), z_order()}};
+}
+
+Status<void> DisplaySurface::RegisterQueue(
+    const std::shared_ptr<ConsumerQueue>& consumer_queue) {
+  ALOGD_IF(TRACE, "DisplaySurface::RegisterQueue: surface_id=%d queue_id=%d",
+           surface_id(), consumer_queue->id());
+  // Capture references for the lambda to work around apparent clang bug.
+  // TODO(eieio): Figure out if there is a clang bug or C++11 ambiguity when
+  // capturing self and consumer_queue by copy in the following case:
+  //    auto self = Self();
+  //    [self, consumer_queue](int events) {
+  //        self->OnQueueEvent(consuemr_queue, events); }
+  //
+  struct State {
+    std::shared_ptr<DisplaySurface> surface;
+    std::shared_ptr<ConsumerQueue> queue;
+  };
+  State state{Self(), consumer_queue};
+
+  return service()->AddEventHandler(
+      consumer_queue->queue_fd(), EPOLLIN | EPOLLHUP | EPOLLET,
+      [state](int events) {
+        state.surface->OnQueueEvent(state.queue, events);
+      });
+}
+
+Status<void> DisplaySurface::UnregisterQueue(
+    const std::shared_ptr<ConsumerQueue>& consumer_queue) {
+  ALOGD_IF(TRACE, "DisplaySurface::UnregisterQueue: surface_id=%d queue_id=%d",
+           surface_id(), consumer_queue->id());
+  return service()->RemoveEventHandler(consumer_queue->queue_fd());
+}
+
+void DisplaySurface::OnQueueEvent(
+    const std::shared_ptr<ConsumerQueue>& /*consumer_queue*/, int /*events*/) {
+  ALOGE(
+      "DisplaySurface::OnQueueEvent: ERROR base virtual method should not be "
+      "called!!!");
+}
+
+std::shared_ptr<ConsumerQueue> ApplicationDisplaySurface::GetQueue(
+    int32_t queue_id) {
+  ALOGD_IF(TRACE,
+           "ApplicationDisplaySurface::GetQueue: surface_id=%d queue_id=%d",
+           surface_id(), queue_id);
+
+  auto search = consumer_queues_.find(queue_id);
+  if (search != consumer_queues_.end())
+    return search->second;
+  else
+    return nullptr;
+}
+
+std::vector<int32_t> ApplicationDisplaySurface::GetQueueIds() const {
+  std::vector<int32_t> queue_ids;
+  for (const auto& entry : consumer_queues_)
+    queue_ids.push_back(entry.first);
+  return queue_ids;
+}
+
+Status<LocalChannelHandle> ApplicationDisplaySurface::OnCreateQueue(
+    Message& /*message*/, size_t meta_size_bytes) {
+  ATRACE_NAME("ApplicationDisplaySurface::OnCreateQueue");
+  ALOGD_IF(TRACE,
+           "ApplicationDisplaySurface::OnCreateQueue: surface_id=%d, "
+           "meta_size_bytes=%zu",
+           surface_id(), meta_size_bytes);
+
   std::lock_guard<std::mutex> autolock(lock_);
-  client_visible_ = visible;
+  auto producer = ProducerQueue::Create(meta_size_bytes);
+  if (!producer) {
+    ALOGE(
+        "ApplicationDisplaySurface::OnCreateQueue: Failed to create producer "
+        "queue!");
+    return ErrorStatus(ENOMEM);
+  }
+
+  std::shared_ptr<ConsumerQueue> consumer =
+      producer->CreateSilentConsumerQueue();
+  auto status = RegisterQueue(consumer);
+  if (!status) {
+    ALOGE(
+        "ApplicationDisplaySurface::OnCreateQueue: Failed to register consumer "
+        "queue: %s",
+        status.GetErrorMessage().c_str());
+    return status.error_status();
+  }
+
+  consumer_queues_[consumer->id()] = std::move(consumer);
+
+  SurfaceUpdated(display::SurfaceUpdateFlags::BuffersChanged);
+  return std::move(producer->GetChannelHandle());
 }
 
-void DisplaySurface::ClientSetZOrder(int z_order) {
+void ApplicationDisplaySurface::OnQueueEvent(
+    const std::shared_ptr<ConsumerQueue>& consumer_queue, int events) {
+  ALOGD_IF(TRACE,
+           "ApplicationDisplaySurface::OnQueueEvent: queue_id=%d events=%x",
+           consumer_queue->id(), events);
+
+  // Always give the queue a chance to handle its internal bookkeeping.
+  consumer_queue->HandleQueueEvents();
+
+  // Check for hangup and remove a queue that is no longer needed.
   std::lock_guard<std::mutex> autolock(lock_);
-  client_z_order_ = z_order;
+  if (consumer_queue->hung_up()) {
+    ALOGD_IF(TRACE, "ApplicationDisplaySurface::OnQueueEvent: Removing queue.");
+    UnregisterQueue(consumer_queue);
+    auto search = consumer_queues_.find(consumer_queue->id());
+    if (search != consumer_queues_.end()) {
+      consumer_queues_.erase(search);
+    } else {
+      ALOGE(
+          "ApplicationDisplaySurface::OnQueueEvent: Failed to find queue_id=%d",
+          consumer_queue->id());
+    }
+    SurfaceUpdated(display::SurfaceUpdateFlags::BuffersChanged);
+  }
 }
 
-void DisplaySurface::ClientSetExcludeFromBlur(bool exclude_from_blur) {
+Status<LocalChannelHandle> DirectDisplaySurface::OnCreateQueue(
+    Message& /*message*/, size_t meta_size_bytes) {
+  ATRACE_NAME("DirectDisplaySurface::OnCreateQueue");
+  ALOGD_IF(
+      TRACE,
+      "DirectDisplaySurface::OnCreateQueue: surface_id=%d meta_size_bytes=%zu",
+      surface_id(), meta_size_bytes);
+
   std::lock_guard<std::mutex> autolock(lock_);
-  client_exclude_from_blur_ = exclude_from_blur;
+  if (!direct_queue_) {
+    auto producer = ProducerQueue::Create(meta_size_bytes);
+    if (!producer) {
+      ALOGE(
+          "DirectDisplaySurface::OnCreateQueue: Failed to create producer "
+          "queue!");
+      return ErrorStatus(ENOMEM);
+    }
+
+    direct_queue_ = producer->CreateConsumerQueue();
+    auto status = RegisterQueue(direct_queue_);
+    if (!status) {
+      ALOGE(
+          "DirectDisplaySurface::OnCreateQueue: Failed to register consumer "
+          "queue: %s",
+          status.GetErrorMessage().c_str());
+      return status.error_status();
+    }
+
+    return std::move(producer->GetChannelHandle());
+  } else {
+    return ErrorStatus(EALREADY);
+  }
 }
 
-void DisplaySurface::ClientSetBlurBehind(bool blur_behind) {
+void DirectDisplaySurface::OnQueueEvent(
+    const std::shared_ptr<ConsumerQueue>& consumer_queue, int events) {
+  ALOGD_IF(TRACE, "DirectDisplaySurface::OnQueueEvent: queue_id=%d events=%x",
+           consumer_queue->id(), events);
+
+  // Always give the queue a chance to handle its internal bookkeeping.
+  consumer_queue->HandleQueueEvents();
+
+  // Check for hangup and remove a queue that is no longer needed.
   std::lock_guard<std::mutex> autolock(lock_);
-  client_blur_behind_ = blur_behind;
+  if (consumer_queue->hung_up()) {
+    ALOGD_IF(TRACE, "DirectDisplaySurface::OnQueueEvent: Removing queue.");
+    UnregisterQueue(consumer_queue);
+    direct_queue_ = nullptr;
+  }
 }
 
-void DisplaySurface::DequeueBuffersLocked() {
-  if (consumer_queue_ == nullptr) {
+void DirectDisplaySurface::DequeueBuffersLocked() {
+  if (direct_queue_ == nullptr) {
     ALOGE(
-        "DisplaySurface::DequeueBuffersLocked: Consumer queue is not "
+        "DirectDisplaySurface::DequeueBuffersLocked: Consumer queue is not "
         "initialized.");
     return;
   }
 
-  size_t slot;
-  uint64_t sequence;
   while (true) {
     LocalHandle acquire_fence;
-    auto buffer_consumer =
-        consumer_queue_->Dequeue(0, &slot, &sequence, &acquire_fence);
-    if (!buffer_consumer) {
-      ALOGD_IF(TRACE,
-               "DisplaySurface::DequeueBuffersLocked: We have dequeued all "
-               "available buffers.");
+    size_t slot;
+    auto buffer_status = direct_queue_->Dequeue(0, &slot, &acquire_fence);
+    if (!buffer_status) {
+      ALOGD_IF(
+          TRACE && buffer_status.error() == ETIMEDOUT,
+          "DirectDisplaySurface::DequeueBuffersLocked: All buffers dequeued.");
+      ALOGE_IF(buffer_status.error() != ETIMEDOUT,
+               "DirectDisplaySurface::DequeueBuffersLocked: Failed to dequeue "
+               "buffer: %s",
+               buffer_status.GetErrorMessage().c_str());
       return;
     }
+    auto buffer_consumer = buffer_status.take();
 
-    // Save buffer index, associated with the buffer id so that it can be looked
-    // up later.
-    int buffer_id = buffer_consumer->id();
-    if (buffer_id_to_index_.find(buffer_id) == buffer_id_to_index_.end()) {
-      buffer_id_to_index_[buffer_id] = allocated_buffer_index_;
-      ++allocated_buffer_index_;
-    }
-
-    if (!IsVisible()) {
+    if (!visible()) {
       ATRACE_NAME("DropFrameOnInvisibleSurface");
       ALOGD_IF(TRACE,
-               "DisplaySurface::DequeueBuffersLocked: Discarding buffer_id=%d "
-               "on invisible surface.",
+               "DirectDisplaySurface::DequeueBuffersLocked: Discarding "
+               "buffer_id=%d on invisible surface.",
                buffer_consumer->id());
       buffer_consumer->Discard();
       continue;
@@ -125,34 +346,34 @@ void DisplaySurface::DequeueBuffersLocked() {
 
     if (acquired_buffers_.IsFull()) {
       ALOGE(
-          "DisplaySurface::DequeueBuffersLocked: Posted buffers full, "
+          "DirectDisplaySurface::DequeueBuffersLocked: Posted buffers full, "
           "overwriting.");
       acquired_buffers_.PopBack();
     }
 
     acquired_buffers_.Append(
-        AcquiredBuffer(buffer_consumer, std::move(acquire_fence), sequence));
+        AcquiredBuffer(buffer_consumer, std::move(acquire_fence)));
   }
 }
 
-AcquiredBuffer DisplaySurface::AcquireCurrentBuffer() {
+AcquiredBuffer DirectDisplaySurface::AcquireCurrentBuffer() {
   std::lock_guard<std::mutex> autolock(lock_);
   DequeueBuffersLocked();
 
   if (acquired_buffers_.IsEmpty()) {
     ALOGE(
-        "DisplaySurface::AcquireCurrentBuffer: attempt to acquire buffer when "
-        "none are posted.");
+        "DirectDisplaySurface::AcquireCurrentBuffer: attempt to acquire buffer "
+        "when none are posted.");
     return AcquiredBuffer();
   }
   AcquiredBuffer buffer = std::move(acquired_buffers_.Front());
   acquired_buffers_.PopFront();
-  ALOGD_IF(TRACE, "DisplaySurface::AcquireCurrentBuffer: buffer: %p",
+  ALOGD_IF(TRACE, "DirectDisplaySurface::AcquireCurrentBuffer: buffer: %p",
            buffer.buffer().get());
   return buffer;
 }
 
-AcquiredBuffer DisplaySurface::AcquireNewestAvailableBuffer(
+AcquiredBuffer DirectDisplaySurface::AcquireNewestAvailableBuffer(
     AcquiredBuffer* skipped_buffer) {
   std::lock_guard<std::mutex> autolock(lock_);
   DequeueBuffersLocked();
@@ -175,23 +396,13 @@ AcquiredBuffer DisplaySurface::AcquireNewestAvailableBuffer(
     if (frames == 2)
       break;
   }
-  ALOGD_IF(TRACE, "DisplaySurface::AcquireNewestAvailableBuffer: buffer: %p",
+  ALOGD_IF(TRACE,
+           "DirectDisplaySurface::AcquireNewestAvailableBuffer: buffer: %p",
            buffer.buffer().get());
   return buffer;
 }
 
-uint32_t DisplaySurface::GetRenderBufferIndex(int buffer_id) {
-  std::lock_guard<std::mutex> autolock(lock_);
-
-  if (buffer_id_to_index_.find(buffer_id) == buffer_id_to_index_.end()) {
-    ALOGW("DisplaySurface::GetRenderBufferIndex: unknown buffer_id %d.",
-          buffer_id);
-    return 0;
-  }
-  return buffer_id_to_index_[buffer_id];
-}
-
-bool DisplaySurface::IsBufferAvailable() {
+bool DirectDisplaySurface::IsBufferAvailable() {
   std::lock_guard<std::mutex> autolock(lock_);
   DequeueBuffersLocked();
 
@@ -199,158 +410,48 @@ bool DisplaySurface::IsBufferAvailable() {
          acquired_buffers_.Front().IsAvailable();
 }
 
-bool DisplaySurface::IsBufferPosted() {
+bool DirectDisplaySurface::IsBufferPosted() {
   std::lock_guard<std::mutex> autolock(lock_);
   DequeueBuffersLocked();
 
   return !acquired_buffers_.IsEmpty();
 }
 
-pdx::Status<void> DisplaySurface::HandleMessage(pdx::Message& message) {
-  switch (message.GetOp()) {
-    case DisplayRPC::SetAttributes::Opcode:
-      DispatchRemoteMethod<DisplayRPC::SetAttributes>(
-          *this, &DisplaySurface::OnClientSetAttributes, message);
-      break;
-
-    case DisplayRPC::CreateBufferQueue::Opcode:
-      DispatchRemoteMethod<DisplayRPC::CreateBufferQueue>(
-          *this, &DisplaySurface::OnCreateBufferQueue, message);
-      break;
-
-    case DisplayRPC::CreateVideoMeshSurface::Opcode:
-      DispatchRemoteMethod<DisplayRPC::CreateVideoMeshSurface>(
-          *this, &DisplaySurface::OnCreateVideoMeshSurface, message);
-      break;
-
-    default:
-      return SurfaceChannel::HandleMessage(message);
-  }
-
-  return {};
-}
-
-int DisplaySurface::OnClientSetAttributes(
-    pdx::Message& /*message*/, const DisplaySurfaceAttributes& attributes) {
-  for (const auto& attribute : attributes) {
-    const auto& key = attribute.first;
-    const auto* variant = &attribute.second;
-    bool invalid_value = false;
-    switch (key) {
-      case DisplaySurfaceAttributeEnum::ZOrder:
-        invalid_value = !IfAnyOf<int32_t, int64_t, float>::Call(
-            variant, [this](const auto& value) {
-              DisplaySurface::ClientSetZOrder(value);
-            });
-        break;
-      case DisplaySurfaceAttributeEnum::Visible:
-        invalid_value = !IfAnyOf<int32_t, int64_t, bool>::Call(
-            variant, [this](const auto& value) {
-              DisplaySurface::ClientSetVisible(value);
-            });
-        break;
-      case DisplaySurfaceAttributeEnum::ExcludeFromBlur:
-        invalid_value = !IfAnyOf<int32_t, int64_t, bool>::Call(
-            variant, [this](const auto& value) {
-              DisplaySurface::ClientSetExcludeFromBlur(value);
-            });
-        break;
-      case DisplaySurfaceAttributeEnum::BlurBehind:
-        invalid_value = !IfAnyOf<int32_t, int64_t, bool>::Call(
-            variant, [this](const auto& value) {
-              DisplaySurface::ClientSetBlurBehind(value);
-            });
-        break;
-      default:
-        ALOGW(
-            "DisplaySurface::OnClientSetAttributes: Unrecognized attribute %d "
-            "surface_id=%d",
-            key, surface_id());
-        break;
-    }
-
-    if (invalid_value) {
-      ALOGW(
-          "DisplaySurface::OnClientSetAttributes: Failed to set display "
-          "surface attribute '%s' because of incompatible type: %d",
-          DisplaySurfaceAttributeEnum::ToString(key).c_str(), variant->index());
+Status<std::shared_ptr<DisplaySurface>> DisplaySurface::Create(
+    DisplayService* service, int surface_id, int process_id, int user_id,
+    const display::SurfaceAttributes& attributes) {
+  bool direct = false;
+  auto search = attributes.find(display::SurfaceAttribute::Direct);
+  if (search != attributes.end()) {
+    if (!IfAnyOf<int32_t, int64_t, bool, float>::Get(&search->second,
+                                                     &direct)) {
+      ALOGE(
+          "DisplaySurface::Create: Invalid type for SurfaceAttribute::Direct!");
+      return ErrorStatus(EINVAL);
     }
   }
 
-  service()->NotifyDisplayConfigurationUpdate();
-  return 0;
-}
+  ALOGD_IF(TRACE,
+           "DisplaySurface::Create: surface_id=%d process_id=%d user_id=%d "
+           "direct=%d",
+           surface_id, process_id, user_id, direct);
 
-LocalChannelHandle DisplaySurface::OnCreateBufferQueue(Message& message) {
-  ATRACE_NAME("DisplaySurface::OnCreateBufferQueue");
-
-  if (consumer_queue_ != nullptr) {
-    ALOGE(
-        "DisplaySurface::OnCreateBufferQueue: A ProdcuerQueue has already been "
-        "created and transported to DisplayClient.");
-    REPLY_ERROR_RETURN(message, EALREADY, {});
-  }
-
-  auto producer = ProducerQueue::Create<uint64_t>();
-  consumer_queue_ = producer->CreateConsumerQueue();
-
-  return std::move(producer->GetChannelHandle());
-}
-
-RemoteChannelHandle DisplaySurface::OnCreateVideoMeshSurface(
-    pdx::Message& message) {
-  if (flags_ & DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION) {
-    ALOGE(
-        "DisplaySurface::OnCreateVideoMeshSurface: system distortion is "
-        "disabled on this display surface, cannot create VideoMeshSurface on "
-        "top of it.");
-    REPLY_ERROR_RETURN(message, EINVAL, {});
-  }
-
-  int channel_id;
-  auto status = message.PushChannel(0, nullptr, &channel_id);
-  if (!status) {
-    ALOGE(
-        "DisplaySurface::OnCreateVideoMeshSurface: failed to push channel: %s",
-        status.GetErrorMessage().c_str());
-    REPLY_ERROR_RETURN(message, status.error(), {});
-  }
-
-  auto surface = std::make_shared<VideoMeshSurface>(service(), channel_id);
-  auto channel_status = service()->SetChannel(channel_id, surface);
-  if (!channel_status) {
-    ALOGE(
-        "DisplaySurface::OnCreateVideoMeshSurface: failed to set new video "
-        "mesh surface channel: %s",
-        channel_status.GetErrorMessage().c_str());
-    REPLY_ERROR_RETURN(message, channel_status.error(), {});
-  }
-
-  {
-    std::lock_guard<std::mutex> autolock(lock_);
-    pending_video_mesh_surfaces_.push_back(surface);
-    video_mesh_surfaces_updated_ = true;
-  }
-
-  return status.take();
-}
-
-std::vector<std::shared_ptr<VideoMeshSurface>>
-DisplaySurface::GetVideoMeshSurfaces() {
-  std::lock_guard<std::mutex> autolock(lock_);
-  std::vector<std::shared_ptr<VideoMeshSurface>> surfaces;
-
-  for (auto& surface : pending_video_mesh_surfaces_) {
-    if (auto video_surface = surface.lock()) {
-      surfaces.push_back(video_surface);
+  if (direct) {
+    const bool trusted = user_id == AID_ROOT || IsTrustedUid(user_id);
+    if (trusted) {
+      return {std::shared_ptr<DisplaySurface>{new DirectDisplaySurface(
+          service, surface_id, process_id, user_id, attributes)}};
     } else {
-      ALOGE("Unable to lock video mesh surface.");
+      ALOGE(
+          "DisplaySurface::Create: Direct surfaces may only be created by "
+          "trusted UIDs: user_id=%d",
+          user_id);
+      return ErrorStatus(EPERM);
     }
+  } else {
+    return {std::shared_ptr<DisplaySurface>{new ApplicationDisplaySurface(
+        service, surface_id, process_id, user_id, attributes)}};
   }
-
-  pending_video_mesh_surfaces_.clear();
-  video_mesh_surfaces_updated_ = false;
-  return surfaces;
 }
 
 }  // namespace dvr
index 1fec344..47a07f0 100644 (file)
@@ -3,7 +3,9 @@
 
 #include <pdx/file_handle.h>
 #include <pdx/service.h>
+#include <private/dvr/buffer_hub_queue_client.h>
 #include <private/dvr/display_protocol.h>
+#include <private/dvr/graphics_private.h>
 #include <private/dvr/ring_buffer.h>
 
 #include <functional>
 #include <vector>
 
 #include "acquired_buffer.h"
-#include "surface_channel.h"
-#include "video_mesh_surface.h"
 
 namespace android {
 namespace dvr {
 
 class DisplayService;
 
-// DisplaySurface is the service-side notion of a client display context. It is
-// responsible for managing display buffer format, geometry, and state, and
-// maintains the buffer consumers connected to the client.
-class DisplaySurface : public SurfaceChannel {
+enum class SurfaceType {
+  Direct,
+  Application,
+};
+
+class DisplaySurface : public pdx::Channel {
  public:
-  DisplaySurface(DisplayService* service, int surface_id, int process_id,
-                 int width, int height, int format, int usage, int flags);
+  static pdx::Status<std::shared_ptr<DisplaySurface>> Create(
+      DisplayService* service, int surface_id, int process_id, int user_id,
+      const display::SurfaceAttributes& attributes);
+
   ~DisplaySurface() override;
 
+  DisplayService* service() const { return service_; }
+  SurfaceType surface_type() const { return surface_type_; }
+  int surface_id() const { return surface_id_; }
   int process_id() const { return process_id_; }
-  int width() const { return width_; }
-  int height() const { return height_; }
-  int format() const { return format_; }
-  int usage() const { return usage_; }
-  int flags() const { return flags_; }
-
-  bool client_visible() const { return client_visible_; }
-  int client_z_order() const { return client_z_order_; }
-  bool client_exclude_from_blur() const { return client_exclude_from_blur_; }
-  bool client_blur_behind() const { return client_blur_behind_; }
-
-  bool manager_visible() const { return manager_visible_; }
-  int manager_z_order() const { return manager_z_order_; }
-  float manager_blur() const { return manager_blur_; }
-
-  bool video_mesh_surfaces_updated() const {
-    return video_mesh_surfaces_updated_;
+  int user_id() const { return user_id_; }
+
+  bool visible() const { return visible_; }
+  int z_order() const { return z_order_; }
+
+  const display::SurfaceAttributes& attributes() const { return attributes_; }
+  display::SurfaceUpdateFlags update_flags() const { return update_flags_; }
+
+  virtual std::vector<int32_t> GetQueueIds() const { return {}; }
+
+  bool IsUpdatePending() const {
+    return update_flags_.value() != display::SurfaceUpdateFlags::None;
   }
 
-  volatile const DisplaySurfaceMetadata* GetMetadataBufferPtr() {
-    if (EnsureMetadataBuffer()) {
-      void* addr = nullptr;
-      metadata_buffer_->GetBlobReadWritePointer(metadata_size(), &addr);
-      return static_cast<const volatile DisplaySurfaceMetadata*>(addr);
-    } else {
-      return nullptr;
-    }
+ protected:
+  DisplaySurface(DisplayService* service, SurfaceType surface_type,
+                 int surface_id, int process_id, int user_id,
+                 const display::SurfaceAttributes& attributes);
+
+  // Utility to retrieve a shared pointer to this channel as the desired derived
+  // type.
+  template <
+      typename T = DisplaySurface,
+      typename = std::enable_if_t<std::is_base_of<DisplaySurface, T>::value>>
+  std::shared_ptr<T> Self() {
+    return std::static_pointer_cast<T>(shared_from_this());
   }
 
-  uint32_t GetRenderBufferIndex(int buffer_id);
+  virtual pdx::Status<pdx::LocalChannelHandle> OnCreateQueue(
+      pdx::Message& message, size_t meta_size_bytes) = 0;
+
+  // Registers a consumer queue with the event dispatcher in DisplayService. The
+  // OnQueueEvent callback below is called to handle queue events.
+  pdx::Status<void> RegisterQueue(
+      const std::shared_ptr<ConsumerQueue>& consumer_queue);
+  pdx::Status<void> UnregisterQueue(
+      const std::shared_ptr<ConsumerQueue>& consumer_queue);
+
+  // Called by the event dispatcher in DisplayService when a registered queue
+  // event triggers. Executes on the event dispatcher thread.
+  virtual void OnQueueEvent(
+      const std::shared_ptr<ConsumerQueue>& consumer_queue, int events);
+
+  void SurfaceUpdated(display::SurfaceUpdateFlags update_flags);
+  void ClearUpdate();
+
+  // Synchronizes access to mutable state below between message dispatch thread
+  // and frame post thread.
+  mutable std::mutex lock_;
+
+ private:
+  friend class DisplayService;
+  friend class DisplayManagerService;
+
+  // Dispatches display surface messages to the appropriate handlers. This
+  // handler runs on the VrFlinger message dispatch thread.
+  pdx::Status<void> HandleMessage(pdx::Message& message);
+
+  pdx::Status<void> OnSetAttributes(
+      pdx::Message& message, const display::SurfaceAttributes& attributes);
+  pdx::Status<display::SurfaceInfo> OnGetSurfaceInfo(pdx::Message& message);
+
+  DisplayService* service_;
+  SurfaceType surface_type_;
+  int surface_id_;
+  int process_id_;
+  int user_id_;
+
+  display::SurfaceAttributes attributes_;
+  display::SurfaceUpdateFlags update_flags_ = display::SurfaceUpdateFlags::None;
+
+  // Subset of attributes that may be interpreted by the display service.
+  bool visible_ = false;
+  int z_order_ = 0;
+
+  DisplaySurface(const DisplaySurface&) = delete;
+  void operator=(const DisplaySurface&) = delete;
+};
+
+class ApplicationDisplaySurface : public DisplaySurface {
+ public:
+  ApplicationDisplaySurface(DisplayService* service, int surface_id,
+                            int process_id, int user_id,
+                            const display::SurfaceAttributes& attributes)
+      : DisplaySurface(service, SurfaceType::Application, surface_id,
+                       process_id, user_id, attributes) {}
+
+  std::shared_ptr<ConsumerQueue> GetQueue(int32_t queue_id);
+  std::vector<int32_t> GetQueueIds() const override;
+
+ private:
+  pdx::Status<pdx::LocalChannelHandle> OnCreateQueue(
+      pdx::Message& message, size_t meta_size_bytes) override;
+  void OnQueueEvent(const std::shared_ptr<ConsumerQueue>& consumer_queue,
+                    int events) override;
+
+  std::unordered_map<int32_t, std::shared_ptr<ConsumerQueue>> consumer_queues_;
+};
+
+class DirectDisplaySurface : public DisplaySurface {
+ public:
+  DirectDisplaySurface(DisplayService* service, int surface_id, int process_id,
+                       int user_id,
+                       const display::SurfaceAttributes& attributes)
+      : DisplaySurface(service, SurfaceType::Direct, surface_id, process_id,
+                       user_id, attributes),
+        acquired_buffers_(kMaxPostedBuffers) {}
   bool IsBufferAvailable();
   bool IsBufferPosted();
   AcquiredBuffer AcquireCurrentBuffer();
@@ -69,31 +153,11 @@ class DisplaySurface : public SurfaceChannel {
   // skipped, it will be stored in skipped_buffer if non null.
   AcquiredBuffer AcquireNewestAvailableBuffer(AcquiredBuffer* skipped_buffer);
 
-  // Display manager interface to control visibility and z order.
-  void ManagerSetVisible(bool visible);
-  void ManagerSetZOrder(int z_order);
-  void ManagerSetBlur(float blur);
-
-  // A surface must be set visible by both the client and the display manager to
-  // be visible on screen.
-  bool IsVisible() const { return client_visible_ && manager_visible_; }
-
-  // A surface is blurred if the display manager requests it.
-  bool IsBlurred() const { return manager_blur_ > 0.0f; }
-
-  // Set by HardwareComposer to the current logical layer order of this surface.
-  void SetLayerOrder(int layer_order) { layer_order_ = layer_order; }
-  // Gets the unique z-order index of this surface among other visible surfaces.
-  // This is not the same as the hardware layer index, as not all display
-  // surfaces map directly to hardware layers. Lower layer orders should be
-  // composited underneath higher layer orders.
-  int layer_order() const { return layer_order_; }
-
-  // Lock all video mesh surfaces so that VideoMeshCompositor can access them.
-  std::vector<std::shared_ptr<VideoMeshSurface>> GetVideoMeshSurfaces();
-
  private:
-  friend class DisplayService;
+  pdx::Status<pdx::LocalChannelHandle> OnCreateQueue(
+      pdx::Message& message, size_t meta_size_bytes) override;
+  void OnQueueEvent(const std::shared_ptr<ConsumerQueue>& consumer_queue,
+                    int events) override;
 
   // The capacity of the pending buffer queue. Should be enough to hold all the
   // buffers of this DisplaySurface, although in practice only 1 or 2 frames
@@ -104,75 +168,14 @@ class DisplaySurface : public SurfaceChannel {
   // Returns whether a frame is available without locking the mutex.
   bool IsFrameAvailableNoLock() const;
 
-  // Dispatches display surface messages to the appropriate handlers. This
-  // handler runs on the displayd message dispatch thread.
-  pdx::Status<void> HandleMessage(pdx::Message& message) override;
-
-  // Sets display surface's client-controlled attributes.
-  int OnClientSetAttributes(pdx::Message& message,
-                            const DisplaySurfaceAttributes& attributes);
-
-  // Creates a BufferHubQueue associated with this surface and returns the PDX
-  // handle of its producer side to the client.
-  pdx::LocalChannelHandle OnCreateBufferQueue(pdx::Message& message);
-
-  // Creates a video mesh surface associated with this surface and returns its
-  // PDX handle to the client.
-  pdx::RemoteChannelHandle OnCreateVideoMeshSurface(pdx::Message& message);
-
-  // Client interface (called through IPC) to set visibility and z order.
-  void ClientSetVisible(bool visible);
-  void ClientSetZOrder(int z_order);
-  void ClientSetExcludeFromBlur(bool exclude_from_blur);
-  void ClientSetBlurBehind(bool blur_behind);
-
   // Dequeue all available buffers from the consumer queue.
   void DequeueBuffersLocked();
 
-  DisplaySurface(const DisplaySurface&) = delete;
-  void operator=(const DisplaySurface&) = delete;
-
-  int process_id_;
-
-  // Synchronizes access to mutable state below between message dispatch thread,
-  // epoll event thread, and frame post thread.
-  mutable std::mutex lock_;
-
-  // The consumer end of a BufferHubQueue. VrFlinger allocates and controls the
-  // buffer queue and pass producer end to the app and the consumer end to
-  // compositor.
-  // TODO(jwcai) Add support for multiple buffer queues per display surface.
-  std::shared_ptr<ConsumerQueue> consumer_queue_;
-
   // In a triple-buffered surface, up to kMaxPostedBuffers buffers may be
   // posted and pending.
   RingBuffer<AcquiredBuffer> acquired_buffers_;
 
-  // Provides access to VideoMeshSurface. Here we don't want to increase
-  // the reference count immediately on allocation, will leave it into
-  // compositor's hand.
-  std::vector<std::weak_ptr<VideoMeshSurface>> pending_video_mesh_surfaces_;
-  volatile bool video_mesh_surfaces_updated_;
-
-  // Surface parameters.
-  int width_;
-  int height_;
-  int format_;
-  int usage_;
-  int flags_;
-  bool client_visible_;
-  int client_z_order_;
-  bool client_exclude_from_blur_;
-  bool client_blur_behind_;
-  bool manager_visible_;
-  int manager_z_order_;
-  float manager_blur_;
-  int layer_order_;
-
-  // The monotonically increasing index for allocated buffers in this surface.
-  uint32_t allocated_buffer_index_;
-  // Maps from the buffer id to the corresponding allocated buffer index.
-  std::unordered_map<int, uint32_t> buffer_id_to_index_;
+  std::shared_ptr<ConsumerQueue> direct_queue_;
 };
 
 }  // namespace dvr
diff --git a/libs/vr/libvrflinger/epoll_event_dispatcher.cpp b/libs/vr/libvrflinger/epoll_event_dispatcher.cpp
new file mode 100644 (file)
index 0000000..06b69bb
--- /dev/null
@@ -0,0 +1,142 @@
+#include "epoll_event_dispatcher.h"
+
+#include <log/log.h>
+#include <sys/epoll.h>
+#include <sys/eventfd.h>
+#include <sys/prctl.h>
+
+#include <dvr/performance_client_api.h>
+
+namespace android {
+namespace dvr {
+
+EpollEventDispatcher::EpollEventDispatcher() {
+  epoll_fd_.Reset(epoll_create(64));
+  if (!epoll_fd_) {
+    ALOGE("Failed to create epoll fd: %s", strerror(errno));
+    return;
+  }
+
+  event_fd_.Reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
+  if (!event_fd_) {
+    ALOGE("Failed to create event for epolling: %s", strerror(errno));
+    return;
+  }
+
+  // Add watch for eventfd. This should only watch for EPOLLIN, which gets set
+  // when eventfd_write occurs. Use "this" as a unique sentinal value to
+  // identify events from the event fd.
+  epoll_event event = {.events = EPOLLIN, .data = {.ptr = this}};
+  if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, event_fd_.Get(), &event) < 0) {
+    ALOGE("Failed to add eventfd to epoll set because: %s", strerror(errno));
+    return;
+  }
+
+  thread_ = std::thread(&EpollEventDispatcher::EventThread, this);
+}
+
+EpollEventDispatcher::~EpollEventDispatcher() { Stop(); }
+
+void EpollEventDispatcher::Stop() {
+  exit_thread_.store(true);
+  eventfd_write(event_fd_.Get(), 1);
+}
+
+pdx::Status<void> EpollEventDispatcher::AddEventHandler(int fd, int event_mask,
+                                                        Handler handler) {
+  std::lock_guard<std::mutex> lock(lock_);
+
+  epoll_event event;
+  event.events = event_mask;
+  event.data.ptr = &(handlers_[fd] = handler);
+
+  ALOGD_IF(
+      TRACE,
+      "EpollEventDispatcher::AddEventHandler: fd=%d event_mask=0x%x handler=%p",
+      fd, event_mask, event.data.ptr);
+
+  if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, fd, &event) < 0) {
+    const int error = errno;
+    ALOGE("Failed to add fd to epoll set because: %s", strerror(error));
+    return pdx::ErrorStatus(error);
+  } else {
+    return {};
+  }
+}
+
+pdx::Status<void> EpollEventDispatcher::RemoveEventHandler(int fd) {
+  ALOGD_IF(TRACE, "EpollEventDispatcher::RemoveEventHandler: fd=%d", fd);
+  std::lock_guard<std::mutex> lock(lock_);
+
+  epoll_event dummy;  // See BUGS in man 2 epoll_ctl.
+  if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_DEL, fd, &dummy) < 0) {
+    const int error = errno;
+    ALOGE("Failed to remove fd from epoll set because: %s", strerror(error));
+    return pdx::ErrorStatus(error);
+  }
+
+  // If the fd was valid above, add it to the list of ids to remove.
+  removed_handlers_.push_back(fd);
+
+  // Wake up the event thread to clean up.
+  eventfd_write(event_fd_.Get(), 1);
+
+  return {};
+}
+
+void EpollEventDispatcher::EventThread() {
+  prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("VrEvent"), 0, 0, 0);
+
+  const int error = dvrSetSchedulerClass(0, "graphics");
+  LOG_ALWAYS_FATAL_IF(
+      error < 0,
+      "EpollEventDispatcher::EventThread: Failed to set scheduler class: %s",
+      strerror(-error));
+
+  const size_t kMaxNumEvents = 128;
+  epoll_event events[kMaxNumEvents];
+
+  while (!exit_thread_.load()) {
+    const int num_events = epoll_wait(epoll_fd_.Get(), events, kMaxNumEvents, -1);
+    if (num_events < 0 && errno != EINTR)
+      break;
+
+    ALOGD_IF(TRACE, "EpollEventDispatcher::EventThread: num_events=%d",
+             num_events);
+
+    for (int i = 0; i < num_events; i++) {
+      ALOGD_IF(
+          TRACE,
+          "EpollEventDispatcher::EventThread: event %d: handler=%p events=0x%x",
+          i, events[i].data.ptr, events[i].events);
+
+      if (events[i].data.ptr == this) {
+        // Clear pending event on event_fd_. Serialize the read with respect to
+        // writes from other threads.
+        std::lock_guard<std::mutex> lock(lock_);
+        eventfd_t value;
+        eventfd_read(event_fd_.Get(), &value);
+      } else {
+        auto handler = reinterpret_cast<Handler*>(events[i].data.ptr);
+        if (handler)
+          (*handler)(events[i].events);
+      }
+    }
+
+    // Remove any handlers that have been posted for removal. This is done here
+    // instead of in RemoveEventHandler() to prevent races between the dispatch
+    // thread and the code requesting the removal. Handlers are guaranteed to
+    // stay alive between exiting epoll_wait() and the dispatch loop above.
+    std::lock_guard<std::mutex> lock(lock_);
+    for (auto handler_fd : removed_handlers_) {
+      ALOGD_IF(TRACE,
+               "EpollEventDispatcher::EventThread: removing handler: fd=%d",
+               handler_fd);
+      handlers_.erase(handler_fd);
+    }
+    removed_handlers_.clear();
+  }
+}
+
+}  // namespace dvr
+}  // namespace android
diff --git a/libs/vr/libvrflinger/epoll_event_dispatcher.h b/libs/vr/libvrflinger/epoll_event_dispatcher.h
new file mode 100644 (file)
index 0000000..eb687f4
--- /dev/null
@@ -0,0 +1,63 @@
+#ifndef ANDROID_DVR_SERVICES_DISPLAYD_EPOLL_EVENT_DISPATCHER_H_
+#define ANDROID_DVR_SERVICES_DISPLAYD_EPOLL_EVENT_DISPATCHER_H_
+
+#include <sys/epoll.h>
+
+#include <atomic>
+#include <functional>
+#include <mutex>
+#include <thread>
+#include <unordered_map>
+#include <vector>
+
+#include <pdx/file_handle.h>
+#include <pdx/status.h>
+
+namespace android {
+namespace dvr {
+
+class EpollEventDispatcher {
+ public:
+  // Function type for event handlers. The handler receives a bitmask of the
+  // epoll events that occurred on the file descriptor associated with the
+  // handler.
+  using Handler = std::function<void(int)>;
+
+  EpollEventDispatcher();
+  ~EpollEventDispatcher();
+
+  // |handler| is called on the internal dispatch thread when |fd| is signaled
+  // by events in |event_mask|.
+  pdx::Status<void> AddEventHandler(int fd, int event_mask, Handler handler);
+  pdx::Status<void> RemoveEventHandler(int fd);
+
+  void Stop();
+
+ private:
+  void EventThread();
+
+  std::thread thread_;
+  std::atomic<bool> exit_thread_{false};
+
+  // Protects handlers_ and removed_handlers_ and serializes operations on
+  // epoll_fd_ and event_fd_.
+  std::mutex lock_;
+
+  // Maintains a map of fds to event handlers. This is primarily to keep any
+  // references alive that may be bound in the std::function instances. It is
+  // not used at dispatch time to avoid performance problems with different
+  // versions of std::unordered_map.
+  std::unordered_map<int, Handler> handlers_;
+
+  // List of fds to be removed from the map. The actual removal is performed
+  // by the event dispatch thread to avoid races.
+  std::vector<int> removed_handlers_;
+
+  pdx::LocalHandle epoll_fd_;
+  pdx::LocalHandle event_fd_;
+};
+
+}  // namespace dvr
+}  // namespace android
+
+#endif  // ANDROID_DVR_SERVICES_DISPLAYD_EPOLL_EVENT_DISPATCHER_H_
index bac9872..079d6fd 100644 (file)
@@ -1,9 +1,9 @@
 #include "hardware_composer.h"
 
-#include <log/log.h>
 #include <cutils/properties.h>
 #include <cutils/sched_policy.h>
 #include <fcntl.h>
+#include <log/log.h>
 #include <poll.h>
 #include <sync/sync.h>
 #include <sys/eventfd.h>
 #include <sys/resource.h>
 #include <sys/system_properties.h>
 #include <sys/timerfd.h>
+#include <time.h>
 #include <unistd.h>
 #include <utils/Trace.h>
 
 #include <algorithm>
+#include <chrono>
 #include <functional>
 #include <map>
 
+#include <dvr/dvr_display_types.h>
 #include <dvr/performance_client_api.h>
 #include <private/dvr/clock_ns.h>
-#include <private/dvr/display_types.h>
+#include <private/dvr/ion_buffer.h>
 #include <private/dvr/pose_client_internal.h>
 #include <private/dvr/sync_util.h>
 
-#include "debug_hud_data.h"
-#include "screenshot_service.h"
-
 using android::pdx::LocalHandle;
+using android::pdx::rpc::EmptyVariant;
+using android::pdx::rpc::IfAnyOf;
+
+using namespace std::chrono_literals;
 
 namespace android {
 namespace dvr {
@@ -42,13 +46,8 @@ namespace {
 // display and the EDS timing coincides with zero pending fences, so this is 0.
 constexpr int kAllowedPendingFenceCount = 0;
 
-// If we think we're going to miss vsync by more than this amount, skip the
-// frame.
-constexpr int64_t kFrameSkipThresholdNs = 4000000;  // 4ms
-
-// Counter PostLayers() deficiency by requiring apps to produce a frame at least
-// 2.5ms before vsync. See b/28881672.
-constexpr int64_t kFrameTimeEstimateMin = 2500000;  // 2.5ms
+// Offset before vsync to submit frames to hardware composer.
+constexpr int64_t kFramePostOffsetNs = 4000000;  // 4ms
 
 constexpr size_t kDefaultDisplayConfigCount = 32;
 
@@ -93,44 +92,52 @@ inline int64_t GetPosePredictionTimeOffset(int64_t vsync_period_ns) {
   return (vsync_period_ns * 150) / 100;
 }
 
+// Attempts to set the scheduler class and partiton for the current thread.
+// Returns true on success or false on failure.
+bool SetThreadPolicy(const std::string& scheduler_class,
+                     const std::string& partition) {
+  int error = dvrSetSchedulerClass(0, scheduler_class.c_str());
+  if (error < 0) {
+    ALOGE(
+        "SetThreadPolicy: Failed to set scheduler class \"%s\" for "
+        "thread_id=%d: %s",
+        scheduler_class.c_str(), gettid(), strerror(-error));
+    return false;
+  }
+  error = dvrSetCpuPartition(0, partition.c_str());
+  if (error < 0) {
+    ALOGE(
+        "SetThreadPolicy: Failed to set cpu partiton \"%s\" for thread_id=%d: "
+        "%s",
+        partition.c_str(), gettid(), strerror(-error));
+    return false;
+  }
+  return true;
+}
+
 }  // anonymous namespace
 
+// Layer static data.
+Hwc2::Composer* Layer::hwc2_hidl_;
+const HWCDisplayMetrics* Layer::display_metrics_;
+
+// HardwareComposer static data;
+constexpr size_t HardwareComposer::kMaxHardwareLayers;
+
 HardwareComposer::HardwareComposer()
-  : HardwareComposer(nullptr) {
-}
+    : HardwareComposer(nullptr, RequestDisplayCallback()) {}
 
-HardwareComposer::HardwareComposer(Hwc2::Composer* hwc2_hidl)
+HardwareComposer::HardwareComposer(
+    Hwc2::Composer* hwc2_hidl, RequestDisplayCallback request_display_callback)
     : initialized_(false),
       hwc2_hidl_(hwc2_hidl),
-      display_transform_(HWC_TRANSFORM_NONE),
-      active_surfaces_updated_(false),
-      active_layer_count_(0),
-      gpu_layer_(nullptr),
-      post_thread_enabled_(false),
-      post_thread_running_(false),
-      post_thread_quit_requested_(false),
-      post_thread_interrupt_event_fd_(-1),
-      backlight_brightness_fd_(-1),
-      primary_display_vsync_event_fd_(-1),
-      primary_display_wait_pp_fd_(-1),
-      vsync_sleep_timer_fd_(-1),
-      last_vsync_timestamp_(0),
-      vsync_count_(0),
-      frame_skip_count_(0),
-      pose_client_(nullptr) {
-  std::transform(layer_storage_.begin(), layer_storage_.end(), layers_.begin(),
-                 [](auto& layer) { return &layer; });
-
-  callbacks_ = new ComposerCallback;
-}
+      request_display_callback_(request_display_callback),
+      callbacks_(new ComposerCallback) {}
 
 HardwareComposer::~HardwareComposer(void) {
-  std::unique_lock<std::mutex> lock(post_thread_mutex_);
-  if (post_thread_.joinable()) {
-    post_thread_quit_requested_ = true;
-    post_thread_cond_var_.notify_all();
+  UpdatePostThreadState(PostThreadState::Quit, true);
+  if (post_thread_.joinable())
     post_thread_.join();
-  }
 }
 
 bool HardwareComposer::Initialize() {
@@ -139,25 +146,25 @@ bool HardwareComposer::Initialize() {
     return false;
   }
 
-  int32_t ret = HWC2_ERROR_NONE;
+  HWC::Error error = HWC::Error::None;
 
   Hwc2::Config config;
-  ret = (int32_t)hwc2_hidl_->getActiveConfig(HWC_DISPLAY_PRIMARY, &config);
+  error = hwc2_hidl_->getActiveConfig(HWC_DISPLAY_PRIMARY, &config);
 
-  if (ret != HWC2_ERROR_NONE) {
+  if (error != HWC::Error::None) {
     ALOGE("HardwareComposer: Failed to get current display config : %d",
           config);
     return false;
   }
 
-  ret =
+  error =
       GetDisplayMetrics(HWC_DISPLAY_PRIMARY, config, &native_display_metrics_);
 
-  if (ret != HWC2_ERROR_NONE) {
+  if (error != HWC::Error::None) {
     ALOGE(
         "HardwareComposer: Failed to get display attributes for current "
         "configuration : %d",
-        ret);
+        error.value);
     return false;
   }
 
@@ -173,10 +180,12 @@ bool HardwareComposer::Initialize() {
   display_transform_ = HWC_TRANSFORM_NONE;
   display_metrics_ = native_display_metrics_;
 
-  post_thread_interrupt_event_fd_.Reset(
-      eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
+  // Pass hwc instance and metrics to setup globals for Layer.
+  Layer::InitializeGlobals(hwc2_hidl_, &native_display_metrics_);
+
+  post_thread_event_fd_.Reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
   LOG_ALWAYS_FATAL_IF(
-      !post_thread_interrupt_event_fd_,
+      !post_thread_event_fd_,
       "HardwareComposer: Failed to create interrupt event fd : %s",
       strerror(errno));
 
@@ -188,38 +197,47 @@ bool HardwareComposer::Initialize() {
 }
 
 void HardwareComposer::Enable() {
-  std::lock_guard<std::mutex> lock(post_thread_mutex_);
-  post_thread_enabled_ = true;
-  post_thread_cond_var_.notify_all();
+  UpdatePostThreadState(PostThreadState::Suspended, false);
 }
 
 void HardwareComposer::Disable() {
+  UpdatePostThreadState(PostThreadState::Suspended, true);
+}
+
+// Update the post thread quiescent state based on idle and suspended inputs.
+void HardwareComposer::UpdatePostThreadState(PostThreadStateType state,
+                                             bool suspend) {
   std::unique_lock<std::mutex> lock(post_thread_mutex_);
-  post_thread_enabled_ = false;
-  if (post_thread_running_) {
-    // Write to the interrupt fd to get fast interrupt of the post thread
-    int error = eventfd_write(post_thread_interrupt_event_fd_.Get(), 1);
-    ALOGW_IF(error,
-             "HardwareComposer::Disable: could not write post "
-             "thread interrupt event fd : %s",
-             strerror(errno));
-
-    post_thread_cond_var_.wait(lock, [this] { return !post_thread_running_; });
-
-    // Read the interrupt fd to clear its state
-    uint64_t interrupt_count= 0;
-    error = eventfd_read(post_thread_interrupt_event_fd_.Get(),
-                         &interrupt_count);
-    ALOGW_IF(error,
-             "HardwareComposer::Disable: could not read post "
-             "thread interrupt event fd : %s",
-             strerror(errno));
+
+  // Update the votes in the state variable before evaluating the effective
+  // quiescent state. Any bits set in post_thread_state_ indicate that the post
+  // thread should be suspended.
+  if (suspend) {
+    post_thread_state_ |= state;
+  } else {
+    post_thread_state_ &= ~state;
+  }
+
+  const bool quit = post_thread_state_ & PostThreadState::Quit;
+  const bool effective_suspend = post_thread_state_ != PostThreadState::Active;
+  if (quit) {
+    post_thread_quiescent_ = true;
+    eventfd_write(post_thread_event_fd_.Get(), 1);
+    post_thread_wait_.notify_one();
+  } else if (effective_suspend && !post_thread_quiescent_) {
+    post_thread_quiescent_ = true;
+    eventfd_write(post_thread_event_fd_.Get(), 1);
+  } else if (!effective_suspend && post_thread_quiescent_) {
+    post_thread_quiescent_ = false;
+    eventfd_t value;
+    eventfd_read(post_thread_event_fd_.Get(), &value);
+    post_thread_wait_.notify_one();
   }
-}
 
-bool HardwareComposer::PostThreadHasWork() {
-  return !display_surfaces_.empty() ||
-      (active_surfaces_updated_ && !active_surfaces_.empty());
+  // Wait until the post thread is in the requested state.
+  post_thread_ready_.wait(lock, [this, effective_suspend] {
+    return effective_suspend != post_thread_resumed_;
+  });
 }
 
 void HardwareComposer::OnPostThreadResumed() {
@@ -233,16 +251,17 @@ void HardwareComposer::OnPostThreadResumed() {
 
   hwc2_hidl_->resetCommands();
 
-  // Associate each Layer instance with a hardware composer layer.
-  for (auto layer : layers_) {
-    layer->Initialize(hwc2_hidl_.get(), &native_display_metrics_);
-  }
-
   // Connect to pose service.
   pose_client_ = dvrPoseCreate();
   ALOGE_IF(!pose_client_, "HardwareComposer: Failed to create pose client");
 
+  // HIDL HWC seems to have an internal race condition. If we submit a frame too
+  // soon after turning on VSync we don't get any VSync signals. Give poor HWC
+  // implementations a chance to enable VSync before we continue.
+  EnableVsync(false);
+  std::this_thread::sleep_for(100ms);
   EnableVsync(true);
+  std::this_thread::sleep_for(100ms);
 
   // TODO(skiazyk): We need to do something about accessing this directly,
   // supposedly there is a backlight service on the way.
@@ -251,34 +270,20 @@ void HardwareComposer::OnPostThreadResumed() {
   // control of the display back to surface flinger?
   SetBacklightBrightness(255);
 
-  // Initialize the GPU compositor.
-  LOG_ALWAYS_FATAL_IF(!compositor_.Initialize(GetHmdDisplayMetrics()),
-                      "Failed to initialize the compositor");
-
   // Trigger target-specific performance mode change.
   property_set(kDvrPerformanceProperty, "performance");
 }
 
 void HardwareComposer::OnPostThreadPaused() {
+  framebuffer_target_.reset();
   retire_fence_fds_.clear();
-  gpu_layer_ = nullptr;
+  display_surfaces_.clear();
 
-  // We have to destroy the layers to fully clear hwc device state before
-  // handing off back to surface flinger
   for (size_t i = 0; i < kMaxHardwareLayers; ++i) {
-    layers_[i]->Reset();
+    layers_[i].Reset();
   }
-
   active_layer_count_ = 0;
 
-  framebuffer_target_.reset();
-
-  display_surfaces_.clear();
-  compositor_surfaces_.clear();
-
-  // Since we're clearing display_surfaces_ we'll need an update.
-  active_surfaces_updated_ = true;
-
   if (pose_client_) {
     dvrPoseDestroy(pose_client_);
     pose_client_ = nullptr;
@@ -286,50 +291,24 @@ void HardwareComposer::OnPostThreadPaused() {
 
   EnableVsync(false);
 
-  frame_time_history_.ResetWithSeed(GuessFrameTime(0));
-  frame_time_backlog_.clear();
-
-  compositor_.Shutdown();
-
   hwc2_hidl_->resetCommands();
 
   // Trigger target-specific performance mode change.
   property_set(kDvrPerformanceProperty, "idle");
 }
 
-DisplayMetrics HardwareComposer::GetHmdDisplayMetrics() const {
-  vec2i screen_size(display_metrics_.width, display_metrics_.height);
-  DisplayOrientation orientation =
-      (display_metrics_.width > display_metrics_.height
-           ? DisplayOrientation::kLandscape
-           : DisplayOrientation::kPortrait);
-  float dpi_x = static_cast<float>(display_metrics_.dpi.x) / 1000.0f;
-  float dpi_y = static_cast<float>(display_metrics_.dpi.y) / 1000.0f;
-  float meters_per_pixel_x = kMetersPerInch / dpi_x;
-  float meters_per_pixel_y = kMetersPerInch / dpi_y;
-  vec2 meters_per_pixel(meters_per_pixel_x, meters_per_pixel_y);
-  double frame_duration_s =
-      static_cast<double>(display_metrics_.vsync_period_ns) / 1000000000.0;
-  // TODO(hendrikw): Hard coding to 3mm.  The Pixel is actually 4mm, but it
-  //                 seems that their tray to lens distance is wrong too, which
-  //                 offsets this, at least for the pixel.
-  float border_size = 0.003f;
-  return DisplayMetrics(screen_size, meters_per_pixel, border_size,
-                        static_cast<float>(frame_duration_s), orientation);
-}
-
-int32_t HardwareComposer::Validate(hwc2_display_t display) {
+HWC::Error HardwareComposer::Validate(hwc2_display_t display) {
   uint32_t num_types;
   uint32_t num_requests;
-  int32_t error =
-      (int32_t)hwc2_hidl_->validateDisplay(display, &num_types, &num_requests);
+  HWC::Error error =
+      hwc2_hidl_->validateDisplay(display, &num_types, &num_requests);
 
   if (error == HWC2_ERROR_HAS_CHANGES) {
     // TODO(skiazyk): We might need to inspect the requested changes first, but
     // so far it seems like we shouldn't ever hit a bad state.
     // error = hwc2_funcs_.accept_display_changes_fn_(hardware_composer_device_,
     //                                               display);
-    error = (int32_t)hwc2_hidl_->acceptDisplayChanges(display);
+    error = hwc2_hidl_->acceptDisplayChanges(display);
   }
 
   return error;
@@ -342,13 +321,13 @@ int32_t HardwareComposer::EnableVsync(bool enabled) {
                                              : HWC2_VSYNC_DISABLE));
 }
 
-int32_t HardwareComposer::Present(hwc2_display_t display) {
+HWC::Error HardwareComposer::Present(hwc2_display_t display) {
   int32_t present_fence;
-  int32_t error = (int32_t)hwc2_hidl_->presentDisplay(display, &present_fence);
+  HWC::Error error = hwc2_hidl_->presentDisplay(display, &present_fence);
 
   // According to the documentation, this fence is signaled at the time of
   // vsync/DMA for physical displays.
-  if (error == HWC2_ERROR_NONE) {
+  if (error == HWC::Error::None) {
     ATRACE_INT("HardwareComposer: VsyncFence", present_fence);
     retire_fence_fds_.emplace_back(present_fence);
   } else {
@@ -358,82 +337,81 @@ int32_t HardwareComposer::Present(hwc2_display_t display) {
   return error;
 }
 
-int32_t HardwareComposer::GetDisplayAttribute(hwc2_display_t display,
-                                              hwc2_config_t config,
-                                              hwc2_attribute_t attribute,
-                                              int32_t* out_value) const {
-  return (int32_t)hwc2_hidl_->getDisplayAttribute(
+HWC::Error HardwareComposer::GetDisplayAttribute(hwc2_display_t display,
+                                                 hwc2_config_t config,
+                                                 hwc2_attribute_t attribute,
+                                                 int32_t* out_value) const {
+  return hwc2_hidl_->getDisplayAttribute(
       display, config, (Hwc2::IComposerClient::Attribute)attribute, out_value);
 }
 
-int32_t HardwareComposer::GetDisplayMetrics(
+HWC::Error HardwareComposer::GetDisplayMetrics(
     hwc2_display_t display, hwc2_config_t config,
     HWCDisplayMetrics* out_metrics) const {
-  int32_t ret = HWC2_ERROR_NONE;
+  HWC::Error error;
 
-  ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_WIDTH,
-                            &out_metrics->width);
-  if (ret != HWC2_ERROR_NONE) {
-    ALOGE("HardwareComposer: Failed to get display width");
-    return ret;
+  error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_WIDTH,
+                              &out_metrics->width);
+  if (error != HWC::Error::None) {
+    ALOGE(
+        "HardwareComposer::GetDisplayMetrics: Failed to get display width: %s",
+        error.to_string().c_str());
+    return error;
   }
 
-  ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_HEIGHT,
-                            &out_metrics->height);
-  if (ret != HWC2_ERROR_NONE) {
-    ALOGE("HardwareComposer: Failed to get display height");
-    return ret;
+  error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_HEIGHT,
+                              &out_metrics->height);
+  if (error != HWC::Error::None) {
+    ALOGE(
+        "HardwareComposer::GetDisplayMetrics: Failed to get display height: %s",
+        error.to_string().c_str());
+    return error;
   }
 
-  ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_VSYNC_PERIOD,
-                            &out_metrics->vsync_period_ns);
-  if (ret != HWC2_ERROR_NONE) {
-    ALOGE("HardwareComposer: Failed to get display height");
-    return ret;
+  error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_VSYNC_PERIOD,
+                              &out_metrics->vsync_period_ns);
+  if (error != HWC::Error::None) {
+    ALOGE(
+        "HardwareComposer::GetDisplayMetrics: Failed to get display height: %s",
+        error.to_string().c_str());
+    return error;
   }
 
-  ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_X,
-                            &out_metrics->dpi.x);
-  if (ret != HWC2_ERROR_NONE) {
-    ALOGE("HardwareComposer: Failed to get display DPI X");
-    return ret;
+  error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_X,
+                              &out_metrics->dpi.x);
+  if (error != HWC::Error::None) {
+    ALOGE(
+        "HardwareComposer::GetDisplayMetrics: Failed to get display DPI X: %s",
+        error.to_string().c_str());
+    return error;
   }
 
-  ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_Y,
-                            &out_metrics->dpi.y);
-  if (ret != HWC2_ERROR_NONE) {
-    ALOGE("HardwareComposer: Failed to get display DPI Y");
-    return ret;
+  error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_Y,
+                              &out_metrics->dpi.y);
+  if (error != HWC::Error::None) {
+    ALOGE(
+        "HardwareComposer::GetDisplayMetrics: Failed to get display DPI Y: %s",
+        error.to_string().c_str());
+    return error;
   }
 
-  return HWC2_ERROR_NONE;
+  return HWC::Error::None;
 }
 
-void HardwareComposer::Dump(char* buffer, uint32_t* out_size) {
-  std::string debug_str = hwc2_hidl_->dumpDebugInfo();
-  ALOGI("%s", debug_str.c_str());
-
-  if (buffer == nullptr) {
-    *out_size = debug_str.size();
-  } else {
-    std::copy(debug_str.begin(), debug_str.begin() + *out_size, buffer);
-  }
-}
+std::string HardwareComposer::Dump() { return hwc2_hidl_->dumpDebugInfo(); }
 
-// TODO(skiazyk): Figure out what to do with `is_geometry_changed`. There does
-// not seem to be any equivalent in the HWC2 API, but that doesn't mean its not
-// there.
-void HardwareComposer::PostLayers(bool /*is_geometry_changed*/) {
+void HardwareComposer::PostLayers() {
   ATRACE_NAME("HardwareComposer::PostLayers");
 
   // Setup the hardware composer layers with current buffers.
   for (size_t i = 0; i < active_layer_count_; i++) {
-    layers_[i]->Prepare();
+    layers_[i].Prepare();
   }
 
-  int32_t ret = Validate(HWC_DISPLAY_PRIMARY);
-  if (ret) {
-    ALOGE("HardwareComposer::Validate failed; ret=%d", ret);
+  HWC::Error error = Validate(HWC_DISPLAY_PRIMARY);
+  if (error != HWC::Error::None) {
+    ALOGE("HardwareComposer::PostLayers: Validate failed: %s",
+          error.to_string().c_str());
     return;
   }
 
@@ -462,7 +440,7 @@ void HardwareComposer::PostLayers(bool /*is_geometry_changed*/) {
              retire_fence_fds_.size());
 
     for (size_t i = 0; i < active_layer_count_; i++) {
-      layers_[i]->Drop();
+      layers_[i].Drop();
     }
     return;
   } else {
@@ -473,55 +451,71 @@ void HardwareComposer::PostLayers(bool /*is_geometry_changed*/) {
 
 #if TRACE
   for (size_t i = 0; i < active_layer_count_; i++)
-    ALOGI("HardwareComposer::PostLayers: dl[%zu] ctype=0x%08x", i,
-          layers_[i]->GetCompositionType());
+    ALOGI("HardwareComposer::PostLayers: layer=%zu composition=%s", i,
+          layers_[i].GetCompositionType().to_string().c_str());
 #endif
 
-  ret = Present(HWC_DISPLAY_PRIMARY);
-  if (ret) {
-    ALOGE("HardwareComposer::Present failed; ret=%d", ret);
+  error = Present(HWC_DISPLAY_PRIMARY);
+  if (error != HWC::Error::None) {
+    ALOGE("HardwareComposer::PostLayers: Present failed: %s",
+          error.to_string().c_str());
     return;
   }
 
   std::vector<Hwc2::Layer> out_layers;
   std::vector<int> out_fences;
-  ret = (int32_t)hwc2_hidl_->getReleaseFences(HWC_DISPLAY_PRIMARY, &out_layers,
-                                              &out_fences);
-  uint32_t num_elements = out_layers.size();
-
-  ALOGE_IF(ret, "HardwareComposer: GetReleaseFences failed; ret=%d", ret);
+  error = hwc2_hidl_->getReleaseFences(HWC_DISPLAY_PRIMARY, &out_layers,
+                                       &out_fences);
+  ALOGE_IF(error != HWC::Error::None,
+           "HardwareComposer::PostLayers: Failed to get release fences: %s",
+           error.to_string().c_str());
 
   // Perform post-frame bookkeeping. Unused layers are a no-op.
+  uint32_t num_elements = out_layers.size();
   for (size_t i = 0; i < num_elements; ++i) {
     for (size_t j = 0; j < active_layer_count_; ++j) {
-      if (layers_[j]->GetLayerHandle() == out_layers[i]) {
-        layers_[j]->Finish(out_fences[i]);
+      if (layers_[j].GetLayerHandle() == out_layers[i]) {
+        layers_[j].Finish(out_fences[i]);
       }
     }
   }
 }
 
 void HardwareComposer::SetDisplaySurfaces(
-    std::vector<std::shared_ptr<DisplaySurface>> surfaces) {
+    std::vector<std::shared_ptr<DirectDisplaySurface>> surfaces) {
   ALOGI("HardwareComposer::SetDisplaySurfaces: surface count=%zd",
         surfaces.size());
-  std::unique_lock<std::mutex> lock(post_thread_mutex_);
-  active_surfaces_ = std::move(surfaces);
-  active_surfaces_updated_ = true;
-  if (post_thread_enabled_)
-    post_thread_cond_var_.notify_all();
+  const bool display_idle = surfaces.size() == 0;
+  {
+    std::unique_lock<std::mutex> lock(post_thread_mutex_);
+    pending_surfaces_ = std::move(surfaces);
+  }
+
+  // Set idle state based on whether there are any surfaces to handle.
+  UpdatePostThreadState(PostThreadState::Idle, display_idle);
+
+  // XXX: TEMPORARY
+  // Request control of the display based on whether there are any surfaces to
+  // handle. This callback sets the post thread active state once the transition
+  // is complete in SurfaceFlinger.
+  // TODO(eieio): Unify the control signal used to move SurfaceFlinger into VR
+  // mode. Currently this is hooked up to persistent VR mode, but perhaps this
+  // makes more sense to control it from VrCore, which could in turn base its
+  // decision on persistent VR mode.
+  if (request_display_callback_)
+    request_display_callback_(!display_idle);
 }
 
-int HardwareComposer::PostThreadPollInterruptible(int event_fd,
-                                                  int requested_events) {
+int HardwareComposer::PostThreadPollInterruptible(
+    const pdx::LocalHandle& event_fd, int requested_events) {
   pollfd pfd[2] = {
       {
-          .fd = event_fd,
+          .fd = event_fd.Get(),
           .events = static_cast<short>(requested_events),
           .revents = 0,
       },
       {
-          .fd = post_thread_interrupt_event_fd_.Get(),
+          .fd = post_thread_event_fd_.Get(),
           .events = POLLPRI | POLLIN,
           .revents = 0,
       },
@@ -642,9 +636,8 @@ int HardwareComposer::ReadVSyncTimestamp(int64_t* timestamp) {
 // TODO(eieio): This is pretty driver specific, this should be moved to a
 // separate class eventually.
 int HardwareComposer::BlockUntilVSync() {
-  return PostThreadPollInterruptible(primary_display_vsync_event_fd_.Get(),
-                                     // There will be a POLLPRI event on vsync
-                                     POLLPRI);
+  // Vsync is signaled by POLLPRI on the fb vsync node.
+  return PostThreadPollInterruptible(primary_display_vsync_event_fd_, POLLPRI);
 }
 
 // Waits for the next vsync and returns the timestamp of the vsync event. If
@@ -683,7 +676,7 @@ int HardwareComposer::WaitForVSync(int64_t* timestamp) {
     // See how close we are to the next expected vsync. If we're within 1ms,
     // sleep for 1ms and try again.
     const int64_t ns_per_frame = display_metrics_.vsync_period_ns;
-    const int64_t threshold_ns = 1000000;
+    const int64_t threshold_ns = 1000000;  // 1ms
 
     const int64_t next_vsync_est = last_vsync_timestamp_ + ns_per_frame;
     const int64_t distance_to_vsync_est = next_vsync_est - GetSystemClockNs();
@@ -695,7 +688,7 @@ int HardwareComposer::WaitForVSync(int64_t* timestamp) {
         return error;
     } else {
       // Sleep for a short time (1 millisecond) before retrying.
-      error = SleepUntil(GetSystemClockNs() + 1000000);
+      error = SleepUntil(GetSystemClockNs() + threshold_ns);
       if (error < 0 || error == kPostThreadInterrupted)
         return error;
     }
@@ -717,24 +710,18 @@ int HardwareComposer::SleepUntil(int64_t wakeup_timestamp) {
     return -error;
   }
 
-  return PostThreadPollInterruptible(timer_fd, POLLIN);
+  return PostThreadPollInterruptible(vsync_sleep_timer_fd_, POLLIN);
 }
 
 void HardwareComposer::PostThread() {
   // NOLINTNEXTLINE(runtime/int)
   prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("VrHwcPost"), 0, 0, 0);
 
-  // Set the scheduler to SCHED_FIFO with high priority.
-  int error = dvrSetSchedulerClass(0, "graphics:high");
-  LOG_ALWAYS_FATAL_IF(
-      error < 0,
-      "HardwareComposer::PostThread: Failed to set scheduler class: %s",
-      strerror(-error));
-  error = dvrSetCpuPartition(0, "/system/performance");
-  LOG_ALWAYS_FATAL_IF(
-      error < 0,
-      "HardwareComposer::PostThread: Failed to set cpu partition: %s",
-      strerror(-error));
+  // Set the scheduler to SCHED_FIFO with high priority. If this fails here
+  // there may have been a startup timing issue between this thread and
+  // performanced. Try again later when this thread becomes active.
+  bool thread_policy_setup =
+      SetThreadPolicy("graphics:high", "/system/performance");
 
 #if ENABLE_BACKLIGHT_BRIGHTNESS
   // TODO(hendrikw): This isn't required at the moment. It's possible that there
@@ -744,7 +731,7 @@ void HardwareComposer::PostThread() {
   ALOGW_IF(!backlight_brightness_fd_,
            "HardwareComposer: Failed to open backlight brightness control: %s",
            strerror(errno));
-#endif // ENABLE_BACKLIGHT_BRIGHTNESS
+#endif  // ENABLE_BACKLIGHT_BRIGHTNESS
 
   // Open the vsync event node for the primary display.
   // TODO(eieio): Move this into a platform-specific class.
@@ -783,11 +770,6 @@ void HardwareComposer::PostThread() {
   right_eye_photon_offset_ns =
       property_get_int64(kRightEyeOffsetProperty, right_eye_photon_offset_ns);
 
-  compositor_surfaces_.reserve(2);
-
-  constexpr int kFrameTimeBacklogMax = 2;
-  frame_time_backlog_.reserve(kFrameTimeBacklogMax);
-
   // Storage for retrieving fence info.
   FenceInfoBuffer fence_info_buffer;
 
@@ -796,35 +778,42 @@ void HardwareComposer::PostThread() {
   while (1) {
     ATRACE_NAME("HardwareComposer::PostThread");
 
-    {
+    while (post_thread_quiescent_) {
       std::unique_lock<std::mutex> lock(post_thread_mutex_);
-      while (!post_thread_enabled_ || post_thread_quit_requested_ ||
-             !PostThreadHasWork()) {
-        if (was_running) {
-          const char* pause_reason = "unknown";
-          if (!post_thread_enabled_)
-            pause_reason = "disabled";
-          else if (post_thread_quit_requested_)
-            pause_reason = "quit requested";
-          else if (!PostThreadHasWork())
-            pause_reason = "no work";
-          ALOGI("VrHwcPost thread paused. Reason: %s.", pause_reason);
-          OnPostThreadPaused();
-          was_running = false;
-        }
-        post_thread_running_ = false;
-        post_thread_cond_var_.notify_all();
-        if (post_thread_quit_requested_)
-          return;
-        post_thread_cond_var_.wait(lock);
+      ALOGI("HardwareComposer::PostThread: Entering quiescent state.");
+
+      // Tear down resources.
+      OnPostThreadPaused();
+
+      was_running = false;
+      post_thread_resumed_ = false;
+      post_thread_ready_.notify_all();
+
+      if (post_thread_state_ & PostThreadState::Quit) {
+        ALOGI("HardwareComposer::PostThread: Quitting.");
+        return;
       }
-      post_thread_running_ = true;
+
+      post_thread_wait_.wait(lock, [this] { return !post_thread_quiescent_; });
+
+      post_thread_resumed_ = true;
+      post_thread_ready_.notify_all();
+
+      ALOGI("HardwareComposer::PostThread: Exiting quiescent state.");
     }
 
     if (!was_running) {
-      ALOGI("VrHwcPost thread resumed");
+      // Setup resources.
       OnPostThreadResumed();
       was_running = true;
+
+      // Try to setup the scheduler policy if it failed during startup. Only
+      // attempt to do this on transitions from inactive to active to avoid
+      // spamming the system with RPCs and log messages.
+      if (!thread_policy_setup) {
+        thread_policy_setup =
+            SetThreadPolicy("graphics:high", "/system/performance");
+      }
     }
 
     int64_t vsync_timestamp = 0;
@@ -834,7 +823,7 @@ void HardwareComposer::PostThread() {
                vsync_count_ + 1);
       ATRACE_NAME(buf.data());
 
-      error = WaitForVSync(&vsync_timestamp);
+      const int error = WaitForVSync(&vsync_timestamp);
       ALOGE_IF(
           error < 0,
           "HardwareComposer::PostThread: Failed to wait for vsync event: %s",
@@ -854,74 +843,27 @@ void HardwareComposer::PostThread() {
                                 ns_per_frame, right_eye_photon_offset_ns);
     }
 
-    bool layer_config_changed = UpdateLayerConfig();
-
-    if (!was_running || layer_config_changed) {
-      frame_time_history_.ResetWithSeed(
-          GuessFrameTime(compositor_surfaces_.size()));
-      frame_time_backlog_.clear();
-    } else {
-      UpdateFrameTimeHistory(&frame_time_backlog_, kFrameTimeBacklogMax,
-                             &fence_info_buffer, &frame_time_history_);
-    }
-
-    // Get our current best estimate at how long the next frame will take to
-    // render, based on how long previous frames took to render. Use this
-    // estimate to decide when to wake up for EDS.
-    int64_t frame_time_estimate =
-        frame_time_history_.GetSampleCount() == 0
-            ? GuessFrameTime(compositor_surfaces_.size())
-            : frame_time_history_.GetAverage();
-    frame_time_estimate = std::max(frame_time_estimate, kFrameTimeEstimateMin);
-    DebugHudData::data.hwc_latency = frame_time_estimate;
+    const bool layer_config_changed = UpdateLayerConfig();
 
     // Signal all of the vsync clients. Because absolute time is used for the
     // wakeup time below, this can take a little time if necessary.
     if (vsync_callback_)
-      vsync_callback_(HWC_DISPLAY_PRIMARY, vsync_timestamp, frame_time_estimate,
-                      vsync_count_);
+      vsync_callback_(HWC_DISPLAY_PRIMARY, vsync_timestamp,
+                      /*frame_time_estimate*/ 0, vsync_count_);
 
     {
-      // Sleep until async EDS wakeup time.
+      // Sleep until shortly before vsync.
       ATRACE_NAME("sleep");
 
-      int64_t display_time_est = vsync_timestamp + ns_per_frame;
-      int64_t now = GetSystemClockNs();
-      int64_t frame_finish_time_est = now + frame_time_estimate;
-      int64_t sleep_time_ns = display_time_est - now - frame_time_estimate;
+      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;
 
       ATRACE_INT64("sleep_time_ns", sleep_time_ns);
-      if (frame_finish_time_est - display_time_est >= kFrameSkipThresholdNs) {
-        ATRACE_INT("frame_skip_count", ++frame_skip_count_);
-        ALOGE(
-            "HardwareComposer::PostThread: Missed frame schedule, drop "
-            "frame. Expected frame miss: %.1fms",
-            static_cast<double>(frame_finish_time_est - display_time_est) /
-                1000000);
-
-        // There are several reasons we might skip a frame, but one possibility
-        // is we mispredicted the frame time. Clear out the frame time history.
-        frame_time_history_.ResetWithSeed(
-            GuessFrameTime(compositor_surfaces_.size()));
-        frame_time_backlog_.clear();
-        DebugHudData::data.hwc_frame_stats.SkipFrame();
-
-        if (layer_config_changed) {
-          // If the layer config changed we need to validateDisplay() even if
-          // we're going to drop the frame, to flush the Composer object's
-          // internal command buffer and apply our layer changes.
-          Validate(HWC_DISPLAY_PRIMARY);
-        }
-
-        continue;
-      } else {
-        // Make the transition more obvious in systrace when the frame skip
-        // happens above.
-        ATRACE_INT("frame_skip_count", 0);
-      }
-
       if (sleep_time_ns > 0) {
-        error = SleepUntil(display_time_est - frame_time_estimate);
+        int error = SleepUntil(wakeup_time_ns);
         ALOGE_IF(error < 0, "HardwareComposer::PostThread: Failed to sleep: %s",
                  strerror(-error));
         if (error == kPostThreadInterrupted) {
@@ -936,312 +878,56 @@ void HardwareComposer::PostThread() {
       }
     }
 
-    DebugHudData::data.hwc_frame_stats.AddFrame();
-
-    int64_t frame_start_time = GetSystemClockNs();
-
-    // Setup the output buffer for the compositor. This needs to happen before
-    // you draw with the compositor.
-    if (gpu_layer_ != nullptr) {
-      gpu_layer_->UpdateDirectBuffer(compositor_.GetBuffer());
-    }
-
-    // Call PostLayers now before performing the GL code for the compositor to
-    // avoid missing the deadline that can cause the lower-level hwc to get
-    // permanently backed up.
-    PostLayers(layer_config_changed);
-
-    PostCompositorBuffers();
-
-    if (gpu_layer_ != nullptr) {
-      // Note, with scanline racing, this draw is timed along with the post
-      // layers to finish just in time.
-      LocalHandle frame_fence_fd;
-      compositor_.DrawFrame(vsync_count_ + 1, &frame_fence_fd);
-      if (frame_fence_fd) {
-        LOG_ALWAYS_FATAL_IF(frame_time_backlog_.size() >= kFrameTimeBacklogMax,
-                            "Frame time backlog exceeds capacity");
-        frame_time_backlog_.push_back(
-            {frame_start_time, std::move(frame_fence_fd)});
-      }
-    } else if (!layer_config_changed) {
-      frame_time_history_.AddSample(GetSystemClockNs() - frame_start_time);
-    }
-
-    HandlePendingScreenshots();
+    PostLayers();
   }
 }
 
+// Checks for changes in the surface stack and updates the layer config to
+// accomodate the new stack.
 bool HardwareComposer::UpdateLayerConfig() {
-  std::vector<std::shared_ptr<DisplaySurface>> old_display_surfaces;
+  std::vector<std::shared_ptr<DirectDisplaySurface>> surfaces;
   {
-    std::lock_guard<std::mutex> lock(post_thread_mutex_);
-    if (!active_surfaces_updated_)
+    std::unique_lock<std::mutex> lock(post_thread_mutex_);
+    if (pending_surfaces_.empty())
       return false;
-    old_display_surfaces = display_surfaces_;
-    display_surfaces_ = active_surfaces_;
-    active_surfaces_updated_ = false;
-  }
-
-  DebugHudData::data.ResetLayers();
-
-  // Figure out whether we need to update hardware layers. If this surface
-  // change does not add or remove hardware layers we can avoid display hiccups
-  // by gracefully updating only the GPU compositor layers.
-  int old_gpu_layer_count = 0;
-  int new_gpu_layer_count = 0;
-  bool hardware_layers_need_update = false;
-  // Look for new hardware layers and count new GPU layers.
-  for (const auto& surface : display_surfaces_) {
-    if (!(surface->flags() &
-          DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION))
-      ++new_gpu_layer_count;
-    else if (std::find(old_display_surfaces.begin(), old_display_surfaces.end(),
-                       surface) == old_display_surfaces.end())
-      // This is a new hardware layer, we need to update.
-      hardware_layers_need_update = true;
-  }
-  // Look for deleted hardware layers or compositor layers.
-  for (const auto& surface : old_display_surfaces) {
-    if (!(surface->flags() &
-          DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION))
-      ++old_gpu_layer_count;
-    else if (std::find(display_surfaces_.begin(), display_surfaces_.end(),
-                       surface) == display_surfaces_.end())
-      // This is a deleted hardware layer, we need to update.
-      hardware_layers_need_update = true;
-  }
-  // Check for compositor hardware layer transition.
-  if ((!old_gpu_layer_count && new_gpu_layer_count) ||
-      (old_gpu_layer_count && !new_gpu_layer_count))
-    hardware_layers_need_update = true;
-
-  // Set the chosen layer order for all surfaces.
-  for (size_t i = 0; i < display_surfaces_.size(); ++i) {
-    display_surfaces_[i]->SetLayerOrder(static_cast<int>(i));
-  }
 
-  // Update compositor layers.
-  {
-    ATRACE_NAME("UpdateLayerConfig_GpuLayers");
-    compositor_.UpdateSurfaces(display_surfaces_);
-    compositor_surfaces_.clear();
-    for (size_t i = 0; i < display_surfaces_.size(); ++i) {
-      const auto& surface = display_surfaces_[i];
-      if (!(surface->flags() &
-            DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION)) {
-        compositor_surfaces_.push_back(surface);
-      }
-    }
+    surfaces = std::move(pending_surfaces_);
   }
 
-  if (!hardware_layers_need_update)
-    return true;
-
-  // Update hardware layers.
-
   ATRACE_NAME("UpdateLayerConfig_HwLayers");
 
-  // Update the display layers in a non-destructive fashion.
-
-  // Create a map from surface id to hardware layer
-  std::map<int, Layer*> display_surface_layers;
-
-  for (size_t i = 0; i < active_layer_count_; ++i) {
-    auto layer = layers_[i];
-    int surface_id = layer->GetSurfaceId();
-
-    auto found =
-        std::find_if(display_surfaces_.begin(), display_surfaces_.end(),
-                     [surface_id](const auto& surface) {
-                       return surface->surface_id() == surface_id;
-                     });
-
-    if (found != display_surfaces_.end()) {
-      display_surface_layers[surface_id] = layer;
-    }
-  }
-
-  bool has_gpu_layer = std::any_of(
-      display_surfaces_.begin(), display_surfaces_.end(),
-      [](const auto& surface) {
-        return !(surface->flags() &
-                 DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION);
-      });
-
-  if (!has_gpu_layer) {
-    gpu_layer_ = nullptr;
-  }
-
-  auto is_layer_active = [&display_surface_layers, has_gpu_layer](auto layer) {
-    int surface_id = layer->GetSurfaceId();
-    if (surface_id >= 0) {
-      return display_surface_layers.count(surface_id) > 0;
-    } else {
-      return has_gpu_layer;
-    }
-  };
-
-  // Compress the in-use layers to the top of the list
-  auto part = std::partition(
-      layers_.begin(), layers_.begin() + active_layer_count_, is_layer_active);
-
-  size_t new_active_layer_count = part - layers_.begin();
+  display_surfaces_.clear();
 
-  // Clear any unused layers
-  for (size_t i = new_active_layer_count; i < active_layer_count_; ++i) {
-    layers_[i]->Reset();
+  Layer* target_layer;
+  size_t layer_index;
+  for (layer_index = 0;
+       layer_index < std::min(surfaces.size(), kMaxHardwareLayers);
+       layer_index++) {
+    // The bottom layer is opaque, other layers blend.
+    HWC::BlendMode blending =
+        layer_index == 0 ? HWC::BlendMode::None : HWC::BlendMode::Coverage;
+    layers_[layer_index].Setup(surfaces[layer_index], blending,
+                               display_transform_, HWC::Composition::Device,
+                               layer_index);
+    display_surfaces_.push_back(surfaces[layer_index]);
   }
 
-  active_layer_count_ = new_active_layer_count;
-
-  bool gpu_layer_applied = false;
-
-  // Create/update all of the hardware layers
-  for (size_t i = 0; i < display_surfaces_.size(); ++i) {
-    const auto& surface = display_surfaces_[i];
-    bool is_hw_surface =
-        surface->flags() & DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION;
-    hwc2_blend_mode_t blending =
-        i == 0 ? HWC2_BLEND_MODE_NONE : HWC2_BLEND_MODE_COVERAGE;
-
-    DebugHudData::data.SetLayerInfo(
-        i, surface->width(), surface->height(),
-        !!(surface->flags() & DVR_DISPLAY_SURFACE_FLAGS_GEOMETRY_SEPARATE_2));
-
-    if (!is_hw_surface && gpu_layer_applied) {
-      continue;
-    }
-
-    Layer* target_layer;
-    bool existing_layer = false;
-
-    if (is_hw_surface) {
-      auto it = display_surface_layers.find(surface->surface_id());
-
-      if (it != display_surface_layers.end()) {
-        target_layer = it->second;
-        existing_layer = true;
-      }
-    } else if (gpu_layer_ != nullptr) {
-      target_layer = gpu_layer_;
-      existing_layer = true;
-    }
-
-    if (!existing_layer) {
-      if (active_layer_count_ >= kMaxHardwareLayers) {
-        ALOGI("HardwareComposer: More than %d hardware layers requested.",
-              kMaxHardwareLayers);
-        break;
-      } else {
-        target_layer = layers_[active_layer_count_];
-        ++active_layer_count_;
-      }
-
-      ALOGD_IF(TRACE,
-               "HardwareComposer::UpdateLayerConfig: (new) surface_id=%d -> "
-               "layer=%zd",
-               surface->surface_id(), i);
-
-      if (is_hw_surface) {
-        target_layer->Setup(surface, blending, display_transform_,
-                            HWC2_COMPOSITION_DEVICE, i);
-      } else {
-        gpu_layer_ = target_layer;
-        target_layer->Setup(compositor_.GetBuffer(), blending,
-                            display_transform_, HWC2_COMPOSITION_DEVICE, i);
-      }
-    } else {
-      ALOGD_IF(TRACE,
-               "HardwareComposer::UpdateLayerConfig: (retained) surface_id=%d "
-               "-> layer=%zd",
-               surface->surface_id(), i);
-
-      target_layer->SetBlending(blending);
-      target_layer->SetZOrderIndex(i);
-      target_layer->UpdateLayerSettings();
-    }
-
-    gpu_layer_applied = !is_hw_surface;
-  }
+  // Clear unused layers.
+  for (size_t i = layer_index; i < kMaxHardwareLayers; i++)
+    layers_[i].Reset();
 
+  active_layer_count_ = layer_index;
   ALOGD_IF(TRACE, "HardwareComposer::UpdateLayerConfig: %zd active layers",
            active_layer_count_);
 
-  return true;
-}
-
-void HardwareComposer::PostCompositorBuffers() {
-  ATRACE_NAME("PostCompositorBuffers");
-  for (const auto& surface : compositor_surfaces_) {
-    compositor_.PostBuffer(surface);
-  }
-}
-
-void HardwareComposer::UpdateFrameTimeHistory(
-    std::vector<FrameTimeMeasurementRecord>* backlog, int backlog_max,
-    FenceInfoBuffer* fence_info_buffer, FrameTimeHistory* history) {
-  while (!backlog->empty()) {
-    const auto& frame_time_record = backlog->front();
-    int64_t end_time = 0;
-    bool frame_finished = CheckFrameFinished(frame_time_record.fence.Get(),
-                                             fence_info_buffer, &end_time);
-    if (frame_finished) {
-      int64_t frame_duration = end_time - frame_time_record.start_time;
-      history->AddSample(frame_duration);
-      // Our backlog is tiny (2 elements), so erasing from the front is ok
-      backlog->erase(backlog->begin());
-    } else {
-      break;
-    }
-  }
+  // Any surfaces left over could not be assigned a hardware layer and will
+  // not be displayed.
+  ALOGW_IF(surfaces.size() != display_surfaces_.size(),
+           "HardwareComposer::UpdateLayerConfig: More surfaces than layers: "
+           "pending_surfaces=%zu display_surfaces=%zu",
+           surfaces.size(), display_surfaces_.size());
 
-  if (backlog->size() == static_cast<size_t>(backlog_max)) {
-    // Yikes, something must've gone wrong if our oldest frame hasn't finished
-    // yet. Give up on waiting for it.
-    const auto& stale_frame_time_record = backlog->front();
-    int64_t frame_duration =
-        GetSystemClockNs() - stale_frame_time_record.start_time;
-    backlog->erase(backlog->begin());
-    history->AddSample(frame_duration);
-    ALOGW("Frame didn't finish after %.1fms",
-          static_cast<double>(frame_duration) / 1000000);
-  }
-}
-
-bool HardwareComposer::CheckFrameFinished(int frame_fence_fd,
-                                          FenceInfoBuffer* fence_info_buffer,
-                                          int64_t* timestamp) {
-  int result = -1;
-  int sync_result = sync_wait(frame_fence_fd, 0);
-  if (sync_result == 0) {
-    result =
-        GetFenceSignaledTimestamp(frame_fence_fd, fence_info_buffer, timestamp);
-    if (result < 0) {
-      ALOGE("Failed getting signaled timestamp from fence");
-    }
-  } else if (errno != ETIME) {
-    ALOGE("sync_wait on frame fence failed");
-  }
-  return result >= 0;
-}
-
-void HardwareComposer::HandlePendingScreenshots() {
-  // Take a screenshot of the requested layer, if available.
-  // TODO(eieio): Look into using virtual displays to composite the layer stack
-  // into a single output buffer that can be returned to the screenshot clients.
-  if (active_layer_count_ > 0) {
-    if (auto screenshot_service = ScreenshotService::GetInstance()) {
-      if (screenshot_service->IsScreenshotRequestPending()) {
-        ATRACE_NAME("screenshot");
-        screenshot_service->TakeIfNeeded(layers_, compositor_);
-      }
-    } else {
-      ALOGW(
-          "HardwareComposer::HandlePendingScreenshots: Failed to get "
-          "screenshot service!");
-    }
-  }
+  return true;
 }
 
 void HardwareComposer::SetVSyncCallback(VSyncCallback callback) {
@@ -1280,145 +966,133 @@ void HardwareComposer::SetBacklightBrightness(int brightness) {
   }
 }
 
-Layer::Layer()
-    : hwc2_hidl_(nullptr),
-      surface_index_(-1),
-      hardware_composer_layer_(0),
-      display_metrics_(nullptr),
-      blending_(HWC2_BLEND_MODE_NONE),
-      transform_(HWC_TRANSFORM_NONE),
-      composition_type_(HWC2_COMPOSITION_DEVICE),
-      surface_rect_functions_applied_(false) {}
-
-void Layer::Initialize(Hwc2::Composer* hwc2_hidl, HWCDisplayMetrics* metrics) {
+void Layer::InitializeGlobals(Hwc2::Composer* hwc2_hidl,
+                              const HWCDisplayMetrics* metrics) {
   hwc2_hidl_ = hwc2_hidl;
   display_metrics_ = metrics;
 }
 
 void Layer::Reset() {
-  const int ret = acquired_buffer_.Release(std::move(release_fence_));
-  ALOGE_IF(ret < 0, "Layer::Reset: failed to release buffer: %s",
-           strerror(-ret));
-
   if (hwc2_hidl_ != nullptr && hardware_composer_layer_) {
     hwc2_hidl_->destroyLayer(HWC_DISPLAY_PRIMARY, hardware_composer_layer_);
     hardware_composer_layer_ = 0;
   }
 
-  surface_index_ = static_cast<size_t>(-1);
-  blending_ = HWC2_BLEND_MODE_NONE;
-  transform_ = HWC_TRANSFORM_NONE;
-  composition_type_ = HWC2_COMPOSITION_DEVICE;
-  direct_buffer_ = nullptr;
-  surface_ = nullptr;
-  acquire_fence_fd_.Close();
+  z_order_ = 0;
+  blending_ = HWC::BlendMode::None;
+  transform_ = HWC::Transform::None;
+  composition_type_ = HWC::Composition::Invalid;
+  target_composition_type_ = composition_type_;
+  source_ = EmptyVariant{};
+  acquire_fence_.Close();
   surface_rect_functions_applied_ = false;
 }
 
-void Layer::Setup(const std::shared_ptr<DisplaySurface>& surface,
-                  hwc2_blend_mode_t blending, hwc_transform_t transform,
-                  hwc2_composition_t composition_type, size_t index) {
+void Layer::Setup(const std::shared_ptr<DirectDisplaySurface>& surface,
+                  HWC::BlendMode blending, HWC::Transform transform,
+                  HWC::Composition composition_type, size_t z_order) {
   Reset();
-  surface_index_ = index;
-  surface_ = surface;
+  z_order_ = z_order;
   blending_ = blending;
   transform_ = transform;
-  composition_type_ = composition_type;
+  composition_type_ = HWC::Composition::Invalid;
+  target_composition_type_ = composition_type;
+  source_ = SourceSurface{surface};
   CommonLayerSetup();
 }
 
 void Layer::Setup(const std::shared_ptr<IonBuffer>& buffer,
-                  hwc2_blend_mode_t blending, hwc_transform_t transform,
-                  hwc2_composition_t composition_type, size_t z_order) {
+                  HWC::BlendMode blending, HWC::Transform transform,
+                  HWC::Composition composition_type, size_t z_order) {
   Reset();
-  surface_index_ = z_order;
-  direct_buffer_ = buffer;
+  z_order_ = z_order;
   blending_ = blending;
   transform_ = transform;
-  composition_type_ = composition_type;
+  composition_type_ = HWC::Composition::Invalid;
+  target_composition_type_ = composition_type;
+  source_ = SourceBuffer{buffer};
   CommonLayerSetup();
 }
 
-void Layer::UpdateDirectBuffer(const std::shared_ptr<IonBuffer>& buffer) {
-  direct_buffer_ = buffer;
+void Layer::UpdateBuffer(const std::shared_ptr<IonBuffer>& buffer) {
+  if (source_.is<SourceBuffer>())
+    std::get<SourceBuffer>(source_) = {buffer};
 }
 
-void Layer::SetBlending(hwc2_blend_mode_t blending) { blending_ = blending; }
-
-void Layer::SetZOrderIndex(int z_index) { surface_index_ = z_index; }
+void Layer::SetBlending(HWC::BlendMode blending) { blending_ = blending; }
+void Layer::SetZOrder(size_t z_order) { z_order_ = z_order; }
 
 IonBuffer* Layer::GetBuffer() {
-  if (direct_buffer_)
-    return direct_buffer_.get();
-  else if (acquired_buffer_.IsAvailable())
-    return acquired_buffer_.buffer()->buffer();
-  else
-    return nullptr;
+  struct Visitor {
+    IonBuffer* operator()(SourceSurface& source) { return source.GetBuffer(); }
+    IonBuffer* operator()(SourceBuffer& source) { return source.GetBuffer(); }
+    IonBuffer* operator()(EmptyVariant) { return nullptr; }
+  };
+  return source_.Visit(Visitor{});
 }
 
 void Layer::UpdateLayerSettings() {
   if (!IsLayerSetup()) {
-    ALOGE("HardwareComposer: Trying to update layers data on an unused layer.");
+    ALOGE(
+        "HardwareComposer::Layer::UpdateLayerSettings: Attempt to update "
+        "unused Layer!");
     return;
   }
 
-  int32_t ret = HWC2_ERROR_NONE;
-
+  HWC::Error error;
   hwc2_display_t display = HWC_DISPLAY_PRIMARY;
 
-  ret = (int32_t)hwc2_hidl_->setLayerCompositionType(
+  error = hwc2_hidl_->setLayerCompositionType(
       display, hardware_composer_layer_,
-      (Hwc2::IComposerClient::Composition)composition_type_);
-  ALOGE_IF(ret, "HardwareComposer: Error setting layer composition type : %d",
-           ret);
-  // ret = (int32_t) hwc2_hidl_->setLayerTransform(display,
-  // hardware_composer_layer_,
-  //                                    (Hwc2::IComposerClient::Transform)
-  //                                    transform_);
-  // ALOGE_IF(ret, "HardwareComposer: Error setting layer transform : %d", ret);
-
-  // ret = hwc2_funcs_->set_layer_blend_mode_fn_(
-  //    hardware_composer_device_, display, hardware_composer_layer_,
-  //    blending_);
-  ret = (int32_t)hwc2_hidl_->setLayerBlendMode(
+      composition_type_.cast<Hwc2::IComposerClient::Composition>());
+  ALOGE_IF(
+      error != HWC::Error::None,
+      "Layer::UpdateLayerSettings: Error setting layer composition type: %s",
+      error.to_string().c_str());
+
+  error = hwc2_hidl_->setLayerBlendMode(
       display, hardware_composer_layer_,
-      (Hwc2::IComposerClient::BlendMode)blending_);
-  ALOGE_IF(ret, "HardwareComposer: Error setting layer blend mode : %d", ret);
-
-  Hwc2::IComposerClient::Rect display_frame;
-  display_frame.left = 0;
-  display_frame.top = 0;
-  display_frame.right = display_metrics_->width;
-  display_frame.bottom = display_metrics_->height;
-  ret = (int32_t)hwc2_hidl_->setLayerDisplayFrame(
-      display, hardware_composer_layer_, display_frame);
-  ALOGE_IF(ret, "HardwareComposer: Error setting layer display frame : %d",
-           ret);
-
-  std::vector<Hwc2::IComposerClient::Rect> visible_region(1);
-  visible_region[0] = display_frame;
-  ret = (int32_t)hwc2_hidl_->setLayerVisibleRegion(
-      display, hardware_composer_layer_, visible_region);
-  ALOGE_IF(ret, "HardwareComposer: Error setting layer visible region : %d",
-           ret);
-
-  ret = (int32_t)hwc2_hidl_->setLayerPlaneAlpha(display,
-                                                hardware_composer_layer_, 1.0f);
-  ALOGE_IF(ret, "HardwareComposer: Error setting layer plane alpha : %d", ret);
-
-  ret = (int32_t)hwc2_hidl_->setLayerZOrder(display, hardware_composer_layer_,
-                                            surface_index_);
-  ALOGE_IF(ret, "HardwareComposer: Error, setting z order index : %d", ret);
+      blending_.cast<Hwc2::IComposerClient::BlendMode>());
+  ALOGE_IF(error != HWC::Error::None,
+           "Layer::UpdateLayerSettings: Error setting layer blend mode: %s",
+           error.to_string().c_str());
+
+  // TODO(eieio): Use surface attributes or some other mechanism to control
+  // the layer display frame.
+  error = hwc2_hidl_->setLayerDisplayFrame(
+      display, hardware_composer_layer_,
+      {0, 0, display_metrics_->width, display_metrics_->height});
+  ALOGE_IF(error != HWC::Error::None,
+           "Layer::UpdateLayerSettings: Error setting layer display frame: %s",
+           error.to_string().c_str());
+
+  error = hwc2_hidl_->setLayerVisibleRegion(
+      display, hardware_composer_layer_,
+      {{0, 0, display_metrics_->width, display_metrics_->height}});
+  ALOGE_IF(error != HWC::Error::None,
+           "Layer::UpdateLayerSettings: Error setting layer visible region: %s",
+           error.to_string().c_str());
+
+  error =
+      hwc2_hidl_->setLayerPlaneAlpha(display, hardware_composer_layer_, 1.0f);
+  ALOGE_IF(error != HWC::Error::None,
+           "Layer::UpdateLayerSettings: Error setting layer plane alpha: %s",
+           error.to_string().c_str());
+
+  error =
+      hwc2_hidl_->setLayerZOrder(display, hardware_composer_layer_, z_order_);
+  ALOGE_IF(error != HWC::Error::None,
+           "Layer::UpdateLayerSettings: Error setting z_ order: %s",
+           error.to_string().c_str());
 }
 
 void Layer::CommonLayerSetup() {
-  int32_t ret = (int32_t)hwc2_hidl_->createLayer(HWC_DISPLAY_PRIMARY,
-                                                 &hardware_composer_layer_);
-
-  ALOGE_IF(ret,
-           "HardwareComposer: Failed to create layer on primary display : %d",
-           ret);
-
+  HWC::Error error =
+      hwc2_hidl_->createLayer(HWC_DISPLAY_PRIMARY, &hardware_composer_layer_);
+  ALOGE_IF(
+      error != HWC::Error::None,
+      "Layer::CommonLayerSetup: Failed to create layer on primary display: %s",
+      error.to_string().c_str());
   UpdateLayerSettings();
 }
 
@@ -1426,114 +1100,69 @@ void Layer::Prepare() {
   int right, bottom;
   sp<GraphicBuffer> handle;
 
-  if (surface_) {
-    // Only update the acquired buffer when one is either available or this is
-    // the first time through.
-    if (surface_->IsBufferAvailable()) {
-      // If we previously set this to a solid color layer to stall for time,
-      // revert it to a device layer.
-      if (acquired_buffer_.IsEmpty() &&
-          composition_type_ != HWC2_COMPOSITION_DEVICE) {
-        composition_type_ = HWC2_COMPOSITION_DEVICE;
-        hwc2_hidl_->setLayerCompositionType(
-            HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
-            (Hwc2::IComposerClient::Composition)HWC2_COMPOSITION_DEVICE);
-      }
-
-      DebugHudData::data.AddLayerFrame(surface_index_);
-      acquired_buffer_.Release(std::move(release_fence_));
-      acquired_buffer_ = surface_->AcquireCurrentBuffer();
-
-      // Basic latency stopgap for when the application misses a frame:
-      // If the application recovers on the 2nd or 3rd (etc) frame after
-      // missing, this code will skip a frame to catch up by checking if
-      // the next frame is also available.
-      if (surface_->IsBufferAvailable()) {
-        DebugHudData::data.SkipLayerFrame(surface_index_);
-        ATRACE_NAME("DropToCatchUp");
-        ATRACE_ASYNC_END("BufferPost", acquired_buffer_.buffer()->id());
-        acquired_buffer_ = surface_->AcquireCurrentBuffer();
-      }
-      ATRACE_ASYNC_END("BufferPost", acquired_buffer_.buffer()->id());
-    } else if (acquired_buffer_.IsEmpty()) {
-      // While we are waiting for a buffer, set this to be an empty layer
-      if (composition_type_ != HWC2_COMPOSITION_SOLID_COLOR) {
-        composition_type_ = HWC2_COMPOSITION_SOLID_COLOR;
-        hwc2_hidl_->setLayerCompositionType(
-            HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
-            (Hwc2::IComposerClient::Composition)HWC2_COMPOSITION_SOLID_COLOR);
-
-        Hwc2::IComposerClient::Color layer_color = {
-            0, 0, 0, 0,
-        };
-        hwc2_hidl_->setLayerColor(HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
-                                  layer_color);
-      }
-      return;
+  // Acquire the next buffer according to the type of source.
+  IfAnyOf<SourceSurface, SourceBuffer>::Call(&source_, [&](auto& source) {
+    std::tie(right, bottom, handle, acquire_fence_) = source.Acquire();
+  });
+
+  // When a layer is first setup there may be some time before the first buffer
+  // arrives. Setup the HWC layer as a solid color to stall for time until the
+  // first buffer arrives. Once the first buffer arrives there will always be a
+  // buffer for the frame even if it is old.
+  if (!handle.get()) {
+    if (composition_type_ == HWC::Composition::Invalid) {
+      composition_type_ = HWC::Composition::SolidColor;
+      hwc2_hidl_->setLayerCompositionType(
+          HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
+          composition_type_.cast<Hwc2::IComposerClient::Composition>());
+      Hwc2::IComposerClient::Color layer_color = {0, 0, 0, 0};
+      hwc2_hidl_->setLayerColor(HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
+                                layer_color);
+    } else {
+      // The composition type is already set. Nothing else to do until a
+      // buffer arrives.
     }
-    right = acquired_buffer_.buffer()->width();
-    bottom = acquired_buffer_.buffer()->height();
-    handle = acquired_buffer_.buffer()->buffer()->buffer();
-    acquire_fence_fd_.Reset(acquired_buffer_.ClaimAcquireFence().Release());
   } else {
-    // TODO(jwcai) Note: this is the GPU compositor's layer, and we need the
-    // mechanism to accept distorted layers from VrCore.
-    right = direct_buffer_->width();
-    bottom = direct_buffer_->height();
-    handle = direct_buffer_->buffer();
-    acquire_fence_fd_.Close();
-  }
+    if (composition_type_ != target_composition_type_) {
+      composition_type_ = target_composition_type_;
+      hwc2_hidl_->setLayerCompositionType(
+          HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
+          composition_type_.cast<Hwc2::IComposerClient::Composition>());
+    }
 
-  int32_t ret = HWC2_ERROR_NONE;
+    HWC::Error error{HWC::Error::None};
+    error = hwc2_hidl_->setLayerBuffer(HWC_DISPLAY_PRIMARY,
+                                       hardware_composer_layer_, 0, handle,
+                                       acquire_fence_.Get());
 
-  if (composition_type_ == HWC2_COMPOSITION_DEVICE) {
-    ret = (int32_t)hwc2_hidl_->setLayerBuffer(HWC_DISPLAY_PRIMARY,
-                                              hardware_composer_layer_, 0,
-                                              handle,
-                                              acquire_fence_fd_.Get());
+    ALOGE_IF(error != HWC::Error::None,
+             "Layer::Prepare: Error setting layer buffer: %s",
+             error.to_string().c_str());
 
-    ALOGE_IF(ret, "HardwareComposer: Error setting layer buffer : %d", ret);
-  }
+    if (!surface_rect_functions_applied_) {
+      const float float_right = right;
+      const float float_bottom = bottom;
+      error = hwc2_hidl_->setLayerSourceCrop(HWC_DISPLAY_PRIMARY,
+                                             hardware_composer_layer_,
+                                             {0, 0, float_right, float_bottom});
 
-  if (!surface_rect_functions_applied_) {
-    Hwc2::IComposerClient::FRect crop_rect = {
-        0, 0, static_cast<float>(right), static_cast<float>(bottom),
-    };
-    hwc2_hidl_->setLayerSourceCrop(HWC_DISPLAY_PRIMARY,
-                                   hardware_composer_layer_, crop_rect);
-
-    ALOGE_IF(ret, "HardwareComposer: Error setting layer source crop : %d",
-             ret);
-
-// TODO(skiazyk): why is this ifdef'd out. Is if a driver-specific issue where
-// it must/cannot be called?
-#ifdef QCOM_BSP
-    hwc_rect_t damage_rect = {
-        0, 0, right, bottom,
-    };
-    hwc_region_t damage = {
-        1, &damage_rect,
-    };
-    // ret = hwc2_funcs_->set_layer_surface_damage(
-    //    hardware_composer_device_, HWC_DISPLAY_PRIMARY,
-    //    hardware_composer_layer_, damage);
-    // uses a std::vector as the listing
-    // hwc2_hidl_->setLayerSurfaceDamage(HWC_DISPLAY_PRIMARY,
-    // hardware_composer_layer_, vector here);
-
-    ALOGE_IF(ret, "HardwareComposer: Error settings layer surface damage : %d",
-             ret);
-#endif
+      ALOGE_IF(error != HWC::Error::None,
+               "Layer::Prepare: Error setting layer source crop: %s",
+               error.to_string().c_str());
 
-    surface_rect_functions_applied_ = true;
+      surface_rect_functions_applied_ = true;
+    }
   }
 }
 
 void Layer::Finish(int release_fence_fd) {
-  release_fence_.Reset(release_fence_fd);
+  IfAnyOf<SourceSurface, SourceBuffer>::Call(
+      &source_, [release_fence_fd](auto& source) {
+        source.Finish(LocalHandle(release_fence_fd));
+      });
 }
 
-void Layer::Drop() { acquire_fence_fd_.Close(); }
+void Layer::Drop() { acquire_fence_.Close(); }
 
 }  // namespace dvr
 }  // namespace android
index e570cb6..5a75f42 100644 (file)
@@ -1,13 +1,12 @@
 #ifndef ANDROID_DVR_SERVICES_DISPLAYD_HARDWARE_COMPOSER_H_
 #define ANDROID_DVR_SERVICES_DISPLAYD_HARDWARE_COMPOSER_H_
 
-#include <log/log.h>
-#include <hardware/gralloc.h>
-#include <hardware/hardware.h>
-#include <hardware/hwcomposer2.h>
+#include <ui/GraphicBuffer.h>
+#include "DisplayHardware/ComposerHal.h"
+#include "hwc_types.h"
 
-#include <private/dvr/buffer_hub_client.h>
-#include <private/dvr/sync_util.h>
+#include <hardware/gralloc.h>
+#include <log/log.h>
 
 #include <array>
 #include <condition_variable>
 #include <tuple>
 #include <vector>
 
+#include <dvr/pose_client.h>
 #include <pdx/file_handle.h>
+#include <pdx/rpc/variant.h>
 #include <private/dvr/buffer_hub_client.h>
 #include <private/dvr/frame_time_history.h>
 #include <private/dvr/sync_util.h>
 
 #include "acquired_buffer.h"
-#include "compositor.h"
 #include "display_surface.h"
 
-#include "DisplayHardware/ComposerHal.h"
-
 // Hardware composer HAL doesn't define HWC_TRANSFORM_NONE as of this writing.
 #ifndef HWC_TRANSFORM_NONE
 #define HWC_TRANSFORM_NONE static_cast<hwc_transform_t>(0)
@@ -53,29 +51,28 @@ struct HWCDisplayMetrics {
 // source supplying buffers for the layer's contents.
 class Layer {
  public:
-  Layer();
+  Layer() {}
 
-  // Sets the hardware composer layer and display metrics that this Layer should
-  // use each Prepare cycle. This class does not own either of these pointers,
-  // which MUST remain valid for its lifetime. This method MUST be called once
-  // in the life of the instance before any other method is valid to call.
-  void Initialize(Hwc2::Composer* hwc2_hidl, HWCDisplayMetrics* metrics);
+  // Sets up the global state used by all Layer instances. This must be called
+  // before using any Layer methods.
+  static void InitializeGlobals(Hwc2::Composer* hwc2_hidl,
+                                const HWCDisplayMetrics* metrics);
 
   // Releases any shared pointers and fence handles held by this instance.
   void Reset();
 
   // Sets up the layer to use a display surface as its content source. The Layer
-  // will automatically handle ACQUIRE/RELEASE phases for the surface's buffer
-  // train every frame.
+  // automatically handles ACQUIRE/RELEASE phases for the surface's buffer train
+  // every frame.
   //
   // |blending| receives HWC_BLENDING_* values.
   // |transform| receives HWC_TRANSFORM_* values.
   // |composition_type| receives either HWC_FRAMEBUFFER for most layers or
   // HWC_FRAMEBUFFER_TARGET (unless you know what you are doing).
-  // |index| is the index of this surface in the DisplaySurface array.
-  void Setup(const std::shared_ptr<DisplaySurface>& surface,
-             hwc2_blend_mode_t blending, hwc_transform_t transform,
-             hwc2_composition_t composition_type, size_t index);
+  // |index| is the index of this surface in the DirectDisplaySurface array.
+  void Setup(const std::shared_ptr<DirectDisplaySurface>& surface,
+             HWC::BlendMode blending, HWC::Transform transform,
+             HWC::Composition composition_type, size_t z_roder);
 
   // Sets up the layer to use a direct buffer as its content source. No special
   // handling of the buffer is performed; responsibility for updating or
@@ -85,13 +82,13 @@ class Layer {
   // |transform| receives HWC_TRANSFORM_* values.
   // |composition_type| receives either HWC_FRAMEBUFFER for most layers or
   // HWC_FRAMEBUFFER_TARGET (unless you know what you are doing).
-  void Setup(const std::shared_ptr<IonBuffer>& buffer,
-             hwc2_blend_mode_t blending, hwc_transform_t transform,
-             hwc2_composition_t composition_type, size_t z_order);
+  void Setup(const std::shared_ptr<IonBuffer>& buffer, HWC::BlendMode blending,
+             HWC::Transform transform, HWC::Composition composition_type,
+             size_t z_order);
 
   // Layers that use a direct IonBuffer should call this each frame to update
   // which buffer will be used for the next PostLayers.
-  void UpdateDirectBuffer(const std::shared_ptr<IonBuffer>& buffer);
+  void UpdateBuffer(const std::shared_ptr<IonBuffer>& buffer);
 
   // Sets up the hardware composer layer for the next frame. When the layer is
   // associated with a display surface, this method automatically ACQUIRES a new
@@ -107,10 +104,10 @@ class Layer {
   void Finish(int release_fence_fd);
 
   // Sets the blending for the layer. |blending| receives HWC_BLENDING_* values.
-  void SetBlending(hwc2_blend_mode_t blending);
+  void SetBlending(HWC::BlendMode blending);
 
-  // Sets the Z-order of this layer
-  void SetZOrderIndex(int surface_index);
+  // Sets the z-order of this layer
+  void SetZOrder(size_t z_order);
 
   // Gets the current IonBuffer associated with this layer. Ownership of the
   // buffer DOES NOT pass to the caller and the pointer is not guaranteed to
@@ -118,57 +115,111 @@ class Layer {
   // Layer::Reset(). YOU HAVE BEEN WARNED.
   IonBuffer* GetBuffer();
 
-  hwc2_composition_t GetCompositionType() const { return composition_type_; }
-
-  hwc2_layer_t GetLayerHandle() const { return hardware_composer_layer_; }
-
-  bool UsesDirectBuffer() const { return direct_buffer_ != nullptr; }
-
-  bool IsLayerSetup() const {
-    return direct_buffer_ != nullptr || surface_ != nullptr;
-  }
+  HWC::Composition GetCompositionType() const { return composition_type_; }
+  HWC::Layer GetLayerHandle() const { return hardware_composer_layer_; }
+  bool IsLayerSetup() const { return !source_.empty(); }
 
   // Applies all of the settings to this layer using the hwc functions
   void UpdateLayerSettings();
 
   int GetSurfaceId() const {
-    if (surface_ != nullptr) {
-      return surface_->surface_id();
-    } else {
-      return -1;
-    }
+    int surface_id = -1;
+    pdx::rpc::IfAnyOf<SourceSurface>::Call(
+        &source_, [&surface_id](const SourceSurface& surface_source) {
+          surface_id = surface_source.surface->surface_id();
+        });
+    return surface_id;
   }
 
  private:
   void CommonLayerSetup();
 
-  Hwc2::Composer* hwc2_hidl_;
-
-  // Original display surface array index for tracking purposes.
-  size_t surface_index_;
+  static Hwc2::Composer* hwc2_hidl_;
+  static const HWCDisplayMetrics* display_metrics_;
 
   // The hardware composer layer and metrics to use during the prepare cycle.
-  hwc2_layer_t hardware_composer_layer_;
-  HWCDisplayMetrics* display_metrics_;
+  hwc2_layer_t hardware_composer_layer_ = 0;
 
   // Layer properties used to setup the hardware composer layer during the
   // Prepare phase.
-  hwc2_blend_mode_t blending_;
-  hwc_transform_t transform_;
-  hwc2_composition_t composition_type_;
+  size_t z_order_ = 0;
+  HWC::BlendMode blending_ = HWC::BlendMode::None;
+  HWC::Transform transform_ = HWC::Transform::None;
+  HWC::Composition composition_type_ = HWC::Composition::Invalid;
+  HWC::Composition target_composition_type_ = HWC::Composition::Device;
+
+  // State when the layer is connected to a surface. Provides the same interface
+  // as SourceBuffer to simplify internal use by Layer.
+  struct SourceSurface {
+    std::shared_ptr<DirectDisplaySurface> surface;
+    AcquiredBuffer acquired_buffer;
+    pdx::LocalHandle release_fence;
+
+    SourceSurface(const std::shared_ptr<DirectDisplaySurface>& surface)
+        : surface(surface) {}
+
+    // Attempts to acquire a new buffer from the surface and return a tuple with
+    // width, height, buffer handle, and fence. If a new buffer is not available
+    // the previous buffer is returned or an empty value if no buffer has ever
+    // been posted. When a new buffer is acquired the previous buffer's release
+    // fence is passed out automatically.
+    std::tuple<int, int, sp<GraphicBuffer>, pdx::LocalHandle> Acquire() {
+      if (surface->IsBufferAvailable()) {
+        acquired_buffer.Release(std::move(release_fence));
+        acquired_buffer = surface->AcquireCurrentBuffer();
+        ATRACE_ASYNC_END("BufferPost", acquired_buffer.buffer()->id());
+      }
+      if (!acquired_buffer.IsEmpty()) {
+        return std::make_tuple(acquired_buffer.buffer()->width(),
+                               acquired_buffer.buffer()->height(),
+                               acquired_buffer.buffer()->buffer()->buffer(),
+                               acquired_buffer.ClaimAcquireFence());
+      } else {
+        return std::make_tuple(0, 0, nullptr, pdx::LocalHandle{});
+      }
+    }
+
+    void Finish(pdx::LocalHandle fence) { release_fence = std::move(fence); }
+
+    // Gets a pointer to the current acquired buffer or returns nullptr if there
+    // isn't one.
+    IonBuffer* GetBuffer() {
+      if (acquired_buffer.IsAvailable())
+        return acquired_buffer.buffer()->buffer();
+      else
+        return nullptr;
+    }
+
+    // Returns the surface id of the surface.
+    int GetSurfaceId() { return surface->surface_id(); }
+  };
+
+  // State when the layer is connected to a buffer. Provides the same interface
+  // as SourceSurface to simplify internal use by Layer.
+  struct SourceBuffer {
+    std::shared_ptr<IonBuffer> buffer;
+
+    std::tuple<int, int, sp<GraphicBuffer>, pdx::LocalHandle> Acquire() {
+      if (buffer)
+        return std::make_tuple(buffer->width(), buffer->height(),
+                               buffer->buffer(), pdx::LocalHandle{});
+      else
+        return std::make_tuple(0, 0, nullptr, pdx::LocalHandle{});
+    }
 
-  // These two members are mutually exclusive. When direct_buffer_ is set the
-  // Layer gets its contents directly from that buffer; when surface_ is set the
-  // Layer gets it contents from the surface's buffer train.
-  std::shared_ptr<IonBuffer> direct_buffer_;
-  std::shared_ptr<DisplaySurface> surface_;
+    void Finish(pdx::LocalHandle /*fence*/) {}
 
-  // State when associated with a display surface.
-  AcquiredBuffer acquired_buffer_;
-  pdx::LocalHandle release_fence_;
+    IonBuffer* GetBuffer() { return buffer.get(); }
 
-  pdx::LocalHandle acquire_fence_fd_;
-  bool surface_rect_functions_applied_;
+    int GetSurfaceId() const { return -1; }
+  };
+
+  // The underlying hardware composer layer is supplied buffers either from a
+  // surface buffer train or from a buffer directly.
+  pdx::rpc::Variant<SourceSurface, SourceBuffer> source_;
+
+  pdx::LocalHandle acquire_fence_;
+  bool surface_rect_functions_applied_ = false;
 
   Layer(const Layer&) = delete;
   void operator=(const Layer&) = delete;
@@ -186,13 +237,15 @@ class HardwareComposer {
  public:
   // Type for vsync callback.
   using VSyncCallback = std::function<void(int, int64_t, int64_t, uint32_t)>;
+  using RequestDisplayCallback = std::function<void(bool)>;
 
   // Since there is no universal way to query the number of hardware layers,
   // just set it to 4 for now.
-  static constexpr int kMaxHardwareLayers = 4;
+  static constexpr size_t kMaxHardwareLayers = 4;
 
   HardwareComposer();
-  HardwareComposer(Hwc2::Composer* hidl);
+  HardwareComposer(Hwc2::Composer* hidl,
+                   RequestDisplayCallback request_display_callback);
   ~HardwareComposer();
 
   bool Initialize();
@@ -207,14 +260,14 @@ class HardwareComposer {
   void Disable();
 
   // Get the HMD display metrics for the current display.
-  DisplayMetrics GetHmdDisplayMetrics() const;
+  display::Metrics GetHmdDisplayMetrics() const;
 
-  int32_t GetDisplayAttribute(hwc2_display_t display, hwc2_config_t config,
-                              hwc2_attribute_t attributes,
-                              int32_t* out_value) const;
-  int32_t GetDisplayMetrics(hwc2_display_t display, hwc2_config_t config,
-                            HWCDisplayMetrics* out_metrics) const;
-  void Dump(char* buffer, uint32_t* out_size);
+  HWC::Error GetDisplayAttribute(hwc2_display_t display, hwc2_config_t config,
+                                 hwc2_attribute_t attributes,
+                                 int32_t* out_value) const;
+  HWC::Error GetDisplayMetrics(hwc2_display_t display, hwc2_config_t config,
+                               HWCDisplayMetrics* out_metrics) const;
+  std::string Dump();
 
   void SetVSyncCallback(VSyncCallback callback);
 
@@ -229,11 +282,9 @@ class HardwareComposer {
     return native_display_metrics_;
   }
 
-  // Set the display surface stack to compose to the display each frame.
+  // Sets the display surfaces to compose the hardware layer stack.
   void SetDisplaySurfaces(
-      std::vector<std::shared_ptr<DisplaySurface>> surfaces);
-
-  Compositor* GetCompositor() { return &compositor_; }
+      std::vector<std::shared_ptr<DirectDisplaySurface>> surfaces);
 
   void OnHardwareComposerRefresh();
 
@@ -265,23 +316,36 @@ class HardwareComposer {
     }
   };
 
-  int32_t Validate(hwc2_display_t display);
-  int32_t Present(hwc2_display_t display);
+  HWC::Error Validate(hwc2_display_t display);
+  HWC::Error Present(hwc2_display_t display);
 
   void SetBacklightBrightness(int brightness);
 
-  void PostLayers(bool is_geometry_changed);
+  void PostLayers();
   void PostThread();
 
-  // Check to see if we have a value written to post_thread_interrupt_event_fd_,
-  // indicating a control thread interrupted the post thread. This clears the
-  // post_thread_interrupt_event_fd_ state in the process. Returns true if an
-  // interrupt was requested.
-  bool CheckPostThreadInterruptEventFd();
+  // The post thread has two controlling states:
+  // 1. Idle: no work to do (no visible surfaces).
+  // 2. Suspended: explicitly halted (system is not in VR mode).
+  // When either #1 or #2 is true then the post thread is quiescent, otherwise
+  // it is active.
+  using PostThreadStateType = uint32_t;
+  struct PostThreadState {
+    enum : PostThreadStateType {
+      Active = 0,
+      Idle = (1 << 0),
+      Suspended = (1 << 1),
+      Quit = (1 << 2),
+    };
+  };
+
+  void UpdatePostThreadState(uint32_t state, bool suspend);
+
   // Blocks until either event_fd becomes readable, or we're interrupted by a
   // control thread. Any errors are returned as negative errno values. If we're
   // interrupted, kPostThreadInterrupted will be returned.
-  int PostThreadPollInterruptible(int event_fd, int requested_events);
+  int PostThreadPollInterruptible(const pdx::LocalHandle& event_fd,
+                                  int requested_events);
 
   // BlockUntilVSync, WaitForVSync, and SleepUntil are all blocking calls made
   // on the post thread that can be interrupted by a control thread. If
@@ -294,49 +358,21 @@ class HardwareComposer {
 
   bool IsFramePendingInDriver() { return ReadWaitPPState() == 1; }
 
-  // Returns true if the layer config changed, false otherwise
+  // Reconfigures the layer stack if the display surfaces changed since the last
+  // frame. Called only from the post thread.
   bool UpdateLayerConfig();
-  void PostCompositorBuffers();
-
-  // Return true if the post thread has work to do (i.e. there are visible
-  // surfaces to post to the screen). Must be called with post_thread_mutex_
-  // locked. Called only from the post thread.
-  bool PostThreadHasWork();
 
   // Called on the post thread when the post thread is resumed.
   void OnPostThreadResumed();
   // Called on the post thread when the post thread is paused or quits.
   void OnPostThreadPaused();
 
-  struct FrameTimeMeasurementRecord {
-    int64_t start_time;
-    pdx::LocalHandle fence;
-
-    FrameTimeMeasurementRecord(FrameTimeMeasurementRecord&&) = default;
-    FrameTimeMeasurementRecord& operator=(FrameTimeMeasurementRecord&&) =
-        default;
-    FrameTimeMeasurementRecord(const FrameTimeMeasurementRecord&) = delete;
-    FrameTimeMeasurementRecord& operator=(const FrameTimeMeasurementRecord&) =
-        delete;
-  };
-
-  void UpdateFrameTimeHistory(std::vector<FrameTimeMeasurementRecord>* backlog,
-                              int backlog_max,
-                              FenceInfoBuffer* fence_info_buffer,
-                              FrameTimeHistory* history);
-
-  // Returns true if the frame finished rendering, false otherwise. If the frame
-  // finished the frame end time is stored in timestamp. Doesn't block.
-  bool CheckFrameFinished(int frame_fence_fd,
-                          FenceInfoBuffer* fence_info_buffer,
-                          int64_t* timestamp);
-
-  void HandlePendingScreenshots();
-
   bool initialized_;
 
-  // Hardware composer HAL device.
-  std::unique_ptr<Hwc2::Composer> hwc2_hidl_;
+  // Hardware composer HAL device from SurfaceFlinger. VrFlinger does not own
+  // this pointer.
+  Hwc2::Composer* hwc2_hidl_;
+  RequestDisplayCallback request_display_callback_;
   sp<ComposerCallback> callbacks_;
 
   // Display metrics of the physical display.
@@ -345,69 +381,39 @@ class HardwareComposer {
   // landscape.
   HWCDisplayMetrics display_metrics_;
   // Transform required to get from native to logical display orientation.
-  hwc_transform_t display_transform_;
+  HWC::Transform display_transform_ = HWC::Transform::None;
 
   // Buffer for the background layer required by hardware composer.
   std::shared_ptr<IonBuffer> framebuffer_target_;
 
-  // Protects access to variables used by the post thread and one of the control
-  // threads (either the vr flinger dispatcher thread or the surface flinger
-  // main thread). This includes active_surfaces_, active_surfaces_updated_,
-  // post_thread_enabled_, post_thread_running_, and
-  // post_thread_quit_requested_.
-  std::mutex post_thread_mutex_;
-
-  // Surfaces configured by the display manager. Written by the vr flinger
-  // dispatcher thread, read by the post thread.
-  std::vector<std::shared_ptr<DisplaySurface>> active_surfaces_;
-  // active_surfaces_updated_ is set to true by the vr flinger dispatcher thread
-  // when the list of active surfaces changes. active_surfaces_updated_ will be
-  // set back to false by the post thread when it processes the update.
-  bool active_surfaces_updated_;
+  // Pending surface list. Set by the display service when DirectSurfaces are
+  // added, removed, or change visibility. Written by the message dispatch
+  // thread and read by the post thread.
+  std::vector<std::shared_ptr<DirectDisplaySurface>> pending_surfaces_;
 
   // The surfaces displayed by the post thread. Used exclusively by the post
   // thread.
-  std::vector<std::shared_ptr<DisplaySurface>> display_surfaces_;
-
-  // The surfaces rendered by the compositor. Used exclusively by the post
-  // thread.
-  std::vector<std::shared_ptr<DisplaySurface>> compositor_surfaces_;
+  std::vector<std::shared_ptr<DirectDisplaySurface>> display_surfaces_;
 
   // Layer array for handling buffer flow into hardware composer layers.
-  // Note that the first array is the actual storage for the layer objects,
-  // and the latter is an array of pointers, which can be freely re-arranged
-  // without messing up the underlying objects.
-  std::array<Layer, kMaxHardwareLayers> layer_storage_;
-  std::array<Layer*, kMaxHardwareLayers> layers_;
-  size_t active_layer_count_;
-
-  // Set by the Post thread to the index of the GPU compositing output
-  // buffer in the layers_ array.
-  Layer* gpu_layer_;
+  std::array<Layer, kMaxHardwareLayers> layers_;
+  size_t active_layer_count_ = 0;
 
   // Handler to hook vsync events outside of this class.
   VSyncCallback vsync_callback_;
 
   // The layer posting thread. This thread wakes up a short time before vsync to
-  // hand buffers to post processing and the results to hardware composer.
+  // hand buffers to hardware composer.
   std::thread post_thread_;
 
-  // Set to true if the post thread is allowed to run. Surface flinger and vr
-  // flinger share access to the display, and vr flinger shouldn't use the
-  // display while surface flinger is using it. While surface flinger owns the
-  // display, post_thread_enabled_ will be set to false to indicate the post
-  // thread shouldn't run.
-  bool post_thread_enabled_;
-  // Set to true by the post thread if it's currently running.
-  bool post_thread_running_;
-  // Set to true if the post thread should quit. Only set when destroying the
-  // HardwareComposer instance.
-  bool post_thread_quit_requested_;
-  // Used to wake the post thread up while it's waiting for vsync or sleeping
-  // until EDS preemption, for faster transition to the paused state.
-  pdx::LocalHandle post_thread_interrupt_event_fd_;
-  // Used to communicate between the control thread and the post thread.
-  std::condition_variable post_thread_cond_var_;
+  // Post thread state machine and synchronization primitives.
+  PostThreadStateType post_thread_state_{PostThreadState::Idle};
+  std::atomic<bool> post_thread_quiescent_{true};
+  bool post_thread_resumed_{false};
+  pdx::LocalHandle post_thread_event_fd_;
+  std::mutex post_thread_mutex_;
+  std::condition_variable post_thread_wait_;
+  std::condition_variable post_thread_ready_;
 
   // Backlight LED brightness sysfs node.
   pdx::LocalHandle backlight_brightness_fd_;
@@ -422,16 +428,13 @@ class HardwareComposer {
   pdx::LocalHandle vsync_sleep_timer_fd_;
 
   // The timestamp of the last vsync.
-  int64_t last_vsync_timestamp_;
+  int64_t last_vsync_timestamp_ = 0;
 
   // Vsync count since display on.
-  uint32_t vsync_count_;
+  uint32_t vsync_count_ = 0;
 
   // Counter tracking the number of skipped frames.
-  int frame_skip_count_;
-
-  // After construction, only accessed on post_thread_.
-  Compositor compositor_;
+  int frame_skip_count_ = 0;
 
   // Fd array for tracking retire fences that are returned by hwc. This allows
   // us to detect when the display driver begins queuing frames.
@@ -439,16 +442,7 @@ class HardwareComposer {
 
   // Pose client for frame count notifications. Pose client predicts poses
   // out to display frame boundaries, so we need to tell it about vsyncs.
-  DvrPose* pose_client_;
-
-  // Our history of frame times. This is used to get a better estimate of how
-  // long the next frame will take, to set a schedule for EDS.
-  FrameTimeHistory frame_time_history_;
-
-  // The backlog is used to allow us to start rendering the next frame before
-  // the previous frame has finished, and still get an accurate measurement of
-  // frame duration.
-  std::vector<FrameTimeMeasurementRecord> frame_time_backlog_;
+  DvrPose* pose_client_ = nullptr;
 
   static constexpr int kPostThreadInterrupted = 1;
 
diff --git a/libs/vr/libvrflinger/hwc_types.h b/libs/vr/libvrflinger/hwc_types.h
new file mode 100644 (file)
index 0000000..cbf636c
--- /dev/null
@@ -0,0 +1,300 @@
+#ifndef ANDROID_LIBVRFLINGER_HWCTYPES_H
+#define ANDROID_LIBVRFLINGER_HWCTYPES_H
+
+// General HWC type support. Hardware composer type support is a bit of a mess
+// between HWC1, HWC2 C/C++11, and HIDL types. Particularly bothersome is the
+// use of enum classes, which make analogous types between versions much
+// harder to deal with in a uniform way.
+//
+// These utilities help address some of these pains by providing a type-safe,
+// flexible interface to translate between different type spaces.
+
+#define HWC2_INCLUDE_STRINGIFICATION
+#define HWC2_USE_CPP11
+#include <hardware/hwcomposer2.h>
+#undef HWC2_INCLUDE_STRINGIFICATION
+#undef HWC2_USE_CPP11
+
+#include <string>
+#include <type_traits>
+
+namespace HWC {
+
+// Value types derived from HWC HAL types. Some of these are stand-alone,
+// while others are also wrapped in translator classes below.
+using ColorMode = int32_t;  // android_color_mode_t;
+using Config = hwc2_config_t;
+using ColorTransform =
+    std::underlying_type<android_color_transform_t>::type;          // int32_t;
+using Dataspace = std::underlying_type<android_dataspace_t>::type;  // int32_t;
+using DisplayId = hwc2_display_t;
+using DisplayRequest = std::underlying_type<HWC2::DisplayRequest>::type;
+using Hdr = std::underlying_type<android_hdr_t>::type;  // int32_t;
+using Layer = hwc2_layer_t;
+using PixelFormat =
+    std::underlying_type<android_pixel_format_t>::type;  // int32_t;
+
+// Type traits and casting utilities.
+
+// SFINAE utility to evaluate type expressions.
+template <typename...>
+using TestTypeExpression = void;
+
+// Traits type to determine the underlying type of an enum, integer,
+// or wrapper class.
+template <typename T, typename = typename std::is_enum<T>::type,
+          typename = typename std::is_integral<T>::type, typename = void>
+struct UnderlyingType {
+  using Type = T;
+};
+// Partial specialization that matches enum types. Captures the underlying type
+// of the enum in member type Type.
+template <typename T>
+struct UnderlyingType<T, std::true_type, std::false_type> {
+  using Type = typename std::underlying_type<T>::type;
+};
+// Partial specialization that matches integral types. Captures the type of the
+// integer in member type Type.
+template <typename T>
+struct UnderlyingType<T, std::false_type, std::true_type> {
+  using Type = T;
+};
+// Partial specialization that matches the wrapper types below. Captures
+// wrapper member type ValueType in member type Type.
+template <typename T>
+struct UnderlyingType<T, std::false_type, std::false_type,
+                      TestTypeExpression<typename T::ValueType>> {
+  using Type = typename T::ValueType;
+};
+
+// Enable if T is an enum with underlying type U.
+template <typename T, typename U, typename ReturnType = void>
+using EnableIfMatchingEnum = typename std::enable_if<
+    std::is_enum<T>::value &&
+        std::is_same<U, typename UnderlyingType<T>::Type>::value,
+    ReturnType>::type;
+
+// Enable if T and U are the same size/alignment and have the same underlying
+// type. Handles enum, integral, and wrapper classes below.
+template <typename T, typename U, typename Return = void>
+using EnableIfSafeCast = typename std::enable_if<
+    sizeof(T) == sizeof(U) && alignof(T) == alignof(U) &&
+        std::is_same<typename UnderlyingType<T>::Type,
+                     typename UnderlyingType<U>::Type>::value,
+    Return>::type;
+
+// Safely cast between std::vectors of matching enum/integer/wraper types.
+// Normally this is not possible with pendantic compiler type checks. However,
+// given the same size, alignment, and underlying type this is safe due to
+// allocator requirements and array-like element access guarantees.
+template <typename T, typename U>
+EnableIfSafeCast<T, U, std::vector<T>*> VectorCast(std::vector<U>* in) {
+  return reinterpret_cast<std::vector<T>*>(in);
+}
+
+// Translator classes that wrap specific HWC types to make translating
+// between different types (especially enum class) in code cleaner.
+
+// Base type for the enum wrappers below. This type provides type definitions
+// and implicit conversion logic common to each wrapper type.
+template <typename EnumType>
+struct Wrapper {
+  // Alias type of this instantiantion of Wrapper. Useful for inheriting
+  // constructors in subclasses via "using Base::Base;" statements.
+  using Base = Wrapper<EnumType>;
+
+  // The enum type wrapped by this instantiation of Wrapper.
+  using BaseType = EnumType;
+
+  // The underlying type of the base enum type.
+  using ValueType = typename UnderlyingType<BaseType>::Type;
+
+  // A default constructor is not defined here. Subclasses should define one
+  // as appropriate to define the correct inital value for the enum type.
+
+  // Default copy constructor.
+  Wrapper(const Wrapper&) = default;
+
+  // Implicit conversion from ValueType.
+  Wrapper(ValueType value) : value(value) {}
+
+  // Implicit conversion from BaseType.
+  Wrapper(BaseType value) : value(static_cast<ValueType>(value)) {}
+
+  // Implicit conversion from an enum type of the same underlying type.
+  template <typename T, typename = EnableIfMatchingEnum<T, ValueType>>
+  Wrapper(const T& value) : value(static_cast<ValueType>(value)) {}
+
+  // Implicit conversion to BaseType.
+  operator BaseType() const { return static_cast<BaseType>(value); }
+
+  // Implicit conversion to ValueType.
+  operator ValueType() const { return value; }
+
+  template <typename T, typename = EnableIfMatchingEnum<T, ValueType>>
+  T cast() const {
+    return static_cast<T>(value);
+  }
+
+  // Converts to string using HWC2 stringification of BaseType.
+  std::string to_string() const {
+    return HWC2::to_string(static_cast<BaseType>(value));
+  }
+
+  bool operator!=(const Wrapper& other) const { return value != other.value; }
+  bool operator!=(ValueType other_value) const { return value != other_value; }
+  bool operator!=(BaseType other_value) const {
+    return static_cast<BaseType>(value) != other_value;
+  }
+  bool operator==(const Wrapper& other) const { return value == other.value; }
+  bool operator==(ValueType other_value) const { return value == other_value; }
+  bool operator==(BaseType other_value) const {
+    return static_cast<BaseType>(value) == other_value;
+  }
+
+  ValueType value;
+};
+
+struct Attribute final : public Wrapper<HWC2::Attribute> {
+  enum : ValueType {
+    Invalid = HWC2_ATTRIBUTE_INVALID,
+    Width = HWC2_ATTRIBUTE_WIDTH,
+    Height = HWC2_ATTRIBUTE_HEIGHT,
+    VsyncPeriod = HWC2_ATTRIBUTE_VSYNC_PERIOD,
+    DpiX = HWC2_ATTRIBUTE_DPI_X,
+    DpiY = HWC2_ATTRIBUTE_DPI_Y,
+  };
+
+  Attribute() : Base(Invalid) {}
+  using Base::Base;
+};
+
+struct BlendMode final : public Wrapper<HWC2::BlendMode> {
+  enum : ValueType {
+    Invalid = HWC2_BLEND_MODE_INVALID,
+    None = HWC2_BLEND_MODE_NONE,
+    Premultiplied = HWC2_BLEND_MODE_PREMULTIPLIED,
+    Coverage = HWC2_BLEND_MODE_COVERAGE,
+  };
+
+  BlendMode() : Base(Invalid) {}
+  using Base::Base;
+};
+
+struct Composition final : public Wrapper<HWC2::Composition> {
+  enum : ValueType {
+    Invalid = HWC2_COMPOSITION_INVALID,
+    Client = HWC2_COMPOSITION_CLIENT,
+    Device = HWC2_COMPOSITION_DEVICE,
+    SolidColor = HWC2_COMPOSITION_SOLID_COLOR,
+    Cursor = HWC2_COMPOSITION_CURSOR,
+    Sideband = HWC2_COMPOSITION_SIDEBAND,
+  };
+
+  Composition() : Base(Invalid) {}
+  using Base::Base;
+};
+
+struct DisplayType final : public Wrapper<HWC2::DisplayType> {
+  enum : ValueType {
+    Invalid = HWC2_DISPLAY_TYPE_INVALID,
+    Physical = HWC2_DISPLAY_TYPE_PHYSICAL,
+    Virtual = HWC2_DISPLAY_TYPE_VIRTUAL,
+  };
+
+  DisplayType() : Base(Invalid) {}
+  using Base::Base;
+};
+
+struct Error final : public Wrapper<HWC2::Error> {
+  enum : ValueType {
+    None = HWC2_ERROR_NONE,
+    BadConfig = HWC2_ERROR_BAD_CONFIG,
+    BadDisplay = HWC2_ERROR_BAD_DISPLAY,
+    BadLayer = HWC2_ERROR_BAD_LAYER,
+    BadParameter = HWC2_ERROR_BAD_PARAMETER,
+    HasChanges = HWC2_ERROR_HAS_CHANGES,
+    NoResources = HWC2_ERROR_NO_RESOURCES,
+    NotValidated = HWC2_ERROR_NOT_VALIDATED,
+    Unsupported = HWC2_ERROR_UNSUPPORTED,
+  };
+
+  Error() : Base(None) {}
+  using Base::Base;
+};
+
+struct LayerRequest final : public Wrapper<HWC2::LayerRequest> {
+  enum : ValueType {
+    ClearClientTarget = HWC2_LAYER_REQUEST_CLEAR_CLIENT_TARGET,
+  };
+
+  LayerRequest() : Base(0) {}
+  using Base::Base;
+};
+
+struct PowerMode final : public Wrapper<HWC2::PowerMode> {
+  enum : ValueType {
+    Off = HWC2_POWER_MODE_OFF,
+    DozeSuspend = HWC2_POWER_MODE_DOZE_SUSPEND,
+    Doze = HWC2_POWER_MODE_DOZE,
+    On = HWC2_POWER_MODE_ON,
+  };
+
+  PowerMode() : Base(Off) {}
+  using Base::Base;
+};
+
+struct Transform final : public Wrapper<HWC2::Transform> {
+  enum : ValueType {
+    None = 0,
+    FlipH = HWC_TRANSFORM_FLIP_H,
+    FlipV = HWC_TRANSFORM_FLIP_V,
+    Rotate90 = HWC_TRANSFORM_ROT_90,
+    Rotate180 = HWC_TRANSFORM_ROT_180,
+    Rotate270 = HWC_TRANSFORM_ROT_270,
+    FlipHRotate90 = HWC_TRANSFORM_FLIP_H_ROT_90,
+    FlipVRotate90 = HWC_TRANSFORM_FLIP_V_ROT_90,
+  };
+
+  Transform() : Base(None) {}
+  using Base::Base;
+};
+
+struct Vsync final : public Wrapper<HWC2::Vsync> {
+  enum : ValueType {
+    Invalid = HWC2_VSYNC_INVALID,
+    Enable = HWC2_VSYNC_ENABLE,
+    Disable = HWC2_VSYNC_DISABLE,
+  };
+
+  Vsync() : Base(Invalid) {}
+  using Base::Base;
+};
+
+// Utility color type.
+struct Color final {
+  Color(const Color&) = default;
+  Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a) : r(r), g(g), b(b), a(a) {}
+  Color(hwc_color_t color) : r(color.r), g(color.g), b(color.b), a(color.a) {}
+
+  operator hwc_color_t() const { return {r, g, b, a}; }
+
+  uint8_t r __attribute__((aligned(1)));
+  uint8_t g __attribute__((aligned(1)));
+  uint8_t b __attribute__((aligned(1)));
+  uint8_t a __attribute__((aligned(1)));
+};
+
+// Utility rectangle type.
+struct Rect final {
+  // TODO(eieio): Implicit conversion to/from Android rect types.
+
+  int32_t left __attribute__((aligned(4)));
+  int32_t top __attribute__((aligned(4)));
+  int32_t right __attribute__((aligned(4)));
+  int32_t bottom __attribute__((aligned(4)));
+};
+
+}  // namespace HWC
+
+#endif  // ANDROID_LIBVRFLINGER_HWCTYPES_H
diff --git a/libs/vr/libvrflinger/screenshot_service.cpp b/libs/vr/libvrflinger/screenshot_service.cpp
deleted file mode 100644 (file)
index d14d588..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-#include "screenshot_service.h"
-
-#include <utils/Trace.h>
-
-#include <pdx/default_transport/service_endpoint.h>
-#include <private/android_filesystem_config.h>
-#include <private/dvr/display_types.h>
-#include <private/dvr/trusted_uids.h>
-
-using android::pdx::Message;
-using android::pdx::MessageInfo;
-using android::pdx::default_transport::Endpoint;
-using android::pdx::rpc::DispatchRemoteMethod;
-using android::pdx::rpc::RemoteMethodError;
-using android::pdx::rpc::RemoteMethodReturn;
-
-namespace android {
-namespace dvr {
-
-ScreenshotService::~ScreenshotService() { instance_ = nullptr; }
-
-pdx::Status<void> ScreenshotService::HandleMessage(pdx::Message& message) {
-  switch (message.GetOp()) {
-    case DisplayScreenshotRPC::GetFormat::Opcode:
-      DispatchRemoteMethod<DisplayScreenshotRPC::GetFormat>(
-          *this, &ScreenshotService::OnGetFormat, message);
-      return {};
-
-    case DisplayScreenshotRPC::TakeScreenshot::Opcode:
-      DispatchRemoteMethod<DisplayScreenshotRPC::TakeScreenshot>(
-          *this, &ScreenshotService::OnTakeScreenshot, message);
-      return {};
-
-    default:
-      return Service::HandleMessage(message);
-  }
-}
-
-int ScreenshotService::OnGetFormat(pdx::Message&) {
-  return HAL_PIXEL_FORMAT_RGB_888;
-}
-
-ScreenshotData ScreenshotService::OnTakeScreenshot(pdx::Message& message,
-                                                   int layer_index) {
-  // Also allow AID_SHELL to support vrscreencap commands.
-  if (message.GetEffectiveUserId() != AID_SHELL &&
-      !IsTrustedUid(message.GetEffectiveUserId())) {
-    REPLY_ERROR_RETURN(message, EACCES, {});
-  }
-
-  AddWaiter(std::move(message), layer_index);
-  return {};
-}
-
-void ScreenshotService::AddWaiter(pdx::Message&& message, int layer_index) {
-  std::lock_guard<std::mutex> lock(mutex_);
-  waiters_.emplace_back(std::move(message), layer_index);
-}
-
-void ScreenshotService::TakeIfNeeded(
-    std::array<Layer*, HardwareComposer::kMaxHardwareLayers>& hw_layers,
-    Compositor& compositor) {
-  std::lock_guard<std::mutex> lock(mutex_);
-
-  // Send the buffer contents to all of our waiting clients.
-  for (auto& waiter : waiters_) {
-    if (waiter.IsDone())
-      continue;
-
-    if (waiter.layer_index() == 0) {
-      ALOGE(
-          "ScreenshotService::TakeIfNeeded: Capturing the composited display "
-          "output is not yet supported.");
-
-      waiter.Error(EINVAL);
-      continue;
-    }
-
-    if (waiter.layer_index() > 0) {
-      // Check for hardware layer screenshot requests.
-      // Hardware layers are requested with positive indices starting at 1.
-      const size_t layer_index = static_cast<size_t>(waiter.layer_index() - 1);
-
-      if (layer_index >= hw_layers.size()) {
-        waiter.Error(EINVAL);
-        continue;
-      }
-
-      auto buffer = hw_layers[layer_index]->GetBuffer();
-      if (!buffer) {
-        waiter.Error(ENOBUFS);
-        continue;
-      }
-
-      auto data = compositor.ReadBufferPixels(buffer);
-      if (data.empty()) {
-        waiter.Error(ENOBUFS);
-        continue;
-      }
-
-      Take(&waiter, data.data(), buffer->width(), buffer->height(),
-           buffer->width());
-    } else {
-      // Check for compositor input layer screenshot requests.
-      // Prewarp surfaces are requested with negative indices starting at -1.
-      const size_t layer_index = static_cast<size_t>(-waiter.layer_index() - 1);
-
-      if (layer_index >= compositor.GetLayerCount()) {
-        waiter.Error(EINVAL);
-        continue;
-      }
-
-      int width = 0;
-      int height = 0;
-      auto data = compositor.ReadLayerPixels(layer_index, &width, &height);
-      if (data.empty()) {
-        waiter.Error(ENOBUFS);
-        continue;
-      }
-
-      Take(&waiter, data.data(), width, height, width);
-    }
-  }
-
-  // Reply with error to requests that did not match up with a source layer.
-  for (auto& waiter : waiters_) {
-    if (!waiter.IsDone())
-      waiter.Error(EAGAIN);
-  }
-  waiters_.clear();
-}
-
-void ScreenshotWaiter::Reply(const ScreenshotData& screenshot) {
-  ALOGI("Returning screenshot: size=%zu recv_size=%zu",
-        screenshot.buffer.size(), message_.GetReceiveLength());
-  RemoteMethodReturn<DisplayScreenshotRPC::TakeScreenshot>(message_,
-                                                           screenshot);
-}
-
-void ScreenshotWaiter::Error(int error) { RemoteMethodError(message_, error); }
-
-void ScreenshotService::Take(ScreenshotWaiter* waiter, const void* rgba_data,
-                             int32_t width, int32_t height, int buffer_stride) {
-  ATRACE_NAME(__PRETTY_FUNCTION__);
-
-  bool is_portrait = height > width;
-  if (is_portrait) {
-    std::swap(width, height);
-  }
-  int response_stride = width;
-
-  // Convert from RGBA to RGB and if in portrait, rotates to landscape; store
-  // the result in the response buffer.
-  ScreenshotData screenshot{width, height,
-                            std::vector<uint8_t>(width * height * 3)};
-
-  const auto rgba_bytes = static_cast<const uint8_t*>(rgba_data);
-  for (int j = 0; j < height; ++j) {
-    for (int i = 0; i < width; ++i) {
-      // If the screenshot is in portrait mode, rotate into landscape mode.
-      const int response_index = is_portrait
-                                     ? (height - j - 1) * response_stride + i
-                                     : j * response_stride + i;
-      const int buffer_index =
-          is_portrait ? i * buffer_stride + j : j * buffer_stride + i;
-      screenshot.buffer[response_index * 3 + 0] =
-          rgba_bytes[buffer_index * 4 + 0];
-      screenshot.buffer[response_index * 3 + 1] =
-          rgba_bytes[buffer_index * 4 + 1];
-      screenshot.buffer[response_index * 3 + 2] =
-          rgba_bytes[buffer_index * 4 + 2];
-    }
-  }
-
-  waiter->Reply(screenshot);
-}
-
-ScreenshotService::ScreenshotService()
-    : BASE("ScreenshotService",
-           Endpoint::Create(DisplayScreenshotRPC::kClientPath)) {
-  instance_ = this;
-}
-
-ScreenshotService* ScreenshotService::GetInstance() { return instance_; }
-
-ScreenshotService* ScreenshotService::instance_ = nullptr;
-
-}  // namespace dvr
-}  // namespace android
diff --git a/libs/vr/libvrflinger/screenshot_service.h b/libs/vr/libvrflinger/screenshot_service.h
deleted file mode 100644 (file)
index f59e872..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-#ifndef ANDROID_DVR_SERVICES_DISPLAYD_SCREENSHOT_SERVICE_H_
-#define ANDROID_DVR_SERVICES_DISPLAYD_SCREENSHOT_SERVICE_H_
-
-#include <pdx/rpc/pointer_wrapper.h>
-#include <pdx/service.h>
-#include <private/dvr/ion_buffer.h>
-
-#include <mutex>
-#include <vector>
-
-#include "hardware_composer.h"
-
-namespace android {
-namespace dvr {
-
-class ScreenshotWaiter {
- public:
-  explicit ScreenshotWaiter(pdx::Message&& message, int layer_index)
-      : message_(std::move(message)), layer_index_(layer_index) {}
-  ScreenshotWaiter(ScreenshotWaiter&&) = default;
-
-  void Reply(const ScreenshotData& screenshot);
-  void Error(int error);
-
-  bool IsDone() const { return message_.replied(); }
-  int layer_index() const { return layer_index_; }
-
- private:
-  pdx::Message message_;
-  int layer_index_;
-
-  ScreenshotWaiter(const ScreenshotWaiter&) = delete;
-  void operator=(const ScreenshotWaiter&) = delete;
-};
-
-// The screenshot service allows clients to obtain screenshots from displayd.
-class ScreenshotService : public pdx::ServiceBase<ScreenshotService> {
- public:
-  ~ScreenshotService();
-
-  pdx::Status<void> HandleMessage(pdx::Message& message) override;
-
-  // Returns true if there is a pending screenshot request.
-  bool IsScreenshotRequestPending() const {
-    std::lock_guard<std::mutex> lock(mutex_);
-    return !waiters_.empty();
-  }
-
-  // If any clients are currently waiting for a screenshot, read back the
-  // contents of requested layers and send the resulting
-  // image to the clients.
-  void TakeIfNeeded(
-      std::array<Layer*, HardwareComposer::kMaxHardwareLayers>& hw_layers,
-      Compositor& compositor);
-
-  static ScreenshotService* GetInstance();
-
- private:
-  friend BASE;
-
-  ScreenshotService();
-
-  void AddWaiter(pdx::Message&& message, int layer_index);
-
-  ScreenshotData OnTakeScreenshot(pdx::Message& message, int index);
-  int OnGetFormat(pdx::Message& message);
-
-  // Copy the given screenshot data into the message reply.
-  void Take(ScreenshotWaiter* waiter, const void* rgba_data, int32_t width,
-            int32_t height, int buffer_stride);
-
-  static ScreenshotService* instance_;
-
-  // Protects access to subsequent member variables.
-  mutable std::mutex mutex_;
-  std::vector<ScreenshotWaiter> waiters_;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_SERVICES_DISPLAYD_SCREENSHOT_SERVICE_H_
diff --git a/libs/vr/libvrflinger/surface_channel.cpp b/libs/vr/libvrflinger/surface_channel.cpp
deleted file mode 100644 (file)
index 263b382..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-#include "surface_channel.h"
-
-using android::pdx::BorrowedChannelHandle;
-using android::pdx::Message;
-using android::pdx::rpc::DispatchRemoteMethod;
-
-namespace android {
-namespace dvr {
-
-pdx::Status<void> SurfaceChannel::HandleMessage(Message& message) {
-  switch (message.GetOp()) {
-    case DisplayRPC::GetMetadataBuffer::Opcode:
-      DispatchRemoteMethod<DisplayRPC::GetMetadataBuffer>(
-          *this, &SurfaceChannel::OnGetMetadataBuffer, message);
-      break;
-  }
-
-  return {};
-}
-
-BorrowedChannelHandle SurfaceChannel::OnGetMetadataBuffer(Message& message) {
-  if (EnsureMetadataBuffer()) {
-    return metadata_buffer_->GetChannelHandle().Borrow();
-  } else {
-    REPLY_ERROR_RETURN(message, -ENOMEM, {});
-  }
-}
-
-bool SurfaceChannel::EnsureMetadataBuffer() {
-  if (!metadata_buffer_) {
-    metadata_buffer_ =
-        BufferProducer::CreateUncachedBlob(metadata_size());
-    if (!metadata_buffer_) {
-      ALOGE(
-          "DisplaySurface::EnsureMetadataBuffer: could not allocate metadata "
-          "buffer");
-      return false;
-    }
-  }
-  return true;
-}
-
-}  // namespace dvr
-}  // namespace android
diff --git a/libs/vr/libvrflinger/surface_channel.h b/libs/vr/libvrflinger/surface_channel.h
deleted file mode 100644 (file)
index 9dcac3f..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef ANDROID_DVR_SERVICES_DISPLAYD_SURFACE_CHANNEL_H_
-#define ANDROID_DVR_SERVICES_DISPLAYD_SURFACE_CHANNEL_H_
-
-#include <pdx/service.h>
-#include <private/dvr/buffer_hub_client.h>
-#include <private/dvr/display_protocol.h>
-
-namespace android {
-namespace dvr {
-
-class DisplayService;
-
-class SurfaceChannel : public pdx::Channel {
- public:
-  SurfaceChannel(DisplayService* service, int channel_id, SurfaceType type,
-                 size_t metadata_size)
-      : service_(service),
-        surface_id_(channel_id),
-        type_(type),
-        metadata_size_(metadata_size) {}
-
-  ~SurfaceChannel() override = default;
-
-  DisplayService* service() const { return service_; }
-  int surface_id() const { return surface_id_; }
-  SurfaceType type() const { return type_; }
-  size_t metadata_size() const { return metadata_size_; }
-
-  pdx::LocalHandle GetMetadataBufferFd() {
-    return EnsureMetadataBuffer() ? metadata_buffer_->GetBlobFd()
-                                  : pdx::LocalHandle{};
-  }
-
-  // Dispatches surface channel messages to the appropriate handlers. This
-  // handler runs on the displayd message dispatch thread.
-  virtual pdx::Status<void> HandleMessage(pdx::Message& message);
-
- protected:
-  // Contains the surface metadata.
-  std::shared_ptr<BufferProducer> metadata_buffer_;
-
-  // Returns the metadata buffer for this surface. The first call allocates the
-  // buffer, while subsequent calls return the same buffer.
-  pdx::BorrowedChannelHandle OnGetMetadataBuffer(pdx::Message& message);
-
-  // Allocates the single metadata buffer for this surface unless it is already
-  // allocated. Idempotent when called multiple times.
-  bool EnsureMetadataBuffer();
-
- private:
-  DisplayService* service_;
-  int surface_id_;
-  SurfaceType type_;
-  size_t metadata_size_;
-
-  SurfaceChannel(const SurfaceChannel&) = delete;
-  void operator=(const SurfaceChannel&) = delete;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_SERVICES_DISPLAYD_SURFACE_CHANNEL_H_
diff --git a/libs/vr/libvrflinger/video_compositor.cpp b/libs/vr/libvrflinger/video_compositor.cpp
deleted file mode 100644 (file)
index e42caaa..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-#include "video_compositor.h"
-
-#include <EGL/eglext.h>
-#include <GLES2/gl2ext.h>
-
-#include <private/dvr/debug.h>
-#include <private/dvr/display_protocol.h>
-
-namespace android {
-namespace dvr {
-
-VideoCompositor::Texture::Texture(
-    EGLDisplay display, const std::shared_ptr<BufferConsumer>& buffer_consumer)
-    : display_(display),
-      image_(EGL_NO_IMAGE_KHR),
-      texture_id_(0),
-      buffer_consumer_(buffer_consumer) {}
-
-VideoCompositor::Texture::~Texture() {
-  if (image_ != EGL_NO_IMAGE_KHR)
-    eglDestroyImageKHR(display_, image_);
-  if (texture_id_ != 0)
-    glDeleteTextures(1, &texture_id_);
-}
-
-GLuint VideoCompositor::Texture::EnsureTextureReady() {
-  if (!image_) {
-    native_buffer_ = new NativeBuffer(buffer_consumer_);
-    CHECK_GL();
-
-    image_ = eglCreateImageKHR(
-        display_, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
-        static_cast<ANativeWindowBuffer*>(native_buffer_.get()), nullptr);
-    if (!image_) {
-      ALOGE("Failed to create EGLImage.");
-      return 0;
-    }
-
-    glGenTextures(1, &texture_id_);
-    glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id_);
-    glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image_);
-    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S,
-                    GL_CLAMP_TO_EDGE);
-    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T,
-                    GL_CLAMP_TO_EDGE);
-    CHECK_GL();
-  }
-
-  return texture_id_;
-}
-
-void VideoCompositor::Texture::Release() {
-  const int ret = buffer_consumer_->Release({});
-  if (ret < 0) {
-    ALOGE(
-        "VideoCompositor::Texture::Release: Failed to release buffer, error: "
-        "%s",
-        strerror(-ret));
-  }
-}
-
-VideoCompositor::VideoCompositor(
-    const std::shared_ptr<VideoMeshSurface>& surface,
-    const volatile DisplaySurfaceMetadata* display_surface_metadata)
-    : surface_(surface),
-      consumer_queue_(surface->GetConsumerQueue()),
-      transform_metadata_(display_surface_metadata),
-      active_texture_slot_(-1) {}
-
-GLuint VideoCompositor::GetActiveTextureId(EGLDisplay display) {
-  size_t slot;
-  BufferHubQueueCore::NativeBufferMetadata metadata;
-
-  while (true) {
-    // A native way to pick the active texture: always dequeue all buffers from
-    // the queue until it's empty. This works well as long as video frames are
-    // queued in order from the producer side.
-    // TODO(jwcai) Use |metadata.timestamp_ns| to schedule video frames
-    // accurately.
-    LocalHandle acquire_fence;
-    auto buffer_consumer =
-        consumer_queue_->Dequeue(0, &slot, &metadata, &acquire_fence);
-
-    if (buffer_consumer) {
-      // Create a new texture if it hasn't been created yet, or the same slot
-      // has a new |buffer_consumer|.
-      if (textures_[slot] == nullptr ||
-          textures_[slot]->event_fd() != buffer_consumer->event_fd()) {
-        textures_[slot] =
-            std::unique_ptr<Texture>(new Texture(display, buffer_consumer));
-      }
-
-      if (active_texture_slot_ != static_cast<int>(slot)) {
-        if (active_texture_slot_ >= 0) {
-          // Release the last active texture and move on to use the new one.
-          textures_[active_texture_slot_]->Release();
-        }
-        active_texture_slot_ = slot;
-      }
-    } else {
-      break;
-    }
-  }
-
-  if (active_texture_slot_ < 0) {
-    // No texture is active yet.
-    return 0;
-  }
-
-  return textures_[active_texture_slot_]->EnsureTextureReady();
-}
-
-mat4 VideoCompositor::GetTransform(int eye, size_t render_buffer_index) {
-  volatile const VideoMeshSurfaceMetadata* transform_metadata =
-      surface_->GetMetadataBufferPtr();
-
-  mat4 screen_transform;
-  for (int i = 0; i < 4; ++i) {
-    for (int j = 0; j < 4; ++j) {
-      screen_transform(i, j) =
-          transform_metadata->transform[render_buffer_index][eye].val[i][j];
-    }
-  }
-
-  return screen_transform;
-}
-
-}  // namespace dvr
-}  // namespace android
diff --git a/libs/vr/libvrflinger/video_compositor.h b/libs/vr/libvrflinger/video_compositor.h
deleted file mode 100644 (file)
index d0e72e1..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-#ifndef ANDROID_DVR_SERVICES_DISPLAYD_VIDEO_COMPOSITOR_H_
-#define ANDROID_DVR_SERVICES_DISPLAYD_VIDEO_COMPOSITOR_H_
-
-#include <EGL/egl.h>
-#include <GLES2/gl2.h>
-#include <private/dvr/buffer_hub_queue_core.h>
-#include <private/dvr/types.h>
-
-#include <vector>
-
-#include "display_surface.h"
-#include "video_mesh_surface.h"
-
-namespace android {
-namespace dvr {
-
-using pdx::LocalHandle;
-
-// Manages video buffer consumers, texture mapping, and playback timing.
-class VideoCompositor {
- public:
-  VideoCompositor(
-      const std::shared_ptr<VideoMeshSurface>& surface,
-      const volatile DisplaySurfaceMetadata* display_surface_metadata);
-
-  int surface_id() const { return surface_ ? surface_->surface_id() : -1; }
-
-  // Returns a GL texture id that should be composited by displayd during the
-  // current rendering loop. Note that this function must be called in
-  // displayd's GL context.
-  GLuint GetActiveTextureId(EGLDisplay display);
-
-  // Returns a basic video mesh tranform.
-  mat4 GetTransform(int eye, size_t render_buffer_index);
-
- private:
-  class Texture {
-   public:
-    Texture(EGLDisplay display,
-            const std::shared_ptr<BufferConsumer>& buffer_consumer);
-    ~Texture();
-
-    // Returns the |event_fd| of the underlying buffer consumer. Caller can use
-    // this to decided whether the Texture need to be recreated for a different
-    // buffer consumer.
-    int event_fd() const { return buffer_consumer_->event_fd(); }
-
-    // Method to map a dvr::BufferConsumer to a GL texture within the current GL
-    // context. If the current Texture object's |image_| hasn't been
-    // initialized, the method will do so based on the |buffer_consumer| and a
-    // new GL texture will be generated, cached, and returned. Otherwise, the
-    // cached |texture_id_| will be returned directly.
-    GLuint EnsureTextureReady();
-
-    // Signal bufferhub that the texture is done rendering so that the buffer
-    // can be re-gained by the producer for future use.
-    void Release();
-
-   private:
-    using NativeBuffer = BufferHubQueueCore::NativeBuffer;
-
-    EGLDisplay display_;
-    EGLImageKHR image_;
-    GLuint texture_id_;
-    sp<NativeBuffer> native_buffer_;
-    std::shared_ptr<BufferConsumer> buffer_consumer_;
-  };
-
-  std::shared_ptr<VideoMeshSurface> surface_;
-  std::shared_ptr<ConsumerQueue> consumer_queue_;
-  std::array<std::unique_ptr<Texture>, BufferHubQueue::kMaxQueueCapacity>
-      textures_;
-
-  const volatile DisplaySurfaceMetadata* transform_metadata_;
-  int active_texture_slot_;
-
-  VideoCompositor(const VideoCompositor&) = delete;
-  void operator=(const VideoCompositor&) = delete;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_SERVICES_DISPLAYD_VIDEO_COMPOSITOR_H_
diff --git a/libs/vr/libvrflinger/video_mesh_surface.cpp b/libs/vr/libvrflinger/video_mesh_surface.cpp
deleted file mode 100644 (file)
index 76dd94f..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-#include "video_mesh_surface.h"
-
-#include <private/dvr/buffer_hub_queue_core.h>
-#include <private/dvr/display_protocol.h>
-
-using android::pdx::LocalChannelHandle;
-using android::pdx::rpc::DispatchRemoteMethod;
-
-namespace android {
-namespace dvr {
-
-VideoMeshSurface::VideoMeshSurface(DisplayService* service, int surface_id)
-    : SurfaceChannel(service, surface_id, SurfaceTypeEnum::VideoMesh,
-                     sizeof(VideoMeshSurfaceMetadata)) {}
-
-VideoMeshSurface::~VideoMeshSurface() {}
-
-pdx::Status<void> VideoMeshSurface::HandleMessage(Message& message) {
-  ATRACE_NAME("VideoMeshSurface::HandleMessage");
-
-  switch (message.GetOp()) {
-    case DisplayRPC::VideoMeshSurfaceCreateProducerQueue::Opcode:
-      DispatchRemoteMethod<DisplayRPC::VideoMeshSurfaceCreateProducerQueue>(
-          *this, &VideoMeshSurface::OnCreateProducerQueue, message);
-      break;
-
-    default:
-      return SurfaceChannel::HandleMessage(message);
-  }
-
-  return {};
-}
-
-std::shared_ptr<ConsumerQueue> VideoMeshSurface::GetConsumerQueue() {
-  if (!consumer_queue_) {
-    ALOGE(
-        "VideoMeshSurface::GetConsumerQueue: consumer_queue is uninitialized.");
-  }
-
-  return consumer_queue_;
-}
-
-LocalChannelHandle VideoMeshSurface::OnCreateProducerQueue(Message& message) {
-  ATRACE_NAME("VideoMeshSurface::OnCreateProducerQueue");
-
-  if (consumer_queue_ != nullptr) {
-    ALOGE(
-        "VideoMeshSurface::OnCreateProducerQueue: A ProdcuerQueue has already "
-        "been created and transported to VideoMeshSurfaceClient.");
-    REPLY_ERROR_RETURN(message, EALREADY, {});
-  }
-
-  auto producer =
-      ProducerQueue::Create<BufferHubQueueCore::NativeBufferMetadata>();
-  consumer_queue_ = producer->CreateConsumerQueue();
-
-  return std::move(producer->GetChannelHandle());
-}
-
-}  // namespace dvr
-}  // namespace android
diff --git a/libs/vr/libvrflinger/video_mesh_surface.h b/libs/vr/libvrflinger/video_mesh_surface.h
deleted file mode 100644 (file)
index 2c9f3e8..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef ANDROID_DVR_SERVICES_DISPLAYD_VIDEO_MESH_SURFACE_H_
-#define ANDROID_DVR_SERVICES_DISPLAYD_VIDEO_MESH_SURFACE_H_
-
-#include <private/dvr/buffer_hub_queue_client.h>
-
-#include "surface_channel.h"
-
-namespace android {
-namespace dvr {
-
-class DisplayService;
-
-// VideoMeshSurface takes three inputs: 1) buffers filled by Android system
-// components (e.g. MediaCodec or camera stack) other than applications' GL
-// context; 2) a 3D mesh chosen by application to define the shape of the
-// surface; 3) a transformation matrix from application to define the rotation,
-// position, and scaling of the video surface.
-class VideoMeshSurface : public SurfaceChannel {
- public:
-  using Message = pdx::Message;
-  using LocalChannelHandle = pdx::LocalChannelHandle;
-
-  VideoMeshSurface(DisplayService* service, int channel_id);
-  ~VideoMeshSurface() override;
-
-  volatile const VideoMeshSurfaceMetadata* GetMetadataBufferPtr() {
-    if (EnsureMetadataBuffer()) {
-      void* addr = nullptr;
-      metadata_buffer_->GetBlobReadWritePointer(metadata_size(), &addr);
-      return static_cast<const volatile VideoMeshSurfaceMetadata*>(addr);
-    } else {
-      return nullptr;
-    }
-  }
-
-  pdx::Status<void> HandleMessage(Message& message) override;
-
-  std::shared_ptr<ConsumerQueue> GetConsumerQueue();
-
- private:
-  LocalChannelHandle OnCreateProducerQueue(Message& message);
-
-  std::shared_ptr<ConsumerQueue> consumer_queue_;
-
-  VideoMeshSurface(const VideoMeshSurface&) = delete;
-  void operator=(const VideoMeshSurface&) = delete;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_SERVICES_DISPLAYD_VIDEO_MESH_SURFACE_H_
index 21226db..b2dc1d8 100644 (file)
@@ -11,9 +11,9 @@
 
 #include <binder/IServiceManager.h>
 #include <binder/ProcessState.h>
-#include <log/log.h>
 #include <cutils/properties.h>
 #include <cutils/sched_policy.h>
+#include <log/log.h>
 #include <private/dvr/display_client.h>
 #include <sys/prctl.h>
 #include <sys/resource.h>
@@ -25,7 +25,6 @@
 #include "DisplayHardware/ComposerHal.h"
 #include "display_manager_service.h"
 #include "display_service.h"
-#include "screenshot_service.h"
 #include "vsync_service.h"
 
 namespace android {
@@ -77,11 +76,11 @@ bool VrFlinger::Init(Hwc2::Composer* hidl,
 
   request_display_callback_ = request_display_callback;
 
-  dispatcher_ =
-      android::pdx::default_transport::ServiceDispatcher::Create();
+  dispatcher_ = android::pdx::default_transport::ServiceDispatcher::Create();
   CHECK_ERROR(!dispatcher_, error, "Failed to create service dispatcher.");
 
-  display_service_ = android::dvr::DisplayService::Create(hidl);
+  display_service_ =
+      android::dvr::DisplayService::Create(hidl, request_display_callback);
   CHECK_ERROR(!display_service_, error, "Failed to create display service.");
   dispatcher_->AddService(display_service_);
 
@@ -89,10 +88,6 @@ bool VrFlinger::Init(Hwc2::Composer* hidl,
   CHECK_ERROR(!service, error, "Failed to create display manager service.");
   dispatcher_->AddService(service);
 
-  service = android::dvr::ScreenshotService::Create();
-  CHECK_ERROR(!service, error, "Failed to create screenshot service.");
-  dispatcher_->AddService(service);
-
   service = android::dvr::VSyncService::Create();
   CHECK_ERROR(!service, error, "Failed to create vsync service.");
   dispatcher_->AddService(service);
@@ -147,7 +142,9 @@ void VrFlinger::OnHardwareComposerRefresh() {
 void VrFlinger::PersistentVrStateCallback::onPersistentVrStateChanged(
     bool enabled) {
   ALOGV("Notified persistent vr mode is %s", enabled ? "on" : "off");
-  request_display_callback_(enabled);
+  // TODO(eieio): Determine the correct signal to request display control.
+  // Persistent VR mode is not enough.
+  // request_display_callback_(enabled);
 }
 
 }  // namespace dvr
index cda815c..2a83933 100644 (file)
@@ -1,17 +1,19 @@
 #include "vsync_service.h"
 
-#include <log/log.h>
 #include <hardware/hwcomposer.h>
+#include <log/log.h>
 #include <poll.h>
 #include <sys/prctl.h>
 #include <time.h>
 #include <utils/Trace.h>
 
+#include <dvr/dvr_display_types.h>
 #include <pdx/default_transport/service_endpoint.h>
 #include <private/dvr/clock_ns.h>
 #include <private/dvr/display_protocol.h>
-#include <private/dvr/display_types.h>
 
+using android::dvr::display::VSyncProtocol;
+using android::dvr::display::VSyncSchedInfo;
 using android::pdx::Channel;
 using android::pdx::Message;
 using android::pdx::MessageInfo;
@@ -22,7 +24,7 @@ namespace android {
 namespace dvr {
 
 VSyncService::VSyncService()
-    : BASE("VSyncService", Endpoint::Create(DisplayVSyncRPC::kClientPath)),
+    : BASE("VSyncService", Endpoint::Create(VSyncProtocol::kClientPath)),
       last_vsync_(0),
       current_vsync_(0),
       compositor_time_ns_(0),
@@ -109,22 +111,22 @@ void VSyncService::UpdateClients() {
 
 pdx::Status<void> VSyncService::HandleMessage(pdx::Message& message) {
   switch (message.GetOp()) {
-    case DisplayVSyncRPC::Wait::Opcode:
+    case VSyncProtocol::Wait::Opcode:
       AddWaiter(message);
       return {};
 
-    case DisplayVSyncRPC::GetLastTimestamp::Opcode:
-      DispatchRemoteMethod<DisplayVSyncRPC::GetLastTimestamp>(
+    case VSyncProtocol::GetLastTimestamp::Opcode:
+      DispatchRemoteMethod<VSyncProtocol::GetLastTimestamp>(
           *this, &VSyncService::OnGetLastTimestamp, message);
       return {};
 
-    case DisplayVSyncRPC::GetSchedInfo::Opcode:
-      DispatchRemoteMethod<DisplayVSyncRPC::GetSchedInfo>(
+    case VSyncProtocol::GetSchedInfo::Opcode:
+      DispatchRemoteMethod<VSyncProtocol::GetSchedInfo>(
           *this, &VSyncService::OnGetSchedInfo, message);
       return {};
 
-    case DisplayVSyncRPC::Acknowledge::Opcode:
-      DispatchRemoteMethod<DisplayVSyncRPC::Acknowledge>(
+    case VSyncProtocol::Acknowledge::Opcode:
+      DispatchRemoteMethod<VSyncProtocol::Acknowledge>(
           *this, &VSyncService::OnAcknowledge, message);
       return {};
 
@@ -133,16 +135,17 @@ pdx::Status<void> VSyncService::HandleMessage(pdx::Message& message) {
   }
 }
 
-int64_t VSyncService::OnGetLastTimestamp(pdx::Message& message) {
+pdx::Status<int64_t> VSyncService::OnGetLastTimestamp(pdx::Message& message) {
   auto client = std::static_pointer_cast<VSyncChannel>(message.GetChannel());
   std::lock_guard<std::mutex> autolock(mutex_);
 
   // Getting the timestamp has the side effect of ACKing.
   client->Ack();
-  return current_vsync_;
+  return {current_vsync_};
 }
 
-VSyncSchedInfo VSyncService::OnGetSchedInfo(pdx::Message& message) {
+pdx::Status<VSyncSchedInfo> VSyncService::OnGetSchedInfo(
+    pdx::Message& message) {
   auto client = std::static_pointer_cast<VSyncChannel>(message.GetChannel());
   std::lock_guard<std::mutex> autolock(mutex_);
 
@@ -176,23 +179,25 @@ VSyncSchedInfo VSyncService::OnGetSchedInfo(pdx::Message& message) {
     }
   }
 
-  return {vsync_period_ns, next_warp, next_vsync_count};
+  return {{vsync_period_ns, next_warp, next_vsync_count}};
 }
 
-int VSyncService::OnAcknowledge(pdx::Message& message) {
+pdx::Status<void> VSyncService::OnAcknowledge(pdx::Message& message) {
   auto client = std::static_pointer_cast<VSyncChannel>(message.GetChannel());
   std::lock_guard<std::mutex> autolock(mutex_);
   client->Ack();
-  return 0;
+  return {};
 }
 
 void VSyncWaiter::Notify(int64_t timestamp) {
   timestamp_ = timestamp;
-  DispatchRemoteMethod<DisplayVSyncRPC::Wait>(*this, &VSyncWaiter::OnWait,
-                                              message_);
+  DispatchRemoteMethod<VSyncProtocol::Wait>(*this, &VSyncWaiter::OnWait,
+                                            message_);
 }
 
-int64_t VSyncWaiter::OnWait(pdx::Message& /*message*/) { return timestamp_; }
+pdx::Status<int64_t> VSyncWaiter::OnWait(pdx::Message& /*message*/) {
+  return {timestamp_};
+}
 
 void VSyncChannel::Ack() {
   ALOGD_IF(TRACE, "VSyncChannel::Ack: pid=%d cid=%d\n", pid_, cid_);
index 1c86d42..215948e 100644 (file)
@@ -23,7 +23,7 @@ class VSyncWaiter {
   void Notify(int64_t timestamp);
 
  private:
-  int64_t OnWait(pdx::Message& message);
+  pdx::Status<int64_t> OnWait(pdx::Message& message);
 
   pdx::Message message_;
   int64_t timestamp_ = 0;
@@ -62,10 +62,9 @@ class VSyncService : public pdx::ServiceBase<VSyncService> {
   void OnChannelClose(pdx::Message& message,
                       const std::shared_ptr<pdx::Channel>& channel) override;
 
-  // Called by the hardware composer HAL, or similar,
-  // whenever a vsync event occurs.
-  // |compositor_time_ns| is the number of ns before the next vsync when the
-  // compositor will preempt the GPU to do EDS and lens warp.
+  // Called by the hardware composer HAL, or similar, whenever a vsync event
+  // occurs. |compositor_time_ns| is the number of ns before the next vsync when
+  // the compositor will preempt the GPU to do EDS and lens warp.
   void VSyncEvent(int display, int64_t timestamp_ns, int64_t compositor_time_ns,
                   uint32_t vsync_count);
 
@@ -74,9 +73,9 @@ class VSyncService : public pdx::ServiceBase<VSyncService> {
 
   VSyncService();
 
-  int64_t OnGetLastTimestamp(pdx::Message& message);
-  VSyncSchedInfo OnGetSchedInfo(pdx::Message& message);
-  int OnAcknowledge(pdx::Message& message);
+  pdx::Status<int64_t> OnGetLastTimestamp(pdx::Message& message);
+  pdx::Status<display::VSyncSchedInfo> OnGetSchedInfo(pdx::Message& message);
+  pdx::Status<void> OnAcknowledge(pdx::Message& message);
 
   void NotifierThreadFunction();
 
index bc4e6c5..4fb428f 100644 (file)
@@ -581,6 +581,7 @@ void SurfaceFlinger::init() {
 
     if (useVrFlinger) {
         auto vrFlingerRequestDisplayCallback = [this] (bool requestDisplay) {
+            ALOGI("VR request display mode: requestDisplay=%d", requestDisplay);
             mVrFlingerRequestsDisplay = requestDisplay;
             signalTransaction();
         };
index 1c0427d..ff6be81 100644 (file)
@@ -6,5 +6,4 @@ service surfaceflinger /system/bin/surfaceflinger
     writepid /dev/stune/foreground/tasks
     socket pdx/system/vr/display/client stream 0666 system graphics
     socket pdx/system/vr/display/manager stream 0666 system graphics
-    socket pdx/system/vr/display/screenshot stream 0660 system graphics
     socket pdx/system/vr/display/vsync stream 0666 system graphics
index 504b26f..5d51827 100644 (file)
@@ -60,24 +60,22 @@ void GetPrimaryDisplaySize(int32_t* width, int32_t* height) {
   *height = 1920;
 
   int error = 0;
-  auto display_client = DisplayClient::Create(&error);
-  SystemDisplayMetrics metrics;
-
-  if (error) {
+  auto display_client = display::DisplayClient::Create(&error);
+  if (!display_client) {
     ALOGE("Could not connect to display service : %s(%d)", strerror(error),
           error);
     return;
   }
 
-  error = display_client->GetDisplayMetrics(&metrics);
-  if (error) {
+  auto status = display_client->GetDisplayMetrics();
+  if (!status) {
     ALOGE("Could not get display metrics from display service : %s(%d)",
-          strerror(error), error);
+          status.GetErrorMessage().c_str(), status.error());
     return;
   }
 
-  *width = metrics.display_native_width;
-  *height = metrics.display_native_height;
+  *width = status.get().display_width;
+  *height = status.get().display_height;
 }
 
 }  // namespace
index 2b53cd6..abd0651 100644 (file)
@@ -196,8 +196,8 @@ void ShellView::dumpInternal(String8& result) {
   result.appendFormat("count = %zu\n", displays_.size());
   for (size_t i = 0; i < displays_.size(); ++i) {
     result.appendFormat("  display_id = %" PRId32 "\n", displays_[i]->id());
-    result.appendFormat("    size=%fx%f\n",
-                        displays_[i]->size().x(), displays_[i]->size().y());
+    result.appendFormat("    size=%fx%f\n", displays_[i]->size().x(),
+                        displays_[i]->size().y());
   }
 
   result.append("\n");
@@ -210,7 +210,7 @@ void ShellView::Set2DMode(bool mode) {
 
 void ShellView::SetRotation(int angle) {
   mat4 m(Eigen::AngleAxisf(M_PI * -0.5f * angle, vec3::UnitZ()));
-  for (auto& d: displays_)
+  for (auto& d : displays_)
     d->set_rotation(m);
 }
 
@@ -300,7 +300,7 @@ base::unique_fd ShellView::OnFrame(std::unique_ptr<HwcCallback::Frame> frame) {
   // Do this on demand in case vr_flinger crashed and we are reconnecting.
   if (!display_client_.get()) {
     int error = 0;
-    display_client_ = DisplayClient::Create(&error);
+    display_client_ = display::DisplayClient::Create(&error);
 
     if (error) {
       ALOGE("Could not connect to display service : %s(%d)", strerror(error),
@@ -310,7 +310,13 @@ base::unique_fd ShellView::OnFrame(std::unique_ptr<HwcCallback::Frame> frame) {
   }
 
   // TODO(achaulk): change when moved into vrcore.
-  bool vr_running = display_client_->IsVrAppRunning();
+  auto status = display_client_->IsVrAppRunning();
+  if (!status) {
+    ALOGE("Failed to check VR running status: %s",
+          status.GetErrorMessage().c_str());
+    return base::unique_fd();
+  }
+  const bool vr_running = status.get();
 
   base::unique_fd fd(
       display->OnFrame(std::move(frame), debug_mode_, vr_running, &showing));
@@ -488,8 +494,8 @@ void ShellView::Touch() {
   // Device is portrait, but in landscape when in VR.
   // Rotate touch input appropriately.
   const android::status_t status = dvrVirtualTouchpadTouch(
-      virtual_touchpad_.get(), active_display_->touchpad_id(),
-      x, y, is_touching_ ? 1.0f : 0.0f);
+      virtual_touchpad_.get(), active_display_->touchpad_id(), x, y,
+      is_touching_ ? 1.0f : 0.0f);
   if (status != OK) {
     ALOGE("touch failed: %d", status);
   }
index d90e833..9b51600 100644 (file)
@@ -68,7 +68,7 @@ class ShellView : public Application,
   std::unique_ptr<SurfaceFlingerView> surface_flinger_view_;
   std::unique_ptr<Reticle> reticle_;
 
-  std::unique_ptr<DisplayClient> display_client_;
+  std::unique_ptr<display::DisplayClient> display_client_;
 
   struct DvrVirtualTouchpadDeleter {
     void operator()(DvrVirtualTouchpad* p) {