Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aab99f57 authored by Chia-I Wu's avatar Chia-I Wu
Browse files

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
parent a8e2af1c
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ LOCAL_SRC_FILES := \
    SurfaceFlingerConsumer.cpp \
    SurfaceInterceptor.cpp \
    Transform.cpp \
    DisplayHardware/ComposerHal.cpp \
    DisplayHardware/FramebufferSurface.cpp \
    DisplayHardware/HWC2.cpp \
    DisplayHardware/HWC2On1Adapter.cpp \
@@ -129,10 +130,14 @@ LOCAL_CFLAGS += -fvisibility=hidden -Werror=format

LOCAL_STATIC_LIBRARIES := libtrace_proto libvkjson
LOCAL_SHARED_LIBRARIES := \
    android.hardware.graphics.allocator@2.0 \
    android.hardware.graphics.composer@2.1 \
    libcutils \
    liblog \
    libdl \
    libhardware \
    libhidl \
    libhwbinder \
    libutils \
    libEGL \
    libGLESv1_CM \
@@ -149,6 +154,12 @@ LOCAL_SHARED_LIBRARIES := \
    libutils \
    android.hardware.power@1.0

LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \
    android.hardware.graphics.allocator@2.0 \
    android.hardware.graphics.composer@2.1 \
    libhidl \
    libhwbinder

LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code

include $(BUILD_SHARED_LIBRARY)
+650 −0
Original line number Diff line number Diff line
/*
 * 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
+142 −0

File added.

Preview size limit exceeded, changes collapsed.

+305 −0

File changed.

Preview size limit exceeded, changes collapsed.

+17 −0
Original line number Diff line number Diff line
@@ -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 @@ namespace android {
    class GraphicBuffer;
    class Rect;
    class Region;
    namespace Hwc2 {
        class Composer;
    };
}

namespace HWC2 {
@@ -57,7 +64,11 @@ typedef std::function<void(std::shared_ptr<Display>, nsecs_t)> VsyncCallback;
class Device
{
public:
#ifdef BYPASS_IHWC
    explicit Device(hwc2_device_t* device);
#else
    Device();
#endif
    ~Device();

    friend class HWC2::Display;
@@ -98,6 +109,7 @@ public:
private:
    // Initialization methods

#ifdef BYPASS_IHWC
    template <typename PFN>
    [[clang::warn_unused_result]] bool loadFunctionPointer(
            FunctionDescriptor desc, PFN& outPFN) {
@@ -121,6 +133,7 @@ private:
        auto pfn = reinterpret_cast<hwc2_function_pointer_t>(hook);
        mRegisterCallback(mHwcDevice, intCallback, callbackData, pfn);
    }
#endif

    void loadCapabilities();
    void loadFunctionPointers();
@@ -132,6 +145,7 @@ private:

    // Member variables

#ifdef BYPASS_IHWC
    hwc2_device_t* mHwcDevice;

    // Device function pointers
@@ -181,6 +195,9 @@ private:
    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;
Loading