我正在尝试使用单个线程使用画布锁定/解锁从 UI 线程渲染三个单独的 TextureView。观察到的问题是正在绘制的每个纹理视图的一致闪烁,闪烁由不同的纹理视图的框架组成。例如,我按顺序绘制帧 A、B 和 C。帧 C 看起来很好,但是帧 A 和 B 会随着帧 C 的偶尔实例闪烁,帧 A 偶尔会随着帧 B 的实例闪烁。
我已经阅读了描述 Android Core Graphics 的文档,并且对 android 的帧缓冲系统的工作原理有了相当好的理解。简而言之,我的怀疑是我连续执行 lockCanvas/unlockCanvasAndPost 调用的速度太快,并且帧缓冲区无法完成我的请求,而是简单地绘制了前一个(不正确的)帧。
我已经尝试了几件事来解决这个问题。尝试使用 Choreographer 在继续调用画布之前等待 VSYNC 有所帮助,但正如预期的那样降低了我的帧速率,但问题仍然存在。我还尝试了另一种无睡眠命令的渲染循环,观察到的现象没有区别。
本质上,我对如何解决这个问题一无所知,并希望获得一些外部意见。在此先感谢,代码片段如下:
主渲染循环:
while (running) {
long now = System.nanoTime();
long updateLength = now - lastLoopTime;
lastLoopTime = now;
float delta = updateLength / ((float)OPTIMAL_TIME.get());
lastFpsTime += updateLength;
fps++;
if (lastFpsTime >= 1000000000)
{
Log.e(TAG, "(FPS Target: " + TARGET_FPS+ " ,FPS Actual: " + fps + ")");
lastFpsTime = 0;
fps = 0;
}
for (MyTextureView mtv : mItemList){
if (!mtv.isLocked()) {
mtv.doUpdate(delta);
mtv.doRender();
}
}
long sleepTime = (lastLoopTime-System.nanoTime() + OPTIMAL_TIME.get())/1000000;
sleepTime = sleepTime < 0 ? 0 : sleepTime;
try{
Thread.sleep( sleepTime );
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
MyTextureView doRender() 方法:
public void doRender() {
doubleBufferCanvas.drawPaint(Colors.BLACK);
doDraw(doubleBufferCanvas); //draws content onto secondary canvas
Canvas c = lockCanvas();
c.drawPaint(Colors.BLACK);
c.save();
c.drawBitmap(dbbmp, 0, 0, null);
c.restore();
unlockCanvasAndPost(c);
}