summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/surfaceflinger/ISurfaceComposer.h8
-rw-r--r--libs/surfaceflinger_client/ISurfaceComposer.cpp32
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp19
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h2
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;