Cocoa Port:

- Move OpenGL renderer code from the UI code to the emulation core interface code.
- Clean up the OpenGL renderer init code, and lazy load the context init.
- Fix bug where the wrong display would show when changing display modes after changing video filters.
- Do some other random bug fixes.
This commit is contained in:
rogerman 2013-02-06 00:54:39 +00:00
parent 2dc9077511
commit 2e6ab871c1
7 changed files with 166 additions and 136 deletions

View File

@ -1781,7 +1781,7 @@
29B97313FDCFA39411CA2CEA /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0430;
LastUpgradeCheck = 0460;
ORGANIZATIONNAME = "DeSmuME Team";
};
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "DeSmuME (XCode 4)" */;
@ -2575,7 +2575,6 @@
AB796D6F15CDCBA200C59155 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
LLVM_LTO = YES;
};
name = Release;
};
@ -2635,6 +2634,10 @@
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CLANG_X86_VECTOR_INSTRUCTIONS = sse3;
COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = YES;
@ -2655,6 +2658,7 @@
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_SHADOW = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IBC_FLATTEN_NIBS = NO;
INFOPLIST_FILE = "Info (Debug).plist";
MACOSX_DEPLOYMENT_TARGET = 10.6;
@ -2674,6 +2678,10 @@
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CLANG_X86_VECTOR_INSTRUCTIONS = ssse3;
"CLANG_X86_VECTOR_INSTRUCTIONS[arch=i386]" = sse3;
COPY_PHASE_STRIP = NO;
@ -2694,6 +2702,7 @@
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_SHADOW = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = Info.plist;
LD_NO_PIE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.6;

View File

@ -179,7 +179,7 @@ static CocoaDSMic *masterMic = nil;
- (UInt8) generateWhiteNoiseSample
{
return (UInt8)(rand() & 0xFF);
return (UInt8)(arc4random() & 0xFF);
}
- (void) fillWithNullSamples

View File

