hwc2: add client target support
am: 7b213359e6

Change-Id: I6e3ce656f40172bfd8d0459739fa4fe763cecffb
diff --git a/hwc2/hwc2.cpp b/hwc2/hwc2.cpp
index 041e772..2864d34 100644
--- a/hwc2/hwc2.cpp
+++ b/hwc2/hwc2.cpp
@@ -111,11 +111,13 @@
             out_layers, out_types);
 }
 
-hwc2_error_t get_client_target_support(hwc2_device_t* /*device*/,
-        hwc2_display_t /*display*/, uint32_t /*width*/, uint32_t /*height*/,
-        android_pixel_format_t /*format*/, android_dataspace_t /*dataspace*/)
+hwc2_error_t get_client_target_support(hwc2_device_t *device,
+        hwc2_display_t display, uint32_t width, uint32_t height,
+        android_pixel_format_t format, android_dataspace_t dataspace)
 {
-    return HWC2_ERROR_NONE;
+    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
+    return dev->get_client_target_support(display, width, height, format,
+            dataspace);
 }
 
 hwc2_error_t get_color_modes(hwc2_device_t* /*device*/,
@@ -199,12 +201,13 @@
     return dev->set_active_config(display, config);
 }
 
-hwc2_error_t set_client_target(hwc2_device_t* /*device*/,
-        hwc2_display_t /*display*/, buffer_handle_t /*target*/,
-        int32_t /*acquire_fence*/, android_dataspace_t /*dataspace*/,
-        hwc_region_t /*damage*/)
+hwc2_error_t set_client_target(hwc2_device_t *device, hwc2_display_t display,
+        buffer_handle_t target, int32_t acquire_fence,
+        android_dataspace_t dataspace, hwc_region_t damage)
 {
-    return HWC2_ERROR_NONE;
+    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
+    return dev->set_client_target(display, target, acquire_fence, dataspace,
+            damage);
 }
 
 hwc2_error_t set_color_mode(hwc2_device_t* /*device*/,
diff --git a/hwc2/hwc2.h b/hwc2/hwc2.h
index 27e894b..8ca3507 100644
--- a/hwc2/hwc2.h
+++ b/hwc2/hwc2.h
@@ -406,6 +406,14 @@
     hwc2_error_t set_active_config(struct adf_hwc_helper *adf_helper,
                     hwc2_config_t config);
 
+    /* Client target functions */
+    hwc2_error_t get_client_target_support(uint32_t width, uint32_t height,
+                    android_pixel_format_t format,
+                    android_dataspace_t dataspace);
+    hwc2_error_t set_client_target(buffer_handle_t target,
+                    int32_t acquire_fence, android_dataspace_t dataspace,
+                    const hwc_region_t &surface_damage);
+
     /* Set layer functions */
     hwc2_error_t create_layer(hwc2_layer_t *out_layer);
     hwc2_error_t destroy_layer(hwc2_layer_t lyr_id);
@@ -470,6 +478,9 @@
     /* The display windows */
     std::array<hwc2_window, HWC2_WINDOW_COUNT> windows;
 
+    /* Recieves the output of the client composition */
+    hwc2_buffer client_target;
+
     /* The layers currently in use */
     std::unordered_map<hwc2_layer_t, hwc2_layer> layers;
 
@@ -538,6 +549,16 @@
                     hwc2_config_t *out_config) const;
     hwc2_error_t set_active_config(hwc2_display_t dpy_id, hwc2_config_t config);
 
+    /* Client target functions */
+    hwc2_error_t get_client_target_support(hwc2_display_t dpy_id,
+                    uint32_t width, uint32_t height,
+                    android_pixel_format_t format,
+                    android_dataspace_t dataspace);
+    hwc2_error_t set_client_target(hwc2_display_t dpy_id,
+                    buffer_handle_t target, int32_t acquire_fence,
+                    android_dataspace_t dataspace,
+                    const hwc_region_t &surface_damage);
+
     /* Layer functions */
     hwc2_error_t create_layer(hwc2_display_t dpy_id, hwc2_layer_t *out_layer);
     hwc2_error_t destroy_layer(hwc2_display_t dpy_id, hwc2_layer_t lyr_id);
diff --git a/hwc2/hwc2_dev.cpp b/hwc2/hwc2_dev.cpp
index 57e0d3a..9af6a56 100644
--- a/hwc2/hwc2_dev.cpp
+++ b/hwc2/hwc2_dev.cpp
@@ -210,6 +210,34 @@
     return it->second.set_active_config(adf_helper, config);
 }
 
