summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cpu_ref/rsCpuExecutable.cpp41
-rw-r--r--cpu_ref/rsCpuExecutable.h14
-rw-r--r--cpu_ref/rsCpuScript.cpp38
-rw-r--r--cpu_ref/rsCpuScript.h22
-rw-r--r--cpu_ref/rsCpuScriptGroup2.cpp20
-rw-r--r--driver/rsdRuntimeStubs.cpp29
-rw-r--r--driver/runtime/rs_allocation.c50
-rw-r--r--rsHidlAdaptation.cpp2
-rw-r--r--tests/java_api/HealingBrush/src/rs/example/android/com/healingbrush/FindRegion.java6
-rw-r--r--tests/java_api/HealingBrush/src/rs/example/android/com/healingbrush/find_region.rs6
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;
}