Android thread controlling multiple texture views causes strange flickering

北城余情 提交于 2019-11-28 09:34:13

问题


I am trying to use a single thread to render three separate TextureView's off the UI thread using canvas lock/unlock. The problem observed is the consistent flickering of each of the Texture Views being drawn, with the flicker consisting of a DIFFERENT TextureView's frame. So for example, I draw frames A,B and C in that order. Frame C will appear fine, however frames A and B will flicker with occasional instances of Frame C, and frame A will occasionally flicker with instances of Frame B.

I have read through the documentation describing Android Core Graphics, and have a fairly good understanding of how android's frame buffering system works. In a nutshell, my suspicion is that I am performing lockCanvas/unlockCanvasAndPost call's too quickly in succession, and that the framebuffer is unable to complete my request and simply draws the previous (incorrect) frame instead.

I've tried several things to resolve this issue. Attempting to use Choreographer to wait for VSYNC before continuing to call canvas helped, but as expected lowered my frame rate however the problem was still there. I've also tried an alternative render loop sans sleep command, with no difference in the observed phenomenon.

Essentially I am out of ideas on how to tackle this problem, and was hoping to get some outside input on it. Thanks in advance, code snippet is below:

Main render loop:

 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() method:

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);
}

回答1:


I was able to find a workaround for this. (i dont observe this on android 5.0 and above).

Add a psuedo transparent view like below

            <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" />

which covers the entire activity wherever there is a textureView. the alpha should be set to 0.01 or a smaller value to make it seem invisible.

This workaround was based on my observation that when the two textureviews rendering videos overlap the flicker is not observed.



来源:https://stackoverflow.com/questions/31124496/android-thread-controlling-multiple-texture-views-causes-strange-flickering

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!