HWComposer合成显示流程分析(转载)

在介绍HWComposer合成显示流程前,需要先了解下 AndroidO显示体统架构如下图:

  1. AndroidO显示体统架构如
    Linux Android display architecture

其中的SDM架构

  1. setUpHWComposer介绍
    在SurfaceFlinger进行合成显示的时候,首先需要初始化HWC,
    代码为setUpHWComposer

void SurfaceFlinger::setUpHWComposer() {

for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {

//判断是否需要重新绘制
bool mustRecompose = dirty && !(empty && wasEmpty);

mDisplays[dpy]->beginFrame(mustRecompose);

}

// build the h/w work list
if (CC_UNLIKELY(mGeometryInvalid)) {
mGeometryInvalid = false;
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
sp displayDevice(mDisplays[dpy]);
const auto hwcId = displayDevice->getHwcDisplayId();
if (hwcId >= 0) {
const Vector<sp>& currentLayers(
displayDevice->getVisibleLayersSortedByZ());

//为每个Layer创建一个与之对应的HwLayer
//并设置Geometry
for (size_t i = 0; i < currentLayers.size(); i++) {
const auto& layer = currentLayers[i];
if (!layer->hasHwcLayer(hwcId)) {
//为layer创建一个与之对应的HwcLayer
if (!layer->createHwcLayer(mHwc.get(), hwcId)) {
//如果创建失败,则强制修改合成方式为Client
layer->forceClientComposition(hwcId);
continue;
}
}
//设置几何尺寸
layer->setGeometry(displayDevice, i);

}
}
}
}

// Set the per-frame data
for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
    auto& displayDevice = mDisplays[displayId];
    const auto hwcId = displayDevice->getHwcDisplayId();
    ...
    //为每个Layer设置显示帧数据
    for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
        layer->setPerFrameData(displayDevice);
    }
    ...
}
...
for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
    auto& displayDevice = mDisplays[displayId];
    if (!displayDevice->isDisplayOn()) {
        continue;
    }
    //尝试直接显示
    //如果成功则返回
    //如果显示不成功,则会执行刷新validate
    status_t result = displayDevice->prepareFrame(*mHwc);
    ...
}

}

setUpHWComposer有几个重要的过程

判断是否需重新绘制
为每个Layer创建一个与之对应的HwcLayer并设置几何尺寸(Geometry)
为每个Layer及与之对应的HwLayer设置显示帧数据
尝试直接显示
2.1 HwLayer创建
我们首选分析下HwLayer的创建。其简要流程图如下:

在这里插入图片描述

2.2 setGeometry流程
下边分析下setGeometry函数:

//surfaceflinger\Layer.cpp
void Layer::setGeometry(const sp& displayDevice, uint32_t z)
{

const auto hwcId = displayDevice->getHwcDisplayId();
auto& hwcInfo = mHwcLayers[hwcId];

...
hwcInfo.forceClientComposition = false;
...
auto& hwcLayer = hwcInfo.layer;
...
// this gives us only the "orientation" component of the transform
const State& s(getDrawingState());
//设置hwcLayer的blendMode
auto error = hwcLayer->setBlendMode(blendMode);

// apply the layer's transform, followed by the display's global transform
// here we're guaranteed that the layer's transform preserves rects
Region activeTransparentRegion(s.activeTransparentRegion);
Transform t = getTransform();
...
const Transform& tr(displayDevice->getTransform());
Rect transformedFrame = tr.transform(frame);
error = hwcLayer->setDisplayFrame(transformedFrame);
...
FloatRect sourceCrop = computeCrop(displayDevice);
error = hwcLayer->setSourceCrop(sourceCrop);
...
float alpha = getAlpha();
error = hwcLayer->setPlaneAlpha(alpha);
...
error = hwcLayer->setZOrder(z);
...
error = hwcLayer->setInfo(type, appId);
...
/*
 * Transformations are applied in this order:
 * 1) buffer orientation/flip/mirror
 * 2) state transformation (window manager)
 * 3) layer orientation (screen orientation)
 * (NOTE: the matrices are multiplied in reverse order)
 */

const Transform bufferOrientation(mCurrentTransform);
Transform transform(tr * t * bufferOrientation);

if (getTransformToDisplayInverse()) {
    ...
    transform = Transform(invTransform) * tr * bufferOrientation;
}

// this gives us only the "orientation" component of the transform
const uint32_t orientation = transform.getOrientation();

if (orientation & Transform::ROT_INVALID) {
    // we can only handle simple transformation
    hwcInfo.forceClientComposition = true;
} else {
    auto transform = static_cast<HWC2::Transform>(orientation);
    auto error = hwcLayer->setTransform(transform);
    ...
}
...

}

