当前位置:   article > 正文

Android6.0 图像合成过程详解(一) setUpHWComposer函数_android dotransaction

android dotransaction

上一篇博客分析了,用户进程如何申请一个GraphicBuffer的过程。这篇博客我们进一步分析图像合成过程,其中也解答之前的一些疑惑:

1. 之前碰到的不支持硬件模块

2. DisplayDevice类

3. 消费者的onFrameAvailable函数

我们直接分析合成的过程,具体的流程我们http://blog.csdn.net/kc58236582/article/details/52778333这篇博客分析了,这篇博客我们增加了一些以前没理解的点。


一、handleTransactionLocked函数

1.1 Layer的doTransaction函数

这里我直接从handleTransactionLocked函数开始分析,这个函数先会调用每个Layer对象的doTransaction函数,我们先来看看这个函数。

  1. uint32_t Layer::doTransaction(uint32_t flags) {
  2. ATRACE_CALL();
  3. const Layer::State& s(getDrawingState());//上次绘制的State对象
  4. const Layer::State& c(getCurrentState());//当前使用的State对象
  5. const bool sizeChanged = (c.requested.w != s.requested.w) ||//如果两个对象的大小不相等,说明Layer的尺寸发生变化
  6. (c.requested.h != s.requested.h);
  7. if (sizeChanged) {//如果Layer的尺寸发生变化,就要改变Surface的缓冲区的尺寸
  8. mSurfaceFlingerConsumer->setDefaultBufferSize(
  9. c.requested.w, c.requested.h);
  10. }
  11. if (!isFixedSize()) {
  12. //如果Layer不是固定尺寸的类型,比较它的实际大小和要求的改变大小
  13. const bool resizePending = (c.requested.w != c.active.w) ||
  14. (c.requested.h != c.active.h);
  15. if (resizePending && mSidebandStream == NULL) {//如果两者不一样,flags加上不更新Geometry标志
  16. flags |= eDontUpdateGeometryState;
  17. }
  18. }
  19. if (flags & eDontUpdateGeometryState) {
  20. } else {
  21. //如果没有eDontUpdateGeometryState标志,更新active的值为request
  22. Layer::State& editCurrentState(getCurrentState());
  23. editCurrentState.active = c.requested;
  24. }
  25. if (s.active != c.active) {
  26. // 如果当前state的active和以前的State的active不等,设置更新标志
  27. flags |= Layer::eVisibleRegion;
  28. }
  29. if (c.sequence != s.sequence) {
  30. //如果当前state的sequence和以前state的sequence不等,设置更新标志
  31. flags |= eVisibleRegion;
  32. this->contentDirty = true;
  33. const uint8_t type = c.transform.getType();
  34. mNeedsFiltering = (!c.transform.preserveRects() ||
  35. (type >= Transform::SCALE));
  36. }
  37. // Commit the transaction
  38. commitTransaction();//将mCurrentState的值赋给mDrawingState
  39. return flags;
  40. }

这个函数之前博客也分析过,这里我们看看其中最重要的一个flag就是eVisibleRegion代表这个Layer是否要更新。而这里如果要更新Layer,也只是大小,sequence(也就是属性)变化才会更新这个flag。而Layer内容(buffer)的更新不在这里。这里使用了mDrawingState,mCurrentState两个变量。这两个变量主要是一些属性值。

最后会把mCurrentState的值赋给mDrawingState。而mCurrentState是在下面一些函数中变化的:

  1. bool Layer::setPosition(float x, float y) {
  2. if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
  3. return false;
  4. mCurrentState.sequence++;
  5. mCurrentState.transform.set(x, y);
  6. setTransactionFlags(eTransactionNeeded);
  7. return true;
  8. }
  9. bool Layer::setLayer(uint32_t z) {
  10. if (mCurrentState.z == z)
  11. return false;
  12. mCurrentState.sequence++;
  13. mCurrentState.z = z;
  14. setTransactionFlags(eTransactionNeeded);
  15. return true;
  16. }
  17. bool Layer::setSize(uint32_t w, uint32_t h) {
  18. if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
  19. return false;
  20. mCurrentState.requested.w = w;
  21. mCurrentState.requested.h = h;
  22. setTransactionFlags(eTransactionNeeded);
  23. return true;
  24. }
  25. bool Layer::setAlpha(uint8_t alpha) {
  26. if (mCurrentState.alpha == alpha)
  27. return false;
  28. mCurrentState.sequence++;
  29. mCurrentState.alpha = alpha;
  30. setTransactionFlags(eTransactionNeeded);
  31. return true;
  32. }

我们下面开始看handleTransactionLocked函数。

先看下处理layer的事务,遍历每个Layer的doTransaction来更新状态,以及根据flags是否要更新layer。

  1. void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
  2. {
  3. const LayerVector& currentLayers(mCurrentState.layersSortedByZ);//所有的Layer
  4. const size_t count = currentLayers.size();
  5. /*
  6. * Traversal of the children
  7. * (perform the transaction for each of them if needed)
  8. */
  9. if (transactionFlags & eTraversalNeeded) {
  10. for (size_t i=0 ; i<count ; i++) {
  11. const sp<Layer>& layer(currentLayers[i]);
  12. uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
  13. if (!trFlags) continue;
  14. const uint32_t flags = layer->doTransaction(0);//遍历每个layer,更新mDrawingState状态
  15. if (flags & Layer::eVisibleRegion)
  16. mVisibleRegionsDirty = true;//有需要更新的layer,把该变量置为true
  17. }
  18. }

1.2 处理显示设备的变化

下面是handleTransactionLocked中处理显示设备的变化的

  1. if (transactionFlags & eDisplayTransactionNeeded) {
  2. //得到当前显示设备列表和之前使用的显示设备列表
  3. const KeyedVector< wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
  4. const KeyedVector< wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
  5. if (!curr.isIdenticalTo(draw)) {
  6. mVisibleRegionsDirty = true;
  7. const size_t cc = curr.size();//现在显示设备的数量
  8. size_t dc = draw.size();//以前显示设备的数量
  9. for (size_t i=0 ; i<dc ; i++) {
  10. const ssize_t j = curr.indexOfKey(draw.keyAt(i));
  11. if (j < 0) {//j< 0代表当前设备列表中找不到以前设备列表中的某个设备,设备被删除了
  12. if (!draw[i].isMainDisplay()) {
  13. ......
  14. //如果不是主设备移除它
  15. mDisplays.removeItem(draw.keyAt(i));
  16. } else {
  17. ALOGW("trying to remove the main display");
  18. }
  19. } else {//j>0代表这个设备两个列表中都存在,再检查有没有其他变化
  20. // this display is in both lists. see if something changed.
  21. const DisplayDeviceState& state(curr[j]);
  22. const wp<IBinder>& display(curr.keyAt(j));
  23. const sp<IBinder> state_binder = IInterface::asBinder(state.surface);
  24. const sp<IBinder> draw_binder = IInterface::asBinder(draw[i].surface);
  25. if (state_binder != draw_binder) {
  26. //设备的Surface已经发生了变化(Surface对象不是一个了),旧的设备必须先删除掉
  27. sp<DisplayDevice> hw(getDisplayDevice(display));
  28. if (hw != NULL)
  29. hw->disconnect(getHwComposer());
  30. mDisplays.removeItem(display);
  31. mDrawingState.displays.removeItemsAt(i);
  32. dc--; i--;
  33. // at this point we must loop to the next item
  34. continue;
  35. }
  36. const sp<DisplayDevice> disp(getDisplayDevice(display));
  37. if (disp != NULL) {
  38. //两个对象的layerStack不相等,使用当前对象的
  39. if (state.layerStack != draw[i].layerStack) {
  40. disp->setLayerStack(state.layerStack);
  41. }
  42. //如果两个对象的方向、viewport、frame不相等,使用当前对象的
  43. if ((state.orientation != draw[i].orientation)
  44. || (state.viewport != draw[i].viewport)
  45. || (state.frame != draw[i].frame))
  46. {
  47. disp->setProjection(state.orientation,
  48. state.viewport, state.frame);
  49. }
  50. if (state.width != draw[i].width || state.height != draw[i].height) {
  51. disp->setDisplaySize(state.width, state.height);
  52. }
  53. }
  54. }
  55. }
  56. // 处理显示设备增加的情况
  57. for (size_t i=0 ; i<cc ; i++) {
  58. if (draw.indexOfKey(curr.keyAt(i)) < 0) {
  59. //当前列表中某个设备在以前列表中没有找到,说明是增加的设备
  60. //创建DisplayDevice对象,把它加入到mDisplays列表中
  61. ......
  62. const wp<IBinder>& display(curr.keyAt(i));
  63. if (dispSurface != NULL) {
  64. sp<DisplayDevice> hw = new DisplayDevice(this,
  65. state.type, hwcDisplayId,
  66. mHwc->getFormat(hwcDisplayId), state.isSecure,
  67. display, dispSurface, producer,
  68. mRenderEngine->getEGLConfig());
  69. ......
  70. mDisplays.add(display, hw);
  71. ......
  72. }
  73. }
  74. }
  75. }
  76. }

这段代码的作用是处理显示设备的变化,分成3种情况:

1.显示设备减少了,需要把显示设备对应的DisplayDevice移除

2.显示设备发生了变化,例如用户设置了Surface、重新设置了layerStack、旋转了屏幕等,这就需要重新设置显示对象的属性

3.显示设备增加了,创建新的DisplayDevice加入系统中。

这些在之前博客都分析过,我们主要看下几个变量mCurrentState.displays, mDrawingState.displays。代表之前的设备和现在的设备。

这些displays是State的一个变量,是每个display的一个唯一码对应一个DisplayDeviceState(状态)。

  1. struct State {
  2. LayerVector layersSortedByZ;
  3. DefaultKeyedVector< wp<IBinder>, DisplayDeviceState> displays;
  4. };

而mDisplays是一个Display的唯一码 对应一个DisplayDevice。

    DefaultKeyedVector< wp<IBinder>, sp<DisplayDevice> > mDisplays;

而这里主要用mCurrentState.displays, mDrawingState.displays中的Display的唯一码看哪个DisplayDevice增加了或者删除了,再去根据这个唯一码来对应在mDisplays中的DisplayDevice增加或者删除或者一些状态的修改。


1.3 设置TransformHint

  1. if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) {
  2. sp<const DisplayDevice> disp;
  3. uint32_t currentlayerStack = 0;
  4. for (size_t i=0; i<count; i++) {
  5. // NOTE: we rely on the fact that layers are sorted by
  6. // layerStack first (so we don't have to traverse the list
  7. // of displays for every layer).
  8. const sp<Layer>& layer(currentLayers[i]);
  9. uint32_t layerStack = layer->getDrawingState().layerStack;
  10. if (i==0 || currentlayerStack != layerStack) {
  11. currentlayerStack = layerStack;
  12. // figure out if this layerstack is mirrored
  13. // (more than one display) if so, pick the default display,
  14. // if not, pick the only display it's on.
  15. disp.clear();//清除disp
  16. for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
  17. sp<const DisplayDevice> hw(mDisplays[dpy]);
  18. if (hw->getLayerStack() == currentlayerStack) {
  19. if (disp == NULL) {
  20. disp = hw;//找到了一个layerStacker相同的显示设备
  21. } else {
  22. disp = NULL;//如果有两个显示设备的layerStacker相同,都不用
  23. break;
  24. }
  25. }
  26. }
  27. }
  28. if (disp == NULL) {
  29. // 没有找到具有相同layerStack的显示设备,使用缺省设备
  30. disp = getDefaultDisplayDevice();
  31. }
  32. layer->updateTransformHint(disp);//设置Layer对象的TransformHint
  33. }
  34. }

