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