Homebrew Best way to draw pixel buffer

bayleef

Well-Known Member
OP
Newcomer
Joined
Sep 15, 2015
Messages
83
Trophies
0
XP
254
Country
Gambia, The
Hello,

I want to draw raw RGBA buffer to screen. Until now, I used sf2d, but it seems overkill for this task: I have to create and free textures all the time.
Code:
sf2d_texture* top_screen = sf2d_create_texture(400, 240, TEXFMT_RGBA8, SF2D_PLACE_RAM);
sf2d_fill_texture_from_RGBA8(top_screen, buffer, 400, 240);
sf2d_texture_tile32(top_screen);
sf2d_start_frame(GFX_TOP, GFX_LEFT);
sf2d_draw_texture(top_screen,0,0);
sf2d_end_frame();
sf2d_swapbuffers();
sf2d_free_texture(top_screen);

So, I tried do use gfx directly. For my opinion, the code looks much better this way: I save allocating and deallocating memory all over the time.
Code:
memcpy(gfxGetFramebuffer(GFX_TOP,GFX_LEFT,0,0), buffer, 4*240*400);
gfxFlushBuffers();
gfxSwapBuffers();
gspWaitForVBlank();

However, I have the following problem: When I suspend the cia, the top screen turns black. With sf2d this problem did not exist. I've created a minimal example to demonstrate the problem:
Code:
#include <3ds.h>

#define WIDTH 240
#define HEIGHT 400

void fill_buffer(u32* buffer, u32 color) {
    int x,y;
    for (y=0;y<HEIGHT;y++) {
        for (x=0;x<WIDTH;x++) {
            buffer[x+y*WIDTH] = color;
        }
    }
}

int main() {
    gfxInit(GSP_RGBA8_OES, GSP_RGBA8_OES, false);
    gfxSetDoubleBuffering(GFX_TOP,1);
    while(aptMainLoop()) {
        hidScanInput();
        // fill top screen with red
        fill_buffer((u32*)gfxGetFramebuffer(GFX_TOP,GFX_LEFT,0,0), 0xFF0000FF);
        gfxFlushBuffers();
        gfxSwapBuffers();
        gspWaitForVBlank();
    }
    gfxExit();
    return 0;
}

What can I do to fix the issue? And notably, is using gfx this way really better to solve my task? I.e., what is the best (i.e. fastest) way to copy a pixel buffer to screen? Should I use citro3d (is there a minimal example)?
 
Last edited by bayleef,

elhobbs

Well-Known Member
Member
Joined
Jul 28, 2008
Messages
1,044
Trophies
1
XP
3,033
Country
United States
Hello,

I want to draw raw RGBA buffer to screen. Until now, I used sf2d, but it seems overkill for this task: I have to create and free textures all the time.
Code:
sf2d_texture* top_screen = sf2d_create_texture(400, 240, TEXFMT_RGBA8, SF2D_PLACE_RAM);
sf2d_fill_texture_from_RGBA8(top_screen, buffer, 400, 240);
sf2d_texture_tile32(top_screen);
sf2d_start_frame(GFX_TOP, GFX_LEFT);
sf2d_draw_texture(top_screen,0,0);
sf2d_end_frame();
sf2d_swapbuffers();
sf2d_free_texture(top_screen);

So, I tried do use gfx directly. For my opinion, the code looks much better this way: I save allocating and deallocating memory all over the time.
Code:
memcpy(gfxGetFramebuffer(GFX_TOP,GFX_LEFT,0,0), buffer, 4*240*400);
gfxFlushBuffers();
gfxSwapBuffers();
gspWaitForVBlank();

However, I have the following problem: When I suspend the cia, the top screen turns black. With sf2d this problem did not exist. I've created a minimal example to demonstrate the problem:
Code:
#include <3ds.h>

#define WIDTH 240
#define HEIGHT 400

void fill_buffer(u32* buffer, u32 color) {
    int x,y;
    for (y=0;y<HEIGHT;y++) {
        for (x=0;x<WIDTH;x++) {
            buffer[x+y*WIDTH] = color;
        }
    }
}

int main() {
    gfxInit(GSP_RGBA8_OES, GSP_RGBA8_OES, false);
    gfxSetDoubleBuffering(GFX_TOP,1);
    while(aptMainLoop()) {
        hidScanInput();
        // fill top screen with red
        fill_buffer((u32*)gfxGetFramebuffer(GFX_TOP,GFX_LEFT,0,0), 0xFF0000FF);
        gfxFlushBuffers();
        gfxSwapBuffers();
        gspWaitForVBlank();
    }
    gfxExit();
    return 0;
}

What can I do to fix the issue? And notably, is using gfx this way really better to solve my task? I.e., what is the best (i.e. fastest) way to copy a pixel buffer to screen? Should I use citro3d (is there a minimal example)?
It depends on what you are trying to do. If there is no texture reuse and no transforms (scaling,rotation, skew, etc)of the objects you are displaying then it is probably best to draw directly to the framebuffer. also depending on what you are doing it may not matter at all. If drawing to the framebuffer is easier then do it. If performance becomes an issue then figure out where the issue is and address it.
 

bayleef

