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

Commit 49563340 authored by Jamie Gennis's avatar Jamie Gennis
Browse files

Add the ISurfaceComposer::createGraphicBuffer IPC.

This change adds a new binder method to the ISurfaceComposer interface.
This IPC is intended to allow SurfaceFlinger clients to allocate gralloc
buffers using SurfaceFlinger as a proxy to gralloc.

Change-Id: Ide9fc283aec5da6268ba62cfed0c3319a50b640d
parent 0383fbf4
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -131,6 +131,13 @@ public:
     * This is an ASYNCHRONOUS call.
     */
    virtual void signal() const = 0;

    /* Create a new GraphicBuffer for the client to use.  SurfaceFlinger will
     * not maintain a reference to the GraphicBuffer, so the underlying native
     * handle will be freed once the client references are released.
     */
    virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
            PixelFormat format, uint32_t usage) const = 0;
};

// ----------------------------------------------------------------------------
@@ -144,6 +151,7 @@ public:
        BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
        CREATE_CONNECTION,
        CREATE_CLIENT_CONNECTION,
        CREATE_GRAPHIC_BUFFER,
        GET_CBLK,
        OPEN_GLOBAL_TRANSACTION,
        CLOSE_GLOBAL_TRANSACTION,
+32 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <binder/IServiceManager.h>

#include <ui/DisplayInfo.h>
#include <ui/GraphicBuffer.h>

#include <surfaceflinger/ISurfaceComposer.h>

@@ -169,6 +170,25 @@ public:
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        remote()->transact(BnSurfaceComposer::SIGNAL, data, &reply, IBinder::FLAG_ONEWAY);
    }

    virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
            PixelFormat format, uint32_t usage) const {
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        data.writeInt32(w);
        data.writeInt32(h);
        data.writeInt32(format);
        data.writeInt32(usage);
        remote()->transact(BnSurfaceComposer::CREATE_GRAPHIC_BUFFER, data,
                &reply);
        sp<GraphicBuffer> graphicBuffer;
        bool nonNull = (bool)reply.readInt32();
        if (nonNull) {
            graphicBuffer = new GraphicBuffer();
            reply.read(*graphicBuffer);
        }
        return graphicBuffer;
    }
};

IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer");
@@ -247,6 +267,18 @@ status_t BnSurfaceComposer::onTransact(
            reply->writeInt32(f);
            reply->writeInt32(res);
        } break;
        case CREATE_GRAPHIC_BUFFER: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            uint32_t w = data.readInt32();
            uint32_t h = data.readInt32();
            PixelFormat format = data.readInt32();
            uint32_t usage = data.readInt32();
            sp<GraphicBuffer> result(createGraphicBuffer(w, h, format, usage));
            reply->writeInt32(result != 0);
            if (result != 0) {
                reply->write(*result);
            }
        } break;
        case TURN_ELECTRON_BEAM_OFF: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            int32_t mode = data.readInt32();
+19 −0
Original line number Diff line number Diff line
@@ -2267,6 +2267,25 @@ sp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const

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

sp<GraphicBuffer> SurfaceFlinger::createGraphicBuffer(uint32_t w, uint32_t h,
        PixelFormat format, uint32_t usage) const {
    // XXX: HACK HACK HACK!!!  This should NOT be static, but it is to fix a
    // race between SurfaceFlinger unref'ing the buffer and the client ref'ing
    // it.
    static sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
    status_t err = graphicBuffer->initCheck();
    if (err != 0) {
        LOGE("createGraphicBuffer: init check failed: %d", err);
        return 0;
    } else if (graphicBuffer->handle == 0) {
        LOGE("createGraphicBuffer: unable to create GraphicBuffer");
        return 0;
    }
    return graphicBuffer;
}

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

Client::Client(const sp<SurfaceFlinger>& flinger)
    : mFlinger(flinger), mNameGenerator(1)
{
+2 −0
Original line number Diff line number Diff line
@@ -322,6 +322,8 @@ private:
            status_t electronBeamOnAnimationImplLocked();
            status_t renderScreenToTextureLocked(DisplayID dpy,
                    GLuint* textureName, GLfloat* uOut, GLfloat* vOut);
            sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
                    PixelFormat format, uint32_t usage) const;

            friend class FreezeLock;
            sp<FreezeLock> getFreezeLock() const;