setGeometry会给HWCLayer设置blendMode、DisplayFrame区域、SourceCrop区域、PlaneAlpha、ZOrder等属性。
基本流程图如下:
在这里插入图片描述

这些区域的含义请参考https://www.jianshu.com/p/824a9ddf68b9这篇大牛博客,我们直接附其一张神图1
在这里插入图片描述

2.3 setPerFrameData流程
下边分析下setPerFrameData

void Layer::setPerFrameData(const sp& 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 = mHwcLayers[hwcId];
auto& hwcLayer = hwcInfo.layer;
auto error = hwcLayer->setVisibleRegion(visible);

error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);

// Sideband layers
if (mSidebandStream.get()) {
    setCompositionType(hwcId, HWC2::Composition::Sideband);
    error = hwcLayer->setSidebandStream(mSidebandStream->handle());
    ...
    return;
}

// Client layers
if (hwcInfo.forceClientComposition ||
        (mActiveBuffer != nullptr && mActiveBuffer->handle == nullptr)) {
    setCompositionType(hwcId, HWC2::Composition::Client);
    return;
}

// SolidColor layers
if (mActiveBuffer == nullptr) {
    setCompositionType(hwcId, HWC2::Composition::SolidColor);

    // For now, we only support black for DimLayer
    error = hwcLayer->setColor({0, 0, 0, 255});
    ...
    // Clear out the transform, because it doesn't make sense absent a
    // source buffer
    error = hwcLayer->setTransform(HWC2::Transform::None);
    ...
    return;
}

// Device or Cursor layers
if (mPotentialCursor) {
    // 如果mPotentialCursor为true,设置合成方式为Cursor
    setCompositionType(hwcId, HWC2::Composition::Cursor);
} else {
    //设置合成方式为Device,Layer的默认值合成方式
    setCompositionType(hwcId, HWC2::Composition::Device);
}
...
//设置dataspace
error = hwcLayer->setDataspace(mCurrentState.dataSpace);
...
uint32_t hwcSlot = 0;
sp<GraphicBuffer> hwcBuffer;
hwcInfo.bufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer,
        &hwcSlot, &hwcBuffer);
auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
//设置hwcLayer的hwcBuffer和acquireFence
error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence);

}

setPerFrameData流程图如下:
在这里插入图片描述

至此,所有hwcLayer都设置完成合成方式和合成显示帧数据后,便可以调用displayDevice->prepareFrame(*mHwc)尝试直接显示,下边分析下该函数

2.3 prepareFrame分析
status_t DisplayDevice::prepareFrame(HWComposer& hwc) {
//调用hwc.prepare尝试显示
status_t error = hwc.prepare(*this);

//mDisplaySurface 为FramebufferSurface.cpp
//空实现
return mDisplaySurface->prepareFrame(compositionType);
}

下边我们分析下HWComposer::prepare

