我是靠谱客的博主 勤奋黄豆,最近开发中收集的这篇文章主要介绍SurfaceFlinger Layer Clip and Draw---大密度注释,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

/*

 *收到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还为空,

                 *每次RepaintmDirtyRegion就清空了。

                 *此处的判断条件使用Layer个数比较,需要与下面mLayersRemoved结合看。

                 *如果Layer有减少,即使增加的个数小于减少的个数,

                 *那么mVisibleRegionsDirty一定会被设置。

                 *如果没有减少,增加Layer后数目一定会增多。可读性不好。

                 */

567        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {

568            // layers have been added

569            mVisibleRegionsDirty = true;

570        }

571

               /*

                 *有减少的Layer,那么其下Layer可能会暴露出来,需要InvalidateLayer

                 *暴露出来的区域,所以需要记录这块区域。

                 *所有移除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

          /*

            * 复制CurrentStateDrawingState中,即提交,下面代码处理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,不予显示。

                *CameraVideo图像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       

              /*

               *使用该LayermActiveBuffer生成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?每个layerdirty是在后面调用的computeVisibleRegions()中计算出来的,

               *可以在彼时设置给Layer,记录脏区域是个很好的优化。

               *但是Region mPostedDirtyRegionclass Layer而不是class LayerBase的成员,

               *慢慢FIX! dirtycomputeVisibleRegions中的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具有全透明区域(全透明子窗口),如VideoCamera

                        *Layer该区域一定是不可见的,visibleRegion应该减去全透区域,

                        * translucent的判断条件并不表示该Layer为半透,而是有全透区域时,

                        *LayerOpaque属性应该设置为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();

                      /*

                       *如果该LayerOpaque的,那么其整个可见区域一定是遮挡下面的层的。

                       *记录,累积到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记录其mVisibleRegionmCoveredRegion

              */

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

           /*

           * 此处先不考虑HWCHWC另见后续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_OVERLAYHWC_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_FBHWC_OVERLAY共存的情形,如CameraVideo

               *暂时认为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 theBACK 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字样是因为SurfaceGPU使用的,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,因为不管用什么方式,

            * EGLFrameBufferNativeWindow的管理者,实现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}

 

没有GPUeglSwapBuffers实现,就看看软的吧。

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 bufferback 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]

最后

以上就是勤奋黄豆为你收集整理的SurfaceFlinger Layer Clip and Draw---大密度注释的全部内容,希望文章能够帮你解决SurfaceFlinger Layer Clip and Draw---大密度注释所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(38)

评论列表共有 0 条评论

立即
投稿
返回
顶部