We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 3455

Summary: Gfx glitches on the Raspberry Pi when scale-copying textures
Product: SDL Reporter: Andreas Falkenhahn <andreas>
Component: videoAssignee: Gabriel Jacobo <gabomdq>
Status: ASSIGNED --- QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: stsp2
Version: 2.0.4   
Hardware: ARM   
OS: Linux   

Description Andreas Falkenhahn 2016-10-14 21:29:10 UTC
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. 

Tests have shown that the issue is related to scaling. 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.