Weird behaviour on the Raspberry Pi

I’ve noticed some weird behaviour on the Raspberry Pi. Take a look at the
following little example code:

#include <SDL.h>

int main(int argc, char *argv[])
{
SDL_Window *window;
SDL_Renderer *renderer;
SDL_Texture *texture1, *texture2, *texture3;
SDL_Event se;
int quit = 0, k;
int w = 295, reverse = 0;
char *pixbuf = malloc(640 * 480 * 4);
unsigned int *ptr;

SDL_Init(SDL_INIT_VIDEO);
SDL_VideoInit("RPI");

window = SDL_CreateWindow("Foo", 0, 0, 640, 480, 0);
renderer = SDL_CreateRenderer(window, -1, 0);
texture1 = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 640, 480);
texture2 = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 640, 480);

memset(pixbuf, 0, 640 * 480 * 4);
SDL_UpdateTexture(texture1, NULL, pixbuf, 640 * 4);	
SDL_RenderCopy(renderer, texture1, NULL, NULL);
SDL_RenderPresent(renderer);

ptr = (unsigned int *) pixbuf;
for(k = 0; k < 640 * 480; k++) *ptr++ = 0xffff0000;
SDL_UpdateTexture(texture2, NULL, pixbuf, 640 * 4);	

SDL_ShowWindow(window);
SDL_RaiseWindow(window);

while(!quit) {

	SDL_RenderCopy(renderer, texture1, NULL, NULL);

	texture3 = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, w, w);
	SDL_SetRenderTarget(renderer, texture3);
	SDL_SetTextureBlendMode(texture2, SDL_BLENDMODE_NONE);	
	SDL_RenderCopy(renderer, texture2, NULL, NULL);
	SDL_SetTextureBlendMode(texture3, SDL_BLENDMODE_BLEND);	
	SDL_SetRenderTarget(renderer, NULL);
	SDL_RenderCopy(renderer, texture3, NULL, NULL);

	SDL_RenderPresent(renderer);
	
	while(SDL_PollEvent(&se)) {
		if(se.type == SDL_MOUSEBUTTONDOWN) quit = 1;
	}

	SDL_DestroyTexture(texture3);

	if(reverse) {
		w -= 10;	
	} else {
		w += 10;
	}

	if(w >= 640) {
		w = 640;
		reverse = 1;
	} else if(w <= 2) {
		w = 2;
		reverse = 0;	
	}
}	

SDL_DestroyTexture(texture1);
SDL_DestroyTexture(texture2);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);

SDL_Quit();

free(pixbuf);

return 0;

}

On Windows, Linux & Mac this always fills the screen with red. On the Raspberry Pi,
however, the screen alternates between red and black. It is mostly red, but sometimes
it’s also black, so it looks really weird.

Is that a bug in my code or in SDL’s Pi backend?–
Best regards,
Andreas Falkenhahn mailto:@Andreas_Falkenhahn

Andreas Falkenhahn wrote:

Is that a bug in my code or in SDL’s Pi backend?

One thing I would question is that there’s no SDL_RenderClear(). The docs say “You are strongly encouraged to call SDL_RenderClear() to initialize the backbuffer before starting each new frame’s drawing”. Does it make any difference if you change it as follows:

Code:
SDL_SetRenderTarget(renderer, NULL);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture3, NULL, NULL);
SDL_RenderPresent(renderer);

Richard.

One thing I would question is that there’s no SDL_RenderClear().
The docs say “You are strongly encouraged to call SDL_RenderClear()
to initialize the backbuffer before starting each new frame’s
drawing”. Does it make any difference if you change it as follows:

No, doesn’t make any difference. The screen still alternates between
red and black. Here is the updated code for reference:

#include <SDL.h>

int main(int argc, char *argv[])
{
SDL_Window *window;
SDL_Renderer *renderer;
SDL_Texture *texture1, *texture2, *texture3;
SDL_Event se;
int quit = 0, k;
int w = 295, reverse = 0;
char *pixbuf = malloc(640 * 480 * 4);
unsigned int *ptr;

SDL_Init(SDL_INIT_VIDEO);
SDL_VideoInit("RPI");

window = SDL_CreateWindow("Foo", 0, 0, 640, 480, 0);
renderer = SDL_CreateRenderer(window, -1, 0);
texture1 = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 640, 480);
texture2 = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 640, 480);

memset(pixbuf, 0, 640 * 480 * 4);
SDL_UpdateTexture(texture1, NULL, pixbuf, 640 * 4);	
SDL_RenderCopy(renderer, texture1, NULL, NULL);
SDL_RenderPresent(renderer);

ptr = (unsigned int *) pixbuf;
for(k = 0; k < 640 * 480; k++) *ptr++ = 0xffff0000;
SDL_UpdateTexture(texture2, NULL, pixbuf, 640 * 4);	

SDL_ShowWindow(window);
SDL_RaiseWindow(window);

while(!quit) {

	texture3 = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, w, w);

	SDL_SetRenderTarget(renderer, texture3);
	SDL_SetTextureBlendMode(texture2, SDL_BLENDMODE_NONE);	
	SDL_RenderCopy(renderer, texture2, NULL, NULL);
	SDL_SetTextureBlendMode(texture3, SDL_BLENDMODE_BLEND);	

	SDL_SetRenderTarget(renderer, NULL);
	SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
  		SDL_RenderClear(renderer);
	SDL_RenderCopy(renderer, texture1, NULL, NULL);
	SDL_RenderCopy(renderer, texture3, NULL, NULL);
	SDL_RenderPresent(renderer);
	
	while(SDL_PollEvent(&se)) {
		if(se.type == SDL_MOUSEBUTTONDOWN) quit = 1;
	}

	SDL_DestroyTexture(texture3);

	if(reverse) {
		w -= 10;	
	} else {
		w += 10;
	}

	if(w >= 640) {
		w = 640;
		reverse = 1;
	} else if(w <= 2) {
		w = 2;
		reverse = 0;	
	}
}	

