SurfaceView flimmern/tearing

Ich versuche, herauszufinden, wie die Arbeit sich um mein problem. Ich habe gelesen, http://groups.google.com/group/android-developers/browse_thread/thread/a2aac88a08cb56c2/b7dff4ba388cd664?lnk=gst&q=SurfaceView#b7dff4ba388cd664 die Art von Antworten, die meine Frage aber soweit ich sagen kann, es ist eine Art von "Pech gehabt" Antworten. Also hier mein problem:

Ich bin mit SurfaceView in der üblichen Weise (lock/unlockAndPost) zum zeichnen einer bitmap auf mein Spiel im hintergrund, wenn die Oberfläche verändert wird (z.B. Orientierung etc) und ich bin rendering eine Reihe von bewegten Kreise (bis zu 30 mit einem radius von etwa 25.f). Die x -, y-Daten für die Positionen dieser Kreise ist, die von einem server und alles läuft wunderbar.
Alle circle-Objekte werden in einer Liste gespeichert, und Ihre position wird aktualisiert, wobei darauf zu achten ist das update synchronisiert wird.
Allerdings, wenn ich ziehen diese Kreise, auf dem Bildschirm (während der Leinwand.lock() ), die meisten der Zeit, die Sie machen, gut, aber gelegentlich (z.B. einmal alle paar Sekunden) einige Kreise scheinen sich zu reißen oder flackern Sie kurz, für einen Rahmen. Die Anzahl der Kreise ist immer konstant, das ist also nicht das problem und es gibt keine gleichzeitigen änderungen an der Liste der Kreise (wie gesagt, es ist synchronisiert).
Ich habe sogar versucht die Zeichnung, die alle diese Kreise zu einem Bitmap auf jedem render loop und Zeichnung, bitmap, um die wichtigsten Leinwand. Dies scheint nur Einfluss auf die perfomance sogar noch mehr (~13FPS im Gegensatz zu ~30 FPS, wenn das zeichnen von Kreisen direkt zur Hauptseite der Leinwand).
Sorry, wenn die Informationen, ist ein wenig vage Jungs, (versuchen zu halten, das Unternehmen freut sich :p ), aber ich Frage mich, ob jemand kann mir eine Ahnung? Oder bin ich nur Pech. Ich sollte beachten Sie, dass die Positionierung der Daten, die vom server kommt ist die Echtzeit-Daten, und es ist äußerst wichtig, dass die Darstellung spiegelt die Echtzeit-Positionen.

Vielen Dank für jede Hilfe!!!
Chris

EDIT:

Fair genug. Hier ist die run() aus der render-thread.

@Override
    public void run() {
        Canvas c;
        while (mRun) {
            c = null;
            try {
                c = mSurfaceHolder.lockCanvas(null);
                synchronized (mSurfaceHolder) {
                    panel.onDraw(c);
                }
            } finally {
                if (c != null) {
                    mSurfaceHolder.unlockCanvasAndPost(c);
                }
            }
        }
    }

Ziemlich standard-Sachen, die (fast eine Kopie des lunar lander :p)

@Override
public void surfaceCreated(SurfaceHolder holder) {
    mBackground= Bitmap.createBitmap(this.getWidth(), this.getHeight(), Bitmap.Config.RGB_565);
    screenOrientation = getResources().getConfiguration().orientation;
    if(thread.getState()== Thread.State.TERMINATED){
        thread = new RenderThread(holder, this);
        thread.setRunning(true);
        thread.start();
    }else {
        thread.setRunning(true);
        thread.start();
    }
}



@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
    Canvas c = new Canvas(mField);
    c.drawARGB(255,0,144,0);
    backgroundDetails.renderOnPanel(c, this);
    screenOrientation = getResources().getConfiguration().orientation;
}

Ziemlich einfach zu Folgen, nur zeichnen das hintergrund-bitmap, wenn die Ausrichtung änderungen und starten Sie den rendering-thread.

public void onDraw(Canvas canvas) {
    canvas.drawBitmap(mField,0,0,null);
    drawPositionBeans(canvas, this);
}

Und schließlich:

    public void onDraw(Canvas canvas, RadarView radarView) {
    float beanX=0, beanY=0;
    float radius = 25.0f;
    final List<PositionBean> copyOfList = Collections.synchronizedList(positionBeans.getPositionBeans());
    synchronized(copyOfList){
        try {
            for (final PositionBean pb : copyOfList)
            {
                if (panel.getOrientation() == Configuration.ORIENTATION_PORTRAIT) {
                    beanX = (float)pb.getY()*(-1);
                    beanY = (float)pb.getX();
                } else {
                    beanX = (float)pb.getY()*(-1);
                    beanY = (float)pb.getX()*(-1);
                }
                mPaint.setARGB(255,pb.getRgbColor().getR(), pb.getRgbColor().getG(), pb.getRgbColor().getB());
                panel.drawSpot(canvas, beanX, beanY, radius, mPaint);

                mPaint.setStyle(Paint.Style.STROKE);
                mPaint.setARGB(255,255,222,1);
                for (int j = 0; j < selectedBean.size(); ++j)
                {
                    if(pb.getTrack()==selectedBean.get(j)) {
                        panel.drawSpot(canvas, beanX, beanY, radius+1, mPaint);
                    }
                }
                mPaint.setStyle(Paint.Style.FILL);
            }

        } catch(Exception e) {
            Log.e("render", "Exception Drawing Beans: " + e);
        }
    }
}

Nochmals vielen Dank Jungs.
Chris

  • Unmöglich zu beantworten, ohne zu sehen, dein gameloop und zeichnen-code.
  • Gleiche wie Sebi schon sagte - ein Codebeispiel wäre hilfreich - aber haben Sie als die Möglichkeit, dass die Positionen, die Sie erhalten gelegentlich falsch sind? Nur so ein Gedanke, warum die Kreise könnten "flimmern", wenn Sie positioniert off-Ansicht. Wieder, ohne code wird dies unmöglich zu beantworten.
  • Vielen Dank für die Hilfe Jungs. Aber ja, ich bin sicher, dass die Positionierung der Daten korrekt ist.
  • Ich habe auch bemerkt, dass jetzt mein positionUpdate thread läuft bei 500-1000 FPS (ich weiß, Breite Palette), die ich empfangen von Paketen bei ~20-70 FPS, und ich bin rendering zwischen 15-30 FPS. Wäre dies verursacht keine Probleme? Ich hätte gedacht, dass die Synchronisierten Art des Rendern aufgehört hätte irgendwelche Probleme damit?
InformationsquelleAutor Sonoman | 2010-08-26
Schreibe einen Kommentar