status_t HWComposer::prepare(DisplayDevice& displayDevice) {

auto displayId = displayDevice.getHwcDisplayId();

auto& displayData = mDisplayData[displayId];
auto& hwcDisplay = displayData.hwcDisplay;
if (!hwcDisplay->isConnected()) {
return NO_ERROR;
}

uint32_t numTypes = 0;
uint32_t numRequests = 0;

HWC2::Error error = HWC2::Error::None;

// First try to skip validate altogether if the HWC supports it.
displayData.validateWasSkipped = false;
//如果HWC支持SkipValidate且没有合成方式为Client,即hasClientComposition为false
//尝试直接显示,如果不能直接显示则执行Validate
if (hasCapability(HWC2::Capability::SkipValidate) &&
        !displayData.hasClientComposition) {
    sp<android::Fence> outPresentFence;
    uint32_t state = UINT32_MAX;
    //首先会尝试直接显示,如果state == 1,表示显示成功
    //如果不能直接显示则尝试Validate,如果如果state == 0,表示validate成功
    error = hwcDisplay->presentOrValidate(&numTypes, &numRequests, &outPresentFence , &state);
    ...
    //如果显示成功了,则直接返回了,不必执行其他操作
    if (state == 1) { //Present Succeeded.
        std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
        error = hwcDisplay->getReleaseFences(&releaseFences);
        displayData.releaseFences = std::move(releaseFences);
        displayData.lastPresentFence = outPresentFence;
        displayData.validateWasSkipped = true;
        displayData.presentError = error;
        return NO_ERROR;
    }
    // Present failed but Validate ran.
} else {
    //尝试更新validate
    error = hwcDisplay->validate(&numTypes, &numRequests);
}
...
std::unordered_map<HWC2::Layer*, HWC2::Composition> changedTypes;
changedTypes.reserve(numTypes);
//执行完validate后,hwc会检查之前设置的合成方式是否支持
//如果不支持,则会尝试修改,通过getChangedCompositionTypes
//可以获取需要修改合成方式的HWcLayer和修改的合成方式
error = hwcDisplay->getChangedCompositionTypes(&changedTypes);
...
displayData.displayRequests = static_cast<HWC2::DisplayRequest>(0);
std::unordered_map<HWC2::Layer*, HWC2::LayerRequest> layerRequests;
layerRequests.reserve(numRequests);
error = hwcDisplay->getRequests(&displayData.displayRequests,
        &layerRequests);
...
displayData.hasClientComposition = false;
displayData.hasDeviceComposition = false;
for (auto& layer : displayDevice.getVisibleLayersSortedByZ()) {
    auto hwcLayer = layer->getHwcLayer(displayId);
    //检查hwcLayer是否在changedTypes中,
    //如果在,则会修改其合成方式为changedTypes[hwcLayer]
    if (changedTypes.count(hwcLayer) != 0) {
        // We pass false so we only update our state and don't call back
        // into the HWC device
        //首先检查先新的合成方式changedTypes[hwcLayer]
        validateChange(layer->getCompositionType(displayId),
                changedTypes[hwcLayer]);
        //修改合成方式为 changedTypes[hwcLayer]
        layer->setCompositionType(displayId, changedTypes[hwcLayer], false);
    }
    //如果存在Client合成,则将hasClientComposition置为true
    //如果存在Device合成,则将hasDeviceComposition置为true
    switch (layer->getCompositionType(displayId)) {
        case HWC2::Composition::Client:
            displayData.hasClientComposition = true;
            break;
        case HWC2::Composition::Device:
        case HWC2::Composition::SolidColor:
        case HWC2::Composition::Cursor:
        case HWC2::Composition::Sideband:
            displayData.hasDeviceComposition = true;
            break;
        default:
            break;
    }
    //如果hwcLayer在layerRequests且值为ClearClientTarget
    //则设置layer的ClearClientTarget标志位,
    //表示是否需要清理Client合成结果
    //否则置为false
    if (layerRequests.count(hwcLayer) != 0 &&
            layerRequests[hwcLayer] ==
                    HWC2::LayerRequest::ClearClientTarget) {
        layer->setClearClientTarget(displayId, true);
    } else {
        ...
        layer->setClearClientTarget(displayId, false);
    }
}
//通知Hwc做相应修改
error = hwcDisplay->acceptChanges();
...
return NO_ERROR;

}

我们分析下presentOrValidate流程,Validate流程在presentOrValidate失败时会执行,所以在分析presentOrValidate,其实也会分析Validate流程。

//ComposerHal.cpp
Error Composer::presentOrValidateDisplay(Display display, uint32_t* outNumTypes,
uint32_t* outNumRequests, int* outPresentFence, uint32_t* state) {
mWriter.selectDisplay(display);
mWriter.presentOrvalidateDisplay();
//提交合成显示命令给IComposer服务
Error error = execute();

//读取结果
mReader.takePresentOrValidateStage(display, state);
//如果state == 1表示 Present succeeded
if (*state == 1) { // Present succeeded
mReader.takePresentFence(display, outPresentFence);
}
//如果state == 0表示 Validate succeeded
if (*state == 0) { // Validate succeeded.
mReader.hasChanges(display, outNumTypes, outNumRequests);
}

return Error::NONE;
}

