Android Surfaceflinger Service (eight) output of-----image

Source: Internet
Author: User

Surfaceflinger the output of the image after it is synthesized. In the image output, there are some differences between the hardware synthesizer and the non-existent situation. The software is synthesized using the image buffer producer and consumer model. First, take a look at the initialization of the image buffers.

void Surfaceflinger::init () {alogi ("Surfaceflinger ' s main thread ready to run.")    "Initializing graphics h/w ...");  ...//Initialize our non-virtual displays for (size_t i=0; i<displaydevice::num_builtin_display_types; i++)        {displaydevice::D isplaytype Type ((displaydevice::D isplaytype) i); Set-up the displays that is already connected if (mhwc->isconnected (i) | | type==displaydevice::D isplay_prima            RY) {//All non-virtual displays is currently considered secure.            bool Issecure = true;            createbuiltindisplaylocked (type);            Wp<ibinder> token = mbuiltindisplays[i];            Sp<igraphicbufferproducer> producer;            Sp<igraphicbufferconsumer> consumer;            Bufferqueue::createbufferqueue (&producer, &consumer, New Graphicbufferalloc ()); Sp<framebuffersurface> FBS = new Framebuffersurface (*MHWC, I, conSumer);            int32_t hwcid = Allocatehwcdisplayid (type); sp<displaydevice> HW = new Displaydevice (this, type, Hwcid, Mhwc->getformat (hwcid), Issecure,            Token, FBS, producer, Mrenderengine->geteglconfig ());                if (i > Displaydevice::D isplay_primary) {//fixme:currently we don ' t get Blank/unblank requests For displays and than the main display, so we all//assume a connected display is Unblank                Ed.                ALOGD ("Marking display%zu as acquired/unblanked", I);            Hw->setpowermode (Hwc_power_mode_normal);        } mdisplays.add (token, HW); }    }   ......}
    • calls Bufferqueue::createbufferqueue to create an image buffer and get its producer and consumer interfaces
    • to create framebuffersurface using the consumer consumer interface obtained above
    • Create Displaydevice
    • displaydevice software synthesized images using the resulting producer producer interface to consume processing in framebuffersurface
