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

Commit b43ac2b3 authored by Craig Donner's avatar Craig Donner Committed by android-build-merger
Browse files

Create graphic buffer using binder interfaces

am: 68671533

Change-Id: I9233639d9d2474fdbb7bcd369b82ae0ed3ee83f3
parents a2cc07e7 68671533
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@ LOCAL_SRC_FILES:= \
	EGL/Loader.cpp 	       \
#

LOCAL_SHARED_LIBRARIES += libcutils libutils liblog libui
LOCAL_SHARED_LIBRARIES += libbinder libcutils libutils liblog libui
LOCAL_MODULE:= libEGL
LOCAL_LDFLAGS += -Wl,--exclude-libs=ALL
LOCAL_SHARED_LIBRARIES += libdl
+66 −5
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@
#include <cutils/properties.h>
#include <cutils/memory.h>

#include <gui/ISurfaceComposer.h>

#include <ui/GraphicBuffer.h>

#include <utils/KeyedVector.h>
@@ -40,6 +42,10 @@
#include <utils/String8.h>
#include <utils/Trace.h>

#include "binder/Binder.h"
#include "binder/Parcel.h"
#include "binder/IServiceManager.h"

#include "../egl_impl.h"
#include "../hooks.h"

@@ -1872,18 +1878,73 @@ EGLClientBuffer eglCreateNativeClientBufferANDROID(const EGLint *attrib_list)
        return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0);
    }

    GraphicBuffer* gBuffer = new GraphicBuffer(width, height, format, usage);
    const status_t err = gBuffer->initCheck();
#define CHECK_ERROR_CONDITION(message) \
    if (err != NO_ERROR) { \
        ALOGE(message); \
        goto error_condition; \
    }

    // The holder is used to destroy the buffer if an error occurs.
    GraphicBuffer* gBuffer = new GraphicBuffer();
    sp<IServiceManager> sm = defaultServiceManager();
    sp<IBinder> surfaceFlinger = sm->getService(String16("SurfaceFlinger"));
    sp<IBinder> allocator;
    Parcel sc_data, sc_reply, data, reply;
    status_t err = NO_ERROR;
    if (sm == NULL) {
        ALOGE("Unable to connect to ServiceManager");
        goto error_condition;
    }

    // Obtain an allocator.
    if (surfaceFlinger == NULL) {
        ALOGE("Unable to connect to SurfaceFlinger");
        goto error_condition;
    }
    sc_data.writeInterfaceToken(String16("android.ui.ISurfaceComposer"));
    err = surfaceFlinger->transact(
            BnSurfaceComposer::CREATE_GRAPHIC_BUFFER_ALLOC, sc_data, &sc_reply);
    CHECK_ERROR_CONDITION("Unable to obtain allocator from SurfaceFlinger");
    allocator = sc_reply.readStrongBinder();

    if (allocator == NULL) {
        ALOGE("Unable to obtain an ISurfaceComposer");
        goto error_condition;
    }
    data.writeInterfaceToken(String16("android.ui.IGraphicBufferAlloc"));
    err = data.writeUint32(width);
    CHECK_ERROR_CONDITION("Unable to write width");
    err = data.writeUint32(height);
    CHECK_ERROR_CONDITION("Unable to write height");
    err = data.writeInt32(static_cast<int32_t>(format));
    CHECK_ERROR_CONDITION("Unable to write format");
    err = data.writeUint32(usage);
    CHECK_ERROR_CONDITION("Unable to write usage");
    err = allocator->transact(IBinder::FIRST_CALL_TRANSACTION, data,
            &reply);
    CHECK_ERROR_CONDITION(
            "Unable to request buffer allocation from surface composer");
    err = reply.readInt32();
    CHECK_ERROR_CONDITION("Unable to obtain buffer from surface composer");
    err = reply.read(*gBuffer);
    CHECK_ERROR_CONDITION("Unable to read buffer from surface composer");

    err = gBuffer->initCheck();
    if (err != NO_ERROR) {
        ALOGE("Unable to create native buffer { w=%d, h=%d, f=%d, u=%#x }: %#x",
                width, height, format, usage, err);
        // Destroy the buffer.
        sp<GraphicBuffer> holder(gBuffer);
        return setError(EGL_BAD_ALLOC, (EGLClientBuffer)0);
        goto error_condition;
    }
    ALOGD("Created new native buffer %p { w=%d, h=%d, f=%d, u=%#x }",
            gBuffer, width, height, format, usage);
    return static_cast<EGLClientBuffer>(gBuffer->getNativeBuffer());

#undef CHECK_ERROR_CONDITION

error_condition:
    // Delete the buffer.
    sp<GraphicBuffer> holder(gBuffer);
    return setError(EGL_BAD_ALLOC, (EGLClientBuffer)0);
}

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