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

Commit 55fa2516 authored by Mathias Agopian's avatar Mathias Agopian
Browse files

implement connect/disconnect in our native_window_t implementations

the framebuffer implementation doesn't do anything special with this
but the surfaceflinger implementation makes sure the surface is not used
by two APIs simultaneously.

Change-Id: Id4ca8ef7093d68846abc2ac814327cc40a64b66b
parent e156e647
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -210,9 +210,16 @@ private:

    status_t dequeueBuffer(sp<GraphicBuffer>* buffer);

    void dispatch_setUsage(va_list args);
    int  dispatch_connect(va_list args);
    int  dispatch_disconnect(va_list args);
    
    void setUsage(uint32_t reqUsage);
    int  connect(int api);
    int  disconnect(int api);

    uint32_t getUsage() const;
    int      getConnectedApi() const;
    
    // constants
    sp<SurfaceComposerClient>   mClient;
@@ -227,6 +234,7 @@ private:
    // protected by mSurfaceLock
    Rect                        mSwapRectangle;
    uint32_t                    mUsage;
    int                         mConnected;
    
    // protected by mSurfaceLock. These are also used from lock/unlock
    // but in that case, they must be called form the same thread.
+82 −7
Original line number Diff line number Diff line
@@ -353,6 +353,7 @@ void Surface::init()
    const_cast<uint32_t&>(android_native_window_t::flags) = 0;
    // be default we request a hardware surface
    mUsage = GRALLOC_USAGE_HW_RENDER;
    mConnected = 0;
    mNeedFullUpdate = false;
}

@@ -580,7 +581,13 @@ int Surface::perform(int operation, va_list args)
    int res = NO_ERROR;
    switch (operation) {
    case NATIVE_WINDOW_SET_USAGE:
            setUsage( va_arg(args, int) );
        dispatch_setUsage( args );
        break;
    case NATIVE_WINDOW_CONNECT:
        res = dispatch_connect( args );
        break;
    case NATIVE_WINDOW_DISCONNECT:
        res = dispatch_disconnect( args );
        break;
    default:
        res = NAME_NOT_FOUND;
@@ -589,18 +596,77 @@ int Surface::perform(int operation, va_list args)
    return res;
}

void Surface::dispatch_setUsage(va_list args) {
    int usage = va_arg(args, int);
    setUsage( usage );
}
int Surface::dispatch_connect(va_list args) {
    int api = va_arg(args, int);
    return connect( api );
}
int Surface::dispatch_disconnect(va_list args) {
    int api = va_arg(args, int);
    return disconnect( api );
}


void Surface::setUsage(uint32_t reqUsage)
{
    Mutex::Autolock _l(mSurfaceLock);
    mUsage = reqUsage;
}

int Surface::connect(int api)
{
    Mutex::Autolock _l(mSurfaceLock);
    int err = NO_ERROR;
    switch (api) {
        case NATIVE_WINDOW_API_EGL:
            if (mConnected) {
                err = -EINVAL;
            } else {
                mConnected = api;
            }
            break;
        default:
            err = -EINVAL;
            break;
    }
    return err;
}

int Surface::disconnect(int api)
{
    Mutex::Autolock _l(mSurfaceLock);
    int err = NO_ERROR;
    switch (api) {
        case NATIVE_WINDOW_API_EGL:
            if (mConnected == api) {
                mConnected = 0;
            } else {
                err = -EINVAL;
            }
            break;
        default:
            err = -EINVAL;
            break;
    }
    return err;
}

uint32_t Surface::getUsage() const
{
    Mutex::Autolock _l(mSurfaceLock);
    return mUsage;
}

int Surface::getConnectedApi() const
{
    Mutex::Autolock _l(mSurfaceLock);
    return mConnected;
}


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

status_t Surface::lock(SurfaceInfo* info, bool blocking) {
@@ -609,11 +675,20 @@ status_t Surface::lock(SurfaceInfo* info, bool blocking) {

status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking) 
{
    if (getConnectedApi()) {
        LOGE("Surface::lock(%p) failed. Already connected to another API",
                (android_native_window_t*)this);
        CallStack stack;
        stack.update();
        stack.dump("");
        return INVALID_OPERATION;
    }

    if (mApiLock.tryLock() != NO_ERROR) {
        LOGE("calling Surface::lock from different threads!");
        CallStack stack;
        stack.update();
        stack.dump("Surface::lock called from different threads");
        stack.dump("");
        return WOULD_BLOCK;
    }

+2 −0
Original line number Diff line number Diff line
@@ -250,6 +250,8 @@ int FramebufferNativeWindow::perform(android_native_window_t* window,
{
    switch (operation) {
        case NATIVE_WINDOW_SET_USAGE:
        case NATIVE_WINDOW_CONNECT:
        case NATIVE_WINDOW_DISCONNECT:
            break;
        default:
            return NAME_NOT_FOUND;