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

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

graphics: add a default implementation to IMapper

The default implementatoin is built on top of conventional gralloc1.

Test: make android.hardware.graphics.mapper.hallib
Change-Id: I8647dc69dbb1637a141d36358d5769f450422ac1
parent 9af67ec5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ subdirs = [
    "graphics/allocator/2.0",
    "graphics/allocator/2.0/default",
    "graphics/mapper/2.0",
    "graphics/mapper/2.0/default",
    "memtrack/1.0",
    "memtrack/1.0/default",
    "nfc/1.0",
+28 −0
Original line number Diff line number Diff line
// 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.

cc_library_shared {
    name: "android.hardware.graphics.mapper.hallib",
    relative_install_path: "hw",
    srcs: ["GrallocMapper.cpp"],
    cppflags: ["-Wall", "-Wextra"],
    static_libs: ["android.hardware.graphics.mapper@2.0"],
    shared_libs: [
        "android.hardware.graphics.allocator@2.0",
        "libhardware",
        "libhidl",
        "libhwbinder",
        "liblog",
    ],
}
+373 −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.
 */

#define LOG_TAG "GrallocMapperPassthrough"

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

namespace android {
namespace hardware {
namespace graphics {
namespace mapper {
namespace V2_0 {
namespace implementation {

class GrallocDevice : public Device {
public:
    GrallocDevice();
    ~GrallocDevice();

    // IMapper interface
    Error retain(const native_handle_t* bufferHandle);
    Error release(const native_handle_t* bufferHandle);
    Error getDimensions(const native_handle_t* bufferHandle,
            uint32_t* outWidth, uint32_t* outHeight);
    Error getFormat(const native_handle_t* bufferHandle,
            PixelFormat* outFormat);
    Error getProducerUsageMask(const native_handle_t* bufferHandle,
            uint64_t* outUsageMask);
    Error getConsumerUsageMask(const native_handle_t* bufferHandle,
            uint64_t* outUsageMask);
    Error getBackingStore(const native_handle_t* bufferHandle,
            BackingStore* outStore);
    Error getStride(const native_handle_t* bufferHandle, uint32_t* outStride);
    Error getNumFlexPlanes(const native_handle_t* bufferHandle,
            uint32_t* outNumPlanes);
    Error lock(const native_handle_t* bufferHandle,
            uint64_t producerUsageMask, uint64_t consumerUsageMask,
            const Rect* accessRegion, int32_t acquireFence, void** outData);
    Error lockFlex(const native_handle_t* bufferHandle,
            uint64_t producerUsageMask, uint64_t consumerUsageMask,
            const Rect* accessRegion, int32_t acquireFence,
            FlexLayout* outFlexLayout);
    Error unlock(const native_handle_t* bufferHandle,
            int32_t* outReleaseFence);

private:
    void initDispatch();

    gralloc1_device_t* mDevice;

    struct {
        GRALLOC1_PFN_RETAIN retain;
        GRALLOC1_PFN_RELEASE release;
        GRALLOC1_PFN_GET_DIMENSIONS getDimensions;
        GRALLOC1_PFN_GET_FORMAT getFormat;
        GRALLOC1_PFN_GET_PRODUCER_USAGE getProducerUsage;
        GRALLOC1_PFN_GET_CONSUMER_USAGE getConsumerUsage;
        GRALLOC1_PFN_GET_BACKING_STORE getBackingStore;
        GRALLOC1_PFN_GET_STRIDE getStride;
        GRALLOC1_PFN_GET_NUM_FLEX_PLANES getNumFlexPlanes;
        GRALLOC1_PFN_LOCK lock;
        GRALLOC1_PFN_LOCK_FLEX lockFlex;
        GRALLOC1_PFN_UNLOCK unlock;
    } mDispatch;
};

GrallocDevice::GrallocDevice()
{
    const hw_module_t* module;
    int status = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
    if (status) {
        LOG_ALWAYS_FATAL("failed to get gralloc module");
    }

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

    status = gralloc1_open(module, &mDevice);
    if (status) {
        LOG_ALWAYS_FATAL("failed to open gralloc1 device");
    }

    initDispatch();
}

GrallocDevice::~GrallocDevice()
{
    gralloc1_close(mDevice);
}

void GrallocDevice::initDispatch()
{
#define CHECK_FUNC(func, desc) do {                                   \
    mDispatch.func = reinterpret_cast<decltype(mDispatch.func)>(      \
        mDevice->getFunction(mDevice, desc));                         \
    if (!mDispatch.func) {                                            \
        LOG_ALWAYS_FATAL("failed to get gralloc1 function %d", desc); \
    }                                                                 \
} while (0)

    CHECK_FUNC(retain, GRALLOC1_FUNCTION_RETAIN);
    CHECK_FUNC(release, GRALLOC1_FUNCTION_RELEASE);
    CHECK_FUNC(getDimensions, GRALLOC1_FUNCTION_GET_DIMENSIONS);
    CHECK_FUNC(getFormat, GRALLOC1_FUNCTION_GET_FORMAT);
    CHECK_FUNC(getProducerUsage, GRALLOC1_FUNCTION_GET_PRODUCER_USAGE);
    CHECK_FUNC(getConsumerUsage, GRALLOC1_FUNCTION_GET_CONSUMER_USAGE);
    CHECK_FUNC(getBackingStore, GRALLOC1_FUNCTION_GET_BACKING_STORE);
    CHECK_FUNC(getStride, GRALLOC1_FUNCTION_GET_STRIDE);
    CHECK_FUNC(getNumFlexPlanes, GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES);
    CHECK_FUNC(lock, GRALLOC1_FUNCTION_LOCK);
    CHECK_FUNC(lockFlex, GRALLOC1_FUNCTION_LOCK_FLEX);
    CHECK_FUNC(unlock, GRALLOC1_FUNCTION_UNLOCK);

#undef CHECK_FUNC
}

Error GrallocDevice::retain(const native_handle_t* bufferHandle)
{
    int32_t error = mDispatch.retain(mDevice, bufferHandle);
    return static_cast<Error>(error);
}

Error GrallocDevice::release(const native_handle_t* bufferHandle)
{
    int32_t error = mDispatch.release(mDevice, bufferHandle);
    return static_cast<Error>(error);
}

Error GrallocDevice::getDimensions(const native_handle_t* bufferHandle,
        uint32_t* outWidth, uint32_t* outHeight)
{
    int32_t error = mDispatch.getDimensions(mDevice, bufferHandle,
            outWidth, outHeight);
    return static_cast<Error>(error);
}

Error GrallocDevice::getFormat(const native_handle_t* bufferHandle,
        PixelFormat* outFormat)
{
    int32_t error = mDispatch.getFormat(mDevice, bufferHandle,
            reinterpret_cast<int32_t*>(outFormat));
    return static_cast<Error>(error);
}

Error GrallocDevice::getProducerUsageMask(const native_handle_t* bufferHandle,
        uint64_t* outUsageMask)
{
    int32_t error = mDispatch.getProducerUsage(mDevice, bufferHandle,
            outUsageMask);
    return static_cast<Error>(error);
}

Error GrallocDevice::getConsumerUsageMask(const native_handle_t* bufferHandle,
        uint64_t* outUsageMask)
{
    int32_t error = mDispatch.getConsumerUsage(mDevice, bufferHandle,
            outUsageMask);
    return static_cast<Error>(error);
}

Error GrallocDevice::getBackingStore(const native_handle_t* bufferHandle,
        BackingStore* outStore)
{
    int32_t error = mDispatch.getBackingStore(mDevice, bufferHandle,
            outStore);
    return static_cast<Error>(error);
}

Error GrallocDevice::getStride(const native_handle_t* bufferHandle,
        uint32_t* outStride)
{
    int32_t error = mDispatch.getStride(mDevice, bufferHandle, outStride);
    return static_cast<Error>(error);
}

Error GrallocDevice::getNumFlexPlanes(const native_handle_t* bufferHandle,
        uint32_t* outNumPlanes)
{
    int32_t error = mDispatch.getNumFlexPlanes(mDevice, bufferHandle,
            outNumPlanes);
    return static_cast<Error>(error);
}

Error GrallocDevice::lock(const native_handle_t* bufferHandle,
        uint64_t producerUsageMask, uint64_t consumerUsageMask,
        const Rect* accessRegion, int32_t acquireFence,
        void** outData)
{
    int32_t error = mDispatch.lock(mDevice, bufferHandle,
            producerUsageMask, consumerUsageMask,
            reinterpret_cast<const gralloc1_rect_t*>(accessRegion),
            outData, acquireFence);
    return static_cast<Error>(error);
}

Error GrallocDevice::lockFlex(const native_handle_t* bufferHandle,
        uint64_t producerUsageMask, uint64_t consumerUsageMask,
        const Rect* accessRegion, int32_t acquireFence,
        FlexLayout* outFlexLayout)
{
    int32_t error = mDispatch.lockFlex(mDevice, bufferHandle,
            producerUsageMask, consumerUsageMask,
            reinterpret_cast<const gralloc1_rect_t*>(accessRegion),
            reinterpret_cast<android_flex_layout_t*>(outFlexLayout),
            acquireFence);
    return static_cast<Error>(error);
}

Error GrallocDevice::unlock(const native_handle_t* bufferHandle,
        int32_t* outReleaseFence)
{
    int32_t error = mDispatch.unlock(mDevice, bufferHandle, outReleaseFence);
    return static_cast<Error>(error);
}

class GrallocMapper : public IMapper {
public:
    GrallocMapper() : IMapper{
        .createDevice = createDevice,
        .destroyDevice = destroyDevice,
        .retain = retain,
        .release = release,
        .getDimensions = getDimensions,
        .getFormat = getFormat,
        .getProducerUsageMask = getProducerUsageMask,
        .getConsumerUsageMask = getConsumerUsageMask,
        .getBackingStore = getBackingStore,
        .getStride = getStride,
        .getNumFlexPlanes = getNumFlexPlanes,
        .lock = lock,
        .lockFlex = lockFlex,
        .unlock = unlock,
    } {}

    const IMapper* getInterface() const
    {
        return static_cast<const IMapper*>(this);
    }

private:
    static GrallocDevice* cast(Device* device)
    {
        return reinterpret_cast<GrallocDevice*>(device);
    }

    static Error createDevice(Device** outDevice)
    {
        *outDevice = new GrallocDevice;
        return Error::NONE;
    }

    static Error destroyDevice(Device* device)
    {
        delete cast(device);
        return Error::NONE;
    }

    static Error retain(Device* device,
            const native_handle_t* bufferHandle)
    {
        return cast(device)->retain(bufferHandle);
    }

    static Error release(Device* device,
            const native_handle_t* bufferHandle)
    {
        return cast(device)->release(bufferHandle);
    }

    static Error getDimensions(Device* device,
            const native_handle_t* bufferHandle,
            uint32_t* outWidth, uint32_t* outHeight)
    {
        return cast(device)->getDimensions(bufferHandle, outWidth, outHeight);
    }

    static Error getFormat(Device* device,
            const native_handle_t* bufferHandle, PixelFormat* outFormat)
    {
        return cast(device)->getFormat(bufferHandle, outFormat);
    }

    static Error getProducerUsageMask(Device* device,
            const native_handle_t* bufferHandle, uint64_t* outUsageMask)
    {
        return cast(device)->getProducerUsageMask(bufferHandle, outUsageMask);
    }

    static Error getConsumerUsageMask(Device* device,
            const native_handle_t* bufferHandle, uint64_t* outUsageMask)
    {
        return cast(device)->getConsumerUsageMask(bufferHandle, outUsageMask);
    }

    static Error getBackingStore(Device* device,
            const native_handle_t* bufferHandle, BackingStore* outStore)
    {
        return cast(device)->getBackingStore(bufferHandle, outStore);
    }

    static Error getStride(Device* device,
            const native_handle_t* bufferHandle, uint32_t* outStride)
    {
        return cast(device)->getStride(bufferHandle, outStride);
    }

    static Error getNumFlexPlanes(Device* device,
            const native_handle_t* bufferHandle, uint32_t* outNumPlanes)
    {
        return cast(device)->getNumFlexPlanes(bufferHandle, outNumPlanes);
    }

    static Error lock(Device* device,
            const native_handle_t* bufferHandle,
            uint64_t producerUsageMask, uint64_t consumerUsageMask,
            const Device::Rect* accessRegion, int32_t acquireFence,
            void** outData)
    {
        return cast(device)->lock(bufferHandle,
                producerUsageMask, consumerUsageMask,
                accessRegion, acquireFence, outData);
    }

    static Error lockFlex(Device* device,
            const native_handle_t* bufferHandle,
            uint64_t producerUsageMask, uint64_t consumerUsageMask,
            const Device::Rect* accessRegion, int32_t acquireFence,
            FlexLayout* outFlexLayout)
    {
        return cast(device)->lockFlex(bufferHandle,
                producerUsageMask, consumerUsageMask,
                accessRegion, acquireFence, outFlexLayout);
    }

    static Error unlock(Device* device,
            const native_handle_t* bufferHandle, int32_t* outReleaseFence)
    {
        return cast(device)->unlock(bufferHandle, outReleaseFence);
    }
};

extern "C" const void* HALLIB_FETCH_Interface(const char* name)
{
    if (strcmp(name, "android.hardware.graphics.mapper@2.0::IMapper") == 0) {
        static GrallocMapper sGrallocMapper;
        return sGrallocMapper.getInterface();
    }

    return nullptr;
}

} // namespace implementation
} // namespace V2_0
} // namespace mapper
} // namespace graphics
} // namespace hardware
} // namespace android