mikrocontroller.net

Forum: PC-Programmierung SDL2: Flackern unter Windows 10


Autor: Walter T. (nicolas)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich habe eine kleine LCD-Emulation in SDL2 geschrieben, um eine schnelle 
Ansicht der Grafik an meinem Mikrocontroller zu haben - zu Testzwecken 
und für die Bilder in der Doku.

Auf meinem PC, der leider mit Windows 10 läuft, ist die Ansicht auf in 
Ordnung. Auf einem anderen PC, auch mit Windows 10, flackert der 
Fensterinhalt heftig.

Es sieht so aus, als schriebe jeder Aufruf der eigentlichen 
Zeichenroutinen in ein anderes Halbbild.

Seit wann? Das kann ich nicht sagen. Die Display-Emulation ist schon 
uralt, und wurde schon recht lange nicht mehr an besagtem Rechner 
getestet.

Die eigentlichen Zeichen-Routinen sind unglaublich banal:
    /* Variablen und Konstanten fuer Display-Emulation */
    const char headline[] = "TFT ILI9341 Emulation";
    SDL_Window   * pWindow;
    SDL_Renderer * pRenderer;
    SDL_Texture * pTexture;


    /* Grafik-Teil des Mockups mit SDL initialisieren */
    exit_t tft_sdl_init(void)
    {
        SDL_Init(SDL_INIT_VIDEO);

        int ret = SDL_InitSubSystem(SDL_INIT_VIDEO);
        assert( ret == 0 );

        pWindow = SDL_CreateWindow(headline,
                SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
                LCD_EMULATION_SCALE*TFT_WIDTH_PX,
                LCD_EMULATION_SCALE*TFT_HEIGHT_PX,
                0);

        pRenderer = SDL_CreateRenderer(pWindow, -1, 0);
        SDL_RenderSetScale(pRenderer, 1.0 * LCD_EMULATION_SCALE, 1.0 * LCD_EMULATION_SCALE);

        uint32_t pixelformat = SDL_PIXELFORMAT_RGB565;

        pTexture = SDL_CreateTexture(pRenderer,
                pixelformat, SDL_TEXTUREACCESS_STATIC,
                TFT_WIDTH_PX,
                TFT_HEIGHT_PX);

        return EXIT_SUCCESS;
    }



    /* Vorschriftsmaessige Beendigung vorbereiten */
    void tft_sdl_deinit(void)
    {
        SDL_DestroyTexture(pTexture);
        SDL_DestroyRenderer(pRenderer);
        SDL_DestroyWindow(pWindow);
        SDL_QuitSubSystem(SDL_INIT_VIDEO);
    }


    /* Rechteck-Koordinaten umwandeln */
    static inline SDL_Rect rect2sdl(Rect_t R)
    {
        SDL_Rect S;
        S.x = R.x;
        S.y = R.y;
        S.w = R.w;
        S.h = R.h;
        return S;
    }


    /* Gefuelltes Rechteck zeichnen
     *  return: Anzahl der gezeichneten Pixel
     *  Die Pruefung, ob das gezeichnete Rechteck noch im erlauben Bereich liegt, erfolgt in der 
     *  aufrufenden static_inline Funktion tft_drawRect() */
    // FIXME: Jeder Aufruf dieser Funktion scheint in ein anderes Halbbild zu zeichnen
    ufast24_t tft_sdl_drawRectF_noclip(Rect_t R, uint16_t color)
    {
        //tft_clipkoord(&Pos, &Size); clipping wird von static-inline-Funktion vorgenommen

        SDL_Rect Rect = rect2sdl(R);

        Rgb24_t Rgb = color_rgb16to24_s(color);

        #if 1 
            // FIXME: REMOVEME abschaltbar, um sicherzustellen, dass wirklich alle Zeichenfunktionen
            // ueber diese Funktion zeichnen
            SDL_SetRenderDrawColor(pRenderer, Rgb.r, Rgb.g, Rgb.b, SDL_ALPHA_OPAQUE );
            SDL_RenderFillRect(pRenderer, &Rect);
            SDL_RenderPresent(pRenderer);
            // SDL_Delay(10); // Macht das Ergebnis nicht besser, nur langsamer
        #endif

        return (uint_fast24_t) R.w * R.h;
    }

