From bc128ddd250e16615ecf38ddaf1f75faf12b6704 Mon Sep 17 00:00:00 2001 From: gecko_reverse Date: Sun, 27 Apr 2008 03:13:53 +0000 Subject: [PATCH] now supports hardware accelerated offscreen opengl using pixel buffers if available --- desmume/src/cocoa/main.m | 2 - desmume/src/cocoa/nds_control.m | 84 ++++++++++++++++++++++++--------- 2 files changed, 61 insertions(+), 25 deletions(-) diff --git a/desmume/src/cocoa/main.m b/desmume/src/cocoa/main.m index 79c2bcf76..97cc21f90 100644 --- a/desmume/src/cocoa/main.m +++ b/desmume/src/cocoa/main.m @@ -27,7 +27,6 @@ Based on work by yopyop and the DeSmuME team! #import "preferences.h" /* -FIXME: Hardware acceleration for openglrender.c ?? FIXME: When cross-platform (core) components end emulation due to error - pause should be called (set the menu checkmark) FIXME: .nds.gba support? */ @@ -191,7 +190,6 @@ void CreateMenu(AppDelegate *delegate) [loadSlot_item[i] setKeyEquivalentModifierMask:0]; } -//fixme changed save state item function names /* To be implemented when saves.h provides a way to get the time of a save that's not string/human formatted... diff --git a/desmume/src/cocoa/nds_control.m b/desmume/src/cocoa/nds_control.m index b58e6b349..65e3df2fe 100644 --- a/desmume/src/cocoa/nds_control.m +++ b/desmume/src/cocoa/nds_control.m @@ -19,6 +19,7 @@ #import "nds_control.h" #import +#import //DeSmuME general includes #define OBJ_C @@ -88,7 +89,8 @@ struct NDS_fw_config_data firmware; NSLog(@"No flash file given\n"); } - //check if we can sen messages on other threads, which we will use for video update + //check if we can send messages on other threads, which we will use for video update + //this is for compatibility for tiger and earlier timer_based = ([NSObject instancesRespondToSelector:@selector(performSelector:onThread:withObject:waitUntilDone:)]==NO)?true:false; //Firmware setup @@ -99,13 +101,10 @@ struct NDS_fw_config_data firmware; NDS_CreateDummyFirmware(&firmware); //3D Init + bool gl_ready = false; - //Create the pixel format for our gpu NSOpenGLPixelFormatAttribute attrs[] = { - //NSOpenGLPFAAccelerated, - //NSOpenGLPFANoRecovery, - //NSOpenGLPFADoubleBuffer, NSOpenGLPFAColorSize, 24, NSOpenGLPFAAlphaSize, 8, NSOpenGLPFADepthSize, 24, @@ -114,28 +113,67 @@ struct NDS_fw_config_data firmware; 0 }; - pixel_format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs]; - if(pixel_format == nil) + if((pixel_format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs]) == nil) { - messageDialog(NSLocalizedString(@"Error", nil), @"Couldn't create OpenGL pixel format for GPU"); - return self; - } + messageDialog(NSLocalizedString(@"Error", nil), @"Couldn't create OpenGL pixel format for 3D rendering"); + context = nil; - context = [[NSOpenGLContext alloc] initWithFormat:pixel_format shareContext:nil]; - if(context == nil) + } else if((context = [[NSOpenGLContext alloc] initWithFormat:pixel_format shareContext:nil]) == nil) { - messageDialog(NSLocalizedString(@"Error", nil), @"Couldn't create OpenGL context for GPU"); - return self; + [pixel_format release]; + pixel_format = nil; + messageDialog(NSLocalizedString(@"Error", nil), @"Couldn't create OpenGL context for 3D rendering"); + } else + { + [context makeCurrentContext]; + + //check extensions + BOOL supports_pixel_buffers = NO; + const char *extension_list = (const char*)glGetString(GL_EXTENSIONS); + if(extension_list) + { + NSArray *extensions = [[NSString stringWithCString:extension_list encoding:NSASCIIStringEncoding] componentsSeparatedByString:@" "]; + supports_pixel_buffers = [extensions containsObject:@"GL_APPLE_pixel_buffer"]; + } + + //attempt to use a pixel-buffer for hopefully hardware accelerated offscreen drawing + if(supports_pixel_buffers == YES) + { + NSOpenGLPixelBuffer *pixel_buffer = [[NSOpenGLPixelBuffer alloc] + initWithTextureTarget:GL_TEXTURE_2D + textureInternalFormat:GL_RGBA + textureMaxMipMapLevel:0 + pixelsWide:DS_SCREEN_WIDTH + pixelsHigh:DS_SCREEN_HEIGHT*2]; + + if(pixel_buffer == nil) + { + GLenum error = glGetError(); + messageDialog(NSLocalizedString(@"Error", nil), + [NSString stringWithFormat:@"Error setting up rgba pixel buffer for 3D rendering (glerror: %d)", error]); + } else + { + [context setPixelBuffer:pixel_buffer cubeMapFace:0 mipMapLevel:0 currentVirtualScreen:0]; + [pixel_buffer release]; + gl_ready = true; + } + } + + //if pixel buffers didn't work out, try simple offscreen renderings (probably software accelerated) + if(!gl_ready) + { + [context setOffScreen:(void*)&gpu_buff width:DS_SCREEN_WIDTH height:DS_SCREEN_HEIGHT rowbytes:DS_SCREEN_WIDTH*5]; + gl_ready = true; + } } - - //offscreen rendering - [context setOffScreen:(void*)&gpu_buff width:DS_SCREEN_WIDTH height:DS_SCREEN_HEIGHT rowbytes:DS_SCREEN_WIDTH * 5]; - [context makeCurrentContext]; - - NDS_3D_SetDriver(GPU3D_OPENGL); - if(!gpu3D->NDS_3D_Init()) - messageDialog(NSLocalizedString(@"Error", nil), @"Unable to initialize OpenGL components"); - + + if(gl_ready) + { + NDS_3D_SetDriver(GPU3D_OPENGL); + if(!gpu3D->NDS_3D_Init()) + messageDialog(NSLocalizedString(@"Error", nil), @"Unable to initialize OpenGL components"); + } + //Sound Init if(SPU_ChangeSoundCore(SNDCORE_OSX, 735 * 4) != 0) messageDialog(NSLocalizedString(@"Error", nil), @"Unable to initialize sound core");