我们来分析下Composer::execute是如何提交合成显示命令的

//ComposerHal.cpp
Error Composer::execute()
{
// prepare input command queue
bool queueChanged = false;
uint32_t commandLength = 0;
hidl_vec<hidl_handle> commandHandles;
//将mWriter的合成显示命令提交给commandHandles
if (!mWriter.writeQueue(&queueChanged, &commandLength, &commandHandles)) {
mWriter.reset();
return Error::NO_RESOURCES;
}

// set up new input command queue if necessary
if (queueChanged) {
    auto ret = mClient->setInputCommandQueue(*mWriter.getMQDescriptor());
    auto error = unwrapRet(ret);
    ...
}
//mClient 为IComposerClient代理对象
//通过该代理对象提交合成显示命令
Error error = kDefaultError;
auto ret = mClient->executeCommands(commandLength, commandHandles,
        [&](const auto& tmpError, const auto& tmpOutChanged,
            const auto& tmpOutLength, const auto& tmpOutHandles)
        {
            error = tmpError;

            // set up new output command queue if necessary
           ...
        });
...
return error;

}

通过上边的分析发现,只有执行Composer::execute才会将合成显示命令提交给IComposer服务做进一步的合成显示。

  1. Client合成Layer渲染至FBTarget
    至此每个Layer的合成显示数据及合成方式都确定了,接着调用doComposition来实现最后的合成显示

如果在prepareFrame时,已经成功显示了,则doComposition只会清理下commandbuffer
如果prepareFrame时,显示不成功,则由doComposition来完成剩余的工作,如存在client合成则调用OpenGL进行合成。
void SurfaceFlinger::doComposition() {

for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
const sp& hw(mDisplays[dpy]);
if (hw->isDisplayOn()) {
// transform the dirty region into this screen’s coordinate space
const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));

        // repaint the framebuffer (if needed)
        //主要处理client合成
        doDisplayComposition(hw, dirtyRegion);
        ...
    }
}
//提交合成显示命令给HWC
postFramebuffer();

}
1

3.1 doDisplayComposition介绍
void SurfaceFlinger::doDisplayComposition(
const sp& displayDevice,
const Region& inDirtyRegion)
{
// We only need to actually compose the display if:
// 1) It is being handled by hardware composer, which may need this to
// keep its virtual display state machine in sync, or
// 2) There is work to be done (the dirty region isn’t empty)

//主要是执行client合成
//将需要Client合成的Layer全部绘制到FBTarget上
if (!doComposeSurfaces(displayDevice, dirtyRegion)) return;

{
// update the swap region and clear the dirty region
displayDevice->swapRegion.orSelf(dirtyRegion);
// swap buffers (presentation)
//调用eglswapbuffer,交换前后buffer
displayDevice->swapBuffers(getHwComposer());
}
}

