- The framebuffer pointers in NDSDisplayInfo are no longer assumed to be 16-bits per pixel in size. This is being done now in preparation for higher color depth processing. (This feature is not yet implemented.)
- Instead, clients should be reading NDSDisplayInfo.colorFormat to determine the color format of the framebuffers. NDSDisplayInfo.pixelBytes is a convenience field that reports the number of bytes per pixel (either 2 or 4 bytes).
- By default, the framebuffers will continue to be in 16-bit BGR555_Rev format for backwards compatibility.
This commit is contained in:
rogerman 2016-03-19 02:22:03 +00:00
parent fbf2b970a1
commit d8a6112049
17 changed files with 407 additions and 167 deletions

View File

@ -4010,8 +4010,8 @@ void GPUEngineBase::SetDisplayByID(const NDSDisplayID theDisplayID)
{
const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo();
this->_targetDisplayID = theDisplayID;
this->nativeBuffer = dispInfo.nativeBuffer[theDisplayID];
this->customBuffer = dispInfo.customBuffer[theDisplayID];
this->nativeBuffer = (u16 *)dispInfo.nativeBuffer[theDisplayID];
this->customBuffer = (u16 *)dispInfo.customBuffer[theDisplayID];
}
GPUEngineID GPUEngineBase::GetEngineID() const
@ -4033,8 +4033,8 @@ void GPUEngineBase::SetCustomFramebufferSize(size_t w, size_t h)
this->_internalRenderLineTargetCustom = newWorkingScanline;
this->_renderLineLayerIDCustom = newBGPixels;
this->nativeBuffer = GPU->GetDisplayInfo().nativeBuffer[this->_targetDisplayID];
this->customBuffer = GPU->GetDisplayInfo().customBuffer[this->_targetDisplayID];
this->nativeBuffer = (u16 *)GPU->GetDisplayInfo().nativeBuffer[this->_targetDisplayID];
this->customBuffer = (u16 *)GPU->GetDisplayInfo().customBuffer[this->_targetDisplayID];
this->_bgLayerIndexCustom = newBGLayerIndexCustom;
this->_bgLayerColorCustom = newBGLayerColorCustom;
@ -5700,17 +5700,19 @@ GPUSubsystem::GPUSubsystem()
_customVRAMBlank = NULL;
_customFramebuffer = (u16 *)malloc_alignedCacheLine(GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * sizeof(u16) * 2);
_displayInfo.colorFormat = NDSColorFormat_BGR555_Rev;
_displayInfo.pixelBytes = sizeof(u16);
_displayInfo.isCustomSizeRequested = false;
_displayInfo.customWidth = GPU_FRAMEBUFFER_NATIVE_WIDTH;
_displayInfo.customHeight = GPU_FRAMEBUFFER_NATIVE_HEIGHT;
_displayInfo.masterNativeBuffer = _nativeFramebuffer;
_displayInfo.nativeBuffer[NDSDisplayID_Main] = _displayInfo.masterNativeBuffer;
_displayInfo.nativeBuffer[NDSDisplayID_Touch] = _displayInfo.masterNativeBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT);
_displayInfo.nativeBuffer[NDSDisplayID_Touch] = (u8 *)_displayInfo.masterNativeBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * _displayInfo.pixelBytes);
_displayInfo.masterCustomBuffer = _customFramebuffer;
_displayInfo.customBuffer[NDSDisplayID_Main] = _displayInfo.masterCustomBuffer;
_displayInfo.customBuffer[NDSDisplayID_Touch] = _displayInfo.masterCustomBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT);
_displayInfo.customBuffer[NDSDisplayID_Touch] = (u8 *)_displayInfo.masterCustomBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * _displayInfo.pixelBytes);
_displayInfo.didPerformCustomRender[NDSDisplayID_Main] = false;
_displayInfo.didPerformCustomRender[NDSDisplayID_Touch] = false;
@ -5788,8 +5790,8 @@ void GPUSubsystem::Reset()
this->_displayInfo.renderedBuffer[NDSDisplayID_Main] = this->_displayInfo.nativeBuffer[NDSDisplayID_Main];
this->_displayInfo.didPerformCustomRender[NDSDisplayID_Touch] = false;
this->_displayInfo.nativeBuffer[NDSDisplayID_Touch] = this->_displayInfo.masterNativeBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT);
this->_displayInfo.customBuffer[NDSDisplayID_Touch] = this->_displayInfo.masterCustomBuffer + (this->_displayInfo.customWidth * this->_displayInfo.customHeight);
this->_displayInfo.nativeBuffer[NDSDisplayID_Touch] = (u8 *)this->_displayInfo.masterNativeBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * this->_displayInfo.pixelBytes);
this->_displayInfo.customBuffer[NDSDisplayID_Touch] = (u8 *)this->_displayInfo.masterCustomBuffer + (this->_displayInfo.customWidth * this->_displayInfo.customHeight * this->_displayInfo.pixelBytes);
this->_displayInfo.renderedWidth[NDSDisplayID_Touch] = GPU_FRAMEBUFFER_NATIVE_WIDTH;
this->_displayInfo.renderedHeight[NDSDisplayID_Touch] = GPU_FRAMEBUFFER_NATIVE_HEIGHT;
this->_displayInfo.renderedBuffer[NDSDisplayID_Touch] = this->_displayInfo.nativeBuffer[NDSDisplayID_Touch];
@ -5942,7 +5944,7 @@ size_t GPUSubsystem::GetCustomFramebufferHeight() const
return this->_displayInfo.customHeight;
}
void GPUSubsystem::SetCustomFramebufferSize(size_t w, size_t h, u16 *clientNativeBuffer, u16 *clientCustomBuffer)
void GPUSubsystem::SetCustomFramebufferSize(size_t w, size_t h, void *clientNativeBuffer, void *clientCustomBuffer)
{
if (w < GPU_FRAMEBUFFER_NATIVE_WIDTH || h < GPU_FRAMEBUFFER_NATIVE_HEIGHT)
{
@ -5955,11 +5957,9 @@ void GPUSubsystem::SetCustomFramebufferSize(size_t w, size_t h, u16 *clientNativ
const float customHeightScale = (float)h / (float)GPU_FRAMEBUFFER_NATIVE_HEIGHT;
const float newGpuLargestDstLineCount = (size_t)ceilf(customHeightScale);
u16 *oldCustomFramebuffer = this->_customFramebuffer;
u16 *oldGpuDstToSrcIndexPtr = _gpuDstToSrcIndex;
u8 *oldGpuDstToSrcSSSE3_u8 = _gpuDstToSrcSSSE3_u8;
u8 *oldGpuDstToSrcSSSE3_u16 = _gpuDstToSrcSSSE3_u16;
u16 *oldCustomVRAM = this->_customVRAM;
for (size_t srcX = 0, currentPitchCount = 0; srcX < GPU_FRAMEBUFFER_NATIVE_WIDTH; srcX++)
{
@ -6024,12 +6024,94 @@ void GPUSubsystem::SetCustomFramebufferSize(size_t w, size_t h, u16 *clientNativ
newGpuDstToSrcSSSE3_u16[(i << 1) + 1] = value_u16 + 1;
}
const size_t newCustomVRAMBlockSize = _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * w;
const size_t newCustomVRAMBlankSize = newGpuLargestDstLineCount * GPU_VRAM_BLANK_REGION_LINES * w;
u16 *newCustomVRAM = (u16 *)malloc_alignedCacheLine(((newCustomVRAMBlockSize * 4) + newCustomVRAMBlankSize) * sizeof(u16));
memset(newCustomVRAM, 0, ((newCustomVRAMBlockSize * 4) + newCustomVRAMBlankSize) * sizeof(u16));
_gpuLargestDstLineCount = newGpuLargestDstLineCount;
_gpuVRAMBlockOffset = _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * w;
_gpuDstToSrcIndex = newGpuDstToSrcIndex;
_gpuDstToSrcSSSE3_u8 = newGpuDstToSrcSSSE3_u8;
_gpuDstToSrcSSSE3_u16 = newGpuDstToSrcSSSE3_u16;
const size_t nativeFramebufferSize = GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2 * sizeof(u16);
this->_displayInfo.isCustomSizeRequested = ( (w != GPU_FRAMEBUFFER_NATIVE_WIDTH) || (h != GPU_FRAMEBUFFER_NATIVE_HEIGHT) );
this->_displayInfo.customWidth = w;
this->_displayInfo.customHeight = h;
if (!this->_displayInfo.isCustomSizeRequested)
{
this->_engineMain->nativeLineCaptureCount[0] = GPU_VRAM_BLOCK_LINES;
this->_engineMain->nativeLineCaptureCount[1] = GPU_VRAM_BLOCK_LINES;
this->_engineMain->nativeLineCaptureCount[2] = GPU_VRAM_BLOCK_LINES;
this->_engineMain->nativeLineCaptureCount[3] = GPU_VRAM_BLOCK_LINES;
for (size_t l = 0; l < GPU_VRAM_BLOCK_LINES; l++)
{
this->_engineMain->isLineCaptureNative[0][l] = true;
this->_engineMain->isLineCaptureNative[1][l] = true;
this->_engineMain->isLineCaptureNative[2][l] = true;
this->_engineMain->isLineCaptureNative[3][l] = true;
}
}
if (this->_displayInfo.didPerformCustomRender[NDSDisplayID_Main])
{
this->_displayInfo.renderedWidth[NDSDisplayID_Main] = this->_displayInfo.customWidth;
this->_displayInfo.renderedHeight[NDSDisplayID_Main] = this->_displayInfo.customHeight;
}
else
{
this->_displayInfo.renderedWidth[NDSDisplayID_Main] = GPU_FRAMEBUFFER_NATIVE_WIDTH;
this->_displayInfo.renderedHeight[NDSDisplayID_Main] = GPU_FRAMEBUFFER_NATIVE_HEIGHT;
}
if (this->_displayInfo.didPerformCustomRender[NDSDisplayID_Touch])
{
this->_displayInfo.renderedWidth[NDSDisplayID_Touch] = this->_displayInfo.customWidth;
this->_displayInfo.renderedHeight[NDSDisplayID_Touch] = this->_displayInfo.customHeight;
}
else
{
this->_displayInfo.renderedWidth[NDSDisplayID_Touch] = GPU_FRAMEBUFFER_NATIVE_WIDTH;
this->_displayInfo.renderedHeight[NDSDisplayID_Touch] = GPU_FRAMEBUFFER_NATIVE_HEIGHT;
}
this->_AllocateFramebuffers(this->_displayInfo.colorFormat, w, h, clientNativeBuffer, clientCustomBuffer);
free_aligned(oldGpuDstToSrcIndexPtr);
free_aligned(oldGpuDstToSrcSSSE3_u8);
free_aligned(oldGpuDstToSrcSSSE3_u16);
}
void GPUSubsystem::SetCustomFramebufferSize(size_t w, size_t h)
{
this->SetCustomFramebufferSize(w, h, NULL, NULL);
}
void GPUSubsystem::SetColorFormat(const NDSColorFormat outputFormat, void *clientNativeBuffer, void *clientCustomBuffer)
{
// TBD: Multiple color formats aren't supported in the renderer yet. Force the color format to NDSColorFormat_BGR555_Rev until then.
//this->_displayInfo.colorFormat = outputFormat;
this->_displayInfo.colorFormat = NDSColorFormat_BGR555_Rev;
this->_displayInfo.pixelBytes = (outputFormat == NDSColorFormat_BGR555_Rev) ? sizeof(u16) : sizeof(u32);
this->_AllocateFramebuffers(this->_displayInfo.colorFormat, this->_displayInfo.customWidth, this->_displayInfo.customHeight, clientNativeBuffer, clientCustomBuffer);
}
void GPUSubsystem::SetColorFormat(const NDSColorFormat outputFormat)
{
this->SetColorFormat(outputFormat, NULL, NULL);
}
void GPUSubsystem::_AllocateFramebuffers(NDSColorFormat outputFormat, size_t w, size_t h, void *clientNativeBuffer, void *clientCustomBuffer)
{
void *oldCustomFramebuffer = this->_customFramebuffer;
void *oldCustomVRAM = this->_customVRAM;
const size_t pixelBytes = (outputFormat == NDSColorFormat_BGR555_Rev) ? sizeof(u16) : sizeof(FragmentColor);
const size_t newCustomVRAMBlockSize = _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * w;
const size_t newCustomVRAMBlankSize = _gpuLargestDstLineCount * GPU_VRAM_BLANK_REGION_LINES * w;
const size_t nativeFramebufferSize = GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2 * pixelBytes;
u16 *newCustomVRAM = (u16 *)malloc_alignedCacheLine(((newCustomVRAMBlockSize * 4) + newCustomVRAMBlankSize) * pixelBytes);
memset(newCustomVRAM, 0, ((newCustomVRAMBlockSize * 4) + newCustomVRAMBlankSize) * pixelBytes);
if (clientNativeBuffer != NULL)
{
@ -6058,44 +6140,15 @@ void GPUSubsystem::SetCustomFramebufferSize(size_t w, size_t h, u16 *clientNativ
}
else
{
u16 *newCustomFramebuffer = (u16 *)malloc_alignedCacheLine(w * h * 2 * sizeof(u16));
u16 *newCustomFramebuffer = (u16 *)malloc_alignedCacheLine(w * h * 2 * pixelBytes);
memset_u16(newCustomFramebuffer, 0x8000, w * h * 2);
this->_customFramebuffer = newCustomFramebuffer;
this->_displayInfo.masterCustomBuffer = newCustomFramebuffer;
}
_gpuLargestDstLineCount = newGpuLargestDstLineCount;
_gpuVRAMBlockOffset = _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * w;
_gpuDstToSrcIndex = newGpuDstToSrcIndex;
_gpuDstToSrcSSSE3_u8 = newGpuDstToSrcSSSE3_u8;
_gpuDstToSrcSSSE3_u16 = newGpuDstToSrcSSSE3_u16;
this->_customVRAM = newCustomVRAM;
this->_customVRAMBlank = newCustomVRAM + (newCustomVRAMBlockSize * 4);
this->_displayInfo.isCustomSizeRequested = ( (w != GPU_FRAMEBUFFER_NATIVE_WIDTH) || (h != GPU_FRAMEBUFFER_NATIVE_HEIGHT) );
this->_displayInfo.customWidth = w;
this->_displayInfo.customHeight = h;
this->_displayInfo.nativeBuffer[NDSDisplayID_Main] = (this->_displayMain->GetEngine()->GetDisplayByID() == NDSDisplayID_Main) ? this->_displayInfo.masterNativeBuffer : this->_displayInfo.masterNativeBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT);
this->_displayInfo.nativeBuffer[NDSDisplayID_Touch] = (this->_displayTouch->GetEngine()->GetDisplayByID() == NDSDisplayID_Main) ? this->_displayInfo.masterNativeBuffer : this->_displayInfo.masterNativeBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT);
this->_displayInfo.customBuffer[NDSDisplayID_Main] = (this->_displayMain->GetEngine()->GetDisplayByID() == NDSDisplayID_Main) ? this->_displayInfo.masterCustomBuffer : this->_displayInfo.masterCustomBuffer + (w * h);
this->_displayInfo.customBuffer[NDSDisplayID_Touch] = (this->_displayTouch->GetEngine()->GetDisplayByID() == NDSDisplayID_Main) ? this->_displayInfo.masterCustomBuffer : this->_displayInfo.masterCustomBuffer + (w * h);
if (!this->_displayInfo.isCustomSizeRequested)
{
this->_engineMain->nativeLineCaptureCount[0] = GPU_VRAM_BLOCK_LINES;
this->_engineMain->nativeLineCaptureCount[1] = GPU_VRAM_BLOCK_LINES;
this->_engineMain->nativeLineCaptureCount[2] = GPU_VRAM_BLOCK_LINES;
this->_engineMain->nativeLineCaptureCount[3] = GPU_VRAM_BLOCK_LINES;
for (size_t l = 0; l < GPU_VRAM_BLOCK_LINES; l++)
{
this->_engineMain->isLineCaptureNative[0][l] = true;
this->_engineMain->isLineCaptureNative[1][l] = true;
this->_engineMain->isLineCaptureNative[2][l] = true;
this->_engineMain->isLineCaptureNative[3][l] = true;
}
}
this->_engineMain->SetCustomFramebufferSize(w, h);
this->_engineSub->SetCustomFramebufferSize(w, h);
BaseRenderer->SetFramebufferSize(w, h); // Since BaseRenderer is persistent, we need to update this manually.
@ -6105,44 +6158,18 @@ void GPUSubsystem::SetCustomFramebufferSize(size_t w, size_t h, u16 *clientNativ
CurrentRenderer->SetFramebufferSize(w, h);
}
if (this->_displayInfo.didPerformCustomRender[NDSDisplayID_Main])
{
this->_displayInfo.renderedBuffer[NDSDisplayID_Main] = this->_displayInfo.customBuffer[NDSDisplayID_Main];
this->_displayInfo.renderedWidth[NDSDisplayID_Main] = this->_displayInfo.customWidth;
this->_displayInfo.renderedHeight[NDSDisplayID_Main] = this->_displayInfo.customHeight;
}
else
{
this->_displayInfo.renderedBuffer[NDSDisplayID_Main] = this->_displayInfo.nativeBuffer[NDSDisplayID_Main];
this->_displayInfo.renderedWidth[NDSDisplayID_Main] = GPU_FRAMEBUFFER_NATIVE_WIDTH;
this->_displayInfo.renderedHeight[NDSDisplayID_Main] = GPU_FRAMEBUFFER_NATIVE_HEIGHT;
}
this->_displayInfo.nativeBuffer[NDSDisplayID_Main] = (this->_displayMain->GetEngine()->GetDisplayByID() == NDSDisplayID_Main) ? this->_displayInfo.masterNativeBuffer : (u8 *)this->_displayInfo.masterNativeBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * this->_displayInfo.pixelBytes);
this->_displayInfo.nativeBuffer[NDSDisplayID_Touch] = (this->_displayTouch->GetEngine()->GetDisplayByID() == NDSDisplayID_Main) ? this->_displayInfo.masterNativeBuffer : (u8 *)this->_displayInfo.masterNativeBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * this->_displayInfo.pixelBytes);
this->_displayInfo.customBuffer[NDSDisplayID_Main] = (this->_displayMain->GetEngine()->GetDisplayByID() == NDSDisplayID_Main) ? this->_displayInfo.masterCustomBuffer : (u8 *)this->_displayInfo.masterCustomBuffer + (w * h * this->_displayInfo.pixelBytes);
this->_displayInfo.customBuffer[NDSDisplayID_Touch] = (this->_displayTouch->GetEngine()->GetDisplayByID() == NDSDisplayID_Main) ? this->_displayInfo.masterCustomBuffer : (u8 *)this->_displayInfo.masterCustomBuffer + (w * h * this->_displayInfo.pixelBytes);
if (this->_displayInfo.didPerformCustomRender[NDSDisplayID_Touch])
{
this->_displayInfo.renderedBuffer[NDSDisplayID_Touch] = this->_displayInfo.customBuffer[NDSDisplayID_Touch];
this->_displayInfo.renderedWidth[NDSDisplayID_Touch] = this->_displayInfo.customWidth;
this->_displayInfo.renderedHeight[NDSDisplayID_Touch] = this->_displayInfo.customHeight;
}
else
{
this->_displayInfo.renderedBuffer[NDSDisplayID_Touch] = this->_displayInfo.nativeBuffer[NDSDisplayID_Touch];
this->_displayInfo.renderedWidth[NDSDisplayID_Touch] = GPU_FRAMEBUFFER_NATIVE_WIDTH;
this->_displayInfo.renderedHeight[NDSDisplayID_Touch] = GPU_FRAMEBUFFER_NATIVE_HEIGHT;
}
this->_displayInfo.renderedBuffer[NDSDisplayID_Main] = (this->_displayInfo.didPerformCustomRender[NDSDisplayID_Main]) ? this->_displayInfo.customBuffer[NDSDisplayID_Main] : this->_displayInfo.nativeBuffer[NDSDisplayID_Main];
this->_displayInfo.renderedBuffer[NDSDisplayID_Touch] = (this->_displayInfo.didPerformCustomRender[NDSDisplayID_Touch]) ? this->_displayInfo.customBuffer[NDSDisplayID_Touch] : this->_displayInfo.nativeBuffer[NDSDisplayID_Touch];
free_aligned(oldCustomFramebuffer);
free_aligned(oldGpuDstToSrcIndexPtr);
free_aligned(oldGpuDstToSrcSSSE3_u8);
free_aligned(oldGpuDstToSrcSSSE3_u16);
free_aligned(oldCustomVRAM);
}
void GPUSubsystem::SetCustomFramebufferSize(size_t w, size_t h)
{
this->SetCustomFramebufferSize(w, h, NULL, NULL);
}
u16* GPUSubsystem::GetCustomVRAMBuffer()
{
return this->_customVRAM;
@ -6294,8 +6321,48 @@ void GPUSubsystem::RenderLine(const u16 l, bool isFrameSkipRequested)
void GPUSubsystem::ClearWithColor(const u16 colorBGRA5551)
{
memset_u16(this->_displayInfo.masterNativeBuffer, colorBGRA5551, GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2);
memset_u16(this->_displayInfo.masterCustomBuffer, colorBGRA5551, this->_displayInfo.customWidth * this->_displayInfo.customHeight * 2);
u16 color16 = colorBGRA5551;
FragmentColor color32;
switch (this->_displayInfo.colorFormat)
{
case NDSColorFormat_BGR555_Rev:
color16 = colorBGRA5551 | 0x8000;
break;
case NDSColorFormat_BGR666_Rev:
color32.r = material_5bit_to_6bit[(colorBGRA5551 & 0x001F)];
color32.g = material_5bit_to_6bit[(colorBGRA5551 & 0x03E0) >> 5];
color32.b = material_5bit_to_6bit[(colorBGRA5551 & 0x7C00) >> 10];
color32.a = 0xFF;
break;
case NDSColorFormat_BGR888_Rev:
color32.r = material_5bit_to_8bit[(colorBGRA5551 & 0x001F)];
color32.g = material_5bit_to_8bit[(colorBGRA5551 & 0x03E0) >> 5];
color32.b = material_5bit_to_8bit[(colorBGRA5551 & 0x7C00) >> 10];
color32.a = 0xFF;
break;
default:
break;
}
switch (this->_displayInfo.pixelBytes)
{
case 2:
memset_u16(this->_displayInfo.masterNativeBuffer, color16, GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2);
memset_u16(this->_displayInfo.masterCustomBuffer, color16, this->_displayInfo.customWidth * this->_displayInfo.customHeight * 2);
break;
case 4:
memset_u32(this->_displayInfo.masterNativeBuffer, color32.color, GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2);
memset_u32(this->_displayInfo.masterCustomBuffer, color32.color, this->_displayInfo.customWidth * this->_displayInfo.customHeight * 2);
break;
default:
break;
}
}
NDSDisplay::NDSDisplay()

View File

@ -1025,6 +1025,61 @@ enum NDSDisplayID
NDSDisplayID_Touch = 1
};
enum NDSColorFormat
{
// The color format information is packed in a 32-bit value.
// The bits are as follows:
// FFFOOOOO AAAAAABB BBBBGGGG GGRRRRRR
//
// F = Flags (see below)
// O = Color order (see below)
// A = Bit count for alpha [0-63]
// B = Bit count for blue [0-63]
// G = Bit count for green [0-63]
// R = Bit count for red [0-63]
//
// Flags:
// Bit 29: Reverse order flag.
// Set = Bits are in reverse order, usually for little-endian usage.
// Cleared = Bits are in normal order, usually for big-endian usage.
//
// Color order bits, 24-28:
// 0x00 = RGBA, common format
// 0x01 = RGAB
// 0x02 = RBGA
// 0x03 = RBAG
// 0x04 = RAGB
// 0x05 = RABG
// 0x06 = GRBA
// 0x07 = GRAB
// 0x08 = GBRA
// 0x09 = GBAR
// 0x0A = GARB
// 0x0B = GABR
// 0x0C = BRGA
// 0x0D = BRAG
// 0x0E = BGRA, common format
// 0x0F = BGAR
// 0x10 = BARG
// 0x11 = BAGR
// 0x12 = ARGB
// 0x13 = ARBG
// 0x14 = AGRB
// 0x15 = AGBR
// 0x16 = ABRG
// 0x17 = ABGR
// Color formats used for internal processing.
//NDSColorFormat_ABGR1555_Rev = 0x20045145,
//NDSColorFormat_ABGR5666_Rev = 0x20186186,
//NDSColorFormat_ABGR8888_Rev = 0x20208208,
// Color formats used by the output framebuffers.
NDSColorFormat_BGR555_Rev = 0x20005145,
NDSColorFormat_BGR666_Rev = 0x20006186,
NDSColorFormat_BGR888_Rev = 0x20008208
};
struct DISPCAPCNT_parsed
{
u8 EVA;
@ -1035,33 +1090,37 @@ struct DISPCAPCNT_parsed
typedef struct
{
// User-requested settings. These fields will always remain constant, and can only be changed if
// the user calls GPUSubsystem::SetFramebufferSize().
// User-requested settings. These fields will always remain constant until changed.
// Changed by calling GPUSubsystem::SetColorFormat().
// TBD: The color format will always be 2-byte NDSColorFormat_BGR555_Rev until internal rendering in multiple formats is fully supported.
NDSColorFormat colorFormat; // The output color format.
size_t pixelBytes; // The number of bytes per pixel.
// Changed by calling GPUSubsystem::SetFramebufferSize().
bool isCustomSizeRequested; // Reports that the call to GPUSubsystem::SetFramebufferSize() resulted in a custom rendering size.
// true - The user requested a custom size.
// false - The user requested the native size.
size_t customWidth; // The requested custom width, measured in pixels.
size_t customHeight; // The requested custom height, measured in pixels.
u16 *masterNativeBuffer; // Pointer to the head of the master native buffer.
u16 *masterCustomBuffer; // Pointer to the head of the master custom buffer.
void *masterNativeBuffer; // Pointer to the head of the master native buffer.
void *masterCustomBuffer; // Pointer to the head of the master custom buffer.
// If GPUSubsystem::GetWillAutoResolveToCustomBuffer() would return true, or if
// GPUEngineBase::ResolveToCustomFramebuffer() is called, then this buffer is used as the target
// buffer for resolving any native-sized renders.
// Frame information. These fields will change per frame, depending on how each display was rendered.
u16 *nativeBuffer[2]; // Pointer to the display's native size framebuffer.
u16 *customBuffer[2]; // Pointer to the display's custom size framebuffer.
void *nativeBuffer[2]; // Pointer to the display's native size framebuffer.
void *customBuffer[2]; // Pointer to the display's custom size framebuffer.
bool didPerformCustomRender[2]; // Reports that the display actually rendered at a custom size for this frame.
// true - The display performed a custom-sized render.
// false - The display performed a native-sized render.
size_t renderedWidth[2]; // The display rendered at this width, measured in pixels.
size_t renderedHeight[2]; // The display rendered at this height, measured in pixels.
u16 *renderedBuffer[2]; // The display rendered to this buffer.
void *renderedBuffer[2]; // The display rendered to this buffer.
} NDSDisplayInfo;
#define VRAM_NO_3D_USAGE 0xFF
@ -1508,6 +1567,8 @@ private:
NDSDisplayInfo _displayInfo;
void _AllocateFramebuffers(NDSColorFormat outputFormat, size_t w, size_t h, void *clientNativeBuffer, void *clientCustomBuffer);
public:
static GPUSubsystem* Allocate();
void FinalizeAndDeallocate();
@ -1530,8 +1591,10 @@ public:
size_t GetCustomFramebufferWidth() const;
size_t GetCustomFramebufferHeight() const;
void SetCustomFramebufferSize(size_t w, size_t h, u16 *clientNativeBuffer, u16 *clientCustomBuffer);
void SetCustomFramebufferSize(size_t w, size_t h, void *clientNativeBuffer, void *clientCustomBuffer);
void SetCustomFramebufferSize(size_t w, size_t h);
void SetColorFormat(const NDSColorFormat outputFormat, void *clientNativeBuffer, void *clientCustomBuffer);
void SetColorFormat(const NDSColorFormat outputFormat);
void UpdateRenderProperties();

View File

@ -371,7 +371,7 @@ resizeWindow( u16 width, u16 height, GLuint *screen_texture) {
static void
opengl_Draw( GLuint *texture, int software_convert) {
GLenum errCode;
u16 *gpuFramebuffer = GPU->GetDisplayInfo().masterNativeBuffer;
u16 *gpuFramebuffer = (u16 *)GPU->GetDisplayInfo().masterNativeBuffer;
/* Clear The Screen And The Depth Buffer */
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
@ -446,7 +446,7 @@ static void
Draw( void) {
SDL_Surface *rawImage;
rawImage = SDL_CreateRGBSurfaceFrom((void*)GPU->GetDisplayInfo().masterNativeBuffer, 256, 384, 16, 512, 0x001F, 0x03E0, 0x7C00, 0);
rawImage = SDL_CreateRGBSurfaceFrom(GPU->GetDisplayInfo().masterNativeBuffer, 256, 384, 16, 512, 0x001F, 0x03E0, 0x7C00, 0);
if(rawImage == NULL) return;
SDL_BlitSurface(rawImage, 0, surface, 0);

View File

@ -6789,6 +6789,8 @@ OGLDisplayLayer::OGLDisplayLayer(OGLVideoOutput *oglVO)
_texLoadedHeight[0] = (GLfloat)GPU_DISPLAY_HEIGHT;
_texLoadedHeight[1] = (GLfloat)GPU_DISPLAY_HEIGHT;
_videoColorFormat = GL_UNSIGNED_SHORT_1_5_5_5_REV;
_videoSrcBufferHead = NULL;
_videoSrcNativeBuffer[0] = NULL;
_videoSrcNativeBuffer[1] = NULL;
_videoSrcCustomBuffer[0] = NULL;
@ -7061,7 +7063,8 @@ void OGLDisplayLayer::DetermineTextureStorageHints(GLint &videoSrcTexStorageHint
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, this->_useClientStorage);
}
void OGLDisplayLayer::SetVideoBuffers(const void *videoBufferHead,
void OGLDisplayLayer::SetVideoBuffers(const uint32_t colorFormat,
const void *videoBufferHead,
const void *nativeBuffer0,
const void *nativeBuffer1,
const void *customBuffer0, const size_t customWidth0, const size_t customHeight0,
@ -7070,12 +7073,17 @@ void OGLDisplayLayer::SetVideoBuffers(const void *videoBufferHead,
GLint videoSrcTexStorageHint = GL_STORAGE_PRIVATE_APPLE;
GLint cpuFilterTexStorageHint = GL_STORAGE_PRIVATE_APPLE;
this->_videoSrcBufferHead = (uint16_t *)videoBufferHead;
this->_videoSrcBufferSize = (GPU_DISPLAY_WIDTH * GPU_DISPLAY_HEIGHT * 2 * sizeof(uint16_t)) + (customWidth0 * customHeight0 * sizeof(uint16_t)) + (customWidth1 * customHeight1 * sizeof(uint16_t));
this->_videoSrcNativeBuffer[0] = (uint16_t *)nativeBuffer0;
this->_videoSrcNativeBuffer[1] = (uint16_t *)nativeBuffer1;
this->_videoSrcCustomBuffer[0] = (uint16_t *)customBuffer0;
this->_videoSrcCustomBuffer[1] = (uint16_t *)customBuffer1;
const u8 bitCount = (colorFormat & 0x0000003F);
const GLenum glColorFormat = (bitCount == 5) ? GL_UNSIGNED_SHORT_1_5_5_5_REV : GL_UNSIGNED_INT_8_8_8_8_REV;
const size_t pixelBytes = (glColorFormat == GL_UNSIGNED_SHORT_1_5_5_5_REV) ? sizeof(uint16_t) : sizeof(uint32_t);
this->_videoColorFormat = glColorFormat;
this->_videoSrcBufferHead = videoBufferHead;
this->_videoSrcBufferSize = (GPU_DISPLAY_WIDTH * GPU_DISPLAY_HEIGHT * 2 * pixelBytes) + (customWidth0 * customHeight0 * pixelBytes) + (customWidth1 * customHeight1 * pixelBytes);
this->_videoSrcNativeBuffer[0] = nativeBuffer0;
this->_videoSrcNativeBuffer[1] = nativeBuffer1;
this->_videoSrcCustomBuffer[0] = customBuffer0;
this->_videoSrcCustomBuffer[1] = customBuffer1;
this->_videoSrcCustomBufferWidth[0] = customWidth0;
this->_videoSrcCustomBufferWidth[1] = customWidth1;
this->_videoSrcCustomBufferHeight[0] = customHeight0;
@ -7093,19 +7101,19 @@ void OGLDisplayLayer::SetVideoBuffers(const void *videoBufferHead,
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataNativeID[0]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_STORAGE_HINT_APPLE, videoSrcTexStorageHint);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT, 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, this->_videoSrcNativeBuffer[0]);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT, 0, GL_RGBA, this->_videoColorFormat, this->_videoSrcNativeBuffer[0]);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataNativeID[1]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_STORAGE_HINT_APPLE, videoSrcTexStorageHint);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT, 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, this->_videoSrcNativeBuffer[1]);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT, 0, GL_RGBA, this->_videoColorFormat, this->_videoSrcNativeBuffer[1]);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataCustomID[0]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_STORAGE_HINT_APPLE, videoSrcTexStorageHint);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, this->_videoSrcCustomBufferWidth[0], this->_videoSrcCustomBufferHeight[0], 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, this->_videoSrcCustomBuffer[0]);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, this->_videoSrcCustomBufferWidth[0], this->_videoSrcCustomBufferHeight[0], 0, GL_RGBA, this->_videoColorFormat, this->_videoSrcCustomBuffer[0]);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataCustomID[1]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_STORAGE_HINT_APPLE, videoSrcTexStorageHint);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, this->_videoSrcCustomBufferWidth[1], this->_videoSrcCustomBufferHeight[1], 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, this->_videoSrcCustomBuffer[1]);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, this->_videoSrcCustomBufferWidth[1], this->_videoSrcCustomBufferHeight[1], 0, GL_RGBA, this->_videoColorFormat, this->_videoSrcCustomBuffer[1]);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
@ -7837,19 +7845,26 @@ void OGLDisplayLayer::LoadFrameOGL(bool isMainSizeNative, bool isTouchSizeNative
if (!isUsingCPUPixelScaler || this->_useDeposterize)
{
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataNativeID[0]);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, this->_videoSrcNativeBuffer[0]);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT, GL_RGBA, this->_videoColorFormat, this->_videoSrcNativeBuffer[0]);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
glFlush();
}
else
{
RGB555ToBGRA8888Buffer(this->_videoSrcNativeBuffer[0], this->_vf[0]->GetSrcBufferPtr(), GPU_DISPLAY_WIDTH * GPU_DISPLAY_HEIGHT);
if (this->_videoColorFormat == GL_UNSIGNED_SHORT_1_5_5_5_REV)
{
RGB555ToBGRA8888Buffer((const uint16_t *)this->_videoSrcNativeBuffer[0], this->_vf[0]->GetSrcBufferPtr(), GPU_DISPLAY_WIDTH * GPU_DISPLAY_HEIGHT);
}
else
{
RGB888ToBGRA8888Buffer((const uint32_t *)this->_videoSrcNativeBuffer[0], this->_vf[0]->GetSrcBufferPtr(), GPU_DISPLAY_WIDTH * GPU_DISPLAY_HEIGHT);
}
}
}
else
{
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataCustomID[0]);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, this->_videoSrcCustomBufferWidth[0], this->_videoSrcCustomBufferHeight[0], GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, this->_videoSrcCustomBuffer[0]);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, this->_videoSrcCustomBufferWidth[0], this->_videoSrcCustomBufferHeight[0], GL_RGBA, this->_videoColorFormat, this->_videoSrcCustomBuffer[0]);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
glFlush();
}
@ -7872,19 +7887,26 @@ void OGLDisplayLayer::LoadFrameOGL(bool isMainSizeNative, bool isTouchSizeNative
if (!isUsingCPUPixelScaler || this->_useDeposterize)
{
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataNativeID[1]);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, this->_videoSrcNativeBuffer[1]);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT, GL_RGBA, this->_videoColorFormat, this->_videoSrcNativeBuffer[1]);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
glFlush();
}
else
{
RGB555ToBGRA8888Buffer(this->_videoSrcNativeBuffer[1], this->_vf[1]->GetSrcBufferPtr(), GPU_DISPLAY_WIDTH * GPU_DISPLAY_HEIGHT);
if (this->_videoColorFormat == GL_UNSIGNED_SHORT_1_5_5_5_REV)
{
RGB555ToBGRA8888Buffer((const uint16_t *)this->_videoSrcNativeBuffer[1], this->_vf[1]->GetSrcBufferPtr(), GPU_DISPLAY_WIDTH * GPU_DISPLAY_HEIGHT);
}
else
{
RGB888ToBGRA8888Buffer((const uint32_t *)this->_videoSrcNativeBuffer[1], this->_vf[1]->GetSrcBufferPtr(), GPU_DISPLAY_WIDTH * GPU_DISPLAY_HEIGHT);
}
}
}
else
{
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataCustomID[1]);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, this->_videoSrcCustomBufferWidth[1], this->_videoSrcCustomBufferHeight[1], GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, this->_videoSrcCustomBuffer[1]);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, this->_videoSrcCustomBufferWidth[1], this->_videoSrcCustomBufferHeight[1], GL_RGBA, this->_videoColorFormat, this->_videoSrcCustomBuffer[1]);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
glFlush();
}

