Cocoa Port: Another round of refactoring for ClientDisplayView.

- Fetching and loading of GPU frame data is now performed as two
separate operations.
- Display windows no longer draw concurrently on backgrounds threads;
instead they are updated synchronously.
- Associate the CALayer after the .xib completely loads the NSView for
better compatibility.
- MacOGLDisplayView now creates an NSOpenGLContext instead of a
CGLContextObj, bringing back compatibility with macOS 10.5 Leopard.
- Fix building with the Xcode 3 project.
This commit is contained in:
rogerman 2017-01-24 19:08:44 -08:00
parent 3b0920d7f0
commit b9a9b8e7b2
11 changed files with 3302 additions and 3232 deletions

View File

@ -481,6 +481,16 @@ void ClientDisplayView::ClearHUDNeedsUpdate()
}
// NDS GPU Interface
void ClientDisplayView::_FetchNativeDisplayByID(const NDSDisplayID displayID)
{
// Do nothing. This is implementation dependent.
}
void ClientDisplayView::_FetchCustomDisplayByID(const NDSDisplayID displayID)
{
// Do nothing. This is implementation dependent.
}
void ClientDisplayView::_LoadNativeDisplayByID(const NDSDisplayID displayID)
{
// Do nothing. This is implementation dependent.
@ -491,6 +501,36 @@ void ClientDisplayView::_LoadCustomDisplayByID(const NDSDisplayID displayID)
// Do nothing. This is implementation dependent.
}
void ClientDisplayView::FetchDisplays()
{
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->_FetchNativeDisplayByID(NDSDisplayID_Main);
}
else
{
this->_FetchCustomDisplayByID(NDSDisplayID_Main);
}
}
if (loadTouchScreen)
{
if (!this->_emuDisplayInfo.didPerformCustomRender[NDSDisplayID_Touch])
{
this->_FetchNativeDisplayByID(NDSDisplayID_Touch);
}
else
{
this->_FetchCustomDisplayByID(NDSDisplayID_Touch);
}
}
}
void ClientDisplayView::LoadDisplays()
{
const bool loadMainScreen = this->_emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Main] && ((this->_renderProperty.mode == ClientDisplayMode_Main) || (this->_renderProperty.mode == ClientDisplayMode_Dual));
@ -536,7 +576,7 @@ const NDSDisplayInfo& ClientDisplayView::GetEmuDisplayInfo() const
return this->_emuDisplayInfo;
}
void ClientDisplayView::HandleGPUFrameEndEvent(const NDSDisplayInfo &ndsDisplayInfo)
void ClientDisplayView::SetEmuDisplayInfo(const NDSDisplayInfo &ndsDisplayInfo)
{
this->_emuDisplayInfo = ndsDisplayInfo;
}

View File

@ -27,6 +27,7 @@
#include FT_FREETYPE_H
#define HUD_MAX_CHARACTERS 2048
#define HUD_VERTEX_ATTRIBUTE_BUFFER_SIZE (sizeof(float) * HUD_MAX_CHARACTERS * (2 * 4))
#define HUD_TEXTBOX_BASEGLYPHSIZE 64.0
#define HUD_TEXTBOX_BASE_SCALE (1.0/3.0)
#define HUD_TEXTBOX_MIN_SCALE 0.70
@ -150,6 +151,8 @@ protected:
virtual void _UpdateClientSize();
virtual void _UpdateViewScale();
virtual void _FetchNativeDisplayByID(const NDSDisplayID displayID);
virtual void _FetchCustomDisplayByID(const NDSDisplayID displayID);
virtual void _LoadNativeDisplayByID(const NDSDisplayID displayID);
virtual void _LoadCustomDisplayByID(const NDSDisplayID displayID);
@ -215,6 +218,7 @@ public:
void ClearHUDNeedsUpdate();
// Client view interface
virtual void FetchDisplays();
virtual void LoadDisplays();
virtual void ProcessDisplays();
virtual void UpdateView();
@ -222,7 +226,7 @@ public:
// Emulator interface
const NDSDisplayInfo& GetEmuDisplayInfo() const;
virtual void HandleGPUFrameEndEvent(const NDSDisplayInfo &ndsDisplayInfo);
void SetEmuDisplayInfo(const NDSDisplayInfo &ndsDisplayInfo);
virtual void HandleEmulatorFrameEndEvent(const NDSFrameInfo &frameInfo);
// Touch screen input handling

