Cocoa Port: More refactoring work on ClientDisplayView.

- Most notably, HandleGPUFrameEndEvent() now sends the entirety of the
NDSDisplayInfo struct to the client.
- The OpenGL blitter now skips the loading, processing and rendering of
disabled screens.
- Begin preparing DisplayView to handle the upcoming Apple Metal
blitter.
- Do some misc. code cleanup and simplification.
This commit is contained in:
rogerman 2017-01-18 16:05:41 -08:00
parent e487193545
commit aa8069ce1a
8 changed files with 248 additions and 254 deletions

View File

@ -76,7 +76,8 @@ void ClientDisplayView::__InstanceInit(const ClientDisplayViewProperties &props)
_showCPULoadAverage = false; _showCPULoadAverage = false;
_showRTC = false; _showRTC = false;
memset(&_frameInfo, 0, sizeof(_frameInfo)); memset(&_emuDisplayInfo, 0, sizeof(_emuDisplayInfo));
memset(&_emuFrameInfo, 0, sizeof(_emuFrameInfo));
_hudString = "\x01"; // Char value 0x01 will represent the "text box" character, which will always be first in the string. _hudString = "\x01"; // Char value 0x01 will represent the "text box" character, which will always be first in the string.
FT_Error error = FT_Init_FreeType(&_ftLibrary); FT_Error error = FT_Init_FreeType(&_ftLibrary);
@ -105,36 +106,36 @@ void ClientDisplayView::_UpdateHUDString()
if (this->_showVideoFPS) if (this->_showVideoFPS)
{ {
ss << "Video FPS: " << this->_frameInfo.videoFPS << "\n"; ss << "Video FPS: " << this->_emuFrameInfo.videoFPS << "\n";
} }
if (this->_showRender3DFPS) if (this->_showRender3DFPS)
{ {
ss << "3D Rendering FPS: " << this->_frameInfo.render3DFPS << "\n"; ss << "3D Rendering FPS: " << this->_emuFrameInfo.render3DFPS << "\n";
} }
if (this->_showFrameIndex) if (this->_showFrameIndex)
{ {
ss << "Frame Index: " << this->_frameInfo.frameIndex << "\n"; ss << "Frame Index: " << this->_emuFrameInfo.frameIndex << "\n";
} }
if (this->_showLagFrameCount) if (this->_showLagFrameCount)
{ {
ss << "Lag Frame Count: " << this->_frameInfo.lagFrameCount << "\n"; ss << "Lag Frame Count: " << this->_emuFrameInfo.lagFrameCount << "\n";
} }
if (this->_showCPULoadAverage) if (this->_showCPULoadAverage)
{ {
static char buffer[32]; static char buffer[32];
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
snprintf(buffer, 25, "CPU Load Avg: %02d%% / %02d%%\n", this->_frameInfo.cpuLoadAvgARM9, this->_frameInfo.cpuLoadAvgARM7); snprintf(buffer, 25, "CPU Load Avg: %02d%% / %02d%%\n", this->_emuFrameInfo.cpuLoadAvgARM9, this->_emuFrameInfo.cpuLoadAvgARM7);
ss << buffer; ss << buffer;
} }
if (this->_showRTC) if (this->_showRTC)
{ {
ss << "RTC: " << this->_frameInfo.rtcString << "\n"; ss << "RTC: " << this->_emuFrameInfo.rtcString << "\n";
} }
this->_hudString = ss.str(); this->_hudString = ss.str();
@ -365,7 +366,7 @@ void ClientDisplayView::CopyHUDFont(const FT_Face &fontFace, const size_t glyphS
void ClientDisplayView::SetHUDInfo(const NDSFrameInfo &frameInfo) void ClientDisplayView::SetHUDInfo(const NDSFrameInfo &frameInfo)
{ {
this->_frameInfo = frameInfo; this->_emuFrameInfo = frameInfo;
this->_UpdateHUDString(); this->_UpdateHUDString();
} }
@ -455,7 +456,47 @@ void ClientDisplayView::SetHUDShowRTC(const bool visibleState)
} }
// NDS GPU Interface // NDS GPU Interface
void ClientDisplayView::FrameProcessGPU() void ClientDisplayView::_LoadNativeDisplayByID(const NDSDisplayID displayID)
{
// Do nothing. This is implementation dependent.
}
void ClientDisplayView::_LoadCustomDisplayByID(const NDSDisplayID displayID)
{
// Do nothing. This is implementation dependent.
}
void ClientDisplayView::LoadDisplays()
{
const bool loadMainScreen = this->_emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Main] && ((this->_renderProperty.mode == ClientDisplayMode_Main) || (this->_renderProperty.mode == ClientDisplayMode_Dual));
const bool loadTouchScreen = this->_emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Touch] && ((this->_renderProperty.mode == ClientDisplayMode_Touch) || (this->_renderProperty.mode == ClientDisplayMode_Dual));
if (loadMainScreen)
{
if (!this->_emuDisplayInfo.didPerformCustomRender[NDSDisplayID_Main])
{
this->_LoadNativeDisplayByID(NDSDisplayID_Main);
}
else
{
this->_LoadCustomDisplayByID(NDSDisplayID_Main);
}
}
if (loadTouchScreen)
{
if (!this->_emuDisplayInfo.didPerformCustomRender[NDSDisplayID_Touch])
{
this->_LoadNativeDisplayByID(NDSDisplayID_Touch);
}
else
{
this->_LoadCustomDisplayByID(NDSDisplayID_Touch);
}
}
}
void ClientDisplayView::ProcessDisplays()
{ {
// Do nothing. This is implementation dependent. // Do nothing. This is implementation dependent.
} }
@ -465,6 +506,16 @@ void ClientDisplayView::FrameProcessHUD()
// Do nothing. This is implementation dependent. // Do nothing. This is implementation dependent.
} }
const NDSDisplayInfo& ClientDisplayView::GetEmuDisplayInfo() const
{
return this->_emuDisplayInfo;
}
void ClientDisplayView::HandleGPUFrameEndEvent(const NDSDisplayInfo &ndsDisplayInfo)
{
this->_emuDisplayInfo = ndsDisplayInfo;
}
// Touch screen input handling // Touch screen input handling
void ClientDisplayView::GetNDSPoint(const int inputID, const bool isInitialTouchPress, void ClientDisplayView::GetNDSPoint(const int inputID, const bool isInitialTouchPress,
const double clientX, const double clientY, const double clientX, const double clientY,

View File

@ -130,7 +130,8 @@ protected:
bool _showCPULoadAverage; bool _showCPULoadAverage;
bool _showRTC; bool _showRTC;
NDSFrameInfo _frameInfo; NDSDisplayInfo _emuDisplayInfo;
NDSFrameInfo _emuFrameInfo;
std::string _hudString; std::string _hudString;
FT_Library _ftLibrary; FT_Library _ftLibrary;
@ -148,6 +149,9 @@ protected:
virtual void _UpdateClientSize() = 0; virtual void _UpdateClientSize() = 0;
virtual void _UpdateViewScale(); virtual void _UpdateViewScale();
virtual void _LoadNativeDisplayByID(const NDSDisplayID displayID);
virtual void _LoadCustomDisplayByID(const NDSDisplayID displayID);
public: public:
ClientDisplayView(); ClientDisplayView();
ClientDisplayView(const ClientDisplayViewProperties &props); ClientDisplayView(const ClientDisplayViewProperties &props);
@ -208,14 +212,15 @@ public:
virtual void SetHUDShowRTC(const bool visibleState); virtual void SetHUDShowRTC(const bool visibleState);
// NDS GPU interface // NDS GPU interface
virtual void FrameLoadGPU(bool isMainSizeNative, bool isTouchSizeNative) = 0; virtual void LoadDisplays();
virtual void FrameProcessGPU(); virtual void ProcessDisplays();
virtual void FrameProcessHUD(); virtual void FrameProcessHUD();
virtual void FrameRender() = 0; virtual void FrameRender() = 0;
virtual void FrameFinish() = 0; virtual void FrameFinish() = 0;
// Emulator interface // Emulator interface
virtual void HandleGPUFrameEndEvent(const bool isMainSizeNative, const bool isTouchSizeNative) = 0; const NDSDisplayInfo& GetEmuDisplayInfo() const;
virtual void HandleGPUFrameEndEvent(const NDSDisplayInfo &ndsDisplayInfo);
virtual void HandleEmulatorFrameEndEvent(const NDSFrameInfo &frameInfo) = 0; virtual void HandleEmulatorFrameEndEvent(const NDSFrameInfo &frameInfo) = 0;
// Touch screen input handling // Touch screen input handling

View File

@ -4881,6 +4881,16 @@ void OGLVideoOutput::_UpdateViewport()
this->_needUpdateViewport = false; this->_needUpdateViewport = false;
} }
void OGLVideoOutput::_LoadNativeDisplayByID(const NDSDisplayID displayID)
{
this->GetDisplayLayer()->LoadNativeDisplayByID_OGL(displayID);
}
void OGLVideoOutput::_LoadCustomDisplayByID(const NDSDisplayID displayID)
{
this->GetDisplayLayer()->LoadCustomDisplayByID_OGL(displayID);
}
OGLContextInfo* OGLVideoOutput::GetContextInfo() OGLContextInfo* OGLVideoOutput::GetContextInfo()
{ {
return this->_contextInfo; return this->_contextInfo;
@ -4992,12 +5002,7 @@ OGLHUDLayer* OGLVideoOutput::GetHUDLayer()
return (OGLHUDLayer *)this->_layerList->at(1); return (OGLHUDLayer *)this->_layerList->at(1);
} }
void OGLVideoOutput::FrameLoadGPU(bool isMainSizeNative, bool isTouchSizeNative) void OGLVideoOutput::ProcessDisplays()
{
this->GetDisplayLayer()->LoadFrameOGL(isMainSizeNative, isTouchSizeNative);
}
void OGLVideoOutput::FrameProcessGPU()
{ {
OGLDisplayLayer *displayLayer = this->GetDisplayLayer(); OGLDisplayLayer *displayLayer = this->GetDisplayLayer();
if (displayLayer->IsVisible()) if (displayLayer->IsVisible())
@ -6447,23 +6452,12 @@ OGLDisplayLayer::OGLDisplayLayer(OGLVideoOutput *oglVO)
_displayTexFilter[0] = GL_NEAREST; _displayTexFilter[0] = GL_NEAREST;
_displayTexFilter[1] = GL_NEAREST; _displayTexFilter[1] = GL_NEAREST;
_isTexVideoInputDataNative[0] = true;
_isTexVideoInputDataNative[1] = true;
_texLoadedWidth[0] = (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH;
_texLoadedWidth[1] = (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH;
_texLoadedHeight[0] = (GLfloat)GPU_FRAMEBUFFER_NATIVE_HEIGHT;
_texLoadedHeight[1] = (GLfloat)GPU_FRAMEBUFFER_NATIVE_HEIGHT;
_videoColorFormat = GL_UNSIGNED_SHORT_1_5_5_5_REV; _videoColorFormat = GL_UNSIGNED_SHORT_1_5_5_5_REV;
_videoSrcBufferHead = NULL; _videoSrcBufferHead = NULL;
_videoSrcNativeBuffer[0] = NULL; _videoSrcNativeBuffer[0] = NULL;
_videoSrcNativeBuffer[1] = NULL; _videoSrcNativeBuffer[1] = NULL;
_videoSrcCustomBuffer[0] = NULL; _videoSrcCustomBuffer[0] = NULL;
_videoSrcCustomBuffer[1] = NULL; _videoSrcCustomBuffer[1] = NULL;
_videoSrcCustomBufferWidth[0] = GPU_FRAMEBUFFER_NATIVE_WIDTH;
_videoSrcCustomBufferWidth[1] = GPU_FRAMEBUFFER_NATIVE_WIDTH;
_videoSrcCustomBufferHeight[0] = GPU_FRAMEBUFFER_NATIVE_HEIGHT;
_videoSrcCustomBufferHeight[1] = GPU_FRAMEBUFFER_NATIVE_HEIGHT;
// Set up textures // Set up textures
glGenTextures(2, _texCPUFilterDstID); glGenTextures(2, _texCPUFilterDstID);
@ -6577,7 +6571,7 @@ OGLDisplayLayer::OGLDisplayLayer(OGLVideoOutput *oglVO)
{ {
for (size_t i = 0; i < 2; i++) for (size_t i = 0; i < 2; i++)
{ {
_filterDeposterize[i] = new OGLFilterDeposterize(_vf[i]->GetSrcWidth(), _vf[i]->GetSrcHeight(), _shaderSupport, _useShader150); _filterDeposterize[i] = new OGLFilterDeposterize(GPU_FRAMEBUFFER_NATIVE_WIDTH, GPU_FRAMEBUFFER_NATIVE_HEIGHT, _shaderSupport, _useShader150);
_shaderFilter[i] = new OGLFilter(_vf[i]->GetSrcWidth(), _vf[i]->GetSrcHeight(), 1); _shaderFilter[i] = new OGLFilter(_vf[i]->GetSrcWidth(), _vf[i]->GetSrcHeight(), 1);
OGLShaderProgram *shaderFilterProgram = _shaderFilter[i]->GetProgram(); OGLShaderProgram *shaderFilterProgram = _shaderFilter[i]->GetProgram();
@ -6732,10 +6726,6 @@ void OGLDisplayLayer::SetVideoBuffers(const uint32_t colorFormat,
this->_videoSrcNativeBuffer[1] = nativeBuffer1; this->_videoSrcNativeBuffer[1] = nativeBuffer1;
this->_videoSrcCustomBuffer[0] = customBuffer0; this->_videoSrcCustomBuffer[0] = customBuffer0;
this->_videoSrcCustomBuffer[1] = customBuffer1; this->_videoSrcCustomBuffer[1] = customBuffer1;
this->_videoSrcCustomBufferWidth[0] = customWidth0;
this->_videoSrcCustomBufferWidth[1] = customWidth1;
this->_videoSrcCustomBufferHeight[0] = customHeight0;
this->_videoSrcCustomBufferHeight[1] = customHeight1;
this->DetermineTextureStorageHints(videoSrcTexStorageHint, cpuFilterTexStorageHint); this->DetermineTextureStorageHints(videoSrcTexStorageHint, cpuFilterTexStorageHint);
@ -6757,11 +6747,11 @@ void OGLDisplayLayer::SetVideoBuffers(const uint32_t colorFormat,
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataCustomID[0]); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataCustomID[0]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_STORAGE_HINT_APPLE, videoSrcTexStorageHint); 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_RGBA, this->_videoColorFormat, this->_videoSrcCustomBuffer[0]); glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, customWidth0, customHeight0, 0, GL_RGBA, this->_videoColorFormat, this->_videoSrcCustomBuffer[0]);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataCustomID[1]); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataCustomID[1]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_STORAGE_HINT_APPLE, videoSrcTexStorageHint); 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_RGBA, this->_videoColorFormat, this->_videoSrcCustomBuffer[1]); glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, customWidth1, customHeight1, 0, GL_RGBA, this->_videoColorFormat, this->_videoSrcCustomBuffer[1]);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
@ -6771,6 +6761,7 @@ void OGLDisplayLayer::SetVideoBuffers(const uint32_t colorFormat,
void OGLDisplayLayer::SetNeedsUpdateRotationScale() void OGLDisplayLayer::SetNeedsUpdateRotationScale()
{ {
this->_needUpdateRotationScale = true; this->_needUpdateRotationScale = true;
this->_needUpdateVertices = true;
} }
void OGLDisplayLayer::SetFiltersPreferGPUOGL() void OGLDisplayLayer::SetFiltersPreferGPUOGL()
@ -7245,105 +7236,39 @@ void OGLDisplayLayer::SetCPUPixelScalerOGL(const VideoFilterTypeID filterID)
this->_vf[1]->ChangeFilterByID(filterID); this->_vf[1]->ChangeFilterByID(filterID);
} }
void OGLDisplayLayer::LoadFrameOGL(bool isMainSizeNative, bool isTouchSizeNative) void OGLDisplayLayer::LoadNativeDisplayByID_OGL(const NDSDisplayID displayID)
{ {
const ClientDisplayMode mode = this->_output->GetViewProperties().mode;
const bool canFilterOnGPU = this->_output->CanFilterOnGPU();
const bool useDeposterize = this->_output->GetSourceDeposterize(); const bool useDeposterize = this->_output->GetSourceDeposterize();
const bool isUsingCPUPixelScaler = (this->_output->GetPixelScaler() != VideoFilterTypeID_None) && !this->_output->WillFilterOnGPU(); const bool isUsingCPUPixelScaler = (this->_output->GetPixelScaler() != VideoFilterTypeID_None) && !this->_output->WillFilterOnGPU();
const bool loadMainScreen = (mode == ClientDisplayMode_Main) || (mode == ClientDisplayMode_Dual);
const bool loadTouchScreen = (mode == ClientDisplayMode_Touch) || (mode == ClientDisplayMode_Dual);
this->_isTexVideoInputDataNative[0] = isMainSizeNative; if (!isUsingCPUPixelScaler || useDeposterize)
this->_isTexVideoInputDataNative[1] = isTouchSizeNative;
this->_texLoadedWidth[0] = (this->_isTexVideoInputDataNative[0]) ? (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH : (GLfloat)this->_videoSrcCustomBufferWidth[0];
this->_texLoadedHeight[0] = (this->_isTexVideoInputDataNative[0]) ? (GLfloat)GPU_FRAMEBUFFER_NATIVE_HEIGHT : (GLfloat)this->_videoSrcCustomBufferHeight[0];
this->_texLoadedWidth[1] = (this->_isTexVideoInputDataNative[1]) ? (GLfloat)GPU_FRAMEBUFFER_NATIVE_WIDTH : (GLfloat)this->_videoSrcCustomBufferWidth[1];
this->_texLoadedHeight[1] = (this->_isTexVideoInputDataNative[1]) ? (GLfloat)GPU_FRAMEBUFFER_NATIVE_HEIGHT : (GLfloat)this->_videoSrcCustomBufferHeight[1];
if (loadMainScreen)
{ {
if (this->_isTexVideoInputDataNative[0]) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataNativeID[displayID]);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, GPU_FRAMEBUFFER_NATIVE_WIDTH, GPU_FRAMEBUFFER_NATIVE_HEIGHT, GL_RGBA, this->_videoColorFormat, this->_videoSrcNativeBuffer[displayID]);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
glFlush();
}
else
{
if (this->_videoColorFormat == GL_UNSIGNED_SHORT_1_5_5_5_REV)
{ {
if (useDeposterize && canFilterOnGPU) ColorspaceConvertBuffer555To8888Opaque<true, false>((const uint16_t *)this->_videoSrcNativeBuffer[displayID], this->_vf[displayID]->GetSrcBufferPtr(), GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT);
{
if ( (this->_filterDeposterize[0]->GetSrcWidth() != this->_texLoadedWidth[0]) || (this->_filterDeposterize[0]->GetSrcHeight() != this->_texLoadedHeight[0]) )
{
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
this->_filterDeposterize[0]->SetSrcSizeOGL(this->_texLoadedWidth[0], this->_texLoadedHeight[0]);
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, this->_useClientStorage);
}
}
if (!isUsingCPUPixelScaler || useDeposterize)
{
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataNativeID[0]);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, GPU_FRAMEBUFFER_NATIVE_WIDTH, GPU_FRAMEBUFFER_NATIVE_HEIGHT, GL_RGBA, this->_videoColorFormat, this->_videoSrcNativeBuffer[0]);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
glFlush();
}
else
{
if (this->_videoColorFormat == GL_UNSIGNED_SHORT_1_5_5_5_REV)
{
ColorspaceConvertBuffer555To8888Opaque<true, false>((const uint16_t *)this->_videoSrcNativeBuffer[0], this->_vf[0]->GetSrcBufferPtr(), GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT);
}
else
{
ColorspaceConvertBuffer888XTo8888Opaque<true, false>((const uint32_t *)this->_videoSrcNativeBuffer[0], this->_vf[0]->GetSrcBufferPtr(), GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT);
}
}
} }
else else
{ {
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataCustomID[0]); ColorspaceConvertBuffer888XTo8888Opaque<true, false>((const uint32_t *)this->_videoSrcNativeBuffer[displayID], this->_vf[displayID]->GetSrcBufferPtr(), GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT);
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();
} }
} }
}
void OGLDisplayLayer::LoadCustomDisplayByID_OGL(const NDSDisplayID displayID)
{
const NDSDisplayInfo &emuDisplayInfo = this->_output->GetEmuDisplayInfo();
if (loadTouchScreen) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataCustomID[displayID]);
{ glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, emuDisplayInfo.customWidth, emuDisplayInfo.customHeight, GL_RGBA, this->_videoColorFormat, this->_videoSrcCustomBuffer[displayID]);
if (this->_isTexVideoInputDataNative[1]) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
{ glFlush();
if (useDeposterize && canFilterOnGPU)
{
if ( (this->_filterDeposterize[1]->GetSrcWidth() != this->_texLoadedWidth[1]) || (this->_filterDeposterize[1]->GetSrcHeight() != this->_texLoadedHeight[1]) )
{
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
this->_filterDeposterize[1]->SetSrcSizeOGL(this->_texLoadedWidth[1], this->_texLoadedHeight[1]);
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, this->_useClientStorage);
}
}
if (!isUsingCPUPixelScaler || useDeposterize)
{
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoInputDataNativeID[1]);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, GPU_FRAMEBUFFER_NATIVE_WIDTH, GPU_FRAMEBUFFER_NATIVE_HEIGHT, GL_RGBA, this->_videoColorFormat, this->_videoSrcNativeBuffer[1]);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
glFlush();
}
else
{
if (this->_videoColorFormat == GL_UNSIGNED_SHORT_1_5_5_5_REV)
{
ColorspaceConvertBuffer555To8888Opaque<true, false>((const uint16_t *)this->_videoSrcNativeBuffer[1], this->_vf[1]->GetSrcBufferPtr(), GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT);
}
else
{
ColorspaceConvertBuffer888XTo8888Opaque<true, false>((const uint32_t *)this->_videoSrcNativeBuffer[1], this->_vf[1]->GetSrcBufferPtr(), GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_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, this->_videoColorFormat, this->_videoSrcCustomBuffer[1]);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
glFlush();
}
}
} }
void OGLDisplayLayer::UpdateViewportOGL() void OGLDisplayLayer::UpdateViewportOGL()
@ -7366,130 +7291,99 @@ void OGLDisplayLayer::UpdateViewportOGL()
} }
} }
void OGLDisplayLayer::ProcessOGL() void OGLDisplayLayer::_ProcessDisplayByID(const NDSDisplayID displayID, GLsizei &inoutWidth, GLsizei &inoutHeight, GLuint &inoutTexID)
{ {
const bool willFilterOnGPU = this->_output->WillFilterOnGPU(); const bool willFilterOnGPU = this->_output->WillFilterOnGPU();
const bool useDeposterize = this->_output->GetSourceDeposterize(); const bool useDeposterize = this->_output->GetSourceDeposterize();
const bool isUsingCPUPixelScaler = (this->_output->GetPixelScaler() != VideoFilterTypeID_None) && !willFilterOnGPU; const bool isUsingCPUPixelScaler = (this->_output->GetPixelScaler() != VideoFilterTypeID_None) && !willFilterOnGPU;
const ClientDisplayMode mode = this->_output->GetViewProperties().mode;
// Source // Source
GLuint texVideoSourceID[2] = { (this->_isTexVideoInputDataNative[0]) ? this->_texVideoInputDataNativeID[0] : this->_texVideoInputDataCustomID[0], if (useDeposterize)
(this->_isTexVideoInputDataNative[1]) ? this->_texVideoInputDataNativeID[1] : this->_texVideoInputDataCustomID[1] };
// Pixel scaler - only perform on native resolution video input
GLfloat w0 = this->_texLoadedWidth[0];
GLfloat h0 = this->_texLoadedHeight[0];
GLfloat w1 = this->_texLoadedWidth[1];
GLfloat h1 = this->_texLoadedHeight[1];
if (this->_isTexVideoInputDataNative[0] && (mode == ClientDisplayMode_Main || mode == ClientDisplayMode_Dual))
{ {
if (useDeposterize) // For all shader-based filters, we need to temporarily disable GL_UNPACK_CLIENT_STORAGE_APPLE.
{ // Filtered images are supposed to remain on the GPU for immediate use for further GPU processing,
// For all shader-based filters, we need to temporarily disable GL_UNPACK_CLIENT_STORAGE_APPLE. // so using client-backed buffers for filtered images would simply waste memory here.
// Filtered images are supposed to remain on the GPU for immediate use for further GPU processing, glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
// so using client-backed buffers for filtered images would simply waste memory here. inoutTexID = this->_filterDeposterize[displayID]->RunFilterOGL(inoutTexID);
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE); glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, this->_useClientStorage);
texVideoSourceID[0] = this->_filterDeposterize[0]->RunFilterOGL(texVideoSourceID[0]);
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, this->_useClientStorage);
if (isUsingCPUPixelScaler) // Hybrid CPU/GPU-based path (may cause a performance hit on pixel download)
{
if ( this->_isTexVideoInputDataNative[0] && ((mode == ClientDisplayMode_Main) || (mode == ClientDisplayMode_Dual)) )
{
this->_filterDeposterize[0]->DownloadDstBufferOGL(this->_vf[0]->GetSrcBufferPtr(), 0, this->_filterDeposterize[0]->GetSrcHeight());
}
}
}
if (!isUsingCPUPixelScaler) if (isUsingCPUPixelScaler) // Hybrid CPU/GPU-based path (may cause a performance hit on pixel download)
{ {
if (willFilterOnGPU) this->_filterDeposterize[displayID]->DownloadDstBufferOGL(this->_vf[displayID]->GetSrcBufferPtr(), 0, this->_filterDeposterize[displayID]->GetSrcHeight());
{
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
texVideoSourceID[0] = this->_shaderFilter[0]->RunFilterOGL(texVideoSourceID[0]);
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, this->_useClientStorage);
w0 = this->_shaderFilter[0]->GetDstWidth();
h0 = this->_shaderFilter[0]->GetDstHeight();
}
}
else
{
uint32_t *texData = this->_vf[0]->RunFilter();
texVideoSourceID[0] = this->_texCPUFilterDstID[0];
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texVideoSourceID[0]);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, this->_vf[0]->GetDstWidth(), this->_vf[0]->GetDstHeight(), GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, texData);
glFlush();
w0 = this->_vf[0]->GetDstWidth();
h0 = this->_vf[0]->GetDstHeight();
} }
} }
if (this->_isTexVideoInputDataNative[1] && (mode == ClientDisplayMode_Touch || mode == ClientDisplayMode_Dual)) // Pixel scaler
if (!isUsingCPUPixelScaler)
{ {
if (useDeposterize) if (willFilterOnGPU)
{ {
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE); glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
texVideoSourceID[1] = this->_filterDeposterize[1]->RunFilterOGL(texVideoSourceID[1]); inoutTexID = this->_shaderFilter[displayID]->RunFilterOGL(inoutTexID);
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, this->_useClientStorage); glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, this->_useClientStorage);
if (isUsingCPUPixelScaler) // Hybrid CPU/GPU-based path (may cause a performance hit on pixel download) inoutWidth = this->_shaderFilter[displayID]->GetDstWidth();
{ inoutHeight = this->_shaderFilter[displayID]->GetDstHeight();
if ( this->_isTexVideoInputDataNative[1] && ((mode == ClientDisplayMode_Touch) || (mode == ClientDisplayMode_Dual)) )
{
this->_filterDeposterize[1]->DownloadDstBufferOGL(this->_vf[1]->GetSrcBufferPtr(), 0, this->_filterDeposterize[1]->GetSrcHeight());
}
}
}
if (!isUsingCPUPixelScaler)
{
if (willFilterOnGPU)
{
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
texVideoSourceID[1] = this->_shaderFilter[1]->RunFilterOGL(texVideoSourceID[1]);
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, this->_useClientStorage);
w1 = this->_shaderFilter[1]->GetDstWidth();
h1 = this->_shaderFilter[1]->GetDstHeight();
}
}
else
{
uint32_t *texData = this->_vf[1]->RunFilter();
texVideoSourceID[1] = this->_texCPUFilterDstID[1];
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texVideoSourceID[1]);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, this->_vf[1]->GetDstWidth(), this->_vf[1]->GetDstHeight(), GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, texData);
glFlush();
w1 = this->_vf[1]->GetDstWidth();
h1 = this->_vf[1]->GetDstHeight();
} }
} }
else
{
uint32_t *texData = this->_vf[displayID]->RunFilter();
inoutTexID = this->_texCPUFilterDstID[displayID];
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, inoutTexID);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, this->_vf[displayID]->GetDstWidth(), this->_vf[displayID]->GetDstHeight(), GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, texData);
glFlush();
inoutWidth = (GLsizei)this->_vf[displayID]->GetDstWidth();
inoutHeight = (GLsizei)this->_vf[displayID]->GetDstHeight();
}
}
void OGLDisplayLayer::ProcessOGL()
{
const NDSDisplayInfo &emuDisplayInfo = this->_output->GetEmuDisplayInfo();
const ClientDisplayMode mode = this->_output->GetViewProperties().mode;
// Output GLuint texVideoSourceID[2] = { (!emuDisplayInfo.didPerformCustomRender[NDSDisplayID_Main]) ? this->_texVideoInputDataNativeID[0] : this->_texVideoInputDataCustomID[0],
this->_texVideoOutputID[0] = texVideoSourceID[0]; (!emuDisplayInfo.didPerformCustomRender[NDSDisplayID_Touch]) ? this->_texVideoInputDataNativeID[1] : this->_texVideoInputDataCustomID[1] };
this->_texVideoOutputID[1] = texVideoSourceID[1]; GLsizei width[2] = { emuDisplayInfo.renderedWidth[NDSDisplayID_Main], emuDisplayInfo.renderedWidth[NDSDisplayID_Touch] };
GLsizei height[2] = { emuDisplayInfo.renderedHeight[NDSDisplayID_Main], emuDisplayInfo.renderedHeight[NDSDisplayID_Touch] };
// Run the video source filters and the pixel scalers
if ( !emuDisplayInfo.didPerformCustomRender[NDSDisplayID_Main] && emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Main] && (mode == ClientDisplayMode_Main || mode == ClientDisplayMode_Dual) )
{
this->_ProcessDisplayByID(NDSDisplayID_Main, width[NDSDisplayID_Main], height[NDSDisplayID_Main], texVideoSourceID[NDSDisplayID_Main]);
}
if ( !emuDisplayInfo.didPerformCustomRender[NDSDisplayID_Touch] && emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Touch] && (mode == ClientDisplayMode_Touch || mode == ClientDisplayMode_Dual) )
{
this->_ProcessDisplayByID(NDSDisplayID_Touch, width[NDSDisplayID_Touch], height[NDSDisplayID_Touch], texVideoSourceID[NDSDisplayID_Touch]);
}
// Set the final output texture IDs
this->_texVideoOutputID[NDSDisplayID_Main] = texVideoSourceID[NDSDisplayID_Main];
this->_texVideoOutputID[NDSDisplayID_Touch] = texVideoSourceID[NDSDisplayID_Touch];
// Update the texture coordinates // Update the texture coordinates
glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->_vboTexCoordID); glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->_vboTexCoordID);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, (4 * 8) * sizeof(GLfloat), NULL, GL_STREAM_DRAW_ARB); glBufferDataARB(GL_ARRAY_BUFFER_ARB, (4 * 8) * sizeof(GLfloat), NULL, GL_STREAM_DRAW_ARB);
float *texCoordPtr = (float *)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); float *texCoordPtr = (float *)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
this->_output->SetScreenTextureCoordinates(w0, h0, w1, h1, texCoordPtr); this->_output->SetScreenTextureCoordinates((float)width[NDSDisplayID_Main], (float)height[NDSDisplayID_Main], (float)width[NDSDisplayID_Touch], (float)height[NDSDisplayID_Touch], texCoordPtr);
glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
// OpenGL shader-based filters can modify the viewport, so it needs to be reset here.
glViewport(0, 0, this->_output->GetViewportWidth(), this->_output->GetViewportHeight()); glViewport(0, 0, this->_output->GetViewportWidth(), this->_output->GetViewportHeight());
} }
void OGLDisplayLayer::RenderOGL() void OGLDisplayLayer::RenderOGL()
{ {
const NDSDisplayInfo &emuDisplayInfo = this->_output->GetEmuDisplayInfo();
if (this->_output->GetContextInfo()->IsShaderSupported()) if (this->_output->GetContextInfo()->IsShaderSupported())
{ {
glUseProgram(this->_finalOutputProgram->GetProgramID()); glUseProgram(this->_finalOutputProgram->GetProgramID());
@ -7511,22 +7405,33 @@ void OGLDisplayLayer::RenderOGL()
switch (this->_output->GetViewProperties().mode) switch (this->_output->GetViewProperties().mode)
{ {
case ClientDisplayMode_Main: case ClientDisplayMode_Main:
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[0]); {
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[0]); if (emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Main])
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[0]); {
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[NDSDisplayID_Main]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[NDSDisplayID_Main]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[NDSDisplayID_Main]);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
break; break;
}
case ClientDisplayMode_Touch: case ClientDisplayMode_Touch:
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[1]); {
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[1]); if (emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Touch])
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[1]); {
glDrawArrays(GL_TRIANGLE_STRIP, 4, 4); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[NDSDisplayID_Touch]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[NDSDisplayID_Touch]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[NDSDisplayID_Touch]);
glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
}
break; break;
}
case ClientDisplayMode_Dual: case ClientDisplayMode_Dual:
{ {
const size_t majorDisplayTex = (this->_output->GetViewProperties().order == ClientDisplayOrder_MainFirst) ? 0 : 1; const NDSDisplayID majorDisplayID = (this->_output->GetViewProperties().order == ClientDisplayOrder_MainFirst) ? NDSDisplayID_Main : NDSDisplayID_Touch;
const size_t majorDisplayVtx = (this->_output->GetViewProperties().order == ClientDisplayOrder_MainFirst) ? 8 : 12; const size_t majorDisplayVtx = (this->_output->GetViewProperties().order == ClientDisplayOrder_MainFirst) ? 8 : 12;
switch (this->_output->GetViewProperties().layout) switch (this->_output->GetViewProperties().layout)
@ -7534,25 +7439,36 @@ void OGLDisplayLayer::RenderOGL()
case ClientDisplayLayout_Hybrid_2_1: case ClientDisplayLayout_Hybrid_2_1:
case ClientDisplayLayout_Hybrid_16_9: case ClientDisplayLayout_Hybrid_16_9:
case ClientDisplayLayout_Hybrid_16_10: case ClientDisplayLayout_Hybrid_16_10:
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[majorDisplayTex]); {
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[majorDisplayTex]); if (emuDisplayInfo.isDisplayEnabled[majorDisplayID])
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[majorDisplayTex]); {
glDrawArrays(GL_TRIANGLE_STRIP, majorDisplayVtx, 4); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[majorDisplayID]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[majorDisplayID]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[majorDisplayID]);
glDrawArrays(GL_TRIANGLE_STRIP, majorDisplayVtx, 4);
}
break; break;
}
default: default:
break; break;
} }
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[0]); if (emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Main])
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[0]); {
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[0]); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[NDSDisplayID_Main]);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[NDSDisplayID_Main]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[NDSDisplayID_Main]);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[1]); if (emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Touch])
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[1]); {
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[1]); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[NDSDisplayID_Touch]);
glDrawArrays(GL_TRIANGLE_STRIP, 4, 4); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[NDSDisplayID_Touch]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[NDSDisplayID_Touch]);
glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
}
} }
default: default:
@ -7567,8 +7483,9 @@ void OGLDisplayLayer::RenderOGL()
void OGLDisplayLayer::FinishOGL() void OGLDisplayLayer::FinishOGL()
{ {
const NDSDisplayInfo &emuDisplayInfo = this->_output->GetEmuDisplayInfo();
const bool isUsingCPUPixelScaler = (this->_output->GetPixelScaler() != VideoFilterTypeID_None) && !this->_output->WillFilterOnGPU(); const bool isUsingCPUPixelScaler = (this->_output->GetPixelScaler() != VideoFilterTypeID_None) && !this->_output->WillFilterOnGPU();
glFinishObjectAPPLE(GL_TEXTURE_RECTANGLE_ARB, (isUsingCPUPixelScaler) ? this->_texCPUFilterDstID[0] : ( (this->_isTexVideoInputDataNative[0]) ? this->_texVideoInputDataNativeID[0] : this->_texVideoInputDataCustomID[0]) ); glFinishObjectAPPLE(GL_TEXTURE_RECTANGLE_ARB, (isUsingCPUPixelScaler) ? this->_texCPUFilterDstID[0] : ( (!emuDisplayInfo.didPerformCustomRender[NDSDisplayID_Main]) ? this->_texVideoInputDataNativeID[0] : this->_texVideoInputDataCustomID[0]) );
glFinishObjectAPPLE(GL_TEXTURE_RECTANGLE_ARB, (isUsingCPUPixelScaler) ? this->_texCPUFilterDstID[1] : ( (this->_isTexVideoInputDataNative[1]) ? this->_texVideoInputDataNativeID[1] : this->_texVideoInputDataCustomID[1]) ); glFinishObjectAPPLE(GL_TEXTURE_RECTANGLE_ARB, (isUsingCPUPixelScaler) ? this->_texCPUFilterDstID[1] : ( (!emuDisplayInfo.didPerformCustomRender[NDSDisplayID_Touch]) ? this->_texVideoInputDataNativeID[1] : this->_texVideoInputDataCustomID[1]) );
} }