这段代码的作用是根据每种显示设备的不同,设置和显示设备关联在一起的Layer(主要看Layer的layerStack是否和DisplayDevice的layerStack)的TransformHint(主要指设备的显示方向orientation)。



1.4 处理Layer增加情况

  1. const LayerVector& layers(mDrawingState.layersSortedByZ);
  2. if (currentLayers.size() > layers.size()) {
  3. // 如果有Layer加入,设置需要更新
  4. mVisibleRegionsDirty = true;
  5. }
  6. // 处理有Layer删除的情况
  7. if (mLayersRemoved) {
  8. mLayersRemoved = false;
  9. mVisibleRegionsDirty = true;
  10. const size_t count = layers.size();
  11. for (size_t i=0 ; i<count ; i++) {
  12. const sp<Layer>& layer(layers[i]);
  13. if (currentLayers.indexOf(layer) < 0) {
  14. //如果这个Layer已经不存在了,把它的所在区域设置为需要更新的区域
  15. const Layer::State& s(layer->getDrawingState());
  16. Region visibleReg = s.transform.transform(
  17. Region(Rect(s.active.w, s.active.h)));
  18. invalidateLayerStack(s.layerStack, visibleReg);
  19. }
  20. }
  21. }

这段代码处理Layer的增加情况,如果Layer增加了,需要重新计算设备的更新区域,因此把mVisibleRegionsDirty设为true,如果Layer删除了,需要把Layer的可见区域加入到系统需要更新的区域中。

而这里mVisibleRegionsDirty设为true代表Layer需要更新,如果Layer不需要更新的话后面的rebuildLayerStack函数的执行就是空的了。


1.5 设置mDrawingState

  1. commitTransaction();
  2. updateCursorAsync();
调用commitTransaction和updateCursorAsync函数 commitTransaction函数作用是把mDrawingState的值设置成mCurrentState的值。而updateCursorAsync函数会更新所有显示设备中光标的位置。

1.6 小结

handleTransaction函数的作用的就是处理系统在两次刷新期间的各种变化。SurfaceFlinger模块中不管是SurfaceFlinger类还是Layer类,都采用了双缓冲的方式来保存他们的属性,这样的好处是刚改变SurfaceFlinger对象或者Layer类对象的属性是,不需要上锁,大大的提高了系统效率。只有在最后的图像输出是,才进行一次上锁,并进行内存的属性变化处理。正因此,应用进程必须收到VSync信号才开始改变Surface的内容。


二、handlePageFlip函数

代码如下,这个函数就是更新Layer中的buffer(内容),遍历每个Layer看这个Layer是否有内容更新,就看其hasQueuedFrame函数是否返回true。之前分析过当有更新的话,mQueuedFrames的值会加1.而hasQueuedFrame函数就是看这个值是否为0

  1. bool SurfaceFlinger::handlePageFlip()
  2. {
  3. Region dirtyRegion;
  4. bool visibleRegions = false;
  5. const LayerVector& layers(mDrawingState.layersSortedByZ);
  6. bool frameQueued = false;
  7. Vector<Layer*> layersWithQueuedFrames;
  8. //查找需要更新的Layer
  9. for (size_t i = 0, count = layers.size(); i<count ; i++) {
  10. const sp<Layer>& layer(layers[i]);
  11. if (layer->hasQueuedFrame()) {
  12. frameQueued = true;
  13. if (layer->shouldPresentNow(mPrimaryDispSync)) {
  14. layersWithQueuedFrames.push_back(layer.get());
  15. } else {
  16. layer->useEmptyDamage();
  17. }
  18. } else {
  19. layer->useEmptyDamage();
  20. }
  21. }
  22. for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) {
  23. Layer* layer = layersWithQueuedFrames[i];
  24. const Region dirty(layer->latchBuffer(visibleRegions));
  25. layer->useSurfaceDamage();
  26. const Layer::State& s(layer->getDrawingState());
  27. invalidateLayerStack(s.layerStack, dirty);
  28. }
  29. mVisibleRegionsDirty |= visibleRegions;
  30. if (frameQueued && layersWithQueuedFrames.empty()) {
  31. signalLayerUpdate();
  32. }
  33. return !layersWithQueuedFrames.empty();
  34. }

hasQueuedFrame函数如下。

    bool hasQueuedFrame() const { return mQueuedFrames > 0 || mSidebandStreamChanged; }
最后把所有需要更新的Layer放在layersWithQueuedFrames,然后调用每个Layer的latchBuffer函数。

调用每个Layer的latchBuffer函数根据返回的更新区域调用invalidateLayerStack来设置更新设备对象的更新区域。

我们先来看看invalidateLayerStack函数,在SurfaceFlinger.cpp中的invalidateLayerStack。先是遍历所有的设备,找到和Layer的layerStack一样的设备,然后调用了DisplayDevice的dirtyRegion.orSelf方法

  1. void SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
  2. const Region& dirty) {
  3. for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
  4. const sp<DisplayDevice>& hw(mDisplays[dpy]);
  5. if (hw->getLayerStack() == layerStack) {
  6. hw->dirtyRegion.orSelf(dirty);
  7. }
  8. }
  9. }
orSelf方法,就是把Layer的更新区域 加到 DisplayDevice的dirtyRegion区域上。
  1. Region& Region::orSelf(const Rect& r) {
  2. return operationSelf(r, op_or);
  3. }