View File

@ -400,10 +400,11 @@ protected:
GLfloat _texLoadedWidth[2];
GLfloat _texLoadedHeight[2];
uint16_t *_videoSrcBufferHead;
GLenum _videoColorFormat;
const void *_videoSrcBufferHead;
const void *_videoSrcNativeBuffer[2];
const void *_videoSrcCustomBuffer[2];
size_t _videoSrcBufferSize;
uint16_t *_videoSrcNativeBuffer[2];
uint16_t *_videoSrcCustomBuffer[2];
GLsizei _videoSrcCustomBufferWidth[2];
GLsizei _videoSrcCustomBufferHeight[2];
@ -456,7 +457,8 @@ public:
OGLDisplayLayer(OGLVideoOutput *oglVO);
virtual ~OGLDisplayLayer();
void SetVideoBuffers(const void *videoBufferHead,
void SetVideoBuffers(const uint32_t colorFormat,
const void *videoBufferHead,
const void *nativeBuffer0,
const void *nativeBuffer1,
const void *customBuffer0, const size_t customWidth0, const size_t customHeight0,

View File

@ -118,15 +118,16 @@ typedef struct
@required
- (void) doInitVideoOutput:(NSDictionary *)properties;
- (void) doSetVideoBuffers:(const uint16_t *)videoBufferHead
nativeBuffer0:(const uint16_t *)nativeBuffer0
nativeBuffer1:(const uint16_t *)nativeBuffer1
customBuffer0:(const uint16_t *)customBuffer0
customWidth0:(const size_t)customWidth0
customHeight0:(const size_t)customHeight0
customBuffer1:(const uint16_t *)customBuffer1
customWidth1:(const size_t)customWidth1
customHeight1:(const size_t)customHeight1;
- (void) doSetVideoBuffersUsingFormat:(const uint32_t)colorFormat
bufferHead:(const void *)videoBufferHead
nativeBuffer0:(const void *)nativeBuffer0
nativeBuffer1:(const void *)nativeBuffer1
customBuffer0:(const void *)customBuffer0
customWidth0:(const size_t)customWidth0
customHeight0:(const size_t)customHeight0
customBuffer1:(const void *)customBuffer1
customWidth1:(const size_t)customWidth1
customHeight1:(const size_t)customHeight1;
- (void) doLoadVideoFrameWithMainSizeNative:(bool)isMainSizeNative touchSizeNative:(bool)isTouchSizeNative;
@ -183,9 +184,9 @@ typedef struct
@interface CocoaDSDisplayVideo : CocoaDSDisplay
{
uint16_t *_videoBuffer;
uint16_t *_nativeBuffer[2];
uint16_t *_customBuffer[2];
void *_videoBuffer;
void *_nativeBuffer[2];
void *_customBuffer[2];
}
- (void) handleReceiveGPUFrame;

View File

@ -725,7 +725,6 @@
const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo();
const NSInteger dispMode = [self displayMode];
uint16_t *displayBuffer = dispInfo.masterCustomBuffer;
NSUInteger w = (NSUInteger)dispInfo.customWidth;
NSUInteger h = (dispMode == DS_DISPLAY_TYPE_DUAL) ? (NSUInteger)(dispInfo.customHeight * 2) : (NSUInteger)dispInfo.customHeight;
@ -745,12 +744,23 @@
return imageRep;
}
void *displayBuffer = dispInfo.masterCustomBuffer;
uint32_t *bitmapData = (uint32_t *)[imageRep bitmapData];
pthread_rwlock_rdlock(self.rwlockProducer);
GPU->GetEngineMain()->ResolveToCustomFramebuffer();
GPU->GetEngineSub()->ResolveToCustomFramebuffer();
RGB555ToRGBA8888Buffer(displayBuffer, bitmapData, (w * h));
if (dispInfo.pixelBytes == 2)
{
RGB555ToRGBA8888Buffer((u16 *)displayBuffer, bitmapData, (w * h));
}
else if (dispInfo.pixelBytes == 4)
{
RGBA8888ForceOpaqueBuffer((u32 *)displayBuffer, bitmapData, (w * h));
}
pthread_rwlock_unlock(self.rwlockProducer);
#ifdef __BIG_ENDIAN__
@ -904,23 +914,23 @@
if (isMainSizeNative && isTouchSizeNative)
{
memcpy(_nativeBuffer[NDSDisplayID_Main], dispInfo.masterNativeBuffer, GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2 * sizeof(uint16_t));
memcpy(_nativeBuffer[NDSDisplayID_Main], dispInfo.masterNativeBuffer, GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2 * dispInfo.pixelBytes);
}
else
{
if (!isMainSizeNative && !isTouchSizeNative)
{
memcpy(_customBuffer[NDSDisplayID_Main], dispInfo.masterCustomBuffer, dispInfo.customWidth * dispInfo.customHeight * 2 * sizeof(uint16_t));
memcpy(_customBuffer[NDSDisplayID_Main], dispInfo.masterCustomBuffer, dispInfo.customWidth * dispInfo.customHeight * 2 * dispInfo.pixelBytes);
}
else if (isTouchSizeNative)
{
memcpy(_customBuffer[NDSDisplayID_Main], dispInfo.customBuffer[NDSDisplayID_Main], dispInfo.customWidth * dispInfo.customHeight * sizeof(uint16_t));
memcpy(_nativeBuffer[NDSDisplayID_Touch], dispInfo.nativeBuffer[NDSDisplayID_Touch], GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * sizeof(uint16_t));
memcpy(_customBuffer[NDSDisplayID_Main], dispInfo.customBuffer[NDSDisplayID_Main], dispInfo.customWidth * dispInfo.customHeight * dispInfo.pixelBytes);
memcpy(_nativeBuffer[NDSDisplayID_Touch], dispInfo.nativeBuffer[NDSDisplayID_Touch], GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * dispInfo.pixelBytes);
}
else
{
memcpy(_nativeBuffer[NDSDisplayID_Main], dispInfo.nativeBuffer[NDSDisplayID_Main], GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * sizeof(uint16_t));
memcpy(_customBuffer[NDSDisplayID_Touch], dispInfo.customBuffer[NDSDisplayID_Touch], dispInfo.customWidth * dispInfo.customHeight * sizeof(uint16_t));
memcpy(_nativeBuffer[NDSDisplayID_Main], dispInfo.nativeBuffer[NDSDisplayID_Main], GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * dispInfo.pixelBytes);
memcpy(_customBuffer[NDSDisplayID_Touch], dispInfo.customBuffer[NDSDisplayID_Touch], dispInfo.customWidth * dispInfo.customHeight * dispInfo.pixelBytes);
}
}
@ -1006,25 +1016,43 @@
- (void) resetVideoBuffers
{
size_t pixelBytes = sizeof(uint16_t);
const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo();
uint16_t *oldVideoBuffer = _videoBuffer;
uint16_t *newVideoBuffer = (uint16_t *)malloc_alignedCacheLine( ((GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT) + (dispInfo.customWidth * dispInfo.customHeight)) * 2 * sizeof(uint16_t) );
[(id<CocoaDSDisplayVideoDelegate>)delegate doSetVideoBuffers:newVideoBuffer
nativeBuffer0:newVideoBuffer
nativeBuffer1:newVideoBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT)
customBuffer0:newVideoBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2)
customWidth0:dispInfo.customWidth
customHeight0:dispInfo.customHeight
customBuffer1:newVideoBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2) + (dispInfo.customWidth * dispInfo.customHeight)
customWidth1:dispInfo.customWidth
customHeight1:dispInfo.customHeight];
switch (dispInfo.colorFormat)
{
case NDSColorFormat_BGR555_Rev:
pixelBytes = sizeof(uint16_t);
break;
case NDSColorFormat_BGR666_Rev:
case NDSColorFormat_BGR888_Rev:
pixelBytes = sizeof(uint32_t);
break;
default:
break;
}
void *oldVideoBuffer = _videoBuffer;
uint8_t *newVideoBuffer = (uint8_t *)malloc_alignedCacheLine( ((GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT) + (dispInfo.customWidth * dispInfo.customHeight)) * 2 * pixelBytes );
[(id<CocoaDSDisplayVideoDelegate>)delegate doSetVideoBuffersUsingFormat:dispInfo.colorFormat
bufferHead:newVideoBuffer
nativeBuffer0:newVideoBuffer
nativeBuffer1:newVideoBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * pixelBytes)
customBuffer0:newVideoBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2 * pixelBytes)
customWidth0:dispInfo.customWidth
customHeight0:dispInfo.customHeight
customBuffer1:newVideoBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2 * pixelBytes) + (dispInfo.customWidth * dispInfo.customHeight * pixelBytes)
customWidth1:dispInfo.customWidth
customHeight1:dispInfo.customHeight];
_videoBuffer = newVideoBuffer;
_nativeBuffer[NDSDisplayID_Main] = newVideoBuffer;
_nativeBuffer[NDSDisplayID_Touch] = newVideoBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT);
_customBuffer[NDSDisplayID_Main] = newVideoBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2);
_customBuffer[NDSDisplayID_Touch] = newVideoBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2) + (dispInfo.customWidth * dispInfo.customHeight);
_nativeBuffer[NDSDisplayID_Touch] = newVideoBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * pixelBytes);
_customBuffer[NDSDisplayID_Main] = newVideoBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2 * pixelBytes);
_customBuffer[NDSDisplayID_Touch] = newVideoBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2 * pixelBytes) + (dispInfo.customWidth * dispInfo.customHeight * pixelBytes);
free_aligned(oldVideoBuffer);
}