View File

@ -5597,7 +5597,7 @@
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = "-I./../../";
PRODUCT_NAME = "DeSmuME (Debug)";
SDKROOT = macosx;
SDKROOT = "";
SKIP_INSTALL = YES;
STRIP_INSTALLED_PRODUCT = NO;
};
@ -5651,7 +5651,7 @@
MACOSX_DEPLOYMENT_TARGET = 10.5;
OTHER_CFLAGS = "-I./../../";
PRODUCT_NAME = DeSmuME;
SDKROOT = macosx;
SDKROOT = "";
STRIP_INSTALLED_PRODUCT = NO;
VALIDATE_PRODUCT = YES;
};

View File

@ -4880,6 +4880,16 @@ void OGLVideoOutput::_UpdateViewport()
}
}
void OGLVideoOutput::_FetchNativeDisplayByID(const NDSDisplayID displayID)
{
this->GetDisplayLayer()->CopyNativeDisplayByID_OGL(displayID);
}
void OGLVideoOutput::_FetchCustomDisplayByID(const NDSDisplayID displayID)
{
this->GetDisplayLayer()->CopyCustomDisplayByID_OGL(displayID);
}
void OGLVideoOutput::_LoadNativeDisplayByID(const NDSDisplayID displayID)
{
this->GetDisplayLayer()->LoadNativeDisplayByID_OGL(displayID);
@ -6137,10 +6147,6 @@ OGLHUDLayer::OGLHUDLayer(OGLVideoOutput *oglVO)
_needUpdateViewport = true;
_output = oglVO;
_glyphInfo = NULL;
_glyphSize = 0.0f;
_glyphTileSize = 0.0f;
if (_output->GetContextInfo()->IsShaderSupported())
{
_program = new OGLShaderProgram;
@ -6236,10 +6242,6 @@ void OGLHUDLayer::CopyHUDFont(const FT_Face &fontFace, const size_t glyphSize, c
{
FT_Error error = FT_Err_Ok;
this->_glyphInfo = glyphInfo;
this->_glyphSize = (GLfloat)glyphSize;
this->_glyphTileSize = (GLfloat)glyphTileSize;
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, this->_texCharMap);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@ -6548,7 +6550,7 @@ OGLDisplayLayer::OGLDisplayLayer(OGLVideoOutput *oglVO)
shaderFilterProgram->SetVertexAndFragmentShaderOGL(Sample1x1_VertShader_110, PassthroughFragShader_110, _useShader150);
}
UploadHQnxLUTs();
_UploadHQnxLUTs();
}
else
{
@ -6600,7 +6602,7 @@ OGLDisplayLayer::~OGLDisplayLayer()
_vfMasterDstBufferSize = 0;
}
void OGLDisplayLayer::UploadHQnxLUTs()
void OGLDisplayLayer::_UploadHQnxLUTs()
{
InitHQnxLUTs();
@ -6642,7 +6644,7 @@ void OGLDisplayLayer::UploadHQnxLUTs()
glActiveTexture(GL_TEXTURE0);
}
void OGLDisplayLayer::DetermineTextureStorageHints(GLint &videoSrcTexStorageHint, GLint &cpuFilterTexStorageHint)
void OGLDisplayLayer::_DetermineTextureStorageHints(GLint &videoSrcTexStorageHint, GLint &cpuFilterTexStorageHint)
{
const bool isUsingCPUPixelScaler = (this->_output->GetPixelScaler() != VideoFilterTypeID_None) && !this->_output->WillFilterOnGPU();
videoSrcTexStorageHint = GL_STORAGE_PRIVATE_APPLE;
@ -6691,12 +6693,12 @@ void OGLDisplayLayer::SetVideoBuffers(const uint32_t colorFormat,
this->_videoColorFormat = glColorFormat;
this->_videoSrcBufferHead = videoBufferHead;
this->_videoSrcBufferSize = (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_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->_videoSrcNativeBuffer[0] = (void *)nativeBuffer0;
this->_videoSrcNativeBuffer[1] = (void *)nativeBuffer1;
this->_videoSrcCustomBuffer[0] = (void *)customBuffer0;
this->_videoSrcCustomBuffer[1] = (void *)customBuffer1;
this->DetermineTextureStorageHints(videoSrcTexStorageHint, cpuFilterTexStorageHint);
this->_DetermineTextureStorageHints(videoSrcTexStorageHint, cpuFilterTexStorageHint);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texCPUFilterDstID[0]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_STORAGE_HINT_APPLE, cpuFilterTexStorageHint);
@ -6737,7 +6739,7 @@ void OGLDisplayLayer::SetFiltersPreferGPUOGL()
{
GLint videoSrcTexStorageHint = GL_STORAGE_PRIVATE_APPLE;
GLint cpuFilterTexStorageHint = GL_STORAGE_PRIVATE_APPLE;
this->DetermineTextureStorageHints(videoSrcTexStorageHint, cpuFilterTexStorageHint);
this->_DetermineTextureStorageHints(videoSrcTexStorageHint, cpuFilterTexStorageHint);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texCPUFilterDstID[0]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_STORAGE_HINT_APPLE, cpuFilterTexStorageHint);
@ -6791,7 +6793,7 @@ void OGLDisplayLayer::_UpdateVerticesOGL()
this->_needUpdateVertices = false;
}
void OGLDisplayLayer::ResizeCPUPixelScalerOGL(const size_t srcWidthMain, const size_t srcHeightMain, const size_t srcWidthTouch, const size_t srcHeightTouch, const size_t scaleMultiply, const size_t scaleDivide)
void OGLDisplayLayer::_ResizeCPUPixelScalerOGL(const size_t srcWidthMain, const size_t srcHeightMain, const size_t srcWidthTouch, const size_t srcHeightTouch, const size_t scaleMultiply, const size_t scaleDivide)
{
this->FinishOGL();
@ -6808,7 +6810,7 @@ void OGLDisplayLayer::ResizeCPUPixelScalerOGL(const size_t srcWidthMain, const s
GLint videoSrcTexStorageHint = GL_STORAGE_PRIVATE_APPLE;
GLint cpuFilterTexStorageHint = GL_STORAGE_PRIVATE_APPLE;
this->DetermineTextureStorageHints(videoSrcTexStorageHint, cpuFilterTexStorageHint);
this->_DetermineTextureStorageHints(videoSrcTexStorageHint, cpuFilterTexStorageHint);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texCPUFilterDstID[0]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_STORAGE_HINT_APPLE, cpuFilterTexStorageHint);
@ -7198,13 +7200,42 @@ void OGLDisplayLayer::SetCPUPixelScalerOGL(const VideoFilterTypeID filterID)
if (oldDstBufferWidth != newDstBufferWidth || oldDstBufferHeight != newDstBufferHeight)
{
this->ResizeCPUPixelScalerOGL(this->_vf[0]->GetSrcWidth(), this->_vf[0]->GetSrcHeight(), this->_vf[1]->GetSrcWidth(), this->_vf[1]->GetSrcHeight(), newFilterAttr.scaleMultiply, newFilterAttr.scaleDivide);
this->_ResizeCPUPixelScalerOGL(this->_vf[0]->GetSrcWidth(), this->_vf[0]->GetSrcHeight(), this->_vf[1]->GetSrcWidth(), this->_vf[1]->GetSrcHeight(), newFilterAttr.scaleMultiply, newFilterAttr.scaleDivide);
}
this->_vf[0]->ChangeFilterByID(filterID);
this->_vf[1]->ChangeFilterByID(filterID);
}
void OGLDisplayLayer::CopyNativeDisplayByID_OGL(const NDSDisplayID displayID)
{
const NDSDisplayInfo &emuDisplayInfo = this->_output->GetEmuDisplayInfo();
const bool useDeposterize = this->_output->GetSourceDeposterize();
const bool isUsingCPUPixelScaler = (this->_output->GetPixelScaler() != VideoFilterTypeID_None) && !this->_output->WillFilterOnGPU();
if (!isUsingCPUPixelScaler || useDeposterize)
{
memcpy(this->_videoSrcNativeBuffer[displayID], emuDisplayInfo.nativeBuffer[displayID], GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * emuDisplayInfo.pixelBytes);
}
else
{
if (this->_videoColorFormat == GL_UNSIGNED_SHORT_1_5_5_5_REV)
{
ColorspaceConvertBuffer555To8888Opaque<true, false>((const uint16_t *)emuDisplayInfo.nativeBuffer[displayID], this->_vf[displayID]->GetSrcBufferPtr(), GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT);
}
else
{
ColorspaceConvertBuffer888XTo8888Opaque<true, false>((const uint32_t *)emuDisplayInfo.nativeBuffer[displayID], this->_vf[displayID]->GetSrcBufferPtr(), GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT);
}
}
}
void OGLDisplayLayer::CopyCustomDisplayByID_OGL(const NDSDisplayID displayID)
{
const NDSDisplayInfo &emuDisplayInfo = this->_output->GetEmuDisplayInfo();
memcpy(this->_videoSrcCustomBuffer[displayID], emuDisplayInfo.customBuffer[displayID], emuDisplayInfo.customWidth * emuDisplayInfo.customHeight * emuDisplayInfo.pixelBytes);
}
void OGLDisplayLayer::LoadNativeDisplayByID_OGL(const NDSDisplayID displayID)
{
const bool useDeposterize = this->_output->GetSourceDeposterize();
@ -7217,17 +7248,6 @@ void OGLDisplayLayer::LoadNativeDisplayByID_OGL(const NDSDisplayID displayID)
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[displayID], this->_vf[displayID]->GetSrcBufferPtr(), GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT);
}
else
{
ColorspaceConvertBuffer888XTo8888Opaque<true, false>((const uint32_t *)this->_videoSrcNativeBuffer[displayID], this->_vf[displayID]->GetSrcBufferPtr(), GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT);
}
}
}
void OGLDisplayLayer::LoadCustomDisplayByID_OGL(const NDSDisplayID displayID)
@ -7318,7 +7338,9 @@ void OGLDisplayLayer::ProcessOGL()
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);
this->_output->SetScreenTextureCoordinates((float)width[NDSDisplayID_Main], (float)height[NDSDisplayID_Main], (float)width[NDSDisplayID_Touch], (float)height[NDSDisplayID_Touch], 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);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);

