结合代码讲讲SurfaceFlinger::latchBuffers
时间: 2023-07-02 13:05:11 浏览: 344
`SurfaceFlinger::latchBuffers()` 是 Android 系统中 SurfaceFlinger 的一个函数,其主要作用是将当前帧的所有 Surface 的图像数据(Buffer)复制到对应的 Display 中去。
在 Android 中,每个 Surface 都对应一个 BufferQueue,即一个 Buffer 以队列的形式存储在 Surface 中。当应用程序需要更新 Surface 上的图像时,会将新图像对应的 Buffer 放入 BufferQueue 的尾部,而 SurfaceFlinger 则会从 BufferQueue 的头部取出最新的 Buffer,并将其渲染到对应的 Display 上。
在 `latchBuffers()` 函数中,SurfaceFlinger 会先遍历所有的 Display,对于每个 Display,它会执行以下操作:
1. 获取 Display 对应的 Surface。
2. 获取 Surface 中的当前 Buffer。
3. 如果当前 Buffer 已经被刷到了 Display 上,则跳过该 Surface。
4. 否则,将当前 Buffer 的内容复制到 Display 中。
具体实现过程可以参考以下代码片段:
```c++
void SurfaceFlinger::latchBuffers() {
// 遍历所有的 Display
for (const auto& [displayToken, display] : mDisplays) {
// 获取 Display 对应的 Surface
const auto& [layerStack, z, displaySurface] = display;
sp<const DisplayDevice> hw(displaySurface->getPhysicalDisplay());
if (hw == nullptr) {
continue;
}
// 获取 Surface 中的当前 Buffer
const auto& [layerStackRequest, layerRequest, releaseFence] =
getLayerStackRequestAndReleaseFenceLocked(hw->getCompositionDisplayId());
const auto& [fence, buffer] = mGraphicBufferProducer->dequeueBuffer(false, false);
// 如果当前 Buffer 已经被刷到了 Display 上,则跳过该 Surface
if (buffer->getGenerationNumber() <= hw->getReleasedFrameNumber()) {
mGraphicBufferProducer->cancelBuffer(buffer, fence);
continue;
}
// 将当前 Buffer 的内容复制到 Display 中
hw->setReleasedFrameNumber(buffer->getGenerationNumber());
hw->compositionComplete();
mGraphicBufferProducer->queueBuffer(buffer, -1, std::move(fence));
}
}
```
需要注意的是,`latchBuffers()` 函数并不是在每次 Surface 更新时都会被调用,而是在 SurfaceFlinger 的主循环中以一定的频率被调用,以确保所有的 Surface 都能及时地被渲染到对应的 Display 上。
阅读全文