From 4f282c94993f36ca391b867ff8a7d6264ff827ca Mon Sep 17 00:00:00 2001 From: rogerman Date: Fri, 10 Aug 2012 15:48:18 +0000 Subject: [PATCH] Cocoa Port: - Refactor video output code to not assume the use of SoftRasterizer - Change SoftRasterizer-based video output in combo display mode to draw a separate quad for each DS screen, instead of drawing one big quad for both screens - Begin adding preliminary support for the OpenGL 3D renderer - Misc. code cleanup --- desmume/src/cocoa/cocoa_output.h | 10 +- desmume/src/cocoa/cocoa_output.mm | 100 +++----- desmume/src/cocoa/userinterface/displayView.h | 10 +- .../src/cocoa/userinterface/displayView.mm | 224 ++++++++++++++---- 4 files changed, 223 insertions(+), 121 deletions(-) diff --git a/desmume/src/cocoa/cocoa_output.h b/desmume/src/cocoa/cocoa_output.h index 55de75f77..052b027c1 100644 --- a/desmume/src/cocoa/cocoa_output.h +++ b/desmume/src/cocoa/cocoa_output.h @@ -180,6 +180,8 @@ - (void) handleRequestScreenshot:(NSData *)fileURLStringData fileTypeData:(NSData *)fileTypeData; - (void) handleCopyToPasteboard; +- (void) fillVideoFrameWithColor:(UInt8)colorValue; + - (NSImage *) image; - (NSBitmapImageRep *) bitmapImageRep; @@ -195,14 +197,16 @@ extern "C" { #endif -bool opengl_init(); - void HandleMessageEchoResponse(NSPortMessage *portMessage); void SetGPULayerState(int displayType, unsigned int i, bool state); bool GetGPULayerState(int displayType, unsigned int i); void SetGPUDisplayState(int displayType, bool state); bool GetGPUDisplayState(int displayType); - + +void SetOpenGLRendererFunctions(bool (*initFunction)(), + bool (*beginOGLFunction)(), + void (*endOGLFunction)()); + #ifdef __cplusplus } #endif diff --git a/desmume/src/cocoa/cocoa_output.mm b/desmume/src/cocoa/cocoa_output.mm index b4e40c6b3..1dd477052 100644 --- a/desmume/src/cocoa/cocoa_output.mm +++ b/desmume/src/cocoa/cocoa_output.mm @@ -36,7 +36,7 @@ GPU3DInterface *core3DList[] = { &gpu3DNull, &gpu3DRasterize, - //&gpu3Dgl, + &gpu3Dgl, NULL }; @@ -1267,74 +1267,12 @@ GPU3DInterface *core3DList[] = { - (void) handleSetViewToBlack { - NSSize destSize = [vf destSize]; - NSUInteger dataSize = (NSUInteger)destSize.width * (NSUInteger)destSize.height; - - void *texData = NULL; - if ([vf typeID] == VideoFilterTypeID_None) - { - texData = calloc(dataSize, sizeof(UInt16)); - dataSize *= sizeof(UInt16); - } - else - { - texData = calloc(dataSize, sizeof(UInt32)); - dataSize *= sizeof(UInt32); - } - - if (texData == NULL) - { - return; - } - - NSData *gpuData = [[[NSData alloc] initWithBytes:texData length:dataSize] autorelease]; - if (gpuData == nil) - { - return; - } - - [delegate doProcessVideoFrame:texData frameSize:destSize]; - - self.frameData = gpuData; - - free(texData); - texData = nil; + [self fillVideoFrameWithColor:0]; } - (void) handleSetViewToWhite { - NSSize destSize = [vf destSize]; - NSUInteger dataSize = (NSUInteger)destSize.width * (NSUInteger)destSize.height; - - if ([vf typeID] == VideoFilterTypeID_None) - { - dataSize *= sizeof(UInt16); - } - else - { - dataSize *= sizeof(UInt32); - } - - void *texData = malloc(dataSize); - if (texData == NULL) - { - return; - } - - memset(texData, 255, dataSize); - - NSData *gpuData = [[[NSData alloc] initWithBytes:texData length:dataSize] autorelease]; - if (gpuData == nil) - { - return; - } - - [delegate doProcessVideoFrame:texData frameSize:destSize]; - - self.frameData = gpuData; - - free(texData); - texData = nil; + [self fillVideoFrameWithColor:255]; } - (void) handleRequestScreenshot:(NSData *)fileURLStringData fileTypeData:(NSData *)fileTypeData @@ -1368,6 +1306,24 @@ GPU3DInterface *core3DList[] = { [pboard setData:[screenshot TIFFRepresentationUsingCompression:NSTIFFCompressionLZW factor:1.0f] forType:NSTIFFPboardType]; } +- (void) fillVideoFrameWithColor:(UInt8)colorValue +{ + UInt16 *gpuBytes = (UInt16 *)malloc(GPU_SCREEN_SIZE_BYTES * 2); + if (gpuBytes == NULL) + { + return; + } + + memset(gpuBytes, colorValue, GPU_SCREEN_SIZE_BYTES * 2); + + NSData *gpuData = [[[NSData alloc] initWithBytes:gpuBytes length:GPU_SCREEN_SIZE_BYTES * 2] autorelease]; + + free(gpuBytes); + gpuBytes = nil; + + [self handleEmuFrameProcessed:gpuData]; +} + - (NSImage *) image { NSImage *newImage = [[NSImage alloc] initWithSize:[vf srcSize]]; @@ -1533,11 +1489,6 @@ GPU3DInterface *core3DList[] = { @end -bool opengl_init(void) -{ - return true; -} - void HandleMessageEchoResponse(NSPortMessage *portMessage) { NSPortMessage *echo = [[NSPortMessage alloc] initWithSendPort:[portMessage receivePort] receivePort:[portMessage sendPort] components:nil]; @@ -1676,3 +1627,12 @@ bool GetGPUDisplayState(int displayType) return result; } + +void SetOpenGLRendererFunctions(bool (*initFunction)(), + bool (*beginOGLFunction)(), + void (*endOGLFunction)()) +{ + oglrender_init = initFunction; + oglrender_beginOpenGL = beginOGLFunction; + oglrender_endOpenGL = endOGLFunction; +} diff --git a/desmume/src/cocoa/userinterface/displayView.h b/desmume/src/cocoa/userinterface/displayView.h index 6666355a2..608a1cb63 100644 --- a/desmume/src/cocoa/userinterface/displayView.h +++ b/desmume/src/cocoa/userinterface/displayView.h @@ -130,11 +130,14 @@ GLenum glTexPixelFormat; GLvoid *glTexBack; NSSize glTexBackSize; - GLuint drawTexture[1]; + GLuint swRasterizerDrawTexture[2]; } - (void) drawVideoFrame; -- (void) uploadFrameTexture:(const GLvoid *)frameBytes textureSize:(NSSize)textureSize; +- (void) uploadSWRasterizerTexturesUsingSize:(NSSize)textureSize + mainBytes:(const GLvoid *)mainBytes + touchBytes:(const GLvoid *)touchBytes; +- (void) renderSWRasterizer; @end @@ -144,6 +147,9 @@ extern "C" #endif void SetupOpenGLView(GLsizei width, GLsizei height, GLfloat scalar, GLfloat angleDegrees); +bool OSXOpenGLRendererInit(); +bool OSXOpenGLRendererBegin(); +void OSXOpenGLRendererEnd(); #ifdef __cplusplus } diff --git a/desmume/src/cocoa/userinterface/displayView.mm b/desmume/src/cocoa/userinterface/displayView.mm index 3eb96ff77..a9177a74a 100644 --- a/desmume/src/cocoa/userinterface/displayView.mm +++ b/desmume/src/cocoa/userinterface/displayView.mm @@ -29,6 +29,8 @@ #undef BOOL +NSOpenGLContext *OSXDefaultOpenGLContext = nil; + @implementation DisplayViewDelegate @synthesize view; @@ -797,6 +799,9 @@ glTexBack = (GLvoid *)calloc(w * h, sizeof(UInt16)); glTexBackSize = NSMakeSize(w, h); + OSXDefaultOpenGLContext = [[self openGLContext] retain]; + [OSXDefaultOpenGLContext makeCurrentContext]; + return self; } @@ -843,52 +848,31 @@ glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glGenTextures(1, &drawTexture[0]); - glBindTexture(GL_TEXTURE_2D, drawTexture[0]); + + glGenTextures(2, &swRasterizerDrawTexture[0]); + + SetOpenGLRendererFunctions(&OSXOpenGLRendererInit, + &OSXOpenGLRendererBegin, + &OSXOpenGLRendererEnd); } - (void) drawVideoFrame { - GLfloat w = (GLfloat)dispViewDelegate.normalSize.width; - GLfloat h = (GLfloat)dispViewDelegate.normalSize.height; - GLfloat texRatioW = (GLfloat)lastFrameSize.width / (GLfloat)GetNearestPositivePOT((UInt32)lastFrameSize.width); - GLfloat texRatioH = (GLfloat)lastFrameSize.height / (GLfloat)GetNearestPositivePOT((UInt32)lastFrameSize.height); - - glClear(GL_COLOR_BUFFER_BIT); - - glBegin(GL_QUADS); - - glTexCoord2f(0.0f, 0.0f); - glVertex3f(-(w/2.0f), (h/2.0f), 0.0f); - - glTexCoord2f(texRatioW, 0.0f); - glVertex3f((w/2.0f), (h/2.0f), 0.0f); - - glTexCoord2f(texRatioW, texRatioH); - glVertex3f((w/2.0f), -(h/2.0f), 0.0f); - - glTexCoord2f(0.0f, texRatioH); - glVertex3f(-(w/2.0f), -(h/2.0f), 0.0f); - - glEnd(); - CGLFlushDrawable((CGLContextObj)[[self openGLContext] CGLContextObj]); } -- (void) uploadFrameTexture:(const GLvoid *)frameBytes textureSize:(NSSize)textureSize +- (void) uploadSWRasterizerTexturesUsingSize:(NSSize)textureSize + mainBytes:(const GLvoid *)mainBytes + touchBytes:(const GLvoid *)touchBytes { - UInt32 w = GetNearestPositivePOT((UInt32)textureSize.width); - UInt32 h = GetNearestPositivePOT((UInt32)textureSize.height); - NSUInteger bitDepth; + uint32_t w = GetNearestPositivePOT((uint32_t)textureSize.width); + uint32_t h = GetNearestPositivePOT((uint32_t)textureSize.height); + + size_t bitDepth = sizeof(uint32_t); if (glTexPixelFormat == GL_UNSIGNED_SHORT_1_5_5_5_REV) { - bitDepth = sizeof(UInt16); - } - else - { - bitDepth = sizeof(UInt32); + bitDepth = sizeof(uint16_t); } if (glTexBackSize.width != w || glTexBackSize.height != h) @@ -897,17 +881,107 @@ glTexBackSize.height = h; free(glTexBack); - glTexBack = (GLvoid *)calloc(w * h, bitDepth); + glTexBack = (GLvoid *)calloc((size_t)w * (size_t)h, bitDepth); if (glTexBack == NULL) { return; } } + // Main screen + glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (GLsizei)w, (GLsizei)h, 0, GL_RGBA, glTexPixelFormat, glTexBack); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, (GLsizei)textureSize.width, (GLsizei)textureSize.height, GL_RGBA, glTexPixelFormat, frameBytes); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, (GLsizei)textureSize.width, (GLsizei)textureSize.height, GL_RGBA, glTexPixelFormat, mainBytes); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glTexRenderStyle); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glTexRenderStyle); + + // Touch screen + glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[1]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (GLsizei)w, (GLsizei)h, 0, GL_RGBA, glTexPixelFormat, glTexBack); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, (GLsizei)textureSize.width, (GLsizei)textureSize.height, GL_RGBA, glTexPixelFormat, touchBytes); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glTexRenderStyle); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glTexRenderStyle); +} + +- (void) renderSWRasterizer +{ + NSInteger displayType = [dispViewDelegate displayType]; + GLfloat w = (GLfloat)dispViewDelegate.normalSize.width; + GLfloat h = (GLfloat)dispViewDelegate.normalSize.height; + + glClear(GL_COLOR_BUFFER_BIT); + + if (displayType == DS_DISPLAY_TYPE_COMBO) + { + GLfloat texRatioMainW = (GLfloat)lastFrameSize.width / (GLfloat)GetNearestPositivePOT((uint32_t)lastFrameSize.width); + GLfloat texRatioMainH = (GLfloat)lastFrameSize.height / (GLfloat)GetNearestPositivePOT((uint32_t)lastFrameSize.height); + GLfloat texRatioTouchW = (GLfloat)lastFrameSize.width / (GLfloat)GetNearestPositivePOT((uint32_t)lastFrameSize.width); + GLfloat texRatioTouchH = (GLfloat)lastFrameSize.height / (GLfloat)GetNearestPositivePOT((uint32_t)lastFrameSize.height); + + // Main screen + glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[0]); + glBegin(GL_QUADS); + + glTexCoord2f(0.0f, 0.0f); + glVertex3f(-(w/2.0f), (h/2.0f), 0.0f); + + glTexCoord2f(texRatioMainW, 0.0f); + glVertex3f((w/2.0f), (h/2.0f), 0.0f); + + glTexCoord2f(texRatioMainW, texRatioMainH); + glVertex3f((w/2.0f), 0.0f, 0.0f); + + glTexCoord2f(0.0f, texRatioMainH); + glVertex3f(-(w/2.0f), 0.0f, 0.0f); + + glEnd(); + + // Touch screen + glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[1]); + glBegin(GL_QUADS); + + glTexCoord2f(0.0f, 0.0f); + glVertex3f(-(w/2.0f), 0.0f, 0.0f); + + glTexCoord2f(texRatioTouchW, 0.0f); + glVertex3f((w/2.0f), 0.0f, 0.0f); + + glTexCoord2f(texRatioTouchW, texRatioTouchH); + glVertex3f((w/2.0f), -(h/2.0f), 0.0f); + + glTexCoord2f(0.0f, texRatioTouchH); + glVertex3f(-(w/2.0f), -(h/2.0f), 0.0f); + + glEnd(); + } + else + { + GLfloat texRatioW = (GLfloat)lastFrameSize.width / (GLfloat)GetNearestPositivePOT((uint32_t)lastFrameSize.width); + GLfloat texRatioH = (GLfloat)lastFrameSize.height / (GLfloat)GetNearestPositivePOT((uint32_t)lastFrameSize.height); + GLuint drawTexture = swRasterizerDrawTexture[0]; + + if (displayType == DS_DISPLAY_TYPE_TOUCH) + { + drawTexture = swRasterizerDrawTexture[1]; + } + + glBindTexture(GL_TEXTURE_2D, drawTexture); + glBegin(GL_QUADS); + + glTexCoord2f(0.0f, 0.0f); + glVertex3f(-(w/2.0f), (h/2.0f), 0.0f); + + glTexCoord2f(texRatioW, 0.0f); + glVertex3f((w/2.0f), (h/2.0f), 0.0f); + + glTexCoord2f(texRatioW, texRatioH); + glVertex3f((w/2.0f), -(h/2.0f), 0.0f); + + glTexCoord2f(0.0f, texRatioH); + glVertex3f(-(w/2.0f), -(h/2.0f), 0.0f); + + glEnd(); + } } - (void)keyDown:(NSEvent *)theEvent @@ -1030,11 +1104,51 @@ - (void)doProcessVideoFrame:(const void *)videoFrameData frameSize:(NSSize)frameSize { + lastFrameSize = frameSize; + CGLLockContext((CGLContextObj)[[self openGLContext] CGLContextObj]); [[self openGLContext] makeCurrentContext]; - [self uploadFrameTexture:(const GLvoid *)videoFrameData textureSize:frameSize]; - lastFrameSize = frameSize; + + switch ([dispViewDelegate displayType]) + { + case DS_DISPLAY_TYPE_MAIN: + [self uploadSWRasterizerTexturesUsingSize:frameSize + mainBytes:videoFrameData + touchBytes:videoFrameData]; + break; + + case DS_DISPLAY_TYPE_TOUCH: + [self uploadSWRasterizerTexturesUsingSize:frameSize + mainBytes:videoFrameData + touchBytes:videoFrameData]; + break; + + case DS_DISPLAY_TYPE_COMBO: + { + frameSize.height /= 2.0; + + if (glTexPixelFormat == GL_UNSIGNED_SHORT_1_5_5_5_REV) + { + [self uploadSWRasterizerTexturesUsingSize:frameSize + mainBytes:videoFrameData + touchBytes:(const uint16_t *)videoFrameData + ((size_t)frameSize.width * (size_t)frameSize.height)]; + } + else + { + [self uploadSWRasterizerTexturesUsingSize:frameSize + mainBytes:videoFrameData + touchBytes:(const uint32_t *)videoFrameData + ((size_t)frameSize.width * (size_t)frameSize.height)]; + } + + break; + } + + default: + break; + } + + [self renderSWRasterizer]; [self drawVideoFrame]; CGLUnlockContext((CGLContextObj)[[self openGLContext] CGLContextObj]); @@ -1056,6 +1170,7 @@ CGLLockContext((CGLContextObj)[[self openGLContext] CGLContextObj]); [[self openGLContext] makeCurrentContext]; + [self renderSWRasterizer]; [self drawVideoFrame]; CGLUnlockContext((CGLContextObj)[[self openGLContext] CGLContextObj]); @@ -1072,17 +1187,14 @@ - (void) doVerticalSyncChanged:(BOOL)useVerticalSync { - GLint swapInt = 1; + GLint swapInt = 0; if (useVerticalSync) { - [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval]; - } - else - { - swapInt = 0; - [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval]; + swapInt = 1; } + + [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval]; } - (void)doVideoFilterChanged:(NSInteger)videoFilterTypeID @@ -1107,3 +1219,23 @@ void SetupOpenGLView(GLsizei width, GLsizei height, GLfloat scalar, GLfloat angl glRotatef((GLfloat)CLOCKWISE_DEGREES(angleDegrees), 0.0f, 0.0f, 1.0f); glScalef(scalar, scalar, 0.0f); } + +bool OSXOpenGLRendererInit() +{ + [OSXDefaultOpenGLContext makeCurrentContext]; + + return true; +} + +bool OSXOpenGLRendererBegin() +{ + CGLLockContext((CGLContextObj)[OSXDefaultOpenGLContext CGLContextObj]); + [OSXDefaultOpenGLContext makeCurrentContext]; + + return true; +} + +void OSXOpenGLRendererEnd() +{ + CGLUnlockContext((CGLContextObj)[OSXDefaultOpenGLContext CGLContextObj]); +}