hwc2: create and destroy layers

Client can create and destroy layers

Test: Add "TARGET_USES_HWC2 := true" to BoardConfig.mk.
      Recompile.
      Run testcases: https://android-review.googlesource.com/#/q/project:
            platform/frameworks/native+branch:master+topic:test-hwc2

Change-Id: I3ff3f1eee28055382cebfb3199da5017cc55f53d
diff --git a/hwc2/Android.mk b/hwc2/Android.mk
index 1e4456f..a111afa 100644
--- a/hwc2/Android.mk
+++ b/hwc2/Android.mk
@@ -43,7 +43,8 @@
 	hwc2_dev.cpp \
 	hwc2_display.cpp \
 	hwc2_config.cpp \
-	hwc2_callback.cpp
+	hwc2_callback.cpp \
+	hwc2_layer.cpp
 
 LOCAL_MODLE_TAGS := optional
 
diff --git a/hwc2/hwc2.cpp b/hwc2/hwc2.cpp
index 036f488..fde75d7 100644
--- a/hwc2/hwc2.cpp
+++ b/hwc2/hwc2.cpp
@@ -80,16 +80,18 @@
     return HWC2_ERROR_NONE;
 }
 
-hwc2_error_t create_layer(hwc2_device_t* /*device*/, hwc2_display_t /*display*/,
-        hwc2_layer_t* /*out_layer*/)
+hwc2_error_t create_layer(hwc2_device_t *device, hwc2_display_t display,
+        hwc2_layer_t *out_layer)
 {
-    return HWC2_ERROR_NONE;
+    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
+    return dev->create_layer(display, out_layer);
 }
 
-hwc2_error_t destroy_layer(hwc2_device_t* /*device*/,
-        hwc2_display_t /*display*/, hwc2_layer_t /*layer*/)
+hwc2_error_t destroy_layer(hwc2_device_t *device, hwc2_display_t display,
+        hwc2_layer_t layer)
 {
-    return HWC2_ERROR_NONE;
+    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
+    return dev->destroy_layer(display, layer);
 }
 
 hwc2_error_t get_active_config(hwc2_device_t* /*device*/,
diff --git a/hwc2/hwc2.h b/hwc2/hwc2.h
index b1fcaf8..9c105e1 100644
--- a/hwc2/hwc2.h
+++ b/hwc2/hwc2.h
@@ -73,6 +73,23 @@
     HWC2_PFN_VSYNC vsync;
 };
 
+class hwc2_layer {
+public:
+    hwc2_layer(hwc2_layer_t id);
+
+    hwc2_layer_t get_id() const { return id; }
+
+    static hwc2_layer_t get_next_id();
+
+private:
+    /* Identifies the layer to the client */
+    hwc2_layer_t id;
+
+    /* Keep track to total number of layers so new layer ids can be
+     * generated */
+    static uint64_t layer_cnt;
+};
+
 class hwc2_display {
 public:
     hwc2_display(hwc2_display_t id, int adf_intf_fd,
@@ -88,6 +105,10 @@
 
     int retrieve_display_configs(struct adf_hwc_helper *adf_helper);
 
+    /* Set layer functions */
+    hwc2_error_t create_layer(hwc2_layer_t *out_layer);
+    hwc2_error_t destroy_layer(hwc2_layer_t lyr_id);
+
     static hwc2_display_t get_next_id();
 
     static void reset_ids() { display_cnt = 0; }
@@ -102,6 +123,9 @@
     /* Physical or virtual */
     hwc2_display_type_t type;
 
+    /* The layers currently in use */
+    std::unordered_map<hwc2_layer_t, hwc2_layer> layers;
+
     /* All the valid configurations for the display */
     std::unordered_map<hwc2_config_t, hwc2_config> configs;
 
@@ -127,6 +151,11 @@
     hwc2_error_t get_display_type(hwc2_display_t dpy_id,
                     hwc2_display_type_t *out_type) const;
 
+    /* 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);
+
+    /* Callback functions */
     void hotplug(hwc2_display_t dpy_id, hwc2_connection_t connection);
 
     hwc2_error_t register_callback(hwc2_callback_descriptor_t descriptor,
diff --git a/hwc2/hwc2_dev.cpp b/hwc2/hwc2_dev.cpp
index e89fd37..15280e3 100644
--- a/hwc2/hwc2_dev.cpp
+++ b/hwc2/hwc2_dev.cpp
@@ -72,6 +72,28 @@
     return HWC2_ERROR_NONE;
 }
 
+hwc2_error_t hwc2_dev::create_layer(hwc2_display_t dpy_id, hwc2_layer_t *out_layer)
+{
+    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.create_layer(out_layer);
+}
+
+hwc2_error_t hwc2_dev::destroy_layer(hwc2_display_t dpy_id, hwc2_layer_t lyr_id)
+{
+    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.destroy_layer(lyr_id);
+}
+
 void hwc2_dev::hotplug(hwc2_display_t dpy_id, hwc2_connection_t connection)
 {
     auto it = displays.find(dpy_id);
diff --git a/hwc2/hwc2_display.cpp b/hwc2/hwc2_display.cpp
index 2040614..a178abf 100644
--- a/hwc2/hwc2_display.cpp
+++ b/hwc2/hwc2_display.cpp
@@ -30,6 +30,7 @@
     : id(id),
       connection(connection),
       type(type),
+      layers(),
       configs(),
       active_config(0),
       adf_intf_fd(adf_intf_fd),
@@ -107,6 +108,28 @@
     return ret;
 }
 
+hwc2_error_t hwc2_display::create_layer(hwc2_layer_t *out_layer)
+{
+    hwc2_layer_t lyr_id = hwc2_layer::get_next_id();
+    layers.emplace(std::piecewise_construct, std::forward_as_tuple(lyr_id),
+            std::forward_as_tuple(lyr_id));
+
+    *out_layer = lyr_id;
+    return HWC2_ERROR_NONE;
+}
+
+hwc2_error_t hwc2_display::destroy_layer(hwc2_layer_t lyr_id)
+{
+    auto it = layers.find(lyr_id);
+    if (it == layers.end()) {
+        ALOGE("dpy %" PRIu64 ": lyr %" PRIu64 ": bad layer handle", id, lyr_id);
+        return HWC2_ERROR_BAD_LAYER;
+    }
+
+    layers.erase(lyr_id);
+    return HWC2_ERROR_NONE;
+}
+
 hwc2_display_t hwc2_display::get_next_id()
 {
     return display_cnt++;
diff --git a/hwc2/hwc2_layer.cpp b/hwc2/hwc2_layer.cpp
new file mode 100644
index 0000000..ea26b38
--- /dev/null
+++ b/hwc2/hwc2_layer.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "hwc2.h"
+
+uint64_t hwc2_layer::layer_cnt = 0;
+
+hwc2_layer::hwc2_layer(hwc2_layer_t id)
+    : id(id) { }
+
+hwc2_layer_t hwc2_layer::get_next_id()
+{
+    return layer_cnt++;
+}