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

[Android][AcrylicBlur] Performance Degradation when ThrowStopExceptionOnDraw set to True #7

Closed
mauro-dasilva opened this issue Jun 7, 2020 · 18 comments

Comments

@mauro-dasilva
Copy link

Platform (please complete the following information):

  • OS: Android
  • Device: Android Emulator/Pixel 2 XL
  • Sdk vervion: Android SDK 28
  • Xamarin.Forms: [4.6.0.847]

Describe the bug
I have noticed that when you set the ThrowStopExceptionOnDraw to True on Android, if you navigate around a few pages that have the MaterialFrames with the following settings:

  • MaterialBlurStyle="Light"
  • MaterialTheme="AcrylicBlur"

The app starts to get slower and slower as you use it and starts to stutter. If you turn ThrowStopExceptionOnDraw to False everything works smoothly.

To Reproduce
I have attached a sample project, as well as the GIF below. In the sample, I have a few MaterialFrames with the settings specified above and I'm just navigating to that page and back. You will see that the content gets slower to load and even the back arrow animation in the top left starts to stutter.

Screenshots (if applicable)

ThrowException
App1.zip

@roubachof
Copy link
Owner

have you tried increasing the AndroidMaterialFrameRenderer.BlurProcessingDelayMilliseconds ?

@mauro-dasilva
Copy link
Author

I tried bumping up the BlurProcessingDelayMilliseconds to 1000, but I think I may have picked up a strange behaviour with it. It seems that the Material grid doesn't get shown until you interact with one of the controls.

I have attached the following image for you to see. The acrylic material frame doesn't show until I click on the toggle button

Delay1000ms

I then changed the BlurProcessingDelayMilliseconds to 250 and the app still gets very sluggish. I have updated the sample app to make it more apparent by adding toggle buttons. To replicate the issue you can do the following:

  1. Click on 'First Item'
  2. Click on the Back button
  3. Repeat the process 5-6 times
  4. Click on one of the Toggle buttons and you will see that the toggle button becomes sluggish when tapping on it.
  5. If you set ThrowStopExceptionOnDraw to false, the sluggishness doesnt occur

App1 (With Toggles).zip

@roubachof
Copy link
Owner

roubachof commented Jun 10, 2020

You are using it wrong.
MaterialFrame is blurring what is underneath it not what is in it :)
And as the same time, you are putting a MaterialFrame with AcryclicBlur in another MaterialFrame with AcrylicBlur, which is blurring a blurred Frame. Seems resource intensive and makes no sense :)

@mauro-dasilva
Copy link
Author

Yeah, I understand it blurs the contents underneath. I think maybe the example image I gave above wasn't the best. I have replaced the background with a pattern so that you can clearly see when it is blurred.

In the example below. I have set the BlurProcessingDelayMilliseconds to 1000 (IE. 1 second).You will see the screen loads and I wait 5 seconds and there is no blur yet. However, as soon as interact with the checkbox, the blur appears.

100msDelay

With regards to the MaterialFrame in MaterialFrame, I agree that would be somewhat intensive and was a mistake on my part as I forgot to remove the outer Material Frame.

To demonstrate the sluggishness, I have attached the following 2 videos of the exact same code and just changing the ThrowStopExceptionOnDraw from False to True.

Sample 1
In this video I have ThrowStopExceptionOnDraw set to False. I then navigated back and forth to the details page about 80 times before recording this snippet. As you can see the blur loads quickly and when I interact with the toggle switch it is smooth. (It is a video, so I had to zip it to upload it here)

ThrowStopExceptionOnDraw_False.zip

Sample 2
In this video I have the same code and just change ThrowStopExceptionOnDraw set to True. I then navigated back and forth to the details page about 30 times before recording this snippet. You will see that the blur loads a lot slower and there is a visible delay when interacting with the toggles.

ThrowStopExceptionOnDraw_True.zip

In the app that I'm building I have seen the same thing, the more I use it with ThrowStopExceptionOnDraw set to True, the slower it gets as I use it.

Here is the updated code for the Gifs/videos above
App1 (Update with Pattern).zip

@roubachof
Copy link
Owner

thanks for the updated sample, I will investigate

@roubachof
Copy link
Owner

I'm very fond of tracking memory leaks (not a joke :)

@mauro-dasilva
Copy link
Author

Now there is something you don't hear everyday :) Hopefully this bug is a good one for you then :)

@roubachof
Copy link
Owner