Dass die Zeichen-Funktionen uralt sind, heisst ja nicht, dass sie 
korrekt sind. Screenshots des Fehlerbildes kann ich gerade nicht machen, 
weil ich am anderen Rechner bin. Aber es ist kein einfacher dynamischer 
Effekt wie tearing - die abwechselnden Halbbilder sind auch in 
Screenshots vorhanden.

Hat jemand einen Tipp für mich?

: Bearbeitet durch User
Autor: Walter T. (nicolas)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier sind mal Screenshots, damit man weiss, was ich mit "Halbbilder" 
meine:

Das erste Testbild soll mehrere Farbverlaufsbalken, darüber gezeichnet 
zwei konzentrische Kreise mit 1px Breite und vier Diagonalen darstellen. 
Jeder horizontale Balken des Farbverlaufs und jedes Einzelpixel bei den 
Linien ist eine Schreiboperation, die mit SDL_RenderPresent() 
abgeschlossen wird (letztendlich jeweils ein einziger Aufruf von 
tft_sdl_drawRectF_noclip()).

Das zweite Testbild ist ein textlastiges Testbild. Der dunkelgraue 
Hintergrund wird in einer einzelnen Schreiboperation geschrieben. Jeder 
Buchstabe ist auch eine einzelne Schreiboperation. Die farbigen 
Piktogramme bestehen meistens aus etlichen unterschiedlich großen 
Schreiboperationen. Ausnahme sind nur das Schloß rechts und die Klemme 
links, die in nur einer Operation geschrieben werden.

Es sieht also so aus, als landeten Schreiboperationen alternierend auf 
unterschiedlichen Fensterebenen - oder wenn man es so nennen mag: In 
unterschiedlichen Doppelpufferhälften.

Insofern ist "Flackern" auch nicht unbedingt der richtige Ausdruck. 
Solange kein Update des Fensterinhalts erfolgt, steht das jeweilige 
Halbbild still.


Alle mir bekannten Kompatibilitätseinstellungen unter Windows für die 
Ausführung der *.exe-Datei habe ich natürlich schon ausprobiert.

: Bearbeitet durch User
Autor: Walter T. (nicolas)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So. Ich habe jetzt mehrere Windows-10-Rechner ausprobiert, und der 
meinige ist der einzige, der diese Grafikfehler anzeigt.

Außerdem zeigt er diese Grafikfehler jetzt auch in einer alten Version, 
des Programms, die damals fehlerfrei angezeigt wurde.

Da muß jetzt nicht heißen, dass von einem der letzten Windows-Updates 
etwas vermurkst wurde - vielleicht hat es nur einen 
Implementierungsfehler meinerseits aufgedeckt.

Aber das heisst auch, dass der Fehler -wenn er auf meiner Seite ist- 
sehr schwer zu finden sein wird, weil er auf anderen Rechnern nicht 
nachvollziehbar ist. Höchstens durch Code-Audit, und das wird wohl 
keiner machen.

Schade.

: Bearbeitet durch User
Autor: Walter T. (nicolas)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachtrag: Das Problem ist verschwunden. Ich habe einen neuen 
NVidia-Treiber installiert und das Problem ist verschwunden.

Irgendwie ist das peinlich, nicht vorher auf die Idee zu kommen. Und 
irgendwie erschreckend, dass bei einer popeligen 
2D-Fenster-Pixel-Ansicht der Grafikkartentreiber immer noch in die Suppe 
spucken kann.

Für mich ist das Problem erledigt. Möge mein Monolog jemandem, der auf 
ein ähnliches Problem stößt, hilfreich sein.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.