/*
*收到VSYNC后 REFRESH显示
*/
413void SurfaceFlinger::onMessageReceived(int32_t what)
{
419 // if we're in a global transaction, don't do anything.
420 const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
421 uint32_t transactionFlags = peekTransactionFlags(mask);
422 if (CC_UNLIKELY(transactionFlags)) {
423 handleTransaction(transactionFlags);
424 }
425
426 // post surfaces (if needed)
427 handlePageFlip();
428
435 handleRefresh();
436
437 const DisplayHardware& hw(graphicPlane(0).displayHardware());
438
443 if (CC_UNLIKELY(mHwWorkListDirty)) {
444 // build the h/w work list
445 handleWorkList();
446 }
447
448 if (CC_LIKELY(hw.canDraw())) {
449 // repaint the framebuffer (if needed)
450 handleRepaint();
451 // inform the h/w that we're done compositing
452 hw.compositionComplete();
453 postFramebuffer();
454 } else {
455 // pretend we did the post
456 hw.compositionComplete();
457 }
}
511void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
512{
513 const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
514 const size_t count = currentLayers.size();
515
516 /*
517 * Traversal of the children
518 * (perform the transaction for each of them if needed)
519 */
520
/*
* 针对每个Layer,提交其所做的状态变化
*/
521 const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
522 if (layersNeedTransaction) {
523 for (size_t i=0 ; i<count ; i++) {
524 const sp<LayerBase>& layer = currentLayers[i];
525 uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
526 if (!trFlags) continue;
527
528 const uint32_t flags = layer->doTransaction(0);
529 if (flags & Layer::eVisibleRegion)
530 mVisibleRegionsDirty = true;
531 }
532 }
533
534 /*
535 * Perform our own transaction if needed
536 */
537 /*
* 处理SurfaceFlinger全局状态变化
*/
538 if (transactionFlags & eTransactionNeeded) {
/*
* 如果屏幕发生旋转,则设置mDirtyRegion为整个屏幕范围,更新mServerCblk
* 客户端可以访问到,通知HWC屏幕位向改变重新设置其参数。
*/
539 if (mCurrentState.orientation != mDrawingState.orientation) {
540 // the orientation has changed, recompute all visible regions
541 // and invalidate everything.
542
543 const int dpy = 0;
544 const int orientation = mCurrentState.orientation;
545 // Currently unused: const uint32_t flags = mCurrentState.orientationFlags;
546 GraphicPlane& plane(graphicPlane(dpy));
547 plane.setOrientation(orientation);
548 const Transform& planeTransform(plane.transform());
549
550 // update the shared control block
551 const DisplayHardware& hw(plane.displayHardware());
552 volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
553 dcblk->orientation = orientation;
554 dcblk->w = plane.getWidth();
555 dcblk->h = plane.getHeight();
556
557 mVisibleRegionsDirty = true;
558 mDirtyRegion.set(hw.bounds());
559
560 //set the new orientation to HWC
561 HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
562 hwc.eventControl(DisplayHardware::EVENT_ORIENTATION,
563 planeTransform.getOrientation());
564
565 }
566
/*
* 如果有Layer增加,设置赃区域标志,此时mDirtyRegion还为空,
* 每次Repaint后mDirtyRegion就清空了。
* 此处的判断条件使用Layer个数比较,需要与下面mLayersRemoved结合看。
* 如果Layer有减少,即使增加的个数小于减少的个数,
* 那么mVisibleRegionsDirty一定会被设置。
* 如果没有减少,增加Layer后数目一定会增多。可读性不好。
*/
567 if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
568 // layers have been added
569 mVisibleRegionsDirty = true;
570 }
571
/*
* 有减少的Layer,那么其下Layer可能会暴露出来,需要Invalidate该Layer
* 暴露出来的区域,所以需要记录这块区域。
* 所有移除layer暴露出来的区域累积,记录在mDirtyRegionRemovedLayer中。
* Invalidate的效果是在lockPageFlip后,将mDirtyRegionRemovedLayer加到
* mDirtyRegion中。
* 用户绘图后Post的赃区域在unlockPageFlip时做。
*/
572 // some layers might have been removed, so
573 // we need to update the regions they're exposing.
574 if (mLayersRemoved) {
575 mLayersRemoved = false;
576 mVisibleRegionsDirty = true;
577 const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
578 const size_t count = previousLayers.size();
579 for (size_t i=0 ; i<count ; i++) {
580 const sp<LayerBase>& layer(previousLayers[i]);
581 if (currentLayers.indexOf( layer ) < 0) {
582 // this layer is not visible anymore
583 mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
584 }
585 }
586 }
587 }
588
/*
* 复制CurrentState到DrawingState中,即提交,下面代码处理Repaint时使用DrawingState
*/
589 commitTransaction();
590}
735void SurfaceFlinger::handlePageFlip()
736{
737 ATRACE_CALL();
738 const DisplayHardware& hw = graphicPlane(0).displayHardware();
739 const Region screenRegion(hw.bounds());
740
/*
* 更新每个Layer的脏区域,获取每Layer这次重绘所需要的GraphicBuffer,
* 为每Layer生成纹理供GPU render使用。
*/
741 const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
742 const bool visibleRegions = lockPageFlip(currentLayers);
743
744 if (visibleRegions || mVisibleRegionsDirty) {
745 Region opaqueRegion;
/*
* 计算更新mDirtyRegion,得到所有Opaqued Layers的总的Region。
*/
746 computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
747
748 /*
749 * rebuild the visible layer list; 重建mVisibleLayersSortedByZ
750 */
751 const size_t count = currentLayers.size();
752 mVisibleLayersSortedByZ.clear();
753 mVisibleLayersSortedByZ.setCapacity(count);
754 for (size_t i=0 ; i<count ; i++) {
755 if (!currentLayers[i]->visibleRegionScreen.isEmpty())
756 mVisibleLayersSortedByZ.add(currentLayers[i]);
757 }
758
/*
* opaqueRegion区域外的区域绘制“虫洞”,记录该区域
*/
759 mWormholeRegion = screenRegion.subtract(opaqueRegion);
/*
* 本轮处理中mVisibleRegionsDirty标志使用完毕,重置。
*/
760 mVisibleRegionsDirty = false;
761 invalidateHwcGeometry();
762 }
763
/*
* 主要是将每个Layer用户Post的区域并到赃区域上
*/
764 unlockPageFlip(currentLayers);
765
766 mDirtyRegion.orSelf(getAndClearInvalidateRegion());
767 mDirtyRegion.andSelf(screenRegion);
768}
775bool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
776{
777 bool recomputeVisibleRegions = false;
778 size_t count = currentLayers.size();
779 sp<LayerBase> const* layers = currentLayers.array();
780 for (size_t i=0 ; i<count ; i++) {
781 const sp<LayerBase>& layer(layers[i]);
782 layer->lockPageFlip(recomputeVisibleRegions);
783 }
784 return recomputeVisibleRegions;
785}
527void Layer::lockPageFlip(bool& recomputeVisibleRegions)
528{
529 ATRACE_CALL();
530
/*
* 本Layer有新Queued Buffer才需要更新纹理。
*/
531 if (mQueuedFrames > 0) {
532
533 // if we've already called updateTexImage() without going through
534 // a composition step, we have to skip this layer at this point
535 // because we cannot call updateTeximage() without a corresponding
536 // compositionComplete() call.
537 // we'll trigger an update in onPreComposition().
/*
* 如果上次的重绘还没有显示,本轮又要显示了,直接返回。
*/
538 if (mRefreshPending) {
539 mPostedDirtyRegion.clear();
540 return;
541 }
542
543 // Capture the old state of the layer for comparisons later
544 const bool oldOpacity = isOpaque();
545 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
546
/*
* 因为有mRefreshPending时导致直接return,所有需要“引发”下个Frame的显示;
* signalLayerUpdate()即是requestNextVsync(),因为setRefreshRate(0)时,
* 不接收VSYNC,所以需要显式要求下一个VSYNC发过来,“引发”下帧显示
*/
547 // signal another event if we have more frames pending
548 if (android_atomic_dec(&mQueuedFrames) > 1) {
549 mFlinger->signalLayerUpdate();
550 }
551
/*
* 内部类用于检验Queued过来的Buffer是否符合该Layer的显示要求,
* 不符合则reject,不予显示。
* 如Camera或Video图像buffer的大小,格式等要符合。
*/
552 struct Reject : public SurfaceTexture::BufferRejecter {
553 Layer::State& front;
554 Layer::State& current;
555 bool& recomputeVisibleRegions;
556 Reject(Layer::State& front, Layer::State& current,
557 bool& recomputeVisibleRegions)
558 : front(front), current(current),
559 recomputeVisibleRegions(recomputeVisibleRegions) {
560 }
561
562 virtual bool reject(const sp<GraphicBuffer>& buf,
563 const BufferQueue::BufferItem& item) {
564 if (buf == NULL) {
565 return false;
566 }
567
568 uint32_t bufWidth = buf->getWidth();
569 uint32_t bufHeight = buf->getHeight();
570
571 // check that we received a buffer of the right size
572 // (Take the buffer's orientation into account)
573 if (item.mTransform & Transform::ROT_90) {
574 swap(bufWidth, bufHeight);
575 }
576
577
578 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
579 if (front.active != front.requested) {
580
581 if (isFixedSize ||
582 (bufWidth == front.requested.w &&
583 bufHeight == front.requested.h))
584 {
585 // Here we pretend the transaction happened by updating the
586 // current and drawing states. Drawing state is only accessed
587 // in this thread, no need to have it locked
588 front.active = front.requested;
589
590 // We also need to update the current state so that
591 // we don't end-up overwriting the drawing state with
592 // this stale current state during the next transaction
593 //
594 // NOTE: We don't need to hold the transaction lock here
595 // because State::active is only accessed from this thread.
596 current.active = front.active;
597
598 // recompute visible region
599 recomputeVisibleRegions = true;
600 }
601
622
623 if (!isFixedSize) {
624 if (front.active.w != bufWidth ||
625 front.active.h != bufHeight) {
626 // reject this buffer
627 return true;
628 }
629 }
630 return false;
631 }
632 };
633
634
635 Reject r(mDrawingState, currentState(), recomputeVisibleRegions);
636
/*
* 使用该Layer的mActiveBuffer生成SurfaceTexture,用于OpenGL/3D GPU render。
* 图像格式不符合时,Reject::reject()被回调。
*/
637 if (mSurfaceTexture->updateTexImage(&r) < NO_ERROR) {
638 // something happened!
639 recomputeVisibleRegions = true;
640 return;
641 }
/*************
* updateTexImage会释放上轮该Layer使用的GraphicBuffer;
*也即本轮使用的GraphicBuffer持续到下次需要重绘时释放。
* 记得其申请是在lockPageFlip中记录在mActiveBuffer。
*/
642
/*
* 记录或更新当前使用的即mActiveBuffer字段
* 注意该buffer直到该Layer下轮重绘Repaint时才Release,
* 期间SurfaceTexture对该Buffer是不可用的。
*/
643 // update the active buffer
644 mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
645 if (mActiveBuffer == NULL) {
646 // this can only happen if the very first buffer was rejected.
647 return;
648 }
649
/*
* 设置mRefreshPending标志了,如果本轮还没有Paint而下次又来了,直接返回。
*/
650 mRefreshPending = true;
651 mFrameLatencyNeeded = true;
652 if (oldActiveBuffer == NULL) {
653 // the first time we receive a buffer, we need to trigger a
654 // geometry invalidation.
655 mFlinger->invalidateHwcGeometry();
656 }
657
/*
* 如果Crop & Transform & Scale改变,重设HWC参数
*/
658 Rect crop(mSurfaceTexture->getCurrentCrop());
659 const uint32_t transform(mSurfaceTexture->getCurrentTransform());
660 const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode());
661 if ((crop != mCurrentCrop) ||
662 (transform != mCurrentTransform) ||
663 (scalingMode != mCurrentScalingMode))
664 {
665 mCurrentCrop = crop;
666 mCurrentTransform = transform;
667 mCurrentScalingMode = scalingMode;
668 mFlinger->invalidateHwcGeometry();
669 }
670
/*
* 比较GraphicBuffer的维度是否有改变,用于更新HWC的维度参数,
* 从而使HWC知道该准备多大的buffer空间,和图像参数用于合成。
*/
671 if (oldActiveBuffer != NULL) {
672 uint32_t bufWidth = mActiveBuffer->getWidth();
673 uint32_t bufHeight = mActiveBuffer->getHeight();
674 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
675 bufHeight != uint32_t(oldActiveBuffer->height)) {
676 mFlinger->invalidateHwcGeometry();
677 }
678 }
679
680 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
681 if (oldOpacity != isOpaque()) {
682 recomputeVisibleRegions = true;
683 }
684
/*
* FIXME? 每个layer的dirty 是在后面调用的computeVisibleRegions()中计算出来的,
* 可以在彼时设置给Layer,记录脏区域是个很好的优化。
* 但是Region mPostedDirtyRegion是class Layer而不是class LayerBase的成员,
* 慢慢FIX! 此dirty非computeVisibleRegions中的dirty
*/
685 // FIXME: mPostedDirtyRegion = dirty & bounds
686 const Layer::State& front(drawingState());
687 mPostedDirtyRegion.set(front.active.w, front.active.h);
688
689 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
690 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
691 }
692}
Layer Clip精髓所在----
592void SurfaceFlinger::computeVisibleRegions(
593 const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
594{
595 ATRACE_CALL();
596
597 const GraphicPlane& plane(graphicPlane(0));
598 const Transform& planeTransform(plane.transform());
599 const DisplayHardware& hw(plane.displayHardware());
600 const Region screenRegion(hw.bounds());
601
602 Region aboveOpaqueLayers;
603 Region aboveCoveredLayers;
604 Region dirty;
605
606 bool secureFrameBuffer = false;
607
608 size_t i = currentLayers.size();
/*
* Clip不就是计算遮挡吗?z-order从顶向底,合乎逻辑。
*/
609 while (i--) {
610 const sp<LayerBase>& layer = currentLayers[i];
611 layer->validateVisibility(planeTransform);
612
613 // start with the whole surface at its current location
614 const Layer::State& s(layer->drawingState());
615
616 /*
617 * opaqueRegion: area of a surface that is fully opaque.
618 */
619 Region opaqueRegion;
620
621 /*
622 * visibleRegion: area of a surface that is visible on screen
623 * and not fully transparent. This is essentially the layer's
624 * footprint minus the opaque regions above it.
625 * Areas covered by a translucent surface are considered visible.
626 */
627 Region visibleRegion;
628
629 /*
630 * coveredRegion: area of a surface that is covered by all
631 * visible regions above it (which includes the translucent areas).
632 */
633 Region coveredRegion;
634
635
636 // handle hidden surfaces by setting the visible region to empty
637 if (CC_LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
// 该Layer是否半透
638 const bool translucent = !layer->isOpaque();
// 该Layer可见范围
639 const Rect bounds(layer->visibleBounds());
640 visibleRegion.set(bounds);
641 visibleRegion.andSelf(screenRegion);
642 if (!visibleRegion.isEmpty()) {
/*
* 如果本layer具有全透明区域(全透明子窗口),如Video或Camera,
* 本Layer该区域一定是不可见的,visibleRegion应该减去全透区域,
* translucent的判断条件并不表示该Layer为半透,而是有全透区域时,
* 该Layer的Opaque属性应该设置为false,表并非Full Opaque。
* setTransparentRegion/setTransparentRegionWindow
* => setTransparentRegionHint设置透明的。
* 那半透明子窗口如何呢?因为Layer的地位相当于该应用的Top most window,
* 所以半透子窗口下的区域也一定是本Layer的子窗口,而不可能是别的Layer,
* 从而该半透子窗口在本Layer范围内部就做Alpha混叠了,对于本Layer来说是
* Opaque的,所以不需要半透部分区域。半透属性是针对整个Layer的。
*/
643 // Remove the transparent area from the visible region
644 if (translucent) {
645 visibleRegion.subtractSelf(layer->transparentRegionScreen);
646 }
647
648 // compute the opaque region
649 const int32_t layerOrientation = layer->getOrientation();
/*
* 如果该Layer是Opaque的,那么其整个可见区域一定是遮挡下面的层的。
* 记录,累积到aboveOpaqueLayers, 供计算下面层的遮挡之用。
*/
650 if (s.alpha==255 && !translucent &&
651 ((layerOrientation & Transform::ROT_INVALID) == false)) {
652 // the opaque region is the layer's footprint
653 opaqueRegion = visibleRegion;
654 }
655 }
656 }
657
/*
* coveredRegion本层被覆盖的区域,包括被上面层半透覆盖的区域,覆盖并非遮挡。
*本层可见区域总对下面层构成覆盖,累积到aboveCoveredLayers
*/
658 // Clip the covered region to the visible region
659 coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
660
661 // Update aboveCoveredLayers for next (lower) layer
662 aboveCoveredLayers.orSelf(visibleRegion);
663
/*
* 减去本层被上面层遮挡的区域
*/
664 // subtract the opaque region covered by the layers above us
665 visibleRegion.subtractSelf(aboveOpaqueLayers);
666
/*
* 计算本层的脏区域,分内容是否为脏(size是否变化)两种情形。
* 如果是用内容脏,即size变化,那么认为整个区域都是脏的;
* 如果是移除上层的Layer暴露出本Layer区域,则计算可见的最小的脏区域;
* 此时赃区域是屏幕坐标系统?
* 这么有用的个dirty为什么不保存给各个Layer?
* 此时的dirty还不包括用户Posted的真正意义上的脏区域!
* 为什么不直接地处理为visbleRegion.andSelf(mDirtyRegionRemovedLayer)?
* 因为mDirtyRegionRemovedLayer仅是个区域,并没有记录层的透明属性。
*/
667 // compute this layer's dirty region
668 if (layer->contentDirty) {
669 // we need to invalidate the whole region
670 dirty = visibleRegion;
671 // as well, as the old visible region
672 dirty.orSelf(layer->visibleRegionScreen);
673 layer->contentDirty = false;
674 } else {
675 /* compute the exposed region:
676 * the exposed region consists of two components:
677 * 1) what's VISIBLE now and was COVERED before
678 * 2) what's EXPOSED now less what was EXPOSED before
679 *
680 * note that (1) is conservative, we start with the whole
681 * visible region but only keep what used to be covered by
682 * something -- which mean it may have been exposed.
683 *
684 * (2) handles areas that were not covered by anything but got
685 * exposed because of a resize.
686 */
687 const Region newExposed = visibleRegion - coveredRegion;
688 const Region oldVisibleRegion = layer->visibleRegionScreen;
689 const Region oldCoveredRegion = layer->coveredRegionScreen;
690 const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
691 dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
692 }
/*
* 被遮挡区域不需要重绘,从脏区域里除去
*/
693 dirty.subtractSelf(aboveOpaqueLayers);
694
/*
* 累积总的脏区域
*/
695 // accumulate to the screen dirty region
696 dirtyRegion.orSelf(dirty);
697
/*
* 累积遮挡区域
*/
698 // Update aboveOpaqueLayers for next (lower) layer
699 aboveOpaqueLayers.orSelf(opaqueRegion);
700
/*
* 为每个Layer记录其mVisibleRegion和mCoveredRegion
*/
701 // Store the visible region is screen space
702 layer->setVisibleRegion(visibleRegion);
703 layer->setCoveredRegion(coveredRegion);
704
705 // If a secure layer is partially visible, lock-down the screen!
706 if (layer->isSecure() && !visibleRegion.isEmpty()) {
707 secureFrameBuffer = true;
708 }
709 }
710
/*
* 把mDirtyRegionRemovedLayer并到mDirtyRegion中去。
* 有移除Layers暴露出来的区域需要其下的Layers重绘,其实这个在dirty计算时已处理
* 关键的是移除的Layer是最底层Layer的时候则直接露出屏底色,所以要此处要或上。
*/
711 // invalidate the areas where a layer was removed
712 dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
713 mDirtyRegionRemovedLayer.clear();
714
/*
* 抓屏相关?
*/
715 mSecureFrameBuffer = secureFrameBuffer;
/*
* 传出遮挡区域,Opaque Region为所有Opaque Layer Area之和
*/
716 opaqueRegion = aboveOpaqueLayers;
717}
787void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
788{
789 const GraphicPlane& plane(graphicPlane(0));
790 const Transform& planeTransform(plane.transform());
791 const size_t count = currentLayers.size();
792 sp<LayerBase> const* layers = currentLayers.array();
793 for (size_t i=0 ; i<count ; i++) {
794 const sp<LayerBase>& layer(layers[i]);
795 layer->unlockPageFlip(planeTransform, mDirtyRegion);
796 }
797}
694void Layer::unlockPageFlip(
695 const Transform& planeTransform, Region& outDirtyRegion)
696{
697 ATRACE_CALL();
698
699 Region postedRegion(mPostedDirtyRegion);
700 if (!postedRegion.isEmpty()) {
701 mPostedDirtyRegion.clear();
702 if (!visibleRegionScreen.isEmpty()) {
703 // The dirty region is given in the layer's coordinate space
704 // transform the dirty region by the surface's transformation
705 // and the global transformation.
706 const Layer::State& s(drawingState());
707 const Transform tr(planeTransform * s.transform);
708 postedRegion = tr.transform(postedRegion);
709
/*
* computeVisibleRegions处理的赃区域是size变化和上层遮挡移除的情况,需要重绘;
* 而用户修改提交的区域也需要重绘,还未加到赃区域中,此时并进来。
*/
710 // At this point, the dirty region is in screen space.
711 // Make sure it's constrained by the visible region (which
712 // is in screen space as well).
713 postedRegion.andSelf(visibleRegionScreen);
714 outDirtyRegion.orSelf(postedRegion);
715 }
716 }
717}
handleRefresh() 没什么作用了。
handleWorkList()是为HWComposer分配缓冲工作集,用于硬件合成,暂不考察。
DisplayHardware.canDraw()用于判断当前是否处于draw过程中,屏是否已经关闭等,得出需要Repaint的判断。
835void SurfaceFlinger::handleRepaint()
836{
837 ATRACE_CALL();
838
839 // compute the invalid region
840 mSwapRegion.orSelf(mDirtyRegion);
841
842 if (CC_UNLIKELY(mDebugRegion)) {
843 debugFlashRegions();
844 }
845
846 // set the frame buffer
847 const DisplayHardware& hw(graphicPlane(0).displayHardware());
848 glMatrixMode(GL_MODELVIEW);
849 glLoadIdentity();
850
/*
* 针对DisplayHardware是支持RECT更新还是RECTS更新,做相应处理。
*/
851 uint32_t flags = hw.getFlags();
852 if (flags & DisplayHardware::SWAP_RECTANGLE) {
853 // we can redraw only what's dirty, but since SWAP_RECTANGLE only
854 // takes a rectangle, we must make sure to update that whole
855 // rectangle in that case
856 mDirtyRegion.set(mSwapRegion.bounds());
857 } else {
858 if (flags & DisplayHardware::PARTIAL_UPDATES) {
859 // We need to redraw the rectangle that will be updated
860 // (pushed to the framebuffer).
861 // This is needed because PARTIAL_UPDATES only takes one
862 // rectangle instead of a region (see DisplayHardware::flip())
863 mDirtyRegion.set(mSwapRegion.bounds());
864 } else {
865 // we need to redraw everything (the whole screen)
866 mDirtyRegion.set(hw.bounds());
867 mSwapRegion = mDirtyRegion;
868 }
869 }
870
/*
* 此处先不考虑HWC,HWC另见后续MIMO display – Overlay & HWComposer
* 只考虑使用 OpenGL / 3D GPU render的情况,即各layer->draw。
*/
871 setupHardwareComposer();
872 composeSurfaces(mDirtyRegion);
873
874 // update the swap region and clear the dirty region
875 mSwapRegion.orSelf(mDirtyRegion);
876 mDirtyRegion.clear();
877}
912void SurfaceFlinger::composeSurfaces(const Region& dirty)
913{
914 const DisplayHardware& hw(graphicPlane(0).displayHardware());
915 HWComposer& hwc(hw.getHwComposer());
916 hwc_layer_t* const cur(hwc.getLayers());
917
/*
* 不考虑HWC或者除HWC_OVERLAY有HWC_FB或者Layer数目超出HWC管道数时,
* 使用GPU render。
*/
918 const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
919 if (!cur || fbLayerCount) {
920 // Never touch the framebuffer if we don't have any framebuffer layers
921
/*
* 有HWC_FB有HWC_OVERLAY共存的情形,如Camera或Video
* 暂时认为0不表,详见后续 MIMO display – Overlay & HWComposer
*/
922 if (hwc.getLayerCount(HWC_OVERLAY)) {
923 // when using overlays, we assume a fully transparent framebuffer
924 // NOTE: we could reduce how much we need to clear, for instance
925 // remove where there are opaque FB layers. however, on some
926 // GPUs doing a "clean slate" glClear might be more efficient.
927 // We'll revisit later if needed.
928 const Region region(hw.bounds());
/*
* 为HWC先清原来的画面
*/
929#ifdef QCOMHW
930 if (0 != qdutils::CBUtils::qcomuiClearRegion(region,
931 hw.getEGLDisplay()))
932#endif
933 {
934 glClearColor(0, 0, 0, 0);
935 glClear(GL_COLOR_BUFFER_BIT);
936 }
937 } else {
/*
* 看来FB的时候不需要清屏;如果需要画虫洞,则为该区域清屏以显示虫洞
*/
938 // screen is already cleared here
939 if (!mWormholeRegion.isEmpty()) {
940 // can happen with SurfaceView
941#ifdef QCOMHW
942 if (0 != qdutils::CBUtils::qcomuiClearRegion(mWormholeRegion,
943 hw.getEGLDisplay()))
944#endif
945 drawWormhole();
946 }
947 }
948
/*
* 真正开画
*/
949 /*
950 * and then, render the layers targeted at the framebuffer
951 */
952
953 const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
954 const size_t count = layers.size();
955
/*
* 显然的,从底层向顶层画
*/
956 for (size_t i=0 ; i<count ; i++) {
957 const sp<LayerBase>& layer(layers[i]);
/*
* 各Layer的赃区域
*/
958 const Region clip(dirty.intersect(layer->visibleRegionScreen));
959 if (!clip.isEmpty()) {
960 if (cur && (cur[i].compositionType == HWC_OVERLAY)) {
961 if (i && (cur[i].hints & HWC_HINT_CLEAR_FB)
962 && layer->isOpaque()) {
963 // never clear the very first layer since we're
964 // guaranteed the FB is already cleared
965#ifdef QCOMHW
966 if (0 != qdutils::CBUtils::qcomuiClearRegion(clip,
967 hw.getEGLDisplay()))
968#endif
969 layer->clearWithOpenGL(clip);
970 }
971 continue;
972 }
/*
* 如果是HWC_OVERLAY的,不需要Layer自己画
*/
973#ifdef QCOMHW
974 if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER))
975 continue;
976#endif
977
/*
* HWC_FB Layer,自己开画
*/
978 // render the layer
979 layer->draw(clip);
980 }
981 }
982 } else if (cur && !mWormholeRegion.isEmpty()) {
983 const Region region(mWormholeRegion.intersect(mDirtyRegion));
984 if (!region.isEmpty()) {
985#ifdef QCOMHW
986 if (0 != qdutils::CBUtils::qcomuiClearRegion(region,
987 hw.getEGLDisplay()))
988#endif
989 drawWormhole();
990 }
991 }
992}
344void LayerBase::draw(const Region& clip) const
345{
346 //Dont draw External-only layers
347 if (isLayerExternalOnly(getLayer())) {
348 return;
349 }
350 onDraw(clip);
351}
/*
* Bind Texture and Draw using OpenGL for this layer on the BACK Framebuffer.
*/
321void Layer::onDraw(const Region& clip) const
322{
323 ATRACE_CALL();
324
325 if (CC_UNLIKELY(mActiveBuffer == 0)) {
326 // the texture has not been created yet, this Layer has
327 // in fact never been drawn into. This happens frequently with
328 // SurfaceView because the WindowManager can't know when the client
329 // has drawn the first time.
330
331 // If there is nothing under us, we paint the screen in black, otherwise
332 // we just skip this update.
333
334 // figure out if there is something below us
335 Region under;
336 const SurfaceFlinger::LayerVector& drawingLayers(
337 mFlinger->mDrawingState.layersSortedByZ);
338 const size_t count = drawingLayers.size();
339 for (size_t i=0 ; i<count ; ++i) {
340 const sp<LayerBase>& layer(drawingLayers[i]);
341 if (layer.get() == static_cast<LayerBase const*>(this))
342 break;
343 under.orSelf(layer->visibleRegionScreen);
344 }
345 // if not everything below us is covered, we plug the holes!
346 Region holes(clip.subtract(under));
347 if (!holes.isEmpty()) {
348 clearWithOpenGL(holes, 0, 0, 0, 1);
349 }
350 return;
351 }
352#ifdef QCOMHW
353 if (!qdutils::isGPUSupportedFormat(mActiveBuffer->format)) {
354 clearWithOpenGL(clip, 0, 0, 0, 1);
355 return;
356 }
357#endif
358 if (!isProtected()) {
359 // TODO: we could be more subtle with isFixedSize()
360 const bool useFiltering = getFiltering() || needsFiltering() || isFixedSize();
361
362 // Query the texture matrix given our current filtering mode.
363 float textureMatrix[16];
364 mSurfaceTexture->setFilteringEnabled(useFiltering);
365 mSurfaceTexture->getTransformMatrix(textureMatrix);
366
367 // Set things up for texturing.
368 glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
369 GLenum filter = GL_NEAREST;
370 if (useFiltering) {
371 filter = GL_LINEAR;
372 }
373 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
374 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
375 glMatrixMode(GL_TEXTURE);
376 glLoadMatrixf(textureMatrix);
377 glMatrixMode(GL_MODELVIEW);
378 glDisable(GL_TEXTURE_2D);
379 glEnable(GL_TEXTURE_EXTERNAL_OES);
380 } else {
381 glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
382 glMatrixMode(GL_TEXTURE);
383 glLoadIdentity();
384 glMatrixMode(GL_MODELVIEW);
385 glDisable(GL_TEXTURE_EXTERNAL_OES);
386 glEnable(GL_TEXTURE_2D);
387 }
388
389 drawWithOpenGL(clip);
390
391 glDisable(GL_TEXTURE_EXTERNAL_OES);
392 glDisable(GL_TEXTURE_2D);
393}
/*
* 提交FrameBuffer
* 对于使用GPU的情况,composeSurfaces已经将所有Surface都合成到BACK Framebuffer上了;
* 对于HWComposer的情况,此时还没有启动硬件合成,是在DisplayHardware::flip =>
* HWComposer::commit中合成到BACK Framebuffer上并交换Framebuffer的。
* 为了统一,应该把HWC合成的功能也放到composeSurfaces类似的composeLayers里面去,
* 不用Surface字样是因为Surface是GPU使用的,MDP HWComposer并不具有
* 操作Surface/Texture的能力,而只能操作支持格式的GraphicBuffer。
*/
463void SurfaceFlinger::postFramebuffer()
464{
465 ATRACE_CALL();
466 // mSwapRegion can be empty here is some cases, for instance if a hidden
467 // or fully transparent window is updating.
468 // in that case, we need to flip anyways to not risk a deadlock with
469 // h/w composer.
470
471 const DisplayHardware& hw(graphicPlane(0).displayHardware());
472 const nsecs_t now = systemTime();
473 mDebugInSwapBuffers = now;
474 hw.flip(mSwapRegion);
475
476 size_t numLayers = mVisibleLayersSortedByZ.size();
477 for (size_t i = 0; i < numLayers; i++) {
478 mVisibleLayersSortedByZ[i]->onLayerDisplayed();
479 }
480
481
482 mLastSwapBufferTime = systemTime() - now;
483 mDebugInSwapBuffers = 0;
484 mSwapRegion.clear();
485}
435void DisplayHardware::flip(const Region& dirty) const
436{
437 checkGLErrors();
438
439 EGLDisplay dpy = mDisplay;
440 EGLSurface surface = mSurface;
441
442#ifdef EGL_ANDROID_swap_rectangle
443 if (mFlags & SWAP_RECTANGLE) {
444 const Region newDirty(dirty.intersect(bounds()));
445 const Rect b(newDirty.getBounds());
446 eglSetSwapRectangleANDROID(dpy, surface,
447 b.left, b.top, b.width(), b.height());
448 }
449#endif
450
451 if (mFlags & PARTIAL_UPDATES) {
452 mNativeWindow->setUpdateRectangle(dirty.getBounds());
453 }
454
455 mPageFlipCount++;
456
/*
* mHwc->commit中也会调用eglSwapBuffers,因为不管用什么方式,
* EGL是FrameBufferNativeWindow的管理者,实现buffer swap,避免竞争。
*/
457 if (mHwc->initCheck() == NO_ERROR) {
458 mHwc->commit();
459 } else {
460 eglSwapBuffers(dpy, surface);
461 }
462 checkEGLErrors("eglSwapBuffers");
463
464 // for debugging
465 //glClearColor(1,0,0,0);
466 //glClear(GL_COLOR_BUFFER_BIT);
467}
没有GPU的eglSwapBuffers实现,就看看软的吧。
484EGLBoolean egl_window_surface_v2_t::swapBuffers()
485{
486 if (!buffer) {
487 return setError(EGL_BAD_ACCESS, EGL_FALSE);
488 }
489
490 /*
491 * Handle eglSetSwapRectangleANDROID()
492 * We copyback from the front buffer
493 */
494 if (!dirtyRegion.isEmpty()) {
495 dirtyRegion.andSelf(Rect(buffer->width, buffer->height));
496 if (previousBuffer) {
497 // This was const Region copyBack, but that causes an
498 // internal compile error on simulator builds
/*
* front buffer和back buffer的赃区域的差值拷贝回back buffer中;
* 因为front buffer的赃区域(即其重绘的区域)并未更新到back buffer中,
* 所以需要考回来;但是back buffer的赃区域已经重绘了,是不能覆盖掉的,
* 所以两个赃区域相减。
* 这仅是double buffer的时候的实现,triple buffer两个dirtyRegion就无法保证了。
*/
499 /*const*/ Region copyBack(Region::subtract(oldDirtyRegion, dirtyRegion));
500 if (!copyBack.isEmpty()) {
501 void* prevBits;
502 if (lock(previousBuffer,
503 GRALLOC_USAGE_SW_READ_OFTEN, &prevBits) == NO_ERROR) {
504 // copy from previousBuffer to buffer
505 copyBlt(buffer, bits, previousBuffer, prevBits, copyBack);
506 unlock(previousBuffer);
507 }
508 }
509 }
510 oldDirtyRegion = dirtyRegion;
511 }
512 /*
* 释放front framebuffer
*/
513 if (previousBuffer) {
514 previousBuffer->common.decRef(&previousBuffer->common);
515 previousBuffer = 0;
516 }
517
/*
* 解锁back framebuffer,表用户用完,要queue了。queueBuffer()
*/
518 unlock(buffer);
519 previousBuffer = buffer;
520 nativeWindow->queueBuffer(nativeWindow, buffer);
521 buffer = 0;
522
/*
* back framebuffer已经提交了,需要再dequeue下一个framebuffer来做back framebuffer
* 并且锁住,供使用;
*/
523 // dequeue a new buffer
524 if (nativeWindow->dequeueBuffer(nativeWindow, &buffer) == NO_ERROR) {
525
526 // TODO: lockBuffer should rather be executed when the very first
527 // direct rendering occurs.
528 nativeWindow->lockBuffer(nativeWindow, buffer);
529
530 // reallocate the depth-buffer if needed
531 if ((width != buffer->width) || (height != buffer->height)) {
532 // TODO: we probably should reset the swap rect here
533 // if the window size has changed
534 width = buffer->width;
535 height = buffer->height;
536 if (depth.data) {
537 free(depth.data);
538 depth.width = width;
539 depth.height = height;
540 depth.stride = buffer->stride;
541 depth.data = (GGLubyte*)malloc(depth.stride*depth.height*2);
542 if (depth.data == 0) {
543 setError(EGL_BAD_ALLOC, EGL_FALSE);
544 return EGL_FALSE;
545 }
546 }
547 }
548
549 // keep a reference on the buffer
550 buffer->common.incRef(&buffer->common);
551
/*
* lock/unlock
*/
552 // finally pin the buffer down
553 if (lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN |
554 GRALLOC_USAGE_SW_WRITE_OFTEN, &bits) != NO_ERROR) {
555 ALOGE("eglSwapBuffers() failed to lock buffer %p (%ux%u)",
556 buffer, buffer->width, buffer->height);
557 return setError(EGL_BAD_ACCESS, EGL_FALSE);
558 // FIXME: we should make sure we're not accessing the buffer anymore
559 }
560 } else {
561 return setError(EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
562 }
563
564 return EGL_TRUE;
565}
[END]