Add basic dvrSurface C API

Test: Build and flash system
Bug: 36563654
Change-Id: Id6c79d33d80e719b1d1d7f43aec99aadfad40c03
diff --git a/libs/vr/libdvr/dvr_api.cpp b/libs/vr/libdvr/dvr_api.cpp
index 4dd49da..5aa9652 100644
--- a/libs/vr/libdvr/dvr_api.cpp
+++ b/libs/vr/libdvr/dvr_api.cpp
@@ -77,6 +77,8 @@
 
     // dvr_surface.h
     dvr_api->get_pose_buffer_ = dvrGetPoseBuffer;
+    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;
diff --git a/libs/vr/libdvr/dvr_surface.cpp b/libs/vr/libdvr/dvr_surface.cpp
index 2abbe63..a3cbba5 100644
--- a/libs/vr/libdvr/dvr_surface.cpp
+++ b/libs/vr/libdvr/dvr_surface.cpp
@@ -4,8 +4,60 @@
 
 using namespace android;
 
+struct DvrSurface {
+  std::unique_ptr<dvr::DisplaySurfaceClient> display_surface_;
+};
+
 extern "C" {
 
+int dvrSurfaceCreate(int width, int height, int format, uint64_t usage0,
+                     uint64_t usage1, int flags, DvrSurface** out_surface) {
+  if (out_surface == nullptr) {
+    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;
+  }
+
+  // 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);
+
+  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) {
+  if (surface == nullptr || out_writer == nullptr) {
+    ALOGE(
+        "dvrSurfaceGetWriteBufferQueue: 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;
+  }
+
+  *out_writer = buffer_writer;
+  return 0;
+}
+
 int dvrGetPoseBuffer(DvrReadBuffer** pose_buffer) {
   auto client = android::dvr::DisplayClient::Create();
   if (!client) {
diff --git a/libs/vr/libdvr/include/dvr/dvr_api.h b/libs/vr/libdvr/include/dvr/dvr_api.h
index 504a046..bee4d66 100644
--- a/libs/vr/libdvr/include/dvr/dvr_api.h
+++ b/libs/vr/libdvr/include/dvr/dvr_api.h
@@ -33,6 +33,8 @@
 typedef struct DvrWriteBufferQueue DvrWriteBufferQueue;
 typedef struct DvrReadBufferQueue DvrReadBufferQueue;
 
+typedef struct DvrSurface DvrSurface;
+
 // display_manager_client.h
 typedef int (*DvrDisplayManagerClientGetSurfaceListPtr)(
     DvrDisplayManagerClient* client,
@@ -107,6 +109,11 @@
 
 // dvr_surface.h
 typedef int (*DvrGetPoseBufferPtr)(DvrReadBuffer** pose_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);
 
 // vsync_client_api.h
 typedef dvr_vsync_client* (*DvrVSyncClientCreatePtr)();
@@ -196,6 +203,8 @@
 
   // Display surface
   DvrGetPoseBufferPtr get_pose_buffer_;
+  DvrSurfaceCreatePtr surface_create_;
+  DvrSurfaceGetWriteBufferQueuePtr surface_get_write_buffer_queue_;
 
   // Pose client
   DvrPoseClientCreatePtr pose_client_create_;
diff --git a/libs/vr/libdvr/include/dvr/dvr_surface.h b/libs/vr/libdvr/include/dvr/dvr_surface.h
index fa8d228..2712f24 100644
--- a/libs/vr/libdvr/include/dvr/dvr_surface.h
+++ b/libs/vr/libdvr/include/dvr/dvr_surface.h
@@ -2,14 +2,25 @@
 #define ANDROID_DVR_SURFACE_H_
 
 #include <dvr/dvr_buffer.h>
+#include <dvr/dvr_buffer_queue.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+typedef struct DvrSurface DvrSurface;
+typedef struct DvrSurfaceParameter DvrSurfaceParameter;
+
 // Get a pointer to the global pose buffer.
 int dvrGetPoseBuffer(DvrReadBuffer** pose_buffer);
 
+int dvrSurfaceCreate(int width, int height, int format, uint64_t usage0,
+                     uint64_t usage1, int flags, DvrSurface** out_surface);
+
+// TODO(eieio, jwcai) Change this once we have multiple buffer queue support.
+int dvrSurfaceGetWriteBufferQueue(DvrSurface* surface,
+                                  DvrWriteBufferQueue** out_writer);
+
 #ifdef __cplusplus
 }  // extern "C"
 #endif