我正在尝试使用单个线程使用canvas lock / unlock从UI线程渲染三个单独的TextureView。观察到的问题是每个正在绘制的纹理视图的一致闪烁,闪烁由 DIFFERENT TextureView的帧组成。例如,我按顺序绘制帧A,B和C.帧C看起来很好,但是帧A和帧B会偶尔闪现帧C的情况,而帧A偶尔会闪现帧B的实例。
我已经阅读了描述Android Core Graphics的文档,并对android的帧缓冲系统的工作方式有了很好的理解。简而言之,我怀疑是我连续快速执行lockCanvas / unlockCanvasAndPost调用,并且帧缓冲无法完成我的请求而只是简单地绘制了先前(不正确)的帧。
我已经尝试了几个方法来解决这个问题。在继续调用canvas之前尝试使用Choreographer等待VSYNC有所帮助,但正如预期的那样降低了我的帧速率,但问题仍然存在。我还尝试了另一种渲染循环sans sleep命令,观察到的现象没有区别。
基本上我没有关于如何解决这个问题的想法,并希望得到一些外部输入。在此先感谢,代码段如下:
主渲染循环:
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);
}
答案 0 :(得分:0)
我能够为此找到解决方法。 (我在Android 5.0及以上版本中没有观察到这一点。)
添加如下所示的伪透明视图
<View
android:id="@+id/flicker_hack_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:alpha="0.01"
android:background="@color/black_12" />
覆盖整个活动,只要有textureView。 alpha应设置为0.01或更小的值,使其看起来不可见。
这个解决方法是基于我的观察,当两个纹理视图渲染视频重叠时,没有观察到闪烁。