@ -250,6 +250,12 @@ bool GetGPULayerState(int gpuType, unsigned int i);
void SetGPUDisplayState(int gpuType, bool state);
bool GetGPUDisplayState(int gpuType);
bool OSXOpenGLRendererInit();
bool OSXOpenGLRendererBegin();
void OSXOpenGLRendererEnd();
bool CreateOpenGLRenderer();
void DestroyOpenGLRenderer();
void RequestOpenGLRenderer_3_2(bool request_3_2);
void SetOpenGLRendererFunctions(bool (*initFunction)(),
bool (*beginOGLFunction)(),

View File

@ -1463,11 +1463,17 @@ GPU3DInterface *core3DList[] = {
[property setValue:[NSNumber numberWithInteger:(NSInteger)VideoFilterTypeID_None] forKey:@"videoFilterType"];
[property setValue:[CocoaVideoFilter typeStringByID:VideoFilterTypeID_None] forKey:@"videoFilterTypeString"];
SetOpenGLRendererFunctions(&OSXOpenGLRendererInit,
&OSXOpenGLRendererBegin,
&OSXOpenGLRendererEnd);
return self;
}
- (void)dealloc
{
DestroyOpenGLRenderer();
[vf release];
[super dealloc];
@ -1854,6 +1860,119 @@ bool GetGPUDisplayState(int gpuType)
return result;
}
CGLContextObj OSXOpenGLRendererContext = NULL;
CGLPBufferObj OSXOpenGLRendererPBuffer = NULL;
bool OSXOpenGLRendererInit()
{
static bool isContextAlreadyCreated = false;
if (!isContextAlreadyCreated)
{
isContextAlreadyCreated = CreateOpenGLRenderer();
}
return true;
}
bool OSXOpenGLRendererBegin()
{
CGLSetCurrentContext(OSXOpenGLRendererContext);
return true;
}
void OSXOpenGLRendererEnd()
{
}
bool CreateOpenGLRenderer()
{
bool result = false;
bool useContext_3_2 = false;
CGLPixelFormatObj cglPixFormat = NULL;
CGLContextObj newContext = NULL;
CGLPBufferObj newPBuffer = NULL;
GLint virtualScreenCount = 0;
CGLPixelFormatAttribute attrs[] = {
kCGLPFAColorSize, (CGLPixelFormatAttribute)24,
kCGLPFAAlphaSize, (CGLPixelFormatAttribute)8,
kCGLPFADepthSize, (CGLPixelFormatAttribute)24,
kCGLPFAStencilSize, (CGLPixelFormatAttribute)8,
kCGLPFAAccelerated,
(CGLPixelFormatAttribute)0, (CGLPixelFormatAttribute)0,
(CGLPixelFormatAttribute)0
};
#ifdef MAC_OS_X_VERSION_10_7
// If we can support a 3.2 Core Profile context, then request that in our
// pixel format attributes.
useContext_3_2 = [CocoaDSUtil OSVersionCheckMajor:10 minor:7 revision:0] ? true : false;
if (useContext_3_2)
{
attrs[9] = kCGLPFAOpenGLProfile;
attrs[10] = (CGLPixelFormatAttribute)kCGLOGLPVersion_3_2_Core;
}
#endif
CGLChoosePixelFormat(attrs, &cglPixFormat, &virtualScreenCount);
if (cglPixFormat == NULL)
{
// Remove the HW rendering requirement and try again. Note that this will
// result in SW rendering, which will cause a substantial speed hit.
attrs[8] = (CGLPixelFormatAttribute)0;
CGLChoosePixelFormat(attrs, &cglPixFormat, &virtualScreenCount);
if (cglPixFormat == NULL)
{
return result;
}
}
CGLCreateContext(cglPixFormat, NULL, &newContext);
CGLReleasePixelFormat(cglPixFormat);
// Create a PBuffer for legacy contexts since the availability of FBOs
// is not guaranteed.
if (!useContext_3_2)
{
CGLCreatePBuffer(GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT, GL_TEXTURE_2D, GL_RGBA, 0, &newPBuffer);
if (newPBuffer == NULL)
{
CGLReleaseContext(newContext);
return result;
}
else
{
GLint virtualScreenID = 0;
CGLGetVirtualScreen(newContext, &virtualScreenID);
CGLSetPBuffer(newContext, newPBuffer, 0, 0, virtualScreenID);
}
}
RequestOpenGLRenderer_3_2(useContext_3_2);
OSXOpenGLRendererContext = newContext;
OSXOpenGLRendererPBuffer = newPBuffer;
result = true;
return result;
}
void DestroyOpenGLRenderer()
{
if (OSXOpenGLRendererContext == NULL)
{
return;
}
CGLReleasePBuffer(OSXOpenGLRendererPBuffer);
CGLReleaseContext(OSXOpenGLRendererContext);
OSXOpenGLRendererContext = NULL;
}
void RequestOpenGLRenderer_3_2(bool request_3_2)
{
#ifdef OGLRENDER_3_2_H

View File

@ -43,7 +43,7 @@ CoreAudioSound::CoreAudioSound(size_t bufferSamples, size_t sampleSize)
}
error = OpenAComponent(comp, &_au);
if (comp == NULL)
if (error != noErr || comp == NULL)
{
return;
}

View File

@ -122,9 +122,7 @@
@interface OpenGLDisplayView : NSOpenGLView <DisplayViewDelegate>
{
CGLContextObj cglDisplayContext;
NSOpenGLContext *oglRendererContext;
BOOL useContext_3_2;
BOOL isVBOSupported;
BOOL isShadersSupported;
BOOL isVAOSupported;
@ -160,9 +158,8 @@
}
- (void) setupOpenGL_Legacy;
- (void) setupOpenGL_3_2;
- (void) drawVideoFrame;
- (void) uploadDisplayTextures:(const GLvoid *)textureData width:(const GLsizei)texWidth height:(const GLsizei)texHeight;
- (void) uploadDisplayTextures:(const GLvoid *)textureData displayMode:(const NSInteger)displayModeID width:(const GLsizei)texWidth height:(const GLsizei)texHeight;
- (void) renderDisplayUsingDisplayMode:(const NSInteger)displayModeID;
- (void) updateDisplayVerticesUsingDisplayMode:(const NSInteger)displayModeID orientation:(const NSInteger)displayOrientationID;
@ -174,9 +171,6 @@ extern "C"
#endif
GLint SetupShaders(GLuint *programID, GLuint *vertShaderID, const char *vertShaderProgram, GLuint *fragShaderID, const char *fragShaderProgram);
bool OSXOpenGLRendererInit();
bool OSXOpenGLRendererBegin();
void OSXOpenGLRendererEnd();
#ifdef __cplusplus
}

