surfaceflinger: add support for android.hardware.graphics
This adds a new path to HWC2 to use
android.hardware.graphics.composer@2.1::IComposer instead of hwcomposer2.
Which path to use is determined by whether BYPASS_IHWC is set at compile
time. When it is set, the old path, kept for HWC2On1Adapter, is used.
When it is not set, the new path is taken.
BYPASS_IHWC2 is set when TARGET_USES_HWC2 is not.
Test: Maps, Camera, YouTube, etc.
Change-Id: I37aceafd1733fa9f76e7f7db4f59ad4776415306
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
new file mode 100644
index 0000000..128e2b0
--- /dev/null
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
@@ -0,0 +1,650 @@
+/*
+ * Copyright 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.
+ */
+
+#undef LOG_TAG
+#define LOG_TAG "HwcComposer"
+
+#include <inttypes.h>
+#include <log/log.h>
+
+#include "ComposerHal.h"
+
+namespace android {
+
+using hardware::Return;
+using hardware::hidl_vec;
+
+namespace Hwc2 {
+
+namespace {
+
+class BufferHandle {
+public:
+ BufferHandle(const native_handle_t* buffer)
+ {
+ // nullptr is not a valid handle to HIDL
+ mHandle = (buffer) ? buffer : native_handle_init(mStorage, 0, 0);
+ }
+
+ operator const native_handle_t*() const
+ {
+ return mHandle;
+ }
+
+private:
+ NATIVE_HANDLE_DECLARE_STORAGE(mStorage, 0, 0);
+ const native_handle_t* mHandle;
+};
+
+class FenceHandle
+{
+public:
+ FenceHandle(int fd, bool owned)
+ : mOwned(owned)
+ {
+ if (fd >= 0) {
+ mHandle = native_handle_init(mStorage, 1, 0);
+ mHandle->data[0] = fd;
+ } else {
+ // nullptr is not a valid handle to HIDL
+ mHandle = native_handle_init(mStorage, 0, 0);
+ }
+ }
+
+ ~FenceHandle()
+ {
+ if (mOwned) {
+ native_handle_close(mHandle);
+ }
+ }
+
+ operator const native_handle_t*() const
+ {
+ return mHandle;
+ }
+
+private:
+ bool mOwned;
+ NATIVE_HANDLE_DECLARE_STORAGE(mStorage, 1, 0);
+ native_handle_t* mHandle;
+};
+
+// assume NO_RESOURCES when Status::isOk returns false
+constexpr Error kDefaultError = Error::NO_RESOURCES;
+
+template<typename T, typename U>
+T unwrapRet(Return<T>& ret, const U& default_val)
+{
+ return (ret.getStatus().isOk()) ? static_cast<T>(ret) :
+ static_cast<T>(default_val);
+}
+
+Error unwrapRet(Return<Error>& ret)
+{
+ return unwrapRet(ret, kDefaultError);
+}
+
+template<typename T>
+void assignFromHidlVec(std::vector<T>& vec, const hidl_vec<T>& data)
+{
+ vec.clear();
+ vec.insert(vec.begin(), &data[0], &data[data.size()]);
+}
+
+} // anonymous namespace
+
+Composer::Composer()
+{
+ mService = IComposer::getService("hwcomposer");
+ if (mService == nullptr) {
+ LOG_ALWAYS_FATAL("failed to get hwcomposer service");
+ }
+}
+
+std::vector<IComposer::Capability> Composer::getCapabilities() const
+{
+ std::vector<IComposer::Capability> capabilities;
+ mService->getCapabilities(
+ [&](const auto& tmpCapabilities) {
+ assignFromHidlVec(capabilities, tmpCapabilities);
+ });
+
+ return capabilities;
+}
+
+std::string Composer::dumpDebugInfo() const
+{
+ std::string info;
+ mService->dumpDebugInfo([&](const auto& tmpInfo) {
+ info = tmpInfo.c_str();
+ });
+
+ return info;
+}
+
+void Composer::registerCallback(const sp<IComposerCallback>& callback) const
+{
+ auto ret = mService->registerCallback(callback);
+ if (!ret.getStatus().isOk()) {
+ ALOGE("failed to register IComposerCallback");
+ }
+}
+
+uint32_t Composer::getMaxVirtualDisplayCount() const
+{
+ auto ret = mService->getMaxVirtualDisplayCount();
+ return unwrapRet(ret, 0);
+}
+
+Error Composer::createVirtualDisplay(uint32_t width, uint32_t height,
+ PixelFormat& format, Display& display) const
+{
+ Error error = kDefaultError;
+ mService->createVirtualDisplay(width, height, format,
+ [&](const auto& tmpError, const auto& tmpDisplay,
+ const auto& tmpFormat) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ display = tmpDisplay;
+ format = tmpFormat;
+ });
+
+ return error;
+}
+
+Error Composer::destroyVirtualDisplay(Display display) const
+{
+ auto ret = mService->destroyVirtualDisplay(display);
+ return unwrapRet(ret);
+}
+
+Error Composer::acceptDisplayChanges(Display display) const
+{
+ auto ret = mService->acceptDisplayChanges(display);
+ return unwrapRet(ret);
+}
+
+Error Composer::createLayer(Display display, Layer& layer) const
+{
+ Error error = kDefaultError;
+ mService->createLayer(display,
+ [&](const auto& tmpError, const auto& tmpLayer) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ layer = tmpLayer;
+ });
+
+ return error;
+}
+
+Error Composer::destroyLayer(Display display, Layer layer) const
+{
+ auto ret = mService->destroyLayer(display, layer);
+ return unwrapRet(ret);
+}
+
+Error Composer::getActiveConfig(Display display, Config& config) const
+{
+ Error error = kDefaultError;
+ mService->getActiveConfig(display,
+ [&](const auto& tmpError, const auto& tmpConfig) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ config = tmpConfig;
+ });
+
+ return error;
+}
+
+Error Composer::getChangedCompositionTypes(Display display,
+ std::vector<Layer>& layers,
+ std::vector<IComposer::Composition>& types) const
+{
+ Error error = kDefaultError;
+ mService->getChangedCompositionTypes(display,
+ [&](const auto& tmpError, const auto& tmpLayers,
+ const auto& tmpTypes) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ assignFromHidlVec(layers, tmpLayers);
+ assignFromHidlVec(types, tmpTypes);
+ });
+
+ return error;
+}
+
+Error Composer::getColorModes(Display display,
+ std::vector<ColorMode>& modes) const
+{
+ Error error = kDefaultError;
+ mService->getColorModes(display,
+ [&](const auto& tmpError, const auto& tmpModes) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ assignFromHidlVec(modes, tmpModes);
+ });
+
+ return error;
+}
+
+Error Composer::getDisplayAttribute(Display display, Config config,
+ IComposer::Attribute attribute, int32_t& value) const
+{
+ Error error = kDefaultError;
+ mService->getDisplayAttribute(display, config, attribute,
+ [&](const auto& tmpError, const auto& tmpValue) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ value = tmpValue;
+ });
+
+ return error;
+}
+
+Error Composer::getDisplayConfigs(Display display,
+ std::vector<Config>& configs) const
+{
+ Error error = kDefaultError;
+ mService->getDisplayConfigs(display,
+ [&](const auto& tmpError, const auto& tmpConfigs) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ assignFromHidlVec(configs, tmpConfigs);
+ });
+
+ return error;
+}
+
+Error Composer::getDisplayName(Display display, std::string& name) const
+{
+ Error error = kDefaultError;
+ mService->getDisplayName(display,
+ [&](const auto& tmpError, const auto& tmpName) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ name = tmpName.c_str();
+ });
+
+ return error;
+}
+
+Error Composer::getDisplayRequests(Display display,
+ uint32_t& displayRequestMask, std::vector<Layer>& layers,
+ std::vector<uint32_t>& layerRequestMasks) const
+{
+ Error error = kDefaultError;
+ mService->getDisplayRequests(display,
+ [&](const auto& tmpError, const auto& tmpDisplayRequestMask,
+ const auto& tmpLayers, const auto& tmpLayerRequestMasks) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ displayRequestMask = tmpDisplayRequestMask;
+ assignFromHidlVec(layers, tmpLayers);
+ assignFromHidlVec(layerRequestMasks, tmpLayerRequestMasks);
+ });
+
+ return error;
+}
+
+Error Composer::getDisplayType(Display display, IComposer::DisplayType& type) const
+{
+ Error error = kDefaultError;
+ mService->getDisplayType(display,
+ [&](const auto& tmpError, const auto& tmpType) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ type = tmpType;
+ });
+
+ return error;
+}
+
+Error Composer::getDozeSupport(Display display, bool& support) const
+{
+ Error error = kDefaultError;
+ mService->getDozeSupport(display,
+ [&](const auto& tmpError, const auto& tmpSupport) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ support = tmpSupport;
+ });
+
+ return error;
+}
+
+Error Composer::getHdrCapabilities(Display display, std::vector<Hdr>& types,
+ float& maxLuminance, float& maxAverageLuminance,
+ float& minLuminance) const
+{
+ Error error = kDefaultError;
+ mService->getHdrCapabilities(display,
+ [&](const auto& tmpError, const auto& tmpTypes,
+ const auto& tmpMaxLuminance,
+ const auto& tmpMaxAverageLuminance,
+ const auto& tmpMinLuminance) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ assignFromHidlVec(types, tmpTypes);
+ maxLuminance = tmpMaxLuminance;
+ maxAverageLuminance = tmpMaxAverageLuminance;
+ minLuminance = tmpMinLuminance;
+ });
+
+ return error;
+}
+
+Error Composer::getReleaseFences(Display display, std::vector<Layer>& layers,
+ std::vector<int>& releaseFences) const
+{
+ Error error = kDefaultError;
+ mService->getReleaseFences(display,
+ [&](const auto& tmpError, const auto& tmpLayers,
+ const auto& tmpReleaseFences) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ if (static_cast<int>(tmpLayers.size()) !=
+ tmpReleaseFences->numFds) {
+ ALOGE("invalid releaseFences outputs: "
+ "layer count %zu != fence count %d",
+ tmpLayers.size(), tmpReleaseFences->numFds);
+ error = Error::NO_RESOURCES;
+ return;
+ }
+
+ // dup the file descriptors
+ std::vector<int> tmpFds;
+ tmpFds.reserve(tmpReleaseFences->numFds);
+ for (int i = 0; i < tmpReleaseFences->numFds; i++) {
+ int fd = dup(tmpReleaseFences->data[i]);
+ if (fd < 0) {
+ break;
+ }
+ tmpFds.push_back(fd);
+ }
+ if (static_cast<int>(tmpFds.size()) <
+ tmpReleaseFences->numFds) {
+ for (auto fd : tmpFds) {
+ close(fd);
+ }
+
+ error = Error::NO_RESOURCES;
+ return;
+ }
+
+ assignFromHidlVec(layers, tmpLayers);
+ releaseFences = std::move(tmpFds);
+ });
+
+ return error;
+}
+
+Error Composer::presentDisplay(Display display, int& presentFence) const
+{
+ Error error = kDefaultError;
+ mService->presentDisplay(display,
+ [&](const auto& tmpError, const auto& tmpPresentFence) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ if (tmpPresentFence->numFds == 1) {
+ int fd = dup(tmpPresentFence->data[0]);
+ if (fd >= 0) {
+ presentFence = fd;
+ } else {
+ error = Error::NO_RESOURCES;
+ }
+ } else {
+ presentFence = -1;
+ }
+ });
+
+ return error;
+}
+
+Error Composer::setActiveConfig(Display display, Config config) const
+{
+ auto ret = mService->setActiveConfig(display, config);
+ return unwrapRet(ret);
+}
+
+Error Composer::setClientTarget(Display display, const native_handle_t* target,
+ int acquireFence, Dataspace dataspace,
+ const std::vector<IComposer::Rect>& damage) const
+{
+ BufferHandle tmpTarget(target);
+ FenceHandle tmpAcquireFence(acquireFence, true);
+
+ hidl_vec<IComposer::Rect> tmpDamage;
+ tmpDamage.setToExternal(const_cast<IComposer::Rect*>(damage.data()),
+ damage.size());
+
+ auto ret = mService->setClientTarget(display, tmpTarget,
+ tmpAcquireFence, dataspace, tmpDamage);
+ return unwrapRet(ret);
+}
+
+Error Composer::setColorMode(Display display, ColorMode mode) const
+{
+ auto ret = mService->setColorMode(display, mode);
+ return unwrapRet(ret);
+}
+
+Error Composer::setColorTransform(Display display, const float* matrix,
+ ColorTransform hint) const
+{
+ hidl_vec<float> tmpMatrix;
+ tmpMatrix.setToExternal(const_cast<float*>(matrix), 16);
+
+ auto ret = mService->setColorTransform(display, tmpMatrix, hint);
+ return unwrapRet(ret);
+}
+
+Error Composer::setOutputBuffer(Display display, const native_handle_t* buffer,
+ int releaseFence) const
+{
+ BufferHandle tmpBuffer(buffer);
+ FenceHandle tmpReleaseFence(releaseFence, false);
+
+ auto ret = mService->setOutputBuffer(display, tmpBuffer, tmpReleaseFence);
+ return unwrapRet(ret);
+}
+
+Error Composer::setPowerMode(Display display, IComposer::PowerMode mode) const
+{
+ auto ret = mService->setPowerMode(display, mode);
+ return unwrapRet(ret);
+}
+
+Error Composer::setVsyncEnabled(Display display, IComposer::Vsync enabled) const
+{
+ auto ret = mService->setVsyncEnabled(display, enabled);
+ return unwrapRet(ret);
+}
+
+Error Composer::validateDisplay(Display display, uint32_t& numTypes, uint32_t&
+ numRequests) const
+{
+ Error error = kDefaultError;
+ mService->validateDisplay(display,
+ [&](const auto& tmpError, const auto& tmpNumTypes,
+ const auto& tmpNumRequests) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ numTypes = tmpNumTypes;
+ numRequests = tmpNumRequests;
+ });
+
+ return error;
+}
+
+Error Composer::setCursorPosition(Display display, Layer layer,
+ int32_t x, int32_t y) const
+{
+ auto ret = mService->setCursorPosition(display, layer, x, y);
+ return unwrapRet(ret);
+}
+
+Error Composer::setLayerBuffer(Display display, Layer layer,
+ const native_handle_t* buffer, int acquireFence) const
+{
+ BufferHandle tmpBuffer(buffer);
+ FenceHandle tmpAcquireFence(acquireFence, true);
+
+ auto ret = mService->setLayerBuffer(display, layer,
+ tmpBuffer, tmpAcquireFence);
+ return unwrapRet(ret);
+}
+
+Error Composer::setLayerSurfaceDamage(Display display, Layer layer,
+ const std::vector<IComposer::Rect>& damage) const
+{
+ hidl_vec<IComposer::Rect> tmpDamage;
+ tmpDamage.setToExternal(const_cast<IComposer::Rect*>(damage.data()),
+ damage.size());
+
+ auto ret = mService->setLayerSurfaceDamage(display, layer, tmpDamage);
+ return unwrapRet(ret);
+}
+
+Error Composer::setLayerBlendMode(Display display, Layer layer,
+ IComposer::BlendMode mode) const
+{
+ auto ret = mService->setLayerBlendMode(display, layer, mode);
+ return unwrapRet(ret);
+}
+
+Error Composer::setLayerColor(Display display, Layer layer,
+ const IComposer::Color& color) const
+{
+ auto ret = mService->setLayerColor(display, layer, color);
+ return unwrapRet(ret);
+}
+
+Error Composer::setLayerCompositionType(Display display, Layer layer,
+ IComposer::Composition type) const
+{
+ auto ret = mService->setLayerCompositionType(display, layer, type);
+ return unwrapRet(ret);
+}
+
+Error Composer::setLayerDataspace(Display display, Layer layer,
+ Dataspace dataspace) const
+{
+ auto ret = mService->setLayerDataspace(display, layer, dataspace);
+ return unwrapRet(ret);
+}
+
+Error Composer::setLayerDisplayFrame(Display display, Layer layer,
+ const IComposer::Rect& frame) const
+{
+ auto ret = mService->setLayerDisplayFrame(display, layer, frame);
+ return unwrapRet(ret);
+}
+
+Error Composer::setLayerPlaneAlpha(Display display, Layer layer,
+ float alpha) const
+{
+ auto ret = mService->setLayerPlaneAlpha(display, layer, alpha);
+ return unwrapRet(ret);
+}
+
+Error Composer::setLayerSidebandStream(Display display, Layer layer,
+ const native_handle_t* stream) const
+{
+ BufferHandle tmpStream(stream);
+
+ auto ret = mService->setLayerSidebandStream(display, layer, tmpStream);
+ return unwrapRet(ret);
+}
+
+Error Composer::setLayerSourceCrop(Display display, Layer layer,
+ const IComposer::FRect& crop) const
+{
+ auto ret = mService->setLayerSourceCrop(display, layer, crop);
+ return unwrapRet(ret);
+}
+
+Error Composer::setLayerTransform(Display display, Layer layer,
+ Transform transform) const
+{
+ auto ret = mService->setLayerTransform(display, layer, transform);
+ return unwrapRet(ret);
+}
+
+Error Composer::setLayerVisibleRegion(Display display, Layer layer,
+ const std::vector<IComposer::Rect>& visible) const
+{
+ hidl_vec<IComposer::Rect> tmpVisible;
+ tmpVisible.setToExternal(const_cast<IComposer::Rect*>(visible.data()),
+ visible.size());
+
+ auto ret = mService->setLayerVisibleRegion(display, layer, tmpVisible);
+ return unwrapRet(ret);
+}
+
+Error Composer::setLayerZOrder(Display display, Layer layer, uint32_t z) const
+{
+ auto ret = mService->setLayerZOrder(display, layer, z);
+ return unwrapRet(ret);
+}
+
+} // namespace Hwc2
+
+} // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
new file mode 100644
index 0000000..fd74a92
--- /dev/null
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef ANDROID_SF_COMPOSER_HAL_H
+#define ANDROID_SF_COMPOSER_HAL_H
+
+#include <string>
+#include <vector>
+
+#include <android/hardware/graphics/composer/2.1/IComposer.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+namespace Hwc2 {
+
+using android::hardware::graphics::allocator::V2_0::PixelFormat;
+
+using android::hardware::graphics::composer::V2_1::IComposer;
+using android::hardware::graphics::composer::V2_1::IComposerCallback;
+using android::hardware::graphics::composer::V2_1::Error;
+using android::hardware::graphics::composer::V2_1::Display;
+using android::hardware::graphics::composer::V2_1::Layer;
+using android::hardware::graphics::composer::V2_1::Config;
+
+using android::hardware::graphics::composer::V2_1::ColorMode;
+using android::hardware::graphics::composer::V2_1::Hdr;
+using android::hardware::graphics::composer::V2_1::Dataspace;
+using android::hardware::graphics::composer::V2_1::ColorTransform;
+using android::hardware::graphics::composer::V2_1::Transform;
+
+// Composer is a wrapper to IComposer, a proxy to server-side composer.
+class Composer {
+public:
+ Composer();
+
+ std::vector<IComposer::Capability> getCapabilities() const;
+ std::string dumpDebugInfo() const;
+
+ void registerCallback(const sp<IComposerCallback>& callback) const;
+
+ uint32_t getMaxVirtualDisplayCount() const;
+ Error createVirtualDisplay(uint32_t width, uint32_t height,
+ PixelFormat& format, Display& display) const;
+ Error destroyVirtualDisplay(Display display) const;
+
+ Error acceptDisplayChanges(Display display) const;
+
+ Error createLayer(Display display, Layer& layer) const;
+ Error destroyLayer(Display display, Layer layer) const;
+
+ Error getActiveConfig(Display display, Config& config) const;
+ Error getChangedCompositionTypes(Display display,
+ std::vector<Layer>& layers,
+ std::vector<IComposer::Composition>& types) const;
+ Error getColorModes(Display display, std::vector<ColorMode>& modes) const;
+ Error getDisplayAttribute(Display display, Config config,
+ IComposer::Attribute attribute, int32_t& value) const;
+ Error getDisplayConfigs(Display display,
+ std::vector<Config>& configs) const;
+ Error getDisplayName(Display display, std::string& name) const;
+
+ Error getDisplayRequests(Display display, uint32_t& displayRequestMask,
+ std::vector<Layer>& layers,
+ std::vector<uint32_t>& layerRequestMasks) const;
+
+ Error getDisplayType(Display display, IComposer::DisplayType& type) const;
+ Error getDozeSupport(Display display, bool& support) const;
+ Error getHdrCapabilities(Display display, std::vector<Hdr>& types,
+ float& maxLuminance, float& maxAverageLuminance,
+ float& minLuminance) const;
+
+ Error getReleaseFences(Display display, std::vector<Layer>& layers,
+ std::vector<int>& releaseFences) const;
+
+ Error presentDisplay(Display display, int& presentFence) const;
+
+ Error setActiveConfig(Display display, Config config) const;
+ Error setClientTarget(Display display, const native_handle_t* target,
+ int acquireFence, Dataspace dataspace,
+ const std::vector<IComposer::Rect>& damage) const;
+ Error setColorMode(Display display, ColorMode mode) const;
+ Error setColorTransform(Display display, const float* matrix,
+ ColorTransform hint) const;
+ Error setOutputBuffer(Display display, const native_handle_t* buffer,
+ int releaseFence) const;
+ Error setPowerMode(Display display, IComposer::PowerMode mode) const;
+ Error setVsyncEnabled(Display display, IComposer::Vsync enabled) const;
+
+ Error validateDisplay(Display display, uint32_t& numTypes,
+ uint32_t& numRequests) const;
+
+ Error setCursorPosition(Display display, Layer layer,
+ int32_t x, int32_t y) const;
+ Error setLayerBuffer(Display display, Layer layer,
+ const native_handle_t* buffer, int acquireFence) const;
+ Error setLayerSurfaceDamage(Display display, Layer layer,
+ const std::vector<IComposer::Rect>& damage) const;
+ Error setLayerBlendMode(Display display, Layer layer,
+ IComposer::BlendMode mode) const;
+ Error setLayerColor(Display display, Layer layer,
+ const IComposer::Color& color) const;
+ Error setLayerCompositionType(Display display, Layer layer,
+ IComposer::Composition type) const;
+ Error setLayerDataspace(Display display, Layer layer,
+ Dataspace dataspace) const;
+ Error setLayerDisplayFrame(Display display, Layer layer,
+ const IComposer::Rect& frame) const;
+ Error setLayerPlaneAlpha(Display display, Layer layer,
+ float alpha) const;
+ Error setLayerSidebandStream(Display display, Layer layer,
+ const native_handle_t* stream) const;
+ Error setLayerSourceCrop(Display display, Layer layer,
+ const IComposer::FRect& crop) const;
+ Error setLayerTransform(Display display, Layer layer,
+ Transform transform) const;
+ Error setLayerVisibleRegion(Display display, Layer layer,
+ const std::vector<IComposer::Rect>& visible) const;
+ Error setLayerZOrder(Display display, Layer layer, uint32_t z) const;
+
+private:
+ sp<IComposer> mService;
+};
+
+} // namespace Hwc2
+
+} // namespace android
+
+#endif // ANDROID_SF_COMPOSER_HAL_H
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 4fe3cfd..c79caf4 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -21,6 +21,7 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
#include "HWC2.h"
+#include "ComposerHal.h"
#include "FloatRect.h"
@@ -79,11 +80,16 @@
using android::Rect;
using android::Region;
using android::sp;
+using android::hardware::Return;
+using android::hardware::Void;
namespace HWC2 {
+namespace Hwc2 = android::Hwc2;
+
// Device methods
+#ifdef BYPASS_IHWC
Device::Device(hwc2_device_t* device)
: mHwcDevice(device),
mCreateVirtualDisplay(nullptr),
@@ -128,6 +134,10 @@
mSetLayerTransform(nullptr),
mSetLayerVisibleRegion(nullptr),
mSetLayerZOrder(nullptr),
+#else
+Device::Device()
+ : mComposer(std::make_unique<Hwc2::Composer>()),
+#endif // BYPASS_IHWC
mCapabilities(),
mDisplays(),
mHotplug(),
@@ -144,9 +154,11 @@
Device::~Device()
{
+#ifdef BYPASS_IHWC
if (mHwcDevice == nullptr) {
return;
}
+#endif
for (auto element : mDisplays) {
auto display = element.second.lock();
@@ -175,13 +187,16 @@
}
}
+#ifdef BYPASS_IHWC
hwc2_close(mHwcDevice);
+#endif
}
// Required by HWC2 device
std::string Device::dump() const
{
+#ifdef BYPASS_IHWC
uint32_t numBytes = 0;
mDump(mHwcDevice, &numBytes, nullptr);
@@ -189,11 +204,18 @@
mDump(mHwcDevice, &numBytes, buffer.data());
return std::string(buffer.data(), buffer.size());
+#else
+ return mComposer->dumpDebugInfo();
+#endif
}
uint32_t Device::getMaxVirtualDisplayCount() const
{
+#ifdef BYPASS_IHWC
return mGetMaxVirtualDisplayCount(mHwcDevice);
+#else
+ return mComposer->getMaxVirtualDisplayCount();
+#endif
}
Error Device::createVirtualDisplay(uint32_t width, uint32_t height,
@@ -202,9 +224,15 @@
ALOGI("Creating virtual display");
hwc2_display_t displayId = 0;
+#ifdef BYPASS_IHWC
int32_t intFormat = static_cast<int32_t>(*format);
int32_t intError = mCreateVirtualDisplay(mHwcDevice, width, height,
&intFormat, &displayId);
+#else
+ auto intFormat = static_cast<Hwc2::PixelFormat>(*format);
+ auto intError = mComposer->createVirtualDisplay(width, height,
+ intFormat, displayId);
+#endif
auto error = static_cast<Error>(intError);
if (error != Error::None) {
return error;
@@ -315,6 +343,7 @@
{
static_assert(sizeof(Capability) == sizeof(int32_t),
"Capability size has changed");
+#ifdef BYPASS_IHWC
uint32_t numCapabilities = 0;
mHwcDevice->getCapabilities(mHwcDevice, &numCapabilities, nullptr);
std::vector<Capability> capabilities(numCapabilities);
@@ -323,6 +352,12 @@
for (auto capability : capabilities) {
mCapabilities.emplace(capability);
}
+#else
+ auto capabilities = mComposer->getCapabilities();
+ for (auto capability : capabilities) {
+ mCapabilities.emplace(static_cast<Capability>(capability));
+ }
+#endif
}
bool Device::hasCapability(HWC2::Capability capability) const
@@ -333,6 +368,7 @@
void Device::loadFunctionPointers()
{
+#ifdef BYPASS_IHWC
// For all of these early returns, we log an error message inside
// loadFunctionPointer specifying which function failed to load
@@ -426,13 +462,48 @@
mSetLayerVisibleRegion)) return;
if (!loadFunctionPointer(FunctionDescriptor::SetLayerZOrder,
mSetLayerZOrder)) return;
+#endif // BYPASS_IHWC
}
+namespace {
+class ComposerCallback : public Hwc2::IComposerCallback {
+public:
+ ComposerCallback(Device* device) : mDevice(device) {}
+
+ Return<void> onHotplug(Hwc2::Display display,
+ Connection connected) override
+ {
+ hotplug_hook(mDevice, display, static_cast<int32_t>(connected));
+ return Void();
+ }
+
+ Return<void> onRefresh(Hwc2::Display display) override
+ {
+ refresh_hook(mDevice, display);
+ return Void();
+ }
+
+ Return<void> onVsync(Hwc2::Display display, int64_t timestamp) override
+ {
+ vsync_hook(mDevice, display, timestamp);
+ return Void();
+ }
+
+private:
+ Device* mDevice;
+};
+} // namespace anonymous
+
void Device::registerCallbacks()
{
+#ifdef BYPASS_IHWC
registerCallback<HWC2_PFN_HOTPLUG>(Callback::Hotplug, hotplug_hook);
registerCallback<HWC2_PFN_REFRESH>(Callback::Refresh, refresh_hook);
registerCallback<HWC2_PFN_VSYNC>(Callback::Vsync, vsync_hook);
+#else
+ sp<ComposerCallback> callback = new ComposerCallback(this);
+ mComposer->registerCallback(callback);
+#endif
}
@@ -441,7 +512,11 @@
void Device::destroyVirtualDisplay(hwc2_display_t display)
{
ALOGI("Destroying virtual display");
+#ifdef BYPASS_IHWC
int32_t intError = mDestroyVirtualDisplay(mHwcDevice, display);
+#else
+ auto intError = mComposer->destroyVirtualDisplay(display);
+#endif
auto error = static_cast<Error>(intError);
ALOGE_IF(error != Error::None, "destroyVirtualDisplay(%" PRIu64 ") failed:"
" %s (%d)", display, to_string(error).c_str(), intError);
@@ -498,14 +573,22 @@
Error Display::acceptChanges()
{
+#ifdef BYPASS_IHWC
int32_t intError = mDevice.mAcceptDisplayChanges(mDevice.mHwcDevice, mId);
+#else
+ auto intError = mDevice.mComposer->acceptDisplayChanges(mId);
+#endif
return static_cast<Error>(intError);
}
Error Display::createLayer(std::shared_ptr<Layer>* outLayer)
{
hwc2_layer_t layerId = 0;
+#ifdef BYPASS_IHWC
int32_t intError = mDevice.mCreateLayer(mDevice.mHwcDevice, mId, &layerId);
+#else
+ auto intError = mDevice.mComposer->createLayer(mId, layerId);
+#endif
auto error = static_cast<Error>(intError);
if (error != Error::None) {
return error;
@@ -522,8 +605,12 @@
{
ALOGV("[%" PRIu64 "] getActiveConfig", mId);
hwc2_config_t configId = 0;
+#ifdef BYPASS_IHWC
int32_t intError = mDevice.mGetActiveConfig(mDevice.mHwcDevice, mId,
&configId);
+#else
+ auto intError = mDevice.mComposer->getActiveConfig(mId, configId);
+#endif
auto error = static_cast<Error>(intError);
if (error != Error::None) {
@@ -546,6 +633,7 @@
Error Display::getChangedCompositionTypes(
std::unordered_map<std::shared_ptr<Layer>, Composition>* outTypes)
{
+#ifdef BYPASS_IHWC
uint32_t numElements = 0;
int32_t intError = mDevice.mGetChangedCompositionTypes(mDevice.mHwcDevice,
mId, &numElements, nullptr, nullptr);
@@ -558,6 +646,14 @@
std::vector<int32_t> types(numElements);
intError = mDevice.mGetChangedCompositionTypes(mDevice.mHwcDevice, mId,
&numElements, layerIds.data(), types.data());
+#else
+ std::vector<Hwc2::Layer> layerIds;
+ std::vector<Hwc2::IComposer::Composition> types;
+ auto intError = mDevice.mComposer->getChangedCompositionTypes(mId,
+ layerIds, types);
+ uint32_t numElements = layerIds.size();
+ auto error = static_cast<Error>(intError);
+#endif
error = static_cast<Error>(intError);
if (error != Error::None) {
return error;
@@ -583,6 +679,7 @@
Error Display::getColorModes(std::vector<android_color_mode_t>* outModes) const
{
+#ifdef BYPASS_IHWC
uint32_t numModes = 0;
int32_t intError = mDevice.mGetColorModes(mDevice.mHwcDevice, mId,
&numModes, nullptr);
@@ -595,6 +692,12 @@
intError = mDevice.mGetColorModes(mDevice.mHwcDevice, mId, &numModes,
modes.data());
error = static_cast<Error>(intError);
+#else
+ std::vector<Hwc2::ColorMode> modes;
+ auto intError = mDevice.mComposer->getColorModes(mId, modes);
+ uint32_t numModes = modes.size();
+ auto error = static_cast<Error>(intError);
+#endif
if (error != Error::None) {
return error;
}
@@ -617,6 +720,7 @@
Error Display::getName(std::string* outName) const
{
+#ifdef BYPASS_IHWC
uint32_t size;
int32_t intError = mDevice.mGetDisplayName(mDevice.mHwcDevice, mId, &size,
nullptr);
@@ -635,12 +739,17 @@
*outName = std::string(rawName.cbegin(), rawName.cend());
return Error::None;
+#else
+ auto intError = mDevice.mComposer->getDisplayName(mId, *outName);
+ return static_cast<Error>(intError);
+#endif
}
Error Display::getRequests(HWC2::DisplayRequest* outDisplayRequests,
std::unordered_map<std::shared_ptr<Layer>, LayerRequest>*
outLayerRequests)
{
+#ifdef BYPASS_IHWC
int32_t intDisplayRequests = 0;
uint32_t numElements = 0;
int32_t intError = mDevice.mGetDisplayRequests(mDevice.mHwcDevice, mId,
@@ -656,6 +765,15 @@
&intDisplayRequests, &numElements, layerIds.data(),
layerRequests.data());
error = static_cast<Error>(intError);
+#else
+ uint32_t intDisplayRequests;
+ std::vector<Hwc2::Layer> layerIds;
+ std::vector<uint32_t> layerRequests;
+ auto intError = mDevice.mComposer->getDisplayRequests(mId,
+ intDisplayRequests, layerIds, layerRequests);
+ uint32_t numElements = layerIds.size();
+ auto error = static_cast<Error>(intError);
+#endif
if (error != Error::None) {
return error;
}
@@ -680,9 +798,15 @@
Error Display::getType(DisplayType* outType) const
{
+#ifdef BYPASS_IHWC
int32_t intType = 0;
int32_t intError = mDevice.mGetDisplayType(mDevice.mHwcDevice, mId,
&intType);
+#else
+ Hwc2::IComposer::DisplayType intType =
+ Hwc2::IComposer::DisplayType::INVALID;
+ auto intError = mDevice.mComposer->getDisplayType(mId, intType);
+#endif
auto error = static_cast<Error>(intError);
if (error != Error::None) {
return error;
@@ -694,9 +818,14 @@
Error Display::supportsDoze(bool* outSupport) const
{
+#ifdef BYPASS_IHWC
int32_t intSupport = 0;
int32_t intError = mDevice.mGetDozeSupport(mDevice.mHwcDevice, mId,
&intSupport);
+#else
+ bool intSupport = false;
+ auto intError = mDevice.mComposer->getDozeSupport(mId, intSupport);
+#endif
auto error = static_cast<Error>(intError);
if (error != Error::None) {
return error;
@@ -712,6 +841,7 @@
float maxLuminance = -1.0f;
float maxAverageLuminance = -1.0f;
float minLuminance = -1.0f;
+#ifdef BYPASS_IHWC
int32_t intError = mDevice.mGetHdrCapabilities(mDevice.mHwcDevice, mId,
&numTypes, nullptr, &maxLuminance, &maxAverageLuminance,
&minLuminance);
@@ -724,6 +854,18 @@
intError = mDevice.mGetHdrCapabilities(mDevice.mHwcDevice, mId, &numTypes,
types.data(), &maxLuminance, &maxAverageLuminance, &minLuminance);
error = static_cast<HWC2::Error>(intError);
+#else
+ std::vector<Hwc2::Hdr> intTypes;
+ auto intError = mDevice.mComposer->getHdrCapabilities(mId, intTypes,
+ maxLuminance, maxAverageLuminance, minLuminance);
+ auto error = static_cast<HWC2::Error>(intError);
+
+ std::vector<int32_t> types;
+ for (auto type : intTypes) {
+ types.push_back(static_cast<int32_t>(type));
+ }
+ numTypes = types.size();
+#endif
if (error != Error::None) {
return error;
}
@@ -736,6 +878,7 @@
Error Display::getReleaseFences(
std::unordered_map<std::shared_ptr<Layer>, sp<Fence>>* outFences) const
{
+#ifdef BYPASS_IHWC
uint32_t numElements = 0;
int32_t intError = mDevice.mGetReleaseFences(mDevice.mHwcDevice, mId,
&numElements, nullptr, nullptr);
@@ -749,6 +892,14 @@
intError = mDevice.mGetReleaseFences(mDevice.mHwcDevice, mId, &numElements,
layerIds.data(), fenceFds.data());
error = static_cast<Error>(intError);
+#else
+ std::vector<Hwc2::Layer> layerIds;
+ std::vector<int> fenceFds;
+ auto intError = mDevice.mComposer->getReleaseFences(mId,
+ layerIds, fenceFds);
+ auto error = static_cast<Error>(intError);
+ uint32_t numElements = layerIds.size();
+#endif
if (error != Error::None) {
return error;
}
@@ -774,8 +925,12 @@
Error Display::present(sp<Fence>* outRetireFence)
{
int32_t retireFenceFd = 0;
+#ifdef BYPASS_IHWC
int32_t intError = mDevice.mPresentDisplay(mDevice.mHwcDevice, mId,
&retireFenceFd);
+#else
+ auto intError = mDevice.mComposer->presentDisplay(mId, retireFenceFd);
+#endif
auto error = static_cast<Error>(intError);
if (error != Error::None) {
return error;
@@ -793,8 +948,12 @@
config->getDisplayId(), mId);
return Error::BadConfig;
}
+#ifdef BYPASS_IHWC
int32_t intError = mDevice.mSetActiveConfig(mDevice.mHwcDevice, mId,
config->getId());
+#else
+ auto intError = mDevice.mComposer->setActiveConfig(mId, config->getId());
+#endif
return static_cast<Error>(intError);
}
@@ -803,22 +962,38 @@
{
// TODO: Properly encode client target surface damage
int32_t fenceFd = acquireFence->dup();
+#ifdef BYPASS_IHWC
int32_t intError = mDevice.mSetClientTarget(mDevice.mHwcDevice, mId, target,
fenceFd, static_cast<int32_t>(dataspace), {0, nullptr});
+#else
+ auto intError = mDevice.mComposer->setClientTarget(mId, target, fenceFd,
+ static_cast<Hwc2::Dataspace>(dataspace),
+ std::vector<Hwc2::IComposer::Rect>());
+#endif
return static_cast<Error>(intError);
}
Error Display::setColorMode(android_color_mode_t mode)
{
+#ifdef BYPASS_IHWC
int32_t intError = mDevice.mSetColorMode(mDevice.mHwcDevice, mId, mode);
+#else
+ auto intError = mDevice.mComposer->setColorMode(mId,
+ static_cast<Hwc2::ColorMode>(mode));
+#endif
return static_cast<Error>(intError);
}
Error Display::setColorTransform(const android::mat4& matrix,
android_color_transform_t hint)
{
+#ifdef BYPASS_IHWC
int32_t intError = mDevice.mSetColorTransform(mDevice.mHwcDevice, mId,
matrix.asArray(), static_cast<int32_t>(hint));
+#else
+ auto intError = mDevice.mComposer->setColorTransform(mId,
+ matrix.asArray(), static_cast<Hwc2::ColorTransform>(hint));
+#endif
return static_cast<Error>(intError);
}
@@ -827,24 +1002,38 @@
{
int32_t fenceFd = releaseFence->dup();
auto handle = buffer->getNativeBuffer()->handle;
+#ifdef BYPASS_IHWC
int32_t intError = mDevice.mSetOutputBuffer(mDevice.mHwcDevice, mId, handle,
fenceFd);
+#else
+ auto intError = mDevice.mComposer->setOutputBuffer(mId, handle, fenceFd);
+#endif
close(fenceFd);
return static_cast<Error>(intError);
}
Error Display::setPowerMode(PowerMode mode)
{
+#ifdef BYPASS_IHWC
auto intMode = static_cast<int32_t>(mode);
int32_t intError = mDevice.mSetPowerMode(mDevice.mHwcDevice, mId, intMode);
+#else
+ auto intMode = static_cast<Hwc2::IComposer::PowerMode>(mode);
+ auto intError = mDevice.mComposer->setPowerMode(mId, intMode);
+#endif
return static_cast<Error>(intError);
}
Error Display::setVsyncEnabled(Vsync enabled)
{
+#ifdef BYPASS_IHWC
auto intEnabled = static_cast<int32_t>(enabled);
int32_t intError = mDevice.mSetVsyncEnabled(mDevice.mHwcDevice, mId,
intEnabled);
+#else
+ auto intEnabled = static_cast<Hwc2::IComposer::Vsync>(enabled);
+ auto intError = mDevice.mComposer->setVsyncEnabled(mId, intEnabled);
+#endif
return static_cast<Error>(intError);
}
@@ -852,8 +1041,13 @@
{
uint32_t numTypes = 0;
uint32_t numRequests = 0;
+#ifdef BYPASS_IHWC
int32_t intError = mDevice.mValidateDisplay(mDevice.mHwcDevice, mId,
&numTypes, &numRequests);
+#else
+ auto intError = mDevice.mComposer->validateDisplay(mId,
+ numTypes, numRequests);
+#endif
auto error = static_cast<Error>(intError);
if (error != Error::None && error != Error::HasChanges) {
return error;
@@ -869,8 +1063,14 @@
int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute)
{
int32_t value = 0;
+#ifdef BYPASS_IHWC
int32_t intError = mDevice.mGetDisplayAttribute(mDevice.mHwcDevice, mId,
configId, static_cast<int32_t>(attribute), &value);
+#else
+ auto intError = mDevice.mComposer->getDisplayAttribute(mId,
+ configId, static_cast<Hwc2::IComposer::Attribute>(attribute),
+ value);
+#endif
auto error = static_cast<Error>(intError);
if (error != Error::None) {
ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId,
@@ -899,6 +1099,7 @@
{
ALOGV("[%" PRIu64 "] loadConfigs", mId);
+#ifdef BYPASS_IHWC
uint32_t numConfigs = 0;
int32_t intError = mDevice.mGetDisplayConfigs(mDevice.mHwcDevice, mId,
&numConfigs, nullptr);
@@ -913,6 +1114,11 @@
intError = mDevice.mGetDisplayConfigs(mDevice.mHwcDevice, mId, &numConfigs,
configIds.data());
error = static_cast<Error>(intError);
+#else
+ std::vector<Hwc2::Config> configIds;
+ auto intError = mDevice.mComposer->getDisplayConfigs(mId, configIds);
+ auto error = static_cast<Error>(intError);
+#endif
if (error != Error::None) {
ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId,
to_string(error).c_str(), intError);
@@ -928,7 +1134,11 @@
void Display::destroyLayer(hwc2_layer_t layerId)
{
+#ifdef BYPASS_IHWC
int32_t intError = mDevice.mDestroyLayer(mDevice.mHwcDevice, mId, layerId);
+#else
+ auto intError =mDevice.mComposer->destroyLayer(mId, layerId);
+#endif
auto error = static_cast<Error>(intError);
ALOGE_IF(error != Error::None, "destroyLayer(%" PRIu64 ", %" PRIu64 ")"
" failed: %s (%d)", mId, layerId, to_string(error).c_str(),
@@ -970,8 +1180,13 @@
Error Layer::setCursorPosition(int32_t x, int32_t y)
{
+#ifdef BYPASS_IHWC
int32_t intError = mDevice.mSetCursorPosition(mDevice.mHwcDevice,
mDisplayId, mId, x, y);
+#else
+ auto intError = mDevice.mComposer->setCursorPosition(mDisplayId,
+ mId, x, y);
+#endif
return static_cast<Error>(intError);
}
@@ -979,8 +1194,13 @@
const sp<Fence>& acquireFence)
{
int32_t fenceFd = acquireFence->dup();
+#ifdef BYPASS_IHWC
int32_t intError = mDevice.mSetLayerBuffer(mDevice.mHwcDevice, mDisplayId,
mId, buffer, fenceFd);
+#else
+ auto intError = mDevice.mComposer->setLayerBuffer(mDisplayId,
+ mId, buffer, fenceFd);
+#endif
return static_cast<Error>(intError);
}
@@ -988,26 +1208,44 @@
{
// We encode default full-screen damage as INVALID_RECT upstream, but as 0
// rects for HWC
+#ifdef BYPASS_IHWC
int32_t intError = 0;
+#else
+ Hwc2::Error intError = Hwc2::Error::NONE;
+#endif
if (damage.isRect() && damage.getBounds() == Rect::INVALID_RECT) {
+#ifdef BYPASS_IHWC
intError = mDevice.mSetLayerSurfaceDamage(mDevice.mHwcDevice,
mDisplayId, mId, {0, nullptr});
+#else
+ intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId,
+ mId, std::vector<Hwc2::IComposer::Rect>());
+#endif
} else {
size_t rectCount = 0;
auto rectArray = damage.getArray(&rectCount);
+#ifdef BYPASS_IHWC
std::vector<hwc_rect_t> hwcRects;
+#else
+ std::vector<Hwc2::IComposer::Rect> hwcRects;
+#endif
for (size_t rect = 0; rect < rectCount; ++rect) {
hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
rectArray[rect].right, rectArray[rect].bottom});
}
+#ifdef BYPASS_IHWC
hwc_region_t hwcRegion = {};
hwcRegion.numRects = rectCount;
hwcRegion.rects = hwcRects.data();
intError = mDevice.mSetLayerSurfaceDamage(mDevice.mHwcDevice,
mDisplayId, mId, hwcRegion);
+#else
+ intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId,
+ mId, hwcRects);
+#endif
}
return static_cast<Error>(intError);
@@ -1015,47 +1253,83 @@
Error Layer::setBlendMode(BlendMode mode)
{
+#ifdef BYPASS_IHWC
auto intMode = static_cast<int32_t>(mode);
int32_t intError = mDevice.mSetLayerBlendMode(mDevice.mHwcDevice,
mDisplayId, mId, intMode);
+#else
+ auto intMode = static_cast<Hwc2::IComposer::BlendMode>(mode);
+ auto intError = mDevice.mComposer->setLayerBlendMode(mDisplayId,
+ mId, intMode);
+#endif
return static_cast<Error>(intError);
}
Error Layer::setColor(hwc_color_t color)
{
+#ifdef BYPASS_IHWC
int32_t intError = mDevice.mSetLayerColor(mDevice.mHwcDevice, mDisplayId,
mId, color);
+#else
+ Hwc2::IComposer::Color hwcColor{color.r, color.g, color.b, color.a};
+ auto intError = mDevice.mComposer->setLayerColor(mDisplayId,
+ mId, hwcColor);
+#endif
return static_cast<Error>(intError);
}
Error Layer::setCompositionType(Composition type)
{
+#ifdef BYPASS_IHWC
auto intType = static_cast<int32_t>(type);
int32_t intError = mDevice.mSetLayerCompositionType(mDevice.mHwcDevice,
mDisplayId, mId, intType);
+#else
+ auto intType = static_cast<Hwc2::IComposer::Composition>(type);
+ auto intError = mDevice.mComposer->setLayerCompositionType(mDisplayId,
+ mId, intType);
+#endif
return static_cast<Error>(intError);
}
Error Layer::setDataspace(android_dataspace_t dataspace)
{
+#ifdef BYPASS_IHWC
auto intDataspace = static_cast<int32_t>(dataspace);
int32_t intError = mDevice.mSetLayerDataspace(mDevice.mHwcDevice,
mDisplayId, mId, intDataspace);
+#else
+ auto intDataspace = static_cast<Hwc2::Dataspace>(dataspace);
+ auto intError = mDevice.mComposer->setLayerDataspace(mDisplayId,
+ mId, intDataspace);
+#endif
return static_cast<Error>(intError);
}
Error Layer::setDisplayFrame(const Rect& frame)
{
+#ifdef BYPASS_IHWC
hwc_rect_t hwcRect{frame.left, frame.top, frame.right, frame.bottom};
int32_t intError = mDevice.mSetLayerDisplayFrame(mDevice.mHwcDevice,
mDisplayId, mId, hwcRect);
+#else
+ Hwc2::IComposer::Rect hwcRect{frame.left, frame.top,
+ frame.right, frame.bottom};
+ auto intError = mDevice.mComposer->setLayerDisplayFrame(mDisplayId,
+ mId, hwcRect);
+#endif
return static_cast<Error>(intError);
}
Error Layer::setPlaneAlpha(float alpha)
{
+#ifdef BYPASS_IHWC
int32_t intError = mDevice.mSetLayerPlaneAlpha(mDevice.mHwcDevice,
mDisplayId, mId, alpha);
+#else
+ auto intError = mDevice.mComposer->setLayerPlaneAlpha(mDisplayId,
+ mId, alpha);
+#endif
return static_cast<Error>(intError);
}
@@ -1066,24 +1340,42 @@
"device supports sideband streams");
return Error::Unsupported;
}
+#ifdef BYPASS_IHWC
int32_t intError = mDevice.mSetLayerSidebandStream(mDevice.mHwcDevice,
mDisplayId, mId, stream);
+#else
+ auto intError = mDevice.mComposer->setLayerSidebandStream(mDisplayId,
+ mId, stream);
+#endif
return static_cast<Error>(intError);
}
Error Layer::setSourceCrop(const FloatRect& crop)
{
+#ifdef BYPASS_IHWC
hwc_frect_t hwcRect{crop.left, crop.top, crop.right, crop.bottom};
int32_t intError = mDevice.mSetLayerSourceCrop(mDevice.mHwcDevice,
mDisplayId, mId, hwcRect);
+#else
+ Hwc2::IComposer::FRect hwcRect{
+ crop.left, crop.top, crop.right, crop.bottom};
+ auto intError = mDevice.mComposer->setLayerSourceCrop(mDisplayId,
+ mId, hwcRect);
+#endif
return static_cast<Error>(intError);
}
Error Layer::setTransform(Transform transform)
{
+#ifdef BYPASS_IHWC
auto intTransform = static_cast<int32_t>(transform);
int32_t intError = mDevice.mSetLayerTransform(mDevice.mHwcDevice,
mDisplayId, mId, intTransform);
+#else
+ auto intTransform = static_cast<Hwc2::Transform>(transform);
+ auto intError = mDevice.mComposer->setLayerTransform(mDisplayId,
+ mId, intTransform);
+#endif
return static_cast<Error>(intError);
}
@@ -1092,25 +1384,38 @@
size_t rectCount = 0;
auto rectArray = region.getArray(&rectCount);
+#ifdef BYPASS_IHWC
std::vector<hwc_rect_t> hwcRects;
+#else
+ std::vector<Hwc2::IComposer::Rect> hwcRects;
+#endif
for (size_t rect = 0; rect < rectCount; ++rect) {
hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
rectArray[rect].right, rectArray[rect].bottom});
}
+#ifdef BYPASS_IHWC
hwc_region_t hwcRegion = {};
hwcRegion.numRects = rectCount;
hwcRegion.rects = hwcRects.data();
int32_t intError = mDevice.mSetLayerVisibleRegion(mDevice.mHwcDevice,
mDisplayId, mId, hwcRegion);
+#else
+ auto intError = mDevice.mComposer->setLayerVisibleRegion(mDisplayId,
+ mId, hwcRects);
+#endif
return static_cast<Error>(intError);
}
Error Layer::setZOrder(uint32_t z)
{
+#ifdef BYPASS_IHWC
int32_t intError = mDevice.mSetLayerZOrder(mDevice.mHwcDevice, mDisplayId,
mId, z);
+#else
+ auto intError = mDevice.mComposer->setLayerZOrder(mDisplayId, mId, z);
+#endif
return static_cast<Error>(intError);
}
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 32a9de0..1145ba1 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -17,6 +17,10 @@
#ifndef ANDROID_SF_HWC2_H
#define ANDROID_SF_HWC2_H
+#ifndef USE_HWC2
+#define BYPASS_IHWC
+#endif
+
#define HWC2_INCLUDE_STRINGIFICATION
#define HWC2_USE_CPP11
#include <hardware/hwcomposer2.h>
@@ -42,6 +46,9 @@
class GraphicBuffer;
class Rect;
class Region;
+ namespace Hwc2 {
+ class Composer;
+ };
}
namespace HWC2 {
@@ -57,7 +64,11 @@
class Device
{
public:
+#ifdef BYPASS_IHWC
explicit Device(hwc2_device_t* device);
+#else
+ Device();
+#endif
~Device();
friend class HWC2::Display;
@@ -98,6 +109,7 @@
private:
// Initialization methods
+#ifdef BYPASS_IHWC
template <typename PFN>
[[clang::warn_unused_result]] bool loadFunctionPointer(
FunctionDescriptor desc, PFN& outPFN) {
@@ -121,6 +133,7 @@
auto pfn = reinterpret_cast<hwc2_function_pointer_t>(hook);
mRegisterCallback(mHwcDevice, intCallback, callbackData, pfn);
}
+#endif
void loadCapabilities();
void loadFunctionPointers();
@@ -132,6 +145,7 @@
// Member variables
+#ifdef BYPASS_IHWC
hwc2_device_t* mHwcDevice;
// Device function pointers
@@ -181,6 +195,9 @@
HWC2_PFN_SET_LAYER_TRANSFORM mSetLayerTransform;
HWC2_PFN_SET_LAYER_VISIBLE_REGION mSetLayerVisibleRegion;
HWC2_PFN_SET_LAYER_Z_ORDER mSetLayerZOrder;
+#else
+ std::unique_ptr<android::Hwc2::Composer> mComposer;
+#endif // BYPASS_IHWC
std::unordered_set<Capability> mCapabilities;
std::unordered_map<hwc2_display_t, std::weak_ptr<Display>> mDisplays;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index c87ba72..bb2e45a 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -109,6 +109,7 @@
{
ALOGV("loadHwcModule");
+#ifdef BYPASS_IHWC
hw_module_t const* module;
if (hw_get_module(HWC_HARDWARE_MODULE_ID, &module) != 0) {
@@ -140,6 +141,9 @@
mHwcDevice = std::make_unique<HWC2::Device>(
static_cast<hwc2_device_t*>(mAdapter.get()));
}
+#else
+ mHwcDevice = std::make_unique<HWC2::Device>();
+#endif
mRemainingHwcVirtualDisplays = mHwcDevice->getMaxVirtualDisplayCount();
}