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

Commit 516c3191 authored by Jason Sams's avatar Jason Sams
Browse files

Implement data push from scripts. Fixes the problem where apps would have to...

Implement data push from scripts.  Fixes the problem where apps would have to poll to monitor a scripts state.
Fix bug in StoreState where state could be overridden by the default unless the script used more than one state.

Change only impacts renderscript and renderscript apps.
parent f7ae77cd
Loading
Loading
Loading
Loading
+55 −0
Original line number Diff line number Diff line
@@ -75,6 +75,9 @@ public class RenderScript {
    native void nContextAddDefineF(String name, float value);
    native void nContextPause();
    native void nContextResume();
    native int nContextGetMessage(int[] data, boolean wait);
    native void nContextInitToClient();
    native void nContextDeinitToClient();

    native void nAssignName(int obj, byte[] name);
    native void nObjDestroy(int id);
@@ -190,6 +193,7 @@ public class RenderScript {
    private int     mContext;
    @SuppressWarnings({"FieldCanBeLocal"})
    private Surface mSurface;
    private MessageThread mMessageThread;


    Element mElement_USER_U8;
@@ -214,6 +218,52 @@ public class RenderScript {
    ///////////////////////////////////////////////////////////////////////////////////
    //

    public static class RSMessage implements Runnable {
        protected int[] mData;
        protected int mID;
        public void run() {
        }
    }
    public RSMessage mMessageCallback = null;

    private static class MessageThread extends Thread {
        RenderScript mRS;
        boolean mRun = true;

        MessageThread(RenderScript rs) {
            super("RSMessageThread");
            mRS = rs;

        }

        public void run() {
            // This function is a temporary solution.  The final solution will
            // used typed allocations where the message id is the type indicator.
            int[] rbuf = new int[16];
            mRS.nContextInitToClient();
            while(mRun) {
                int msg = mRS.nContextGetMessage(rbuf, true);
                if (msg == 0) {
                    // Should only happen during teardown.
                    // But we want to avoid starving other threads during
                    // teardown by yielding until the next line in the destructor
                    // can execute to set mRun = false
                    try {
                        sleep(1, 0);
                    } catch(InterruptedException e) {
                    }
                }
                if(mRS.mMessageCallback != null) {
                    mRS.mMessageCallback.mData = rbuf;
                    mRS.mMessageCallback.mID = msg;
                    mRS.mMessageCallback.run();
                }
                //Log.d("rs", "MessageThread msg " + msg + " v1 " + rbuf[0] + " v2 " + rbuf[1] + " v3 " +rbuf[2]);
            }
            Log.d("rs", "MessageThread exiting.");
        }
    }

    public RenderScript(Surface sur, boolean useDepth, boolean forceSW) {
        mSurface = sur;
        mDev = nDeviceCreate();
@@ -222,9 +272,14 @@ public class RenderScript {
        }
        mContext = nContextCreate(mDev, mSurface, 0, useDepth);
        Element.initPredefined(this);
        mMessageThread = new MessageThread(this);
        mMessageThread.start();
    }

    public void destroy() {
        nContextDeinitToClient();
        mMessageThread.mRun = false;

        nContextDestroy(mContext);
        mContext = 0;

+34 −0
Original line number Diff line number Diff line
@@ -194,6 +194,37 @@ nContextResume(JNIEnv *_env, jobject _this)
    rsContextResume(con);
}

static jint
nContextGetMessage(JNIEnv *_env, jobject _this, jintArray data, jboolean wait)
{
    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
    jint len = _env->GetArrayLength(data);
    LOG_API("nContextGetMessage, con(%p), len(%i)", con, len);
    jint *ptr = _env->GetIntArrayElements(data, NULL);
    size_t receiveLen;
    int id = rsContextGetMessage(con, ptr, &receiveLen, len * 4, wait);
    if (!id && receiveLen) {
        LOGE("message receive buffer too small.  %i", receiveLen);
    }
    _env->ReleaseIntArrayElements(data, ptr, 0);
    return id;
}

static void nContextInitToClient(JNIEnv *_env, jobject _this)
{
    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
    LOG_API("nContextInitToClient, con(%p)", con);
    rsContextInitToClient(con);
}

static void nContextDeinitToClient(JNIEnv *_env, jobject _this)
{
    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
    LOG_API("nContextDeinitToClient, con(%p)", con);
    rsContextDeinitToClient(con);
}


static void
nElementBegin(JNIEnv *_env, jobject _this)
{
@@ -1303,6 +1334,9 @@ static JNINativeMethod methods[] = {
{"nAssignName",                    "(I[B)V",                               (void*)nAssignName },
{"nObjDestroy",                    "(I)V",                                 (void*)nObjDestroy },
{"nObjDestroyOOB",                 "(I)V",                                 (void*)nObjDestroyOOB },
{"nContextGetMessage",             "([IZ)I",                               (void*)nContextGetMessage },
{"nContextInitToClient",           "()V",                                  (void*)nContextInitToClient },
{"nContextDeinitToClient",         "()V",                                  (void*)nContextDeinitToClient },

{"nFileOpen",                      "([B)I",                                (void*)nFileOpen },

+4 −0
Original line number Diff line number Diff line
@@ -59,6 +59,10 @@ RsContext rsContextCreate(RsDevice, void *, uint32_t version, bool useDepth);
void rsContextDestroy(RsContext);
void rsObjDestroyOOB(RsContext, void *);

uint32_t rsContextGetMessage(RsContext, void *data, size_t *receiveLen, size_t bufferLen, bool wait);
void rsContextInitToClient(RsContext);
void rsContextDeinitToClient(RsContext);

#define RS_MAX_TEXTURE 2

enum RsDataType {
+77 −0
Original line number Diff line number Diff line
@@ -142,6 +142,7 @@ bool Context::runRootScript()
    if (this->props.mLogTimes) {
        timerSet(RS_TIMER_SCRIPT);
    }
    mStateFragmentStore.mLast.clear();
    bool ret = runScript(mRootScript.get(), 0);
    return ret;
}
@@ -529,6 +530,64 @@ void Context::objDestroyAdd(ObjectBase *obj)
    }
}

uint32_t Context::getMessageToClient(void *data, size_t *receiveLen, size_t bufferLen, bool wait)
{
    //LOGE("getMessageToClient %i %i", bufferLen, wait);
    if (!wait) {
        if (mIO.mToClient.isEmpty()) {
            // No message to get and not going to wait for one.
            receiveLen = 0;
            return 0;
        }
    }

    //LOGE("getMessageToClient 2 con=%p", this);
    uint32_t bytesData = 0;
    uint32_t commandID = 0;
    const void *d = mIO.mToClient.get(&commandID, &bytesData);
    //LOGE("getMessageToClient 3    %i  %i", commandID, bytesData);

    *receiveLen = bytesData;
    if (bufferLen >= bytesData) {
        memcpy(data, d, bytesData);
        mIO.mToClient.next();
        return commandID;
    }
    return 0;
}

bool Context::sendMessageToClient(void *data, uint32_t cmdID, size_t len, bool waitForSpace)
{
    //LOGE("sendMessageToClient %i %i %i", cmdID, len, waitForSpace);
    if (cmdID == 0) {
        LOGE("Attempting to send invalid command 0 to client.");
        return false;
    }
    if (!waitForSpace) {
        if (mIO.mToClient.getFreeSpace() < len) {
            // Not enough room, and not waiting.
            return false;
        }
    }
    //LOGE("sendMessageToClient 2");
    void *p = mIO.mToClient.reserve(len);
    memcpy(p, data, len);
    mIO.mToClient.commit(cmdID, len);
    //LOGE("sendMessageToClient 3");
    return true;
}

void Context::initToClient()
{
    while(!mRunning) {
        usleep(100);
    }
}

void Context::deinitToClient()
{
    mIO.mToClient.shutdown();
}


///////////////////////////////////////////////////////////////////////////////////////////
@@ -636,3 +695,21 @@ void rsObjDestroyOOB(RsContext vrsc, void *obj)
    rsc->objDestroyAdd(static_cast<ObjectBase *>(obj));
}

uint32_t rsContextGetMessage(RsContext vrsc, void *data, size_t *receiveLen, size_t bufferLen, bool wait)
{
    Context * rsc = static_cast<Context *>(vrsc);
    return rsc->getMessageToClient(data, receiveLen, bufferLen, wait);
}

void rsContextInitToClient(RsContext vrsc)
{
    Context * rsc = static_cast<Context *>(vrsc);
    rsc->initToClient();
}

void rsContextDeinitToClient(RsContext vrsc)
{
    Context * rsc = static_cast<Context *>(vrsc);
    rsc->deinitToClient();
}
+6 −0
Original line number Diff line number Diff line
@@ -97,6 +97,12 @@ public:
    void appendNameDefines(String8 *str) const;
    void appendVarDefines(String8 *str) const;

    uint32_t getMessageToClient(void *data, size_t *receiveLen, size_t bufferLen, bool wait);
    bool sendMessageToClient(void *data, uint32_t cmdID, size_t len, bool waitForSpace);

    void initToClient();
    void deinitToClient();

    ProgramFragment * getDefaultProgramFragment() const {
        return mStateFragment.mDefault.get();
    }
Loading