Well-Known Member
OP
Newcomer
Joined
Sep 15, 2015
Messages
83
Trophies
0
XP
254
Country
Gambia, The
It depends on what you are trying to do. If there is no texture reuse and no transforms (scaling,rotation, skew, etc)of the objects you are displaying then it is probably best to draw directly to the framebuffer. also depending on what you are doing it may not matter at all. If drawing to the framebuffer is easier then do it. If performance becomes an issue then figure out where the issue is and address it.
Okay, I could reuse a lot of very small textures (causing a lot of memory overhead due to minimal texture size) and – partially – some larger parts, but it would be really complicated. Thus, I really should draw to buffer directly.

How could I fix the issue with the black screen? Is it a bug in ctrulib or am I doing something wrong?
 
Last edited by bayleef,

nop90

Well-Known Member
Member
Joined
Jan 11, 2014
Messages
1,556
Trophies
0
Location
Rome
XP
3,136
Country
Italy
After suspending the app the framebuffer position in memory may change. Get again the framebuffer pointer when returning to the app.
 

bayleef

Well-Known Member
OP
Newcomer
Joined
Sep 15, 2015
Messages
83
Trophies
0
XP
254
Country
Gambia, The
After suspending the app the framebuffer position in memory may change. Get again the framebuffer pointer when returning to the app.
I do so (see minimal example in original post). After return, everything is fine. The screen where the frozen app should be displayed in background (home menu screen) only shows a black background (instead of a red one).
 

bayleef

Well-Known Member
OP
Newcomer
Joined
Sep 15, 2015
Messages
83
Trophies
0
XP
254
Country
Gambia, The
I've solved the problem. If anybody runs into the same problem: The problem was caused by the frame buffer format. When replacing GSP_RGBA8_OES by GSP_BGR8_OES, everything works fine. So, it may be a ctrulib (or a Nintendo) bug.
 

nop90

Well-Known Member
Member
Joined
Jan 11, 2014
Messages
1,556
Trophies
0
Location
Rome
XP
3,136
Country
Italy
Or maybe could be a problem with the value of the alpha channel.

If you write directly in the framebuffer, it can't be a ctrulib bug. And such a bug in the firmware is unlikely.
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • BigOnYa @ BigOnYa:
    New Vegas is awesome, F3 was ok too.
  • Psionic Roshambo @ Psionic Roshambo:
    I played Fallout 4 on PC, I enjoyed it honestly. Not my favorite game on earth but at the same time I didn't hate it at all lol
  • BigOnYa @ BigOnYa:
    That's cool you got a ps3... Glad to hear. Game on!
    +1
  • Psionic Roshambo @ Psionic Roshambo:
    Ironic this was posted today lol
  • BigOnYa @ BigOnYa:
    I think the tv series has boasted play of, I did see they said playing of it Is up, way more than norm
    +1
  • BigOnYa @ BigOnYa:
    I've been playing the next gen version on Series X all day, I love it. :wub:
    +1
  • Psionic Roshambo @ Psionic Roshambo:
    Downloading some random stuff, damn almost 400GBs in like 4 hours lol
  • Psionic Roshambo @ Psionic Roshambo:
    Gonna be over 1TB this month.... damn lol
  • Xdqwerty @ Xdqwerty:
    good night
    +1
  • BigOnYa @ BigOnYa:
    At least you have some fast speeds. What a drag that used to be, I remb downloading 1 pic back in the day, and seeing line by line show
    +1
  • BigOnYa @ BigOnYa:
    Nighty night.
  • BigOnYa @ BigOnYa:
    Or worse, you downloading something, and someone calls your phone and interupts the download, good ole AOL. Of course that's before most you guys even were born yet.
  • Psionic Roshambo @ Psionic Roshambo:
    Lol I think my first modem was 48K but it had some sort of firmware or software update that let me get 56K
    +1
  • Psionic Roshambo @ Psionic Roshambo:
    I had EarthLink lol
  • Psionic Roshambo @ Psionic Roshambo:
    A bunch of NetZero accounts that I used for things... Lol
    +1
  • Psionic Roshambo @ Psionic Roshambo:
    So glad I'm not in prison lol
  • BigOnYa @ BigOnYa:
    Yea marriage is a bitch sometimes...
  • Psionic Roshambo @ Psionic Roshambo:
    I legit think they passed the cyber terrorism laws from some of my hmm pranks lol
  • Psionic Roshambo @ Psionic Roshambo:
    I knocked the east coast backbone of EarthLink offline for like 6 hours one time, was on the news and everything well I mean I wasn't on the news.... Just they where having "technical difficulties" lol
    +1
  • Psionic Roshambo @ Psionic Roshambo:
    Was just one single custom packet. I miss when Internet security was an afterthought lol almost all modems and network hardware operated in promiscuous mode.
  • Psionic Roshambo @ Psionic Roshambo:
    Now these days they do sanity checks.... The source IP can't also be the destination IP lol
  • Psionic Roshambo @ Psionic Roshambo:
    They did end up using some of my stuff in the first Gulf war though lol
  • BakerMan @ BakerMan:
    GUYS I JUST COMMENTED A YOUR MOM JOKE ON A GACHA YT COMMUNITY POST (the algorithm has cursed me in terms of community posts, bc I fuck around on that sort of community post, just commenting and being a jackass)
    +1
  • BakerMan @ BakerMan:
    IT FELT SO GOOD
    +1
    BakerMan @ BakerMan: IT FELT SO GOOD +1