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

Commit ce20e0a3 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "media.c2 aidl: Implement IGraphicBufferAllocator" into main am:...

Merge "media.c2 aidl: Implement IGraphicBufferAllocator" into main am: bdc19985 am: 77329420 am: 013f271f

Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/2734537



Change-Id: I82cc23f82ca7d71687170585e0b16fc4f8170d1c
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents fa532c20 013f271f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ cc_library {
    name: "libcodec2_client",

    srcs: [
        "GraphicBufferAllocator.cpp",
        "GraphicsTracker.cpp",
        "client.cpp",
        "output.cpp",
+152 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.
 */

#include <gui/IProducerListener.h>
#include <media/stagefright/foundation/ADebug.h>

#include <codec2/aidl/GraphicBufferAllocator.h>
#include <codec2/aidl/GraphicsTracker.h>

namespace aidl::android::hardware::media::c2::implementation {

class OnBufferReleasedListener : public ::android::BnProducerListener {
private:
    uint32_t mGeneration;
    std::weak_ptr<GraphicBufferAllocator> mAllocator;
public:
    OnBufferReleasedListener(
            uint32_t generation,
            const std::shared_ptr<GraphicBufferAllocator> &allocator)
            : mGeneration(generation), mAllocator(allocator) {}
    virtual ~OnBufferReleasedListener() = default;
    virtual void onBufferReleased() {
        auto p = mAllocator.lock();
        if (p) {
            p->onBufferReleased(mGeneration);
        }
    }
    virtual bool needsReleaseNotify() { return true; }
};

::ndk::ScopedAStatus GraphicBufferAllocator::allocate(
        const IGraphicBufferAllocator::Description& in_desc,
        IGraphicBufferAllocator::Allocation* _aidl_return) {
    AHardwareBuffer *buf;
    ::android::sp<::android::Fence> fence;
    c2_status_t ret = allocate(
            in_desc.width, in_desc.height, in_desc.format, in_desc.usage,
            &buf, &fence);
    if (ret == C2_OK) {
        _aidl_return->buffer.reset(buf);
        _aidl_return->fence = ::ndk::ScopedFileDescriptor(fence->dup());
        return ::ndk::ScopedAStatus::ok();
    }
    return ::ndk::ScopedAStatus::fromServiceSpecificError(ret);
}

::ndk::ScopedAStatus GraphicBufferAllocator::deallocate(int64_t in_id, bool* _aidl_return) {
    *_aidl_return = deallocate(in_id, ::android::Fence::NO_FENCE);
    return ::ndk::ScopedAStatus::ok();
}

::ndk::ScopedAStatus GraphicBufferAllocator::getWaitableFds(
        IGraphicBufferAllocator::WaitableFds* _aidl_return) {
    int allocFd;
    int statusFd;
    c2_status_t ret = mGraphicsTracker->getWaitableFds(&allocFd, &statusFd);
    if (ret == C2_OK) {
        _aidl_return->allocEvent.set(allocFd);
        _aidl_return->statusEvent.set(statusFd);
        return ::ndk::ScopedAStatus::ok();
    }
    return ::ndk::ScopedAStatus::fromServiceSpecificError(ret);
}

bool GraphicBufferAllocator::configure(
        const ::android::sp<IGraphicBufferProducer>& igbp,
        uint32_t generation,
        int maxDequeueBufferCount) {
    c2_status_t ret = C2_OK;

    ret = mGraphicsTracker->configureGraphics(igbp, generation);
    if (ret != C2_OK) {
        ALOGE("configuring igbp failed gen #(%d), configuring max dequeue count didn't happen",
              (unsigned int)generation);
        return false;
    }

    ret = mGraphicsTracker->configureMaxDequeueCount(maxDequeueBufferCount);
    if (ret != C2_OK) {
        ALOGE("configuring max dequeue count to %d failed", maxDequeueBufferCount);
        return false;
    }
    return true;
}

void GraphicBufferAllocator::updateMaxDequeueBufferCount(int count) {
    c2_status_t ret = mGraphicsTracker->configureMaxDequeueCount(count);
    if (ret != C2_OK) {
        ALOGE("updating max dequeue buffer count failed %d", ret);
    }
}

void GraphicBufferAllocator::reset() {
    mGraphicsTracker->stop();
}

const ::android::sp<::android::IProducerListener> GraphicBufferAllocator::createReleaseListener(
      uint32_t generation) {
    return new OnBufferReleasedListener(generation, ref<GraphicBufferAllocator>());
}

void GraphicBufferAllocator::onBufferReleased(uint32_t generation) {
    mGraphicsTracker->onReleased(generation);
}

c2_status_t GraphicBufferAllocator::allocate(
        uint32_t width, uint32_t height, ::android::PixelFormat format, uint64_t usage,
        AHardwareBuffer **buf, ::android::sp<::android::Fence> *fence) {
    return mGraphicsTracker->allocate(width, height, format, usage, buf, fence);
}

bool GraphicBufferAllocator::deallocate(const uint64_t id,
                                        const ::android::sp<::android::Fence> &fence) {
    c2_status_t ret = mGraphicsTracker->deallocate(id, fence);
    if (ret != C2_OK) {
        ALOGW("deallocate() %llu was not successful %d", (unsigned long long)id, ret);
        return false;
    }
    return true;
}

c2_status_t GraphicBufferAllocator::displayBuffer(
        const C2ConstGraphicBlock& block,
        const IGraphicBufferProducer::QueueBufferInput& input,
        IGraphicBufferProducer::QueueBufferOutput *output) {
    return mGraphicsTracker->render(block, input, output);
}

GraphicBufferAllocator::~GraphicBufferAllocator() {}

std::shared_ptr<GraphicBufferAllocator> GraphicBufferAllocator::CreateGraphicBufferAllocator(
        int maxDequeueCount) {
    return ::ndk::SharedRefBase::make<GraphicBufferAllocator>(maxDequeueCount);
}

GraphicBufferAllocator::GraphicBufferAllocator(int maxDequeueCount)
        : mGraphicsTracker(GraphicsTracker::CreateGraphicsTracker(maxDequeueCount)) {}

} // namespace aidl::android::hardware::media::c2::implementation
+154 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.
 */

#pragma once

#include <aidl/android/hardware/media/c2/BnGraphicBufferAllocator.h>

#include <android-base/unique_fd.h>
#include <gui/IGraphicBufferProducer.h>

#include <memory>

#include <C2Buffer.h>

namespace aidl::android::hardware::media::c2::implementation {

// forward declarations
class GraphicsTracker;

struct GraphicBufferAllocator : public BnGraphicBufferAllocator {
public:
    // HAL interfaces
    ::ndk::ScopedAStatus allocate(const IGraphicBufferAllocator::Description& in_desc,
                                  IGraphicBufferAllocator::Allocation* _aidl_return) override;

    ::ndk::ScopedAStatus deallocate(int64_t in_id, bool* _aidl_return) override;

    ::ndk::ScopedAStatus getWaitableFds(
            IGraphicBufferAllocator::WaitableFds* _aidl_return) override;

    /**
     * Configuring Surface/BufferQueue for the interface.
     *
     * Configure Surface, generation # and max dequeueBuffer() count for
     * allocate interface.
     *
     * @param   igbp              Surface where to allocate.
     * @param   generation        Generation # for allocations.
     * @param   maxDequeueBufferCount
     *                            Maximum # of pending allocations.
     */
    bool configure(const ::android::sp<::android::IGraphicBufferProducer>& igbp,
                   uint32_t generation,
                   int maxDequeueBufferCount);

    /**
     * Update max dequeue buffer count of BufferQueue.
     *
     * BufferQueue does not update this value if count is smaller
     * than the currently dequeued count.
     * TODO: better to update the value inside this interface.
     * for return value inspection from BQ, also for delayed updates.
     *
     * @param   count             the new value to update
     */
    void updateMaxDequeueBufferCount(int count);

    void reset();

    /**
     * Create a listener for buffer being released.
     *
     * Surface will register this listener and notify whenever the consumer
     * releases a buffer.
     *
     * @param   generation        generation # for the BufferQueue.
     * @return  IProducerListener can be used when connect# to Surface.
     */
    const ::android::sp<::android::IProducerListener> createReleaseListener(
            uint32_t generation);

    /**
     * Notifies a buffer being released.
     *
     * @param   generation        generation # for the BufferQueue.
     */
    void onBufferReleased(uint32_t generation);

    /**
     * Allocates a buffer.
     *
     * @param   width             width of the requested buffer.
     * @param   height            height of the requested buffer.
     * @param   format            format of the requested buffer.
     * @param   usage             usage of the requested buffer.
     * @param   buf               out param for created buffer.
     * @param   fence             out param for a pending fence.
     *
     * @return  OK                When an allocation was created.
     *          C2_BAD_STATE      Client is not in the state for allocating
     *          C2_BLOCKING       operation is blocked. Waitable fds can be
     *                            used to know when it unblocks.
     *          C2_CORRUPTED      Failed with a serious reason.
     */
    c2_status_t allocate(uint32_t width, uint32_t height,
                         ::android::PixelFormat format, uint64_t usage,
                         AHardwareBuffer **buf, ::android::sp<::android::Fence> *fence);

    /**
     * De-allocate a buffer.
     *
     * @param   id                unique id for a buffer.
     * @param   fence             write fence if it's deallocated due to
     *                            cancellation of displaying
     */
    bool deallocate(const uint64_t id, const ::android::sp<::android::Fence> &fence);

    /**
     * Display a graphic buffer to BufferQueue.
     *
     * @param   block             block to display to Surface.
     * @param   input             input parameter for displaying.
     * @param   output            out parameter from Surface.
     */
    c2_status_t displayBuffer(
            const C2ConstGraphicBlock& block,
            const ::android::IGraphicBufferProducer::QueueBufferInput& input,
            ::android::IGraphicBufferProducer::QueueBufferOutput *output);

    ~GraphicBufferAllocator();

    /**
     * Create the interface.
     *
     * The interface and codec instance's relationship is 1 to 1.
     * The interface will be cretaed in the beginning of Codec createion. And
     * lives until the instance destroyed.
     *
     * @param   maxDequeueCount   Initial max allocatable count
     */
    static std::shared_ptr<GraphicBufferAllocator> CreateGraphicBufferAllocator(
            int maxDequeueCount);
private:
    GraphicBufferAllocator(int maxDequeueCount);

    std::shared_ptr<GraphicsTracker> mGraphicsTracker;

    friend class ::ndk::SharedRefBase;
};

} // namespace aidl::android::hardware::media::c2::implementation