Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 38efe86d authored by Jesse Hall's avatar Jesse Hall
Browse files

Rewrite VirtualDisplaySurface

The previous implementation assumed that the HWC could read and write
the same buffer on frames that involved both GLES and HWC composition.
It turns out some hardware can't do this. The new implementation
maintains a scratch buffer pool to use on these mixed frames, but on
GLES-only or HWC-only frames still does composition directly into the
output buffer.

Bug: 8384764
Change-Id: I7a3addb34fad9bfcbdabbb8b635083e10223df69
parent 5cd46aa3
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -188,6 +188,25 @@ void DisplayDevice::flip(const Region& dirty) const
    mPageFlipCount++;
}

status_t DisplayDevice::prepareFrame(const HWComposer& hwc) const {
    DisplaySurface::CompositionType compositionType;
    bool haveGles = hwc.hasGlesComposition(mHwcDisplayId);
    bool haveHwc = hwc.hasHwcComposition(mHwcDisplayId);
    if (haveGles && haveHwc) {
        compositionType = DisplaySurface::COMPOSITION_MIXED;
    } else if (haveGles) {
        compositionType = DisplaySurface::COMPOSITION_GLES;
    } else if (haveHwc) {
        compositionType = DisplaySurface::COMPOSITION_HWC;
    } else {
        // Nothing to do -- when turning the screen off we get a frame like
        // this. Call it a HWC frame since we won't be doing any GLES work but
        // will do a prepare/set cycle.
        compositionType = DisplaySurface::COMPOSITION_HWC;
    }
    return mDisplaySurface->prepareFrame(compositionType);
}

void DisplayDevice::swapBuffers(HWComposer& hwc) const {
    // We need to call eglSwapBuffers() unless:
    // (a) there was no GLES composition this frame, or
+2 −0
Original line number Diff line number Diff line
@@ -119,6 +119,8 @@ public:
    int32_t                 getHwcDisplayId() const { return mHwcDisplayId; }
    const wp<IBinder>&      getDisplayToken() const { return mDisplayToken; }

    status_t prepareFrame(const HWComposer& hwc) const;

    void swapBuffers(HWComposer& hwc) const;
    status_t compositionComplete() const;

+12 −0
Original line number Diff line number Diff line
@@ -32,6 +32,18 @@ class DisplaySurface : public virtual RefBase {
public:
    virtual sp<IGraphicBufferProducer> getIGraphicBufferProducer() const = 0;

    // prepareFrame is called after the composition configuration is known but
    // before composition takes place. The DisplaySurface can use the
    // composition type to decide how to manage the flow of buffers between
    // GLES and HWC for this frame.
    enum CompositionType {
        COMPOSITION_UNKNOWN = 0,
        COMPOSITION_GLES    = 1,
        COMPOSITION_HWC     = 2,
        COMPOSITION_MIXED   = COMPOSITION_GLES | COMPOSITION_HWC
    };
    virtual status_t prepareFrame(CompositionType compositionType) = 0;

    // Should be called when composition rendering is complete for a frame (but
    // eglSwapBuffers hasn't necessarily been called). Required by certain
    // older drivers for synchronization.
+4 −0
Original line number Diff line number Diff line
@@ -72,6 +72,10 @@ sp<IGraphicBufferProducer> FramebufferSurface::getIGraphicBufferProducer() const
    return getBufferQueue();
}

status_t FramebufferSurface::prepareFrame(CompositionType compositionType) {
    return NO_ERROR;
}

status_t FramebufferSurface::advanceFrame() {
    // Once we remove FB HAL support, we can call nextBuffer() from here
    // instead of using onFrameAvailable(). No real benefit, except it'll be
+1 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ public:

    virtual sp<IGraphicBufferProducer> getIGraphicBufferProducer() const;

    virtual status_t prepareFrame(CompositionType compositionType);
    virtual status_t compositionComplete();
    virtual status_t advanceFrame();
    virtual void onFrameCommitted();
Loading