最后我们再来看看latchBuffer函数

  1. Region Layer::latchBuffer(bool& recomputeVisibleRegions)
  2. {
  3. ATRACE_CALL();
  4. if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
  5. // mSidebandStreamChanged was true
  6. mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
  7. if (mSidebandStream != NULL) {
  8. setTransactionFlags(eTransactionNeeded);
  9. mFlinger->setTransactionFlags(eTraversalNeeded);
  10. }
  11. recomputeVisibleRegions = true;
  12. const State& s(getDrawingState());
  13. return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
  14. }
  15. Region outDirtyRegion;
  16. if (mQueuedFrames > 0) { //mQueuedFrames大于0代表有Surface更新的要求
  17. if (mRefreshPending) {
  18. return outDirtyRegion;
  19. }
  20. // Capture the old state of the layer for comparisons later
  21. const State& s(getDrawingState());//注意这是使用的DrawingState
  22. const bool oldOpacity = isOpaque(s);
  23. sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
  24. struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
  25. ......//定义Reject结构体
  26. };
  27. Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
  28. getProducerStickyTransform() != 0);
  29. uint64_t maxFrameNumber = 0;
  30. {
  31. Mutex::Autolock lock(mQueueItemLock);
  32. maxFrameNumber = mLastFrameNumberReceived;
  33. }
  34. status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,//更新纹理
  35. mFlinger->mPrimaryDispSync, maxFrameNumber);
  36. if (updateResult == BufferQueue::PRESENT_LATER) {
  37. mFlinger->signalLayerUpdate();//如果结果是推迟处理,发送Invalidate消息
  38. return outDirtyRegion;
  39. } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
  40. // If the buffer has been rejected, remove it from the shadow queue
  41. // and return early
  42. Mutex::Autolock lock(mQueueItemLock);
  43. mQueueItems.removeAt(0);
  44. android_atomic_dec(&mQueuedFrames);
  45. return outDirtyRegion;
  46. } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
  47. // This can occur if something goes wrong when trying to create the
  48. // EGLImage for this buffer. If this happens, the buffer has already
  49. // been released, so we need to clean up the queue and bug out
  50. // early.
  51. {
  52. Mutex::Autolock lock(mQueueItemLock);
  53. mQueueItems.clear();
  54. android_atomic_and(0, &mQueuedFrames);
  55. }
  56. // Once we have hit this state, the shadow queue may no longer
  57. // correctly reflect the incoming BufferQueue's contents, so even if
  58. // updateTexImage starts working, the only safe course of action is
  59. // to continue to ignore updates.
  60. mUpdateTexImageFailed = true;
  61. return outDirtyRegion;
  62. }
  63. { // Autolock scope
  64. auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
  65. Mutex::Autolock lock(mQueueItemLock);
  66. // Remove any stale buffers that have been dropped during
  67. // updateTexImage
  68. while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
  69. mQueueItems.removeAt(0);
  70. android_atomic_dec(&mQueuedFrames);
  71. }
  72. mQueueItems.removeAt(0);
  73. }
  74. // Decrement the queued-frames count. Signal another event if we
  75. // have more frames pending.
  76. if (android_atomic_dec(&mQueuedFrames) > 1) {//减少mQueuedFrames的值
  77. mFlinger->signalLayerUpdate();//如果还有更多frame需要处理,要发消息
  78. }
  79. if (updateResult != NO_ERROR) {
  80. // something happened!
  81. recomputeVisibleRegions = true;
  82. return outDirtyRegion;
  83. }
  84. //更新mActiveBuffer,得到现在需要输出的图像数据
  85. mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
  86. if (mActiveBuffer == NULL) {
  87. return outDirtyRegion;//出错
  88. }
  89. mRefreshPending = true;
  90. mFrameLatencyNeeded = true;
  91. //下面根据各种情况是否重新计算更新区域
  92. if (oldActiveBuffer == NULL) {
  93. // the first time we receive a buffer, we need to trigger a
  94. // geometry invalidation.
  95. recomputeVisibleRegions = true;
  96. }
  97. Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
  98. const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
  99. const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
  100. if ((crop != mCurrentCrop) ||
  101. (transform != mCurrentTransform) ||
  102. (scalingMode != mCurrentScalingMode))
  103. {
  104. mCurrentCrop = crop;
  105. mCurrentTransform = transform;
  106. mCurrentScalingMode = scalingMode;
  107. recomputeVisibleRegions = true;
  108. }
  109. if (oldActiveBuffer != NULL) {
  110. uint32_t bufWidth = mActiveBuffer->getWidth();
  111. uint32_t bufHeight = mActiveBuffer->getHeight();
  112. if (bufWidth != uint32_t(oldActiveBuffer->width) ||
  113. bufHeight != uint32_t(oldActiveBuffer->height)) {
  114. recomputeVisibleRegions = true;
  115. }
  116. }
  117. mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
  118. if (oldOpacity != isOpaque(s)) {
  119. recomputeVisibleRegions = true;
  120. }
  121. // FIXME: postedRegion should be dirty & bounds
  122. Region dirtyRegion(Rect(s.active.w, s.active.h));
  123. // transform the dirty region to window-manager space
  124. outDirtyRegion = (s.transform.transform(dirtyRegion));//返回Layer的更新区域
  125. }
  126. return outDirtyRegion;
  127. }

这里我们来看mSurfaceFlingerConsumer->updateTexImage更新纹理

  1. status_t SurfaceFlingerConsumer::updateTexImage(BufferRejecter* rejecter,
  2. const DispSync& dispSync, uint64_t maxFrameNumber)
  3. {
  4. ATRACE_CALL();
  5. Mutex::Autolock lock(mMutex);
  6. if (mAbandoned) {
  7. ALOGE("updateTexImage: GLConsumer is abandoned!");
  8. return NO_INIT;
  9. }
  10. // Make sure the EGL state is the same as in previous calls.
  11. status_t err = checkAndUpdateEglStateLocked();
  12. if (err != NO_ERROR) {
  13. return err;
  14. }
  15. BufferItem item;
  16. // Acquire the next buffer.
  17. // In asynchronous mode the list is guaranteed to be one buffer
  18. // deep, while in synchronous mode we use the oldest buffer.
  19. err = acquireBufferLocked(&item, computeExpectedPresent(dispSync),//消费者端取数据
  20. maxFrameNumber);
  21. if (err != NO_ERROR) {
  22. if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
  23. err = NO_ERROR;
  24. } else if (err == BufferQueue::PRESENT_LATER) {
  25. // return the error, without logging
  26. } else {
  27. ALOGE("updateTexImage: acquire failed: %s (%d)",
  28. strerror(-err), err);
  29. }
  30. return err;
  31. }
  32. // We call the rejecter here, in case the caller has a reason to
  33. // not accept this buffer. This is used by SurfaceFlinger to
  34. // reject buffers which have the wrong size
  35. int buf = item.mBuf;
  36. if (rejecter && rejecter->reject(mSlots[buf].mGraphicBuffer, item)) {
  37. releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, EGL_NO_SYNC_KHR);
  38. return BUFFER_REJECTED;
  39. }
  40. // Release the previous buffer.
  41. err = updateAndReleaseLocked(item);
  42. if (err != NO_ERROR) {
  43. return err;
  44. }
  45. if (!SyncFeatures::getInstance().useNativeFenceSync()) {
  46. // Bind the new buffer to the GL texture.
  47. //
  48. // Older devices require the "implicit" synchronization provided
  49. // by glEGLImageTargetTexture2DOES, which this method calls. Newer
  50. // devices will either call this in Layer::onDraw, or (if it's not
  51. // a GL-composited layer) not at all.
  52. err = bindTextureImageLocked();
  53. }
  54. return err;
  55. }
我们再来看看updateAndReleaseLocked函数,这个函数释放了buffer,然后更新了mCurrentTexture mCurrentTextureImage等。

  1. status_t GLConsumer::updateAndReleaseLocked(const BufferItem& item)
  2. {
  3. status_t err = NO_ERROR;
  4. int buf = item.mBuf;
  5. if (!mAttached) {
  6. releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer,
  7. mEglDisplay, EGL_NO_SYNC_KHR);
  8. return INVALID_OPERATION;
  9. }
  10. err = checkAndUpdateEglStateLocked();
  11. ......
  12. err = mEglSlots[buf].mEglImage->createIfNeeded(mEglDisplay, item.mCrop);
  13. ......
  14. err = syncForReleaseLocked(mEglDisplay);
  15. ......
  16. //释放buffer
  17. if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
  18. status_t status = releaseBufferLocked(
  19. mCurrentTexture, mCurrentTextureImage->graphicBuffer(),
  20. mEglDisplay, mEglSlots[mCurrentTexture].mEglFence);
  21. if (status < NO_ERROR) {
  22. GLC_LOGE("updateAndRelease: failed to release buffer: %s (%d)",
  23. strerror(-status), status);
  24. err = status;
  25. // keep going, with error raised [?]
  26. }
  27. }
  28. // 更新状态
  29. mCurrentTexture = buf;
  30. mCurrentTextureImage = mEglSlots[buf].mEglImage;
  31. mCurrentCrop = item.mCrop;
  32. mCurrentTransform = item.mTransform;
  33. mCurrentScalingMode = item.mScalingMode;
  34. mCurrentTimestamp = item.mTimestamp;
  35. mCurrentFence = item.mFence;
  36. mCurrentFrameNumber = item.mFrameNumber;
  37. computeCurrentTransformMatrixLocked();
  38. return err;
  39. }
