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

Commit d6fce7ab authored by Michael Lentine's avatar Michael Lentine Committed by Android (Google) Code Review
Browse files

Merge "Remove lock around ref count check in terminate." into lmp-mr1-dev

parents 1665c8e1 54466bc4
Loading
Loading
Loading
Loading
+144 −119
Original line number Original line Diff line number Diff line
@@ -57,7 +57,7 @@ static bool findExtension(const char* exts, const char* name, size_t nameLen) {
egl_display_t egl_display_t::sDisplay[NUM_DISPLAYS];
egl_display_t egl_display_t::sDisplay[NUM_DISPLAYS];


egl_display_t::egl_display_t() :
egl_display_t::egl_display_t() :
    magic('_dpy'), finishOnSwap(false), traceGpuCompletion(false), refs(0) {
    magic('_dpy'), finishOnSwap(false), traceGpuCompletion(false), refs(0), eglIsInitialized(false) {
}
}


egl_display_t::~egl_display_t() {
egl_display_t::~egl_display_t() {
@@ -120,17 +120,25 @@ EGLDisplay egl_display_t::getDisplay(EGLNativeDisplayType display) {


EGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {
EGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {


    Mutex::Autolock _l(lock);
    {
        Mutex::Autolock _rf(refLock);


    if (refs > 0) {
        refs++;
        if (refs > 1) {
            if (major != NULL)
            if (major != NULL)
                *major = VERSION_MAJOR;
                *major = VERSION_MAJOR;
            if (minor != NULL)
            if (minor != NULL)
                *minor = VERSION_MINOR;
                *minor = VERSION_MINOR;
        refs++;
            while(!eglIsInitialized) refCond.wait(refLock);
            return EGL_TRUE;
            return EGL_TRUE;
        }
        }


        while(eglIsInitialized) refCond.wait(refLock);
    }

    {
        Mutex::Autolock _l(lock);

#if EGL_TRACE
#if EGL_TRACE


        // Called both at early_init time and at this time. (Early_init is pre-zygote, so
        // Called both at early_init time and at this time. (Early_init is pre-zygote, so
@@ -214,21 +222,27 @@ EGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {
            traceGpuCompletion = true;
            traceGpuCompletion = true;
        }
        }


    refs++;
        if (major != NULL)
        if (major != NULL)
            *major = VERSION_MAJOR;
            *major = VERSION_MAJOR;
        if (minor != NULL)
        if (minor != NULL)
            *minor = VERSION_MINOR;
            *minor = VERSION_MINOR;


        mHibernation.setDisplayValid(true);
        mHibernation.setDisplayValid(true);
    }

    {
        Mutex::Autolock _rf(refLock);
        eglIsInitialized = true;
        refCond.broadcast();
    }


    return EGL_TRUE;
    return EGL_TRUE;
}
}


EGLBoolean egl_display_t::terminate() {
EGLBoolean egl_display_t::terminate() {


    Mutex::Autolock _l(lock);
    {

        Mutex::Autolock _rl(refLock);
        if (refs == 0) {
        if (refs == 0) {
            /*
            /*
             * From the EGL spec (3.2):
             * From the EGL spec (3.2):
@@ -240,12 +254,17 @@ EGLBoolean egl_display_t::terminate() {
        }
        }


        // this is specific to Android, display termination is ref-counted.
        // this is specific to Android, display termination is ref-counted.
    if (refs > 1) {
        refs--;
        refs--;
        if (refs > 0) {
            return EGL_TRUE;
            return EGL_TRUE;
        }
        }
    }


    EGLBoolean res = EGL_FALSE;
    EGLBoolean res = EGL_FALSE;

    {
        Mutex::Autolock _l(lock);

        egl_connection_t* const cnx = &gEGLImpl;
        egl_connection_t* const cnx = &gEGLImpl;
        if (cnx->dso && disp.state == egl_display_t::INITIALIZED) {
        if (cnx->dso && disp.state == egl_display_t::INITIALIZED) {
            if (cnx->egl.eglTerminate(disp.dpy) == EGL_FALSE) {
            if (cnx->egl.eglTerminate(disp.dpy) == EGL_FALSE) {
@@ -275,8 +294,14 @@ EGLBoolean egl_display_t::terminate() {


        // this marks all object handles are "terminated"
        // this marks all object handles are "terminated"
        objects.clear();
        objects.clear();
    }

    {
        Mutex::Autolock _rl(refLock);
        eglIsInitialized = false;
        refCond.broadcast();
    }


    refs--;
    return res;
    return res;
}
}


+3 −1
Original line number Original line Diff line number Diff line
@@ -131,7 +131,9 @@ private:
    void leave() { return mHibernation.decWakeCount(HibernationMachine::WEAK); }
    void leave() { return mHibernation.decWakeCount(HibernationMachine::WEAK); }


            uint32_t                    refs;
            uint32_t                    refs;
    mutable Mutex                       lock;
            bool                        eglIsInitialized;
    mutable Mutex                       lock, refLock;
    mutable Condition                   refCond;
            SortedVector<egl_object_t*> objects;
            SortedVector<egl_object_t*> objects;
            String8 mVendorString;
            String8 mVendorString;
            String8 mVersionString;
            String8 mVersionString;