Add gspGetBytesPerPixel (replaces internal function)

Also fixes GSPGPU_FramebufferFormat's name
This commit is contained in:
fincs 2020-06-12 19:24:15 +02:00
parent 6c0f7ac99c
commit 528f8feb0b
No known key found for this signature in database
GPG Key ID: 62C7609ADA219C60
6 changed files with 50 additions and 53 deletions

View File

@ -42,7 +42,7 @@ typedef enum
/**
* @brief Initializes the LCD framebuffers with default parameters
*
* By default ctrulib will configure the LCD framebuffers with the @ref GSP_BGR8_OES format in linear memory.
* By default libctru will configure the LCD framebuffers with the @ref GSP_BGR8_OES format in linear memory.
* This is the same as calling : @code gfxInit(GSP_BGR8_OES,GSP_BGR8_OES,false); @endcode
*
* @note You should always call @ref gfxExit once done to free the memory and services
@ -63,7 +63,7 @@ void gfxInitDefault(void);
* @note Even if the double buffering is disabled, it will allocate two buffer per screen.
* @note You should always call @ref gfxExit once done to free the memory and services
*/
void gfxInit(GSPGPU_FramebufferFormats topFormat, GSPGPU_FramebufferFormats bottomFormat, bool vrambuffers);
void gfxInit(GSPGPU_FramebufferFormat topFormat, GSPGPU_FramebufferFormat bottomFormat, bool vrambuffers);
/**
* @brief Closes the gsp service and frees the framebuffers.
@ -92,21 +92,21 @@ bool gfxIs3D(void);
* @param screen The screen of which format should be changed
* @param format One of the gsp pixel formats.
*/
void gfxSetScreenFormat(gfxScreen_t screen, GSPGPU_FramebufferFormats format);
void gfxSetScreenFormat(gfxScreen_t screen, GSPGPU_FramebufferFormat format);
/**
* @brief Gets a screen pixel format.
* @param screen Screen to get the pixel format of.
* @return the pixel format of the chosen screen set by ctrulib.
* @return the pixel format of the chosen screen set by libctru.
*/
GSPGPU_FramebufferFormats gfxGetScreenFormat(gfxScreen_t screen);
GSPGPU_FramebufferFormat gfxGetScreenFormat(gfxScreen_t screen);
/**
* @brief Sets whether to use ctrulib's double buffering
* @brief Sets whether to use libctru's double buffering
* @param screen Screen to toggle double buffering for.
* @param doubleBuffering Whether to use double buffering.
*
* ctrulib is by default using a double buffering scheme.
* libctru is by default using a double buffering scheme.
* If you do not want to swap one of the screen framebuffers when @ref gfxSwapBuffers or @ref gfxSwapBuffers is called,
* then you have to disable double buffering.
*

View File

@ -13,7 +13,7 @@
/**
* @brief Supported transfer pixel formats.
* @sa GSPGPU_FramebufferFormats
* @sa GSPGPU_FramebufferFormat
*/
typedef enum
{

View File

@ -26,7 +26,7 @@ typedef enum
GSP_RGB565_OES=2, ///< RGB565. (2 bytes)
GSP_RGB5_A1_OES=3, ///< RGB5A1. (2 bytes)
GSP_RGBA4_OES=4 ///< RGBA4. (2 bytes)
} GSPGPU_FramebufferFormats;
} GSPGPU_FramebufferFormat;
/// Capture info entry.
typedef struct
@ -57,6 +57,27 @@ typedef enum
GSPGPU_EVENT_MAX, ///< Used to know how many events there are.
} GSPGPU_Event;
/**
* @brief Gets the number of bytes per pixel for the specified format.
* @param format See \ref GSPGPU_FramebufferFormat.
* @return Bytes per pixel.
*/
static inline unsigned gspGetBytesPerPixel(GSPGPU_FramebufferFormat format)
{
switch (format)
{
case GSP_RGBA8_OES:
return 4;
default:
case GSP_BGR8_OES:
return 3;
case GSP_RGB565_OES:
case GSP_RGB5_A1_OES:
case GSP_RGBA4_OES:
return 2;
}
}
/// Initializes GSPGPU.
Result gspInit(void);

View File

@ -266,12 +266,6 @@
<arg nr="1"><not-uninit/></arg>
<arg nr="2"><not-uninit/></arg>
</function>
<function name="__get_bytes_per_pixel">
<leak-ignore/>
<pure/>
<noreturn>false</noreturn>
<arg nr="1"><not-uninit/></arg>
</function>
<function name="gfxSetFramebufferInfo">
<leak-ignore/>
<noreturn>false</noreturn>

View File