最后Layer的mActiveBuffer是从mSurfaceFlingerConsumer->getCurrentBuffer(),而就是mCurrentTextureImage变量。

  1. sp<GraphicBuffer> GLConsumer::getCurrentBuffer() const {
  2. Mutex::Autolock lock(mMutex);
  3. return (mCurrentTextureImage == NULL) ?
  4. NULL : mCurrentTextureImage->graphicBuffer();
  5. }

LatchBuffer函数调用updateTextImage来得到需要的图像。这里参数r是Reject对象,其作用是判断在缓冲区的尺寸是否符合要求。调用updateTextImage函数如果得到的结果是PRESENT_LATER,表示推迟处理,然后调用signalLayerUpdate函数来发送invalidate消息,这次绘制过程就不处理这个Surface的图像了。

如果不需要推迟处理,把mQueuedFrames的值减1.

最后LatchBuffer函数调用mSurfaceFlingerConsumer的getCurrentBuffer来取回当前的图像缓冲区指针,保存在mActiveBuffer中。



这样经过handleTransaction handlePageFlip两个函数处理SurfaceFlinger中无论是Layer属性的变化还是图像的变化都处理好了,只等VSync信号到来就可以输出了。



三、rebuildLayerStack函数

VSync信号来了之后先是调用的这个函数,前面分析handleTransactionLocked的时候,当mVisibleRegionsDirty为 true代表是要更新Layer,这里上来就是看这个变量是否为true。

  1. void SurfaceFlinger::rebuildLayerStacks() {
  2. // rebuild the visible layer list per screen
  3. if (CC_UNLIKELY(mVisibleRegionsDirty)) {//mVisibleRegionsDirty是否为true
  4. ATRACE_CALL();
  5. mVisibleRegionsDirty = false;
  6. invalidateHwcGeometry();
  7. //计算每个显示设备上可见的Layer
  8. const LayerVector& layers(mDrawingState.layersSortedByZ);
  9. for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
  10. Region opaqueRegion;
  11. Region dirtyRegion;
  12. Vector< sp<Layer> > layersSortedByZ;
  13. const sp<DisplayDevice>& hw(mDisplays[dpy]);
  14. const Transform& tr(hw->getTransform());
  15. const Rect bounds(hw->getBounds());
  16. if (hw->isDisplayOn()) {
  17. //计算每个layer的可见区域,确定设备需要重新绘制的区域
  18. SurfaceFlinger::computeVisibleRegions(layers,
  19. hw->getLayerStack(), dirtyRegion, opaqueRegion);
  20. const size_t count = layers.size();
  21. for (size_t i=0 ; i<count ; i++) {
  22. const sp<Layer>& layer(layers[i]);
  23. const Layer::State& s(layer->getDrawingState());
  24. if (s.layerStack == hw->getLayerStack()) {
  25. //只需要和显示设备的LayerStack相同的layer
  26. Region drawRegion(tr.transform(
  27. layer->visibleNonTransparentRegion));
  28. drawRegion.andSelf(bounds);
  29. if (!drawRegion.isEmpty()) {
  30. //如果Layer的显示区域和显示设备的窗口有交集
  31. //把Layer加入列表中
  32. layersSortedByZ.add(layer);
  33. }
  34. }
  35. }
  36. }
  37. //设置显示设备的可见Layer列表
  38. hw->setVisibleLayersSortedByZ(layersSortedByZ);
  39. hw->undefinedRegion.set(bounds);
  40. hw->undefinedRegion.subtractSelf(tr.transform(opaqueRegion));
  41. hw->dirtyRegion.orSelf(dirtyRegion);//设置每个DisplayDevice的drawRegions 加上dirtyRegion区域
  42. }
  43. }
  44. }

rebuildLayerStacks函数的作用是重建每个显示设备的可见layer对象列表。其他的说明还是看另一篇博客http://write.blog.csdn.net/postedit?ref=toolbar&ticket=ST-83533-ejxpwYJbCoASdBlu6Tpr-passport.csdn.net


四、setUpHWComposer函数

HWComposer中有一个类型为DisplayData结构的数组mDisplayData[],维护每个显示设备的信息。我们先来看在HWComposer构造函数中有下面这段代码,我们这里mFbDev为空,因此我们遍历每个设备,调用queryDisplayProperties函数。

  1. if (mFbDev) {
  2. ALOGD("chenchen mFbDev end");
  3. ALOG_ASSERT(!(mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)),
  4. "should only have fbdev if no hwc or hwc is 1.0");
  5. DisplayData& disp(mDisplayData[HWC_DISPLAY_PRIMARY]);
  6. disp.connected = true;
  7. disp.format = mFbDev->format;
  8. DisplayConfig config = DisplayConfig();
  9. config.width = mFbDev->width;
  10. config.height = mFbDev->height;
  11. config.xdpi = mFbDev->xdpi;
  12. config.ydpi = mFbDev->ydpi;
  13. config.refresh = nsecs_t(1e9 / mFbDev->fps);
  14. disp.configs.push_back(config);
  15. disp.currentConfig = 0;
  16. } else if (mHwc) {
  17. // here we're guaranteed to have at least HWC 1.1
  18. for (size_t i =0 ; i<NUM_BUILTIN_DISPLAYS ; i++) {
  19. queryDisplayProperties(i);
  20. }
  21. }

下面我们来看queryDisplayProperties函数,通过hwc模块的getDisplayConfigs和getDisplayAttributes方法来获取configs,最后把格式和connect设置为true。

  1. status_t HWComposer::queryDisplayProperties(int disp) {
  2. LOG_ALWAYS_FATAL_IF(!mHwc || !hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1));
  3. // use zero as default value for unspecified attributes
  4. int32_t values[NUM_DISPLAY_ATTRIBUTES - 1];
  5. memset(values, 0, sizeof(values));
  6. const size_t MAX_NUM_CONFIGS = 128;
  7. uint32_t configs[MAX_NUM_CONFIGS] = {0};
  8. size_t numConfigs = MAX_NUM_CONFIGS;
  9. status_t err = mHwc->getDisplayConfigs(mHwc, disp, configs, &numConfigs);
  10. if (err != NO_ERROR) {
  11. // this can happen if an unpluggable display is not connected
  12. mDisplayData[disp].connected = false;
  13. return err;
  14. }
  15. mDisplayData[disp].currentConfig = 0;
  16. for (size_t c = 0; c < numConfigs; ++c) {
  17. err = mHwc->getDisplayAttributes(mHwc, disp, configs[c],
  18. DISPLAY_ATTRIBUTES, values);
  19. // If this is a pre-1.5 HWC, it may not know about color transform, so
  20. // try again with a smaller set of attributes
  21. if (err != NO_ERROR) {
  22. err = mHwc->getDisplayAttributes(mHwc, disp, configs[c],
  23. PRE_HWC15_DISPLAY_ATTRIBUTES, values);
  24. }
  25. if (err != NO_ERROR) {
  26. // we can't get this display's info. turn it off.
  27. mDisplayData[disp].connected = false;
  28. return err;
  29. }
  30. DisplayConfig config = DisplayConfig();
  31. for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
  32. switch (DISPLAY_ATTRIBUTES[i]) {
  33. case HWC_DISPLAY_VSYNC_PERIOD:
  34. config.refresh = nsecs_t(values[i]);//设置config
  35. break;
  36. case HWC_DISPLAY_WIDTH:
  37. config.width = values[i];
  38. break;
  39. case HWC_DISPLAY_HEIGHT:
  40. config.height = values[i];
  41. break;
  42. case HWC_DISPLAY_DPI_X:
  43. config.xdpi = values[i] / 1000.0f;
  44. break;
  45. case HWC_DISPLAY_DPI_Y:
  46. config.ydpi = values[i] / 1000.0f;
  47. break;
  48. case HWC_DISPLAY_COLOR_TRANSFORM:
  49. config.colorTransform = values[i];
  50. break;
  51. default:
  52. ALOG_ASSERT(false, "unknown display attribute[%zu] %#x",
  53. i, DISPLAY_ATTRIBUTES[i]);
  54. break;
  55. }
  56. }
  57. if (config.xdpi == 0.0f || config.ydpi == 0.0f) {
  58. float dpi = getDefaultDensity(config.width, config.height);
  59. config.xdpi = dpi;
  60. config.ydpi = dpi;
  61. }
  62. mDisplayData[disp].configs.push_back(config);
  63. }
  64. // FIXME: what should we set the format to?
  65. mDisplayData[disp].format = HAL_PIXEL_FORMAT_RGBA_8888;//格式
  66. mDisplayData[disp].connected = true;//已连接
  67. return NO_ERROR;
  68. }

