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

Commit 1f0a16a5 authored by Robert Carr's avatar Robert Carr
Browse files

SurfaceFlinger and libgui: Support for child layers.

Add support for parenting Layers in a tree. Layers
follow scene-graph style rules, that is to say:
   1. A child is cropped to the final bounds of the parent.
   2. A child inherits the parent's transform (including position)
   3. A child's Z ordering is relative to the parent and bounded between
      the parents siblings.
   4. A childs lifetime is bounded by it's parents lifetime.

Test: New tests in Transaction_test plus manual testing with later branches.
Change-Id: I96f8ad863665b9a70b6f845561344c297b7e6eff
parent 2047fae0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ public:
    virtual status_t createSurface(
            const String8& name, uint32_t w, uint32_t h,
            PixelFormat format, uint32_t flags,
            const sp<IBinder>& parent,
            sp<IBinder>* handle,
            sp<IGraphicBufferProducer>* gbp) = 0;

+2 −1
Original line number Diff line number Diff line
@@ -105,7 +105,8 @@ public:
            uint32_t w,         // width in pixel
            uint32_t h,         // height in pixel
            PixelFormat format, // pixel-format desired
            uint32_t flags = 0  // usage flags
            uint32_t flags = 0,  // usage flags
            SurfaceControl* parent = nullptr // parent
    );

    //! Create a virtual display
+9 −2
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@ public:

    virtual status_t createSurface(const String8& name, uint32_t width,
            uint32_t height, PixelFormat format, uint32_t flags,
            sp<IBinder>* handle,
            const sp<IBinder>& parent, sp<IBinder>* handle,
            sp<IGraphicBufferProducer>* gbp) {
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
@@ -65,6 +65,9 @@ public:
        data.writeUint32(height);
        data.writeInt32(static_cast<int32_t>(format));
        data.writeUint32(flags);
        if (parent != nullptr) {
            data.writeStrongBinder(parent);
        }
        remote()->transact(CREATE_SURFACE, data, &reply);
        *handle = reply.readStrongBinder();
        *gbp = interface_cast<IGraphicBufferProducer>(reply.readStrongBinder());
@@ -145,10 +148,14 @@ status_t BnSurfaceComposerClient::onTransact(
            uint32_t height = data.readUint32();
            PixelFormat format = static_cast<PixelFormat>(data.readInt32());
            uint32_t createFlags = data.readUint32();
            sp<IBinder> parent = nullptr;
            if (data.dataAvail() > 0) {
                parent = data.readStrongBinder();
            }
            sp<IBinder> handle;
            sp<IGraphicBufferProducer> gbp;
            status_t result = createSurface(name, width, height, format,
                    createFlags, &handle, &gbp);
                    createFlags, parent, &handle, &gbp);
            reply->writeStrongBinder(handle);
            reply->writeStrongBinder(IInterface::asBinder(gbp));
            reply->writeInt32(result);
+8 −2
Original line number Diff line number Diff line
@@ -610,13 +610,19 @@ sp<SurfaceControl> SurfaceComposerClient::createSurface(
        uint32_t w,
        uint32_t h,
        PixelFormat format,
        uint32_t flags)
        uint32_t flags,
        SurfaceControl* parent)
{
    sp<SurfaceControl> sur;
    if (mStatus == NO_ERROR) {
        sp<IBinder> handle;
        sp<IBinder> parentHandle;
        sp<IGraphicBufferProducer> gbp;
        status_t err = mClient->createSurface(name, w, h, format, flags,

        if (parent != nullptr) {
            parentHandle = parent->getHandle();
        }
        status_t err = mClient->createSurface(name, w, h, format, flags, parentHandle,
                &handle, &gbp);
        ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
        if (err == NO_ERROR) {
+16 −5
Original line number Diff line number Diff line
@@ -106,14 +106,22 @@ status_t Client::onTransact(
status_t Client::createSurface(
        const String8& name,
        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
        const sp<IBinder>& parentHandle,
        sp<IBinder>* handle,
        sp<IGraphicBufferProducer>* gbp)
{
    sp<Layer> parent = nullptr;
    if (parentHandle != nullptr) {
        parent = getLayerUser(parentHandle);
        if (parent == nullptr) {
            return NAME_NOT_FOUND;
        }
    }

    /*
     * createSurface must be called from the GL thread so that it can
     * have access to the GL context.
     */

    class MessageCreateLayer : public MessageBase {
        SurfaceFlinger* flinger;
        Client* client;
@@ -124,26 +132,29 @@ status_t Client::createSurface(
        uint32_t w, h;
        PixelFormat format;
        uint32_t flags;
        sp<Layer>* parent;
    public:
        MessageCreateLayer(SurfaceFlinger* flinger,
                const String8& name, Client* client,
                uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
                sp<IBinder>* handle,
                sp<IGraphicBufferProducer>* gbp)
                sp<IGraphicBufferProducer>* gbp,
                sp<Layer>* parent)
            : flinger(flinger), client(client),
              handle(handle), gbp(gbp), result(NO_ERROR),
              name(name), w(w), h(h), format(format), flags(flags) {
              name(name), w(w), h(h), format(format), flags(flags),
              parent(parent) {
        }
        status_t getResult() const { return result; }
        virtual bool handler() {
            result = flinger->createLayer(name, client, w, h, format, flags,
                    handle, gbp);
                    handle, gbp, parent);
            return true;
        }
    };

    sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),
            name, this, w, h, format, flags, handle, gbp);
            name, this, w, h, format, flags, handle, gbp, &parent);
    mFlinger->postMessageSync(msg);
    return static_cast<MessageCreateLayer*>( msg.get() )->getResult();
}
Loading