1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > Android12 HDR相关

Android12 HDR相关

时间:2022-05-10 13:08:42

相关推荐

Android12 HDR相关

以hdr10为例

在nativewindow中,提供native_window_set_buffers_hdr10_plus_metadata接口

在dequeue buffer之后,queue buffer之前调用该接口,将hdr的元数据与该buffer关联起来

/** native_window_set_buffers_hdr10_plus_metadata(..., metadata)* All buffers queued after this call will be associated with the* HDR10+ dynamic metadata specified.** metadata specifies additional dynamic information about the* contents of the buffer that may affect how it is displayed. When* it is nullptr, it means no such information is available. No* HDR10+ dynamic emtadata is associated with the buffers by default.** Parameter "size" refers to the length of the metadata blob pointed to* by parameter "data". The metadata blob will adhere to the HDR10+ SEI* message standard.*/static inline int native_window_set_buffers_hdr10_plus_metadata(struct ANativeWindow* window,const size_t size,const uint8_t* metadata) {return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_HDR10_PLUS_METADATA, size,metadata);}

那么是如何关联起来的呢,继续往下走

在Surface.cpp中,将hdr元数据保存在input中

void Surface::getQueueBufferInputLocked(android_native_buffer_t* buffer, int fenceFd,nsecs_t timestamp, IGraphicBufferProducer::QueueBufferInput* out) {...IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp,static_cast<android_dataspace>(mDataSpace), crop, mScalingMode,mTransform ^ mStickyTransform, fence, mStickyTransform,mEnableFrameTimestamps);// we should send HDR metadata as needed if this becomes a bottleneckinput.setHdrMetadata(mHdrMetadata);...

那什么时候会走到这个逻辑呢?在Surface::queuebuffer的时候,会走到这里,将元数据保存下来。然后调用GraphicBufferProducer将buffer 入列。此时会将buffer的信息作为BufferItem对象保存在mCore->mQueue中,即GraphicBufferCore中,其中mQueue是一个FIFO的队列。

int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {...IGraphicBufferProducer::QueueBufferOutput output;IGraphicBufferProducer::QueueBufferInput input;getQueueBufferInputLocked(buffer, fenceFd, mTimestamp, &input);sp<Fence> fence = input.fence;nsecs_t now = systemTime();status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);...

BufferItem是一个对buffer信息的封装,后面消费者在acquire buffer时拿到的也是一个bufferItem对象。

我们看surfaceflinger中是如何拿到buffer的。

在BufferLayerConsumer.cpp中,在updateTexImage接口中去获取buffer。我们看acquireBufferLocked具体的实现。