我们再来看SurfaceFlinger中init函数,后面创建DisplayDevice过程。

  1. for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
  2. DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
  3. // set-up the displays that are already connected
  4. if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {//当前设备连接了,或者是默认设备(即使没有连接)
  5. // All non-virtual displays are currently considered secure.
  6. bool isSecure = true;
  7. createBuiltinDisplayLocked(type);//分配一个token
  8. wp<IBinder> token = mBuiltinDisplays[i];
  9. sp<IGraphicBufferProducer> producer;
  10. sp<IGraphicBufferConsumer> consumer;
  11. BufferQueue::createBufferQueue(&producer, &consumer,//创建producer consumer
  12. new GraphicBufferAlloc());
  13. sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i,
  14. consumer);
  15. int32_t hwcId = allocateHwcDisplayId(type);
  16. sp<DisplayDevice> hw = new DisplayDevice(this,//创建DisplayDevice
  17. type, hwcId, mHwc->getFormat(hwcId), isSecure, token,
  18. fbs, producer,
  19. mRenderEngine->getEGLConfig());
  20. if (i > DisplayDevice::DISPLAY_PRIMARY) {
  21. // FIXME: currently we don't get blank/unblank requests
  22. // for displays other than the main display, so we always
  23. // assume a connected display is unblanked.
  24. ALOGD("marking display %zu as acquired/unblanked", i);
  25. hw->setPowerMode(HWC_POWER_MODE_NORMAL);
  26. }
  27. mDisplays.add(token, hw);//放入mDisplays中
  28. }
  29. }

setUpHWComposer函数的作用是更新HWComposer对象中图层对象列表以及图层属性。下面函数先会遍历各个设备DisplayDevice,然后根据可见layer数量,调用createWorkList创建hwc_layer_list_t列表,然后在每个设备上遍历可见layer,将layer的mActiveBuffer设置到HWComposer中去,最后调用了HWComposer的prepare函数。

  1. void SurfaceFlinger::setUpHWComposer() {
  2. ......
  3. HWComposer& hwc(getHwComposer());
  4. if (hwc.initCheck() == NO_ERROR) {
  5. // build the h/w work list
  6. if (CC_UNLIKELY(mHwWorkListDirty)) {
  7. mHwWorkListDirty = false;
  8. for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {//遍历mDisplays
  9. sp<const DisplayDevice> hw(mDisplays[dpy]);
  10. const int32_t id = hw->getHwcDisplayId();
  11. if (id >= 0) {
  12. const Vector< sp<Layer> >& currentLayers(//遍历DisplayDevice所有可见layer
  13. hw->getVisibleLayersSortedByZ());
  14. const size_t count = currentLayers.size();
  15. if (hwc.createWorkList(id, count) == NO_ERROR) {//根据layer数量调用createWorkList创建hwc_layer_list_t列表
  16. HWComposer::LayerListIterator cur = hwc.begin(id);
  17. const HWComposer::LayerListIterator end = hwc.end(id);
  18. for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
  19. const sp<Layer>& layer(currentLayers[i]);
  20. layer->setGeometry(hw, *cur);
  21. if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix) {
  22. cur->setSkip(true);
  23. }
  24. }
  25. }
  26. }
  27. }
  28. }
  29. // set the per-frame data
  30. for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
  31. sp<const DisplayDevice> hw(mDisplays[dpy]);
  32. const int32_t id = hw->getHwcDisplayId();
  33. if (id >= 0) {
  34. const Vector< sp<Layer> >& currentLayers(
  35. hw->getVisibleLayersSortedByZ());
  36. const size_t count = currentLayers.size();
  37. HWComposer::LayerListIterator cur = hwc.begin(id);
  38. const HWComposer::LayerListIterator end = hwc.end(id);
  39. for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
  40. //将layer的mActiveBuffer设置到HWComposer中去
  41. const sp<Layer>& layer(currentLayers[i]);
  42. layer->setPerFrameData(hw, *cur);
  43. }
  44. }
  45. }
  46. // If possible, attempt to use the cursor overlay on each display.
  47. for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
  48. sp<const DisplayDevice> hw(mDisplays[dpy]);
  49. const int32_t id = hw->getHwcDisplayId();
  50. if (id >= 0) {
  51. const Vector< sp<Layer> >& currentLayers(
  52. hw->getVisibleLayersSortedByZ());
  53. const size_t count = currentLayers.size();
  54. HWComposer::LayerListIterator cur = hwc.begin(id);
  55. const HWComposer::LayerListIterator end = hwc.end(id);
  56. for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
  57. const sp<Layer>& layer(currentLayers[i]);
  58. if (layer->isPotentialCursor()) {
  59. cur->setIsCursorLayerHint();
  60. break;
  61. }
  62. }
  63. }
  64. }
  65. status_t err = hwc.prepare();
  66. ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
  67. for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
  68. sp<const DisplayDevice> hw(mDisplays[dpy]);
  69. hw->prepareFrame(hwc);
  70. }
  71. }
  72. }
我们先来看下createWorkList函数,我们先为DisplayData的list申请内存,这个内存要先hwc_display_contents_1_t结构体本身的长度加上后面hwc_layer_1_t个数的长度。后面用DisplayData中list中hwLayers最后一个作为DisplayData中的framebufferTarget。 注意到这个细节没有,当支持egl合成的时候,会把numLayers加1,这是因为如果支持egl合成list最后一个layer是egl合成后的buffer用的,所以要增加一个layer,而前面都是普通的layer。

  1. status_t HWComposer::createWorkList(int32_t id, size_t numLayers) {
  2. if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id)) {
  3. return BAD_INDEX;
  4. }
  5. if (mHwc) {
  6. DisplayData& disp(mDisplayData[id]);
  7. if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
  8. // we need space for the HWC_FRAMEBUFFER_TARGET
  9. numLayers++;//注意到这个细节没有,当支持egl合成的时候,会把numLayers加1
  10. }
  11. if (disp.capacity < numLayers || disp.list == NULL) {//当DisplayData中的list为空,我们就要malloc
  12. size_t size = sizeof(hwc_display_contents_1_t)
  13. + numLayers * sizeof(hwc_layer_1_t);//整个申请内存长度,hwc_display_contents_1_t结构体本身的长度加上后面hwc_layer_1_t个数的长度
  14. free(disp.list);
  15. disp.list = (hwc_display_contents_1_t*)malloc(size);//malloc
  16. disp.capacity = numLayers;
  17. }
  18. if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
  19. disp.framebufferTarget = &disp.list->hwLayers[numLayers - 1];
  20. memset(disp.framebufferTarget, 0, sizeof(hwc_layer_1_t));//DisplayData的framebufferTarget清0
  21. const DisplayConfig& currentConfig =
  22. disp.configs[disp.currentConfig];
  23. const hwc_rect_t r = { 0, 0,
  24. (int) currentConfig.width, (int) currentConfig.height };
  25. disp.framebufferTarget->compositionType = HWC_FRAMEBUFFER_TARGET;
  26. disp.framebufferTarget->hints = 0;
  27. disp.framebufferTarget->flags = 0;
  28. disp.framebufferTarget->handle = disp.fbTargetHandle;
  29. disp.framebufferTarget->transform = 0;
  30. disp.framebufferTarget->blending = HWC_BLENDING_PREMULT;
  31. if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) {
  32. disp.framebufferTarget->sourceCropf.left = 0;
  33. disp.framebufferTarget->sourceCropf.top = 0;
  34. disp.framebufferTarget->sourceCropf.right =
  35. currentConfig.width;
  36. disp.framebufferTarget->sourceCropf.bottom =
  37. currentConfig.height;
  38. } else {
  39. disp.framebufferTarget->sourceCrop = r;
  40. }
  41. disp.framebufferTarget->displayFrame = r;
  42. disp.framebufferTarget->visibleRegionScreen.numRects = 1;
  43. disp.framebufferTarget->visibleRegionScreen.rects =
  44. &disp.framebufferTarget->displayFrame;
  45. disp.framebufferTarget->acquireFenceFd = -1;
  46. disp.framebufferTarget->releaseFenceFd = -1;
  47. disp.framebufferTarget->planeAlpha = 0xFF;
  48. }
  49. disp.list->retireFenceFd = -1;
  50. disp.list->flags = HWC_GEOMETRY_CHANGED;
  51. disp.list->numHwLayers = numLayers;//DisplayData中list中layer的个数
  52. }
  53. return NO_ERROR;
  54. }

