EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID

  • VR廠商為了讓渲染出來(lái)的buffer快速上屏,采用了單緩沖機(jī)制,也就是EGL_SINGLE_BUFFER
    但是單緩沖不需要swapbuffer,怎么呈現(xiàn)?

EGL有個(gè)擴(kuò)展自動(dòng)刷新上屏
EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID

  • 配合使用就是
      bool bRes = eglSurfaceAttrib(display, surface, EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER);
       bRes = eglSurfaceAttrib(display, surface, EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID, 1);
  • 網(wǎng)上關(guān)于EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID的介紹機(jī)會(huì)沒(méi)有
    幸好有opengl的官方spec

1、 This extension is intended for latency-sensitive applications that are doing
front-buffer rendering. It allows them to indicate to the Android compositor
that it should perform composition every time the display refreshes. This
removes the overhead of having to notify the compositor that the window
surface has been updated, but it comes at the cost of doing potentially
unneeded composition work if the window surface has not been updated.
解釋下:此擴(kuò)展適合對(duì)延遲要求比較高的應(yīng)用,它向android合成器指示它應(yīng)該在每次顯示器刷新時(shí)執(zhí)行合成,也就是說(shuō)每次vync來(lái)了我都要合成。這減少了通知合成器的時(shí)間,但是這是有代價(jià)的,就算沒(méi)有界面更新,他也會(huì)去合成

2、If attribute is EGL_ANDROID_front_buffer_auto_refresh, then value specifies
whether to enable or disable auto-refresh in the Android compositor when
doing front-buffer rendering.
EGL_ANDROID_front_buffer_auto_refresh 是個(gè)開(kāi)關(guān),指示合成器是否用前緩沖區(qū)渲染

現(xiàn)在看來(lái)自動(dòng)刷新不一定好

  • 跟蹤下代碼
    frameworks/native/libs/nativewindow/include/system/window.h
 * native_window_set_auto_refresh(..., autoRefresh)
 * Enable/disable auto refresh when in shared buffer mode
 */
static inline int native_window_set_auto_refresh(
        struct ANativeWindow* window,
        bool autoRefresh)
{
    return window->perform(window, NATIVE_WINDOW_SET_AUTO_REFRESH, autoRefresh);
}

frameworks/native/libs/gui/Surface.cpp

int Surface::perform(int operation, va_list args)
{ case NATIVE_WINDOW_SET_AUTO_REFRESH:
        res = dispatchSetAutoRefresh(args);
        break;
}
int Surface::dispatchSetAutoRefresh(va_list args) {
    bool autoRefresh = va_arg(args, int);
    return setAutoRefresh(autoRefresh);
}
int Surface::setAutoRefresh(bool autoRefresh) {
    ATRACE_CALL();
    ALOGV("Surface::setAutoRefresh (%d)", autoRefresh);
    Mutex::Autolock lock(mMutex);

    status_t err = mGraphicBufferProducer->setAutoRefresh(autoRefresh);
    if (err == NO_ERROR) {
        mAutoRefresh = autoRefresh;
    }
    ALOGE_IF(err, "IGraphicBufferProducer::setAutoRefresh(%d) returned %s",
            autoRefresh, strerror(-err));
    return err;
}

frameworks/native/libs/gui/IGraphicBufferProducer.cpp

 case SET_AUTO_REFRESH: {
            CHECK_INTERFACE(IGraphicBuffer, data, reply);
            bool autoRefresh = data.readInt32();
            status_t result = setAutoRefresh(autoRefresh);
            reply->writeInt32(result);
            return NO_ERROR;
        }

frameworks/native/libs/gui/BufferHubProducer.cpp

status_t BufferQueueProducer::setAutoRefresh(bool autoRefresh) {
    ATRACE_CALL();
    BQ_LOGV("setAutoRefresh: %d", autoRefresh);

    std::lock_guard<std::mutex> lock(mCore->mMutex);

    mCore->mAutoRefresh = autoRefresh;
    return NO_ERROR;
}

services/surfaceflinger/BufferLayer.cpp

bool BufferLayer::hasReadyFrame() const {
    return hasFrameUpdate() || getSidebandStreamChanged() || getAutoRefresh();
}

services/surfaceflinger/SurfaceFlinger.cpp
handleMessageRefresh();

void SurfaceFlinger::preComposition()
{
    ATRACE_CALL();
    ALOGV("preComposition");

    mRefreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);

    bool needExtraInvalidate = false;
    mDrawingState.traverseInZOrder([&](Layer* layer) {
        if(!layer){
            ALOGE("%s, found invalid layer!!!",__FUNCTION__);
            return;
        }
        if (layer->onPreComposition(mRefreshStartTime)) {
            needExtraInvalidate = true;
        }
    });

    if (needExtraInvalidate) {
        signalLayerUpdate();
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 本篇文章是基于谷歌有關(guān)Graphic的一篇概覽文章的翻譯:http://source.android.com/de...
    lee_3do閱讀 7,177評(píng)論 2 21
  • SurfaceView與TextureView是Android做視頻開(kāi)發(fā)是必定要用到的兩個(gè)控件,它們的特性和使用場(chǎng)...
    yabin小站閱讀 3,378評(píng)論 0 11
  • 作者:TANGZHIMING原文:http://tangzm.com/blog/?p=167 Google在And...
    WindsOfDanzon閱讀 7,553評(píng)論 0 8
  • GPU由來(lái):CPU的任務(wù)繁多,做邏輯計(jì)算,還要做內(nèi)存管理、顯示操作,因此在實(shí)際運(yùn)算(浮點(diǎn)運(yùn)算)的時(shí)候性能會(huì)大打折扣...
    ArcherZang閱讀 8,760評(píng)論 0 9
  • 每一個(gè)開(kāi)發(fā)者都應(yīng)該了解的關(guān)于 Surface,SurfaceHolder,EGLSurface,SurfaceVi...
    hanpfei閱讀 865評(píng)論 2 1