status_t BufferLayerConsumer::updateTexImage(BufferRejecter* rejecter, nsecs_t expectedPresentTime,bool* autoRefresh, bool* queuedBuffer,uint64_t maxFrameNumber) {...BufferItem item;// Acquire the next buffer.// In asynchronous mode the list is guaranteed to be one buffer// deep, while in synchronous mode we use the oldest buffer.status_t err = acquireBufferLocked(&item, expectedPresentTime, maxFrameNumber);if (err != NO_ERROR) {if (err == BufferQueue::NO_BUFFER_AVAILABLE) {err = NO_ERROR;} else if (err == BufferQueue::PRESENT_LATER) {// return the error, without logging} else {BLC_LOGE("updateTexImage: acquire failed: %s (%d)", strerror(-err), err);}return err;}

acquireBufferLocked的具体实现逻辑在ConsumerBase::acquireBufferLocked中,其中mConsumer是

IGraphicBufferConsumer对象,具体的实现在GraphicBufferConsumer中。

status_t ConsumerBase::acquireBufferLocked(BufferItem *item,nsecs_t presentWhen, uint64_t maxFrameNumber) {if (mAbandoned) {CB_LOGE("acquireBufferLocked: ConsumerBase is abandoned!");return NO_INIT;}status_t err = mConsumer->acquireBuffer(item, presentWhen, maxFrameNumber);if (err != NO_ERROR) {return err;}if (item->mGraphicBuffer != nullptr) {if (mSlots[item->mSlot].mGraphicBuffer != nullptr) {freeBufferLocked(item->mSlot);}mSlots[item->mSlot].mGraphicBuffer = item->mGraphicBuffer;}mSlots[item->mSlot].mFrameNumber = item->mFrameNumber;mSlots[item->mSlot].mFence = item->mFence;CB_LOGV("acquireBufferLocked: -> slot=%d/%" PRIu64,item->mSlot, item->mFrameNumber);return OK;}

然后在GraphicBufferConsumer::acquireBuffer()中获取buffer的信息,即bufferItem。因为hdr的元数据已经保存在bufferitem中,所以当acquirebuffer拿到一块buffer时,hdr元数据信息会同步设置过去。

在获取了bufferitem之后,调用BufferLayerConsumer::updateAndReleaseLocked接口,将hdr数据更新到bufferlayerconsumer的状态中

...// Update the BufferLayerConsumer state.mCurrentTexture = slot;mCurrentTextureBuffer = nextTextureBuffer;mCurrentCrop = item.mCrop;mCurrentTransform = item.mTransform;mCurrentScalingMode = item.mScalingMode;mCurrentTimestamp = item.mTimestamp;mCurrentDataSpace = static_cast<ui::Dataspace>(item.mDataSpace);mCurrentHdrMetadata = item.mHdrMetadata;mCurrentFence = item.mFence;mCurrentFenceTime = item.mFenceTime;mCurrentFrameNumber = item.mFrameNumber;mCurrentTransformToDisplayInverse = item.mTransformToDisplayInverse;mCurrentSurfaceDamage = item.mSurfaceDamage;mCurrentApi = item.mApi;...

继续对mCurrentHdrMetadata 进行追踪,如下接口提供了获取buffer hdr数据的功能

const HdrMetadata& BufferLayerConsumer::getCurrentHdrMetadata() const {BLC_LOGV("getCurrentHdrMetadata");Mutex::Autolock lock(mMutex);return mCurrentHdrMetadata;}

该接口在bufferQueueLayer中被调用

void BufferQueueLayer::gatherBufferInfo() {BufferLayer::gatherBufferInfo();mBufferInfo.mDesiredPresentTime = mConsumer->getTimestamp();mBufferInfo.mFenceTime = mConsumer->getCurrentFenceTime();mBufferInfo.mFence = mConsumer->getCurrentFence();mBufferInfo.mTransform = mConsumer->getCurrentTransform();mBufferInfo.mDataspace = translateDataspace(mConsumer->getCurrentDataSpace());mBufferInfo.mCrop = mConsumer->getCurrentCrop();mBufferInfo.mScaleMode = mConsumer->getCurrentScalingMode();mBufferInfo.mSurfaceDamage = mConsumer->getSurfaceDamage();mBufferInfo.mHdrMetadata = mConsumer->getCurrentHdrMetadata();mBufferInfo.mApi = mConsumer->getCurrentApi();mBufferInfo.mTransformToDisplayInverse = mConsumer->getTransformToDisplayInverse();}

继续往下追踪,发现在latchbuffer的时候会调用该接口

bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime,nsecs_t expectedPresentTime) {ATRACE_CALL();bool refreshRequired = latchSidebandStream(recomputeVisibleRegions);if (refreshRequired) {return refreshRequired;}if (!hasReadyFrame()) {return false;}// if we've already called updateTexImage() without going through// a composition step, we have to skip this layer at this point// because we cannot call updateTeximage() without a corresponding// compositionComplete() call.// we'll trigger an update in onPreComposition().if (mRefreshPending) {return false;}// If the head buffer's acquire fence hasn't signaled yet, return and// try again laterif (!fenceHasSignaled()) {ATRACE_NAME("!fenceHasSignaled()");mFlinger->signalLayerUpdate();return false;}// Capture the old state of the layer for comparisons laterconst State& s(getDrawingState());const bool oldOpacity = isOpaque(s);BufferInfo oldBufferInfo = mBufferInfo;status_t err = updateTexImage(recomputeVisibleRegions, latchTime, expectedPresentTime);if (err != NO_ERROR) {return false;}err = updateActiveBuffer();if (err != NO_ERROR) {return false;}err = updateFrameNumber(latchTime);if (err != NO_ERROR) {return false;}gatherBufferInfo();mRefreshPending = true;if (oldBufferInfo.mBuffer == nullptr) {// the first time we receive a buffer, we need to trigger a// geometry invalidation.recomputeVisibleRegions = true;}if ((mBufferInfo.mCrop != oldBufferInfo.mCrop) ||(mBufferInfo.mTransform != oldBufferInfo.mTransform) ||(mBufferInfo.mScaleMode != oldBufferInfo.mScaleMode) ||(mBufferInfo.mTransformToDisplayInverse != oldBufferInfo.mTransformToDisplayInverse)) {recomputeVisibleRegions = true;}if (oldBufferInfo.mBuffer != nullptr) {uint32_t bufWidth = mBufferInfo.mBuffer->getBuffer()->getWidth();uint32_t bufHeight = mBufferInfo.mBuffer->getBuffer()->getHeight();if (bufWidth != uint32_t(oldBufferInfo.mBuffer->getBuffer()->width) ||bufHeight != uint32_t(oldBufferInfo.mBuffer->getBuffer()->height)) {recomputeVisibleRegions = true;}}if (oldOpacity != isOpaque(s)) {recomputeVisibleRegions = true;}return true;}

latchbuffer就是在invalidate阶段获取buffer用的。所以也就是说,当获取buffer时,会同时获取hdr metadata,即buffer与metadata是绑定的。

在SurfaceFlinger::handlePageFlip()中,如果layer获取到了buffer,并且满足显示的条件,那么就应该送去合成显示。

for (const auto& layer : mLayersWithQueuedFrames) {if (layer->latchBuffer(visibleRegions, latchTime, expectedPresentTime)) {mLayersPendingRefresh.push_back(layer);}layer->useSurfaceDamage();if (layer->isBufferLatched()) {newDataLatched = true;}}}

后面基本不会涉及到与buffer相关的操作,因为buffer的信息已经保存在layer的mBufferInfo中,需要时去取即可。

surfaceflinger中hdr layer还有另外的处理,需要继续研究。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。