下面我们来看下DisplayData的数据结构

  1. struct DisplayData {
  2. DisplayData();
  3. ~DisplayData();
  4. Vector<DisplayConfig> configs;
  5. size_t currentConfig;
  6. uint32_t format; // pixel format from FB hal, for pre-hwc-1.1
  7. bool connected;
  8. bool hasFbComp;
  9. bool hasOvComp;
  10. size_t capacity;
  11. hwc_display_contents_1* list;
  12. hwc_layer_1* framebufferTarget;
  13. buffer_handle_t fbTargetHandle;
  14. sp<Fence> lastRetireFence; // signals when the last set op retires
  15. sp<Fence> lastDisplayFence; // signals when the last set op takes
  16. // effect on screen
  17. buffer_handle_t outbufHandle;
  18. sp<Fence> outbufAcquireFence;
  19. // protected by mEventControlLock
  20. int32_t events;
  21. };

再来看下hwc_display_contents_1。保留了原始的注释,我们先看hwc_display_contents_1,我们先看联合体union,第一个hwc_display_t dpy hwc_surface_t sur这个是EGL使用的,而如果是普通的就使用另外一个联合体outbuf什么的,后面还保存了layer的个数和hwc_layer_1_t 数组的起始地址hwLayers[0]

  1. typedef struct hwc_display_contents_1 {
  2. /* File descriptor referring to a Sync HAL fence object which will signal
  3. * when this composition is retired. For a physical display, a composition
  4. * is retired when it has been replaced on-screen by a subsequent set. For
  5. * a virtual display, the composition is retired when the writes to
  6. * outputBuffer are complete and can be read. The fence object is created
  7. * and returned by the set call; this field will be -1 on entry to prepare
  8. * and set. SurfaceFlinger will close the returned file descriptor.
  9. */
  10. int retireFenceFd;
  11. union {
  12. /* Fields only relevant for HWC_DEVICE_VERSION_1_0. */
  13. struct {
  14. /* (dpy, sur) is the target of SurfaceFlinger's OpenGL ES
  15. * composition for HWC_DEVICE_VERSION_1_0. They aren't relevant to
  16. * prepare. The set call should commit this surface atomically to
  17. * the display along with any overlay layers.
  18. */
  19. hwc_display_t dpy;
  20. hwc_surface_t sur;
  21. };
  22. /* These fields are used for virtual displays when the h/w composer
  23. * version is at least HWC_DEVICE_VERSION_1_3. */
  24. struct {
  25. /* outbuf is the buffer that receives the composed image for
  26. * virtual displays. Writes to the outbuf must wait until
  27. * outbufAcquireFenceFd signals. A fence that will signal when
  28. * writes to outbuf are complete should be returned in
  29. * retireFenceFd.
  30. *
  31. * This field is set before prepare(), so properties of the buffer
  32. * can be used to decide which layers can be handled by h/w
  33. * composer.
  34. *
  35. * If prepare() sets all layers to FRAMEBUFFER, then GLES
  36. * composition will happen directly to the output buffer. In this
  37. * case, both outbuf and the FRAMEBUFFER_TARGET layer's buffer will
  38. * be the same, and set() has no work to do besides managing fences.
  39. *
  40. * If the TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS board config
  41. * variable is defined (not the default), then this behavior is
  42. * changed: if all layers are marked for FRAMEBUFFER, GLES
  43. * composition will take place to a scratch framebuffer, and
  44. * h/w composer must copy it to the output buffer. This allows the
  45. * h/w composer to do format conversion if there are cases where
  46. * that is more desirable than doing it in the GLES driver or at the
  47. * virtual display consumer.
  48. *
  49. * If some or all layers are marked OVERLAY, then the framebuffer
  50. * and output buffer will be different. As with physical displays,
  51. * the framebuffer handle will not change between frames if all
  52. * layers are marked for OVERLAY.
  53. */
  54. buffer_handle_t outbuf;
  55. /* File descriptor for a fence that will signal when outbuf is
  56. * ready to be written. The h/w composer is responsible for closing
  57. * this when no longer needed.
  58. *
  59. * Will be -1 whenever outbuf is NULL, or when the outbuf can be
  60. * written immediately.
  61. */
  62. int outbufAcquireFenceFd;
  63. };
  64. };
  65. /* List of layers that will be composed on the display. The buffer handles
  66. * in the list will be unique. If numHwLayers is 0, all composition will be
  67. * performed by SurfaceFlinger.
  68. */
  69. uint32_t flags;
  70. size_t numHwLayers;//layer个数
  71. hwc_layer_1_t hwLayers[0];//layer起始地址
  72. } hwc_display_contents_1_t;