View File

@ -34,7 +34,6 @@
#include "ClientDisplayView.h"
#define HUD_VERTEX_ATTRIBUTE_BUFFER_SIZE (sizeof(GLfloat) * HUD_MAX_CHARACTERS * (2 * 4))
class OGLVideoOutput;
struct NDSFrameInfo;
@ -286,11 +285,6 @@ protected:
GLuint _vboElementID;
GLuint _texCharMap;
GlyphInfo *_glyphInfo;
GLfloat _glyphSize;
GLfloat _glyphTileSize;
void _SetShowInfoItemOGL(bool &infoItemFlag, const bool visibleState);
void _UpdateVerticesOGL();
public:
@ -320,8 +314,8 @@ protected:
GLenum _videoColorFormat;
const void *_videoSrcBufferHead;
const void *_videoSrcNativeBuffer[2];
const void *_videoSrcCustomBuffer[2];
void *_videoSrcNativeBuffer[2];
void *_videoSrcCustomBuffer[2];
size_t _videoSrcBufferSize;
uint32_t *_vfMasterDstBuffer;
@ -342,10 +336,10 @@ protected:
GLint _uniformFinalOutputScalar;
GLint _uniformFinalOutputViewSize;
void UploadHQnxLUTs();
void DetermineTextureStorageHints(GLint &videoSrcTexStorageHint, GLint &cpuFilterTexStorageHint);
void _UploadHQnxLUTs();
void _DetermineTextureStorageHints(GLint &videoSrcTexStorageHint, GLint &cpuFilterTexStorageHint);
void ResizeCPUPixelScalerOGL(const size_t srcWidthMain, const size_t srcHeightMain, const size_t srcWidthTouch, const size_t srcHeightTouch, const size_t scaleMultiply, const size_t scaleDivide);
void _ResizeCPUPixelScalerOGL(const size_t srcWidthMain, const size_t srcHeightMain, const size_t srcWidthTouch, const size_t srcHeightTouch, const size_t scaleMultiply, const size_t scaleDivide);
void _UpdateRotationScaleOGL();
void _UpdateVerticesOGL();
@ -373,6 +367,8 @@ public:
bool SetGPUPixelScalerOGL(const VideoFilterTypeID filterID);
void SetCPUPixelScalerOGL(const VideoFilterTypeID filterID);
void CopyNativeDisplayByID_OGL(const NDSDisplayID displayID);
void CopyCustomDisplayByID_OGL(const NDSDisplayID displayID);
void LoadNativeDisplayByID_OGL(const NDSDisplayID displayID);
void LoadCustomDisplayByID_OGL(const NDSDisplayID displayID);
@ -398,6 +394,8 @@ protected:
virtual void _UpdateClientSize();
virtual void _UpdateViewScale();
virtual void _FetchNativeDisplayByID(const NDSDisplayID displayID);
virtual void _FetchCustomDisplayByID(const NDSDisplayID displayID);
virtual void _LoadNativeDisplayByID(const NDSDisplayID displayID);
virtual void _LoadCustomDisplayByID(const NDSDisplayID displayID);

