SideBand SurfaceView黑屏分析

本文深入探讨了SideBand在Android图形渲染中的作用,分析了SideBand Flow,特别是针对Tunneled Playback时可能出现的黑屏现象。在黑屏问题的分析中,提到了SurfaceFlinger的合成过程,指出了由于tunneled video playback的背景SurfaceView覆盖导致的问题,并通过检查SurfaceView的isOpaque属性找到关键。文章最后提供了修复该问题的Google源码修改方案。

Brief Introduction SideBand

SideBand Flow

Tunneled Playback: Analysis Black Frame

 

 •Brief Introduction SideBand

 

App在运行的过程会create Surface, 并会产生对应的BufferQueueLayer, BufferQueue里面有好几个Slot可以存Graphic Buffer。所以App在绘制的过程就是不断的DequeueEnqueue这些Buffer

SurfaceFlinger会拿这些EnqueueBuffer去做后续处理, SurfaceFlinger会将各Layer当前的Buffer封裝成imageKHR, 当成texure再去给OpenGL ComposerFramebuffer, 最后透过HWCset 里面调用了gralloc, 经过层层呼叫会到OSD driverpandisplay去显示。

CompositionType

HWC_FRAMEBUFFER

HWC_OVERLAY

HWC_BACKGROUND

HWC_FRAMEBUFFER_TARGET

HWC_SIDEBAND

HWC_CURSOR_OVERLAY

HWC_OVERLAY

HWC_SIDEBAND

l this layer's contents are taken from a sideband buffer stream. Added in HWC_DEVICE_API_VERSION_1_4.

SideBand Flow

sideband相关类图

sideband flow

 

l non-tunneled video,ACodec的configureCodec中设置sideband的为NULL

 ltunneled-playback,在ACodec的configureTunneledVideoPlayback设置sidebandHandle,非NULL

status_t ACodec::configureTunneledVideoPlayback(
        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
    native_handle_t* sidebandHandle;

    status_t err = mOMXNode->configureVideoTunnelMode(
            kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
    if (err != OK) {
        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
        return err;
    }

    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
    if (err != OK) {
        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
                sidebandHandle, err);
        return err;
    }

    return OK;
}

 •How the hwcomposer handle sideband

l在prepare阶段,hwcomposer会将sideband compositionType修改为OVERLAY

     并调用DRM的driver设置crop ,displayFrame等信息

l因为在OSD no-tunneled playback设置的sideband为NULL

    hwcomposer prepare阶段未做任何处理,合成有GLES来完成

Tunneled Playback: Analysis Black Frame 

dumpsys SurfaceFlinger

    type   |  handle  | hint | flag | tr | blnd |   format    |     source crop (l,t,r,b)      |          frame         | name

-----------+----------+------+------+----+------+-------------+--------------------------------+------------------------+------

      GLES | 00000000 | 0000 | 0001 | 00 | 0105 | ? ffffffff  |      0,      0,     -1,     -1 |    0,    0, 1920, 1080 | Background for - SurfaceView - com.google.android.exoplayer2.demo/com.google.android.exoplayer2.demo.PlayerActivity#0

       HWC | ad7a4640 | 0002 | 0000 | 00 | 0105 | ? ffffffff  |      0,      0,     -1,     -1 |    0,    0, 1920, 1080 | SurfaceView - com.google.android.exoplayer2.demo/com.google.android.exoplayer2.demo.PlayerActivity#0

      GLES | addcae00 | 0000 | 0000 | 00 | 0105 | RGBA_8888   |      0,      0,   1920,   1080 |    0,    0, 1920, 1080 | com.google.android.exoplayer2.demo/com.google.android.exoplayer2.demo.PlayerActivity#0

 FB TARGET | addc96e0 | 0000 | 0000 | 00 | 0105 | RGBA_8888   |      0,      0,   1920,   1080 |    0,    0, 1920, 1080 | HWC_FRAMEBUFFER_TARGET

可以发现tunneled video playback在SurfaceFlinger进行合成时,多了一层Background SurfaceView,将surfaceview给遮住了,查看SurfaceView的isOpaque = 0,这个数值异常,

在SurfaceFlinger的rebuildLayerStacks中会去computeVisibleRegions,其中就会使用到这个参数isOpaque,因为其为0;这样就导致在计算background surfaceview时,就是全屏了,因为surfaceview没有将background遮住

定位到isOpaque这个函数,查看Google源码发现,Google在8.1版本对此处有修改

Sync过来这个修改,问题就解了 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值