绘制大位图时非常慢的nSyncAndDrawFrame [英] Extremely slow nSyncAndDrawFrame when drawing large Bitmaps
问题描述
我想使用多个大位图来优化视差滚动视图.在我的Nexus 5上,一切都很顺利,Traceview转储看起来像这样:
I want to optimize a parallax scrolling view with multiple large Bitmaps. On my Nexus 5, everything is smooth and the Traceview dump looks like this:
doFrame()方法使用〜18 ms来完成操作.
The doFrame() method uses ~18 ms to finish.
但是,当使用我的Nexus 7或Android 6仿真器(Genymotion)时,Traceview转储看起来像这样:
However, when using my Nexus 7 or an Android 6 Emulator (Genymotion), the Traceview dump looks like this:
现在,运行完全相同的应用程序时,nSyncAndDrawFrame方法大约需要300毫秒.
The nSyncAndDrawFrame method now takes ~300 ms when running the exact same application.
有趣的代码部分在视差视图的onDraw()中:
The interesting code part is in onDraw() of the parallax view:
for (int i = 0; i < parallaxConfigManager.getNumberOfLayers(); i++) {
Bitmap layer = parallaxConfigManager.getLayer(i);
float dx = (offset * parallaxConfigManager.getScrollSpeedFactorForLayer(i) * imageScaleFactor);
int offset = Math.round(-parallaxConfigManager.getBoardOffset(i) + dx);
srcRect.offsetTo(offset, 0);
int realWidth = getRealWidth(srcRect, layer.getWidth());
float scaleFactor = destRect.width() / (float) srcRect.width();
if (realWidth < srcRect.width()) {
destRect.left = (int) (scaleFactor * Math.max(0, -srcRect.left));
destRect.right = destRect.left + (int) (scaleFactor * realWidth);
}
destRect.bottom = Math.min(screenHeight, (int) (scaleFactor * layer.getHeight()));
canvas.drawBitmap(layer, srcRect, destRect, paint);
destRect.left = 0;
destRect.right = screenWidth;
}
但是,此代码足够快.最慢的部分是Android的原生nSyncAndDrawFrame().
However, this code is fast enough. The slow part is in Androids native nSyncAndDrawFrame().
这里可能是什么问题?有没有一种方法可以更深入地研究这个问题?现在,此方法是一个黑匣子,因为我看不到本机调用堆栈.
What could be the problem here? Is there a way to look deeper into this problem? Right now this method is a black box, because I can not see the native call stack.
推荐答案
我在 CollapsingToolbarLayout
中遇到大图像(1920x933)的类似行为后,偶然发现了这个问题.探查器显示,对 android.view.ThreadedRenderer.nSyncAndDrawFrame()
的调用需要很长时间才能完成.
I stumbled on this question after encountering similar behavior with a large image (1920x933) in a CollapsingToolbarLayout
. The profiler revealed that calls to android.view.ThreadedRenderer.nSyncAndDrawFrame()
were taking a long time to complete.
尽管将图像分辨率降低(例如降低到1280x622)可以解决该问题,但是有一种方法可以完全避免该问题.
Although reducing the image resolution (to 1280x622, for example) will eliminate the problem, there is a way to avoid the issue altogether.
将图像移到 drawable-nodpi
文件夹,这表示图像与分辨率无关.渲染滞后应该消失.
Move your image into the drawable-nodpi
folder, which indicates that the image is resolution-independent. The rendering lag should disappear.
这篇关于绘制大位图时非常慢的nSyncAndDrawFrame的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!