1221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams/*
2a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray * Copyright (C) 2013 The Android Open Source Project
3221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams *
4221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams * you may not use this file except in compliance with the License.
6221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams * You may obtain a copy of the License at
7221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams *
8221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams *
10221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams * Unless required by applicable law or agreed to in writing, software
11221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams * See the License for the specific language governing permissions and
14221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams * limitations under the License.
15221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams */
16221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
17221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#include <malloc.h>
18221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#include <string.h>
1984bf2b877024aaa154b66e0f2338d54bdabd855aTim Murray#include <pthread.h>
20221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
21221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#include "RenderScript.h"
2289daad6bae798779e57f252e9da4fe4e62337124Tim Murray#include "rsCppStructs.h"
23eeaf7142d7e06efb3e0ddc7ef542884ab1d527dcTim Murray#include "rsCppInternal.h"
24221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
25a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray#include <dlfcn.h>
260f98d50a8128e68760aa6e819b962e9a1d4b5bedTim Murray#include <unistd.h>
27a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray
280f98d50a8128e68760aa6e819b962e9a1d4b5bedTim Murray#if !defined(RS_SERVER) && !defined(RS_COMPATIBILITY_LIB) && defined(HAVE_ANDROID_OS)
294a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray#include <cutils/properties.h>
300f98d50a8128e68760aa6e819b962e9a1d4b5bedTim Murray#else
310f98d50a8128e68760aa6e819b962e9a1d4b5bedTim Murray#include "rsCompatibilityLib.h"
324a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray#endif
334a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray
340f98d50a8128e68760aa6e819b962e9a1d4b5bedTim Murray
3569cccdf0659a193d6a75420ec745421fb5c436e6Jason Samsusing namespace android;
369eb7f4b90120ebe4be74343856e86b46495f72dfTim Murrayusing namespace RSC;
3769cccdf0659a193d6a75420ec745421fb5c436e6Jason Sams
3884bf2b877024aaa154b66e0f2338d54bdabd855aTim Murraybool RS::gInitialized = false;
394a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murraybool RS::usingNative = false;
4084bf2b877024aaa154b66e0f2338d54bdabd855aTim Murraypthread_mutex_t RS::gInitMutex = PTHREAD_MUTEX_INITIALIZER;
4144bef6fba6244292b751387f3d6c31cca96c28adChris WailesdispatchTable* RS::dispatch = nullptr;
42a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murraystatic int gInitError = 0;
43221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
4484bf2b877024aaa154b66e0f2338d54bdabd855aTim MurrayRS::RS() {
4544bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mDev = nullptr;
4644bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mContext = nullptr;
4744bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mErrorFunc = nullptr;
4844bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mMessageFunc = nullptr;
49221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    mMessageRun = false;
50a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray    mInit = false;
5121fa7a0a23eddab88ff261017f6d7a2548b4d89aTim Murray    mCurrentError = RS_SUCCESS;
52221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
53221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    memset(&mElements, 0, sizeof(mElements));
54729b6fe58aff47c4f666b22bbb7a6d6114ddefa9Tim Murray    memset(&mSamplers, 0, sizeof(mSamplers));
55221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
56221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
5784bf2b877024aaa154b66e0f2338d54bdabd855aTim MurrayRS::~RS() {
58a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray    if (mInit == true) {
59a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray        mMessageRun = false;
60221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
61fea96e8d145b1915b7bd66f68e973dd572a469e3Xiaofei Wan        if (mContext) {
62fea96e8d145b1915b7bd66f68e973dd572a469e3Xiaofei Wan            RS::dispatch->ContextDeinitToClient(mContext);
63fea96e8d145b1915b7bd66f68e973dd572a469e3Xiaofei Wan
6444bef6fba6244292b751387f3d6c31cca96c28adChris Wailes            void *res = nullptr;
65fea96e8d145b1915b7bd66f68e973dd572a469e3Xiaofei Wan            int status = pthread_join(mMessageThreadId, &res);
66fea96e8d145b1915b7bd66f68e973dd572a469e3Xiaofei Wan
67fea96e8d145b1915b7bd66f68e973dd572a469e3Xiaofei Wan            RS::dispatch->ContextDestroy(mContext);
6844bef6fba6244292b751387f3d6c31cca96c28adChris Wailes            mContext = nullptr;
69fea96e8d145b1915b7bd66f68e973dd572a469e3Xiaofei Wan        }
70fea96e8d145b1915b7bd66f68e973dd572a469e3Xiaofei Wan        if (mDev) {
71fea96e8d145b1915b7bd66f68e973dd572a469e3Xiaofei Wan            RS::dispatch->DeviceDestroy(mDev);
7244bef6fba6244292b751387f3d6c31cca96c28adChris Wailes            mDev = nullptr;
73fea96e8d145b1915b7bd66f68e973dd572a469e3Xiaofei Wan        }
74a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray    }
75221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
76221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
77bc10dff26207bb8c02051b28326bb134a8f28eb3Miao Wangbool RS::init(const char * name, uint32_t flags) {
78caf4126512b2152ea5f6573ce5d9ca29767b9678Tim Murray    return RS::init(name, RS_VERSION, flags);
7984bf2b877024aaa154b66e0f2338d54bdabd855aTim Murray}
8084bf2b877024aaa154b66e0f2338d54bdabd855aTim Murray
8175e877d157f9429eb6d8fb1b09c75c5472db161aTim Murray// this will only open API 19+ libRS
8275e877d157f9429eb6d8fb1b09c75c5472db161aTim Murray// because that's when we changed libRS to extern "C" entry points
83e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wangstatic bool loadSO(const char* filename, int targetApi) {
844a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray    void* handle = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
8544bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if (handle == nullptr) {
8687c9d77a3be0dff4a4413bbb6f5b91014896e048Tim Murray        ALOGV("couldn't dlopen %s, %s", filename, dlerror());
874a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray        return false;
884a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray    }
890b8a2be7eb9322ec221383de325be8f30b36fe9aTim Murray
90e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang    if (loadSymbols(handle, *RS::dispatch, targetApi) == false) {
9187c9d77a3be0dff4a4413bbb6f5b91014896e048Tim Murray        ALOGV("%s init failed!", filename);
924a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray        return false;
934a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray    }
9484e3dea053bea25c1cec44ffb298f8b5b9b9141aTim Murray    //ALOGE("Successfully loaded %s", filename);
954a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray    return true;
964a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray}
974a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray
984a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murraystatic uint32_t getProp(const char *str) {
99cbbac9f5916b9253d88bc10c3661b1ecaa80afd8Tim Murray#if !defined(__LP64__) && !defined(RS_SERVER) && defined(HAVE_ANDROID_OS)
1004a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray    char buf[256];
1014a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray    property_get(str, buf, "0");
1024a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray    return atoi(buf);
1034a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray#else
1044a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray    return 0;
1054a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray#endif
1064a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray}
1074a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray
1084a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murraybool RS::initDispatch(int targetApi) {
1090b8a2be7eb9322ec221383de325be8f30b36fe9aTim Murray    pthread_mutex_lock(&gInitMutex);
1100b8a2be7eb9322ec221383de325be8f30b36fe9aTim Murray    if (gInitError) {
1110b8a2be7eb9322ec221383de325be8f30b36fe9aTim Murray        goto error;
1120b8a2be7eb9322ec221383de325be8f30b36fe9aTim Murray    } else if (gInitialized) {
11347666f52468d8ce14498fac635125f24f79d3257Tim Murray        pthread_mutex_unlock(&gInitMutex);
1140b8a2be7eb9322ec221383de325be8f30b36fe9aTim Murray        return true;
1150b8a2be7eb9322ec221383de325be8f30b36fe9aTim Murray    }
1160b8a2be7eb9322ec221383de325be8f30b36fe9aTim Murray
1170b8a2be7eb9322ec221383de325be8f30b36fe9aTim Murray    RS::dispatch = new dispatchTable;
1184a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray
1194a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray    // attempt to load libRS, load libRSSupport on failure
1204a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray    // if property is set, proceed directly to libRSSupport
1214a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray    if (getProp("debug.rs.forcecompat") == 0) {
122e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        usingNative = loadSO("libRS.so", targetApi);
1234a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray    }
1244a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray    if (usingNative == false) {
125e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang        if (loadSO("libRSSupport.so", targetApi) == false) {
1264a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray            ALOGE("Failed to load libRS.so and libRSSupport.so");
1274a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray            goto error;
1284a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray        }
129a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray    }
130a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray
131a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray    gInitialized = true;
132a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray
133a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray    pthread_mutex_unlock(&gInitMutex);
134a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray    return true;
135a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray
136a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray error:
137a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray    gInitError = 1;
138a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray    pthread_mutex_unlock(&gInitMutex);
139a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray    return false;
140a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray}
141a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray
142bc10dff26207bb8c02051b28326bb134a8f28eb3Miao Wangbool RS::init(const char * name, int targetApi, uint32_t flags) {
143caf4126512b2152ea5f6573ce5d9ca29767b9678Tim Murray    if (mInit) {
144caf4126512b2152ea5f6573ce5d9ca29767b9678Tim Murray        return true;
145caf4126512b2152ea5f6573ce5d9ca29767b9678Tim Murray    }
146caf4126512b2152ea5f6573ce5d9ca29767b9678Tim Murray
147a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray    if (initDispatch(targetApi) == false) {
148a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray        ALOGE("Couldn't initialize dispatch table");
149a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray        return false;
150a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray    }
151a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray
152bc10dff26207bb8c02051b28326bb134a8f28eb3Miao Wang    uint32_t nameLen = strlen(name);
153bc10dff26207bb8c02051b28326bb134a8f28eb3Miao Wang    if (nameLen > PATH_MAX) {
154bc10dff26207bb8c02051b28326bb134a8f28eb3Miao Wang        ALOGE("The path to the cache directory is too long");
155bc10dff26207bb8c02051b28326bb134a8f28eb3Miao Wang        return false;
156bc10dff26207bb8c02051b28326bb134a8f28eb3Miao Wang    }
157bc10dff26207bb8c02051b28326bb134a8f28eb3Miao Wang    memcpy(mCacheDir, name, nameLen);
158bc10dff26207bb8c02051b28326bb134a8f28eb3Miao Wang    mCacheDir[nameLen] = 0; //add the null character even if the user does not.
159bc10dff26207bb8c02051b28326bb134a8f28eb3Miao Wang    mCacheDirLen = nameLen + 1;
160caf4126512b2152ea5f6573ce5d9ca29767b9678Tim Murray
161a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray    mDev = RS::dispatch->DeviceCreate();
162221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if (mDev == 0) {
163221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        ALOGE("Device creation failed");
164221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        return false;
165221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
166221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
167bfa5a8e76fd9469cdecb3115685ded677d2d210aJason Sams    if (flags & ~(RS_CONTEXT_SYNCHRONOUS | RS_CONTEXT_LOW_LATENCY |
16893fbc61ad282cbbf4a6a93396fdd8747b1fe3451Stephen McGroarty                  RS_CONTEXT_LOW_POWER | RS_CONTEXT_WAIT_FOR_ATTACH)) {
16984e3dea053bea25c1cec44ffb298f8b5b9b9141aTim Murray        ALOGE("Invalid flags passed");
17084e3dea053bea25c1cec44ffb298f8b5b9b9141aTim Murray        return false;
17184e3dea053bea25c1cec44ffb298f8b5b9b9141aTim Murray    }
17284e3dea053bea25c1cec44ffb298f8b5b9b9141aTim Murray
17384e3dea053bea25c1cec44ffb298f8b5b9b9141aTim Murray    mContext = RS::dispatch->ContextCreate(mDev, 0, targetApi, RS_CONTEXT_TYPE_NORMAL, flags);
174221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if (mContext == 0) {
175221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        ALOGE("Context creation failed");
176221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        return false;
177221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
178221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
179221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    pid_t mNativeMessageThreadId;
180221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
18144bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    int status = pthread_create(&mMessageThreadId, nullptr, threadProc, this);
182221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if (status) {
18384bf2b877024aaa154b66e0f2338d54bdabd855aTim Murray        ALOGE("Failed to start RS message thread.");
184221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        return false;
185221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
186221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    // Wait for the message thread to be active.
187221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    while (!mMessageRun) {
188221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        usleep(1000);
189221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
190221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
191a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray    mInit = true;
192a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray
193221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    return true;
194221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
195221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
19621fa7a0a23eddab88ff261017f6d7a2548b4d89aTim Murrayvoid RS::throwError(RSError error, const char *errMsg) {
19721fa7a0a23eddab88ff261017f6d7a2548b4d89aTim Murray    if (mCurrentError == RS_SUCCESS) {
19821fa7a0a23eddab88ff261017f6d7a2548b4d89aTim Murray        mCurrentError = error;
19921fa7a0a23eddab88ff261017f6d7a2548b4d89aTim Murray        ALOGE("RS CPP error: %s", errMsg);
20021fa7a0a23eddab88ff261017f6d7a2548b4d89aTim Murray    } else {
20121fa7a0a23eddab88ff261017f6d7a2548b4d89aTim Murray        ALOGE("RS CPP error (masked by previous error): %s", errMsg);
20221fa7a0a23eddab88ff261017f6d7a2548b4d89aTim Murray    }
203b2e3dc51dcbbe52b5e72d9c6a16de7000de70edfJason Sams}
204b2e3dc51dcbbe52b5e72d9c6a16de7000de70edfJason Sams
20510913a5c37ba119bef335320d3e8be25212c05adTim MurrayRSError RS::getError() {
20610913a5c37ba119bef335320d3e8be25212c05adTim Murray    return mCurrentError;
20710913a5c37ba119bef335320d3e8be25212c05adTim Murray}
20810913a5c37ba119bef335320d3e8be25212c05adTim Murray
209b2e3dc51dcbbe52b5e72d9c6a16de7000de70edfJason Sams
21084bf2b877024aaa154b66e0f2338d54bdabd855aTim Murrayvoid * RS::threadProc(void *vrsc) {
21184bf2b877024aaa154b66e0f2338d54bdabd855aTim Murray    RS *rs = static_cast<RS *>(vrsc);
212221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    size_t rbuf_size = 256;
213221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    void * rbuf = malloc(rbuf_size);
214221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
215a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray    RS::dispatch->ContextInitToClient(rs->mContext);
216221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    rs->mMessageRun = true;
217221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
218221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    while (rs->mMessageRun) {
219221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        size_t receiveLen = 0;
220221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        uint32_t usrID = 0;
221221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        uint32_t subID = 0;
222a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray        RsMessageToClientType r = RS::dispatch->ContextPeekMessage(rs->mContext,
223a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray                                                                   &receiveLen, sizeof(receiveLen),
224a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray                                                                   &usrID, sizeof(usrID));
225221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
226221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        if (receiveLen >= rbuf_size) {
227221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams            rbuf_size = receiveLen + 32;
228221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams            rbuf = realloc(rbuf, rbuf_size);
229221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        }
230221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        if (!rbuf) {
23184bf2b877024aaa154b66e0f2338d54bdabd855aTim Murray            ALOGE("RS::message handler realloc error %zu", rbuf_size);
232221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams            // No clean way to recover now?
233221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        }
234a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray        RS::dispatch->ContextGetMessage(rs->mContext, rbuf, rbuf_size, &receiveLen, sizeof(receiveLen),
235221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams                            &subID, sizeof(subID));
236221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
237221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        switch(r) {
238221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        case RS_MESSAGE_TO_CLIENT_ERROR:
239221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams            ALOGE("RS Error %s", (const char *)rbuf);
24021fa7a0a23eddab88ff261017f6d7a2548b4d89aTim Murray            rs->throwError(RS_ERROR_RUNTIME_ERROR, "Error returned from runtime");
24144bef6fba6244292b751387f3d6c31cca96c28adChris Wailes            if(rs->mMessageFunc != nullptr) {
242221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams                rs->mErrorFunc(usrID, (const char *)rbuf);
243221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams            }
244221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams            break;
24576a1be4a35267cf0814fb85fb9b1b5bf887e6ae7Stephen Hines        case RS_MESSAGE_TO_CLIENT_NONE:
246221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        case RS_MESSAGE_TO_CLIENT_EXCEPTION:
24776a1be4a35267cf0814fb85fb9b1b5bf887e6ae7Stephen Hines        case RS_MESSAGE_TO_CLIENT_RESIZE:
248221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams            // teardown. But we want to avoid starving other threads during
249221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams            // teardown by yielding until the next line in the destructor can
25076a1be4a35267cf0814fb85fb9b1b5bf887e6ae7Stephen Hines            // execute to set mRun = false. Note that the FIFO sends an
25176a1be4a35267cf0814fb85fb9b1b5bf887e6ae7Stephen Hines            // empty NONE message when it reaches its destructor.
252221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams            usleep(1000);
253221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams            break;
254221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        case RS_MESSAGE_TO_CLIENT_USER:
25544bef6fba6244292b751387f3d6c31cca96c28adChris Wailes            if(rs->mMessageFunc != nullptr) {
256221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams                rs->mMessageFunc(usrID, rbuf, receiveLen);
257221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams            } else {
258221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams                ALOGE("Received a message from the script with no message handler installed.");
259221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams            }
260221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams            break;
261221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
262221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        default:
26384bf2b877024aaa154b66e0f2338d54bdabd855aTim Murray            ALOGE("RS unknown message type %i", r);
264221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        }
265221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
266221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
267221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    if (rbuf) {
268221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams        free(rbuf);
269221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    }
27087c9d77a3be0dff4a4413bbb6f5b91014896e048Tim Murray    ALOGV("RS Message thread exiting.");
27144bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    return nullptr;
272221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
273221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
27484bf2b877024aaa154b66e0f2338d54bdabd855aTim Murrayvoid RS::setErrorHandler(ErrorHandlerFunc_t func) {
275221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    mErrorFunc = func;
276221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
277221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams
27884bf2b877024aaa154b66e0f2338d54bdabd855aTim Murrayvoid RS::setMessageHandler(MessageHandlerFunc_t func) {
279221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams    mMessageFunc  = func;
280221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}
281baca6c3c3d79a324c7976ba873afdded0b6bcfb5Tim Murray
282baca6c3c3d79a324c7976ba873afdded0b6bcfb5Tim Murrayvoid RS::finish() {
283a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray    RS::dispatch->ContextFinish(mContext);
284baca6c3c3d79a324c7976ba873afdded0b6bcfb5Tim Murray}
285