split framebuffer.
setup doublebuffering inside GPU.cpp. avoid copying a whole framebuffer every frame. better performance at higher res.
This commit is contained in:
parent
939a376389
commit
c88981b589
94
src/GPU.cpp
94
src/GPU.cpp
|
@ -71,9 +71,9 @@ u32 VRAMMap_TexPal[8];
|
||||||
|
|
||||||
u32 VRAMMap_ARM7[2];
|
u32 VRAMMap_ARM7[2];
|
||||||
|
|
||||||
u32* Framebuffer;
|
int FrontBuffer;
|
||||||
int FBScale;
|
u32* Framebuffer[2][2];
|
||||||
int FBScreenStride;
|
int FBScale[2];
|
||||||
|
|
||||||
GPU2D* GPU2D_A;
|
GPU2D* GPU2D_A;
|
||||||
GPU2D* GPU2D_B;
|
GPU2D* GPU2D_B;
|
||||||
|
@ -85,8 +85,12 @@ bool Init()
|
||||||
GPU2D_B = new GPU2D(1);
|
GPU2D_B = new GPU2D(1);
|
||||||
if (!GPU3D::Init()) return false;
|
if (!GPU3D::Init()) return false;
|
||||||
|
|
||||||
|
FrontBuffer = 0;
|
||||||
|
Framebuffer[0][0] = NULL; Framebuffer[0][1] = NULL;
|
||||||
|
Framebuffer[1][0] = NULL; Framebuffer[1][1] = NULL;
|
||||||
|
FBScale[0] = -1; FBScale[1] = -1;
|
||||||
//SetFramebufferScale(1);
|
//SetFramebufferScale(1);
|
||||||
SetFramebufferScale(2);
|
SetFramebufferScale(1, 1);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -97,7 +101,10 @@ void DeInit()
|
||||||
delete GPU2D_B;
|
delete GPU2D_B;
|
||||||
GPU3D::DeInit();
|
GPU3D::DeInit();
|
||||||
|
|
||||||
if (Framebuffer) delete[] Framebuffer;
|
if (Framebuffer[0][0]) delete[] Framebuffer[0][0];
|
||||||
|
if (Framebuffer[0][1]) delete[] Framebuffer[0][1];
|
||||||
|
if (Framebuffer[1][0]) delete[] Framebuffer[1][0];
|
||||||
|
if (Framebuffer[1][1]) delete[] Framebuffer[1][1];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset()
|
void Reset()
|
||||||
|
@ -145,22 +152,32 @@ void Reset()
|
||||||
VRAMMap_ARM7[0] = 0;
|
VRAMMap_ARM7[0] = 0;
|
||||||
VRAMMap_ARM7[1] = 0;
|
VRAMMap_ARM7[1] = 0;
|
||||||
|
|
||||||
for (int i = 0; i < 256*192*2; i++)
|
for (int i = 0; i < (256*192)<<(FBScale[0]*2); i++)
|
||||||
{
|
{
|
||||||
Framebuffer[i] = 0xFFFFFFFF;
|
Framebuffer[0][0][i] = 0xFFFFFFFF;
|
||||||
|
Framebuffer[1][0][i] = 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < (256*192)<<(FBScale[1]*2); i++)
|
||||||
|
{
|
||||||
|
Framebuffer[0][1][i] = 0xFFFFFFFF;
|
||||||
|
Framebuffer[1][1][i] = 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
GPU2D_A->Reset();
|
GPU2D_A->Reset();
|
||||||
GPU2D_B->Reset();
|
GPU2D_B->Reset();
|
||||||
GPU3D::Reset();
|
GPU3D::Reset();
|
||||||
|
|
||||||
GPU2D_A->SetFramebuffer(&Framebuffer[FBScreenStride]);
|
int backbuf = FrontBuffer ? 0 : 1;
|
||||||
GPU2D_B->SetFramebuffer(&Framebuffer[0]);
|
GPU2D_A->SetFramebuffer(Framebuffer[backbuf][1]);
|
||||||
|
GPU2D_B->SetFramebuffer(Framebuffer[backbuf][0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stop()
|
void Stop()
|
||||||
{
|
{
|
||||||
memset(Framebuffer, 0, FBScreenStride*2*sizeof(u32));
|
memset(Framebuffer[0][0], 0, (256*192)<<(FBScale[0]*2));
|
||||||
|
memset(Framebuffer[0][1], 0, (256*192)<<(FBScale[1]*2));
|
||||||
|
memset(Framebuffer[1][0], 0, (256*192)<<(FBScale[0]*2));
|
||||||
|
memset(Framebuffer[1][1], 0, (256*192)<<(FBScale[1]*2));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoSavestate(Savestate* file)
|
void DoSavestate(Savestate* file)
|
||||||
|
@ -215,13 +232,46 @@ void DoSavestate(Savestate* file)
|
||||||
GPU3D::DoSavestate(file);
|
GPU3D::DoSavestate(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetFramebufferScale(int scale)
|
void AssignFramebuffers()
|
||||||
{
|
{
|
||||||
FBScale = scale;
|
int backbuf = FrontBuffer ? 0 : 1;
|
||||||
FBScreenStride = (256*scale) * (192*scale);
|
if (NDS::PowerControl9 & (1<<15))
|
||||||
|
{
|
||||||
|
GPU2D_A->SetFramebuffer(Framebuffer[backbuf][0]);
|
||||||
|
GPU2D_B->SetFramebuffer(Framebuffer[backbuf][1]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GPU2D_A->SetFramebuffer(Framebuffer[backbuf][1]);
|
||||||
|
GPU2D_B->SetFramebuffer(Framebuffer[backbuf][0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Framebuffer) delete[] Framebuffer;
|
void SetFramebufferScale(int top, int bottom)
|
||||||
Framebuffer = new u32[FBScreenStride * 2];
|
{
|
||||||
|
if (top != FBScale[0])
|
||||||
|
{
|
||||||
|
FBScale[0] = top;
|
||||||
|
|
||||||
|
int fbsize = (256 * 192) << (FBScale[0] * 2);
|
||||||
|
if (Framebuffer[0][0]) delete[] Framebuffer[0][0];
|
||||||
|
if (Framebuffer[1][0]) delete[] Framebuffer[1][0];
|
||||||
|
Framebuffer[0][0] = new u32[fbsize];
|
||||||
|
Framebuffer[1][0] = new u32[fbsize];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bottom != FBScale[1])
|
||||||
|
{
|
||||||
|
FBScale[1] = bottom;
|
||||||
|
|
||||||
|
int fbsize = (256 * 192) << (FBScale[1] * 2);
|
||||||
|
if (Framebuffer[0][1]) delete[] Framebuffer[0][1];
|
||||||
|
if (Framebuffer[1][1]) delete[] Framebuffer[1][1];
|
||||||
|
Framebuffer[0][1] = new u32[fbsize];
|
||||||
|
Framebuffer[1][1] = new u32[fbsize];
|
||||||
|
}
|
||||||
|
|
||||||
|
AssignFramebuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -682,16 +732,7 @@ void SetPowerCnt(u32 val)
|
||||||
GPU2D_B->SetEnabled(val & (1<<9));
|
GPU2D_B->SetEnabled(val & (1<<9));
|
||||||
GPU3D::SetEnabled(val & (1<<3), val & (1<<2));
|
GPU3D::SetEnabled(val & (1<<3), val & (1<<2));
|
||||||
|
|
||||||
if (val & (1<<15))
|
AssignFramebuffers();
|
||||||
{
|
|
||||||
GPU2D_A->SetFramebuffer(&Framebuffer[0]);
|
|
||||||
GPU2D_B->SetFramebuffer(&Framebuffer[FBScreenStride]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GPU2D_A->SetFramebuffer(&Framebuffer[FBScreenStride]);
|
|
||||||
GPU2D_B->SetFramebuffer(&Framebuffer[0]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -762,6 +803,9 @@ void StartHBlank(u32 line)
|
||||||
|
|
||||||
void FinishFrame(u32 lines)
|
void FinishFrame(u32 lines)
|
||||||
{
|
{
|
||||||
|
FrontBuffer = FrontBuffer ? 0 : 1;
|
||||||
|
AssignFramebuffers();
|
||||||
|
|
||||||
TotalScanlines = lines;
|
TotalScanlines = lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,8 @@ extern u32 VRAMMap_Texture[4];
|
||||||
extern u32 VRAMMap_TexPal[8];
|
extern u32 VRAMMap_TexPal[8];
|
||||||
extern u32 VRAMMap_ARM7[2];
|
extern u32 VRAMMap_ARM7[2];
|
||||||
|
|
||||||
extern u32* Framebuffer;
|
extern int FrontBuffer;
|
||||||
|
extern u32* Framebuffer[2][2];
|
||||||
|
|
||||||
extern GPU2D* GPU2D_A;
|
extern GPU2D* GPU2D_A;
|
||||||
extern GPU2D* GPU2D_B;
|
extern GPU2D* GPU2D_B;
|
||||||
|
@ -74,7 +75,7 @@ void Stop();
|
||||||
|
|
||||||
void DoSavestate(Savestate* file);
|
void DoSavestate(Savestate* file);
|
||||||
|
|
||||||
void SetFramebufferScale(int scale);
|
void SetFramebufferScale(int top, int bottom);
|
||||||
|
|
||||||
|
|
||||||
void MapVRAM_AB(u32 bank, u8 cnt);
|
void MapVRAM_AB(u32 bank, u8 cnt);
|
||||||
|
|
|
@ -160,7 +160,7 @@ void Open()
|
||||||
|
|
||||||
uiRadioButtons* rbApplyScalingTo = uiNewRadioButtons();
|
uiRadioButtons* rbApplyScalingTo = uiNewRadioButtons();
|
||||||
uiRadioButtonsAppend(rbApplyScalingTo, "Both screens");
|
uiRadioButtonsAppend(rbApplyScalingTo, "Both screens");
|
||||||
uiRadioButtonsAppend(rbApplyScalingTo, "Emphasized screen");
|
uiRadioButtonsAppend(rbApplyScalingTo, "Emphasized screen (see 'Screen sizing')");
|
||||||
uiRadioButtonsAppend(rbApplyScalingTo, "Top screen");
|
uiRadioButtonsAppend(rbApplyScalingTo, "Top screen");
|
||||||
uiRadioButtonsAppend(rbApplyScalingTo, "Bottom screen");
|
uiRadioButtonsAppend(rbApplyScalingTo, "Bottom screen");
|
||||||
uiBoxAppend(in_ctrl, uiControl(rbApplyScalingTo), 0);
|
uiBoxAppend(in_ctrl, uiControl(rbApplyScalingTo), 0);
|
||||||
|
|
|
@ -95,7 +95,8 @@ char PrevSRAMPath[1024]; // for savestate 'undo load'
|
||||||
bool SavestateLoaded;
|
bool SavestateLoaded;
|
||||||
|
|
||||||
bool ScreenDrawInited = false;
|
bool ScreenDrawInited = false;
|
||||||
uiDrawBitmap* ScreenBitmap = NULL;
|
uiDrawBitmap* ScreenBitmap[2] = {NULL,NULL};
|
||||||
|
SDL_mutex* ScreenMutex;
|
||||||
u32* ScreenBuffer;
|
u32* ScreenBuffer;
|
||||||
|
|
||||||
int ScreenScale;
|
int ScreenScale;
|
||||||
|
@ -555,7 +556,7 @@ int EmuThreadFunc(void* burp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(ScreenBuffer, GPU::Framebuffer, (256*ScreenScale)*(384*ScreenScale)*4);
|
//memcpy(ScreenBuffer, GPU::Framebuffer, (256*ScreenScale)*(384*ScreenScale)*4);
|
||||||
uiAreaQueueRedrawAll(MainDrawArea);
|
uiAreaQueueRedrawAll(MainDrawArea);
|
||||||
|
|
||||||
// framerate limiter based off SDL2_gfx
|
// framerate limiter based off SDL2_gfx
|
||||||
|
@ -636,24 +637,27 @@ void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params)
|
||||||
if (!ScreenDrawInited)
|
if (!ScreenDrawInited)
|
||||||
{
|
{
|
||||||
ScreenDrawInited = true;
|
ScreenDrawInited = true;
|
||||||
ScreenBitmap = uiDrawNewBitmap(params->Context, 256*ScreenScale, 384*ScreenScale);
|
ScreenBitmap[0] = uiDrawNewBitmap(params->Context, 256*ScreenScale, 384*ScreenScale);
|
||||||
|
ScreenBitmap[1] = uiDrawNewBitmap(params->Context, 256*ScreenScale, 384*ScreenScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ScreenBitmap) return;
|
if (!ScreenBitmap[0] || !ScreenBitmap[1]) return;
|
||||||
|
|
||||||
uiRect top = {0, 0, 256*ScreenScale, 192*ScreenScale};
|
uiRect top = {0, 0, 256*ScreenScale, 192*ScreenScale};
|
||||||
uiRect bot = {0, 192*ScreenScale, 256*ScreenScale, 192*ScreenScale};
|
uiRect bot = {0, 0, 256*ScreenScale, 192*ScreenScale};
|
||||||
|
|
||||||
if (ScreenBuffer) uiDrawBitmapUpdate(ScreenBitmap, ScreenBuffer);
|
int frontbuf = GPU::FrontBuffer;
|
||||||
|
uiDrawBitmapUpdate(ScreenBitmap[0], GPU::Framebuffer[frontbuf][0]);
|
||||||
|
uiDrawBitmapUpdate(ScreenBitmap[1], GPU::Framebuffer[frontbuf][1]);
|
||||||
|
|
||||||
uiDrawSave(params->Context);
|
uiDrawSave(params->Context);
|
||||||
uiDrawTransform(params->Context, &TopScreenTrans);
|
uiDrawTransform(params->Context, &TopScreenTrans);
|
||||||
uiDrawBitmapDraw(params->Context, ScreenBitmap, &top, &TopScreenRect, Config::ScreenFilter==1);
|
uiDrawBitmapDraw(params->Context, ScreenBitmap[0], &top, &TopScreenRect, Config::ScreenFilter==1);
|
||||||
uiDrawRestore(params->Context);
|
uiDrawRestore(params->Context);
|
||||||
|
|
||||||
uiDrawSave(params->Context);
|
uiDrawSave(params->Context);
|
||||||
uiDrawTransform(params->Context, &BottomScreenTrans);
|
uiDrawTransform(params->Context, &BottomScreenTrans);
|
||||||
uiDrawBitmapDraw(params->Context, ScreenBitmap, &bot, &BottomScreenRect, Config::ScreenFilter==1);
|
uiDrawBitmapDraw(params->Context, ScreenBitmap[1], &bot, &BottomScreenRect, Config::ScreenFilter==1);
|
||||||
uiDrawRestore(params->Context);
|
uiDrawRestore(params->Context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1993,6 +1997,8 @@ int main(int argc, char** argv)
|
||||||
uiMenuItemDisable(MenuItem_Reset);
|
uiMenuItemDisable(MenuItem_Reset);
|
||||||
uiMenuItemDisable(MenuItem_Stop);
|
uiMenuItemDisable(MenuItem_Stop);
|
||||||
|
|
||||||
|
ScreenMutex = SDL_CreateMutex();
|
||||||
|
|
||||||
uiAreaHandler areahandler;
|
uiAreaHandler areahandler;
|
||||||
areahandler.Draw = OnAreaDraw;
|
areahandler.Draw = OnAreaDraw;
|
||||||
areahandler.MouseEvent = OnAreaMouseEvent;
|
areahandler.MouseEvent = OnAreaMouseEvent;
|
||||||
|
@ -2131,7 +2137,10 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
Config::Save();
|
Config::Save();
|
||||||
|
|
||||||
if (ScreenBitmap) uiDrawFreeBitmap(ScreenBitmap);
|
SDL_DestroyMutex(ScreenMutex);
|
||||||
|
|
||||||
|
if (ScreenBitmap[0]) uiDrawFreeBitmap(ScreenBitmap[0]);
|
||||||
|
if (ScreenBitmap[1]) uiDrawFreeBitmap(ScreenBitmap[1]);
|
||||||
|
|
||||||
uiUninit();
|
uiUninit();
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
|
Loading…
Reference in New Issue