在 RenderScript 中增加计数变量
Increment a count variable in RenderScript
我想使用以下 RenderScript 代码计算位图的像素
RenderScript
文件名:counter.rs
#pragma version(1)
#pragma rs java_package_name(com.mypackage)
#pragma rs_fp_relaxed
uint count; // initialized in Java
void countPixels(uchar4* unused, uint x, uint y) {
rsAtomicInc(&count);
}
Java
Application context = ...; // The application context
RenderScript rs = RenderScript.create(applicationContext);
Bitmap bitmap = ...; // A random bitmap
Allocation allocation = Allocation.createFromBitmap(rs, bitmap);
ScriptC_Counter script = new ScriptC_Counter(rs);
script.set_count(0);
script.forEach_countPixels(allocation);
allocation.syncAll(Allocation.USAGE_SCRIPT);
long count = script.get_count();
错误
这是我收到的错误消息:
ERROR: Address not found for count
问题
- 为什么我的代码不起作用?
- 我该如何解决?
链接
附带说明一下,除非必须,否则在并行计算中使用原子操作通常不是一个好习惯。 RenderScript 实际上为这种应用程序提供了 reduction kernel。也许你可以试试看。
代码有几个问题:
- 应该声明变量 "count" "volatile"
- countPixels 应该是 "void RS_KERNEL countPixels(uchar4 in)"
- script.get_count() 不会为您提供 "count" 的最新值,您必须通过分配取回该值。
如果你必须使用 rsAtomicInc,一个很好的例子实际上是 RenderScript CTS 测试:
这是我的工作解决方案。
RenderScript
文件名:counter.rs
#pragma version(1)
#pragma rs java_package_name(com.mypackage)
#pragma rs_fp_relaxed
int32_t count = 0;
rs_allocation rsAllocationCount;
void countPixels(uchar4* unused, uint x, uint y) {
rsAtomicInc(&count);
rsSetElementAt_int(rsAllocationCount, count, 0);
}
Java
Context context = ...;
RenderScript renderScript = RenderScript.create(context);
Bitmap bitmap = ...; // A random bitmap
Allocation allocationBitmap = Allocation.createFromBitmap(renderScript, bitmap);
Allocation allocationCount = Allocation.createTyped(renderScript, Type.createX(renderScript, Element.I32(renderScript), 1));
ScriptC_Counter script = new ScriptC_Counter(renderScript);
script.set_rsAllocationCount(allocationCount);
script.forEach_countPixels(allocationBitmap);
int[] count = new int[1];
allocationBitmap.syncAll(Allocation.USAGE_SCRIPT);
allocationCount.copyTo(count);
// The count can now be accessed via
count[0];
我想使用以下 RenderScript 代码计算位图的像素
RenderScript
文件名:counter.rs
#pragma version(1)
#pragma rs java_package_name(com.mypackage)
#pragma rs_fp_relaxed
uint count; // initialized in Java
void countPixels(uchar4* unused, uint x, uint y) {
rsAtomicInc(&count);
}
Java
Application context = ...; // The application context
RenderScript rs = RenderScript.create(applicationContext);
Bitmap bitmap = ...; // A random bitmap
Allocation allocation = Allocation.createFromBitmap(rs, bitmap);
ScriptC_Counter script = new ScriptC_Counter(rs);
script.set_count(0);
script.forEach_countPixels(allocation);
allocation.syncAll(Allocation.USAGE_SCRIPT);
long count = script.get_count();
错误
这是我收到的错误消息:
ERROR: Address not found for count
问题
- 为什么我的代码不起作用?
- 我该如何解决?
链接
附带说明一下,除非必须,否则在并行计算中使用原子操作通常不是一个好习惯。 RenderScript 实际上为这种应用程序提供了 reduction kernel。也许你可以试试看。
代码有几个问题:
- 应该声明变量 "count" "volatile"
- countPixels 应该是 "void RS_KERNEL countPixels(uchar4 in)"
- script.get_count() 不会为您提供 "count" 的最新值,您必须通过分配取回该值。
如果你必须使用 rsAtomicInc,一个很好的例子实际上是 RenderScript CTS 测试:
这是我的工作解决方案。
RenderScript
文件名:counter.rs
#pragma version(1)
#pragma rs java_package_name(com.mypackage)
#pragma rs_fp_relaxed
int32_t count = 0;
rs_allocation rsAllocationCount;
void countPixels(uchar4* unused, uint x, uint y) {
rsAtomicInc(&count);
rsSetElementAt_int(rsAllocationCount, count, 0);
}
Java
Context context = ...;
RenderScript renderScript = RenderScript.create(context);
Bitmap bitmap = ...; // A random bitmap
Allocation allocationBitmap = Allocation.createFromBitmap(renderScript, bitmap);
Allocation allocationCount = Allocation.createTyped(renderScript, Type.createX(renderScript, Element.I32(renderScript), 1));
ScriptC_Counter script = new ScriptC_Counter(renderScript);
script.set_rsAllocationCount(allocationCount);
script.forEach_countPixels(allocationBitmap);
int[] count = new int[1];
allocationBitmap.syncAll(Allocation.USAGE_SCRIPT);
allocationCount.copyTo(count);
// The count can now be accessed via
count[0];