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 28dfcfabfccad8a8f2f42f83081638c7e5c9bfb4b9Chih-Hung Hsiehusing android::RSC::RS; 29dfcfabfccad8a8f2f42f83081638c7e5c9bfb4b9Chih-Hung Hsiehusing android::RSC::RSError; 3069cccdf0659a193d6a75420ec745421fb5c436e6Jason Sams 3184bf2b877024aaa154b66e0f2338d54bdabd855aTim Murraybool RS::gInitialized = false; 324a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murraybool RS::usingNative = false; 3384bf2b877024aaa154b66e0f2338d54bdabd855aTim Murraypthread_mutex_t RS::gInitMutex = PTHREAD_MUTEX_INITIALIZER; 3444bef6fba6244292b751387f3d6c31cca96c28adChris WailesdispatchTable* RS::dispatch = nullptr; 35a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murraystatic int gInitError = 0; 36221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 3784bf2b877024aaa154b66e0f2338d54bdabd855aTim MurrayRS::RS() { 3844bef6fba6244292b751387f3d6c31cca96c28adChris Wailes mContext = nullptr; 3944bef6fba6244292b751387f3d6c31cca96c28adChris Wailes mErrorFunc = nullptr; 4044bef6fba6244292b751387f3d6c31cca96c28adChris Wailes mMessageFunc = nullptr; 41221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams mMessageRun = false; 42a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray mInit = false; 4321fa7a0a23eddab88ff261017f6d7a2548b4d89aTim Murray mCurrentError = RS_SUCCESS; 44221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 45221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams memset(&mElements, 0, sizeof(mElements)); 46729b6fe58aff47c4f666b22bbb7a6d6114ddefa9Tim Murray memset(&mSamplers, 0, sizeof(mSamplers)); 47221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 48221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 4984bf2b877024aaa154b66e0f2338d54bdabd855aTim MurrayRS::~RS() { 50a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray if (mInit == true) { 51a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray mMessageRun = false; 52221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 53fea96e8d145b1915b7bd66f68e973dd572a469e3Xiaofei Wan if (mContext) { 54e8f9651ed5678846959771bc32a310674408e8a8Miao Wang finish(); 55fea96e8d145b1915b7bd66f68e973dd572a469e3Xiaofei Wan RS::dispatch->ContextDeinitToClient(mContext); 56fea96e8d145b1915b7bd66f68e973dd572a469e3Xiaofei Wan 5744bef6fba6244292b751387f3d6c31cca96c28adChris Wailes void *res = nullptr; 58c2459dc5f1c9d299247f77d565c5be5dc57c75e0Yang Ni pthread_join(mMessageThreadId, &res); 59fea96e8d145b1915b7bd66f68e973dd572a469e3Xiaofei Wan 60fea96e8d145b1915b7bd66f68e973dd572a469e3Xiaofei Wan RS::dispatch->ContextDestroy(mContext); 6144bef6fba6244292b751387f3d6c31cca96c28adChris Wailes mContext = nullptr; 62fea96e8d145b1915b7bd66f68e973dd572a469e3Xiaofei Wan } 63a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray } 64221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 65221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 66fda559674cb1bd16b885f97951bda775cdc3af5cMiao Wangbool RS::init(const char * name, uint32_t flags) { 67fda559674cb1bd16b885f97951bda775cdc3af5cMiao Wang return RS::init(name, flags, 0); 68fda559674cb1bd16b885f97951bda775cdc3af5cMiao Wang} 69fda559674cb1bd16b885f97951bda775cdc3af5cMiao Wang 70cf067b8c4d1e53bc4768fbad239851c579717f2cMiao Wang// This will only open API 19+ libRS, because that's when 71cf067b8c4d1e53bc4768fbad239851c579717f2cMiao Wang// we changed libRS to extern "C" entry points. 72e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wangstatic bool loadSO(const char* filename, int targetApi) { 734a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray void* handle = dlopen(filename, RTLD_LAZY | RTLD_LOCAL); 7444bef6fba6244292b751387f3d6c31cca96c28adChris Wailes if (handle == nullptr) { 7587c9d77a3be0dff4a4413bbb6f5b91014896e048Tim Murray ALOGV("couldn't dlopen %s, %s", filename, dlerror()); 764a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray return false; 774a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray } 780b8a2be7eb9322ec221383de325be8f30b36fe9aTim Murray 79e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang if (loadSymbols(handle, *RS::dispatch, targetApi) == false) { 8087c9d77a3be0dff4a4413bbb6f5b91014896e048Tim Murray ALOGV("%s init failed!", filename); 814a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray return false; 824a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray } 834a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray return true; 844a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray} 854a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray 864a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murraystatic uint32_t getProp(const char *str) { 8762237219e567b9f972c86e7ca4e96f9b3d5ad4deMiao Wang#if !defined(__LP64__) && defined(__ANDROID__) 884a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray char buf[256]; 892a61168a777ee434ce2c28945aa74f6a6bcf2820Miao Wang android::renderscript::property_get(str, buf, "0"); 904a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray return atoi(buf); 914a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray#else 924a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray return 0; 934a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray#endif 944a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray} 954a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray 964a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murraybool RS::initDispatch(int targetApi) { 970b8a2be7eb9322ec221383de325be8f30b36fe9aTim Murray pthread_mutex_lock(&gInitMutex); 980b8a2be7eb9322ec221383de325be8f30b36fe9aTim Murray if (gInitError) { 990b8a2be7eb9322ec221383de325be8f30b36fe9aTim Murray goto error; 1000b8a2be7eb9322ec221383de325be8f30b36fe9aTim Murray } else if (gInitialized) { 10147666f52468d8ce14498fac635125f24f79d3257Tim Murray pthread_mutex_unlock(&gInitMutex); 1020b8a2be7eb9322ec221383de325be8f30b36fe9aTim Murray return true; 1030b8a2be7eb9322ec221383de325be8f30b36fe9aTim Murray } 1040b8a2be7eb9322ec221383de325be8f30b36fe9aTim Murray 1050b8a2be7eb9322ec221383de325be8f30b36fe9aTim Murray RS::dispatch = new dispatchTable; 1064a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray 107cf067b8c4d1e53bc4768fbad239851c579717f2cMiao Wang // Attempt to load libRS, load libRSSupport on failure. 108cf067b8c4d1e53bc4768fbad239851c579717f2cMiao Wang // If property is set, proceed directly to libRSSupport. 1094a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray if (getProp("debug.rs.forcecompat") == 0) { 110e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang usingNative = loadSO("libRS.so", targetApi); 1114a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray } 1124a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray if (usingNative == false) { 113e5428e661ce6f9d24f838cab0a8fb0fa8c76dbcaMiao Wang if (loadSO("libRSSupport.so", targetApi) == false) { 1144a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray ALOGE("Failed to load libRS.so and libRSSupport.so"); 1154a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray goto error; 1164a92d1268983edaf329f73c8a5b8860cdbb11596Tim Murray } 117a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray } 118a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray 119a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray gInitialized = true; 120a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray 121a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray pthread_mutex_unlock(&gInitMutex); 122a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray return true; 123a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray 124a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray error: 125a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray gInitError = 1; 126a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray pthread_mutex_unlock(&gInitMutex); 127a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray return false; 128a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray} 129a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray 130d9a0257f82cf4c634f6d2005c7fe1b46b1f7e1f1Miao Wangbool RS::init(const char * name, uint32_t flags, int targetApi) { 131caf4126512b2152ea5f6573ce5d9ca29767b9678Tim Murray if (mInit) { 132caf4126512b2152ea5f6573ce5d9ca29767b9678Tim Murray return true; 133caf4126512b2152ea5f6573ce5d9ca29767b9678Tim Murray } 134d9a0257f82cf4c634f6d2005c7fe1b46b1f7e1f1Miao Wang // When using default value 0, set targetApi to RS_VERSION, 135d9a0257f82cf4c634f6d2005c7fe1b46b1f7e1f1Miao Wang // to preserve the behavior of existing apps. 136d9a0257f82cf4c634f6d2005c7fe1b46b1f7e1f1Miao Wang if (targetApi == 0) { 137d9a0257f82cf4c634f6d2005c7fe1b46b1f7e1f1Miao Wang targetApi = RS_VERSION; 138d9a0257f82cf4c634f6d2005c7fe1b46b1f7e1f1Miao Wang } 139caf4126512b2152ea5f6573ce5d9ca29767b9678Tim Murray 140a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray if (initDispatch(targetApi) == false) { 141a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray ALOGE("Couldn't initialize dispatch table"); 142a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray return false; 143a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray } 144a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray 145bc10dff26207bb8c02051b28326bb134a8f28eb3Miao Wang uint32_t nameLen = strlen(name); 146bc10dff26207bb8c02051b28326bb134a8f28eb3Miao Wang if (nameLen > PATH_MAX) { 147bc10dff26207bb8c02051b28326bb134a8f28eb3Miao Wang ALOGE("The path to the cache directory is too long"); 148bc10dff26207bb8c02051b28326bb134a8f28eb3Miao Wang return false; 149bc10dff26207bb8c02051b28326bb134a8f28eb3Miao Wang } 150bc10dff26207bb8c02051b28326bb134a8f28eb3Miao Wang memcpy(mCacheDir, name, nameLen); 151cf067b8c4d1e53bc4768fbad239851c579717f2cMiao Wang // Add the null character even if the user does not. 152cf067b8c4d1e53bc4768fbad239851c579717f2cMiao Wang mCacheDir[nameLen] = 0; 153bc10dff26207bb8c02051b28326bb134a8f28eb3Miao Wang mCacheDirLen = nameLen + 1; 154caf4126512b2152ea5f6573ce5d9ca29767b9678Tim Murray 1558ca49acfcc784355bd806f87701747a4c1ab9749Yang Ni RsDevice device = RS::dispatch->DeviceCreate(); 1568ca49acfcc784355bd806f87701747a4c1ab9749Yang Ni if (device == 0) { 157221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams ALOGE("Device creation failed"); 158221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return false; 159221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams } 160221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 161bfa5a8e76fd9469cdecb3115685ded677d2d210aJason Sams if (flags & ~(RS_CONTEXT_SYNCHRONOUS | RS_CONTEXT_LOW_LATENCY | 16215c1d06c654c246b8e8047f64f781add32483576Stephen McGroarty RS_CONTEXT_LOW_POWER | RS_CONTEXT_WAIT_FOR_ATTACH)) { 16384e3dea053bea25c1cec44ffb298f8b5b9b9141aTim Murray ALOGE("Invalid flags passed"); 16484e3dea053bea25c1cec44ffb298f8b5b9b9141aTim Murray return false; 16584e3dea053bea25c1cec44ffb298f8b5b9b9141aTim Murray } 16684e3dea053bea25c1cec44ffb298f8b5b9b9141aTim Murray 1678ca49acfcc784355bd806f87701747a4c1ab9749Yang Ni mContext = RS::dispatch->ContextCreate(device, 0, targetApi, RS_CONTEXT_TYPE_NORMAL, flags); 168221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (mContext == 0) { 169221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams ALOGE("Context creation failed"); 170221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return false; 171221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams } 172221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 173221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams pid_t mNativeMessageThreadId; 174221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 17544bef6fba6244292b751387f3d6c31cca96c28adChris Wailes int status = pthread_create(&mMessageThreadId, nullptr, threadProc, this); 176221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (status) { 17784bf2b877024aaa154b66e0f2338d54bdabd855aTim Murray ALOGE("Failed to start RS message thread."); 178221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return false; 179221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams } 180221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams // Wait for the message thread to be active. 181221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams while (!mMessageRun) { 182221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams usleep(1000); 183221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams } 184221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 185a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray mInit = true; 186a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray 187221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return true; 188221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 189221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 19021fa7a0a23eddab88ff261017f6d7a2548b4d89aTim Murrayvoid RS::throwError(RSError error, const char *errMsg) { 19121fa7a0a23eddab88ff261017f6d7a2548b4d89aTim Murray if (mCurrentError == RS_SUCCESS) { 19221fa7a0a23eddab88ff261017f6d7a2548b4d89aTim Murray mCurrentError = error; 19321fa7a0a23eddab88ff261017f6d7a2548b4d89aTim Murray ALOGE("RS CPP error: %s", errMsg); 19421fa7a0a23eddab88ff261017f6d7a2548b4d89aTim Murray } else { 19521fa7a0a23eddab88ff261017f6d7a2548b4d89aTim Murray ALOGE("RS CPP error (masked by previous error): %s", errMsg); 19621fa7a0a23eddab88ff261017f6d7a2548b4d89aTim Murray } 197b2e3dc51dcbbe52b5e72d9c6a16de7000de70edfJason Sams} 198b2e3dc51dcbbe52b5e72d9c6a16de7000de70edfJason Sams 19910913a5c37ba119bef335320d3e8be25212c05adTim MurrayRSError RS::getError() { 20010913a5c37ba119bef335320d3e8be25212c05adTim Murray return mCurrentError; 20110913a5c37ba119bef335320d3e8be25212c05adTim Murray} 20210913a5c37ba119bef335320d3e8be25212c05adTim Murray 203b2e3dc51dcbbe52b5e72d9c6a16de7000de70edfJason Sams 20484bf2b877024aaa154b66e0f2338d54bdabd855aTim Murrayvoid * RS::threadProc(void *vrsc) { 20584bf2b877024aaa154b66e0f2338d54bdabd855aTim Murray RS *rs = static_cast<RS *>(vrsc); 206221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams size_t rbuf_size = 256; 207221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams void * rbuf = malloc(rbuf_size); 208221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 209a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray RS::dispatch->ContextInitToClient(rs->mContext); 210221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams rs->mMessageRun = true; 211221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 212221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams while (rs->mMessageRun) { 213221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams size_t receiveLen = 0; 214221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams uint32_t usrID = 0; 215221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams uint32_t subID = 0; 216a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray RsMessageToClientType r = RS::dispatch->ContextPeekMessage(rs->mContext, 217a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray &receiveLen, sizeof(receiveLen), 218a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray &usrID, sizeof(usrID)); 219221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 220221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (receiveLen >= rbuf_size) { 221221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams rbuf_size = receiveLen + 32; 2227cd1c52c31e8cc56e00eae1d2a66204eb1a8e557rie kanazawa void *tmpBuf = realloc(rbuf, rbuf_size); 2237cd1c52c31e8cc56e00eae1d2a66204eb1a8e557rie kanazawa if (tmpBuf) { 2247cd1c52c31e8cc56e00eae1d2a66204eb1a8e557rie kanazawa rbuf = tmpBuf; 2257cd1c52c31e8cc56e00eae1d2a66204eb1a8e557rie kanazawa } else { 2267cd1c52c31e8cc56e00eae1d2a66204eb1a8e557rie kanazawa free(rbuf); 2277cd1c52c31e8cc56e00eae1d2a66204eb1a8e557rie kanazawa rbuf = NULL; 2287cd1c52c31e8cc56e00eae1d2a66204eb1a8e557rie kanazawa } 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: 248cf067b8c4d1e53bc4768fbad239851c579717f2cMiao Wang /* 249cf067b8c4d1e53bc4768fbad239851c579717f2cMiao Wang * Teardown. We want to avoid starving other threads during 250cf067b8c4d1e53bc4768fbad239851c579717f2cMiao Wang * teardown by yielding until the next line in the destructor can 251cf067b8c4d1e53bc4768fbad239851c579717f2cMiao Wang * execute to set mRun = false. Note that the FIFO sends an 252cf067b8c4d1e53bc4768fbad239851c579717f2cMiao Wang * empty NONE message when it reaches its destructor. 253cf067b8c4d1e53bc4768fbad239851c579717f2cMiao Wang */ 254221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams usleep(1000); 255221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams break; 256221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams case RS_MESSAGE_TO_CLIENT_USER: 25744bef6fba6244292b751387f3d6c31cca96c28adChris Wailes if(rs->mMessageFunc != nullptr) { 258221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams rs->mMessageFunc(usrID, rbuf, receiveLen); 259221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams } else { 260221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams ALOGE("Received a message from the script with no message handler installed."); 261221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams } 262221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams break; 263221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 264221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams default: 26584bf2b877024aaa154b66e0f2338d54bdabd855aTim Murray ALOGE("RS unknown message type %i", r); 266221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams } 267221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams } 268221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 269221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (rbuf) { 270221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams free(rbuf); 271221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams } 27287c9d77a3be0dff4a4413bbb6f5b91014896e048Tim Murray ALOGV("RS Message thread exiting."); 27344bef6fba6244292b751387f3d6c31cca96c28adChris Wailes return nullptr; 274221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 275221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 27684bf2b877024aaa154b66e0f2338d54bdabd855aTim Murrayvoid RS::setErrorHandler(ErrorHandlerFunc_t func) { 277221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams mErrorFunc = func; 278221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 279221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 28084bf2b877024aaa154b66e0f2338d54bdabd855aTim Murrayvoid RS::setMessageHandler(MessageHandlerFunc_t func) { 281221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams mMessageFunc = func; 282221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 283baca6c3c3d79a324c7976ba873afdded0b6bcfb5Tim Murray 284baca6c3c3d79a324c7976ba873afdded0b6bcfb5Tim Murrayvoid RS::finish() { 285a423096c0d49e5cfe13a400b4323a76f89c6885cTim Murray RS::dispatch->ContextFinish(mContext); 286baca6c3c3d79a324c7976ba873afdded0b6bcfb5Tim Murray} 287