再来看下每个layer的数据结构体hwc_layer_1 ,其主要数据在buffer_handle_t handle中,buffer_handle_t 其实就是native_handle_t之前分析过,里面有共享内存的fd和地址。

  1. typedef struct hwc_layer_1 {
  2. /*
  3. * compositionType is used to specify this layer's type and is set by either
  4. * the hardware composer implementation, or by the caller (see below).
  5. *
  6. * This field is always reset to HWC_BACKGROUND or HWC_FRAMEBUFFER
  7. * before (*prepare)() is called when the HWC_GEOMETRY_CHANGED flag is
  8. * also set, otherwise, this field is preserved between (*prepare)()
  9. * calls.
  10. *
  11. * HWC_BACKGROUND
  12. * Always set by the caller before calling (*prepare)(), this value
  13. * indicates this is a special "background" layer. The only valid field
  14. * is backgroundColor.
  15. * The HWC can toggle this value to HWC_FRAMEBUFFER to indicate it CANNOT
  16. * handle the background color.
  17. *
  18. *
  19. * HWC_FRAMEBUFFER_TARGET
  20. * Always set by the caller before calling (*prepare)(), this value
  21. * indicates this layer is the framebuffer surface used as the target of
  22. * OpenGL ES composition. If the HWC sets all other layers to HWC_OVERLAY
  23. * or HWC_BACKGROUND, then no OpenGL ES composition will be done, and
  24. * this layer should be ignored during set().
  25. *
  26. * This flag (and the framebuffer surface layer) will only be used if the
  27. * HWC version is HWC_DEVICE_API_VERSION_1_1 or higher. In older versions,
  28. * the OpenGL ES target surface is communicated by the (dpy, sur) fields
  29. * in hwc_compositor_device_1_t.
  30. *
  31. * This value cannot be set by the HWC implementation.
  32. *
  33. *
  34. * HWC_FRAMEBUFFER
  35. * Set by the caller before calling (*prepare)() ONLY when the
  36. * HWC_GEOMETRY_CHANGED flag is also set.
  37. *
  38. * Set by the HWC implementation during (*prepare)(), this indicates
  39. * that the layer will be drawn into the framebuffer using OpenGL ES.
  40. * The HWC can toggle this value to HWC_OVERLAY to indicate it will
  41. * handle the layer.
  42. *
  43. *
  44. * HWC_OVERLAY
  45. * Set by the HWC implementation during (*prepare)(), this indicates
  46. * that the layer will be handled by the HWC (ie: it must not be
  47. * composited with OpenGL ES).
  48. *
  49. *
  50. * HWC_SIDEBAND
  51. * Set by the caller before calling (*prepare)(), this value indicates
  52. * the contents of this layer come from a sideband video stream.
  53. *
  54. * The h/w composer is responsible for receiving new image buffers from
  55. * the stream at the appropriate time (e.g. synchronized to a separate
  56. * audio stream), compositing them with the current contents of other
  57. * layers, and displaying the resulting image. This happens
  58. * independently of the normal prepare/set cycle. The prepare/set calls
  59. * only happen when other layers change, or when properties of the
  60. * sideband layer such as position or size change.
  61. *
  62. * If the h/w composer can't handle the layer as a sideband stream for
  63. * some reason (e.g. unsupported scaling/blending/rotation, or too many
  64. * sideband layers) it can set compositionType to HWC_FRAMEBUFFER in
  65. * (*prepare)(). However, doing so will result in the layer being shown
  66. * as a solid color since the platform is not currently able to composite
  67. * sideband layers with the GPU. This may be improved in future
  68. * versions of the platform.
  69. *
  70. *
  71. * HWC_CURSOR_OVERLAY
  72. * Set by the HWC implementation during (*prepare)(), this value
  73. * indicates the layer's composition will now be handled by the HWC.
  74. * Additionally, the client can now asynchronously update the on-screen
  75. * position of this layer using the setCursorPositionAsync() api.
  76. */
  77. int32_t compositionType;
  78. /*
  79. * hints is bit mask set by the HWC implementation during (*prepare)().
  80. * It is preserved between (*prepare)() calls, unless the
  81. * HWC_GEOMETRY_CHANGED flag is set, in which case it is reset to 0.
  82. *
  83. * see hwc_layer_t::hints
  84. */
  85. uint32_t hints;
  86. /* see hwc_layer_t::flags */
  87. uint32_t flags;
  88. union {
  89. /* color of the background. hwc_color_t.a is ignored */
  90. hwc_color_t backgroundColor;
  91. struct {
  92. union {
  93. /* When compositionType is HWC_FRAMEBUFFER, HWC_OVERLAY,
  94. * HWC_FRAMEBUFFER_TARGET, this is the handle of the buffer to
  95. * compose. This handle is guaranteed to have been allocated
  96. * from gralloc using the GRALLOC_USAGE_HW_COMPOSER usage flag.
  97. * If the layer's handle is unchanged across two consecutive
  98. * prepare calls and the HWC_GEOMETRY_CHANGED flag is not set
  99. * for the second call then the HWComposer implementation may
  100. * assume that the contents of the buffer have not changed. */
  101. buffer_handle_t handle;
  102. /* When compositionType is HWC_SIDEBAND, this is the handle
  103. * of the sideband video stream to compose. */
  104. const native_handle_t* sidebandStream;
  105. };
  106. /* transformation to apply to the buffer during composition */
  107. uint32_t transform;
  108. /* blending to apply during composition */
  109. int32_t blending;
  110. /* area of the source to consider, the origin is the top-left corner of
  111. * the buffer. As of HWC_DEVICE_API_VERSION_1_3, sourceRect uses floats.
  112. * If the h/w can't support a non-integer source crop rectangle, it should
  113. * punt to OpenGL ES composition.
  114. */
  115. union {
  116. // crop rectangle in integer (pre HWC_DEVICE_API_VERSION_1_3)
  117. hwc_rect_t sourceCropi;
  118. hwc_rect_t sourceCrop; // just for source compatibility
  119. // crop rectangle in floats (as of HWC_DEVICE_API_VERSION_1_3)
  120. hwc_frect_t sourceCropf;
  121. };
  122. /* where to composite the sourceCrop onto the display. The sourceCrop
  123. * is scaled using linear filtering to the displayFrame. The origin is the
  124. * top-left corner of the screen.
  125. */
  126. hwc_rect_t displayFrame;
  127. /* visible region in screen space. The origin is the
  128. * top-left corner of the screen.
  129. * The visible region INCLUDES areas overlapped by a translucent layer.
  130. */
  131. hwc_region_t visibleRegionScreen;
  132. /* Sync fence object that will be signaled when the buffer's
  133. * contents are available. May be -1 if the contents are already
  134. * available. This field is only valid during set(), and should be
  135. * ignored during prepare(). The set() call must not wait for the
  136. * fence to be signaled before returning, but the HWC must wait for
  137. * all buffers to be signaled before reading from them.
  138. *
  139. * HWC_FRAMEBUFFER layers will never have an acquire fence, since
  140. * reads from them are complete before the framebuffer is ready for
  141. * display.
  142. *
  143. * HWC_SIDEBAND layers will never have an acquire fence, since
  144. * synchronization is handled through implementation-defined
  145. * sideband mechanisms.
  146. *
  147. * The HWC takes ownership of the acquireFenceFd and is responsible
  148. * for closing it when no longer needed.
  149. */
  150. int acquireFenceFd;
  151. /* During set() the HWC must set this field to a file descriptor for
  152. * a sync fence object that will signal after the HWC has finished
  153. * reading from the buffer. The field is ignored by prepare(). Each
  154. * layer should have a unique file descriptor, even if more than one
  155. * refer to the same underlying fence object; this allows each to be
  156. * closed independently.
  157. *
  158. * If buffer reads can complete at significantly different times,
  159. * then using independent fences is preferred. For example, if the
  160. * HWC handles some layers with a blit engine and others with
  161. * overlays, then the blit layers can be reused immediately after
  162. * the blit completes, but the overlay layers can't be reused until
  163. * a subsequent frame has been displayed.
  164. *
  165. * Since HWC doesn't read from HWC_FRAMEBUFFER layers, it shouldn't
  166. * produce a release fence for them. The releaseFenceFd will be -1
  167. * for these layers when set() is called.
  168. *
  169. * Since HWC_SIDEBAND buffers don't pass through the HWC client,
  170. * the HWC shouldn't produce a release fence for them. The
  171. * releaseFenceFd will be -1 for these layers when set() is called.
  172. *
  173. * The HWC client taks ownership of the releaseFenceFd and is
  174. * responsible for closing it when no longer needed.
  175. */
  176. int releaseFenceFd;
  177. /*
  178. * Availability: HWC_DEVICE_API_VERSION_1_2
  179. *
  180. * Alpha value applied to the whole layer. The effective
  181. * value of each pixel is computed as:
  182. *
  183. * if (blending == HWC_BLENDING_PREMULT)
  184. * pixel.rgb = pixel.rgb * planeAlpha / 255
  185. * pixel.a = pixel.a * planeAlpha / 255
  186. *
  187. * Then blending proceeds as usual according to the "blending"
  188. * field above.
  189. *
  190. * NOTE: planeAlpha applies to YUV layers as well:
  191. *
  192. * pixel.rgb = yuv_to_rgb(pixel.yuv)
  193. * if (blending == HWC_BLENDING_PREMULT)
  194. * pixel.rgb = pixel.rgb * planeAlpha / 255
  195. * pixel.a = planeAlpha
  196. *
  197. *
  198. * IMPLEMENTATION NOTE:
  199. *
  200. * If the source image doesn't have an alpha channel, then
  201. * the h/w can use the HWC_BLENDING_COVERAGE equations instead of
  202. * HWC_BLENDING_PREMULT and simply set the alpha channel to
  203. * planeAlpha.
  204. *
  205. * e.g.:
  206. *
  207. * if (blending == HWC_BLENDING_PREMULT)
  208. * blending = HWC_BLENDING_COVERAGE;
  209. * pixel.a = planeAlpha;
  210. *
  211. */
  212. uint8_t planeAlpha;
  213. /* Pad to 32 bits */
  214. uint8_t _pad[3];
  215. /*
  216. * Availability: HWC_DEVICE_API_VERSION_1_5
  217. *
  218. * This defines the region of the source buffer that has been
  219. * modified since the last frame.
  220. *
  221. * If surfaceDamage.numRects > 0, then it may be assumed that any
  222. * portion of the source buffer not covered by one of the rects has
  223. * not been modified this frame. If surfaceDamage.numRects == 0,
  224. * then the whole source buffer must be treated as if it had been
  225. * modified.
  226. *
  227. * If the layer's contents are not modified relative to the prior
  228. * prepare/set cycle, surfaceDamage will contain exactly one empty
  229. * rect ([0, 0, 0, 0]).
  230. *
  231. * The damage rects are relative to the pre-transformed buffer, and
  232. * their origin is the top-left corner.
  233. */
  234. hwc_region_t surfaceDamage;
  235. };
  236. };
  237. #ifdef __LP64__
  238. /*
  239. * For 64-bit mode, this struct is 120 bytes (and 8-byte aligned), and needs
  240. * to be padded as such to maintain binary compatibility.
  241. */
  242. uint8_t reserved[120 - 112];
  243. #else
  244. /*
  245. * For 32-bit mode, this struct is 96 bytes, and needs to be padded as such
  246. * to maintain binary compatibility.
  247. */
  248. uint8_t reserved[96 - 84];
  249. #endif
  250. } hwc_layer_1_t;

回到setUpHWComposer函数,下面是变量所有的设备上的layer调用其setPerFrameData函数。

在分析setPerFrameData之前我们先分析下setUpHWComposer中的遍历Layer时候用到的cur和end。我把这段代码单独拿出来。

  1. HWComposer::LayerListIterator cur = hwc.begin(id);
  2. const HWComposer::LayerListIterator end = hwc.end(id);
  3. for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
  4. /*
  5. * update the per-frame h/w composer data for each layer
  6. * and build the transparent region of the FB
  7. */
  8. const sp<Layer>& layer(currentLayers[i]);
  9. layer->setPerFrameData(hw, *cur);
  10. }
看下HWComposer中的begin函数

  1. HWComposer::LayerListIterator HWComposer::begin(int32_t id) {
  2. return getLayerIterator(id, 0);
  3. }

再来看下getLayerIterator函数,正常应该是最后一个分支。注意这个时候index是0

  1. HWComposer::LayerListIterator HWComposer::getLayerIterator(int32_t id, size_t index) {
  2. if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id)) {
  3. return LayerListIterator();
  4. }
  5. const DisplayData& disp(mDisplayData[id]);
  6. if (!mHwc || !disp.list || index > disp.list->numHwLayers) {
  7. return LayerListIterator();
  8. }
  9. return LayerListIterator(new HWCLayerVersion1(mHwc, disp.list->hwLayers), index);
  10. }