View File

@ -316,21 +316,16 @@ protected:
OGLFilter *_shaderFilter[2]; OGLFilter *_shaderFilter[2];
GLint _displayTexFilter[2]; GLint _displayTexFilter[2];
bool _isTexVideoInputDataNative[2];
GLuint _texVideoInputDataNativeID[2]; GLuint _texVideoInputDataNativeID[2];
GLuint _texVideoInputDataCustomID[2]; GLuint _texVideoInputDataCustomID[2];
GLuint _texVideoOutputID[2]; GLuint _texVideoOutputID[2];
GLfloat _texLoadedWidth[2];
GLfloat _texLoadedHeight[2];
GLenum _videoColorFormat; GLenum _videoColorFormat;
const void *_videoSrcBufferHead; const void *_videoSrcBufferHead;
const void *_videoSrcNativeBuffer[2]; const void *_videoSrcNativeBuffer[2];
const void *_videoSrcCustomBuffer[2]; const void *_videoSrcCustomBuffer[2];
size_t _videoSrcBufferSize; size_t _videoSrcBufferSize;
GLsizei _videoSrcCustomBufferWidth[2];
GLsizei _videoSrcCustomBufferHeight[2];
uint32_t *_vfMasterDstBuffer; uint32_t *_vfMasterDstBuffer;
size_t _vfMasterDstBufferSize; size_t _vfMasterDstBufferSize;
VideoFilter *_vf[2]; VideoFilter *_vf[2];
@ -357,6 +352,8 @@ protected:
void _UpdateRotationScaleOGL(); void _UpdateRotationScaleOGL();
void _UpdateVerticesOGL(); void _UpdateVerticesOGL();
void _ProcessDisplayByID(const NDSDisplayID displayID, GLsizei &inoutWidth, GLsizei &inoutHeight, GLuint &inoutTexID);
public: public:
OGLDisplayLayer() {}; OGLDisplayLayer() {};
OGLDisplayLayer(OGLVideoOutput *oglVO); OGLDisplayLayer(OGLVideoOutput *oglVO);
@ -377,7 +374,9 @@ public:
OutputFilterTypeID SetOutputFilterOGL(const OutputFilterTypeID filterID); OutputFilterTypeID SetOutputFilterOGL(const OutputFilterTypeID filterID);
bool SetGPUPixelScalerOGL(const VideoFilterTypeID filterID); bool SetGPUPixelScalerOGL(const VideoFilterTypeID filterID);
void SetCPUPixelScalerOGL(const VideoFilterTypeID filterID); void SetCPUPixelScalerOGL(const VideoFilterTypeID filterID);
void LoadFrameOGL(bool isMainSizeNative, bool isTouchSizeNative);
void LoadNativeDisplayByID_OGL(const NDSDisplayID displayID);
void LoadCustomDisplayByID_OGL(const NDSDisplayID displayID);
virtual void UpdateViewportOGL(); virtual void UpdateViewportOGL();
virtual void ProcessOGL(); virtual void ProcessOGL();
@ -402,6 +401,9 @@ protected:
virtual void _UpdateClientSize(); virtual void _UpdateClientSize();
virtual void _UpdateViewScale(); virtual void _UpdateViewScale();
virtual void _LoadNativeDisplayByID(const NDSDisplayID displayID);
virtual void _LoadCustomDisplayByID(const NDSDisplayID displayID);
public: public:
OGLVideoOutput(); OGLVideoOutput();
~OGLVideoOutput(); ~OGLVideoOutput();
@ -430,8 +432,7 @@ public:
const void *customBuffer0, const size_t customWidth0, const size_t customHeight0, const void *customBuffer0, const size_t customWidth0, const size_t customHeight0,
const void *customBuffer1, const size_t customWidth1, const size_t customHeight1); const void *customBuffer1, const size_t customWidth1, const size_t customHeight1);
virtual void FrameLoadGPU(bool isMainSizeNative, bool isTouchSizeNative); virtual void ProcessDisplays();
virtual void FrameProcessGPU();
virtual void FrameProcessHUD(); virtual void FrameProcessHUD();
virtual void FrameRender(); virtual void FrameRender();
virtual void FrameFinish(); virtual void FrameFinish();