@ -26,8 +26,8 @@ static int doubleBuf[2] = {1,1};
Handle gspEvent, gspSharedMemHandle;
static GSPGPU_FramebufferFormats topFormat = GSP_BGR8_OES;
static GSPGPU_FramebufferFormats botFormat = GSP_BGR8_OES;
static GSPGPU_FramebufferFormat topFormat = GSP_BGR8_OES;
static GSPGPU_FramebufferFormat botFormat = GSP_BGR8_OES;
static GSPGPU_FramebufferInfo* const framebufferInfoSt[] = { &topFramebufferInfo, &bottomFramebufferInfo };
@ -44,26 +44,11 @@ bool gfxIs3D(void)
return enable3d;
}
u32 __get_bytes_per_pixel(GSPGPU_FramebufferFormats format) {
switch(format) {
case GSP_RGBA8_OES:
return 4;
case GSP_BGR8_OES:
return 3;
case GSP_RGB565_OES:
case GSP_RGB5_A1_OES:
case GSP_RGBA4_OES:
return 2;
}
return 3;
}
void gfxSetScreenFormat(gfxScreen_t screen, GSPGPU_FramebufferFormats format) {
void gfxSetScreenFormat(gfxScreen_t screen, GSPGPU_FramebufferFormat format) {
if (screenAlloc == NULL || screenFree == NULL) return;
if(screen==GFX_TOP)
{
u32 topSize = 400 * 240 * __get_bytes_per_pixel(format);
u32 topSize = 400 * 240 * gspGetBytesPerPixel(format);
if (gfxTopFramebufferMaxSize < topSize)
{
screenFree(gfxTopLeftFramebuffers[0]);
@ -78,7 +63,7 @@ void gfxSetScreenFormat(gfxScreen_t screen, GSPGPU_FramebufferFormats format) {
}
topFormat = format;
}else{
u32 bottomSize = 320 * 240 * __get_bytes_per_pixel(format);
u32 bottomSize = 320 * 240 * gspGetBytesPerPixel(format);
if (gfxBottomFramebufferMaxSize < bottomSize)
{
screenFree(gfxBottomFramebuffers[0]);
@ -91,7 +76,7 @@ void gfxSetScreenFormat(gfxScreen_t screen, GSPGPU_FramebufferFormats format) {
}
}
GSPGPU_FramebufferFormats gfxGetScreenFormat(gfxScreen_t screen) {
GSPGPU_FramebufferFormat gfxGetScreenFormat(gfxScreen_t screen) {
if(screen==GFX_TOP)
return topFormat;
else
@ -110,7 +95,7 @@ static void gfxSetFramebufferInfo(gfxScreen_t screen, u8 id)
topFramebufferInfo.framebuf0_vaddr=(u32*)gfxTopLeftFramebuffers[id];
if(enable3d)topFramebufferInfo.framebuf1_vaddr=(u32*)gfxTopRightFramebuffers[id];
else topFramebufferInfo.framebuf1_vaddr=topFramebufferInfo.framebuf0_vaddr;
topFramebufferInfo.framebuf_widthbytesize=240*__get_bytes_per_pixel(topFormat);
topFramebufferInfo.framebuf_widthbytesize=240*gspGetBytesPerPixel(topFormat);
u8 bit5=(enable3d!=0);
topFramebufferInfo.format=((1)<<8)|((1^bit5)<<6)|((bit5)<<5)|topFormat;
topFramebufferInfo.framebuf_dispselect=id;
@ -119,7 +104,7 @@ static void gfxSetFramebufferInfo(gfxScreen_t screen, u8 id)
bottomFramebufferInfo.active_framebuf=id;
bottomFramebufferInfo.framebuf0_vaddr=(u32*)gfxBottomFramebuffers[id];
bottomFramebufferInfo.framebuf1_vaddr=0x00000000;
bottomFramebufferInfo.framebuf_widthbytesize=240*__get_bytes_per_pixel(botFormat);
bottomFramebufferInfo.framebuf_widthbytesize=240*gspGetBytesPerPixel(botFormat);
bottomFramebufferInfo.format=botFormat;
bottomFramebufferInfo.framebuf_dispselect=id;
bottomFramebufferInfo.unk=0x00000000;
@ -271,7 +256,7 @@ static void gfxGxHwInit(void)
gfxWriteGxReg(0x0574, 0x10501);
}
void gfxInit(GSPGPU_FramebufferFormats topFormat, GSPGPU_FramebufferFormats bottomFormat, bool vrambuffers)
void gfxInit(GSPGPU_FramebufferFormat topFormat, GSPGPU_FramebufferFormat bottomFormat, bool vrambuffers)
{
if (vrambuffers)
{
@ -307,8 +292,8 @@ void gfxInit(GSPGPU_FramebufferFormats topFormat, GSPGPU_FramebufferFormats bott
// if 3d enabled :
// topright1 0x000FD200-0x00143700
// topright2 0x00143700-0x00189C00
u32 topSize = 400 * 240 * __get_bytes_per_pixel(topFormat);
u32 bottomSize = 320 * 240 * __get_bytes_per_pixel(bottomFormat);
u32 topSize = 400 * 240 * gspGetBytesPerPixel(topFormat);
u32 bottomSize = 320 * 240 * gspGetBytesPerPixel(bottomFormat);
gfxTopLeftFramebuffers[0]=screenAlloc(topSize);
gfxTopLeftFramebuffers[1]=screenAlloc(topSize);
@ -398,8 +383,8 @@ u8* gfxGetFramebuffer(gfxScreen_t screen, gfx3dSide_t side, u16* width, u16* hei
void gfxFlushBuffers(void)
{
u32 topSize = 400 * 240 * __get_bytes_per_pixel(gfxGetScreenFormat(GFX_TOP));
u32 bottomSize = 320 * 240 * __get_bytes_per_pixel(gfxGetScreenFormat(GFX_BOTTOM));
u32 topSize = 400 * 240 * gspGetBytesPerPixel(gfxGetScreenFormat(GFX_TOP));
u32 bottomSize = 320 * 240 * gspGetBytesPerPixel(gfxGetScreenFormat(GFX_BOTTOM));
GSPGPU_FlushDataCache(gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), topSize);
if(enable3d)GSPGPU_FlushDataCache(gfxGetFramebuffer(GFX_TOP, GFX_RIGHT, NULL, NULL), topSize);

View File

@ -18,9 +18,6 @@
#include <3ds/thread.h>
#include <3ds/os.h>
// TODO: find a better place for this function (currently defined in gfx.c)
u32 __get_bytes_per_pixel(GSPGPU_FramebufferFormats format);
#define APT_HANDLER_STACKSIZE (0x1000)
static int aptRefCount = 0;
@ -171,8 +168,8 @@ static void aptInitCaptureInfo(aptCaptureBufInfo* capinfo, const GSPGPU_CaptureI
capinfo->top.format = gspcapinfo->screencapture[0].format & 0x7;
capinfo->bottom.format = gspcapinfo->screencapture[1].format & 0x7;
u32 main_pixsz = __get_bytes_per_pixel((GSPGPU_FramebufferFormats)capinfo->top.format);
u32 sub_pixsz = __get_bytes_per_pixel((GSPGPU_FramebufferFormats)capinfo->bottom.format);
u32 main_pixsz = gspGetBytesPerPixel((GSPGPU_FramebufferFormat)capinfo->top.format);
u32 sub_pixsz = gspGetBytesPerPixel((GSPGPU_FramebufferFormat)capinfo->bottom.format);
capinfo->bottom.leftOffset = 0;
capinfo->bottom.rightOffset = 0;
@ -615,11 +612,11 @@ APT_Command aptWaitForWakeUp(APT_Transition transition)
return cmd;
}
static void aptConvertScreenForCapture(void* dst, const void* src, u32 height, GSPGPU_FramebufferFormats format)
static void aptConvertScreenForCapture(void* dst, const void* src, u32 height, GSPGPU_FramebufferFormat format)
{
const u32 width = 240;
const u32 width_po2 = 1U << (32 - __builtin_clz(width-1)); // next_po2(240) = 256
const u32 bpp = __get_bytes_per_pixel(format);
const u32 bpp = gspGetBytesPerPixel(format);
const u32 tilesize = 8*8*bpp;
// Terrible conversion code that is also probably really slow
@ -699,16 +696,16 @@ static void aptScreenTransfer(NS_APPID appId, bool sysApplet)
aptConvertScreenForCapture( // Bottom screen
(u8*)map + capinfo.bottom.leftOffset,
gspcapinfo.screencapture[1].framebuf0_vaddr,
320, (GSPGPU_FramebufferFormats)capinfo.bottom.format);
320, (GSPGPU_FramebufferFormat)capinfo.bottom.format);
aptConvertScreenForCapture( // Top screen (Left eye)
(u8*)map + capinfo.top.leftOffset,
gspcapinfo.screencapture[0].framebuf0_vaddr,
400, (GSPGPU_FramebufferFormats)capinfo.top.format);
400, (GSPGPU_FramebufferFormat)capinfo.top.format);
if (capinfo.is3D)
aptConvertScreenForCapture( // Top screen (Right eye)
(u8*)map + capinfo.top.rightOffset,
gspcapinfo.screencapture[0].framebuf1_vaddr,
400, (GSPGPU_FramebufferFormats)capinfo.top.format);
400, (GSPGPU_FramebufferFormat)capinfo.top.format);
svcUnmapMemoryBlock(hCapMemBlk, (u32)map);
}
mappableFree(map);