SurfaceFlinger合成流程(三)
配置硬件合成 setUpHWComposer
回到handleMessageRefresh,继续看Refresh消息的处理。此时需要进行合成显示的数据,在rebuildLayerStacks时,已经被更新到每个Display各自的layersSortedByZ中。Layer栈创建完成后,进行HWC 合成的设置。
setUpHWComposer的代码比较长,我们分段看,在setUpHWComposer中,主要做了以下几件事:
1.DisplayDevice beginFrame
void SurfaceFlinger::setUpHWComposer() {
... ...
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
bool dirty = !mDisplays[dpy]->getDirtyRegion(false).isEmpty();
bool empty = mDisplays[dpy]->getVisibleLayersSortedByZ().size() == 0;
bool wasEmpty = !mDisplays[dpy]->lastCompositionHadVisibleLayers;
// 判断是否需要重新合成
bool mustRecompose = dirty && !(empty && wasEmpty);
... ...
mDisplays[dpy]->beginFrame(mustRecompose);
if (mustRecompose) {
mDisplays[dpy]->lastCompositionHadVisibleLayers = !empty;
}
}
Android对每一块显示屏的处理都是分开的。这里主要是调Display的beginFrame
函数。
status_t DisplayDevice::beginFrame(bool mustRecompose) const {
return mDisplaySurface->beginFrame(mustRecompose);
}
mDisplaySurface根据屏幕有所不同。
主显和外显用的FramebufferSurface,需显示用的VirtualDisplaySurface,我们这里先不关虚显。
status_t FramebufferSurface::beginFrame(bool /*mustRecompose*/) {
return NO_ERROR;
}
FramebufferSurface在beginFrame是每一做什么过多的处理。
回到setUpHWComposer函数
2.创建工作列表
void SurfaceFlinger::setUpHWComposer() {
... ...
// build the h/w work list
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);
}
}
}
}
}
对每个Display中的每个Layer创建对应的HWC Layer,注意hwcId,只是对hwcId大于零的Layer才会创建HWC Layer。Layer的createHwcLayer函数如下:
bool Layer::createHwcLayer(HWComposer* hwc, int32_t hwcId) {
LOG_ALWAYS_FATAL_IF(getBE().mHwcLayers.count(hwcId) != 0,
"Already have a layer for hwcId %d", hwcId);
HWC2::Layer* layer = hwc->createLayer(hwcId);
if (!layer) {
return false;
}
LayerBE::HWCInfo& hwcInfo = getBE().mHwcLayers[hwcId];
hwcInfo.hwc = hwc;
hwcInfo.layer = layer;
layer->setLayerDestroyedListener(
[this, hwcId](HWC2::Layer* /*layer*/) { getBE().mHwcLayers.erase(hwcId); });
return true;
}
根据hwcId来创建,也就是说,HWC上层(SurfaceFlinger)的每个Layer,都会为每个Display创建一个HWC Layer。HWComposer 根据hwcId找对HWC2的Display,再通过具体的HWC2::Dispaly去创建自己的HWC Layer;
Layer通过HWComposer来创建,
HWC2::Layer* HWComposer::createLayer(int32_t displayId) {
if (!isValidDisplay(displayId)) {
ALOGE("Failed to create layer on invalid display %d", displayId);
return nullptr;
}
auto display = mDisplayData[displayId].hwcDisplay;
HWC2::Layer* layer;
auto error = display->createLayer(&layer);
if (error != HWC2::Error::None) {
ALOGE("Failed to create layer on display %d: %s (%d)", displayId,
to_string(error).c_str(), static_cast<int32_t>(error));
return nullptr;
}
return layer;
}
创建HWC Layer的实现,最终是在Vendor实现的HAL中来完成的。对应的HWC2command为HWC2_FUNCTION_CREATE_LAYER
。
Error HwcHal::createLayer(Display display, Layer* outLayer)
{
int32_t err = mDispatch.createLayer(mDevice, display, outLayer);
return static_cast<Error>(err);
}
创建的HWC Layer在HWC2::Dispaly中也保存了一个引用:
* frameworks/native/services/surfaceflinger/DisplayHardware/HWC2.cpp
Error Display::createLayer(Layer** outLayer)
{
if (!outLayer) {
return Error::BadParameter;
}
hwc2_layer_t layerId = 0;
auto intError = mComposer.createLayer(mId, &layerId);
auto error = static_cast<Error>(intError);
if (error != Error::None) {
return error;
}
auto layer = std::make_unique<Layer>(
mComposer, mCapabilities, mId, layerId);
*outLayer = layer.get();
mLayers.emplace(layerId, std::move(layer));
return Error::None;
}
如果hwclayer没有创建成功,那么这一层Layer就强制用Client方式合成forceClientComposition。
void Layer::forceClientComposition(int32_t hwcId) {
if (getBE().mHwcLayers.count(hwcId) == 0) {
ALOGE("forceClientComposition: no HWC layer found (%d)", hwcId);
return;
}
getBE().mHwcLayers[hwcId].forceClientComposition = true;
}
另外,如果是Disable掉HWC合成,或者调试Region,也强制用Client方式合成:
mDebugDisableHWC || mDebugRegion
这两个调试方式可以在系统设置,开发者选项中进行设置。
创建完hwcLayer后,设置Layer的几何尺寸:
void Layer::setGeometry(const sp<const DisplayDevice>& displayDevice, uint32_t z)
{
... ... //注意,我们这里的数据都是来源于DrawingState
const State& s(getDrawingState());
... ...
if (!isOpaque(s) || getAlpha() != 1.0f) {
blendMode =
mPremultipliedAlpha ? HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
}
auto error = hwcLayer->setBlendMode(blendMode);
// 计算displayFrame
Rect frame{t.transform(computeBounds(activeTransparentRegion))};
... ...
const Transform& tr(displayDevice->getTransform());
Rect transformedFrame = tr.transform(frame);
error = hwcLayer->setDisplayFrame(transformedFrame);
... ...
// 计算sourceCrop
FloatRect sourceCrop = computeCrop(displayDevice);
error = hwcLayer->setSourceCrop(sourceCrop);
... ...
// 设置Alpha
float alpha = static_cast<float>(getAlpha());
error = hwcLayer->setPlaneAlpha(alpha);
... ...
// 设置z-order
error = hwcLayer->setZOrder(z);
... ...
int type = s.type;
int appId = s.appId;
sp<Layer> parent = mDrawingParent.promote();
if (parent.get()) {
auto& parentState = parent->getDrawingState();
type = parentState.type;
appId = parentState.appId;
}
// 设置Layer的信息
error = hwcLayer->setInfo(type, appId);
ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set info (%d)", mName.string(),
static_cast<int32_t>(error));
// 设置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);
... ...
}
}
注意,我们这里的数据都是来源于DrawingState,setGeometry函数中,主要做了以下几件事:
- 确认HWCLayer的混合模式
混合模式,是两个Layer直接的混合方式,主要下面的几种:
/* Blend modes, settable per layer */
typedef enum {
HWC2_BLEND_MODE_INVALID = 0,
/* colorOut = colorSrc */
HWC2_BLEND_MODE_NONE = 1,
/* colorOut = colorSrc + colorDst * (1 - alphaSrc) */
HWC2_BLEND_MODE_PREMULTIPLIED = 2,
/* colorOut = colorSrc * alphaSrc + colorDst * (1 - alphaSrc) */
HWC2_BLEND_MODE_COVERAGE = 3,
} hwc2_blend_mode_t;
HWC2_BLEND_MODE_NONE,不混合,源是什么样,输出就是什么样的。
HWC2_BLEND_MODE_PREMULTIPLIED,预乘,Dst需要做Alpha的处理。
HWC2_BLEND_MODE_COVERAGE,覆盖方式,源和Dst都需要做Alpha的处理。
-
计算displayFrame并设置给hwcLayer
displayFrame通过transform转换过的 -
计算sourceCrop并设置给hwcLayer
sourceCrop是上层传下来的,再和Dispaly,其他Layer的属性进行计算。 -
设置Alpha值
-
设置z-Order
-
设置Layer的信息
type和appId是Android Framework层创建SurfaceControl时设置的,可以搜搜"new SurfaceControl"就出来了。type是类型,比如ScreenshotSurface
,Background
等;appId是应用的进程号。 -
设置变换信息transform
Layer信息的设置,是通过CommandBuffer的读写来完成的,比如,设置混合模式,最终是调的HwcHal的setLayerBlendMode方法。
Error HwcHal::setLayerBlendMode(Display display, Layer layer, int32_t mode)
{
int32_t err = mDispatch.setLayerBlendMode(mDevice, display, layer, mode);
return static_cast<Error>(err);
}
回到setUpHWComposer函数
3.设置每层Layer的Frame数据
void SurfaceFlinger::setUpHWComposer() {
... ...
mat4 colorMatrix = mColorMatrix * computeSaturationMatrix() * mDaltonizer();
// Set the per-frame data
for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
auto& displayDevice = mDisplays[displayId];
const auto hwcId = displayDevice->getHwcDisplayId();
... ... // 设置每个Dispaly的颜色矩阵
if (colorMatrix != mPreviousColorMatrix) {
status_t result = getBE().mHwc->setColorTransform(hwcId, colorMatrix);
... ...
}
for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
if (layer->getForceClientComposition(hwcId)) {
ALOGV("[%s] Requesting Client composition", layer->getName().string());
layer->setCompositionType(hwcId, HWC2::Composition::Client);
continue;
}
layer->setPerFrameData(displayDevice);
}
if (hasWideColorDisplay) {
android_color_mode newColorMode;
android_dataspace newDataSpace = HAL_DATASPACE_V0_SRGB;
for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
newDataSpace = bestTargetDataSpace(layer->getDataSpace(), newDataSpace);
ALOGV("layer: %s, dataspace: %s (%#x), newDataSpace: %s (%#x)",
layer->getName().string(), dataspaceDetails(layer->getDataSpace()).c_str(),
layer->getDataSpace(), dataspaceDetails(newDataSpace).c_str(), newDataSpace);
}
newColorMode = pickColorMode(newDataSpace);
setActiveColorModeInternal(displayDevice, newColorMode);
}
}
mPreviousColorMatrix = colorMatrix;
设置Frame数据时,主要做了以下几件事:
- 设置每个Dispaly的颜色矩阵
可以在开发这选项中设置,模拟颜色空间。其支持的transform主要有:
typedef enum {
HAL_COLOR_TRANSFORM_IDENTITY = 0,
HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX = 1,
HAL_COLOR_TRANSFORM_VALUE_INVERSE = 2,
HAL_COLOR_TRANSFORM_GRAYSCALE = 3,
HAL_COLOR_TRANSFORM_CORRECT_PROTANOPIA = 4,
HAL_COLOR_TRANSFORM_CORRECT_DEUTERANOPIA = 5,
HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA = 6,
} android_color_transform_t;
colorTransform主要是用以做颜色变换,以模拟或帮助色盲患者等。
- 设置每一层Layer的显示数据
setPerFrameData BufferLayer和ColorLayer的实现不一样。ColorLayer 的逻辑比较简单:
void ColorLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
... ...
// 设置可见区域
auto error = hwcLayer->setVisibleRegion(visible);
// 制定合成方式
setCompositionType(hwcId, HWC2::Composition::SolidColor);
half4 color = getColor();
// 设置颜色
error = hwcLayer->setColor({static_cast<uint8_t>(std::round(255.0f * color.r)),
static_cast<uint8_t>(std::round(255.0f * color.g)),
static_cast<uint8_t>(std::round(255.0f *