+hwc2_error_t hwc2_dev::get_client_target_support(hwc2_display_t dpy_id,
+        uint32_t width, uint32_t height, android_pixel_format_t format,
+        android_dataspace_t dataspace)
+{
+    auto it = displays.find(dpy_id);
+    if (it == displays.end()) {
+        ALOGE("dpy %" PRIu64 ": invalid display handle", dpy_id);
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+
+    return it->second.get_client_target_support(width, height, format,
+            dataspace);
+}
+
+hwc2_error_t hwc2_dev::set_client_target(hwc2_display_t dpy_id,
+        buffer_handle_t target, int32_t acquire_fence,
+        android_dataspace_t dataspace, const hwc_region_t &surface_damage)
+{
+    auto it = displays.find(dpy_id);
+    if (it == displays.end()) {
+        ALOGE("dpy %" PRIu64 ": invalid display handle", dpy_id);
+        return HWC2_ERROR_BAD_DISPLAY;
+    }
+
+    return it->second.set_client_target(target, acquire_fence, dataspace,
+            surface_damage);
+}
+
 hwc2_error_t hwc2_dev::create_layer(hwc2_display_t dpy_id, hwc2_layer_t *out_layer)
 {
     auto it = displays.find(dpy_id);
diff --git a/hwc2/hwc2_display.cpp b/hwc2/hwc2_display.cpp
index 1fc08e1..ff3fba6 100644
--- a/hwc2/hwc2_display.cpp
+++ b/hwc2/hwc2_display.cpp
@@ -35,6 +35,7 @@
       display_state(modified),
       client_target_used(false),
       windows(),
+      client_target(),
       layers(),
       vsync_enabled(HWC2_VSYNC_DISABLE),
       changed_comp_types(),
@@ -457,6 +458,58 @@
     return HWC2_ERROR_NONE;
 }
 
+hwc2_error_t hwc2_display::get_client_target_support(uint32_t width,
+        uint32_t height, android_pixel_format_t format,
+        android_dataspace_t dataspace)
+{
+    if (active_config >= configs.size()) {
+        ALOGE("dpy %" PRIu64 ": no active_config", id);
+        return HWC2_ERROR_UNSUPPORTED;
+    }
+
+    int32_t cnfg_width = configs[active_config].get_attribute(
+            HWC2_ATTRIBUTE_WIDTH);
+    int32_t cnfg_height = configs[active_config].get_attribute(
+            HWC2_ATTRIBUTE_HEIGHT);
+
+    if (cnfg_width < 0 || width != static_cast<uint32_t>(cnfg_width)) {
+        ALOGE("dpy %" PRIu64 ": unsupported client target width", id);
+        return HWC2_ERROR_UNSUPPORTED;
+    }
+
+    if (cnfg_height < 0 || height != static_cast<uint32_t>(cnfg_height)) {
+        ALOGE("dpy %" PRIu64 ": unsupported client target height", id);
+        return HWC2_ERROR_UNSUPPORTED;
+    }
+
+    if (format != HAL_PIXEL_FORMAT_RGBA_8888) {
+        ALOGE("dpy %" PRIu64 ": unsupported client target format", id);
+        return HWC2_ERROR_UNSUPPORTED;
+    }
+
+    if (dataspace != HAL_DATASPACE_UNKNOWN) {
+        ALOGE("dpy %" PRIu64 ": unsupported client target dataspace", id);
+        return HWC2_ERROR_UNSUPPORTED;
+    }
+
+    return HWC2_ERROR_NONE;
+}
+
+hwc2_error_t hwc2_display::set_client_target(buffer_handle_t handle,
+        int32_t acquire_fence, android_dataspace_t dataspace,
+        const hwc_region_t &surface_damage)
+{
+    hwc2_error_t ret = client_target.set_buffer(handle, acquire_fence);
+    if (ret != HWC2_ERROR_NONE)
+        return ret;
+
+    ret = client_target.set_dataspace(dataspace);
+    if (ret != HWC2_ERROR_NONE)
+        return ret;
+
+    return client_target.set_surface_damage(surface_damage);
+}
+
 hwc2_error_t hwc2_display::create_layer(hwc2_layer_t *out_layer)
 {
     display_state = modified;