View File

@ -1043,34 +1043,13 @@
pthread_rwlock_rdlock(self.rwlockProducer);
const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo();
const bool isMainSizeNative = !dispInfo.didPerformCustomRender[NDSDisplayID_Main];
const bool isTouchSizeNative = !dispInfo.didPerformCustomRender[NDSDisplayID_Touch];
if (isMainSizeNative && isTouchSizeNative)
{
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 * dispInfo.pixelBytes);
}
else if (isTouchSizeNative)
{
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 * dispInfo.pixelBytes);
memcpy(_customBuffer[NDSDisplayID_Touch], dispInfo.customBuffer[NDSDisplayID_Touch], dispInfo.customWidth * dispInfo.customHeight * dispInfo.pixelBytes);
}
}
_cdv->SetEmuDisplayInfo(dispInfo);
_cdv->FetchDisplays();
pthread_rwlock_unlock(self.rwlockProducer);
_cdv->HandleGPUFrameEndEvent(dispInfo);
_cdv->LoadDisplays();
_cdv->ProcessDisplays();
}
- (void) handleReloadReprocessRedraw

View File

@ -60,6 +60,8 @@ class OGLVideoOutput;
@property (assign) NSInteger outputFilter;
@property (assign) NSInteger pixelScaler;
- (void) reassignLocalCALayer;
- (BOOL) handleKeyPress:(NSEvent *)theEvent keyPressed:(BOOL)keyPressed;
- (BOOL) handleMouseButton:(NSEvent *)theEvent buttonPressed:(BOOL)buttonPressed;
- (void) requestScreenshot:(NSURL *)fileURL fileType:(NSBitmapImageFileType)fileType;

