diff options
-rw-r--r-- | cpu_ref/rsCpuExecutable.cpp | 41 | ||||
-rw-r--r-- | cpu_ref/rsCpuExecutable.h | 14 | ||||
-rw-r--r-- | cpu_ref/rsCpuScript.cpp | 38 | ||||
-rw-r--r-- | cpu_ref/rsCpuScript.h | 22 | ||||
-rw-r--r-- | cpu_ref/rsCpuScriptGroup2.cpp | 20 | ||||
-rw-r--r-- | driver/rsdRuntimeStubs.cpp | 29 | ||||
-rw-r--r-- | driver/runtime/rs_allocation.c | 50 | ||||
-rw-r--r-- | rsHidlAdaptation.cpp | 2 | ||||
-rw-r--r-- | tests/java_api/HealingBrush/src/rs/example/android/com/healingbrush/FindRegion.java | 6 | ||||
-rw-r--r-- | tests/java_api/HealingBrush/src/rs/example/android/com/healingbrush/find_region.rs | 6 |
10 files changed, 164 insertions, 64 deletions
diff --git a/cpu_ref/rsCpuExecutable.cpp b/cpu_ref/rsCpuExecutable.cpp index a79f671a..83ef7574 100644 --- a/cpu_ref/rsCpuExecutable.cpp +++ b/cpu_ref/rsCpuExecutable.cpp @@ -60,7 +60,8 @@ static int copyFile(const char *dstFile, const char *srcFile) { } static std::string findSharedObjectName(const char *cacheDir, - const char *resName) { + const char *resName, + const bool reuse = true) { std::string scriptSOName(cacheDir); #if defined(RS_COMPATIBILITY_LIB) && !defined(__LP64__) size_t cutPos = scriptSOName.rfind("cache"); @@ -74,6 +75,20 @@ static std::string findSharedObjectName(const char *cacheDir, scriptSOName.append("/librs."); #endif // RS_COMPATIBILITY_LIB scriptSOName.append(resName); + if (!reuse) { + // If the generated shared library is not reused, e.g., with a debug + // context or forced by a system property, multiple threads may read + // and write the shared library at the same time. To avoid the race + // on the generated shared library, delete it before finishing script + // initialization. To avoid deleting a file generated by a regular + // context, use a special suffix here. + // Because the script initialization is guarded by a lock from the Java + // API, it is safe to name this file with a consistent name and suffix + // and delete it after loading. The same lock has also prevented write- + // write races on the .so during script initialization even if reuse is + // true. + scriptSOName.append("#delete_after_load"); + } scriptSOName.append(".so"); return scriptSOName; @@ -88,8 +103,13 @@ const char* SharedLibraryUtils::RS_CACHE_DIR = "com.android.renderscript.cache"; bool SharedLibraryUtils::createSharedLibrary(const char *driverName, const char *cacheDir, - const char *resName) { - std::string sharedLibName = findSharedObjectName(cacheDir, resName); + const char *resName, + const bool reuse, + std::string *fullPath) { + std::string sharedLibName = findSharedObjectName(cacheDir, resName, reuse); + if (fullPath) { + *fullPath = sharedLibName; + } std::string objFileName = cacheDir; objFileName.append("/"); objFileName.append(resName); @@ -125,6 +145,21 @@ bool SharedLibraryUtils::createSharedLibrary(const char *driverName, const char* RsdCpuScriptImpl::BCC_EXE_PATH = "/system/bin/bcc"; +void* SharedLibraryUtils::loadAndDeleteSharedLibrary(const char *fullPath) { + void *loaded = dlopen(fullPath, RTLD_NOW | RTLD_LOCAL); + if (loaded == nullptr) { + ALOGE("Unable to open shared library (%s): %s", fullPath, dlerror()); + return nullptr; + } + + int r = unlink(fullPath); + if (r != 0) { + ALOGE("Could not unlink copy %s", fullPath); + return nullptr; + } + return loaded; +} + void* SharedLibraryUtils::loadSharedLibrary(const char *cacheDir, const char *resName, const char *nativeLibDir, diff --git a/cpu_ref/rsCpuExecutable.h b/cpu_ref/rsCpuExecutable.h index ee58e377..82cf7742 100644 --- a/cpu_ref/rsCpuExecutable.h +++ b/cpu_ref/rsCpuExecutable.h @@ -31,9 +31,14 @@ class Context; class SharedLibraryUtils { public: #ifndef RS_COMPATIBILITY_LIB + // Creates a shared library in cacheDir for the bitcode named resName. + // If reuse is false and SOPath is not nullptr, saves the filename + // used for the shared library in SOPath. static bool createSharedLibrary(const char* driverName, const char* cacheDir, - const char* resName); + const char* resName, + const bool reuse = true, + std::string *SOPath = nullptr); #endif // Load the shared library referred to by cacheDir and resName. If we have @@ -48,6 +53,13 @@ public: const char *nativeLibDir = nullptr, bool *alreadyLoaded = nullptr); + // Load the shared library referred to by fullPath, and delete it right + // after loading it. Files loaded by this function are only used once, e.g., + // shared libraries generated for scripts in a debug context. Deleting them + // is OK in this case since the shared libraries have already been dlopened. + // Deletion is also required because such files are not intended for reuse. + static void* loadAndDeleteSharedLibrary(const char *fullPath); + // Create a len length string containing random characters from [A-Za-z0-9]. static std::string getRandomString(size_t len); diff --git a/cpu_ref/rsCpuScript.cpp b/cpu_ref/rsCpuScript.cpp index 545e92f3..dec9ab29 100644 --- a/cpu_ref/rsCpuScript.cpp +++ b/cpu_ref/rsCpuScript.cpp @@ -57,24 +57,6 @@ static bool allocationLODIsNull(const android::renderscript::Allocation *alloc) #ifndef RS_COMPATIBILITY_LIB -static bool is_force_recompile() { - char buf[PROP_VALUE_MAX]; - - // Re-compile if floating point precision has been overridden. - android::renderscript::property_get("debug.rs.precision", buf, ""); - if (buf[0] != '\0') { - return true; - } - - // Re-compile if debug.rs.forcerecompile is set. - android::renderscript::property_get("debug.rs.forcerecompile", buf, "0"); - if ((::strcmp(buf, "1") == 0) || (::strcmp(buf, "true") == 0)) { - return true; - } else { - return false; - } -} - static void setCompileArguments(std::vector<const char*>* args, const std::string& bcFileName, const char* cacheDir, const char* resName, @@ -381,7 +363,8 @@ bool RsdCpuScriptImpl::init(char const *resName, char const *cacheDir, compileArguments.push_back(checksumStr.c_str()); compileArguments.push_back(nullptr); - if (!is_force_recompile() && !useRSDebugContext) { + const bool reuse = !is_force_recompile() && !useRSDebugContext; + if (reuse) { mScriptSO = SharedLibraryUtils::loadSharedLibrary(cacheDir, resName); // Read RS info from the shared object to detect checksum mismatch @@ -391,8 +374,8 @@ bool RsdCpuScriptImpl::init(char const *resName, char const *cacheDir, } } - // If we can't, it's either not there or out of date. We compile the bit code and try loading - // again. + // If reuse is desired and we can't, it's either not there or out of date. + // We compile the bit code and try loading again. if (mScriptSO == nullptr) { if (!compileBitcode(bcFileName, (const char*)bitcode, bitcodeSize, compileArguments)) @@ -402,14 +385,21 @@ bool RsdCpuScriptImpl::init(char const *resName, char const *cacheDir, return false; } - if (!SharedLibraryUtils::createSharedLibrary(mCtx->getContext()->getDriverName(), - cacheDir, resName)) { + std::string SOPath; + + if (!SharedLibraryUtils::createSharedLibrary( + mCtx->getContext()->getDriverName(), cacheDir, resName, reuse, + &SOPath)) { ALOGE("Linker: Failed to link object file '%s'", resName); mCtx->unlockMutex(); return false; } - mScriptSO = SharedLibraryUtils::loadSharedLibrary(cacheDir, resName); + if (reuse) { + mScriptSO = SharedLibraryUtils::loadSharedLibrary(cacheDir, resName); + } else { + mScriptSO = SharedLibraryUtils::loadAndDeleteSharedLibrary(SOPath.c_str()); + } if (mScriptSO == nullptr) { ALOGE("Unable to load '%s'", resName); mCtx->unlockMutex(); diff --git a/cpu_ref/rsCpuScript.h b/cpu_ref/rsCpuScript.h index 1814d5ff..dc96f8ba 100644 --- a/cpu_ref/rsCpuScript.h +++ b/cpu_ref/rsCpuScript.h @@ -171,4 +171,26 @@ uint32_t constructBuildChecksum(uint8_t const *bitcode, size_t bitcodeSize, } // namespace android +namespace { + +inline bool is_force_recompile() { + char buf[PROP_VALUE_MAX]; + + // Re-compile if floating point precision has been overridden. + android::renderscript::property_get("debug.rs.precision", buf, ""); + if (buf[0] != '\0') { + return true; + } + + // Re-compile if debug.rs.forcerecompile is set. + android::renderscript::property_get("debug.rs.forcerecompile", buf, "0"); + if ((::strcmp(buf, "1") == 0) || (::strcmp(buf, "true") == 0)) { + return true; + } else { + return false; + } +} + +} // anonymous namespace + #endif // RSD_CPU_SCRIPT_H diff --git a/cpu_ref/rsCpuScriptGroup2.cpp b/cpu_ref/rsCpuScriptGroup2.cpp index 11393ff4..d624e623 100644 --- a/cpu_ref/rsCpuScriptGroup2.cpp +++ b/cpu_ref/rsCpuScriptGroup2.cpp @@ -473,8 +473,13 @@ void CpuScriptGroup2Impl::compile(const char* cacheDir) { bool alreadyLoaded = false; std::string cloneName; - mScriptObj = SharedLibraryUtils::loadSharedLibrary(cacheDir, resName, nullptr, - &alreadyLoaded); + const bool useRSDebugContext = + (mCpuRefImpl->getContext()->getContextType() == RS_CONTEXT_TYPE_DEBUG); + const bool reuse = !is_force_recompile() && !useRSDebugContext; + if (reuse) { + mScriptObj = SharedLibraryUtils::loadSharedLibrary(cacheDir, resName, nullptr, + &alreadyLoaded); + } if (mScriptObj != nullptr) { // A shared library named resName is found in code cache directory // cacheDir, and loaded with the handle stored in mScriptObj. @@ -528,8 +533,11 @@ void CpuScriptGroup2Impl::compile(const char* cacheDir) { // Create and load the shared lib //===--------------------------------------------------------------------===// + std::string SOPath; + if (!SharedLibraryUtils::createSharedLibrary( - getCpuRefImpl()->getContext()->getDriverName(), cacheDir, resName)) { + getCpuRefImpl()->getContext()->getDriverName(), cacheDir, resName, + reuse, &SOPath)) { ALOGE("Failed to link object file '%s'", resName); unlink(objFilePath.c_str()); return; @@ -537,7 +545,11 @@ void CpuScriptGroup2Impl::compile(const char* cacheDir) { unlink(objFilePath.c_str()); - mScriptObj = SharedLibraryUtils::loadSharedLibrary(cacheDir, resName); + if (reuse) { + mScriptObj = SharedLibraryUtils::loadSharedLibrary(cacheDir, resName); + } else { + mScriptObj = SharedLibraryUtils::loadAndDeleteSharedLibrary(SOPath.c_str()); + } if (mScriptObj == nullptr) { ALOGE("Unable to load '%s'", resName); return; diff --git a/driver/rsdRuntimeStubs.cpp b/driver/rsdRuntimeStubs.cpp index 74c79182..e96904a5 100644 --- a/driver/rsdRuntimeStubs.cpp +++ b/driver/rsdRuntimeStubs.cpp @@ -589,7 +589,36 @@ ELEMENT_AT(uint, RS_TYPE_UNSIGNED_32, 1) ELEMENT_AT(uint2, RS_TYPE_UNSIGNED_32, 2) ELEMENT_AT(uint3, RS_TYPE_UNSIGNED_32, 3) ELEMENT_AT(uint4, RS_TYPE_UNSIGNED_32, 4) +#ifdef __LP64__ ELEMENT_AT(long, RS_TYPE_SIGNED_64, 1) +#else +/* the long versions need special treatment; the long * argument has to be + * kept so the signatures match, but the actual accesses have to be done in + * int64_t * to be consistent with the script ABI. + */ +void rsSetElementAt_long(::rs_allocation a, const long *val, uint32_t x, uint32_t y, uint32_t z) { + void *r = ElementAt((Allocation *)a.p, RS_TYPE_SIGNED_64, 1, x, y, z); + if (r != nullptr) ((int64_t *)r)[0] = *((int64_t *)val); + else ALOGE("Error from %s", __PRETTY_FUNCTION__); +} +void rsSetElementAt_long(::rs_allocation a, const long *val, uint32_t x, uint32_t y) { + rsSetElementAt_long(a, val, x, y, 0); +} +void rsSetElementAt_long(::rs_allocation a, const long *val, uint32_t x) { + rsSetElementAt_long(a, val, x, 0, 0); +} +void rsGetElementAt_long(::rs_allocation a, long *val, uint32_t x, uint32_t y, uint32_t z) { /*NOLINT*/ + void *r = ElementAt((Allocation *)a.p, RS_TYPE_SIGNED_64, 1, x, y, z); + if (r != nullptr) *((int64_t*)val) = ((int64_t *)r)[0]; + else ALOGE("Error from %s", __PRETTY_FUNCTION__); +} +void rsGetElementAt_long(::rs_allocation a, long *val, uint32_t x, uint32_t y) { /*NOLINT*/ + rsGetElementAt_long(a, val, x, y, 0); +} +void rsGetElementAt_long(::rs_allocation a, long *val, uint32_t x) { /*NOLINT*/ + rsGetElementAt_long(a, val, x, 0, 0); +} +#endif ELEMENT_AT(long2, RS_TYPE_SIGNED_64, 2) ELEMENT_AT(long3, RS_TYPE_SIGNED_64, 3) ELEMENT_AT(long4, RS_TYPE_SIGNED_64, 4) diff --git a/driver/runtime/rs_allocation.c b/driver/runtime/rs_allocation.c index a20d99ab..2163e77c 100644 --- a/driver/runtime/rs_allocation.c +++ b/driver/runtime/rs_allocation.c @@ -61,6 +61,32 @@ static void local_memcpy(void* dst, const void* src, size_t size) { } } +#ifndef RS_DEBUG_RUNTIME +uint8_t* +rsOffset(rs_allocation a, uint32_t sizeOf, uint32_t x, uint32_t y, + uint32_t z) { + Allocation_t *alloc = (Allocation_t *)a.p; + uint8_t *p = (uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr; + const uint32_t stride = (uint32_t)alloc->mHal.drvState.lod[0].stride; + const uint32_t dimY = alloc->mHal.drvState.lod[0].dimY; + uint8_t *dp = &p[(sizeOf * x) + (y * stride) + + (z * stride * dimY)]; + return dp; +} +#endif + +uint8_t* +rsOffsetNs(rs_allocation a, uint32_t x, uint32_t y, uint32_t z) { + Allocation_t *alloc = (Allocation_t *)a.p; + uint8_t *p = (uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr; + const uint32_t stride = alloc->mHal.drvState.lod[0].stride; + const uint32_t dimY = alloc->mHal.drvState.lod[0].dimY; + const uint32_t sizeOf = alloc->mHal.state.elementSizeBytes;; + uint8_t *dp = &p[(sizeOf * x) + (y * stride) + + (z * stride * dimY)]; + return dp; +} + #ifdef RS_DEBUG_RUNTIME #define ELEMENT_AT(T) \ extern void __attribute__((overloadable)) \ @@ -108,30 +134,6 @@ static void local_memcpy(void* dst, const void* src, size_t size) { } #else // NOT RS_DEBUG_RUNTIME -uint8_t* -rsOffset(rs_allocation a, uint32_t sizeOf, uint32_t x, uint32_t y, - uint32_t z) { - Allocation_t *alloc = (Allocation_t *)a.p; - uint8_t *p = (uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr; - const uint32_t stride = (uint32_t)alloc->mHal.drvState.lod[0].stride; - const uint32_t dimY = alloc->mHal.drvState.lod[0].dimY; - uint8_t *dp = &p[(sizeOf * x) + (y * stride) + - (z * stride * dimY)]; - return dp; -} - -uint8_t* -rsOffsetNs(rs_allocation a, uint32_t x, uint32_t y, uint32_t z) { - Allocation_t *alloc = (Allocation_t *)a.p; - uint8_t *p = (uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr; - const uint32_t stride = alloc->mHal.drvState.lod[0].stride; - const uint32_t dimY = alloc->mHal.drvState.lod[0].dimY; - const uint32_t sizeOf = alloc->mHal.state.elementSizeBytes;; - uint8_t *dp = &p[(sizeOf * x) + (y * stride) + - (z * stride * dimY)]; - return dp; -} - // The functions rsSetElementAtImpl_T and rsGetElementAtImpl_T are implemented in bitcode // in ll32/allocation.ll and ll64/allocation.ll. To be able to provide debug info for // these functions define them here instead, if we are linking with the debug library. diff --git a/rsHidlAdaptation.cpp b/rsHidlAdaptation.cpp index ead47542..e6a28abc 100644 --- a/rsHidlAdaptation.cpp +++ b/rsHidlAdaptation.cpp @@ -919,8 +919,6 @@ RsScript RsHidlAdaptation::ScriptCCreate (RsContext context, const char *cacheDir, size_t cacheDir_length, const char *text, size_t text_length) { - ALOGD("resName: %s, cacheDir: %s, text: %s", resName, cacheDir, text); - hidl_vec<uint8_t> _text; _text.setToExternal(reinterpret_cast<uint8_t *>(const_cast<char *>(text)), text_length); uint64_t scriptc = GetIContextHandle(context)->scriptCCreate(hidl_string(resName), hidl_string(cacheDir), _text); diff --git a/tests/java_api/HealingBrush/src/rs/example/android/com/healingbrush/FindRegion.java b/tests/java_api/HealingBrush/src/rs/example/android/com/healingbrush/FindRegion.java index 9ac9cb4e..7f2f3aaf 100644 --- a/tests/java_api/HealingBrush/src/rs/example/android/com/healingbrush/FindRegion.java +++ b/tests/java_api/HealingBrush/src/rs/example/android/com/healingbrush/FindRegion.java @@ -86,9 +86,9 @@ public class FindRegion { Allocation border_coords; Allocation border_values; - Type.Builder builderU32_2 = new Type.Builder(mRs, Element.U32_2(mRs)); - builderU32_2.setX(mPointsXY.length / 2); - border_coords = Allocation.createTyped(mRs, builderU32_2.create()); + Type.Builder builderI32_2 = new Type.Builder(mRs, Element.I32_2(mRs)); + builderI32_2.setX(mPointsXY.length / 2); + border_coords = Allocation.createTyped(mRs, builderI32_2.create()); Allocation border_coords_float; border_coords_float = Allocation.createSized(mRs, Element.F32_2(mRs), mPointsXY.length / 2); diff --git a/tests/java_api/HealingBrush/src/rs/example/android/com/healingbrush/find_region.rs b/tests/java_api/HealingBrush/src/rs/example/android/com/healingbrush/find_region.rs index 38821d8c..249bd9a0 100644 --- a/tests/java_api/HealingBrush/src/rs/example/android/com/healingbrush/find_region.rs +++ b/tests/java_api/HealingBrush/src/rs/example/android/com/healingbrush/find_region.rs @@ -87,12 +87,12 @@ void calcBounds(rs_allocation xy, rs_allocation rect) { } -float3 __attribute__((kernel))extractBorder(uint2 in) { +float3 __attribute__((kernel))extractBorder(int2 in) { return convert_float3(rsGetElementAt_uchar4(image, in.x, in.y).xyz); } -uint2 __attribute__((kernel)) toInt(float2 in) { - uint2 out = {(int)in.x, (int) in.y}; +int2 __attribute__((kernel)) toInt(float2 in) { + int2 out = {(int)in.x, (int) in.y}; return out; } |