1076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian/*
2076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * Copyright (C) 2007 The Android Open Source Project
3076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian *
4076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License");
5076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * you may not use this file except in compliance with the License.
6076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * You may obtain a copy of the License at
7076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian *
8076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian *      http://www.apache.org/licenses/LICENSE-2.0
9076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian *
10076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * Unless required by applicable law or agreed to in writing, software
11076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS,
12076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * See the License for the specific language governing permissions and
14076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * limitations under the License.
15076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian */
16076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
173330b203039dea366d4981db1408a460134b2d2cMathias Agopian#define LOG_TAG "GraphicBufferMapper"
18cf56319d4deb2215e5274f321f7fee71caa1ada1Mathias Agopian#define ATRACE_TAG ATRACE_TAG_GRAPHICS
198deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza//#define LOG_NDEBUG 0
20076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
21fe2f54fc8a9810708fe05d719721af19aea10a4aMathias Agopian#include <ui/GraphicBufferMapper.h>
22076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
235bac7f36ee9d5ed0c2e8a0141909ca94351965a8Chia-I Wu#include <grallocusage/GrallocUsageConversion.h>
245bac7f36ee9d5ed0c2e8a0141909ca94351965a8Chia-I Wu
25d31824004277f554000417cea349d69f18655e95Dan Stoza// We would eliminate the non-conforming zero-length array, but we can't since
26d31824004277f554000417cea349d69f18655e95Dan Stoza// this is effectively included from the Linux kernel
27d31824004277f554000417cea349d69f18655e95Dan Stoza#pragma clang diagnostic push
28d31824004277f554000417cea349d69f18655e95Dan Stoza#pragma clang diagnostic ignored "-Wzero-length-array"
298f3960179c56767e5077be8337792bd4e244b7d7Francis Hart#include <sync/sync.h>
30d31824004277f554000417cea349d69f18655e95Dan Stoza#pragma clang diagnostic pop
318f3960179c56767e5077be8337792bd4e244b7d7Francis Hart
32076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <utils/Log.h>
33cf56319d4deb2215e5274f321f7fee71caa1ada1Mathias Agopian#include <utils/Trace.h>
34076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
355bac7f36ee9d5ed0c2e8a0141909ca94351965a8Chia-I Wu#include <ui/Gralloc2.h>
36a9347647eca3101c014be902b713772de3977d87Mathias Agopian#include <ui/GraphicBuffer.h>
37076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
388deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza#include <system/graphics.h>
398b765b7f5ea7f56963ea0e3141d043d20944dbccMathias Agopian
40076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiannamespace android {
41076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------
42076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
433330b203039dea366d4981db1408a460134b2d2cMathias AgopianANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferMapper )
444243e666213029a293935987c979831093fb0779Mathias Agopian
453330b203039dea366d4981db1408a460134b2d2cMathias AgopianGraphicBufferMapper::GraphicBufferMapper()
469ba189dc5c03040d45dad2080a81115f48f099c3Chia-I Wu  : mMapper(std::make_unique<const Gralloc2::Mapper>())
479ba189dc5c03040d45dad2080a81115f48f099c3Chia-I Wu{
489ba189dc5c03040d45dad2080a81115f48f099c3Chia-I Wu}
498deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza
505bac7f36ee9d5ed0c2e8a0141909ca94351965a8Chia-I Wustatus_t GraphicBufferMapper::importBuffer(buffer_handle_t rawHandle,
515bac7f36ee9d5ed0c2e8a0141909ca94351965a8Chia-I Wu        buffer_handle_t* outHandle)
52076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
53cf56319d4deb2215e5274f321f7fee71caa1ada1Mathias Agopian    ATRACE_CALL();
540a757814f3e4ca4db772144e85b687fe89a7fba5Mathias Agopian
55cb8405e7e74398aeafc9ef6ddb59af2d7cc6d2a6Chia-I Wu    Gralloc2::Error error = mMapper->importBuffer(
56cb8405e7e74398aeafc9ef6ddb59af2d7cc6d2a6Chia-I Wu            hardware::hidl_handle(rawHandle), outHandle);
579ba189dc5c03040d45dad2080a81115f48f099c3Chia-I Wu
585bac7f36ee9d5ed0c2e8a0141909ca94351965a8Chia-I Wu    ALOGW_IF(error != Gralloc2::Error::NONE, "importBuffer(%p) failed: %d",
595bac7f36ee9d5ed0c2e8a0141909ca94351965a8Chia-I Wu            rawHandle, error);
600a757814f3e4ca4db772144e85b687fe89a7fba5Mathias Agopian
615bac7f36ee9d5ed0c2e8a0141909ca94351965a8Chia-I Wu    return static_cast<status_t>(error);
62076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
63076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
645bac7f36ee9d5ed0c2e8a0141909ca94351965a8Chia-I Wustatus_t GraphicBufferMapper::freeBuffer(buffer_handle_t handle)
65076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
66cf56319d4deb2215e5274f321f7fee71caa1ada1Mathias Agopian    ATRACE_CALL();
670a757814f3e4ca4db772144e85b687fe89a7fba5Mathias Agopian
68cb8405e7e74398aeafc9ef6ddb59af2d7cc6d2a6Chia-I Wu    mMapper->freeBuffer(handle);
69076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
70cb8405e7e74398aeafc9ef6ddb59af2d7cc6d2a6Chia-I Wu    return NO_ERROR;
718deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza}
721f9f71e183946b390fff4d20900bc4a03246a882Lajos Molnar
735bac7f36ee9d5ed0c2e8a0141909ca94351965a8Chia-I Wustatic inline Gralloc2::IMapper::Rect asGralloc2Rect(const Rect& rect) {
745bac7f36ee9d5ed0c2e8a0141909ca94351965a8Chia-I Wu    Gralloc2::IMapper::Rect outRect{};
755bac7f36ee9d5ed0c2e8a0141909ca94351965a8Chia-I Wu    outRect.left = rect.left;
765bac7f36ee9d5ed0c2e8a0141909ca94351965a8Chia-I Wu    outRect.top = rect.top;
775bac7f36ee9d5ed0c2e8a0141909ca94351965a8Chia-I Wu    outRect.width = rect.width();
785bac7f36ee9d5ed0c2e8a0141909ca94351965a8Chia-I Wu    outRect.height = rect.height();
795bac7f36ee9d5ed0c2e8a0141909ca94351965a8Chia-I Wu    return outRect;
8058a1ef23ca0f82cb9b8278f74e8b337947a97b93Craig Donner}
8158a1ef23ca0f82cb9b8278f74e8b337947a97b93Craig Donner
828deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stozastatus_t GraphicBufferMapper::lock(buffer_handle_t handle, uint32_t usage,
838deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza        const Rect& bounds, void** vaddr)
848deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza{
858deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza    return lockAsync(handle, usage, bounds, vaddr, -1);
868deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza}
87c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala
888deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stozastatus_t GraphicBufferMapper::lockYCbCr(buffer_handle_t handle, uint32_t usage,
898deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza        const Rect& bounds, android_ycbcr *ycbcr)
908deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza{
918deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza    return lockAsyncYCbCr(handle, usage, bounds, ycbcr, -1);
92c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala}
93c43946b931de5dafd28f49963f9af78e05390b26Eino-Ville Talvala
943330b203039dea366d4981db1408a460134b2d2cMathias Agopianstatus_t GraphicBufferMapper::unlock(buffer_handle_t handle)
95076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
968deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza    int32_t fenceFd = -1;
978deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza    status_t error = unlockAsync(handle, &fenceFd);
988deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza    if (error == NO_ERROR) {
998deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza        sync_wait(fenceFd, -1);
1008deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza        close(fenceFd);
1018deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza    }
1028deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza    return error;
103b26af23744fa73e8bc142b1eb98772fde5970c10Mathias Agopian}
104b26af23744fa73e8bc142b1eb98772fde5970c10Mathias Agopian
1058f3960179c56767e5077be8337792bd4e244b7d7Francis Hartstatus_t GraphicBufferMapper::lockAsync(buffer_handle_t handle,
106d31824004277f554000417cea349d69f18655e95Dan Stoza        uint32_t usage, const Rect& bounds, void** vaddr, int fenceFd)
1078f3960179c56767e5077be8337792bd4e244b7d7Francis Hart{
108e96a325aff9da4e02abeb7b9178592583cf3b78cCraig Donner    return lockAsync(handle, usage, usage, bounds, vaddr, fenceFd);
109e96a325aff9da4e02abeb7b9178592583cf3b78cCraig Donner}
110e96a325aff9da4e02abeb7b9178592583cf3b78cCraig Donner
111e96a325aff9da4e02abeb7b9178592583cf3b78cCraig Donnerstatus_t GraphicBufferMapper::lockAsync(buffer_handle_t handle,
112e96a325aff9da4e02abeb7b9178592583cf3b78cCraig Donner        uint64_t producerUsage, uint64_t consumerUsage, const Rect& bounds,
113e96a325aff9da4e02abeb7b9178592583cf3b78cCraig Donner        void** vaddr, int fenceFd)
114e96a325aff9da4e02abeb7b9178592583cf3b78cCraig Donner{
1158f3960179c56767e5077be8337792bd4e244b7d7Francis Hart    ATRACE_CALL();
1168deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza
117cb8405e7e74398aeafc9ef6ddb59af2d7cc6d2a6Chia-I Wu    const uint64_t usage = static_cast<uint64_t>(
118cb8405e7e74398aeafc9ef6ddb59af2d7cc6d2a6Chia-I Wu            android_convertGralloc1To0Usage(producerUsage, consumerUsage));
119cb8405e7e74398aeafc9ef6ddb59af2d7cc6d2a6Chia-I Wu    Gralloc2::Error error = mMapper->lock(handle, usage,
120cb8405e7e74398aeafc9ef6ddb59af2d7cc6d2a6Chia-I Wu            asGralloc2Rect(bounds), fenceFd, vaddr);
1219ba189dc5c03040d45dad2080a81115f48f099c3Chia-I Wu
122cb8405e7e74398aeafc9ef6ddb59af2d7cc6d2a6Chia-I Wu    ALOGW_IF(error != Gralloc2::Error::NONE, "lock(%p, ...) failed: %d",
123cb8405e7e74398aeafc9ef6ddb59af2d7cc6d2a6Chia-I Wu            handle, error);
1248deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza
125cb8405e7e74398aeafc9ef6ddb59af2d7cc6d2a6Chia-I Wu    return static_cast<status_t>(error);
1268deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza}
1278deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza
1288deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stozastatic inline bool isValidYCbCrPlane(const android_flex_plane_t& plane) {
1298deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza    if (plane.bits_per_component != 8) {
1308deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza        ALOGV("Invalid number of bits per component: %d",
1318deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza                plane.bits_per_component);
1328deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza        return false;
1338deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza    }
1348deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza    if (plane.bits_used != 8) {
1358deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza        ALOGV("Invalid number of bits used: %d", plane.bits_used);
1368deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza        return false;
1378deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza    }
1388deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza
1398deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza    bool hasValidIncrement = plane.h_increment == 1 ||
1408deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza            (plane.component != FLEX_COMPONENT_Y && plane.h_increment == 2);
1418deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza    hasValidIncrement = hasValidIncrement && plane.v_increment > 0;
1428deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza    if (!hasValidIncrement) {
1438deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza        ALOGV("Invalid increment: h %d v %d", plane.h_increment,
1448deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza                plane.v_increment);
1458deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza        return false;
1468f3960179c56767e5077be8337792bd4e244b7d7Francis Hart    }
1478f3960179c56767e5077be8337792bd4e244b7d7Francis Hart
1488deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza    return true;
1498f3960179c56767e5077be8337792bd4e244b7d7Francis Hart}
1508f3960179c56767e5077be8337792bd4e244b7d7Francis Hart
1518f3960179c56767e5077be8337792bd4e244b7d7Francis Hartstatus_t GraphicBufferMapper::lockAsyncYCbCr(buffer_handle_t handle,
152d31824004277f554000417cea349d69f18655e95Dan Stoza        uint32_t usage, const Rect& bounds, android_ycbcr *ycbcr, int fenceFd)
1538f3960179c56767e5077be8337792bd4e244b7d7Francis Hart{
1548f3960179c56767e5077be8337792bd4e244b7d7Francis Hart    ATRACE_CALL();
1558deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza
156cb8405e7e74398aeafc9ef6ddb59af2d7cc6d2a6Chia-I Wu    Gralloc2::YCbCrLayout layout;
157cb8405e7e74398aeafc9ef6ddb59af2d7cc6d2a6Chia-I Wu    Gralloc2::Error error = mMapper->lock(handle, usage,
158cb8405e7e74398aeafc9ef6ddb59af2d7cc6d2a6Chia-I Wu            asGralloc2Rect(bounds), fenceFd, &layout);
159cb8405e7e74398aeafc9ef6ddb59af2d7cc6d2a6Chia-I Wu    if (error == Gralloc2::Error::NONE) {
160cb8405e7e74398aeafc9ef6ddb59af2d7cc6d2a6Chia-I Wu        ycbcr->y = layout.y;
161cb8405e7e74398aeafc9ef6ddb59af2d7cc6d2a6Chia-I Wu        ycbcr->cb = layout.cb;
162cb8405e7e74398aeafc9ef6ddb59af2d7cc6d2a6Chia-I Wu        ycbcr->cr = layout.cr;
163cb8405e7e74398aeafc9ef6ddb59af2d7cc6d2a6Chia-I Wu        ycbcr->ystride = static_cast<size_t>(layout.yStride);
164cb8405e7e74398aeafc9ef6ddb59af2d7cc6d2a6Chia-I Wu        ycbcr->cstride = static_cast<size_t>(layout.cStride);
165cb8405e7e74398aeafc9ef6ddb59af2d7cc6d2a6Chia-I Wu        ycbcr->chroma_step = static_cast<size_t>(layout.chromaStep);
1668deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza    }
1678deb4da6e8fe4687991da32ae68fa0bca4cb8212Dan Stoza
168cb8405e7e74398aeafc9ef6ddb59af2d7cc6d2a6Chia-I Wu    return static_cast<status_t>(error);
1698f3960179c56767e5077be8337792bd4e244b7d7Francis Hart}
1708f3960179c56767e5077be8337792bd4e244b7d7Francis Hart
1718f3960179c56767e5077be8337792bd4e244b7d7Francis Hartstatus_t GraphicBufferMapper::unlockAsync(buffer_handle_t handle, int *fenceFd)
1728f3960179c56767e5077be8337792bd4e244b7d7Francis Hart{
1738f3960179c56767e5077be8337792bd4e244b7d7Francis Hart    ATRACE_CALL();
1748f3960179c56767e5077be8337792bd4e244b7d7Francis Hart
175cb8405e7e74398aeafc9ef6ddb59af2d7cc6d2a6Chia-I Wu    *fenceFd = mMapper->unlock(handle);
176cb8405e7e74398aeafc9ef6ddb59af2d7cc6d2a6Chia-I Wu
177cb8405e7e74398aeafc9ef6ddb59af2d7cc6d2a6Chia-I Wu    return NO_ERROR;
1788f3960179c56767e5077be8337792bd4e244b7d7Francis Hart}
1798f3960179c56767e5077be8337792bd4e244b7d7Francis Hart
180b26af23744fa73e8bc142b1eb98772fde5970c10Mathias Agopian// ---------------------------------------------------------------------------
181076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}; // namespace android
182