Loading media/codec2/hal/client/GraphicsTracker.cpp +104 −4 Original line number Diff line number Diff line Loading @@ -18,6 +18,9 @@ #include <fcntl.h> #include <unistd.h> #include <gui/BufferItemConsumer.h> #include <gui/BufferQueue.h> #include <gui/Surface.h> #include <media/stagefright/foundation/ADebug.h> #include <private/android/AHardwareBufferHelpers.h> #include <vndk/hardware_buffer.h> Loading Loading @@ -57,6 +60,90 @@ c2_status_t retrieveAHardwareBufferId(const C2ConstGraphicBlock &blk, uint64_t * } // anonymous namespace using ::android::BufferQueue; using ::android::BufferItemConsumer; using ::android::ConsumerListener; using ::android::IConsumerListener; using ::android::IGraphicBufferProducer; using ::android::IGraphicBufferConsumer; using ::android::Surface; class GraphicsTracker::PlaceHolderSurface { public: static const int kMaxAcquiredBuffer = 2; // Enough number to allocate in stop/release status. static const int kMaxDequeuedBuffer = 16; explicit PlaceHolderSurface(uint64_t usage) : mUsage(usage) {} ~PlaceHolderSurface() { if (mInit == C2_NO_INIT) { return; } if (mSurface) { mSurface->disconnect(NATIVE_WINDOW_API_MEDIA); } } c2_status_t allocate(uint32_t width, uint32_t height, uint32_t format, uint64_t usage, AHardwareBuffer **pBuf, sp<Fence> *fence) { std::unique_lock<std::mutex> l(mLock); if (mInit == C2_NO_INIT) { mInit = init(); } if (!mBufferItemConsumer || !mSurface) { ALOGE("PlaceHolderSurface not properly initialized"); return C2_CORRUPTED; } native_window_set_usage(mSurface.get(), usage); native_window_set_buffers_format(mSurface.get(), format); native_window_set_buffers_dimensions(mSurface.get(), width, height); ::android::status_t res; std::vector<Surface::BatchBuffer> buffers(1); res = mSurface->dequeueBuffers(&buffers); if (res != ::android::OK) { ALOGE("dequeueBuffers failed from PlaceHolderSurface %d", res); return C2_CORRUPTED; } sp<GraphicBuffer> gb = GraphicBuffer::from(buffers[0].buffer); *pBuf = AHardwareBuffer_from_GraphicBuffer(gb.get()); AHardwareBuffer_acquire(*pBuf); *fence = new Fence(buffers[0].fenceFd); return C2_OK; } private: uint64_t mUsage; sp<Surface> mSurface; sp<BufferItemConsumer> mBufferItemConsumer; c2_status_t mInit = C2_NO_INIT; std::mutex mLock; c2_status_t init() { #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) mBufferItemConsumer = sp<BufferItemConsumer>::make(mUsage, kMaxAcquiredBuffer); mSurface = mBufferItemConsumer->getSurface(); #else sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); mBufferItemConsumer = sp<BufferItemConsumer>::make(consumer, mUsage); mSurface = sp<Surface>::make(producer, false); #endif if (mSurface) { mSurface->connect(NATIVE_WINDOW_API_MEDIA, nullptr); mSurface->setMaxDequeuedBufferCount(kMaxDequeuedBuffer); } return C2_OK; } }; GraphicsTracker::BufferItem::BufferItem( uint32_t generation, int slot, const sp<GraphicBuffer>& buf, const sp<Fence>& fence) : mInit{false}, mGeneration{generation}, mSlot{slot} { Loading Loading @@ -256,9 +343,13 @@ c2_status_t GraphicsTracker::configureGraphics( // to the old surface in MediaCodec and allocate from the new surface from // GraphicsTracker cannot be synchronized properly. uint64_t bqId{0ULL}; uint64_t bqUsage{0ULL}; ::android::status_t ret = ::android::OK; if (igbp) { ret = igbp->getUniqueId(&bqId); if (ret == ::android::OK) { (void)igbp->getConsumerUsage(&bqUsage); } } if (ret != ::android::OK || prevCache->mGeneration == generation) { Loading Loading @@ -287,7 +378,8 @@ c2_status_t GraphicsTracker::configureGraphics( } ALOGD("new surface configured with id:%llu gen:%lu maxDequeue:%d", (unsigned long long)bqId, (unsigned long)generation, prevDequeueCommitted); std::shared_ptr<BufferCache> newCache = std::make_shared<BufferCache>(bqId, generation, igbp); std::shared_ptr<BufferCache> newCache = std::make_shared<BufferCache>(bqId, bqUsage, generation, igbp); { std::unique_lock<std::mutex> l(mLock); mInConfig = false; Loading Loading @@ -501,6 +593,9 @@ void GraphicsTracker::onRequestStop() { if (mStopRequested) { return; } if (mBufferCache && mBufferCache->mBqId != 0) { mReleaseSurface.reset(new PlaceHolderSurface(mBufferCache->mUsage)); } mStopRequested = true; writeIncDequeueableLocked(kMaxDequeueMax - 1); } Loading Loading @@ -764,9 +859,7 @@ c2_status_t GraphicsTracker::_allocateDirect( } } int alloced = mAllocAfterStopRequested++; *rFence = Fence::NO_FENCE; ALOGD("_allocateDirect() allocated %d buffer", alloced); return C2_OK; } Loading @@ -783,7 +876,14 @@ c2_status_t GraphicsTracker::allocate( std::unique_lock<std::mutex> l(mLock); if (mStopRequested) { l.unlock(); if (mReleaseSurface) { res = mReleaseSurface->allocate(width, height, format, usage, buf, rFence); } else { res = _allocateDirect(width, height, format, usage, buf, rFence); } if (res == C2_OK) { ALOGD("allocateed %d buffer after stop", ++mAllocAfterStopRequested); } // Delay a little bit for HAL to receive stop()/release() request. ::usleep(kAllocateDirectDelayUs); return res; Loading media/codec2/hal/client/include/codec2/aidl/GraphicsTracker.h +10 −3 Original line number Diff line number Diff line Loading @@ -224,6 +224,7 @@ private: static constexpr int kNumSlots = ::android::BufferQueueDefs::NUM_BUFFER_SLOTS; uint64_t mBqId; uint64_t mUsage; uint32_t mGeneration; ::android::sp<IGraphicBufferProducer> mIgbp; Loading @@ -245,9 +246,11 @@ private: std::atomic<int> mNumAttached; BufferCache() : mBqId{0ULL}, mGeneration{0}, mIgbp{nullptr}, mNumAttached{0} {} BufferCache(uint64_t bqId, uint32_t generation, const sp<IGraphicBufferProducer>& igbp) : mBqId{bqId}, mGeneration{generation}, mIgbp{igbp}, mNumAttached{0} {} BufferCache() : mBqId{0ULL}, mUsage{0ULL}, mGeneration{0}, mIgbp{nullptr}, mNumAttached{0} {} BufferCache(uint64_t bqId, uint64_t usage, uint32_t generation, const sp<IGraphicBufferProducer>& igbp) : mBqId{bqId}, mUsage{usage}, mGeneration{generation}, mIgbp{igbp}, mNumAttached{0} {} ~BufferCache(); Loading Loading @@ -307,6 +310,10 @@ private: bool mStopRequested; std::atomic<int> mAllocAfterStopRequested; // Release Surface where we get allocations after stop/release being requested. class PlaceHolderSurface; std::unique_ptr<PlaceHolderSurface> mReleaseSurface; private: explicit GraphicsTracker(int maxDequeueCount); Loading Loading
media/codec2/hal/client/GraphicsTracker.cpp +104 −4 Original line number Diff line number Diff line Loading @@ -18,6 +18,9 @@ #include <fcntl.h> #include <unistd.h> #include <gui/BufferItemConsumer.h> #include <gui/BufferQueue.h> #include <gui/Surface.h> #include <media/stagefright/foundation/ADebug.h> #include <private/android/AHardwareBufferHelpers.h> #include <vndk/hardware_buffer.h> Loading Loading @@ -57,6 +60,90 @@ c2_status_t retrieveAHardwareBufferId(const C2ConstGraphicBlock &blk, uint64_t * } // anonymous namespace using ::android::BufferQueue; using ::android::BufferItemConsumer; using ::android::ConsumerListener; using ::android::IConsumerListener; using ::android::IGraphicBufferProducer; using ::android::IGraphicBufferConsumer; using ::android::Surface; class GraphicsTracker::PlaceHolderSurface { public: static const int kMaxAcquiredBuffer = 2; // Enough number to allocate in stop/release status. static const int kMaxDequeuedBuffer = 16; explicit PlaceHolderSurface(uint64_t usage) : mUsage(usage) {} ~PlaceHolderSurface() { if (mInit == C2_NO_INIT) { return; } if (mSurface) { mSurface->disconnect(NATIVE_WINDOW_API_MEDIA); } } c2_status_t allocate(uint32_t width, uint32_t height, uint32_t format, uint64_t usage, AHardwareBuffer **pBuf, sp<Fence> *fence) { std::unique_lock<std::mutex> l(mLock); if (mInit == C2_NO_INIT) { mInit = init(); } if (!mBufferItemConsumer || !mSurface) { ALOGE("PlaceHolderSurface not properly initialized"); return C2_CORRUPTED; } native_window_set_usage(mSurface.get(), usage); native_window_set_buffers_format(mSurface.get(), format); native_window_set_buffers_dimensions(mSurface.get(), width, height); ::android::status_t res; std::vector<Surface::BatchBuffer> buffers(1); res = mSurface->dequeueBuffers(&buffers); if (res != ::android::OK) { ALOGE("dequeueBuffers failed from PlaceHolderSurface %d", res); return C2_CORRUPTED; } sp<GraphicBuffer> gb = GraphicBuffer::from(buffers[0].buffer); *pBuf = AHardwareBuffer_from_GraphicBuffer(gb.get()); AHardwareBuffer_acquire(*pBuf); *fence = new Fence(buffers[0].fenceFd); return C2_OK; } private: uint64_t mUsage; sp<Surface> mSurface; sp<BufferItemConsumer> mBufferItemConsumer; c2_status_t mInit = C2_NO_INIT; std::mutex mLock; c2_status_t init() { #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) mBufferItemConsumer = sp<BufferItemConsumer>::make(mUsage, kMaxAcquiredBuffer); mSurface = mBufferItemConsumer->getSurface(); #else sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); mBufferItemConsumer = sp<BufferItemConsumer>::make(consumer, mUsage); mSurface = sp<Surface>::make(producer, false); #endif if (mSurface) { mSurface->connect(NATIVE_WINDOW_API_MEDIA, nullptr); mSurface->setMaxDequeuedBufferCount(kMaxDequeuedBuffer); } return C2_OK; } }; GraphicsTracker::BufferItem::BufferItem( uint32_t generation, int slot, const sp<GraphicBuffer>& buf, const sp<Fence>& fence) : mInit{false}, mGeneration{generation}, mSlot{slot} { Loading Loading @@ -256,9 +343,13 @@ c2_status_t GraphicsTracker::configureGraphics( // to the old surface in MediaCodec and allocate from the new surface from // GraphicsTracker cannot be synchronized properly. uint64_t bqId{0ULL}; uint64_t bqUsage{0ULL}; ::android::status_t ret = ::android::OK; if (igbp) { ret = igbp->getUniqueId(&bqId); if (ret == ::android::OK) { (void)igbp->getConsumerUsage(&bqUsage); } } if (ret != ::android::OK || prevCache->mGeneration == generation) { Loading Loading @@ -287,7 +378,8 @@ c2_status_t GraphicsTracker::configureGraphics( } ALOGD("new surface configured with id:%llu gen:%lu maxDequeue:%d", (unsigned long long)bqId, (unsigned long)generation, prevDequeueCommitted); std::shared_ptr<BufferCache> newCache = std::make_shared<BufferCache>(bqId, generation, igbp); std::shared_ptr<BufferCache> newCache = std::make_shared<BufferCache>(bqId, bqUsage, generation, igbp); { std::unique_lock<std::mutex> l(mLock); mInConfig = false; Loading Loading @@ -501,6 +593,9 @@ void GraphicsTracker::onRequestStop() { if (mStopRequested) { return; } if (mBufferCache && mBufferCache->mBqId != 0) { mReleaseSurface.reset(new PlaceHolderSurface(mBufferCache->mUsage)); } mStopRequested = true; writeIncDequeueableLocked(kMaxDequeueMax - 1); } Loading Loading @@ -764,9 +859,7 @@ c2_status_t GraphicsTracker::_allocateDirect( } } int alloced = mAllocAfterStopRequested++; *rFence = Fence::NO_FENCE; ALOGD("_allocateDirect() allocated %d buffer", alloced); return C2_OK; } Loading @@ -783,7 +876,14 @@ c2_status_t GraphicsTracker::allocate( std::unique_lock<std::mutex> l(mLock); if (mStopRequested) { l.unlock(); if (mReleaseSurface) { res = mReleaseSurface->allocate(width, height, format, usage, buf, rFence); } else { res = _allocateDirect(width, height, format, usage, buf, rFence); } if (res == C2_OK) { ALOGD("allocateed %d buffer after stop", ++mAllocAfterStopRequested); } // Delay a little bit for HAL to receive stop()/release() request. ::usleep(kAllocateDirectDelayUs); return res; Loading
media/codec2/hal/client/include/codec2/aidl/GraphicsTracker.h +10 −3 Original line number Diff line number Diff line Loading @@ -224,6 +224,7 @@ private: static constexpr int kNumSlots = ::android::BufferQueueDefs::NUM_BUFFER_SLOTS; uint64_t mBqId; uint64_t mUsage; uint32_t mGeneration; ::android::sp<IGraphicBufferProducer> mIgbp; Loading @@ -245,9 +246,11 @@ private: std::atomic<int> mNumAttached; BufferCache() : mBqId{0ULL}, mGeneration{0}, mIgbp{nullptr}, mNumAttached{0} {} BufferCache(uint64_t bqId, uint32_t generation, const sp<IGraphicBufferProducer>& igbp) : mBqId{bqId}, mGeneration{generation}, mIgbp{igbp}, mNumAttached{0} {} BufferCache() : mBqId{0ULL}, mUsage{0ULL}, mGeneration{0}, mIgbp{nullptr}, mNumAttached{0} {} BufferCache(uint64_t bqId, uint64_t usage, uint32_t generation, const sp<IGraphicBufferProducer>& igbp) : mBqId{bqId}, mUsage{usage}, mGeneration{generation}, mIgbp{igbp}, mNumAttached{0} {} ~BufferCache(); Loading Loading @@ -307,6 +310,10 @@ private: bool mStopRequested; std::atomic<int> mAllocAfterStopRequested; // Release Surface where we get allocations after stop/release being requested. class PlaceHolderSurface; std::unique_ptr<PlaceHolderSurface> mReleaseSurface; private: explicit GraphicsTracker(int maxDequeueCount); Loading