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

Commit c5e181f8 authored by Mathias Agopian's avatar Mathias Agopian
Browse files

fix [2315900] Monochrome camera preview screen after launching camera

this was introduced by a recent change. when we try to figure out the size of
the yuv->rgb temporary buffer, the output resolution has not been computed yet
and an invalid buffer size is used. most of the time the allocation fails
and the system reverts to "standard" GL will uses onle the Y plane.

the allocation of the temporary buffer is moved to onDraw(), the first
time it is called, by that time, the window is positioned properly.
parent cb94f70d
Loading
Loading
Loading
Loading
+67 −49
Original line number Diff line number Diff line
@@ -364,43 +364,6 @@ LayerBuffer::BufferSource::BufferSource(LayerBuffer& layer,
        return;
    }

    if (mLayer.mBlitEngine) {
        // create our temporary buffer and corresponding EGLImageKHR.
        // note that the size of this buffer doesn't really matter,
        // the final image will always be drawn with proper aspect ratio.

        int w = layer.mTransformedBounds.width();
        int h = layer.mTransformedBounds.height();
        if (buffers.w * h != buffers.h * w) {
            int t = w; w = h; h = t;
        }
        if (buffers.w * h == buffers.h * w) {
            // same pixel area, don't use filtering
            layer.mUseLinearFiltering = false;
        }

        mTempGraphicBuffer.clear();
        mTempGraphicBuffer = new GraphicBuffer(
                w, h, HAL_PIXEL_FORMAT_RGB_565,
                GraphicBuffer::USAGE_HW_TEXTURE |
                GraphicBuffer::USAGE_HW_2D);

        if (mTempGraphicBuffer->initCheck() == NO_ERROR) {
            NativeBuffer& dst(mTempBuffer);
            dst.img.w = mTempGraphicBuffer->getStride();
            dst.img.h = h;
            dst.img.format = mTempGraphicBuffer->getPixelFormat();
            dst.img.handle = (native_handle_t *)mTempGraphicBuffer->handle;
            dst.img.base = 0;
            dst.crop.l = 0;
            dst.crop.t = 0;
            dst.crop.r = w;
            dst.crop.b = h;
        } else {
            mTempGraphicBuffer.clear();
        }
    }

    mBufferHeap = buffers;
    mLayer.setNeedsBlending((info.h_alpha - info.l_alpha) > 0);    
    mBufferSize = info.getScanlineSize(buffers.hor_stride)*buffers.ver_stride;
@@ -492,18 +455,7 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const
        copybit_device_t* copybit = mLayer.mBlitEngine;
        if (copybit) {
            // create our EGLImageKHR the first time
            if (mTexture.image == EGL_NO_IMAGE_KHR) {
                err = NO_MEMORY;
                if (mTempGraphicBuffer!=0) {
                    err = mLayer.initializeEglImage(
                            mTempGraphicBuffer, &mTexture);
                    // once the EGLImage has been created (whether it fails
                    // or not) we don't need the graphic buffer reference
                    // anymore.
                    mTempGraphicBuffer.clear();
                }
            }

            err = initTempBuffer();
            if (err == NO_ERROR) {
                // NOTE: Assume the buffer is allocated with the proper USAGE flags
                const NativeBuffer& dst(mTempBuffer);
@@ -542,6 +494,72 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const
    mLayer.drawWithOpenGL(clip, mTexture);
}

status_t LayerBuffer::BufferSource::initTempBuffer() const
{
    // figure out the size we need now
    const ISurface::BufferHeap& buffers(mBufferHeap);
    uint32_t w = mLayer.mTransformedBounds.width();
    uint32_t h = mLayer.mTransformedBounds.height();
    if (buffers.w * h != buffers.h * w) {
        int t = w; w = h; h = t;
    }

    if (mTexture.image != EGL_NO_IMAGE_KHR) {
        // we have an EGLImage, make sure the needed size didn't change
        if (w!=mTexture.width || h!= mTexture.height) {
            // delete the EGLImage and texture
            EGLDisplay dpy(mLayer.mFlinger->graphicPlane(0).getEGLDisplay());
            glDeleteTextures(1, &mTexture.name);
            eglDestroyImageKHR(dpy, mTexture.image);
            Texture defaultTexture;
            mTexture = defaultTexture;
            mTempGraphicBuffer.clear();
        } else {
            // we're good, we have an EGLImageKHR and it's (still) the
            // right size
            return NO_ERROR;
        }
    }

    // figure out if we need linear filtering
    if (buffers.w * h == buffers.h * w) {
        // same pixel area, don't use filtering
        mLayer.mUseLinearFiltering = false;
    }

    // Allocate a temporary buffer and create the corresponding EGLImageKHR

    status_t err;
    mTempGraphicBuffer.clear();
    mTempGraphicBuffer = new GraphicBuffer(
            w, h, HAL_PIXEL_FORMAT_RGB_565,
            GraphicBuffer::USAGE_HW_TEXTURE |
            GraphicBuffer::USAGE_HW_2D);

    err = mTempGraphicBuffer->initCheck();
    if (err == NO_ERROR) {
        NativeBuffer& dst(mTempBuffer);
        dst.img.w = mTempGraphicBuffer->getStride();
        dst.img.h = h;
        dst.img.format = mTempGraphicBuffer->getPixelFormat();
        dst.img.handle = (native_handle_t *)mTempGraphicBuffer->handle;
        dst.img.base = 0;
        dst.crop.l = 0;
        dst.crop.t = 0;
        dst.crop.r = w;
        dst.crop.b = h;

        err = mLayer.initializeEglImage(
                mTempGraphicBuffer, &mTexture);
        // once the EGLImage has been created (whether it fails
        // or not) we don't need the graphic buffer reference
        // anymore.
        mTempGraphicBuffer.clear();
    }

    return err;
}

// ---------------------------------------------------------------------------

LayerBuffer::OverlaySource::OverlaySource(LayerBuffer& layer,
+2 −1
Original line number Diff line number Diff line
@@ -130,13 +130,14 @@ private:
        virtual bool transformed() const;
        virtual void destroy() { }
    private:
        status_t initTempBuffer() const;
        mutable Mutex                   mBufferSourceLock;
        sp<Buffer>                      mBuffer;
        status_t                        mStatus;
        ISurface::BufferHeap            mBufferHeap;
        size_t                          mBufferSize;
        mutable LayerBase::Texture      mTexture;
        NativeBuffer                    mTempBuffer;
        mutable NativeBuffer            mTempBuffer;
        mutable sp<GraphicBuffer>       mTempGraphicBuffer;
    };