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