2013-03-20 38 views
1

我有一個帶有許多項目和圖像的微調器的應用程序。很多對renderscript的調用會產生錯誤「創建的RS線程數量少於預期數量」

每當用戶選擇列表中的項目時,將執行一個數字(1到5)的renderscript腳本來更改圖像的像素。

做出大約30個選擇後,應用程序崩潰並出現錯誤。

這是堆棧跟蹤。

03-20 13:56:59.366: ERROR/RenderScript(3405): Created fewer than expected number of RS threads. 
03-20 13:57:02.990: ERROR/AndroidRuntime(3405): FATAL EXCEPTION: main 
    java.lang.RuntimeException: createWindowSurface failed EGL_BAD_ALLOC 
    at android.view.HardwareRenderer$GlRenderer.createSurface(HardwareRenderer.java:1064) 
    at android.view.HardwareRenderer$GlRenderer.createEglSurface(HardwareRenderer.java:961) 
    at android.view.HardwareRenderer$GlRenderer.initialize(HardwareRenderer.java:787) 
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1502) 
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989) 
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4351) 
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749) 
    at android.view.Choreographer.doCallbacks(Choreographer.java:562) 
    at android.view.Choreographer.doFrame(Choreographer.java:532) 
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735) 
    at android.os.Handler.handleCallback(Handler.java:725) 
    at android.os.Handler.dispatchMessage(Handler.java:92) 
    at android.os.Looper.loop(Looper.java:137) 
    at android.app.ActivityThread.main(ActivityThread.java:5041) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:511) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 
    at dalvik.system.NativeStart.main(Native Method) 

我想我應該以某種方式關閉renderscript使用的非平民線程或什麼?

UPDATE:

有時誤差是不同的:

03-20 16:09:42.293: ERROR/bcc(24984): !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
03-20 16:09:42.293: ERROR/bcc(24984): rslAssert [frameworks/compile/linkloader/include/ELFObject.h:86] SHNCommonDataPtr && "Must init common data size before use!" 
03-20 16:09:42.293: ERROR/bcc(24984): !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 

03-20 15:46:27.315: ERROR/AndroidRuntime(19330): FATAL EXCEPTION: Thread-3582 
    android.renderscript.RSRuntimeException: Loading of ScriptC script failed. 
    at android.renderscript.ScriptC.<init>(ScriptC.java:60) 
    at com.gfranq.android.ScriptC_BrightnessContrast.<init>(ScriptC_BrightnessContrast.java:41) 
    at com.gfranq.android.filters.logic.ImageFilter.brightnessContrastRs(ImageFilter.java:1438) 

它指向的線

 ScriptC_BrightnessContrast script = new ScriptC_BrightnessContrast(rs, context.getResources(), 
      R.raw.brightnesscontrast); 

更新2:

這是Brightness conrast過濾器。 我想,每次吃內存時都會創建新的輸入輸出分配和Script對象。是否可以使用一個分配來執行一系列renderscript動作?例如,我從位圖進行分配,然後對其應用brightnesscontrastfilter,然後使用類似實現的一些不同的過濾器?

public Bitmap brightnessContrastRs(Bitmap bmIn, int brightness, int contrast, Context context) 
{ 
    Bitmap bmOut = Bitmap.createBitmap(bmIn.getWidth(), bmIn.getHeight(), 
      bmIn.getConfig()); 
// RenderScript rs = RenderScript.create(context); 
    Allocation allocIn; 
    allocIn = Allocation.createFromBitmap(rs, bmIn, 
      Allocation.MipmapControl.MIPMAP_NONE, 
      Allocation.USAGE_SCRIPT); 
    Allocation allocOut = Allocation.createTyped(rs, allocIn.getType()); 
    ScriptC_BrightnessContrast script = new ScriptC_BrightnessContrast(rs, context.getResources(), 
      R.raw.brightnesscontrast); 
    script.set_in(allocIn); 
    allocIn.destroy(); 
    script.set_out(allocOut); 
    script.set_script(script); 
    float rowContrast = ((100.0f + contrast) * (100.0f + contrast)/10000.0f); 
    float rowBrightness = brightness/255.f; 
    script.set_rowBrightness(rowBrightness); 
    script.set_rowContrast(rowContrast); 
    script.invoke_filter(); 
    allocOut.copyTo(bmOut); 
    allocOut.destroy(); 
    return bmOut; 
} 

除此之外的一些動作內我有相當大的INT陣列(360000個整數),如我理解每次我創建小號criptC對象它爲每一個陣列,所述的renderScript內部限定分配內存時間,因此存儲器可以泄漏相當快。

當我發佈這個問題時,每次創建RenderScript對象的註釋行都沒有被註釋,並且內存泄漏速度更快。

該設備的Nexus 4

例如這裏是RS使用數組文件(其他文件與此類似,但可能不包含數組)

rs_allocation out; 
rs_allocation in; 
rs_script script; 

float opacity; 
float alphas[360000]; 
int width; 

void root(const uchar4* v_in, uchar4* v_out, const void* usrData, uint32_t x, 
     uint32_t y) 
{ 
    float4 current = rsUnpackColor8888(*v_in); 
    current.a = alphas[width * y + x] * opacity; 
    *v_out = rsPackColorTo8888(current.r, current.g, current.b, current.a); 
} 
void filter() 
{ 
#if !defined(RS_VERSION) || (RS_VERSION < 14) 
rsForEach(script, in, out, 0); 
#else 
rsForEach(script, in, out); 
#endif 
} 
+0

你可以發佈你的BrightnessContrast.rs文件,也許你如何運行它?這也有助於在日誌失敗之前再添加幾行(並提及您正在運行的設備)。 – 2013-03-20 16:15:36

+0

這是代碼。 – TpoM6oH 2013-03-21 06:29:38

回答

1

是真的花了很多的內存每次都創建一個新的ScriptC對象。我將它們移到了類字段變量並且一直運行正常。

+0

我也面臨類似的問題,所以我做了rs和腳本對象類字段變量,它現在不會崩潰,即使我改變了方向15-20次。感謝那!在活動上運行rs約20次,在許多位圖上運行。調用銷燬分配真的會提高性能嗎?我沒有那樣做。 – 2014-02-07 14:26:39

相關問題