View File

@ -85,8 +85,6 @@ enum OGLVertexAttributeID
};
CGLContextObj OSXOpenGLRendererContext = NULL;
@implementation DisplayViewDelegate
@synthesize view;
@ -348,7 +346,7 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
if ( (oldMode == DS_DISPLAY_TYPE_MAIN && displayModeID == DS_DISPLAY_TYPE_TOUCH) ||
(oldMode == DS_DISPLAY_TYPE_TOUCH && displayModeID == DS_DISPLAY_TYPE_MAIN) )
{
[view setNeedsDisplay:YES];
[CocoaDSUtil messageSendOneWay:self.sendPortDisplay msgID:MESSAGE_REDRAW_VIEW];
}
}
@ -1009,82 +1007,11 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
vtxIndexBuffer = new GLubyte[12];
vtxBufferOffset = 0;
// Create a new context for the OpenGL-based emulated 3D renderer
#ifdef MAC_OS_X_VERSION_10_7
NSOpenGLPixelFormatAttribute attrs[] = {
NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute)24,
NSOpenGLPFAAlphaSize, (NSOpenGLPixelFormatAttribute)8,
NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)24,
NSOpenGLPFAStencilSize, (NSOpenGLPixelFormatAttribute)8,
NSOpenGLPFAAccelerated,
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
(NSOpenGLPixelFormatAttribute)0
};
useContext_3_2 = [CocoaDSUtil OSVersionCheckMajor:10 minor:7 revision:0] ? YES : NO;
#else
NSOpenGLPixelFormatAttribute attrs[] =
{
NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute)24,
NSOpenGLPFAAlphaSize, (NSOpenGLPixelFormatAttribute)8,
NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)24,
NSOpenGLPFAStencilSize, (NSOpenGLPixelFormatAttribute)8,
NSOpenGLPFAAccelerated,
(NSOpenGLPixelFormatAttribute)0, (NSOpenGLPixelFormatAttribute)0,
(NSOpenGLPixelFormatAttribute)0
};
useContext_3_2 = NO;
#endif
// If we're not using a 3.2 Core Profile context, then remove that
// requirement from the pixel format.
if (!useContext_3_2)
{
attrs[9] = (NSOpenGLPixelFormatAttribute)0;
attrs[10] = (NSOpenGLPixelFormatAttribute)0;
}
NSOpenGLPixelFormat *tempPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
if (tempPixelFormat == nil)
{
// Remove the HW rendering requirement and try again. Note that this will
// result in SW rendering, which will cause a substantial speed hit.
attrs[8] = (NSOpenGLPixelFormatAttribute)0;
tempPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
}
NSOpenGLContext *newOGLRendererContext = [[NSOpenGLContext alloc] initWithFormat:tempPixelFormat shareContext:nil];
[tempPixelFormat release];
if (!useContext_3_2)
{
NSOpenGLPixelBuffer *tempPixelBuffer = [[NSOpenGLPixelBuffer alloc]
initWithTextureTarget:GL_TEXTURE_2D
textureInternalFormat:GL_BGRA
textureMaxMipMapLevel:0
pixelsWide:GPU_DISPLAY_WIDTH
pixelsHigh:GPU_DISPLAY_HEIGHT*2];
[newOGLRendererContext setPixelBuffer:tempPixelBuffer cubeMapFace:0 mipMapLevel:0 currentVirtualScreen:[[self openGLContext] currentVirtualScreen]];
[tempPixelBuffer release];
}
oglRendererContext = newOGLRendererContext;
OSXOpenGLRendererContext = (CGLContextObj)[oglRendererContext CGLContextObj];
RequestOpenGLRenderer_3_2(useContext_3_2);
SetOpenGLRendererFunctions(&OSXOpenGLRendererInit,
&OSXOpenGLRendererBegin,
&OSXOpenGLRendererEnd);
return self;
}
- (void)dealloc
{
[oglRendererContext release];
OSXOpenGLRendererContext = NULL;
CGLContextObj prevContext = CGLGetCurrentContext();
CGLSetCurrentContext(cglDisplayContext);
@ -1182,7 +1109,6 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
{
// Check the OpenGL capabilities for this renderer
const GLubyte *glExtString = glGetString(GL_EXTENSIONS);
BOOL isPBOSupported = gluCheckExtension((const GLubyte *)"GL_ARB_pixel_buffer_object", glExtString);
// Set up textures
glGenTextures(1, &displayTexID);
@ -1285,22 +1211,22 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
CGLFlushDrawable(cglDisplayContext);
}
- (void) uploadDisplayTextures:(const GLvoid *)textureData width:(const GLsizei)texWidth height:(const GLsizei)texHeight
- (void) uploadDisplayTextures:(const GLvoid *)textureData displayMode:(const NSInteger)displayModeID width:(const GLsizei)texWidth height:(const GLsizei)texHeight
{
if (textureData == NULL)
{
return;
}
const GLint lineOffset = (displayModeID == DS_DISPLAY_TYPE_TOUCH) ? texHeight : 0;
glBindTexture(GL_TEXTURE_2D, displayTexID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, GL_RGBA, glTexPixelFormat, textureData);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, lineOffset, texWidth, texHeight, GL_RGBA, glTexPixelFormat, textureData);
glBindTexture(GL_TEXTURE_2D, 0);
}
- (void) renderDisplayUsingDisplayMode:(const NSInteger)displayModeID
{
GLubyte *elementPointer = NULL;
// Assign vertex attributes based on which OpenGL features we have.
if (isVAOSupported)
{
@ -1322,7 +1248,6 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
{
glVertexAttribPointer(OGLVertexAttributeID_Position, 2, GL_INT, GL_FALSE, 0, vtxBuffer);
glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, 0, texCoordBuffer);
elementPointer = vtxIndexBuffer;
}
glEnableVertexAttribArray(OGLVertexAttributeID_Position);
@ -1342,7 +1267,6 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
{
glTexCoordPointer(2, GL_FLOAT, 0, texCoordBuffer);
glVertexPointer(2, GL_INT, 0, vtxBuffer);
elementPointer = vtxIndexBuffer;
}
glEnableClientState(GL_VERTEX_ARRAY);
@ -1364,10 +1288,12 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
}
}
GLsizei vtxElementCount = 6;
if (displayModeID == DS_DISPLAY_TYPE_COMBO)
const GLsizei vtxElementCount = (displayModeID == DS_DISPLAY_TYPE_COMBO) ? 12 : 6;
GLubyte *elementPointer = isVBOSupported ? NULL : vtxIndexBuffer;
if (displayModeID == DS_DISPLAY_TYPE_TOUCH)
{
vtxElementCount = 12;
elementPointer += vtxElementCount;
}
glClear(GL_COLOR_BUFFER_BIT);
@ -1568,7 +1494,7 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
[self uploadDisplayTextures:videoFrameData width:frameWidth height:frameHeight];
[self uploadDisplayTextures:videoFrameData displayMode:displayModeID width:frameWidth height:frameHeight];
[self renderDisplayUsingDisplayMode:displayModeID];
[self drawVideoFrame];
@ -1738,6 +1664,11 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
glTexPixelFormat = GL_UNSIGNED_SHORT_1_5_5_5_REV;
}
if ([dispViewDelegate displayMode] != DS_DISPLAY_TYPE_COMBO)
{
videoFilterDestSize.height = (uint32_t)videoFilterDestSize.height * 2;
}
// Convert textures to Power-of-Two to support older GPUs
// Example: Radeon X1600M on the 2006 MacBook Pro
uint32_t potW = GetNearestPositivePOT((uint32_t)videoFilterDestSize.width);
@ -1756,31 +1687,19 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
}
}
GLfloat s = (GLfloat)(videoFilterDestSize.width / potW);
GLfloat t = (GLfloat)(videoFilterDestSize.height / potH);
const GLfloat s = (GLfloat)videoFilterDestSize.width / (GLfloat)potW;
const GLfloat t = (GLfloat)videoFilterDestSize.height / (GLfloat)potH;
// Set up texture coordinates
if ([dispViewDelegate displayMode] == DS_DISPLAY_TYPE_COMBO)
{
texCoordBuffer[0] = 0.0f; texCoordBuffer[1] = 0.0f;
texCoordBuffer[2] = s; texCoordBuffer[3] = 0.0f;
texCoordBuffer[4] = s; texCoordBuffer[5] = t/2.0f;
texCoordBuffer[6] = 0.0f; texCoordBuffer[7] = t/2.0f;
texCoordBuffer[8] = 0.0f; texCoordBuffer[9] = t/2.0f;
texCoordBuffer[10] = s; texCoordBuffer[11] = t/2.0f;
texCoordBuffer[12] = s; texCoordBuffer[13] = t;
texCoordBuffer[14] = 0.0f; texCoordBuffer[15] = t;
}
else // displayMode == DS_DISPLAY_TYPE_MAIN || displayMode == DS_DISPLAY_TYPE_TOUCH
{
texCoordBuffer[0] = 0.0f; texCoordBuffer[1] = 0.0f;
texCoordBuffer[2] = s; texCoordBuffer[3] = 0.0f;
texCoordBuffer[4] = s; texCoordBuffer[5] = t;
texCoordBuffer[6] = 0.0f; texCoordBuffer[7] = t;
memcpy(texCoordBuffer + (1 * 8), texCoordBuffer + (0 * 8), sizeof(GLfloat) * (1 * 8));
}
texCoordBuffer[0] = 0.0f; texCoordBuffer[1] = 0.0f;
texCoordBuffer[2] = s; texCoordBuffer[3] = 0.0f;
texCoordBuffer[4] = s; texCoordBuffer[5] = t/2.0f;
texCoordBuffer[6] = 0.0f; texCoordBuffer[7] = t/2.0f;
texCoordBuffer[8] = 0.0f; texCoordBuffer[9] = t/2.0f;
texCoordBuffer[10] = s; texCoordBuffer[11] = t/2.0f;
texCoordBuffer[12] = s; texCoordBuffer[13] = t;
texCoordBuffer[14] = 0.0f; texCoordBuffer[15] = t;
CGLLockContext(cglDisplayContext);
@ -1870,20 +1789,3 @@ GLint SetupShaders(GLuint *programID, GLuint *vertShaderID, const char *vertShad
return shaderStatus;
}
bool OSXOpenGLRendererInit()
{
return true;
}
bool OSXOpenGLRendererBegin()
{
CGLSetCurrentContext(OSXOpenGLRendererContext);
return true;
}
void OSXOpenGLRendererEnd()
{
}