SDL_DestroyTexture(texture1);
SDL_DestroyTexture(texture2);

SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);

SDL_Quit();

free(pixbuf);

return 0;

}On 28.09.2016 at 17:59 rtrussell wrote:


Best regards,
Andreas Falkenhahn mailto:@Andreas_Falkenhahn

Can you simplify this example with fewer textures and RTT calls and still
get this behavior?

Jonny DOn Wed, Sep 28, 2016 at 12:40 PM, Andreas Falkenhahn <andreas at falkenhahn.com wrote:

On 28.09.2016 at 17:59 rtrussell wrote:

One thing I would question is that there’s no SDL_RenderClear().
The docs say “You are strongly encouraged to call SDL_RenderClear()
to initialize the backbuffer before starting each new frame’s
drawing”. Does it make any difference if you change it as follows:

No, doesn’t make any difference. The screen still alternates between
red and black. Here is the updated code for reference:

#include <SDL.h>

int main(int argc, char *argv[])
{
SDL_Window *window;
SDL_Renderer *renderer;
SDL_Texture *texture1, *texture2, *texture3;
SDL_Event se;
int quit = 0, k;
int w = 295, reverse = 0;
char *pixbuf = malloc(640 * 480 * 4);
unsigned int *ptr;

    SDL_Init(SDL_INIT_VIDEO);
    SDL_VideoInit("RPI");

    window = SDL_CreateWindow("Foo", 0, 0, 640, 480, 0);
    renderer = SDL_CreateRenderer(window, -1, 0);
    texture1 = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888,

SDL_TEXTUREACCESS_STREAMING, 640, 480);
texture2 = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING, 640, 480);

    memset(pixbuf, 0, 640 * 480 * 4);
    SDL_UpdateTexture(texture1, NULL, pixbuf, 640 * 4);
    SDL_RenderCopy(renderer, texture1, NULL, NULL);
    SDL_RenderPresent(renderer);

    ptr = (unsigned int *) pixbuf;
    for(k = 0; k < 640 * 480; k++) *ptr++ = 0xffff0000;
    SDL_UpdateTexture(texture2, NULL, pixbuf, 640 * 4);

    SDL_ShowWindow(window);
    SDL_RaiseWindow(window);

    while(!quit) {

            texture3 = SDL_CreateTexture(renderer,

SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, w, w);

            SDL_SetRenderTarget(renderer, texture3);
            SDL_SetTextureBlendMode(texture2, SDL_BLENDMODE_NONE);
            SDL_RenderCopy(renderer, texture2, NULL, NULL);
            SDL_SetTextureBlendMode(texture3, SDL_BLENDMODE_BLEND);

            SDL_SetRenderTarget(renderer, NULL);
            SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
            SDL_RenderClear(renderer);
            SDL_RenderCopy(renderer, texture1, NULL, NULL);
            SDL_RenderCopy(renderer, texture3, NULL, NULL);
            SDL_RenderPresent(renderer);

            while(SDL_PollEvent(&se)) {
                    if(se.type == SDL_MOUSEBUTTONDOWN) quit = 1;
            }

            SDL_DestroyTexture(texture3);

            if(reverse) {
                    w -= 10;
            } else {
                    w += 10;
            }

            if(w >= 640) {
                    w = 640;
                    reverse = 1;
            } else if(w <= 2) {
                    w = 2;
                    reverse = 0;
            }
    }

    SDL_DestroyTexture(texture1);
    SDL_DestroyTexture(texture2);

    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);

    SDL_Quit();

    free(pixbuf);

    return 0;

}


Best regards,
Andreas Falkenhahn mailto:
andreas at falkenhahn.com


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Can you simplify this example with fewer textures and RTT calls and still get this behavior?

It works correctly when disabling scaling, i.e. changing the following line

texture3 = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, w, w);

into this line

texture3 = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, 640, 480);

solves the problem and there is no alternation between red and black screens any
more. The problem only seems to appear when the dimensions of texture3 and texture2
don’t match, i.e. when SDL_RenderCopy() needs to scale-copy texture2 to texture3
instead of just copying it without the involvement of scaling.On 28.09.2016 at 18:44 Jonathan Dearborn wrote:


Best regards,
Andreas Falkenhahn mailto:@Andreas_Falkenhahn

Filed this now as

https://bugzilla.libsdl.org/show_bug.cgi?id=3455

because it clearly seems to be a bug in the Raspi backend.On 29.09.2016 at 17:16 Andreas Falkenhahn wrote:

On 28.09.2016 at 18:44 Jonathan Dearborn wrote:

Can you simplify this example with fewer textures and RTT calls and still get this behavior?

It works correctly when disabling scaling, i.e. changing the following line

    texture3 = SDL_CreateTexture(renderer,

SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, w, w);

into this line

    texture3 = SDL_CreateTexture(renderer,

SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, 640, 480);

solves the problem and there is no alternation between red and black screens any
more. The problem only seems to appear when the dimensions of texture3 and texture2
don’t match, i.e. when SDL_RenderCopy() needs to scale-copy texture2 to texture3
instead of just copying it without the involvement of scaling.


Best regards,
Andreas Falkenhahn mailto:@Andreas_Falkenhahn