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
This commit is contained in:
Jamie Gennis
2010-12-20 11:21:07 -08:00
parent 42edf0f8cf
commit 0a53d5c81b
4 changed files with 61 additions and 0 deletions

View File

@@ -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,

View File

@@ -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();

View File

@@ -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)
{

View File

@@ -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;