View File

@ -1070,7 +1070,7 @@
pthread_rwlock_unlock(self.rwlockProducer); pthread_rwlock_unlock(self.rwlockProducer);
_cdv->HandleGPUFrameEndEvent(isMainSizeNative, isTouchSizeNative); _cdv->HandleGPUFrameEndEvent(dispInfo);
} }
- (void) handleReloadReprocessRedraw - (void) handleReloadReprocessRedraw

View File

@ -1618,21 +1618,39 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
inputManager = nil; inputManager = nil;
cdsVideoOutput = nil; cdsVideoOutput = nil;
localLayer = nil;
/*#if defined(MAC_OS_X_VERSION_10_11) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_11) localOGLContext = nil;
/*
#if defined(MAC_OS_X_VERSION_10_11) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_11)
if (IsOSXVersionSupported(10, 11, 0)) if (IsOSXVersionSupported(10, 11, 0))
{ {
localLayer = [[DisplayViewMetalLayer alloc] init]; localLayer = [[DisplayViewMetalLayer alloc] init];
if ([(DisplayViewMetalLayer *)localLayer device] == nil)
{
[localLayer release];
localLayer = nil;
}
else
{
[self setLayer:localLayer];
[self setWantsLayer:YES];
if ([self respondsToSelector:@selector(setLayerContentsRedrawPolicy:)])
{
[self setLayerContentsRedrawPolicy:NSViewLayerContentsRedrawNever];
}
}
} }
else #endif
#endif*/ */
if (localLayer == nil)
{ {
localLayer = [[DisplayViewOpenGLLayer alloc] init]; localLayer = [[DisplayViewOpenGLLayer alloc] init];
MacOGLDisplayView *macOGLCDV = (MacOGLDisplayView *)[(id<DisplayViewCALayer>)localLayer clientDisplay3DView]; MacOGLDisplayView *macOGLCDV = (MacOGLDisplayView *)[(id<DisplayViewCALayer>)localLayer clientDisplay3DView];
if (IsOSXVersionSupported(10, 8, 0)) if (IsOSXVersionSupported(10, 8, 0))
{ {
localOGLContext = nil;
macOGLCDV->SetRenderToCALayer(true); macOGLCDV->SetRenderToCALayer(true);
[self setLayer:localLayer]; [self setLayer:localLayer];

View File

@ -87,7 +87,7 @@ public:
virtual void SetHUDShowRTC(const bool visibleState); virtual void SetHUDShowRTC(const bool visibleState);
virtual void FrameFinish(); virtual void FrameFinish();
virtual void HandleGPUFrameEndEvent(const bool isMainSizeNative, const bool isTouchSizeNative); virtual void HandleGPUFrameEndEvent(const NDSDisplayInfo &ndsDisplayInfo);
virtual void HandleEmulatorFrameEndEvent(const NDSFrameInfo &frameInfo); virtual void HandleEmulatorFrameEndEvent(const NDSFrameInfo &frameInfo);
virtual void UpdateView(); virtual void UpdateView();

View File

@ -348,12 +348,14 @@ void MacOGLDisplayView::FrameFinish()
CGLUnlockContext(this->_context); CGLUnlockContext(this->_context);
} }
void MacOGLDisplayView::HandleGPUFrameEndEvent(const bool isMainSizeNative, const bool isTouchSizeNative) void MacOGLDisplayView::HandleGPUFrameEndEvent(const NDSDisplayInfo &ndsDisplayInfo)
{ {
this->OGLVideoOutput::HandleGPUFrameEndEvent(ndsDisplayInfo);
CGLLockContext(this->_context); CGLLockContext(this->_context);
CGLSetCurrentContext(this->_context); CGLSetCurrentContext(this->_context);
this->FrameLoadGPU(isMainSizeNative, isTouchSizeNative); this->LoadDisplays();
this->FrameProcessGPU(); this->ProcessDisplays();
CGLUnlockContext(this->_context); CGLUnlockContext(this->_context);
} }