View File

@ -27,11 +27,13 @@
#import "cocoa_util.h"
#include "MacOGLDisplayView.h"
/*
#if defined(MAC_OS_X_VERSION_10_11) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_11)
//#define ENABLE_APPLE_METAL
#if defined(MAC_OS_X_VERSION_10_11) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_11) && defined(ENABLE_APPLE_METAL)
#include "MacMetalDisplayView.h"
#endif
*/
#include <Carbon/Carbon.h>
#if defined(__ppc__) || defined(__ppc64__)
@ -652,9 +654,9 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
defer:NO
screen:targetScreen] autorelease];
[newFullScreenWindow setHasShadow:NO];
[newFullScreenWindow setInitialFirstResponder:view];
[view setFrame:screenRect];
[[newFullScreenWindow contentView] addSubview:view];
[newFullScreenWindow setInitialFirstResponder:view];
[newFullScreenWindow setDelegate:self];
// If the target screen is the main screen (index 0), then autohide the menu bar and dock.
@ -690,8 +692,10 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
NSRect viewFrame = [[masterWindow contentView] frame];
viewFrame.size.height -= _statusBarHeight;
viewFrame.origin.y = _statusBarHeight;
[view setFrame:viewFrame];
[[masterWindow contentView] addSubview:view];
[masterWindow setInitialFirstResponder:view];
[masterWindow makeKeyAndOrderFront:self];
[masterWindow display];
}
@ -1268,6 +1272,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
[[emuControl windowList] addObject:self];
[emuControl updateAllWindowTitles];
[view reassignLocalCALayer];
[view setInputManager:[emuControl inputManager]];
// Set up the scaling factor if this is a Retina window
@ -1620,8 +1625,8 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
cdsVideoOutput = nil;
localLayer = nil;
localOGLContext = nil;
/*
#if defined(MAC_OS_X_VERSION_10_11) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_11)
#if defined(MAC_OS_X_VERSION_10_11) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_11) && defined(ENABLE_APPLE_METAL)
if (IsOSXVersionSupported(10, 11, 0))
{
localLayer = [[DisplayViewMetalLayer alloc] init];
@ -1631,37 +1636,20 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
[localLayer release];
localLayer = nil;
}
else
{
[self setLayer:localLayer];
[self setWantsLayer:YES];
if ([self respondsToSelector:@selector(setLayerContentsRedrawPolicy:)])
{
[self setLayerContentsRedrawPolicy:NSViewLayerContentsRedrawNever];
}
}
}
#endif
*/
if (localLayer == nil)
{
localLayer = [[DisplayViewOpenGLLayer alloc] init];
MacOGLDisplayView *macOGLCDV = (MacOGLDisplayView *)[(id<DisplayViewCALayer>)localLayer clientDisplay3DView];
// For macOS 10.8 Mountain Lion and later, we can use the CAOpenGLLayer directly. But for
// earlier versions of macOS, using the CALayer directly will cause too many strange issues,
// so we'll just keep using the old-school NSOpenGLContext for these older macOS versions.
if (IsOSXVersionSupported(10, 8, 0))
{
macOGLCDV->SetRenderToCALayer(true);
[self setLayer:localLayer];
[self setWantsLayer:YES];
#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
if ([self respondsToSelector:@selector(setLayerContentsRedrawPolicy:)])
{
[self setLayerContentsRedrawPolicy:NSViewLayerContentsRedrawNever];
}
#endif
}
else
{
@ -1671,7 +1659,8 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
[self setWantsBestResolutionOpenGLSurface:YES];
}
#endif
localOGLContext = [[NSOpenGLContext alloc] initWithCGLContextObj:macOGLCDV->GetContext()];
localOGLContext = macOGLCDV->GetNSContext();
[localOGLContext retain];
macOGLCDV->SetRenderToCALayer(false);
}
}
@ -1828,6 +1817,29 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
return [[self cdsVideoOutput] pixelScaler];
}
#pragma mark Class Methods
- (void) reassignLocalCALayer
{
if (localOGLContext != nil)
{
// If localOGLContext isn't nil, then we will not assign the local layer
// directly to the view, since the OpenGL context will already be what
// is assigned.
return;
}
[localLayer setNeedsDisplay];
[self setLayer:localLayer];
[self setWantsLayer:YES];
#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
if ([self respondsToSelector:@selector(setLayerContentsRedrawPolicy:)])
{
[self setLayerContentsRedrawPolicy:NSViewLayerContentsRedrawNever];
}
#endif
}
#pragma mark InputHIDManagerTarget Protocol
- (BOOL) handleHIDQueue:(IOHIDQueueRef)hidQueue hidManager:(InputHIDManager *)hidManager
{
@ -1959,7 +1971,6 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
return NO;
}
#if defined(MAC_OS_X_VERSION_10_8) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8)
- (BOOL)wantsUpdateLayer
{
return YES;
@ -1970,7 +1981,6 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
ClientDisplay3DView *cdv = [(id<DisplayViewCALayer>)localLayer clientDisplay3DView];
cdv->UpdateView();
}
#endif
- (void)drawRect:(NSRect)dirtyRect
{
@ -1985,11 +1995,6 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
if (rect.size.width != oldFrame.size.width || rect.size.height != oldFrame.size.height)
{
if (localOGLContext != nil)
{
[localOGLContext update];
}
DisplayWindowController *windowController = (DisplayWindowController *)[[self window] delegate];
ClientDisplayViewProperties &props = [windowController localViewProperties];
NSRect newViewportRect = rect;
@ -2010,6 +2015,21 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
props.clientHeight = newViewportRect.size.height;
props.viewScale = ClientDisplayView::GetMaxScalarWithinBounds(checkWidth, checkHeight, props.clientWidth, props.clientHeight);
if (localOGLContext != nil)
{
[localOGLContext update];
}
else if ([localLayer isKindOfClass:[CAOpenGLLayer class]])
{
[localLayer setBounds:CGRectMake(0.0f, 0.0f, props.clientWidth, props.clientHeight)];
}
#if defined(MAC_OS_X_VERSION_10_11) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_11) && defined(ENABLE_APPLE_METAL)
else if ([[self layer] isKindOfClass:[CAMetalLayer class]])
{
[(CAMetalLayer *)localLayer setDrawableSize:CGSizeMake(props.clientWidth, props.clientHeight)];
}
#endif
[[self cdsVideoOutput] commitViewProperties:props];
}
}

