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

Commit 22c67843 authored by Mathias Agopian's avatar Mathias Agopian
Browse files

[3171580] SurfaceFlinger Bypass mode. (DO NOT MERGE)

This is a poor's man precursor to the h/w composer HAL.
Basically we detect when a window is full screen and in
that case we bypass surfaceflinger's composition step, which
yields to much improved performance.

Change-Id: Ie03796ae81a1c951949b771c9323044b980cb347
parent 30eb1b18
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ ifeq ($(TARGET_BOARD_PLATFORM), omap3)
endif
ifeq ($(TARGET_BOARD_PLATFORM), s5pc110)
	LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY
	LOCAL_CFLAGS += -DUSE_COMPOSITION_BYPASS
endif


+6 −0
Original line number Diff line number Diff line
@@ -339,6 +339,12 @@ void DisplayHardware::flip(const Region& dirty) const
    //glClear(GL_COLOR_BUFFER_BIT);
}

status_t DisplayHardware::postBypassBuffer(const native_handle_t* handle) const
{
   framebuffer_device_t *fbDev = (framebuffer_device_t *)mNativeWindow->getDevice();
   return fbDev->post(fbDev, handle);
}

uint32_t DisplayHardware::getFlags() const
{
    return mFlags;
+1 −0
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ public:
    // Flip the front and back buffers if the back buffer is "dirty".  Might
    // be instantaneous, might involve copying the frame buffer around.
    void flip(const Region& dirty) const;
    status_t postBypassBuffer(const native_handle_t* handle) const;

    float       getDpiX() const;
    float       getDpiY() const;
+85 −8
Original line number Diff line number Diff line
@@ -57,7 +57,8 @@ Layer::Layer(SurfaceFlinger* flinger,
        mSecure(false),
        mTextureManager(),
        mBufferManager(mTextureManager),
        mWidth(0), mHeight(0), mNeedsScaling(false), mFixedSize(false)
        mWidth(0), mHeight(0), mNeedsScaling(false), mFixedSize(false),
        mBypassState(false)
{
}

@@ -251,6 +252,29 @@ void Layer::onDraw(const Region& clip) const
        }
        return;
    }

#ifdef USE_COMPOSITION_BYPASS
    sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
    if ((buffer != NULL) && (buffer->transform)) {
        // Here we have a "bypass" buffer, but we need to composite it
        // most likely because it's not fullscreen anymore.
        // Since the buffer may have a transformation applied by the client
        // we need to inverse this transformation here.

        // calculate the inverse of the buffer transform
        const uint32_t mask = HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_FLIP_H;
        const uint32_t bufferTransformInverse = buffer->transform ^ mask;

        // To accomplish the inverse transform, we use "mBufferTransform"
        // which is not used by Layer.cpp
        const_cast<Layer*>(this)->mBufferTransform = bufferTransformInverse;
        drawWithOpenGL(clip, tex);
        // reset to "no transfrom"
        const_cast<Layer*>(this)->mBufferTransform = 0;
        return;
    }
#endif

    drawWithOpenGL(clip, tex);
}

@@ -311,11 +335,12 @@ sp<GraphicBuffer> Layer::requestBuffer(int index,
     * buffer 'index' as our front buffer.
     */

    status_t err = NO_ERROR;
    uint32_t w, h, f;
    uint32_t w, h, f, bypass;
    { // scope for the lock
        Mutex::Autolock _l(mLock);

        bypass = mBypassState;

        // zero means default
        mFixedSize = reqWidth && reqHeight;
        if (!reqFormat) reqFormat = mFormat;
@@ -340,9 +365,40 @@ sp<GraphicBuffer> Layer::requestBuffer(int index,
    // here we have to reallocate a new buffer because the buffer could be
    // used as the front buffer, or by a client in our process
    // (eg: status bar), and we can't release the handle under its feet.
    const uint32_t effectiveUsage = getEffectiveUsage(usage);
    uint32_t effectiveUsage = getEffectiveUsage(usage);

    status_t err = NO_MEMORY;

#ifdef USE_COMPOSITION_BYPASS
    if (!mSecure && bypass && (effectiveUsage & GRALLOC_USAGE_HW_RENDER)) {
        // always allocate a buffer matching the screen size. the size
        // may be different from (w,h) if the buffer is rotated.
        const DisplayHardware& hw(graphicPlane(0).displayHardware());
        int32_t w = hw.getWidth();
        int32_t h = hw.getHeight();
        int32_t f = hw.getFormat();

        buffer = new GraphicBuffer(w, h, f, effectiveUsage | GRALLOC_USAGE_HW_FB);
        err = buffer->initCheck();
        buffer->transform = uint8_t(getOrientation());

        if (err != NO_ERROR) {
            // allocation didn't succeed, probably because an older bypass
            // window hasn't released all its resources yet.
            ClientRef::Access sharedClient(mUserClientRef);
            SharedBufferServer* lcblk(sharedClient.get());
            if (lcblk) {
                // all buffers need reallocation
                lcblk->reallocateAll();
            }
        }
    }
#endif

    if (err != NO_ERROR) {
        buffer = new GraphicBuffer(w, h, f, effectiveUsage);
        err = buffer->initCheck();
    }

    if (err || buffer->handle == 0) {
        GraphicBuffer::dumpAllocationsToSystemLog();
@@ -389,6 +445,27 @@ uint32_t Layer::getEffectiveUsage(uint32_t usage) const
    return usage;
}

bool Layer::setBypass(bool enable)
{
    Mutex::Autolock _l(mLock);

    if (mNeedsScaling || mNeedsFiltering) {
        return false;
    }

    if (mBypassState != enable) {
        mBypassState = enable;
        ClientRef::Access sharedClient(mUserClientRef);
        SharedBufferServer* lcblk(sharedClient.get());
        if (lcblk) {
            // all buffers need reallocation
            lcblk->reallocateAll();
        }
    }

    return true;
}

uint32_t Layer::doTransaction(uint32_t flags)
{
    const Layer::State& front(drawingState());
@@ -639,9 +716,9 @@ void Layer::dump(String8& result, char* buffer, size_t SIZE) const
    snprintf(buffer, SIZE,
            "      "
            "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u],"
            " freezeLock=%p, dq-q-time=%u us\n",
            " freezeLock=%p, bypass=%d, dq-q-time=%u us\n",
            mFormat, w0, h0, s0, w1, h1, s1,
            getFreezeLock().get(), totalTime);
            getFreezeLock().get(), mBypassState, totalTime);

    result.append(buffer);
}
+5 −0
Original line number Diff line number Diff line
@@ -81,6 +81,10 @@ public:
    virtual sp<Surface> createSurface() const;
    virtual status_t ditch();
    virtual void onRemoved();
    virtual bool setBypass(bool enable);

    inline sp<GraphicBuffer> getBypassBuffer() const {
        return mBufferManager.getActiveBuffer(); }

    // only for debugging
    inline sp<GraphicBuffer> getBuffer(int i) const {
@@ -232,6 +236,7 @@ private:
    uint32_t mReqFormat;
    bool mNeedsScaling;
    bool mFixedSize;
    bool mBypassState;
};

// ---------------------------------------------------------------------------
Loading