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

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

graphics: use mapper from the composer

We must use the mapper HAL instead of gralloc0/gralloc1 from the
composer.

Bug: 37540361
Test: boots on marlin, angler, and ryu
Change-Id: I5a3ff6a025bf51a3507a4f33fa77e9506a6f1ec9
parent ec74596a
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -5,8 +5,8 @@ cc_library_static {
    export_include_dirs: ["."],
    srcs: ["ComposerClient.cpp"],
    shared_libs: [
        "android.hardware.graphics.allocator@2.0",
        "android.hardware.graphics.composer@2.1",
        "android.hardware.graphics.mapper@2.0",
        "libbase",
        "libcutils",
        "libfmq",
@@ -27,8 +27,8 @@ cc_library_shared {
    srcs: ["Hwc.cpp"],
    static_libs: ["libhwcomposer-client"],
    shared_libs: [
        "android.hardware.graphics.allocator@2.0",
        "android.hardware.graphics.composer@2.1",
        "android.hardware.graphics.mapper@2.0",
        "libbase",
        "libcutils",
        "libfmq",
@@ -51,7 +51,6 @@ cc_binary {
    init_rc: ["android.hardware.graphics.composer@2.1-service.rc"],
    static_libs: ["libhwcomposer-client"],
    shared_libs: [
        "android.hardware.graphics.allocator@2.0",
        "android.hardware.graphics.composer@2.1",
        "libbase",
        "libbinder",
+20 −108
Original line number Diff line number Diff line
@@ -16,8 +16,7 @@

#define LOG_TAG "HwcPassthrough"

#include <hardware/gralloc.h>
#include <hardware/gralloc1.h>
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
#include <log/log.h>

#include "ComposerClient.h"
@@ -33,10 +32,11 @@ namespace implementation {

namespace {

using MapperError = android::hardware::graphics::mapper::V2_0::Error;
using android::hardware::graphics::mapper::V2_0::IMapper;

class HandleImporter {
public:
    HandleImporter() : mInitialized(false) {}

    bool initialize()
    {
        // allow only one client
@@ -44,9 +44,7 @@ public:
            return false;
        }

        if (!openGralloc()) {
            return false;
        }
        mMapper = IMapper::getService();

        mInitialized = true;
        return true;
@@ -54,11 +52,7 @@ public:

    void cleanup()
    {
        if (!mInitialized) {
            return;
        }

        closeGralloc();
        mMapper.clear();
        mInitialized = false;
    }

@@ -76,12 +70,20 @@ public:
            return true;
        }

        buffer_handle_t clone = cloneBuffer(handle);
        if (!clone) {
        MapperError error;
        buffer_handle_t importedHandle;
        mMapper->importBuffer(
            hidl_handle(handle),
            [&](const auto& tmpError, const auto& tmpBufferHandle) {
                error = tmpError;
                importedHandle = static_cast<buffer_handle_t>(tmpBufferHandle);
            });
        if (error != MapperError::NONE) {
            return false;
        }

        handle = clone;
        handle = importedHandle;

        return true;
    }

@@ -91,102 +93,12 @@ public:
            return;
        }

        releaseBuffer(handle);
        mMapper->freeBuffer(const_cast<native_handle_t*>(handle));
    }

private:
    bool mInitialized;

    // Some existing gralloc drivers do not support retaining more than once,
    // when we are in passthrough mode.
    bool openGralloc()
    {
        const hw_module_t* module = nullptr;
        int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
        if (err) {
            ALOGE("failed to get gralloc module");
            return false;
        }

        uint8_t major = (module->module_api_version >> 8) & 0xff;
        if (major > 1) {
            ALOGE("unknown gralloc module major version %d", major);
            return false;
        }

        if (major == 1) {
            err = gralloc1_open(module, &mDevice);
            if (err) {
                ALOGE("failed to open gralloc1 device");
                return false;
            }

            mRetain = reinterpret_cast<GRALLOC1_PFN_RETAIN>(
                    mDevice->getFunction(mDevice, GRALLOC1_FUNCTION_RETAIN));
            mRelease = reinterpret_cast<GRALLOC1_PFN_RELEASE>(
                    mDevice->getFunction(mDevice, GRALLOC1_FUNCTION_RELEASE));
            if (!mRetain || !mRelease) {
                ALOGE("invalid gralloc1 device");
                gralloc1_close(mDevice);
                return false;
            }
        } else {
            mModule = reinterpret_cast<const gralloc_module_t*>(module);
        }

        return true;
    }

    void closeGralloc()
    {
        if (mDevice) {
            gralloc1_close(mDevice);
        }
    }

    buffer_handle_t cloneBuffer(buffer_handle_t handle)
    {
        native_handle_t* clone = native_handle_clone(handle);
        if (!clone) {
            ALOGE("failed to clone buffer %p", handle);
            return nullptr;
        }

        bool err;
        if (mDevice) {
            err = (mRetain(mDevice, clone) != GRALLOC1_ERROR_NONE);
        } else {
            err = (mModule->registerBuffer(mModule, clone) != 0);
        }

        if (err) {
            ALOGE("failed to retain/register buffer %p", clone);
            native_handle_close(clone);
            native_handle_delete(clone);
            return nullptr;
        }

        return clone;
    }

    void releaseBuffer(buffer_handle_t handle)
    {
        if (mDevice) {
            mRelease(mDevice, handle);
        } else {
            mModule->unregisterBuffer(mModule, handle);
        }
        native_handle_close(handle);
        native_handle_delete(const_cast<native_handle_t*>(handle));
    }

    // gralloc1
    gralloc1_device_t* mDevice;
    GRALLOC1_PFN_RETAIN mRetain;
    GRALLOC1_PFN_RELEASE mRelease;

    // gralloc0
    const gralloc_module_t* mModule;
 bool mInitialized = false;
 sp<IMapper> mMapper;
};

HandleImporter sHandleImporter;