新建了一个LayerListIterator,这里面HWCLayerVersion1就是mLayerList, index就是mIndex. 我们看下*符号的重载,因为我们后面用到了,就是mLayerList。

  1. class LayerListIterator {
  2. friend class HWComposer;
  3. HWCLayer* const mLayerList;
  4. size_t mIndex;
  5. LayerListIterator() : mLayerList(NULL), mIndex(0) { }
  6. LayerListIterator(HWCLayer* layer, size_t index)
  7. : mLayerList(layer), mIndex(index) { }
  8. // we don't allow assignment, because we don't need it for now
  9. LayerListIterator& operator = (const LayerListIterator& rhs);
  10. public:
  11. // copy operators
  12. LayerListIterator(const LayerListIterator& rhs)
  13. : mLayerList(HWCLayer::copy(rhs.mLayerList)), mIndex(rhs.mIndex) {
  14. }
  15. ~LayerListIterator() { delete mLayerList; }
  16. // pre-increment
  17. LayerListIterator& operator++() {
  18. mLayerList->setLayer(++mIndex);
  19. return *this;
  20. }
  21. // dereference
  22. HWCLayerInterface& operator * () { return *mLayerList; }
  23. HWCLayerInterface* operator -> () { return mLayerList; }
  24. // comparison
  25. bool operator == (const LayerListIterator& rhs) const {
  26. return mIndex == rhs.mIndex;
  27. }
  28. bool operator != (const LayerListIterator& rhs) const {
  29. return !operator==(rhs);
  30. }
  31. };
而上面的mLayerList就是HWCLayerVersion1对象。

而我们再来看看下HWComposer中的end函数,end函数和begin很像只是在调用getLayerIterator的时候,begin传入0,end传入layer的最后一位。最后就是mIndex成员变量不一样

  1. HWComposer::LayerListIterator HWComposer::end(int32_t id) {
  2. size_t numLayers = 0;
  3. if (uint32_t(id) <= 31 && mAllocatedDisplayIDs.hasBit(id)) {
  4. const DisplayData& disp(mDisplayData[id]);
  5. if (mHwc && disp.list) {
  6. numLayers = disp.list->numHwLayers;//获取到list中laye的个数
  7. if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
  8. // with HWC 1.1, the last layer is always the HWC_FRAMEBUFFER_TARGET,
  9. // which we ignore when iterating through the layer list.
  10. ALOGE_IF(!numLayers, "mDisplayData[%d].list->numHwLayers is 0", id);
  11. if (numLayers) {
  12. numLayers--;//变成最后一位
  13. }
  14. }
  15. }
  16. }
  17. return getLayerIterator(id, numLayers);//和上面一样,只是传入的index不一样。
  18. }

我们再来看LayerListIterator操作符++的重载,会调用mLayerList->setLayer函数

  1. LayerListIterator& operator++() {
  2. mLayerList->setLayer(++mIndex);
  3. return *this;
  4. }
setLayer会从mLayerList中设置当前的mCurrentLayer,通过mLayerList, 这个变量就是disp.list->hwLayers

  1. virtual status_t setLayer(size_t index) {
  2. mCurrentLayer = &mLayerList[index];
  3. return NO_ERROR;
  4. }
这样准备工作就好了,我们再来分析Layer的setPerFrameData函数,主要就是调用了HWCLayerVersion1的setBuffer函数

  1. void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
  2. HWComposer::HWCLayerInterface& layer) {
  3. // we have to set the visible region on every frame because
  4. // we currently free it during onLayerDisplayed(), which is called
  5. // after HWComposer::commit() -- every frame.
  6. // Apply this display's projection's viewport to the visible region
  7. // before giving it to the HWC HAL.
  8. const Transform& tr = hw->getTransform();
  9. Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
  10. layer.setVisibleRegionScreen(visible);
  11. layer.setSurfaceDamage(surfaceDamageRegion);
  12. if (mSidebandStream.get()) {
  13. layer.setSidebandStream(mSidebandStream);
  14. } else {
  15. // NOTE: buffer can be NULL if the client never drew into this
  16. // layer yet, or if we ran out of memory
  17. layer.setBuffer(mActiveBuffer);
  18. }
  19. }
再来看HWCLayerVersion1的setBuffer函数,调用getLayer函数设置其handle,而getLayer就是mCurrentLayer。之前mCurrentLayer会一个个遍历各个Layer,这样就把所有的layer都设置其handle,就是hwc_layer_1_t中的handle。
  1. virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
  2. if (buffer == 0 || buffer->handle == 0) {
  3. getLayer()->compositionType = HWC_FRAMEBUFFER;
  4. getLayer()->flags |= HWC_SKIP_LAYER;
  5. getLayer()->handle = 0;
  6. } else {
  7. if (getLayer()->compositionType == HWC_SIDEBAND) {
  8. // If this was a sideband layer but the stream was removed, reset
  9. // it to FRAMEBUFFER. The HWC can change it to OVERLAY in prepare.
  10. getLayer()->compositionType = HWC_FRAMEBUFFER;
  11. }
  12. getLayer()->handle = buffer->handle;
  13. }
  14. }
最后会调用HWComposer的prepare函数,我们再来看下这个函数。这里我们先将DisplayData的framebufferTarget的composition设置为HWC_FRAMEBUFFER_TARGET,然后将每个DisplayData的list放入mList中。最后调用了mHwc的prepare函数。
  1. status_t HWComposer::prepare() {
  2. Mutex::Autolock _l(mDisplayLock);
  3. for (size_t i=0 ; i<mNumDisplays ; i++) {
  4. DisplayData& disp(mDisplayData[i]);
  5. if (disp.framebufferTarget) {//这里其实就是disp.list中最后一个layer
  6. // make sure to reset the type to HWC_FRAMEBUFFER_TARGET
  7. // DO NOT reset the handle field to NULL, because it's possible
  8. // that we have nothing to redraw (eg: eglSwapBuffers() not called)
  9. // in which case, we should continue to use the same buffer.
  10. LOG_FATAL_IF(disp.list == NULL);
  11. disp.framebufferTarget->compositionType = HWC_FRAMEBUFFER_TARGET;
  12. }
  13. if (!disp.connected && disp.list != NULL) {
  14. ALOGW("WARNING: disp %zu: connected, non-null list, layers=%zu",
  15. i, disp.list->numHwLayers);
  16. }
  17. mLists[i] = disp.list;//DisplayData的list就是mList的一个组员
  18. if (mLists[i]) {
  19. if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) {
  20. mLists[i]->outbuf = disp.outbufHandle;
  21. mLists[i]->outbufAcquireFenceFd = -1;
  22. } else if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
  23. // garbage data to catch improper use
  24. mLists[i]->dpy = (hwc_display_t)0xDEADBEEF;
  25. mLists[i]->sur = (hwc_surface_t)0xDEADBEEF;
  26. } else {
  27. mLists[i]->dpy = EGL_NO_DISPLAY;
  28. mLists[i]->sur = EGL_NO_SURFACE;
  29. }
  30. }
  31. }
  32. int err = mHwc->prepare(mHwc, mNumDisplays, mLists);//调用Hwc模块的prepare函数
  33. ALOGE_IF(err, "HWComposer: prepare failed (%s)", strerror(-err));
  34. if (err == NO_ERROR) {
  35. // here we're just making sure that "skip" layers are set
  36. // to HWC_FRAMEBUFFER and we're also counting how many layers
  37. // we have of each type.
  38. //
  39. // If there are no window layers, we treat the display has having FB
  40. // composition, because SurfaceFlinger will use GLES to draw the
  41. // wormhole region.
  42. for (size_t i=0 ; i<mNumDisplays ; i++) {
  43. DisplayData& disp(mDisplayData[i]);
  44. disp.hasFbComp = false;
  45. disp.hasOvComp = false;
  46. if (disp.list) {
  47. for (size_t i=0 ; i<disp.list->numHwLayers ; i++) {
  48. hwc_layer_1_t& l = disp.list->hwLayers[i];
  49. //ALOGD("prepare: %d, type=%d, handle=%p",
  50. // i, l.compositionType, l.handle);
  51. if (l.flags & HWC_SKIP_LAYER) {
  52. l.compositionType = HWC_FRAMEBUFFER;
  53. }
  54. if (l.compositionType == HWC_FRAMEBUFFER) {
  55. disp.hasFbComp = true;
  56. }
  57. if (l.compositionType == HWC_OVERLAY) {
  58. disp.hasOvComp = true;
  59. }
  60. if (l.compositionType == HWC_CURSOR_OVERLAY) {
  61. disp.hasOvComp = true;
  62. }
  63. }
  64. if (disp.list->numHwLayers == (disp.framebufferTarget ? 1 : 0)) {
  65. disp.hasFbComp = true;
  66. }
  67. } else {
  68. disp.hasFbComp = true;
  69. }
  70. }
  71. }
  72. return (status_t)err;
  73. }
mHwc的prepare主要将每个Layer的composition设置为HWC_FRAMEBUFFER。





声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/734542
推荐阅读
相关标签
  

闽ICP备14008679号