bool SurfaceFlinger::doComposeSurfaces(
const sp& displayDevice, const Region& dirty)
{

//检查是否存在client合成的Layer
bool hasClientComposition = mHwc->hasClientComposition(hwcId);
if (hasClientComposition) {

//eglMakeCurrent
//glViewport(0, 0, vpw, vph);
//获取透视矩阵mProjectionMatrix
if (!displayDevice->makeCurrent(mEGLDisplay, mEGLContext)) {

return false;
}

//检查是否存在Device合成的Layer
const bool hasDeviceComposition = mHwc->hasDeviceComposition(hwcId);
if (hasDeviceComposition) {
//清理FBTarget为(0, 0, 0, 0)透明
mRenderEngine->clearWithColor(0, 0, 0, 0);
} else {
//如果Layer全部是Client合成
//计算dirty region

// screen is already cleared here
if (!region.isEmpty()) {
// can happen with SurfaceView
//清理FBTarget的region对应的区域
drawWormhole(displayDevice, region);
}
}

}
/*
* and then, render the layers targeted at the framebuffer
*/
//绘制需Client合成的Layer
if (hwcId >= 0) {
// we’re using h/w composer
bool firstLayer = true;
for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
const Region clip(dirty.intersect(
displayTransform.transform(layer->visibleRegion)));

if (!clip.isEmpty()) {
switch (layer->getCompositionType(hwcId)) {
case HWC2::Composition::Cursor:
case HWC2::Composition::Device:
case HWC2::Composition::Sideband:
case HWC2::Composition::SolidColor: {
const Layer::State& state(layer->getDrawingState());
//如果ClearClientTarget为true,且不是第一个Layer
//说明存在其他Layer为Client合成
if (layer->getClearClientTarget(hwcId) && !firstLayer &&
layer->isOpaque(state) && (layer->getAlpha() == 1.0f)
&& hasClientComposition) {
// never clear the very first layer since we’re
// guaranteed the FB is already cleared
//如果Layer是Device合成,则通过OpenGL清理layer在FBTarget上的对应区域
layer->clearWithOpenGL(displayDevice);
}
break;
}
case HWC2::Composition::Client: {
//如果是Client合成,则直接调用OpenGl绘制到FBTarget,区域为clip
//具体opengl实现,我们就不介绍了,这一部分需要有一些opengl的知识
layer->draw(displayDevice, clip);
break;
}
default:
break;
}
}
firstLayer = false;
}
}

return true;
}

至此FBTarget绘制完成,简单总结下:

首先如果display中的Layer存在client合成,则需要绑定glcontext,设置viewport
调用opengl做一些清理工作
对client合成Layer使用OpenGL渲染合成至FBTarget上
3.2 swapBuffers介绍
至此,需client合成的Layer已经使用OpenGL渲染合成至FBTarget上了,接着需要执行swapBuffers交换前后buffer,并将渲染结果提交给Hwccomposer

void DisplayDevice::swapBuffers(HWComposer& hwc) const {

//如果存在Client合成
if (hwc.hasClientComposition(mHwcDisplayId)
|| hwc.hasFlipFBTRequest(mHwcDisplayId)) {

//交换前后buffer
EGLBoolean success = eglSwapBuffers(mDisplay, mSurface);

}

//获取渲染结果并提交给hwc
status_t result = mDisplaySurface->advanceFrame();

}

获取FBTarget渲染结果并提交给hwc

status_t FramebufferSurface::advanceFrame() {

uint32_t slot = 0;
sp buf;
sp acquireFence(Fence::NO_FENCE);
android_dataspace_t dataspace = HAL_DATASPACE_UNKNOWN;
//通过acquireBuffer获取bufferqueue中一个queue状态的buffer
//后边肯定会有一个releaBuffer
status_t result = nextBuffer(slot, buf, acquireFence, dataspace);

return result;
}

status_t FramebufferSurface::nextBuffer(uint32_t& outSlot,
sp& outBuffer, sp& outFence,
android_dataspace_t& outDataspace) {

BufferItem item;
//通过acquireBuffer获取bufferqueue中一个queue状态的buffer
//后边肯定会有一个releaBuffer
status_t err = acquireBufferLocked(&item, 0);

//通过获取的item更新mCurrentBuffer
mCurrentBufferSlot = item.mSlot;
mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer;
mCurrentFence = item.mFence;
outFence = item.mFence;
//在mHwcBufferCache中查找mCurrentBuffer并返回查找结果outBuffer、outSlot
mHwcBufferCache.getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer,
&outSlot, &outBuffer);
outDataspace = item.mDataSpace;
//设置渲染结果提交给mHwc
status_t result =
mHwc.setClientTarget(mDisplayType, outSlot, outFence, outBuffer, outDataspace);

return NO_ERROR;
}

Error Composer::setClientTarget(Display display, uint32_t slot,
const sp& target,
int acquireFence, Dataspace dataspace,
const std::vectorIComposerClient::Rect& damage)
{
mWriter.selectDisplay(display);

const native_handle_t* handle = nullptr;
if (target.get()) {
handle = target->getNativeBuffer()->handle;
}
//将渲染结果写入mWriter
mWriter.setClientTarget(slot, handle, acquireFence, dataspace, damage);
return Error::NONE;
}