View File

@ -42,18 +42,20 @@ class MacOGLDisplayView;
class MacOGLDisplayView : public OGLVideoOutput, public DisplayViewCALayerInterface
{
protected:
CGLPixelFormatObj _pixelFormat;
NSOpenGLContext *_nsContext;
NSOpenGLPixelFormat *_nsPixelFormat;
CGLContextObj _context;
CGLPixelFormatObj _pixelFormat;
bool _willRenderToCALayer;
void _FrameRenderAndFlush();
public:
void operator delete(void *ptr);
MacOGLDisplayView();
virtual void Init();
NSOpenGLPixelFormat* GetNSPixelFormat() const;
NSOpenGLContext* GetNSContext() const;
CGLPixelFormatObj GetPixelFormat() const;
CGLContextObj GetContext() const;
@ -78,11 +80,10 @@ public:
virtual void SetPixelScaler(const VideoFilterTypeID filterID);
// Client view interface
virtual void LoadDisplays();
virtual void ProcessDisplays();
virtual void UpdateView();
virtual void FrameFinish();
// Emulator interface
virtual void HandleGPUFrameEndEvent(const NDSDisplayInfo &ndsDisplayInfo);
};
#endif // _MAC_OGLDISPLAYOUTPUT_H_

View File

@ -32,6 +32,7 @@
_cdv->SetFrontendLayer(self);
_cdv->Init();
[self setBounds:CGRectMake(0.0f, 0.0f, (float)GPU_FRAMEBUFFER_NATIVE_WIDTH, (float)GPU_FRAMEBUFFER_NATIVE_HEIGHT)];
[self setAsynchronous:NO];
[self setOpaque:YES];
@ -72,15 +73,17 @@
- (void)drawInCGLContext:(CGLContextObj)glContext pixelFormat:(CGLPixelFormatObj)pixelFormat forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
{
CGLSetCurrentContext(glContext);
CGLLockContext(glContext);
_cdv->RenderViewOGL();
[super drawInCGLContext:glContext pixelFormat:pixelFormat forLayerTime:timeInterval displayTime:timeStamp];
CGLUnlockContext(glContext);
}
@end
void MacOGLDisplayView::operator delete(void *ptr)
{
CGLPixelFormatObj pixelFormat = ((MacOGLDisplayView *)ptr)->GetPixelFormat();
CGLContextObj context = ((MacOGLDisplayView *)ptr)->GetContext();
OGLContextInfo *contextInfo = ((MacOGLDisplayView *)ptr)->GetContextInfo();
@ -92,23 +95,28 @@ void MacOGLDisplayView::operator delete(void *ptr)
CGLSetCurrentContext(prevContext);
delete contextInfo;
CGLReleaseContext(context);
CGLReleasePixelFormat(pixelFormat);
[((MacOGLDisplayView *)ptr)->GetNSContext() release];
[((MacOGLDisplayView *)ptr)->GetNSPixelFormat() release];
}
}
MacOGLDisplayView::MacOGLDisplayView()
{
// Initialize the OpenGL context
// Initialize the OpenGL context.
//
// We create an NSOpenGLContext and extract the CGLContextObj from it because
// [NSOpenGLContext CGLContextObj] is available on macOS 10.5 Leopard, but
// [NSOpenGLContext initWithCGLContextObj:] is only available on macOS 10.6
// Snow Leopard.
bool useContext_3_2 = false;
CGLPixelFormatAttribute attributes[] = {
kCGLPFAColorSize, (CGLPixelFormatAttribute)24,
kCGLPFAAlphaSize, (CGLPixelFormatAttribute)8,
kCGLPFADepthSize, (CGLPixelFormatAttribute)0,
kCGLPFAStencilSize, (CGLPixelFormatAttribute)0,
kCGLPFADoubleBuffer,
(CGLPixelFormatAttribute)0, (CGLPixelFormatAttribute)0,
(CGLPixelFormatAttribute)0
NSOpenGLPixelFormatAttribute attributes[] = {
NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute)24,
NSOpenGLPFAAlphaSize, (NSOpenGLPixelFormatAttribute)8,
NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)0,
NSOpenGLPFAStencilSize, (NSOpenGLPixelFormatAttribute)0,
NSOpenGLPFADoubleBuffer,
(NSOpenGLPixelFormatAttribute)0, (NSOpenGLPixelFormatAttribute)0,
(NSOpenGLPixelFormatAttribute)0
};
#ifdef _OGLDISPLAYOUTPUT_3_2_H_
@ -117,25 +125,25 @@ MacOGLDisplayView::MacOGLDisplayView()
useContext_3_2 = IsOSXVersionSupported(10, 7, 0);
if (useContext_3_2)
{
attributes[9] = kCGLPFAOpenGLProfile;
attributes[10] = (CGLPixelFormatAttribute)kCGLOGLPVersion_3_2_Core;
attributes[9] = NSOpenGLPFAOpenGLProfile;
attributes[10] = (NSOpenGLPixelFormatAttribute)NSOpenGLProfileVersion3_2Core;
}
#endif
GLint virtualScreenCount = 0;
CGLChoosePixelFormat(attributes, &_pixelFormat, &virtualScreenCount);
if (_pixelFormat == NULL)
_nsPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
if (_nsPixelFormat == nil)
{
// If we can't get a 3.2 Core Profile context, then switch to using a
// legacy context instead.
useContext_3_2 = false;
attributes[9] = (CGLPixelFormatAttribute)0;
attributes[10] = (CGLPixelFormatAttribute)0;
CGLChoosePixelFormat(attributes, &_pixelFormat, &virtualScreenCount);
attributes[9] = (NSOpenGLPixelFormatAttribute)0;
attributes[10] = (NSOpenGLPixelFormatAttribute)0;
_nsPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
}
CGLCreateContext(_pixelFormat, NULL, &_context);
_nsContext = [[NSOpenGLContext alloc] initWithFormat:_nsPixelFormat shareContext:nil];
_context = (CGLContextObj)[_nsContext CGLContextObj];
_pixelFormat = (CGLPixelFormatObj)[_nsPixelFormat CGLPixelFormatObj];
CGLContextObj prevContext = CGLGetCurrentContext();
CGLSetCurrentContext(_context);
@ -164,17 +172,14 @@ void MacOGLDisplayView::Init()
CGLSetCurrentContext(prevContext);
}
void MacOGLDisplayView::_FrameRenderAndFlush()
NSOpenGLPixelFormat* MacOGLDisplayView::GetNSPixelFormat() const
{
if (this->_willRenderToCALayer)
{
this->CALayerDisplay();
}
else
{
this->RenderViewOGL();
CGLFlushDrawable(this->_context);
}
return this->_nsPixelFormat;
}
NSOpenGLContext* MacOGLDisplayView::GetNSContext() const
{
return this->_nsContext;
}
CGLPixelFormatObj MacOGLDisplayView::GetPixelFormat() const
@ -268,14 +273,39 @@ void MacOGLDisplayView::SetPixelScaler(const VideoFilterTypeID filterID)
CGLUnlockContext(this->_context);
}
void MacOGLDisplayView::UpdateView()
// NDS GPU Interface
void MacOGLDisplayView::LoadDisplays()
{
CGLLockContext(this->_context);
CGLSetCurrentContext(this->_context);
this->_FrameRenderAndFlush();
this->OGLVideoOutput::LoadDisplays();
CGLUnlockContext(this->_context);
}
void MacOGLDisplayView::ProcessDisplays()
{
CGLLockContext(this->_context);
CGLSetCurrentContext(this->_context);
this->OGLVideoOutput::ProcessDisplays();
CGLUnlockContext(this->_context);
}
void MacOGLDisplayView::UpdateView()
{
if (this->_willRenderToCALayer)
{
this->CALayerDisplay();
}
else
{
CGLLockContext(this->_context);
CGLSetCurrentContext(this->_context);
this->RenderViewOGL();
CGLFlushDrawable(this->_context);
CGLUnlockContext(this->_context);
}
}
void MacOGLDisplayView::FrameFinish()
{
CGLLockContext(this->_context);
@ -283,14 +313,3 @@ void MacOGLDisplayView::FrameFinish()
this->OGLVideoOutput::FrameFinish();
CGLUnlockContext(this->_context);
}
void MacOGLDisplayView::HandleGPUFrameEndEvent(const NDSDisplayInfo &ndsDisplayInfo)
{
this->OGLVideoOutput::HandleGPUFrameEndEvent(ndsDisplayInfo);
CGLLockContext(this->_context);
CGLSetCurrentContext(this->_context);
this->LoadDisplays();
this->ProcessDisplays();
CGLUnlockContext(this->_context);
}