Ok so the android material frame isn't leaking: I tested it thoroughly. The Java finalizer is called and the renderer is disposed as well.
The only issue that can cause this is a bug in Xamarin.Android framework I opened here: xamarin/xamarin-android#4632

It's been opened for more than a month now, but they didn't seem to really care about it...
So, you can maybe add a comment in the issue to try to push things further :)

@mauro-dasilva
Copy link
Author

Thanks so much for you efforts. I will go post on that thread to hopefully get some traction. Just wanted to also say your projects are really fantastic and I just saw your new one with shadows. Its really AWESOME! Keep up the great work bud!

@roubachof
Copy link
Owner

roubachof commented Jun 11, 2020

I dig further, and the more we go back and forth, the more JNI UNHANDLED EXCEPTION stack trace becomes bigger.
It's pretty interesting there is always 5 UNHANDLED EXCEPTION matching our 5 blur views Draw() calls, but for some reason the exception stack is getting bigger and bigger, repeating this segment:

06-11 10:53:43.068: I/MonoDroid(15003):   at Sharpnado.MaterialFrame.Droid.RealtimeBlurView.Draw (Android.Graphics.Canvas canvas) [0x0003b] in <6066746bf0d2461494ede6c595763683>:0 
06-11 10:53:43.068: I/MonoDroid(15003):   at Android.Views.View.n_Draw_Landroid_graphics_Canvas_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_canvas) [0x0000f] in <eaa205f580954a64824b74a79fa87c62>:0 
06-11 10:53:43.068: I/MonoDroid(15003):   at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.120(intptr,intptr,intptr)
06-11 10:53:43.068: I/MonoDroid(15003): --- End of stack trace from previous location where exception was thrown ---

And it's just getting repeated countless times:

06-11 10:53:43.069: I/MonoDroid(15003):   at Sharpnado.MaterialFrame.Droid.RealtimeBlurView.Draw (Android.Graphics.Canvas canvas) [0x0003b] in <6066746bf0d2461494ede6c595763683>:0 
06-11 10:53:43.069: I/MonoDroid(15003):   at Android.Views.View.n_Draw_Landroid_graphics_Canvas_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_canvas) [0x0000f] in <eaa205f580954a64824b74a79fa87c62>:0 
06-11 10:53:43.069: I/MonoDroid(15003):   at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.120(intptr,intptr,intptr)
06-11 10:53:43.069: I/MonoDroid(15003): --- End of stack trace from previous location where exception was thrown ---
06-11 10:53:43.069: I/MonoDroid(15003):   at Sharpnado.MaterialFrame.Droid.RealtimeBlurView.Draw (Android.Graphics.Canvas canvas) [0x0003b] in <6066746bf0d2461494ede6c595763683>:0 
06-11 10:53:43.069: I/MonoDroid(15003):   at Android.Views.View.n_Draw_Landroid_graphics_Canvas_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_canvas) [0x0000f] in <eaa205f580954a64824b74a79fa87c62>:0 
06-11 10:53:43.069: I/MonoDroid(15003):   at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.120(intptr,intptr,intptr)
06-11 10:53:43.069: I/MonoDroid(15003): --- End of stack trace from previous location where exception was thrown ---
06-11 10:53:43.069: I/MonoDroid(15003):   at Sharpnado.MaterialFrame.Droid.RealtimeBlurView.Draw (Android.Graphics.Canvas canvas) [0x0003b] in <6066746bf0d2461494ede6c595763683>:0 
06-11 10:53:43.069: I/MonoDroid(15003):   at Android.Views.View.n_Draw_Landroid_graphics_Canvas_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_canvas) [0x0000f] in <eaa205f580954a64824b74a79fa87c62>:0 
06-11 10:53:43.069: I/MonoDroid(15003):   at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.120(intptr,intptr,intptr)
06-11 10:53:43.069: I/MonoDroid(15003): --- End of stack trace from previous location where exception was thrown ---
06-11 10:53:43.069: I/MonoDroid(15003):   at Sharpnado.MaterialFrame.Droid.RealtimeBlurView.Draw (Android.Graphics.Canvas canvas) [0x0003b] in <6066746bf0d2461494ede6c595763683>:0 
06-11 10:53:43.069: I/MonoDroid(15003):   at Android.Views.View.n_Draw_Landroid_graphics_Canvas_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_canvas) [0x0000f] in <eaa205f580954a64824b74a79fa87c62>:0 
06-11 10:53:43.069: I/MonoDroid(15003):   at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.120(intptr,intptr,intptr)
06-11 10:53:43.069: I/MonoDroid(15003): --- End of stack trace from previous location where exception was thrown ---
06-11 10:53:43.069: I/MonoDroid(15003):   at Sharpnado.MaterialFrame.Droid.RealtimeBlurView.Draw (Android.Graphics.Canvas canvas) [0x0003b] in <6066746bf0d2461494ede6c595763683>:0 
06-11 10:53:43.069: I/MonoDroid(15003):   at Android.Views.View.n_Draw_Landroid_graphics_Canvas_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_canvas) [0x0000f] in <eaa205f580954a64824b74a79fa87c62>:0 
06-11 10:53:43.069: I/MonoDroid(15003):   at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.120(intptr,intptr,intptr)
06-11 10:53:43.069: I/MonoDroid(15003): --- End of stack trace from previous location where exception was thrown ---
06-11 10:53:43.069: I/MonoDroid(15003):   at Sharpnado.MaterialFrame.Droid.RealtimeBlurView.Draw (Android.Graphics.Canvas canvas) [0x0003b] in <6066746bf0d2461494ede6c595763683>:0 
06-11 10:53:43.069: I/MonoDroid(15003):   at Android.Views.View.n_Draw_Landroid_graphics_Canvas_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_canvas) [0x0000f] in <eaa205f580954a64824b74a79fa87c62>:0 
06-11 10:53:43.070: I/MonoDroid(15003):   at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.120(intptr,intptr,intptr)
06-11 10:53:43.070: I/MonoDroid(15003): --- End of stack trace from previous location where exception was thrown ---
06-11 10:53:43.070: I/MonoDroid(15003):   at Sharpnado.MaterialFrame.Droid.RealtimeBlurView.Draw (Android.Graphics.Canvas canvas) [0x0003b] in <6066746bf0d2461494ede6c595763683>:0 
06-11 10:53:43.070: I/MonoDroid(15003):   at Android.Views.View.n_Draw_Landroid_graphics_Canvas_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_canvas) [0x0000f] in <eaa205f580954a64824b74a79fa87c62>:0 
06-11 10:53:43.070: I/MonoDroid(15003):   at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.120(intptr,intptr,intptr)
06-11 10:53:43.070: I/MonoDroid(15003): --- End of stack trace from previous location where exception was thrown ---
06-11 10:53:43.070: I/MonoDroid(15003):   at Sharpnado.MaterialFrame.Droid.RealtimeBlurView.Draw (Android.Graphics.Canvas canvas) [0x0003b] in <6066746bf0d2461494ede6c595763683>:0 
06-11 10:53:43.070: I/MonoDroid(15003):   at Android.Views.View.n_Draw_Landroid_graphics_Canvas_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_canvas) [0x0000f] in <eaa205f580954a64824b74a79fa87c62>:0 
06-11 10:53:43.070: I/MonoDroid(15003):   at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.120(intptr,intptr,intptr)
06-11 10:53:43.070: I/MonoDroid(15003): --- End of stack trace from previous location where exception was thrown ---
06-11 10:53:43.070: I/MonoDroid(15003):   at Sharpnado.MaterialFrame.Droid.RealtimeBlurView.Draw (Android.Graphics.Canvas canvas) [0x0003b] in <6066746bf0d2461494ede6c595763683>:0 
06-11 10:53:43.070: I/MonoDroid(15003):   at Android.Views.View.n_Draw_Landroid_graphics_Canvas_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_canvas) [0x0000f] in <eaa205f580954a64824b74a79fa87c62>:0 
06-11 10:53:43.070: I/MonoDroid(15003):   at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.120(intptr,intptr,intptr)
06-11 10:53:43.070: I/MonoDroid(15003): --- End of stack trace from previous location where exception was thrown ---
06-11 10:53:43.070: I/MonoDroid(15003):   at Sharpnado.MaterialFrame.Droid.RealtimeBlurView.Draw (Android.Graphics.Canvas canvas) [0x0003b] in <6066746bf0d2461494ede6c595763683>:0 
06-11 10:53:43.070: I/MonoDroid(15003):   at Android.Views.View.n_Draw_Landroid_graphics_Canvas_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_canvas) [0x0000f] in <eaa205f580954a64824b74a79fa87c62>:0 
06-11 10:53:43.070: I/MonoDroid(15003):   at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.120(intptr,intptr,intptr)
06-11 10:53:43.070: I/MonoDroid(15003): --- End of stack trace from previous location where exception was thrown ---
06-11 10:53:43.070: I/MonoDroid(15003):   at Sharpnado.MaterialFrame.Droid.RealtimeBlurView.Draw (Android.Graphics.Canvas canvas) [0x0003b] in <6066746bf0d2461494ede6c595763683>:0 
06-11 10:53:43.070: I/MonoDroid(15003):   at Android.Views.View.n_Draw_Landroid_graphics_Canvas_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_canvas) [0x0000f] in <eaa205f580954a64824b74a79fa87c62>:0 
06-11 10:53:43.070: I/MonoDroid(15003):   at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.120(intptr,intptr,intptr)
06-11 10:53:43.070: I/MonoDroid(15003): --- End of stack trace from previous location where exception was thrown ---
06-11 10:53:43.070: I/MonoDroid(15003):   at Sharpnado.MaterialFrame.Droid.RealtimeBlurView.Draw (Android.Graphics.Canvas canvas) [0x0003b] in <6066746bf0d2461494ede6c595763683>:0 
06-11 10:53:43.070: I/MonoDroid(15003):   at Android.Views.View.n_Draw_Landroid_graphics_Canvas_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_canvas) [0x0000f] in <eaa205f580954a64824b74a79fa87c62>:0 
06-11 10:53:43.070: I/MonoDroid(15003):   at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.120(intptr,intptr,intptr)
06-11 10:53:43.070: I/MonoDroid(15003): --- End of stack trace from previous location where exception was thrown ---
06-11 10:53:43.070: I/MonoDroid(15003):   at Sharpnado.MaterialFrame.Droid.RealtimeBlurView.Draw (Android.Graphics.Canvas canvas) [0x0003b] in <6066746bf0d2461494ede6c595763683>:0 
06-11 10:53:43.070: I/MonoDroid(15003):   at Android.Views.View.n_Draw_Landroid_graphics_Canvas_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_canvas) [0x0000f] in <eaa205f580954a64824b74a79fa87c62>:0 
06-11 10:53:43.070: I/MonoDroid(15003):   at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.120(intptr,intptr,intptr)
06-11 10:53:43.070: I/MonoDroid(15003): --- End of stack trace from previous location where exception was thrown ---
06-11 10:53:43.070: I/MonoDroid(15003):   at Sharpnado.MaterialFrame.Droid.RealtimeBlurView.Draw (Android.Graphics.Canvas canvas) [0x0003b] in <6066746bf0d2461494ede6c595763683>:0 
06-11 10:53:43.070: I/MonoDroid(15003):   at Android.Views.View.n_Draw_Landroid_graphics_Canvas_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_canvas) [0x0000f] in <eaa205f580954a64824b74a79fa87c62>:0 
06-11 10:53:43.070: I/MonoDroid(15003):   at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.120(intptr,intptr,intptr)
06-11 10:53:43.070: I/MonoDroid(15003): --- End of stack trace from previous location where exception was thrown ---