3.3 postFramebuffer()分析
至此,将渲染结果写入了mWriter,需要执行postFramebuffer将FBtarget提交给IComposer服务进行渲染

void SurfaceFlinger::postFramebuffer()
{

const nsecs_t now = systemTime();
mDebugInSwapBuffers = now;

for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
    auto& displayDevice = mDisplays[displayId];
    if (!displayDevice->isDisplayOn()) {
        continue;
    }
    const auto hwcId = displayDevice->getHwcDisplayId();
    if (hwcId >= 0) {
        //提交合成显示命令给IComposer
        mHwc->presentAndGetReleaseFences(hwcId);
    }
    //执行releaseBufferLocked,将buffer归还给bufferqueue中
    displayDevice->onSwapBuffersCompleted();
    displayDevice->makeCurrent(mEGLDisplay, mEGLContext);
    //更新layer的release
    for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
        ...
        sp<Fence> releaseFence = Fence::NO_FENCE;
        if (hwcId >= 0) {
            auto hwcLayer = layer->getHwcLayer(hwcId);
            releaseFence = mHwc->getLayerReleaseFence(hwcId, hwcLayer);
        }
        if (layer->getCompositionType(hwcId) == HWC2::Composition::Client) {
            releaseFence = Fence::merge("LayerRelease", releaseFence,
                    displayDevice->getClientTargetAcquireFence());
        }
        layer->onLayerDisplayed(releaseFence);
    }
    ...
}

}

下边分析下presentAndGetReleaseFences

status_t HWComposer::presentAndGetReleaseFences(int32_t displayId) {

auto& displayData = mDisplayData[displayId];
auto& hwcDisplay = displayData.hwcDisplay;
//在DisplayDevice::prepareFrame尝试直接显示的时候
//如果直接显示成功会将displayData.validateWasSkipped置为true
if (displayData.validateWasSkipped) {
bool discardCommands = true;

if (discardCommands) {
//清理调commandbuffer,并直接返回
hwcDisplay->discardCommands();
}
auto error = displayData.presentError;

return NO_ERROR;
}
//至此所有Layer及FBTarget都有合成显示buffer及其他相关信息了
//调用hwcDisplay->present执行显示
auto error = hwcDisplay->present(&displayData.lastPresentFence);

std::unordered_map<HWC2::Layer*, sp> releaseFences;
//获取hwc返回的releasefence
error = hwcDisplay->getReleaseFences(&releaseFences);

//保存到displayData.releaseFences
displayData.releaseFences = std::move(releaseFences);

return NO_ERROR;

}

3.4 releaseBuffer流程分析
下边分析onSwapBuffersCompleted

void DisplayDevice::onSwapBuffersCompleted() const {
mDisplaySurface->onFrameCommitted();
}

void FramebufferSurface::onFrameCommitted() {
if (mHasPendingRelease) {
sp fence = mHwc.getPresentFence(mDisplayType);
if (fence->isValid()) {
//更新releasefence
status_t result = addReleaseFence(mPreviousBufferSlot,
mPreviousBuffer, fence);
}
//归还buffer给bufferqueue
status_t result = releaseBufferLocked(mPreviousBufferSlot,
mPreviousBuffer, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);

mPreviousBuffer.clear();
mHasPendingRelease = false;
}
}

5 IComposer服务响应presentOrValidateDisplay流程
前边分析了SurfaceFlinger中的合成显示流程,SurfaceFlinger会将合成显示命令提交给IComposer在继续完成合成显示。下边我们分析下
IComposer服务响应presentOrValidateDisplay的流程:

//ap\hardware\interfaces\graphics\composer\2.1\default\ComposerClient.cpp
bool ComposerClient::CommandReader::parsePresentOrValidateDisplay(uint16_t length)
{

// First try to Present as is.
int presentFence = -1;
std::vector layers;
std::vector fences;
//mHal为HwcHal对象
//最终会调用HWCSession::PresentDisplay
//HWCSession是一个hwc2_device_t设备对象
auto err = mHal.presentDisplay(mDisplay, &presentFence, &layers, &fences);
//显示成功
if (err == Error::NONE) {
//设置parsePresentOrValidateDisplay结果为1
mWriter.setPresentOrValidateResult(1);
mWriter.setPresentFence(presentFence);
//设置ReleaseFence
mWriter.setReleaseFences(layers, fences);
return true;
}
// Present has failed. We need to fallback to validate
//如果显示失败,则会执行validate
std::vector changedLayers;
std::vectorIComposerClient::Composition compositionTypes;
uint32_t displayRequestMask = 0x0;
std::vector requestedLayers;
std::vector<uint32_t> requestMasks;
//mHal为HWCSession对象
err = mHal.validateDisplay(mDisplay, &changedLayers,
&compositionTypes, &displayRequestMask,
&requestedLayers, &requestMasks);
if (err == Error::NONE) {
//设置parsePresentOrValidateDisplay结果为0
mWriter.setPresentOrValidateResult(0);
//修改合成方式
mWriter.setChangedCompositionTypes(changedLayers,
compositionTypes);
//设置DisplayRequests
mWriter.setDisplayRequests(displayRequestMask,
requestedLayers, requestMasks);
} else {
mWriter.setError(getCommandLoc(), err);
}

return true;

}

接着分析下HWCSession::PresentDisplay

int32_t HWCSession::PresentDisplay(hwc2_device_t *device, hwc2_display_t display,
int32_t *out_retire_fence) {
HWCSession *hwc_session = static_cast<HWCSession *>(device);

if (hwc_session->hwc_display_[display]) {
//hwc_display_类型有几种,我们只介绍下HWCDisplayPrimary
status = hwc_session->hwc_display_[display]->Present(out_retire_fence);

}

return INT32(status);
}

接着分析下present

//ap\hardware\qcom\display\sdm\libs\hwc2\hwc_display_builtin.cpp
HWC2::Error HWCDisplayPrimary::Present(int32_t *out_retire_fence) {
auto status = HWC2::Error::None;
if (display_paused_) {

} else {
status = HWCDisplay::CommitLayerStack();
if (status == HWC2::Error::None) {
HandleFrameOutput();
SolidFillCommit();
status = HWCDisplay::PostCommitLayerStack(out_retire_fence);
}
}
pending_commit_ = false;
return status;
}

接着分下下CommitLayerStack

//hwc_display.cpp
HWC2::Error HWCDisplay::CommitLayerStack(void) {

DumpInputBuffers();

//display_intf_有三种类型
//DisplayPrimary、DisplayHDMI、DisplayVirtual
//我们只分析下DisplayPrimary
error = display_intf_->Commit(&layer_stack_);

skip_validate_ = true;
return HWC2::Error::None;
}

//display_primary.cpp
DisplayError DisplayPrimary::Commit(LayerStack *layer_stack) {

error = DisplayBase::Commit(layer_stack);

return error;
}

DisplayError DisplayBase::Commit(LayerStack *layer_stack) {

DisplayError error = kErrorNone;

DLOGI_IF(kTagDisplay, “Entering commit for display type : %d”, display_type_);
CommitLayerParams(layer_stack);

error = comp_manager_->Commit(display_comp_ctx_, &hw_layers_);

//hw_intf_有几种类型
//kPrimary:HWPeripheralDRM
//kHDMI:HWTVDRM
//kVirtual:HWVirtualDRM
error = hw_intf_->Commit(&hw_layers_);

PostCommitLayerParams(layer_stack);

error = comp_manager_->PostCommit(display_comp_ctx_, &hw_layers_);
DLOGI_IF(kTagDisplay, “Exiting commit for display type : %d”, display_type_);
return kErrorNone;
}

DisplayError HWPeripheralDRM::Commit(HWLayers *hw_layers) {
HWLayersInfo &hw_layer_info = hw_layers->info;
SetDestScalarData(hw_layer_info);
return HWDeviceDRM::Commit(hw_layers);
}

最终的提交在:

//hardware\qcom\display\sdm\libs\core\drm\hw_device_drm.cpp
DisplayError HWDeviceDRM::Commit(HWLayers *hw_layers) {

DisplayError err = kErrorNone;
registry_.RegisterCurrent(hw_layers);
//目前default_mode_为false
if (default_mode_) {
err = DefaultCommit(hw_layers);
} else {
err = AtomicCommit(hw_layers);
}
registry_.UnregisterNext();
return err;
}

DisplayError HWDeviceDRM::AtomicCommit(HWLayers hw_layers) {

SetupAtomic(hw_layers, false /
validate /);

//drm_atomic_intf_是在ap\hardware\qcom\display\libdrmutils\drm_lib_loader.cpp中
//通过dlopen(libsdedrm.so)获取的方法
//libsdedrm.so源码高通并未开源
int ret = drm_atomic_intf_->Commit(false /
synchronous /, false / retain_planes*/);

int release_fence = -1;
int retire_fence = -1;

drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, &release_fence);
drm_atomic_intf_->Perform(DRMOps::CONNECTOR_GET_RETIRE_FENCE, token_.conn_id, &retire_fence);

return kErrorNone;
}

在继续分析前需要先了解几个结构体

/*! @brief This structure defines a layer stack that contains layers which need to be composed and
rendered onto the target.
*/
struct LayerStack {
std::vector<Layer > layers = {}; //!< Vector of layer pointers.

}
/
! @brief This structure defines display layer object which contains layer properties and a drawing
buffer.

@sa LayerArray
*/
struct Layer {
LayerBuffer input_buffer = {}; //!< Buffer to be composed.
//!< If this remains unchanged between two
//!< consecutive Prepare() calls and
//!< geometry_changed flag is not set for the
//!< second call, then the display device will
//!< assume that buffer content has not
//!< changed.

LayerComposition composition = kCompositionGPU; //!< Composition type which can be set by either
//!< the client or the display device. This value
//!< should be preserved between Prepare() and
//!< Commit() calls.

LayerRect src_rect = {}; //!< Rectangular area of the layer buffer to
//!< consider for composition.

LayerRect dst_rect = {}; //!< The target position where the frame will be
//!< displayed. Cropping rectangle is scaled to
//!< fit into this rectangle. The origin is the
//!< top-left corner of the screen.

std::vector visible_regions = {}; //!< Visible rectangular areas in screen space.
//!< The visible region includes areas overlapped
//!< by a translucent layer.

std::vector dirty_regions = {}; //!< Rectangular areas in the current frames
//!< that have changed in comparison to
//!< previous frame.

std::vector blit_regions = {}; //!< Rectangular areas of this layer which need
//!< to be composed to blit target. Display
//!< device will update blit rectangles if a
//!< layer composition is set as hybrid. Nth blit
//!< rectangle shall be composed onto Nth blit
//!< target.

LayerBlending blending = kBlendingPremultiplied; //!< Blending operation which need to be
//!< applied on the layer buffer during
//!< composition.

LayerTransform transform = {}; //!< Rotation/Flip operations which need to be
//!< applied to the layer buffer during
//!< composition.

uint8_t plane_alpha = 0xff; //!< Alpha value applied to the whole layer.
//!< Value of each pixel is computed as:
//!< if(kBlendingPremultiplied) {
//!< pixel.RGB = pixel.RGB * planeAlpha/255
//!< }
//!< pixel.a = pixel.a * planeAlpha

uint32_t frame_rate = 0; //!< Rate at which frames are being updated for
//!< this layer.

uint32_t solid_fill_color = 0; //!< TODO: Remove this field when fb support
//! is deprecated.
//!< Solid color used to fill the layer when
//!< no content is associated with the layer.

LayerFlags flags; //!< Flags associated with this layer.

LayerRequest request = {}; //!< o/p - request on this Layer by SDM.

Lut3d lut_3d = {}; //!< o/p - Populated by SDM when tone mapping is
//!< needed on this layer.
LayerSolidFill solid_fill_info = {}; //!< solid fill info along with depth.
}

图片来源于https://www.jianshu.com/p/824a9ddf68b9,如有侵权,请告知删除,谢谢。 ↩︎

原文链接:https://blog.csdn.net/u010116586/article/details/107840156?utm_medium=distribute.pc_feed.428677.nonecase&depth_1-utm_source=distribute.pc_feed.428677.nonecase

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值