Displaydevice::D isplaydevice (const sp<surfaceflinger>& Flinger, DisplayType type, int32_t hwcid, int format, bool issecure, const wp<ibinder>& Displaytoken, const SP&LT;DISPL    aysurface>& Displaysurface, const sp<igraphicbufferproducer>& producer, EGLConfig config) : Lastcompositionhadvisiblelayers (False), Mflinger (Flinger), Mtype (type), Mhwcdisplayid (hwcid), Mdisplayt      Oken (Displaytoken), Mdisplaysurface (Displaysurface), Mdisplay (Egl_no_display), Msurface (Egl_no_surface), Mdisplaywidth (), Mdisplayheight (), Mformat (), Mflags (), Mpageflipcount (), Missecure (issecure), MSec Urelayervisible (False), Mlayerstack (No_layer_stack), Morientation (), Mpowermode (Hwc_power_mode_off), M    Activeconfig (0) {Mnativewindow = new Surface (producer, false);    anativewindow* Const window = Mnativewindow.get (); /* * Create our DISPlay ' surface */eglsurface surface;    Egldisplay display = Eglgetdisplay (egl_default_display);    if (config = = egl_no_config) {config = renderengine::chooseeglconfig (display, format);    Surface = Eglcreatewindowsurface (Display, config, window, NULL);    Eglquerysurface (display, surface, egl_width, &mdisplaywidth);    Eglquerysurface (display, surface, egl_height, &mdisplayheight); Make sure this composition can never be stalled by a virtual display//consumer that isn ' t processing buffers fast Enough.    We have a to does this//in the Places://* Here, in case the display was composed entirely by HWC. * in Makecurrent (), using Eglswapinterval.  Some EGL Drivers set the//window ' s swap interval in eglmakecurrent, so they ' ll override the//interval we set    Here.    if (mtype >= displaydevice::D isplay_virtual) window->setswapinterval (window, 0);    mconfig = config;    Mdisplay = display;    Msurface = surface; Mformat = format;    Mpageflipcount = 0;    Mviewport.makeinvalid ();    Mframe.makeinvalid ();                  Virtual displays is always considered enabled Mpowermode = (mtype >= displaydevice::D isplay_virtual)?    Hwc_power_mode_normal:hwc_power_mode_off;  Name the display.    The name would be replaced shortly if the display//is created with Createdisplay ().            Switch (mtype) {case display_primary:mdisplayname = ' built-in screen ';        Break            Case display_external:mdisplayname = "HDMI screen";        Break    Default:mdisplayname = "Virtual screen";    e.g. Overlay #n break;    }//Initialize the display orientation transform. Setprojection (Displaystate::eorientationdefault, Mviewport, mframe);}
    • Initializing the EGL graphics library using the producer interface
    • The EGL graphics library is called when the software draws the layer, and the producer interface is called indirectly

In Surfaceflinger: Call the Docomposesurfaces function composition layer in the:d odisplaycomposition function, and then call Hw->swapbuffers. For no hwcomper exists, the direct commit is displayed. When Hwcomper is present, the layer of the software composition is referred to hwcomper for processing.

void Displaydevice::swapbuffers (hwcomposer& hwc) const {//We need to call Eglswapbuffers () if:      (1) We don ' t have a hardware composer, or//(2) We do GLES composition this frame, and either (a) We have framebuffer target support (not present on legacy//devices, where hwcomposer::commit () h Andles things);                                  or//(b) This is a virtual display if (Hwc.initcheck ()! = No_error | | (Hwc.hasglescomposition (Mhwcdisplayid) && (hwc.supportsframebuffertarget () | | | mtype >= DISPL             ay_virtual)) {Eglboolean success = Eglswapbuffers (Mdisplay, msurface);                               if (!success) {Eglint error = Eglgeterror ();                                    if (Error = = Egl_context_lost | | Mtype = = Displaydevice::D isplay_primary) {log_always_fatal ("eglswapbuffers (%p,%p) failed W  ITH 0x%08x ",                              Mdisplay, Msurface, error); } else {Aloge ("eglswapbuffers (%p,%p) failed with 0x%08x", Mdisp                     Lay, Msurface, error);          }}} status_t result = Mdisplaysurface->advanceframe (); if (Result! = No_error) {aloge ("[%s] failed pushing new frame to HWC:%d", mdisplayname.string ()                 , result); }  }
    • Call Eglswapbuffers commit gles composition buffer when no hwcomposer exists or hwcomposer is present but gles composition is used
    • Other conditions do not handle layer layers

Eglswapbuffers submits the buffer of the gles synthesis to the layer consumer to deal with, the previous article mentions that the consumer is framebuffersurface. Look at its handler function:

void FramebufferSurface::onFrameAvailable(const BufferItem& /* item */) {    sp<GraphicBuffer> buf;    sp<Fence> acquireFence;    status_t err = nextBuffer(buf, acquireFence);    if (err != NO_ERROR) {        ALOGE("error latching nnext FramebufferSurface buffer: %s (%d)",                strerror(-err), err);        return;    }    err = mHwc.fbPost(mDisplayType, acquireFence, buf);    if (err != NO_ERROR) {        ALOGE("error posting framebuffer: %d", err);    }}
    • Call Mhwc.fbpost commit buffer to Hwcomposer function
int HWComposer::fbPost(int32_t id,        const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buffer) {    if (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {        return setFramebufferTarget(id, acquireFence, buffer);    } else {        acquireFence->waitForever("HWComposer::fbPost");        return mFbDev->post(mFbDev, buffer->handle);    }}
    • When a hardware synthesizer is present, call the Setframebuffertarget function to submit the results of the software composition to the hardware synthesizer to blend the layer output
    • When there is no hardware synthesizer, call Mfbdev->post directly to submit the results of the software synthesis to framebuffer in the output

When you finish dodisplaycomposition in Surfaceflinger, the layer is processed and the Postframebuffer submission layer is called to Hwcomposer.

void SurfaceFlinger::postFramebuffer(){    ATRACE_CALL();    ......    HWComposer& hwc(getHwComposer());    if (hwc.initCheck() == NO_ERROR) {        if (!hwc.supportsFramebufferTarget()) {            // EGL spec says:            //   "surface must be bound to the calling thread‘s current context,            //    for the current rendering API."            getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);                                                                                                                        }        hwc.commit();    }      ......}
    • Call Hwc.commit () to submit the layer when there is hwcomposer.
status_t Hwcomposer::commit () {int err = No_error; if (MHWC) {if (!hwchasapiversion (MHWC, hwc_device_api_version_1_1)) {//On VERSION 1.0, the Ope            NGL ES Target surface is communicated//by the (Dpy, Sur) fields and we were guaranteed to has only            A single display.                    Mlists[0]->dpy = Eglgetcurrentdisplay ();        Mlists[0]->sur = Eglgetcurrentsurface (Egl_draw); } for (size_t i=virtual_display_id_base; i<mnumdisplays; i++) {displaydata& disp (mdisplaydat            A[i]);                      if (disp.outbufhandle) {mlists[i]->outbuf = Disp.outbufhandle;                 MLISTS[I]-&GT;OUTBUFACQUIREFENCEFD = Disp.outbufacquirefence->dup ();        }} Err = Mhwc->set (MHWC, Mnumdisplays, mlists); for (size_t i=0; i<mnumdisplays; i++) {displaydata& disp (mDiSplaydata[i]);            Disp.lastdisplayfence = disp.lastretirefence;                     Disp.lastretirefence = fence::no_fence; if (disp.list) {if (disp.list->retirefencefd! =-1) {disp.lastretirefence =                      New Fence (DISP.LIST-&GT;RETIREFENCEFD);                          DISP.LIST-&GT;RETIREFENCEFD =-1;              } disp.list->flags &= ~hwc_geometry_changed; }}} "return (status_t) err;}
    • Call Mhwc->set to compose and output the layer graph to the display device using hardware

Android Surfaceflinger Service (eight) output of-----image

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.