上篇分析到SurfaceFlinger.signalRefresh()里会调用到SurfaceFlinger里的handleMessageRefresh(), 现在这里面开始涉及到图层合成了,这里面涉及的流程。
handleMessageRefresh()
void SurfaceFlinger::handleMessageRefresh() {
mRefreshPending = false;
nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
//合成图像前的准备工作,设置各种状态
preComposition(refreshStartTime);
//重建可见区域的所有图层
rebuildLayerStacks();
//启动硬件图像合成
setUpHWComposer();
//调试信息
doDebugFlashRegions();
doTracing("handleRefresh");
logLayerStats();
//合成处理
doComposition();
//更新状态与下次合成时间
postComposition(refreshStartTime);
}
上面重点的就是两块,一个setupHWComposer() 启动硬件图像合成, 另一个是doComposition()合成处理。
setUpHWComposer()
void SurfaceFlinger::setUpHWComposer() {
...
if (CC_UNLIKELY(mGeometryInvalid)) {
mGeometryInvalid = false;
//遍历所有的显示设备
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
sp<const DisplayDevice> displayDevice(mDisplays[dpy]);
const auto hwcId = displayDevice->getHwcDisplayId();
if (hwcId >= 0) {
const Vector<sp<Layer>>& currentLayers(
displayDevice->getVisibleLayersSortedByZ());
//遍历当前显示设备的所有图层
for (size_t i = 0; i < currentLayers.size(); i++) {
const auto& layer = currentLayers[i];
if (!layer->hasHwcLayer(hwcId)) {
//如果没有硬件图层,则创建一个硬件图层
if (!layer->createHwcLayer(getBE().mHwc.get(), hwcId)) {
layer->forceClientComposition(hwcId);
continue;
}
}
//设置图层大小,坐标
layer->setGeometry(displayDevice, i);
if (mDebugDisableHWC || mDebugRegion) {
layer->forceClientComposition(hwcId);
}
}
}
}
// Set the per-frame data
//遍历所有显示屏
for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
auto& displayDevice = mDisplays[displayId];
const auto hwcId = displayDevice->getHwcDisplayId();
if (hwcId < 0) {
continue;
}
//更新颜色变化
if (mDrawingState.colorMatrixChanged) {
displayDevice->setColorTransform(mDrawingState.colorMatrix);
status_t result = getBE().mHwc->setColorTransform(hwcId, mDrawingState.colorMatrix);
ALOGE_IF(result != NO_ERROR, "Failed to set color transform on "
"display %zd: %d", displayId, result);
}
//遍历当前显示屏的所有图层
for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
//设置数据存储格式
if (layer->isHdrY410()) {
layer->forceClientComposition(hwcId);
} else if ((layer->getDataSpace() == Dataspace::BT2020_PQ ||
layer->getDataSpace() == Dataspace::BT2020_ITU_PQ) &&
!displayDevice->hasHDR10Support()) {
layer->forceClientComposition(hwcId);
} else if ((layer->getDataSpace() == Dataspace::BT2020_HLG ||
layer->getDataSpace() == Dataspace::BT2020_ITU_HLG) &&
!displayDevice->hasHLGSupport()) {
layer->forceClientComposition(hwcId);
}
//设置图层合成类型
if (layer->getForceClientComposition(hwcId)) {
ALOGV("[%s] Requesting Client composition", layer->getName().string());
layer->setCompositionType(hwcId, HWC2::Composition::Client);
continue;
}
//图层的数据设置到显示器
layer->setPerFrameData(displayDevice);
}
//设置颜色模式
if (hasWideColorDisplay) {
ColorMode colorMode;
Dataspace dataSpace;
RenderIntent renderIntent;
pickColorMode(displayDevice, &colorMode, &dataSpace, &renderIntent);
setActiveColorModeInternal(displayDevice, colorMode, dataSpace, renderIntent);
}
}
mDrawingState.colorMatrixChanged = false;
//遍历所有显示屏设备,做了prepareFrame
for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
auto& displayDevice = mDisplays[displayId];
if (!displayDevice->isDisplayOn()) {
continue;
}
status_t result = displayDevice->prepareFrame(*getBE().mHwc);
ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:"
" %d (%s)", displayId, result, strerror(-result));
}
}
因为setUpHWComposer()里做的事情很多,我们一个一个来撸下:
按照我们《Android P 显示流程(一)—Display设备初始化过程分析》
后续最终会调用到HWC2On1Adapter里的createLayer的方法:
Error HWC2On1Adapter::Display::createLayer(hwc2_layer_t* outLayerId) {
std::unique_lock<std::recursive_mutex> lock(mStateMutex);
//通过当前Display对象,创建一个新的layer对象,最后添加到mLayers 容器中
auto layer = *mLayers.emplace(std::make_shared<Layer>(*this));
mDevice.mLayers.emplace(std::make_pair(layer->getId(), layer));
*outLayerId = layer->getId();
ALOGV("[%" PRIu64 "] created layer %" PRIu64, mId, *outLayerId);
markGeometryChanged();
return Error::None;
}
-
layer->setGeometry(displayDevice, i)
设置图层大小和坐标位置,这个不是重点,我们就不往下分析了,后面更新颜色矩阵变化也直接跳过 -
后面有遍历显示屏的所有图层,设置数据存储格式也跳过不研究,来看看设置合成类型。
void Layer::setCompositionType(int32_t hwcId, HWC2::Composition type, bool callIntoHwc) {
auto& hwcInfo = getBE().mHwcLayers[hwcId];
auto& hwcLayer = hwcInfo.layer;
//判读与目前此图层的合成类型是否一致,如果不一致,更改合成类型
if (hwcInfo.compositionType != type) {
ALOGV(" actually setting");
hwcInfo.compositionType = type;
if (callIntoHwc) {
auto error = hwcLayer->setCompositionType(type);
}
}
}
Error Layer::setCompositionType(Composition type)
{
auto intType = static_cast<Hwc2::IComposerClient::Composition>(type);
auto intError = mComposer.setLayerCompositionType(
mDisplayId, mId, intType);
return static_cast<Error>(intError);
}
//同之前分析的流程,最后会调用到HWC2On1Adapter里面
Error HWC2On1Adapter::Layer::setCompositionType(Composition type)
{
mCompositionType.setPending(type);
return Error::None;
}
这个设置图层的类型,那图层到底有哪些类型呢?
- Composition::Client
- Composition::Device
- Composition::SolidColor
- Composition::Cursor
- Composition::Sideband
上面这几种Composition 类型到底有什么区别呢,看看applyCompositionType:
void HWC2On1Adapter::Layer::applyCompositionType(hwc_layer_1_t& hwc1Layer,
bool applyAllState)
{
// HWC1 never supports color transforms or dataspaces and only sometimes
// supports plane alpha (depending on the version). These require us to drop
// some or all layers to client composition.
if (mHasUnsupportedDataspace || mHasUnsupportedPlaneAlpha ||
mDisplay.hasColorTransform()) {
hwc1Layer.compositionType = HWC_FRAMEBUFFER;
hwc1Layer.flags = HWC_SKIP_LAYER;
return;
}
if (applyAllState || mCompositionType.isDirty()) {
hwc1Layer.flags = 0;
switch (mCompositionType.getPendingValue()) {
case Composition::Client:
hwc1Layer.compositionType = HWC_FRAMEBUFFER;
hwc1Layer.flags |= HWC_SKIP_LAYER;
break;
case Composition::Device:
hwc1Layer.compositionType = HWC_FRAMEBUFFER;
break;
case Composition::SolidColor:
// In theory the following line should work, but since the HWC1
// version of SurfaceFlinger never used HWC_BACKGROUND, HWC1
// devices may not work correctly. To be on the safe side, we
// fall back to client composition.
//
// hwc1Layer.compositionType = HWC_BACKGROUND;
hwc1Layer.compositionType = HWC_FRAMEBUFFER;
hwc1Layer.flags |= HWC_SKIP_LAYER;
break;
case Composition::Cursor:
hwc1Layer.compositionType = HWC_FRAMEBUFFER;
if (mDisplay.getDevice().getHwc1MinorVersion() >= 4) {
hwc1Layer.hints |= HWC_IS_CURSOR_LAYER;
}
break;
case Composition::Sideband:
if (mDisplay.getDevice().getHwc1MinorVersion() < 4) {
hwc1Layer.compositionType = HWC_SIDEBAND;
} else {
hwc1Layer.compositionType = HWC_FRAMEBUFFER;
hwc1Layer.flags |= HWC_SKIP_LAYER;
}
break;
default:
hwc1Layer.compositionType = HWC_FRAMEBUFFER;
hwc1Layer.flags |= HWC_SKIP_LAYER;
break;
}
ALOGV("Layer %" PRIu64 " %s set to %d", mId,
to_string(mCompositionType.getPendingValue()).c_str(),
hwc1Layer.compositionType);
ALOGV_IF(hwc1Layer.flags & HWC_SKIP_LAYER, " and skipping");
mCompositionType.latch();
}
}
这几种虽然不一样,但对应的hwc1Layer.compositionType都是HWC_FRAMEBUFFER,实际上对应HAL层的实现没什么区别。
- 每个图层设置每帧的数据
layer->setPerFrameData(displayDevice)
但图层又分BufferLayer和ColorLayer,这两路图层有什么区别呢?
const sp<Client>& client,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
int32_t windowType, int32_t ownerUid, sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp, sp<Layer>* parent)
{
switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
case ISurfaceComposerClient::eFXSurfaceNormal:
result = createBufferLayer(client,
uniqueName, w, h, flags, format,
handle, gbp, &layer);
break;
case ISurfaceComposerClient::eFXSurfaceColor:
result = createColorLayer(client,
uniqueName, w, h, flags,
handle, &layer);
break;
default:
result = BAD_VALUE;
...
创建图层时,根据Flag 的不同来创建图层的,一种是纯色的,一种是普通数据显示的图层,这里我们一般指的是BufferLayer.
那继续看BufferLayer的setPerFrameData的函数:
void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
// Apply this display's projection's viewport to the visible region
// before giving it to the HWC HAL.
const Transform& tr = displayDevice->getTransform();
const auto& viewport = displayDevice->getViewport();
Region visible = tr.transform(visibleRegion.intersect(viewport));
auto hwcId = displayDevice->getHwcDisplayId();
auto& hwcInfo = getBE().mHwcLayers[hwcId];
auto& hwcLayer = hwcInfo.layer;
//设置可见区域
auto error = hwcLayer->setVisibleRegion(visible);
if (error != HWC2::Error::None) {
ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
to_string(error).c_str(), static_cast<int32_t>(error));
visible.dump(LOG_TAG);
}
//设置损坏区域
error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
if (error != HWC2::Error::None) {
ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
to_string(error).c_str(), static_cast<int32_t>(error));
surfaceDamageRegion.dump(LOG_TAG);
}
//如果是sideband 图层,直接设置sideband流,然后就返回了
if (getBE().compositionInfo.hwc.sidebandStream.get()) {
setCompositionType(hwcId, HWC2::Composition::Sideband);
ALOGV("[%s] Requesting Sideband composition", mName.string());
error = hwcLayer->setSidebandStream(getBE().compositionInfo.hwc.sidebandStream->handle());
if (error != HWC2::Error::None) {
ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", mName.string(),
getBE().compositionInfo.hwc.sidebandStream->handle(), to_string(error).c_str(),
static_cast<int32_t>(error));
}
return;
}
//如果是设备或光标图层,设置相对应的CompositionType
// Device or Cursor layers
if (mPotentialCursor) {
ALOGV("[%s] Requesting Cursor composition", mName.string());
setCompositionType(hwcId, HWC2::Composition::Cursor);
} else {
ALOGV("[%s] Requesting Device composition", mName.string());
setCompositionType(hwcId, HWC2::Composition::Device);
}
//设置Dataspace
ALOGV("setPerFrameData: dataspace = %d", mCurrentDataSpace);
error = hwcLayer->setDataspace(mCurrentDataSpace);
if (error != HWC2::Error::None) {
ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mCurrentDataSpace,
to_string(error).c_str(), static_cast<int32_t>(error));
}
//设置metadata
const HdrMetadata& metadata = mConsumer->getCurrentHdrMetadata();
error = hwcLayer->setPerFrameMetadata(displayDevice->getSupportedPerFrameMetadata(), metadata);
if (error != HWC2::Error::None && error != HWC2::Error::Unsupported) {
ALOGE("[%s] Failed to set hdrMetadata: %s (%d)", mName.string(),
to_string(error).c_str(), static_cast<int32_t>(error));
}
//获取hwcBuffer
uint32_t hwcSlot = 0;
sp<GraphicBuffer> hwcBuffer;
hwcInfo.bufferCache.getHwcBuffer(getBE().compositionInfo.mBufferSlot,
getBE().compositionInfo.mBuffer, &hwcSlot, &hwcBuffer);
//根据fence,设置buffer
auto acquireFence = mConsumer->getCurrentFence();
error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence);
if (error != HWC2::Error::None) {
ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
getBE().compositionInfo.mBuffer->handle, to_string(error).c_str(),
static_cast<int32_t>(error));
}
}
那重点来看看获取hwcBuffer和设置buffer
void HWComposerBufferCache::getHwcBuffer(int slot,
const sp<GraphicBuffer>& buffer,
uint32_t* outSlot, sp<GraphicBuffer>* outBuffer)
{
if (slot == BufferQueue::INVALID_BUFFER_SLOT || slot < 0) {
// default to slot 0
slot = 0;
}
if (static_cast<size_t>(slot) >= mBuffers.size()) {
mBuffers.resize(slot + 1);
}
*outSlot = slot;
if (mBuffers[slot] == buffer) {
// already cached in HWC, skip sending the buffer
*outBuffer = nullptr;
} else {
*outBuffer = buffer;
// update cache
mBuffers[slot] = buffer;
}
}
获取Buffer 其实就是将buffer指向outBuffer, 将slot 赋值给outSlot, 中间经过了一个mBuffer[]的缓存。
- 那最后看设置Buffer, setBuffer根据之前的调用链分析会调用到HW2On1Adapter::Layer里的setBuffer.
Error HWC2On1Adapter::Layer::setBuffer(buffer_handle_t buffer,
int32_t acquireFence) {
ALOGV("Setting acquireFence to %d for layer %" PRIu64, acquireFence, mId);
mBuffer.setBuffer(buffer);
mBuffer.setFence(acquireFence);
return Error::None;
}
到这里setPerFrameData 这个函数分析完了。
- 遍历所有显示屏,displayDevice->prepareFrame(*getBE().mHwc), 这里面针对FrameBufferSurface来做,没有做实际的事情。这个就跳过不分析了。
到这里setUpHWComposer() 就分析完了,下篇我们来关键的doCompostion().