View File

@ -2288,21 +2288,23 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
CGLUnlockContext(cglDisplayContext);
}
- (void)doSetVideoBuffers:(const uint16_t *)videoBufferHead
nativeBuffer0:(const uint16_t *)nativeBuffer0
nativeBuffer1:(const uint16_t *)nativeBuffer1
customBuffer0:(const uint16_t *)customBuffer0
customWidth0:(const size_t)customWidth0
customHeight0:(const size_t)customHeight0
customBuffer1:(const uint16_t *)customBuffer1
customWidth1:(const size_t)customWidth1
customHeight1:(const size_t)customHeight1
- (void) doSetVideoBuffersUsingFormat:(const uint32_t)colorFormat
bufferHead:(const void *)videoBufferHead
nativeBuffer0:(const void *)nativeBuffer0
nativeBuffer1:(const void *)nativeBuffer1
customBuffer0:(const void *)customBuffer0
customWidth0:(const size_t)customWidth0
customHeight0:(const size_t)customHeight0
customBuffer1:(const void *)customBuffer1
customWidth1:(const size_t)customWidth1
customHeight1:(const size_t)customHeight1
{
OGLDisplayLayer *displayLayer = oglv->GetDisplayLayer();
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
displayLayer->SetVideoBuffers(videoBufferHead,
displayLayer->SetVideoBuffers(colorFormat,
videoBufferHead,
nativeBuffer0,
nativeBuffer1,
customBuffer0, customWidth0, customHeight0,

View File

@ -170,6 +170,28 @@ inline uint32_t RGB555ToBGRA8888(const uint16_t color16)
0xFF000000;
}
/********************************************************************************************
RGB888ToBGRA8888() - INLINE
Converts a color from 24-bit RGB888 format into 32-bit BGRA8888 format.
Takes:
color32 - The pixel in 24-bit RGB888 format.
Returns:
A 32-bit unsigned integer containing the BGRA8888 formatted color.
Details:
The input and output pixels are expected to have little-endian byte order.
********************************************************************************************/
inline uint32_t RGB888ToBGRA8888(const uint32_t color32)
{
return ((color32 & 0x000000FF) << 16) |
((color32 & 0x0000FF00) ) |
((color32 & 0x00FF0000) >> 16) |
0xFF000000;
}
/********************************************************************************************
RGBA8888ForceOpaque() - INLINE
@ -249,6 +271,36 @@ void RGB555ToBGRA8888Buffer(const uint16_t *__restrict__ srcBuffer, uint32_t *__
}
}
/********************************************************************************************
RGB888ToBGRA8888Buffer()
Copies a 24-bit RGB888 pixel buffer into a 32-bit BGRA8888 pixel buffer.
Takes:
srcBuffer - Pointer to the source 24-bit RGB888 pixel buffer.
destBuffer - Pointer to the destination 32-bit BGRA8888 pixel buffer.
pixelCount - The number of pixels to copy.
Returns:
Nothing.
Details:
The source and destination pixels are expected to have little-endian byte order.
Also, it is the caller's responsibility to ensure that the source and destination
buffers are large enough to accomodate the requested number of pixels.
********************************************************************************************/
void RGB888ToBGRA8888Buffer(const uint32_t *__restrict__ srcBuffer, uint32_t *__restrict__ destBuffer, size_t pixelCount)
{
const uint32_t *__restrict__ destBufferEnd = destBuffer + pixelCount;
while (destBuffer < destBufferEnd)
{
*destBuffer++ = RGB888ToBGRA8888(*srcBuffer++);
}
}
/********************************************************************************************
RGBA8888ForceOpaqueBuffer()

View File

@ -31,9 +31,11 @@ bool IsOSXVersionSupported(const unsigned int major, const unsigned int minor, c
uint32_t RGB555ToRGBA8888(const uint16_t color16);
uint32_t RGB555ToBGRA8888(const uint16_t color16);
uint32_t RGB888ToBGRA8888(const uint32_t color32);
uint32_t RGBA8888ForceOpaque(const uint32_t color32);
void RGB555ToRGBA8888Buffer(const uint16_t *__restrict__ srcBuffer, uint32_t *__restrict__ destBuffer, size_t pixelCount);
void RGB555ToBGRA8888Buffer(const uint16_t *__restrict__ srcBuffer, uint32_t *__restrict__ destBuffer, size_t pixelCount);
void RGB888ToBGRA8888Buffer(const uint32_t *__restrict__ srcBuffer, uint32_t *__restrict__ destBuffer, size_t pixelCount);
void RGBA8888ForceOpaqueBuffer(const uint32_t *__restrict__ srcBuffer, uint32_t *__restrict__ destBuffer, size_t pixelCount);
CGSize GetTransformedBounds(const double normalBoundsWidth, const double normalBoundsHeight,

View File

@ -739,6 +739,7 @@ extern CACHE_ALIGN u16 color_15bit_to_16bit_reverse[32768];
extern CACHE_ALIGN u32 dsDepthExtend_15bit_to_24bit[32768];
extern CACHE_ALIGN u8 mixTable555[32][32][32];
extern CACHE_ALIGN const u32 material_5bit_to_31bit[32];
extern CACHE_ALIGN const u8 material_5bit_to_6bit[32];
extern CACHE_ALIGN const u8 material_5bit_to_8bit[32];
extern CACHE_ALIGN const u8 material_3bit_to_5bit[8];
extern CACHE_ALIGN const u8 material_3bit_to_6bit[8];

View File

@ -221,7 +221,7 @@ static void Printscreen()
gchar *filename;
GError *error = NULL;
u8 *rgb;
u16 *gpuFramebuffer = GPU->GetDisplayInfo().masterNativeBuffer;
u16 *gpuFramebuffer = (u16 *)GPU->GetDisplayInfo().masterNativeBuffer;
static int seq = 0;
rgb = (u8 *) malloc(SCREENS_PIXEL_SIZE*3);

View File

@ -117,7 +117,7 @@ static void decode_screen () {
int x,y, m, W,H,L,BL;
u32 image[RAW_H*2][RAW_W], pix;
u16 * pixel = GPU->GetDisplayInfo().masterNativeBuffer;
u16 * pixel = (u16 *)GPU->GetDisplayInfo().masterNativeBuffer;
u32 * rgb32 = &on_screen_image32[0];
/* decode colors */

View File

@ -1547,7 +1547,7 @@ static inline void RGB555ToBGRA8888Buffer(const uint16_t *__restrict__ srcBuffer
static inline void gpu_screen_to_rgb(u32* dst)
{
RGB555ToRGBA8888Buffer(GPU->GetDisplayInfo().masterNativeBuffer, dst, 256 * 384);
RGB555ToRGBA8888Buffer((const uint16_t *)GPU->GetDisplayInfo().masterNativeBuffer, dst, 256 * 384);
}
static inline void drawScreen(cairo_t* cr, u32* buf, gint w, gint h) {
@ -1672,7 +1672,7 @@ static gboolean ExposeDrawingArea (GtkWidget *widget, GdkEventExpose *event, gpo
}
static void RedrawScreen() {
RGB555ToBGRA8888Buffer(GPU->GetDisplayInfo().masterNativeBuffer, video->GetSrcBufferPtr(), 256 * 384);
RGB555ToBGRA8888Buffer((const uint16_t *)GPU->GetDisplayInfo().masterNativeBuffer, video->GetSrcBufferPtr(), 256 * 384);
#ifdef HAVE_LIBAGG
aggDraw.hud->attach((u8*)video->GetSrcBufferPtr(), 256, 384, 1024);
osd->update();
@ -2437,7 +2437,7 @@ gboolean EmuLoop(gpointer data)
desmume_cycle(); /* Emule ! */
_updateDTools();
avout_x264.updateVideo(GPU->GetDisplayInfo().masterNativeBuffer);
avout_x264.updateVideo((const uint16_t *)GPU->GetDisplayInfo().masterNativeBuffer);
RedrawScreen();
if (!config.fpslimiter || keys_latch & KEYMASK_(KEY_BOOST - 1)) {

View File

@ -106,7 +106,7 @@ bool Video::setFilter(VideoFilterTypeID filterID) {
}
unsigned int* Video::runFilter() {
RGB555ToRGBA8888Buffer(GPU->GetDisplayInfo().masterNativeBuffer, this->mFilter.GetSrcBufferPtr(), 256 * 384);
RGB555ToRGBA8888Buffer((const uint16_t *)GPU->GetDisplayInfo().masterNativeBuffer, this->mFilter.GetSrcBufferPtr(), 256 * 384);
unsigned int* buf = this->mFilter.RunFilter();
this->screenBufferUpdated(buf, this->getDstSize(), this->getDstScale());
return buf;

View File

@ -419,7 +419,7 @@ void DRV_AviVideoUpdate()
return;
const NDSDisplayInfo& dispInfo = GPU->GetDisplayInfo();
const u16* buffer = dispInfo.masterCustomBuffer;
const u16* buffer = (const u16 *)dispInfo.masterCustomBuffer;
//dont do anything if prescale has changed, it's just going to be garbage
if(video.prescaleHD != avi_file->prescaleLevel)

View File

@ -164,13 +164,13 @@ void HK_QuickScreenShot(int param, bool justPressed)
case path.PNG:
{
strcat(fname, ".png");
NDS_WritePNG_16bpp(dispInfo.customWidth, dispInfo.customHeight*2, dispInfo.masterCustomBuffer, fname);
NDS_WritePNG_16bpp(dispInfo.customWidth, dispInfo.customHeight*2, (const u16 *)dispInfo.masterCustomBuffer, fname);
}
break;
case path.BMP:
{
strcat(fname, ".bmp");
NDS_WriteBMP_16bpp(dispInfo.customWidth, dispInfo.customHeight *2, dispInfo.masterCustomBuffer, fname);
NDS_WriteBMP_16bpp(dispInfo.customWidth, dispInfo.customHeight *2, (const u16 *)dispInfo.masterCustomBuffer, fname);
}
break;
}
@ -224,9 +224,9 @@ void HK_PrintScreen(int param, bool justPressed)
filename = outFilename;
if(toupper(strright(filename,4)) == ".PNG")
NDS_WritePNG_16bpp(dispInfo.customWidth, dispInfo.customHeight*2, dispInfo.masterCustomBuffer, filename.c_str());
NDS_WritePNG_16bpp(dispInfo.customWidth, dispInfo.customHeight*2, (const u16 *)dispInfo.masterCustomBuffer, filename.c_str());
else if(toupper(strright(filename,4)) == ".BMP")
NDS_WriteBMP_16bpp(dispInfo.customWidth, dispInfo.customHeight*2, dispInfo.masterCustomBuffer, filename.c_str());
NDS_WriteBMP_16bpp(dispInfo.customWidth, dispInfo.customHeight*2, (const u16 *)dispInfo.masterCustomBuffer, filename.c_str());
}
if(unpause) NDS_UnPause(false);