diff options
-rw-r--r-- | include/surfaceflinger/ISurfaceComposer.h | 8 | ||||
-rw-r--r-- | libs/surfaceflinger_client/ISurfaceComposer.cpp | 32 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 19 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 2 |
4 files changed, 61 insertions, 0 deletions
diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/surfaceflinger/ISurfaceComposer.h index 693fbfb..1bab7d7 100644 --- a/include/surfaceflinger/ISurfaceComposer.h +++ b/include/surfaceflinger/ISurfaceComposer.h @@ -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, diff --git a/libs/surfaceflinger_client/ISurfaceComposer.cpp b/libs/surfaceflinger_client/ISurfaceComposer.cpp index b8a7a79..a42b49d 100644 --- a/libs/surfaceflinger_client/ISurfaceComposer.cpp +++ b/libs/surfaceflinger_client/ISurfaceComposer.cpp @@ -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(); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 825d90b..c982ea5 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -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) { diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index ca7d27d..48642d4 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -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; |