You can have a look to the 4 logs corresponding to 4 successive tries.

log_1.txt
log_2.txt
log_3.txt
log_4.txt

First log is 360 lines, second is 937, third one is 1949, last one is 2644.

@roubachof roubachof changed the title Performance Degradation when ThrowStopExceptionOnDraw set to True [Android][AcrylicBlur] Performance Degradation when ThrowStopExceptionOnDraw set to True Jun 11, 2020
@mauro-dasilva
Copy link
Author

That is very interesting. It's almost as if the stack trace isn't being cleared out.

Originally, while I was trying to figure out what was causing this issue, I removed all the acrylic blur material frames on one of the pages in the app, and whenever I navigated to it, the performance was all of sudden fine, which really confused me. But with what you posted here now, it all makes sense.

@roubachof
Copy link
Owner

@mauro-dasilva we made some good progress with the Xamarin.Android bug. Now let's just hope that the "growing" exception stack will be fixed as well. I'm worried they will only fix the logging in adb but some weird bug will remain.

@roubachof
Copy link
Owner

@mauro-dasilva some update: xamarin/xamarin-android#4987 seems to find a workaround for the exception stack getting bigger and bigger. Just have to throw new StopException each time instead of throwing the static instance :)

@roubachof
Copy link
Owner

Next version should be published next week

@mauro-dasilva
Copy link
Author

Awesome! Thansk bud

@roubachof
Copy link
Owner

should be fixed by https://github.com/roubachof/Sharpnado.MaterialFrame/releases/tag/v1.1.3 AND vs 2019 studio 16.8.

@roubachof
Copy link
Owner

Visual Studio 16.8 is released \o/

@roubachof
Copy link
Owner

let's close this :o)

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

2 participants