/* * 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. */ //#define LOG_NDEBUG 0 #define LOG_TAG "Codec2-GraphicBufferAllocator" #include #include #include #include namespace aidl::android::hardware::media::c2::implementation { class OnBufferReleasedListener : public ::android::BnProducerListener { private: uint32_t mGeneration; std::weak_ptr mAllocator; public: OnBufferReleasedListener( uint32_t generation, const std::shared_ptr &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::getWaitableFd( ::ndk::ScopedFileDescriptor* _aidl_return) { int pipeFd; c2_status_t ret = mGraphicsTracker->getWaitableFd(&pipeFd); if (ret == C2_OK) { _aidl_return->set(pipeFd); return ::ndk::ScopedAStatus::ok(); } return ::ndk::ScopedAStatus::fromServiceSpecificError(ret); } bool GraphicBufferAllocator::configure( const ::android::sp& 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()); } 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::CreateGraphicBufferAllocator( int maxDequeueCount) { return ::ndk::SharedRefBase::make(maxDequeueCount); } GraphicBufferAllocator::GraphicBufferAllocator(int maxDequeueCount) : mGraphicsTracker(GraphicsTracker::CreateGraphicsTracker(maxDequeueCount)) {} } // namespace aidl::android::hardware::media::c2::implementation