平台 | 内核版本 | 安卓版本 |
---|---|---|
RK3399 | Linux4.4 | Android7.1 |
文章目录
如何合成
方案一
在Framebuffer上依次画出(使用opengl)每个app,然后把Framebuffer显示出来
方案二(HWComposer)
各个app写入不同的window,硬件合成后在LCD上直接显示
使用OpenGL
void SurfaceFlinger::handleMessageRefresh() {
ATRACE_CALL();
preComposition();
rebuildLayerStacks(); //计算dirty区域
setUpHWComposer(); //如果有硬件合成单元的话
doDebugFlashRegions();
doComposition(); //对于opengl
postComposition();
}
- 绘画出每一个Layer
对于每个Layer,执行
layer->draw()
===>drawWithOpenGL()
- swapBuffer
void SurfaceFlinger::doComposition() {
ATRACE_CALL();
const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
const sp<DisplayDevice>& 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)
★ doDisplayComposition(hw, dirtyRegion); //重绘buffer
hw->dirtyRegion.clear();
hw->flip(hw->swapRegion);
hw->swapRegion.clear();
}
// inform the h/w that we're done compositing
hw->compositionComplete();
}
postFramebuffer();
}
doDisplayComposition函数对第个DisplayDevice的图层进行合成,在没有硬件合成模块的情况下,还进行输出显示
void SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
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)
bool isHwcDisplay = hw->getHwcDisplayId() >= 0;
if (!isHwcDisplay && inDirtyRegion.isEmpty()) {
return;
}
Region dirtyRegion(inDirtyRegion);
// compute the invalid region
hw->swapRegion.orSelf(dirtyRegion);
uint32_t flags = hw->getFlags();
if (flags & DisplayDevice::SWAP_RECTANGLE) {
// we can redraw only what's dirty, but since SWAP_RECTANGLE only
// takes a rectangle, we must make sure to update that whole
// rectangle in that case
dirtyRegion.set(hw->swapRegion.bounds());
} else {
if (flags & DisplayDevice::PARTIAL_UPDATES) {
// We need to redraw the rectangle that will be updated
// (pushed to the framebuffer).
// This is needed because PARTIAL_UPDATES only takes one
// rectangle instead of a region (see DisplayDevice::flip())
dirtyRegion.set(hw->swapRegion.bounds());
} else {
// we need to redraw everything (the whole screen)
dirtyRegion.set(hw->bounds());
hw->swapRegion = dirtyRegion;
}
}
if (CC_LIKELY(!mDaltonize && !mHasColorMatrix)) {
if (!doComposeSurfaces(hw, dirtyRegion)) return;
} else {
RenderEngine& engine(getRenderEngine());
mat4 colorMatrix = mColorMatrix;
if (mDaltonize) {
colorMatrix = colorMatrix * mDaltonizer();
}
engine.beginGroup(colorMatrix);
★ doComposeSurfaces(hw, dirtyRegion);
engine.endGroup();
}
// update the swap region and clear the dirty region
hw->swapRegion.orSelf(dirtyRegion);
// swap buffers (presentation)
★ hw->swapBuffers(getHwComposer());//重绘完图层后,应该把绘制完的图层替换过来以显示
}
- 调用doComposeSurfaces函数进行图层的合成,图像合成的真正执行者
- 调用hw->swapBuffers将软件合成的结果提交到图像缓冲区,待消费者去处理
bool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
{
......
/*
* and then, render the layers targeted at the framebuffer
*/
const Vector< sp<Layer> >& layers(hw->getVisibleLayersSortedByZ());
const size_t count = layers.size();
const Transform& tr = hw->getTransform();
if (cur != end) {
// we're using h/w composer
for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) {
const sp<Layer>& layer(layers[i]);
const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
if (!clip.isEmpty()) {
switch (cur->getCompositionType()) {
case HWC_CURSOR_OVERLAY:
case HWC_OVERLAY: {
const Layer::State& state(layer->getDrawingState());
if ((cur->getHints() & HWC_HINT_CLEAR_FB)
&& i
&& layer->isOpaque(state) && (state.alpha == 0xFF)
&& hasGlesComposition) {
// never clear the very first layer since we're
// guaranteed the FB is already cleared
layer->clearWithOpenGL(hw, clip);
}
break;
}
case HWC_FRAMEBUFFER: {
layer->draw(hw, clip);
break;
}
case HWC_FRAMEBUFFER_TARGET: {
// this should not happen as the iterator shouldn't
// let us get there.
ALOGW("HWC_FRAMEBUFFER_TARGET found in hwc list (index=%zu)", i);
break;
}
}
}
layer->setAcquireFence(hw, *cur);
}
} else {
// we're not using h/w composer
for (size_t i=0 ; i<count ; ++i) {
const sp<Layer>& layer(layers[i]);
const Region clip(dirty.intersect(
tr.transform(layer->visibleRegion)));
if (!clip.isEmpty()) {
layer->draw(hw, clip);
}
}
}
// disable scissor at the end of the frame
engine.disableScissor();
return true;
}
当图层的compositionType值为HWC_CURSOR_OVERLAY或HWC_OVERLAY,采用硬件合成。既将图层提交给HWComposer去处理
当图层的compositionType值为HWC_FRAMEBUFFER,采用软件gl合成。既调用Layer的draw方法绘制