-
Notifications
You must be signed in to change notification settings - Fork 6.1k
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
GIF animations are very slow. Possible solution and workaround. #3575
Comments
BTW, this is fixed in master branch:
|
A workaround is to update verstion to 4.10.0-SNAPSHOT and: builder.setAnimationExecutor(
GlideExecutor.newSourceExecutor(
DEFAULT_THREAD_POOL_SIZE,
"animation",
GlideExecutor.UncaughtThrowableStrategy.DEFAULT
)
) We can't use newAnimationExecutor() because it will stay on one thread until it's queue is full, which is impossible while using PriorityBlockingQueue with it's Integer.MAX_VALUE ramainingCapacity(). From PriorityBlockingQueue source code: /**
* Always returns {@code Integer.MAX_VALUE} because
* a {@code PriorityBlockingQueue} is not capacity constrained.
* @return {@code Integer.MAX_VALUE} always
*/
public int remainingCapacity() {
return Integer.MAX_VALUE;
} |
So, this problem should be fixed anyway. In other case GIF animations will play very slow. |
This issue has been automatically marked as stale because it has not had activity in the last seven days. It will be closed if no further activity occurs within the next seven days. Thank you for your contributions. |
Thanks for investigating this, I appreciate the detail! |
@yuriy-budiyev can you please explain what do you mean by updating to 4.10.0-SNAPSHOT ?? |
@rizwan321 In version 4.9.0 you can't set custom executor for animation (builder.setAnimationExecutor will have no effect). In 4.10.0 this was fixed. |
@yuriy-budiyev i am getting following error when update to 4.10.0 i have added following lines in build |
@sjudd Thread pool executor will increase it's pool size only if it's queue is full, oterwise it will stay on minimum possible thread count. public static GlideExecutor newAnimationExecutor(
int threadCount, UncaughtThrowableStrategy uncaughtThrowableStrategy) {
return new GlideExecutor(
new ThreadPoolExecutor(
0 /* corePoolSize */,
threadCount,
KEEP_ALIVE_TIME_MS,
TimeUnit.MILLISECONDS,
new PriorityBlockingQueue<Runnable>(),
new DefaultThreadFactory(
ANIMATION_EXECUTOR_NAME,
uncaughtThrowableStrategy,
true)));
} This pool will not work as expected because PriorityBlockingQueue isn't capacity constrained. Executors.newCachedThreadPool uses SynchronousQueue which literally has no capacity and just transfers objects beetween producers and consumers. So each time when task is added and there are no available worker thread, it will create a new one. PriorityBlockingQueue /**
* Always returns {@code Integer.MAX_VALUE} because
* a {@code PriorityBlockingQueue} is not capacity constrained.
* @return {@code Integer.MAX_VALUE} always
*/
public int remainingCapacity() {
return Integer.MAX_VALUE;
} SynchronousQueue /**
* Always returns zero.
* A {@code SynchronousQueue} has no internal capacity.
*
* @return zero
*/
public int remainingCapacity() {
return 0;
} SynchronousQueue is unusable for this situation because when maxPoolSize value will be reached it will cause producer to wait when cunsumer become available (all adding methods can block). Also, if you restrict PriorityBlockingQueue capacity, execution of the task will be rejected when the queue is full and maxPoolSize is reached. So the possible solution is just use fixed thread pool for animations public static GlideExecutor newAnimationExecutor(
int threadCount, UncaughtThrowableStrategy uncaughtThrowableStrategy) {
return new GlideExecutor(
new ThreadPoolExecutor(
threadCount,
threadCount,
0,
TimeUnit.MILLISECONDS,
new PriorityBlockingQueue<Runnable>(),
new DefaultThreadFactory(
ANIMATION_EXECUTOR_NAME,
uncaughtThrowableStrategy,
true)));
} |
@rizwan321 See here. |
@yuriy-budiyev thanks for the replying me Glide.with(context).load(icon).into(imageView); can you please let me know what i have to add further and how to add ??? |
@yuriy-budiyev i also tried below lines but again animation is slow GlideBuilder builder = new GlideBuilder(); builder.setAnimationExecutor(GlideExecutor.newSourceExecutor(DEFAULT_THREAD_POOL_SIZE, "animation", GlideExecutor.UncaughtThrowableStrategy.DEFAULT)); |
@rizwan321 See here. You should create your AppGlideModule, builder will be available in applyOptions method. |
@yuriy-budiyev very sorry for disturbing you again and again. i have implemented below in my application @GlideModule what do you mean by builder will be available in applyOptions method. ?? |
@rizwan321 override this method in your class. |
@yuriy-budiyev i am not getting your point what you are trying to say. It will be great if you paste a proper solution here ?? |
@GlideModule
class MyGlideModule: AppGlideModule() {
override fun applyOptions(
context: Context,
builder: GlideBuilder
) {
builder.setAnimationExecutor(
GlideExecutor.newSourceExecutor(
4 /*thread count*/,
"animation",
GlideExecutor.UncaughtThrowableStrategy.DEFAULT
)
)
}
} |
Can anyone post a full detailed reply, I am still facing the issue, implemented snapshot library and made glide module class, how to solve the issue? |
@yuriy-budiyev i have implemented glide with your suggested way. its speed is good in only Note7. while testing on other device Like S8, S7 its speed is slow as before. can you please look into it or let me know what i have to do further ? |
@RISHABHPATNI1108 @rizwan321 Probably, better way is just wait 4.10.0 release. The snapshot version can be unstable and shouldn't be used in production. I tested my solution on Pixel 2 XL, Pixel 3, Galaxy S9, Galaxy Tab S3 and Redmi 5. Have you added glide compiler dependency? Read this article. |
Glide Version: 4.9.0
Integration libraries: none
Device/Android Version: Pixel 3, Android Q beta
Issue details / Repro steps / Use case background: Unable to set animation executor in GlideBuilder, setted value is ignored in build method (line 487 in v4.9.0). animationExecutor field is unused.
This causes GIF animations to run on default one or two threaded executor wrich is VERY SLOW, so if you have many GIF's, there are 1fps slideshow or even slower.
Also, by profiling, we can see that one animation thread is used by Glide and fully loaded (never idle), so device's cpu can't be utilized properly.
Glide is used with AppGlideModule, and builder methods called there.
The text was updated successfully, but these errors were encountered: