graphics: add composer 2.2 default impl

This adds

  android.hardware.graphics.composer@2.2-hal
  android.hardware.graphics.composer@2.2-passthrough
  android.hardware.graphics.composer@2.2-service

The -hal module makes it easier to write composer 2.2 HAL and is
reusable by vendors.  The -passthrough module provides a HwcHal
class that implements ComposerHal 2.2 on top of hwcomposer2, and is
also resuable by vendors.  Finally, the -service module provides a
(stub) default implementation.

Test: boots and VTS
Change-Id: I4f940a9dea656abc7d9d485bf48d852c13d2ed56
diff --git a/graphics/composer/2.2/utils/passthrough/Android.bp b/graphics/composer/2.2/utils/passthrough/Android.bp
new file mode 100644
index 0000000..318ce91
--- /dev/null
+++ b/graphics/composer/2.2/utils/passthrough/Android.bp
@@ -0,0 +1,14 @@
+cc_library_headers {
+    name: "android.hardware.graphics.composer@2.2-passthrough",
+    defaults: ["hidl_defaults"],
+    vendor: true,
+    header_libs: [
+        "android.hardware.graphics.composer@2.1-passthrough",
+        "android.hardware.graphics.composer@2.2-hal",
+    ],
+    export_header_lib_headers: [
+        "android.hardware.graphics.composer@2.1-passthrough",
+        "android.hardware.graphics.composer@2.2-hal",
+    ],
+    export_include_dirs: ["include"],
+}
diff --git a/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h b/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h
new file mode 100644
index 0000000..b251351
--- /dev/null
+++ b/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#pragma once
+
+#ifndef LOG_TAG
+#warning "HwcHal.h included without LOG_TAG"
+#endif
+
+#include <type_traits>
+
+#include <composer-hal/2.2/ComposerHal.h>
+#include <composer-passthrough/2.1/HwcHal.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace composer {
+namespace V2_2 {
+namespace passthrough {
+
+namespace detail {
+
+using common::V1_0::Dataspace;
+using common::V1_0::PixelFormat;
+using V2_1::Display;
+using V2_1::Error;
+using V2_1::Layer;
+
+// HwcHalImpl implements V2_*::hal::ComposerHal on top of hwcomposer2
+template <typename Hal>
+class HwcHalImpl : public V2_1::passthrough::detail::HwcHalImpl<Hal> {
+   public:
+    // XXX when can we return Error::UNSUPPORTED?
+
+    Error getPerFrameMetadataKeys(
+        Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) override {
+        if (!mDispatch.getPerFrameMetadataKeys) {
+            return Error::UNSUPPORTED;
+        }
+
+        uint32_t count = 0;
+        int32_t error = mDispatch.getPerFrameMetadataKeys(mDevice, display, &count, nullptr);
+        if (error != HWC2_ERROR_NONE) {
+            return static_cast<Error>(error);
+        }
+
+        std::vector<IComposerClient::PerFrameMetadataKey> keys(count);
+        error = mDispatch.getPerFrameMetadataKeys(
+            mDevice, display, &count,
+            reinterpret_cast<std::underlying_type<IComposerClient::PerFrameMetadataKey>::type*>(
+                keys.data()));
+        if (error != HWC2_ERROR_NONE) {
+            return static_cast<Error>(error);
+        }
+
+        keys.resize(count);
+        *outKeys = std::move(keys);
+        return Error::NONE;
+    }
+
+    Error setPerFrameMetadata(
+        Display display, const std::vector<IComposerClient::PerFrameMetadata>& metadata) override {
+        if (!mDispatch.setPerFrameMetadata) {
+            return Error::UNSUPPORTED;
+        }
+
+        std::vector<int32_t> keys;
+        std::vector<float> values;
+        keys.reserve(metadata.size());
+        values.reserve(metadata.size());
+        for (const auto& m : metadata) {
+            keys.push_back(static_cast<int32_t>(m.key));
+            values.push_back(m.value);
+        }
+
+        int32_t error = mDispatch.setPerFrameMetadata(mDevice, display, metadata.size(),
+                                                      keys.data(), values.data());
+        return static_cast<Error>(error);
+    }
+
+    Error getReadbackBufferAttributes(Display display, PixelFormat* outFormat,
+                                      Dataspace* outDataspace) override {
+        if (!mDispatch.getReadbackBufferAttributes) {
+            return Error::UNSUPPORTED;
+        }
+
+        int32_t format = 0;
+        int32_t dataspace = 0;
+        int32_t error =
+            mDispatch.getReadbackBufferAttributes(mDevice, display, &format, &dataspace);
+        if (error == HWC2_ERROR_NONE) {
+            *outFormat = static_cast<PixelFormat>(format);
+            *outDataspace = static_cast<Dataspace>(dataspace);
+        }
+        return static_cast<Error>(error);
+    }
+
+    Error setReadbackBuffer(Display display, const native_handle_t* bufferHandle,
+                            base::unique_fd fenceFd) override {
+        if (!mDispatch.setReadbackBuffer) {
+            return Error::UNSUPPORTED;
+        }
+
+        int32_t error =
+            mDispatch.setReadbackBuffer(mDevice, display, bufferHandle, fenceFd.release());
+        return static_cast<Error>(error);
+    }
+
+    Error getReadbackBufferFence(Display display, base::unique_fd* outFenceFd) override {
+        if (!mDispatch.getReadbackBufferFence) {
+            return Error::UNSUPPORTED;
+        }
+
+        int32_t fenceFd = -1;
+        int32_t error = mDispatch.getReadbackBufferFence(mDevice, display, &fenceFd);
+        outFenceFd->reset(fenceFd);
+        return static_cast<Error>(error);
+    }
+
+    Error setPowerMode_2_2(Display display, IComposerClient::PowerMode mode) override {
+        if (mode == IComposerClient::PowerMode::ON_SUSPEND) {
+            return Error::UNSUPPORTED;
+        }
+        return setPowerMode(display, static_cast<V2_1::IComposerClient::PowerMode>(mode));
+    }
+
+    Error setLayerFloatColor(Display display, Layer layer,
+                             IComposerClient::FloatColor color) override {
+        if (!mDispatch.setLayerFloatColor) {
+            return Error::UNSUPPORTED;
+        }
+
+        int32_t error = mDispatch.setLayerFloatColor(
+            mDevice, display, layer, hwc_float_color{color.r, color.g, color.b, color.a});
+        return static_cast<Error>(error);
+    }
+
+   protected:
+    template <typename T>
+    bool initOptionalDispatch(hwc2_function_descriptor_t desc, T* outPfn) {
+        auto pfn = mDevice->getFunction(mDevice, desc);
+        if (pfn) {
+            *outPfn = reinterpret_cast<T>(pfn);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    bool initDispatch() override {
+        if (!BaseType2_1::initDispatch()) {
+            return false;
+        }
+
+        initOptionalDispatch(HWC2_FUNCTION_SET_LAYER_FLOAT_COLOR, &mDispatch.setLayerFloatColor);
+
+        initOptionalDispatch(HWC2_FUNCTION_SET_PER_FRAME_METADATA, &mDispatch.setPerFrameMetadata);
+        initOptionalDispatch(HWC2_FUNCTION_GET_PER_FRAME_METADATA_KEYS,
+                             &mDispatch.getPerFrameMetadataKeys);
+
+        initOptionalDispatch(HWC2_FUNCTION_SET_READBACK_BUFFER, &mDispatch.setReadbackBuffer);
+        initOptionalDispatch(HWC2_FUNCTION_GET_READBACK_BUFFER_ATTRIBUTES,
+                             &mDispatch.getReadbackBufferAttributes);
+        initOptionalDispatch(HWC2_FUNCTION_GET_READBACK_BUFFER_FENCE,
+                             &mDispatch.getReadbackBufferFence);
+
+        return true;
+    }
+
+    struct {
+        HWC2_PFN_SET_LAYER_FLOAT_COLOR setLayerFloatColor;
+        HWC2_PFN_SET_PER_FRAME_METADATA setPerFrameMetadata;
+        HWC2_PFN_GET_PER_FRAME_METADATA_KEYS getPerFrameMetadataKeys;
+        HWC2_PFN_SET_READBACK_BUFFER setReadbackBuffer;
+        HWC2_PFN_GET_READBACK_BUFFER_ATTRIBUTES getReadbackBufferAttributes;
+        HWC2_PFN_GET_READBACK_BUFFER_FENCE getReadbackBufferFence;
+    } mDispatch = {};
+
+   private:
+    using BaseType2_1 = V2_1::passthrough::detail::HwcHalImpl<Hal>;
+    using BaseType2_1::mDevice;
+    using BaseType2_1::setPowerMode;
+};
+
+}  // namespace detail
+
+using HwcHal = detail::HwcHalImpl<hal::ComposerHal>;
+
+}  // namespace passthrough
+}  // namespace V2_2
+}  // namespace composer
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
diff --git a/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcLoader.h b/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcLoader.h
new file mode 100644
index 0000000..cb4a238
--- /dev/null
+++ b/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcLoader.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#pragma once
+
+#ifndef LOG_TAG
+#warning "HwcLoader.h included without LOG_TAG"
+#endif
+
+#include <composer-hal/2.2/Composer.h>
+#include <composer-hal/2.2/ComposerHal.h>
+#include <composer-passthrough/2.1/HwcLoader.h>
+#include <composer-passthrough/2.2/HwcHal.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace composer {
+namespace V2_2 {
+namespace passthrough {
+
+class HwcLoader : public V2_1::passthrough::HwcLoader {
+   public:
+    static IComposer* load() {
+        const hw_module_t* module = loadModule();
+        if (!module) {
+            return nullptr;
+        }
+
+        auto hal = createHalWithAdapter(module);
+        if (!hal) {
+            return nullptr;
+        }
+
+        return createComposer(std::move(hal)).release();
+    }
+
+    // create a ComposerHal instance
+    static std::unique_ptr<hal::ComposerHal> createHal(const hw_module_t* module) {
+        auto hal = std::make_unique<HwcHal>();
+        return hal->initWithModule(module) ? std::move(hal) : nullptr;
+    }
+
+    // create a ComposerHal instance, insert an adapter if necessary
+    static std::unique_ptr<hal::ComposerHal> createHalWithAdapter(const hw_module_t* module) {
+        bool adapted;
+        hwc2_device_t* device = openDeviceWithAdapter(module, &adapted);
+        if (!device) {
+            return nullptr;
+        }
+        auto hal = std::make_unique<HwcHal>();
+        return hal->initWithDevice(std::move(device), !adapted) ? std::move(hal) : nullptr;
+    }
+
+    // create an IComposer instance
+    static std::unique_ptr<IComposer> createComposer(std::unique_ptr<hal::ComposerHal> hal) {
+        return hal::Composer::create(std::move(hal));
+    }
+};
+
+}  // namespace passthrough
+}  // namespace V2_2
+}  // namespace composer
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android