2

単一のスレッドを使用して、キャンバスのロック/ロック解除を使用して UI スレッドから 3 つの個別の TextureView をレンダリングしようとしています。観測された問題は、描画されている各テクスチャ ビューの一貫したちらつきであり、ちらつきは異なる TextureView のフレームで構成されています。たとえば、フレーム A、B、C の順に描画します。フレーム C は問題なく表示されますが、フレーム A と B はフレーム C のインスタンスでときどきちらつき、フレーム A はフレーム B のインスタンスでときどきちらつきます。

Android Core Graphics について説明したドキュメントを読み、Android のフレーム バッファリング システムがどのように機能するかをかなりよく理解しています。一言で言えば、私の疑いは、lockCanvas/unlockCanvasAndPost 呼び出しを連続して実行するのが速すぎて、フレームバッファが要求を完了できず、代わりに前の (間違った) フレームを単に描画することです。

この問題を解決するために、いくつかのことを試しました。キャンバスの呼び出しを続行する前に Choreographer を使用して VSYNC を待機しようとすると、問題は解決しませんでしたが、予想どおりフレーム レートが低下しました。また、別の render loop 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);
}
4

1 に答える 1

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 がある場所ならどこでもアクティビティ全体をカバーします。見えないようにするには、アルファを 0.01 以下の値に設定する必要があります。

この回避策は、ビデオをレンダリングする 2 つの textureviews がオーバーラップするとちらつきが観察されないという私の観察に基づいていました。

于 2015-10-10T10:22:55.430 に答える