1*e1eccf28SAndroid Build Coastguard Worker /* 2*e1eccf28SAndroid Build Coastguard Worker * Copyright (C) 2015 The Android Open Source Project 3*e1eccf28SAndroid Build Coastguard Worker * 4*e1eccf28SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*e1eccf28SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*e1eccf28SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*e1eccf28SAndroid Build Coastguard Worker * 8*e1eccf28SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*e1eccf28SAndroid Build Coastguard Worker * 10*e1eccf28SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*e1eccf28SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*e1eccf28SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*e1eccf28SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*e1eccf28SAndroid Build Coastguard Worker * limitations under the License. 15*e1eccf28SAndroid Build Coastguard Worker */ 16*e1eccf28SAndroid Build Coastguard Worker 17*e1eccf28SAndroid Build Coastguard Worker #ifndef ANDROID_RENDERSCRIPT_EXECUTABLE_H 18*e1eccf28SAndroid Build Coastguard Worker #define ANDROID_RENDERSCRIPT_EXECUTABLE_H 19*e1eccf28SAndroid Build Coastguard Worker 20*e1eccf28SAndroid Build Coastguard Worker 21*e1eccf28SAndroid Build Coastguard Worker #include "rsCpuScript.h" 22*e1eccf28SAndroid Build Coastguard Worker 23*e1eccf28SAndroid Build Coastguard Worker #include <stdlib.h> 24*e1eccf28SAndroid Build Coastguard Worker #include <string> 25*e1eccf28SAndroid Build Coastguard Worker 26*e1eccf28SAndroid Build Coastguard Worker namespace android { 27*e1eccf28SAndroid Build Coastguard Worker namespace renderscript { 28*e1eccf28SAndroid Build Coastguard Worker 29*e1eccf28SAndroid Build Coastguard Worker class Context; 30*e1eccf28SAndroid Build Coastguard Worker 31*e1eccf28SAndroid Build Coastguard Worker class SharedLibraryUtils { 32*e1eccf28SAndroid Build Coastguard Worker public: 33*e1eccf28SAndroid Build Coastguard Worker #ifndef RS_COMPATIBILITY_LIB 34*e1eccf28SAndroid Build Coastguard Worker // Creates a shared library in cacheDir for the bitcode named resName. 35*e1eccf28SAndroid Build Coastguard Worker // If reuse is false and SOPath is not nullptr, saves the filename 36*e1eccf28SAndroid Build Coastguard Worker // used for the shared library in SOPath. 37*e1eccf28SAndroid Build Coastguard Worker static bool createSharedLibrary(const char* driverName, 38*e1eccf28SAndroid Build Coastguard Worker const char* cacheDir, 39*e1eccf28SAndroid Build Coastguard Worker const char* resName, 40*e1eccf28SAndroid Build Coastguard Worker const bool reuse = true, 41*e1eccf28SAndroid Build Coastguard Worker std::string *SOPath = nullptr); 42*e1eccf28SAndroid Build Coastguard Worker #endif 43*e1eccf28SAndroid Build Coastguard Worker 44*e1eccf28SAndroid Build Coastguard Worker // Load the shared library referred to by cacheDir and resName. If we have 45*e1eccf28SAndroid Build Coastguard Worker // already loaded this library, we instead create a new copy (in the 46*e1eccf28SAndroid Build Coastguard Worker // cache dir) and then load that. We then immediately destroy the copy. 47*e1eccf28SAndroid Build Coastguard Worker // This is required behavior to implement script instancing for the support 48*e1eccf28SAndroid Build Coastguard Worker // library, since shared objects are loaded and de-duped by name only. 49*e1eccf28SAndroid Build Coastguard Worker 50*e1eccf28SAndroid Build Coastguard Worker // For 64bit RS Support Lib, the shared lib path cannot be constructed from 51*e1eccf28SAndroid Build Coastguard Worker // cacheDir, so nativeLibDir is needed to load shared libs. 52*e1eccf28SAndroid Build Coastguard Worker static void* loadSharedLibrary(const char *cacheDir, const char *resName, 53*e1eccf28SAndroid Build Coastguard Worker const char *nativeLibDir = nullptr, 54*e1eccf28SAndroid Build Coastguard Worker bool *alreadyLoaded = nullptr); 55*e1eccf28SAndroid Build Coastguard Worker 56*e1eccf28SAndroid Build Coastguard Worker // Load the shared library referred to by fullPath, and delete it right 57*e1eccf28SAndroid Build Coastguard Worker // after loading it. Files loaded by this function are only used once, e.g., 58*e1eccf28SAndroid Build Coastguard Worker // shared libraries generated for scripts in a debug context. Deleting them 59*e1eccf28SAndroid Build Coastguard Worker // is OK in this case since the shared libraries have already been dlopened. 60*e1eccf28SAndroid Build Coastguard Worker // Deletion is also required because such files are not intended for reuse. 61*e1eccf28SAndroid Build Coastguard Worker static void* loadAndDeleteSharedLibrary(const char *fullPath); 62*e1eccf28SAndroid Build Coastguard Worker 63*e1eccf28SAndroid Build Coastguard Worker // Create a len length string containing random characters from [A-Za-z0-9]. 64*e1eccf28SAndroid Build Coastguard Worker static std::string getRandomString(size_t len); 65*e1eccf28SAndroid Build Coastguard Worker 66*e1eccf28SAndroid Build Coastguard Worker private: 67*e1eccf28SAndroid Build Coastguard Worker // Attempt to load the shared library from origName, but then fall back to 68*e1eccf28SAndroid Build Coastguard Worker // creating a copy of the shared library if necessary (to ensure instancing). 69*e1eccf28SAndroid Build Coastguard Worker // This function returns the dlopen()-ed handle if successful. 70*e1eccf28SAndroid Build Coastguard Worker static void *loadSOHelper(const char *origName, const char *cacheDir, 71*e1eccf28SAndroid Build Coastguard Worker const char *resName, bool* alreadyLoaded = nullptr); 72*e1eccf28SAndroid Build Coastguard Worker 73*e1eccf28SAndroid Build Coastguard Worker static const char* LD_EXE_PATH; 74*e1eccf28SAndroid Build Coastguard Worker static const char* RS_CACHE_DIR; 75*e1eccf28SAndroid Build Coastguard Worker }; 76*e1eccf28SAndroid Build Coastguard Worker 77*e1eccf28SAndroid Build Coastguard Worker class ScriptExecutable { 78*e1eccf28SAndroid Build Coastguard Worker public: ScriptExecutable(void ** fieldAddress,bool * fieldIsObject,const char * const * fieldName,size_t varCount,InvokeFunc_t * invokeFunctions,size_t funcCount,ForEachFunc_t * forEachFunctions,uint32_t * forEachSignatures,size_t forEachCount,ReduceDescription * reduceDescriptions,size_t reduceCount,const char ** pragmaKeys,const char ** pragmaValues,size_t pragmaCount,const char ** globalNames,const void ** globalAddresses,const size_t * globalSizes,const uint32_t * globalProperties,size_t globalEntries,bool isThreadable,uint32_t buildChecksum)79*e1eccf28SAndroid Build Coastguard Worker ScriptExecutable(void** fieldAddress, bool* fieldIsObject, 80*e1eccf28SAndroid Build Coastguard Worker const char* const * fieldName, size_t varCount, 81*e1eccf28SAndroid Build Coastguard Worker InvokeFunc_t* invokeFunctions, size_t funcCount, 82*e1eccf28SAndroid Build Coastguard Worker ForEachFunc_t* forEachFunctions, uint32_t* forEachSignatures, 83*e1eccf28SAndroid Build Coastguard Worker size_t forEachCount, 84*e1eccf28SAndroid Build Coastguard Worker ReduceDescription *reduceDescriptions, size_t reduceCount, 85*e1eccf28SAndroid Build Coastguard Worker const char** pragmaKeys, const char** pragmaValues, 86*e1eccf28SAndroid Build Coastguard Worker size_t pragmaCount, 87*e1eccf28SAndroid Build Coastguard Worker const char **globalNames, const void **globalAddresses, 88*e1eccf28SAndroid Build Coastguard Worker const size_t *globalSizes, 89*e1eccf28SAndroid Build Coastguard Worker const uint32_t *globalProperties, size_t globalEntries, 90*e1eccf28SAndroid Build Coastguard Worker bool isThreadable, uint32_t buildChecksum) : 91*e1eccf28SAndroid Build Coastguard Worker mFieldAddress(fieldAddress), mFieldIsObject(fieldIsObject), 92*e1eccf28SAndroid Build Coastguard Worker mFieldName(fieldName), mExportedVarCount(varCount), 93*e1eccf28SAndroid Build Coastguard Worker mInvokeFunctions(invokeFunctions), mFuncCount(funcCount), 94*e1eccf28SAndroid Build Coastguard Worker mForEachFunctions(forEachFunctions), mForEachSignatures(forEachSignatures), 95*e1eccf28SAndroid Build Coastguard Worker mForEachCount(forEachCount), 96*e1eccf28SAndroid Build Coastguard Worker mReduceDescriptions(reduceDescriptions), mReduceCount(reduceCount), 97*e1eccf28SAndroid Build Coastguard Worker mPragmaKeys(pragmaKeys), mPragmaValues(pragmaValues), 98*e1eccf28SAndroid Build Coastguard Worker mPragmaCount(pragmaCount), mGlobalNames(globalNames), 99*e1eccf28SAndroid Build Coastguard Worker mGlobalAddresses(globalAddresses), mGlobalSizes(globalSizes), 100*e1eccf28SAndroid Build Coastguard Worker mGlobalProperties(globalProperties), mGlobalEntries(globalEntries), 101*e1eccf28SAndroid Build Coastguard Worker mIsThreadable(isThreadable), mBuildChecksum(buildChecksum) { 102*e1eccf28SAndroid Build Coastguard Worker } 103*e1eccf28SAndroid Build Coastguard Worker ~ScriptExecutable()104*e1eccf28SAndroid Build Coastguard Worker ~ScriptExecutable() { 105*e1eccf28SAndroid Build Coastguard Worker for (size_t i = 0; i < mExportedVarCount; ++i) { 106*e1eccf28SAndroid Build Coastguard Worker if (mFieldIsObject[i]) { 107*e1eccf28SAndroid Build Coastguard Worker if (mFieldAddress[i] != nullptr) { 108*e1eccf28SAndroid Build Coastguard Worker rs_object_base *obj_addr = 109*e1eccf28SAndroid Build Coastguard Worker reinterpret_cast<rs_object_base *>(mFieldAddress[i]); 110*e1eccf28SAndroid Build Coastguard Worker rsrClearObject(obj_addr); 111*e1eccf28SAndroid Build Coastguard Worker } 112*e1eccf28SAndroid Build Coastguard Worker } 113*e1eccf28SAndroid Build Coastguard Worker } 114*e1eccf28SAndroid Build Coastguard Worker 115*e1eccf28SAndroid Build Coastguard Worker for (size_t i = 0; i < mPragmaCount; ++i) { 116*e1eccf28SAndroid Build Coastguard Worker delete [] mPragmaKeys[i]; 117*e1eccf28SAndroid Build Coastguard Worker delete [] mPragmaValues[i]; 118*e1eccf28SAndroid Build Coastguard Worker } 119*e1eccf28SAndroid Build Coastguard Worker delete[] mPragmaValues; 120*e1eccf28SAndroid Build Coastguard Worker delete[] mPragmaKeys; 121*e1eccf28SAndroid Build Coastguard Worker 122*e1eccf28SAndroid Build Coastguard Worker delete[] mReduceDescriptions; 123*e1eccf28SAndroid Build Coastguard Worker 124*e1eccf28SAndroid Build Coastguard Worker delete[] mForEachSignatures; 125*e1eccf28SAndroid Build Coastguard Worker delete[] mForEachFunctions; 126*e1eccf28SAndroid Build Coastguard Worker 127*e1eccf28SAndroid Build Coastguard Worker delete[] mInvokeFunctions; 128*e1eccf28SAndroid Build Coastguard Worker 129*e1eccf28SAndroid Build Coastguard Worker for (size_t i = 0; i < mExportedVarCount; i++) { 130*e1eccf28SAndroid Build Coastguard Worker delete[] mFieldName[i]; 131*e1eccf28SAndroid Build Coastguard Worker } 132*e1eccf28SAndroid Build Coastguard Worker delete[] mFieldName; 133*e1eccf28SAndroid Build Coastguard Worker delete[] mFieldIsObject; 134*e1eccf28SAndroid Build Coastguard Worker delete[] mFieldAddress; 135*e1eccf28SAndroid Build Coastguard Worker } 136*e1eccf28SAndroid Build Coastguard Worker 137*e1eccf28SAndroid Build Coastguard Worker // Create an ScriptExecutable object from a shared object. 138*e1eccf28SAndroid Build Coastguard Worker // If expectedChecksum is not zero, it will be compared to the checksum 139*e1eccf28SAndroid Build Coastguard Worker // embedded in the shared object. A mismatch will cause a failure. 140*e1eccf28SAndroid Build Coastguard Worker // If succeeded, returns the new object. Otherwise, returns nullptr. 141*e1eccf28SAndroid Build Coastguard Worker static ScriptExecutable* 142*e1eccf28SAndroid Build Coastguard Worker createFromSharedObject(void* sharedObj, 143*e1eccf28SAndroid Build Coastguard Worker uint32_t expectedChecksum = 0); 144*e1eccf28SAndroid Build Coastguard Worker getExportedVariableCount()145*e1eccf28SAndroid Build Coastguard Worker size_t getExportedVariableCount() const { return mExportedVarCount; } getExportedFunctionCount()146*e1eccf28SAndroid Build Coastguard Worker size_t getExportedFunctionCount() const { return mFuncCount; } getExportedForEachCount()147*e1eccf28SAndroid Build Coastguard Worker size_t getExportedForEachCount() const { return mForEachCount; } getExportedReduceCount()148*e1eccf28SAndroid Build Coastguard Worker size_t getExportedReduceCount() const { return mReduceCount; } getPragmaCount()149*e1eccf28SAndroid Build Coastguard Worker size_t getPragmaCount() const { return mPragmaCount; } 150*e1eccf28SAndroid Build Coastguard Worker getFieldAddress(int slot)151*e1eccf28SAndroid Build Coastguard Worker void* getFieldAddress(int slot) const { return mFieldAddress[slot]; } 152*e1eccf28SAndroid Build Coastguard Worker void* getFieldAddress(const char* name) const; getFieldIsObject(int slot)153*e1eccf28SAndroid Build Coastguard Worker bool getFieldIsObject(int slot) const { return mFieldIsObject[slot]; } getFieldName(int slot)154*e1eccf28SAndroid Build Coastguard Worker const char* getFieldName(int slot) const { return mFieldName[slot]; } 155*e1eccf28SAndroid Build Coastguard Worker getInvokeFunction(int slot)156*e1eccf28SAndroid Build Coastguard Worker InvokeFunc_t getInvokeFunction(int slot) const { return mInvokeFunctions[slot]; } 157*e1eccf28SAndroid Build Coastguard Worker getForEachFunction(int slot)158*e1eccf28SAndroid Build Coastguard Worker ForEachFunc_t getForEachFunction(int slot) const { return mForEachFunctions[slot]; } getForEachSignature(int slot)159*e1eccf28SAndroid Build Coastguard Worker uint32_t getForEachSignature(int slot) const { return mForEachSignatures[slot]; } 160*e1eccf28SAndroid Build Coastguard Worker getReduceDescription(int slot)161*e1eccf28SAndroid Build Coastguard Worker const ReduceDescription* getReduceDescription(int slot) const { 162*e1eccf28SAndroid Build Coastguard Worker return &mReduceDescriptions[slot]; 163*e1eccf28SAndroid Build Coastguard Worker } 164*e1eccf28SAndroid Build Coastguard Worker getPragmaKeys()165*e1eccf28SAndroid Build Coastguard Worker const char ** getPragmaKeys() const { return mPragmaKeys; } getPragmaValues()166*e1eccf28SAndroid Build Coastguard Worker const char ** getPragmaValues() const { return mPragmaValues; } 167*e1eccf28SAndroid Build Coastguard Worker getGlobalName(int i)168*e1eccf28SAndroid Build Coastguard Worker const char* getGlobalName(int i) const { 169*e1eccf28SAndroid Build Coastguard Worker if (i < mGlobalEntries) { 170*e1eccf28SAndroid Build Coastguard Worker return mGlobalNames[i]; 171*e1eccf28SAndroid Build Coastguard Worker } else { 172*e1eccf28SAndroid Build Coastguard Worker return nullptr; 173*e1eccf28SAndroid Build Coastguard Worker } 174*e1eccf28SAndroid Build Coastguard Worker } getGlobalAddress(int i)175*e1eccf28SAndroid Build Coastguard Worker const void* getGlobalAddress(int i) const { 176*e1eccf28SAndroid Build Coastguard Worker if (i < mGlobalEntries) { 177*e1eccf28SAndroid Build Coastguard Worker return mGlobalAddresses[i]; 178*e1eccf28SAndroid Build Coastguard Worker } else { 179*e1eccf28SAndroid Build Coastguard Worker return nullptr; 180*e1eccf28SAndroid Build Coastguard Worker } 181*e1eccf28SAndroid Build Coastguard Worker } getGlobalSize(int i)182*e1eccf28SAndroid Build Coastguard Worker size_t getGlobalSize(int i) const { 183*e1eccf28SAndroid Build Coastguard Worker if (i < mGlobalEntries) { 184*e1eccf28SAndroid Build Coastguard Worker return mGlobalSizes[i]; 185*e1eccf28SAndroid Build Coastguard Worker } else { 186*e1eccf28SAndroid Build Coastguard Worker return 0; 187*e1eccf28SAndroid Build Coastguard Worker } 188*e1eccf28SAndroid Build Coastguard Worker } getGlobalProperties(int i)189*e1eccf28SAndroid Build Coastguard Worker uint32_t getGlobalProperties(int i) const { 190*e1eccf28SAndroid Build Coastguard Worker if (i < mGlobalEntries) { 191*e1eccf28SAndroid Build Coastguard Worker return mGlobalProperties[i]; 192*e1eccf28SAndroid Build Coastguard Worker } else { 193*e1eccf28SAndroid Build Coastguard Worker return 0; 194*e1eccf28SAndroid Build Coastguard Worker } 195*e1eccf28SAndroid Build Coastguard Worker } getGlobalEntries()196*e1eccf28SAndroid Build Coastguard Worker int getGlobalEntries() const { return mGlobalEntries; } 197*e1eccf28SAndroid Build Coastguard Worker getThreadable()198*e1eccf28SAndroid Build Coastguard Worker bool getThreadable() const { return mIsThreadable; } 199*e1eccf28SAndroid Build Coastguard Worker getBuildChecksum()200*e1eccf28SAndroid Build Coastguard Worker uint32_t getBuildChecksum() const { return mBuildChecksum; } 201*e1eccf28SAndroid Build Coastguard Worker 202*e1eccf28SAndroid Build Coastguard Worker bool dumpGlobalInfo() const; 203*e1eccf28SAndroid Build Coastguard Worker 204*e1eccf28SAndroid Build Coastguard Worker private: 205*e1eccf28SAndroid Build Coastguard Worker void** mFieldAddress; 206*e1eccf28SAndroid Build Coastguard Worker bool* mFieldIsObject; 207*e1eccf28SAndroid Build Coastguard Worker const char* const * mFieldName; 208*e1eccf28SAndroid Build Coastguard Worker size_t mExportedVarCount; 209*e1eccf28SAndroid Build Coastguard Worker 210*e1eccf28SAndroid Build Coastguard Worker InvokeFunc_t* mInvokeFunctions; 211*e1eccf28SAndroid Build Coastguard Worker size_t mFuncCount; 212*e1eccf28SAndroid Build Coastguard Worker 213*e1eccf28SAndroid Build Coastguard Worker ForEachFunc_t* mForEachFunctions; 214*e1eccf28SAndroid Build Coastguard Worker uint32_t* mForEachSignatures; 215*e1eccf28SAndroid Build Coastguard Worker size_t mForEachCount; 216*e1eccf28SAndroid Build Coastguard Worker 217*e1eccf28SAndroid Build Coastguard Worker ReduceDescription* mReduceDescriptions; 218*e1eccf28SAndroid Build Coastguard Worker size_t mReduceCount; 219*e1eccf28SAndroid Build Coastguard Worker 220*e1eccf28SAndroid Build Coastguard Worker const char ** mPragmaKeys; 221*e1eccf28SAndroid Build Coastguard Worker const char ** mPragmaValues; 222*e1eccf28SAndroid Build Coastguard Worker size_t mPragmaCount; 223*e1eccf28SAndroid Build Coastguard Worker 224*e1eccf28SAndroid Build Coastguard Worker const char ** mGlobalNames; 225*e1eccf28SAndroid Build Coastguard Worker const void ** mGlobalAddresses; 226*e1eccf28SAndroid Build Coastguard Worker const size_t * mGlobalSizes; 227*e1eccf28SAndroid Build Coastguard Worker const uint32_t * mGlobalProperties; 228*e1eccf28SAndroid Build Coastguard Worker int mGlobalEntries; 229*e1eccf28SAndroid Build Coastguard Worker 230*e1eccf28SAndroid Build Coastguard Worker bool mIsThreadable; 231*e1eccf28SAndroid Build Coastguard Worker uint32_t mBuildChecksum; 232*e1eccf28SAndroid Build Coastguard Worker }; 233*e1eccf28SAndroid Build Coastguard Worker 234*e1eccf28SAndroid Build Coastguard Worker } // namespace renderscript 235*e1eccf28SAndroid Build Coastguard Worker } // namespace android 236*e1eccf28SAndroid Build Coastguard Worker 237*e1eccf28SAndroid Build Coastguard Worker #endif // ANDROID_RENDERSCRIPT_EXECUTABLE_H 238