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

Commit 4a9ac37f authored by Mathias Agopian's avatar Mathias Agopian
Browse files

Fix rotation displays frame N-1 briefly while rotating

The ScreenShot layer is now created hidden. The screenshot itself
is aquired during the transaction when the layer is made visible.
This guarantees the screenshot and the layer happen atomically
with respect to screen updates.

Bug: 5534521
Change-Id: Ida23e1f13d5716ec83b78a15712e0646d6cf8729
parent d9440fe1
Loading
Loading
Loading
Loading
+44 −2
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include "SurfaceFlinger.h"
#include "DisplayHardware/DisplayHardware.h"


namespace android {
// ---------------------------------------------------------------------------

@@ -45,23 +46,64 @@ LayerScreenshot::~LayerScreenshot()
    }
}

status_t LayerScreenshot::captureLocked() {
    GLfloat u, v;
    status_t result = mFlinger->renderScreenToTextureLocked(0, &mTextureName, &u, &v);
    if (result != NO_ERROR) {
        return result;
    }
    initTexture(u, v);
    return NO_ERROR;
}

status_t LayerScreenshot::capture() {
    GLfloat u, v;
    status_t result = mFlinger->renderScreenToTexture(0, &mTextureName, &u, &v);
    if (result != NO_ERROR) {
        return result;
    }
    initTexture(u, v);
    return NO_ERROR;
}

void LayerScreenshot::initTexture(GLfloat u, GLfloat v) {
    glBindTexture(GL_TEXTURE_2D, mTextureName);
    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    mTexCoords[0] = 0;         mTexCoords[1] = v;
    mTexCoords[2] = 0;         mTexCoords[3] = 0;
    mTexCoords[4] = u;         mTexCoords[5] = 0;
    mTexCoords[6] = u;         mTexCoords[7] = v;
}

    return NO_ERROR;
void LayerScreenshot::initStates(uint32_t w, uint32_t h, uint32_t flags) {
    LayerBaseClient::initStates(w, h, flags);
    if (!(flags & ISurfaceComposer::eHidden)) {
        capture();
    }
}

uint32_t LayerScreenshot::doTransaction(uint32_t flags)
{
    const Layer::State& draw(drawingState());
    const Layer::State& curr(currentState());

    if (draw.flags & ISurfaceComposer::eLayerHidden) {
        if (!(curr.flags & ISurfaceComposer::eLayerHidden)) {
            // we're going from hidden to visible
            status_t err = captureLocked();
            if (err != NO_ERROR) {
                LOGW("createScreenshotSurface failed (%s)", strerror(-err));
            }
        }
    } else if (curr.flags & ISurfaceComposer::eLayerHidden) {
        // we're going from visible to hidden
        if (mTextureName) {
            glDeleteTextures(1, &mTextureName);
            mTextureName = 0;
        }
    }
    return LayerBaseClient::doTransaction(flags);
}

void LayerScreenshot::onDraw(const Region& clip) const
+6 −0
Original line number Diff line number Diff line
@@ -41,12 +41,18 @@ public:

        status_t capture();

    virtual void initStates(uint32_t w, uint32_t h, uint32_t flags);
    virtual uint32_t doTransaction(uint32_t flags);
    virtual void onDraw(const Region& clip) const;
    virtual bool isOpaque() const         { return false; }
    virtual bool isSecure() const         { return false; }
    virtual bool isProtectedByApp() const { return false; }
    virtual bool isProtectedByDRM() const { return false; }
    virtual const char* getTypeId() const { return "LayerScreenshot"; }

private:
    status_t captureLocked();
    void initTexture(GLfloat u, GLfloat v);
};

// ---------------------------------------------------------------------------
+0 −5
Original line number Diff line number Diff line
@@ -1360,11 +1360,6 @@ sp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface(
        uint32_t w, uint32_t h, uint32_t flags)
{
    sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
    status_t err = layer->capture();
    if (err != NO_ERROR) {
        layer.clear();
        LOGW("createScreenshotSurface failed (%s)", strerror(-err));
    }
    return layer;
}

+2 −2
Original line number Diff line number Diff line
@@ -186,6 +186,8 @@ public:

            status_t renderScreenToTexture(DisplayID dpy,
                    GLuint* textureName, GLfloat* uOut, GLfloat* vOut);
            status_t renderScreenToTextureLocked(DisplayID dpy,
                    GLuint* textureName, GLfloat* uOut, GLfloat* vOut);

            status_t postMessageAsync(const sp<MessageBase>& msg,
                    nsecs_t reltime=0, uint32_t flags = 0);
@@ -328,8 +330,6 @@ private:
            status_t turnElectronBeamOnImplLocked(int32_t mode);
            status_t electronBeamOffAnimationImplLocked();
            status_t electronBeamOnAnimationImplLocked();
            status_t renderScreenToTextureLocked(DisplayID dpy,
                    GLuint* textureName, GLfloat* uOut, GLfloat* vOut);

            void        debugFlashRegions();
            void        debugShowFPS() const;