Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calling RS with no context active #62

Closed
tristangrichard opened this issue Feb 5, 2018 · 16 comments
Closed

Calling RS with no context active #62

tristangrichard opened this issue Feb 5, 2018 · 16 comments

Comments

@tristangrichard
Copy link

tristangrichard commented Feb 5, 2018

Hi,

Blurview v. 1.3.4

Been using this library for months.
Just started getting this error.

Fatal Exception: android.renderscript.RSInvalidStateException: Calling RS with no Context active.
       at android.renderscript.RenderScript.validate(RenderScript.java:1237)
       at android.renderscript.Allocation.createFromBitmap(Allocation.java:2798)
       at android.renderscript.Allocation.createFromBitmap(Allocation.java:3062)
       at eightbitlab.com.blurview.RenderScriptBlur.blur(RenderScriptBlur.java:47)
       at eightbitlab.com.blurview.BlockingBlurController.blurAndSave(BlockingBlurController.java:1241)
       at eightbitlab.com.blurview.BlurView.draw(BlurView.java:57)
       at android.view.View.updateDisplayListIfDirty(View.java:16200)
       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3758)
       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3738)
       at android.view.View.updateDisplayListIfDirty(View.java:16163)
       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3758)
       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3738)
       at android.view.View.updateDisplayListIfDirty(View.java:16163)
       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3758)
       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3738)
       at android.view.View.updateDisplayListIfDirty(View.java:16163)
       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3758)
       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3738)
       at android.view.View.updateDisplayListIfDirty(View.java:16163)
       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3758)
       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3738)
       at android.view.View.updateDisplayListIfDirty(View.java:16163)
       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3758)
       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3738)
       at android.view.View.updateDisplayListIfDirty(View.java:16163)
       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3758)
       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3738)
       at android.view.View.updateDisplayListIfDirty(View.java:16163)
       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3758)
       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3738)
       at android.view.View.updateDisplayListIfDirty(View.java:16163)
       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3758)
       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3738)
       at android.view.View.updateDisplayListIfDirty(View.java:16163)
       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3758)
       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3738)
       at android.view.View.updateDisplayListIfDirty(View.java:16163)
       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3758)
       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3738)
       at android.view.View.updateDisplayListIfDirty(View.java:16163)
       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3758)
       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3738)
       at android.view.View.updateDisplayListIfDirty(View.java:16163)
       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3758)
       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3738)
       at android.view.View.updateDisplayListIfDirty(View.java:16163)
       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3758)
       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3738)
       at android.view.View.updateDisplayListIfDirty(View.java:16163)
       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3758)
       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3738)
       at android.view.View.updateDisplayListIfDirty(View.java:16163)
       at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:676)
       at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:682)
       at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:796)
       at android.view.ViewRootImpl.draw(ViewRootImpl.java:2989)
       at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2783)
       at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2374)
       at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1364)
       at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6763)
       at android.view.Choreographer$CallbackRecord.run(Choreographer.java:923)
       at android.view.Choreographer.doCallbacks(Choreographer.java:735)
       at android.view.Choreographer.doFrame(Choreographer.java:667)
       at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:909)
       at android.os.Handler.handleCallback(Handler.java:761)
       at android.os.Handler.dispatchMessage(Handler.java:98)
       at android.os.Looper.loop(Looper.java:156)
       at android.app.ActivityThread.main(ActivityThread.java:6524)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:941)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:831)

Any idea?

@tristangrichard
Copy link
Author

@Dimezis can you help?

@Dimezis
Copy link
Owner

Dimezis commented Feb 9, 2018

When does this appear?
What Android version are you using?
Any way I can reproduce it? Some test project or specific setup?

@tristangrichard
Copy link
Author

tristangrichard commented Feb 9, 2018

I have no clue, it does not seem related to my code!
It occurs on Android 6 and 7 mostly See here
I am unable to reproduce it myself!
The app is written in kotlin

compileSdkVersion 27
buildToolsVersion "27.0.3"

compile 'com.eightbitlab:blurview:1.3.3-4'

@Dimezis
Copy link
Owner

Dimezis commented Feb 11, 2018

Just a guess, but do you call setupWith(ViewGroup rootView) couple of times?
Do you reuse RenderScriptBlur between these calls? Do you have couple of BlurView in hierarchy?

Can you post where and how do you initialize the BlurView?

@tristangrichard
Copy link
Author

Sure! It should only be called once. I'll check that again.
There is only one blurview
The code is:

fun init(parent: ViewGroup) {
    if (!isBlurSetup) {
        isBlurSetup = true
        val radius = 10f
        blurView?.setupWith(parent)
                ?.blurAlgorithm(RenderScriptBlur(context))
                ?.blurRadius(radius)
    }
}

@Dimezis
Copy link
Owner

Dimezis commented Feb 12, 2018

I'm investigating it, but so far can't find a cause.
If you have a lot of crashes, you can workaround it temporary by implementing BlurAlgorithm interface and basically delegating all methods to RenderScriptBlur, but with try-catch on blur method.

Ugly, but at least you'll be safe while I'm trying to fix it.

@tristangrichard
Copy link
Author

I have deactivated the blur totally for now and replaced it with a alpha overlay. :)

@Dimezis
Copy link
Owner

Dimezis commented Feb 22, 2018

So I spent quite a lot of time investigating this crash.

The conclusion is - from library's POV it's impossible to call RS without context, at least on API 23+. I'm obtaining it in BlurAlgorithm's constructor to use in the same object. Eventually, destroy() is called on RS and I thought it could be an issue in certain cases if you are accidentally reusing the same BlurAlgorithm. But, on API 23+ destroy() is a no-op, because of changes in SDK.

So I have only couple of potential explanations to the problem:

  1. Some vendors changed RS API and something doesn't correspond to official documentation.
  2. RS Context can be destroyed implicitly by SDK in some weird cases and I have no control over it. For example, from RS sources it seems like it can happen during GC of Renderscipt object.
  3. You have some memory leaks or duplicated BlurViews or BlurAlgorithms which you are not aware of and it causes some issues, theoretically related to point 2.

Long story short, at this point I'm not able to fix it, and I have only 3 suggestions for you:

  1. You can use a workaround I provided in post above, with custom BlurAlgorithm and try-catch
  2. Give a try to com.eightbitlab:supportrenderscriptblur, maybe Support Renderscript doesn't have this issue.
  3. Set up Strict Mode to check if there's only 1 instance of BlurView and RenderscriptBlur at a time.

@tristangrichard
Copy link
Author

I will look into it

@tristangrichard
Copy link
Author

@Dimezis
Just an update
No memory leaks were found. So I gave supportrenderscriptblur a shot.
No crashes yet.

@ghost
Copy link

ghost commented Oct 25, 2018

Hi @Dimezis,

Just wanted to tell you that using the support script caused other errors. Therefore I tried the Blurry library instead and they too had similar issues and has been fix here.

@Dimezis
Copy link
Owner

Dimezis commented Oct 25, 2018

Hey,
For me it doesn't seem like a similar issue. And the workaroud is pretty dirty, IMO. Falling back to another algorithm, without dev control, is not a way to go

@ghost
Copy link

ghost commented Oct 25, 2018

I was getting too many crashes (on cheap devices only), dirty or not this fallback prevents the devices from crashing.
Most of them happened few seconds after launch where context was active.

@Dimezis
Copy link
Owner

Dimezis commented Oct 29, 2018

@tristanrichard
Well the thing is that you're able to do the same kind of fallback on your own, if you experience this issue. And you can pick an algorithm you want, while still being able to track the pattern of this crash, so this might be fixed one day.

This way the lib can stay hack/workaround free.

Unfortunately I wasn't able to reproduce it, and I have a released product with crash reporting tools integrated, yet I didn't get any crashes like this.
So hard to judge what's the reason here and what's the proper fix.

@isidro89
Copy link

isidro89 commented May 5, 2022

I know this is an old thread, but I am also having the same issue and it turned out to be because p.wasabeef.glide.transformations.BlurTransformation also uses RenderScript and calls the method RenderScript.releaseAllContexts(); after applying the blur.

That happens in another activity, and when I return to the activity where I am using this lib, it crashes because when the OnPreDrawListener calls the method blur(Bitmap bitmap, float blurRadius) the field renderScript is marked as destroyed (a boolean flag inside it) hence the crash.

I used the workaround proposed in an earlier comment but created another instance of RenderScriptBlur if it throws an exception. I know it's dirty, but at the moment I have no time to find a better way.

Any comments to find a better solution are welcome :)

    @Override
    public Bitmap blur(Bitmap bitmap, float v) {
        try {
            return renderScriptBlur.blur(bitmap, v);
        } catch (RSInvalidStateException exception) {
            renderScriptBlur = new RenderScriptBlur(context);
            return renderScriptBlur.blur(bitmap, v);
        }
    }

@Dimezis
Copy link
Owner

Dimezis commented May 5, 2022

glide-transformations should just stop calling releaseAllContexts.
It can break more than this library

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants