12abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni/*
22abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni * Copyright (C) 2015 The Android Open Source Project
32abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni *
42abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni * Licensed under the Apache License, Version 2.0 (the "License");
52abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni * you may not use this file except in compliance with the License.
62abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni * You may obtain a copy of the License at
72abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni *
82abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni *      http://www.apache.org/licenses/LICENSE-2.0
92abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni *
102abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni * Unless required by applicable law or agreed to in writing, software
112abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni * distributed under the License is distributed on an "AS IS" BASIS,
122abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni * See the License for the specific language governing permissions and
142abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni * limitations under the License.
152abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni */
162abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
172abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#ifndef ANDROID_RENDERSCRIPT_EXECUTABLE_H
182abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#define ANDROID_RENDERSCRIPT_EXECUTABLE_H
192abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
202abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#include <stdlib.h>
212abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
222abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#include "rsCpuScript.h"
232abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
242abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ninamespace android {
252abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ninamespace renderscript {
262abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
272abfcc6d129fe3defddef4540aa95cc445c03a7aYang Niclass Context;
282abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
292abfcc6d129fe3defddef4540aa95cc445c03a7aYang Niclass SharedLibraryUtils {
302abfcc6d129fe3defddef4540aa95cc445c03a7aYang Nipublic:
312abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#ifndef RS_COMPATIBILITY_LIB
324c368af7e705f0bcb77fa99495b2e33ef20d2699Stephen Hines    static bool createSharedLibrary(const char* driverName,
334c368af7e705f0bcb77fa99495b2e33ef20d2699Stephen Hines                                    const char* cacheDir,
344c368af7e705f0bcb77fa99495b2e33ef20d2699Stephen Hines                                    const char* resName);
352abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#endif
362abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
372abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    // Load the shared library referred to by cacheDir and resName. If we have
382abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    // already loaded this library, we instead create a new copy (in the
392abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    // cache dir) and then load that. We then immediately destroy the copy.
402abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    // This is required behavior to implement script instancing for the support
412abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    // library, since shared objects are loaded and de-duped by name only.
422abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
432abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    // For 64bit RS Support Lib, the shared lib path cannot be constructed from
442abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    // cacheDir, so nativeLibDir is needed to load shared libs.
452abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    static void* loadSharedLibrary(const char *cacheDir, const char *resName,
461efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni                                   const char *nativeLibDir = nullptr,
471efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni                                   bool *alreadyLoaded = nullptr);
481efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni
491efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni    // Create a len length string containing random characters from [A-Za-z0-9].
501efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni    static String8 getRandomString(size_t len);
512abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
522abfcc6d129fe3defddef4540aa95cc445c03a7aYang Niprivate:
532abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    // Attempt to load the shared library from origName, but then fall back to
542abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    // creating a copy of the shared library if necessary (to ensure instancing).
552abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    // This function returns the dlopen()-ed handle if successful.
562abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    static void *loadSOHelper(const char *origName, const char *cacheDir,
571efae29f4bbe6c165caf6dfc4b89cf8a5f8c469bYang Ni                              const char *resName, bool* alreadyLoaded = nullptr);
582abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
592abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    static const char* LD_EXE_PATH;
602abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    static const char* RS_CACHE_DIR;
612abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni};
622abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
632abfcc6d129fe3defddef4540aa95cc445c03a7aYang Niclass ScriptExecutable {
642abfcc6d129fe3defddef4540aa95cc445c03a7aYang Nipublic:
655e48002cc4a11e9ce63852a77488cfb9f6765c2bYang Ni    ScriptExecutable(void** fieldAddress, bool* fieldIsObject,
66062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni                     const char* const * fieldName, size_t varCount,
672abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni                     InvokeFunc_t* invokeFunctions, size_t funcCount,
682abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni                     ForEachFunc_t* forEachFunctions, uint32_t* forEachSignatures,
692abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni                     size_t forEachCount,
70ae2ec3febedfc29376b9104413fb4042028f1265David Gross                     ReduceDescription *reduceDescriptions, size_t reduceCount,
71062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni                     const char** pragmaKeys, const char** pragmaValues,
722abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni                     size_t pragmaCount,
738409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines                     const char **globalNames, const void **globalAddresses,
745aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines                     const size_t *globalSizes,
755aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines                     const uint32_t *globalProperties, size_t globalEntries,
76cb17015fed6b11a5028f31cc804a3847e379945dYang Ni                     bool isThreadable, uint32_t buildChecksum) :
772abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni        mFieldAddress(fieldAddress), mFieldIsObject(fieldIsObject),
78062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni        mFieldName(fieldName), mExportedVarCount(varCount),
79062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni        mInvokeFunctions(invokeFunctions), mFuncCount(funcCount),
80062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni        mForEachFunctions(forEachFunctions), mForEachSignatures(forEachSignatures),
81062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni        mForEachCount(forEachCount),
82ae2ec3febedfc29376b9104413fb4042028f1265David Gross        mReduceDescriptions(reduceDescriptions), mReduceCount(reduceCount),
83062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni        mPragmaKeys(pragmaKeys), mPragmaValues(pragmaValues),
848409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines        mPragmaCount(pragmaCount), mGlobalNames(globalNames),
858409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines        mGlobalAddresses(globalAddresses), mGlobalSizes(globalSizes),
865aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines        mGlobalProperties(globalProperties), mGlobalEntries(globalEntries),
875e48002cc4a11e9ce63852a77488cfb9f6765c2bYang Ni        mIsThreadable(isThreadable), mBuildChecksum(buildChecksum) {
882abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    }
892abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
902abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    ~ScriptExecutable() {
912abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni        for (size_t i = 0; i < mExportedVarCount; ++i) {
922abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni            if (mFieldIsObject[i]) {
932abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni                if (mFieldAddress[i] != nullptr) {
942abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni                    rs_object_base *obj_addr =
952abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni                            reinterpret_cast<rs_object_base *>(mFieldAddress[i]);
965e48002cc4a11e9ce63852a77488cfb9f6765c2bYang Ni                    rsrClearObject(obj_addr);
972abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni                }
982abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni            }
992abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni        }
1002abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
1012abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni        for (size_t i = 0; i < mPragmaCount; ++i) {
1022abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni            delete [] mPragmaKeys[i];
1032abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni            delete [] mPragmaValues[i];
1042abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni        }
1052abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni        delete[] mPragmaValues;
1062abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni        delete[] mPragmaKeys;
107062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni
108ae2ec3febedfc29376b9104413fb4042028f1265David Gross        delete[] mReduceDescriptions;
1096c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
1102abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni        delete[] mForEachSignatures;
1112abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni        delete[] mForEachFunctions;
112062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni
1132abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni        delete[] mInvokeFunctions;
114062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni
115062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni        for (size_t i = 0; i < mExportedVarCount; i++) {
116062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni            delete[] mFieldName[i];
117062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni        }
118062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni        delete[] mFieldName;
1192abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni        delete[] mFieldIsObject;
1202abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni        delete[] mFieldAddress;
1212abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    }
1222abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
123cb17015fed6b11a5028f31cc804a3847e379945dYang Ni    // Create an ScriptExecutable object from a shared object.
124cb17015fed6b11a5028f31cc804a3847e379945dYang Ni    // If expectedChecksum is not zero, it will be compared to the checksum
125cb17015fed6b11a5028f31cc804a3847e379945dYang Ni    // embedded in the shared object. A mismatch will cause a failure.
126cb17015fed6b11a5028f31cc804a3847e379945dYang Ni    // If succeeded, returns the new object. Otherwise, returns nullptr.
1272abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    static ScriptExecutable*
1285e48002cc4a11e9ce63852a77488cfb9f6765c2bYang Ni            createFromSharedObject(void* sharedObj,
129cb17015fed6b11a5028f31cc804a3847e379945dYang Ni                                   uint32_t expectedChecksum = 0);
1302abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
1312abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    size_t getExportedVariableCount() const { return mExportedVarCount; }
1322abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    size_t getExportedFunctionCount() const { return mFuncCount; }
1332abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    size_t getExportedForEachCount() const { return mForEachCount; }
13414ce007a633b10e3b9a3fae29d8f53a7e8c9b59fMatt Wala    size_t getExportedReduceCount() const { return mReduceCount; }
1352abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    size_t getPragmaCount() const { return mPragmaCount; }
1362abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
1372abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    void* getFieldAddress(int slot) const { return mFieldAddress[slot]; }
138062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni    void* getFieldAddress(const char* name) const;
1392abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    bool getFieldIsObject(int slot) const { return mFieldIsObject[slot]; }
140062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni    const char* getFieldName(int slot) const { return mFieldName[slot]; }
141062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni
1422abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    InvokeFunc_t getInvokeFunction(int slot) const { return mInvokeFunctions[slot]; }
143062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni
1442abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    ForEachFunc_t getForEachFunction(int slot) const { return mForEachFunctions[slot]; }
1452abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    uint32_t getForEachSignature(int slot) const { return mForEachSignatures[slot]; }
1462abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
147ae2ec3febedfc29376b9104413fb4042028f1265David Gross    const ReduceDescription* getReduceDescription(int slot) const {
148ae2ec3febedfc29376b9104413fb4042028f1265David Gross        return &mReduceDescriptions[slot];
1496c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    }
1506c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
1512abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    const char ** getPragmaKeys() const { return mPragmaKeys; }
1522abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    const char ** getPragmaValues() const { return mPragmaValues; }
1532abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
1548409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines    const char* getGlobalName(int i) const {
1558409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines        if (i < mGlobalEntries) {
1568409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines            return mGlobalNames[i];
1578409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines        } else {
1588409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines            return nullptr;
1598409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines        }
1608409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines    }
1618409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines    const void* getGlobalAddress(int i) const {
1628409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines        if (i < mGlobalEntries) {
1638409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines            return mGlobalAddresses[i];
1648409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines        } else {
1658409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines            return nullptr;
1668409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines        }
1678409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines    }
1688409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines    size_t getGlobalSize(int i) const {
1698409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines        if (i < mGlobalEntries) {
1708409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines            return mGlobalSizes[i];
1718409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines        } else {
1728409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines            return 0;
1738409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines        }
1748409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines    }
1755aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines    uint32_t getGlobalProperties(int i) const {
1765aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines        if (i < mGlobalEntries) {
1775aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines            return mGlobalProperties[i];
1785aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines        } else {
1795aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines            return 0;
1805aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines        }
1815aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines    }
1828409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines    int getGlobalEntries() const { return mGlobalEntries; }
1838409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines
1842abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    bool getThreadable() const { return mIsThreadable; }
1852abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
186cb17015fed6b11a5028f31cc804a3847e379945dYang Ni    uint32_t getBuildChecksum() const { return mBuildChecksum; }
187aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar
1888409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines    bool dumpGlobalInfo() const;
1898409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines
1902abfcc6d129fe3defddef4540aa95cc445c03a7aYang Niprivate:
1912abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    void** mFieldAddress;
1922abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    bool* mFieldIsObject;
193062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni    const char* const * mFieldName;
1942abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    size_t mExportedVarCount;
1952abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
1962abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    InvokeFunc_t* mInvokeFunctions;
1972abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    size_t mFuncCount;
1982abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
1992abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    ForEachFunc_t* mForEachFunctions;
2002abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    uint32_t* mForEachSignatures;
2012abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    size_t mForEachCount;
2022abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
203ae2ec3febedfc29376b9104413fb4042028f1265David Gross    ReduceDescription* mReduceDescriptions;
20414ce007a633b10e3b9a3fae29d8f53a7e8c9b59fMatt Wala    size_t mReduceCount;
20514ce007a633b10e3b9a3fae29d8f53a7e8c9b59fMatt Wala
2062abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    const char ** mPragmaKeys;
2072abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    const char ** mPragmaValues;
2082abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    size_t mPragmaCount;
2092abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
2108409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines    const char ** mGlobalNames;
2118409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines    const void ** mGlobalAddresses;
2128409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines    const size_t * mGlobalSizes;
2135aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines    const uint32_t * mGlobalProperties;
2148409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines    int mGlobalEntries;
2158409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines
2162abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    bool mIsThreadable;
217cb17015fed6b11a5028f31cc804a3847e379945dYang Ni    uint32_t mBuildChecksum;
2182abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni};
2192abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
2202abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni}  // namespace renderscript
2212abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni}  // namespace android
2222abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni
2232abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#endif  // ANDROID_RENDERSCRIPT_EXECUTABLE_H
224