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

Commit 968a9571 authored by Android (Google) Code Review's avatar Android (Google) Code Review
Browse files

Merge change I516c3191 into eclair

* changes:
  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.
parents 962f2536 516c3191
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