Surface::dequeueBuffer是Android系统中Surface类的一个方法,用于从Surface中获取一个可用的Buffer。它通常在图形渲染或视频播放等场景中使用。
Surface::dequeueBuffer的调用地方可以有多个,具体取决于应用程序的实现和使用场景。以下是一些可能的调用地方:
-
图形渲染引擎:在图形渲染引擎中,Surface::dequeueBuffer通常用于获取一个可用的绘制缓冲区,以便进行图形绘制操作。这样可以实现流畅的图形渲染效果。
-
视频播放器:在视频播放器中,Surface::dequeueBuffer可以用于获取一个可用的视频帧缓冲区,以便将视频数据解码并显示在屏幕上。这样可以实现流畅的视频播放效果。
-
图像处理应用:在图像处理应用中,Surface::dequeueBuffer可以用于获取一个可用的图像缓冲区,以便进行图像处理操作,如滤镜、特效等。这样可以实现实时的图像处理效果。
-
游戏引擎:在游戏引擎中,Surface::dequeueBuffer可以用于获取一个可用的游戏画面缓冲区,以便进行游戏画面的渲染和更新。这样可以实现流畅的游戏画面效果。
Surface的dequeueBuffer方法的作用是应用程序一端请求绘制图像时,向BufferQueue中申请一块可用的GraphicBuffer,有了这个buffer就可以绘制图像数据了,生产者在生成内容的时候,就会有这么一个过程;
-
生产者向 BufferQueue 中申请 slot(缓冲槽)
-
生产者拿到 slot,但是 slot 并没有关联对应的 GraphicBuffer(缓冲区)
-
生产者创建一个缓冲区,并将它与缓冲槽相关联。
下面从代码角度进行分析:
//framework/native/libs/gui/Surface.cpp
sp<IGraphicBufferProducer> mGraphicBufferProducer;
class Surface : public ANativeObjectBase<ANativeWindow, Surface, RefBase> {
int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
ATRACE_CALL();
ALOGV("Surface::dequeueBuffer");
IGraphicBufferProducer::DequeueBufferInput dqInput;
{
Mutex::Autolock lock(mMutex);
if (mReportRemovedBuffers) {
mRemovedBuffers.clear();
}
getDequeueBufferInputLocked(&dqInput);
if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot !=
BufferItem::INVALID_BUFFER_SLOT) {
sp<GraphicBuffer>& gbuf(mSlots[mSharedBufferSlot].buffer);
if (gbuf != nullptr) {
*buffer = gbuf.get();
*fenceFd = -1;
return OK;
}
}
} // Drop the lock so that we can still touch the Surface while blocking in IGBP::dequeueBuffer
int buf = -1;
sp<Fence> fence;
nsecs_t startTime = systemTime();
FrameEventHistoryDelta frameTimestamps;
//这里尝试去dequeueBuffer,因为这时SurfaceFlinger对应Layer的slot还没有分配buffer,这时SurfaceFlinger会回复的flag会有BUFFER_NEEDS_REALLOCATIO
status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, dqInput.width,
dqInput.height, dqInput.format,
dqInput.usage, &mBufferAge,
dqInput.getTimestamps ?