diff --git a/desmume/src/cocoa/cocoa_output.h b/desmume/src/cocoa/cocoa_output.h index 98b3299b5..da6e94c3d 100644 --- a/desmume/src/cocoa/cocoa_output.h +++ b/desmume/src/cocoa/cocoa_output.h @@ -95,23 +95,28 @@ @protocol CocoaDSDisplayDelegate @required -- (void) doInitVideoOutput:(NSDictionary *)properties; -- (void) doProcessVideoFrame:(const void *)videoFrameData frameSize:(NSSize)frameSize; +- (void) doDisplayTypeChanged:(NSInteger)displayTypeID; @property (retain) NSPort *sendPortDisplay; +@property (assign) BOOL isHudEnabled; +@property (assign) BOOL isHudEditingModeEnabled; + +@end + +@protocol CocoaDSDisplayVideoDelegate + +@required +- (void) doInitVideoOutput:(NSDictionary *)properties; +- (void) doProcessVideoFrame:(const void *)videoFrameData frameSize:(NSSize)frameSize; @optional - (void) doResizeView:(NSRect)rect; - (void) doRedraw; -- (void) doDisplayTypeChanged:(NSInteger)displayTypeID; - (void) doDisplayOrientationChanged:(NSInteger)displayOrientationID; - (void) doDisplayOrderChanged:(NSInteger)displayOrderID; - (void) doBilinearOutputChanged:(BOOL)useBilinear; - (void) doVerticalSyncChanged:(BOOL)useVerticalSync; -- (void) doVideoFilterChanged:(NSInteger)videoFilterTypeID; - -@property (assign) BOOL isHudEnabled; -@property (assign) BOOL isHudEditingModeEnabled; +- (void) doVideoFilterChanged:(NSInteger)videoFilterTypeID frameSize:(NSSize)videoFilterDestSize; @end @@ -121,14 +126,12 @@ UInt32 gpuStateFlags; id delegate; NSInteger displayType; - CocoaVideoFilter *vf; + NSSize frameSize; pthread_mutex_t *mutexRender3D; OSSpinLock spinlockDelegate; OSSpinLock spinlockGpuState; OSSpinLock spinlockDisplayType; - OSSpinLock spinlockVideoFilterType; - OSSpinLock spinlockVfSrcBuffer; OSSpinLock spinlockRender3DRenderingEngine; OSSpinLock spinlockRender3DHighPrecisionColorInterpolation; OSSpinLock spinlockRender3DEdgeMarking; @@ -142,7 +145,7 @@ @property (assign) UInt32 gpuStateFlags; @property (retain) id delegate; @property (assign) NSInteger displayType; -@property (assign) CocoaVideoFilter *vf; +@property (readonly) NSSize frameSize; @property (readonly) pthread_mutex_t *mutexRender3D; - (void) setRender3DRenderingEngine:(NSInteger)methodID; @@ -162,15 +165,8 @@ - (void) setRender3DLineHack:(BOOL)state; - (BOOL) render3DLineHack; -- (void) handleResizeView:(NSData *)rectData; -- (void) handleRedrawView; - (void) handleChangeGpuStateFlags:(NSData *)flagsData; - (void) handleChangeDisplayType:(NSData *)displayTypeIdData; -- (void) handleChangeDisplayOrientation:(NSData *)displayOrientationIdData; -- (void) handleChangeDisplayOrder:(NSData *)displayOrderIdData; -- (void) handleChangeBilinearOutput:(NSData *)bilinearStateData; -- (void) handleChangeVerticalSync:(NSData *)verticalSyncStateData; -- (void) handleChangeVideoFilter:(NSData *)videoFilterTypeIdData; - (void) handleSetRender3DRenderingEngine:(NSData *)methodIdData; - (void) handleSetRender3DHighPrecisionColorInterpolation:(NSData *)stateData; - (void) handleSetRender3DEdgeMarking:(NSData *)stateData; @@ -196,6 +192,28 @@ @end +@interface CocoaDSDisplayVideo : CocoaDSDisplay +{ + CocoaVideoFilter *vf; + id videoDelegate; + + OSSpinLock spinlockVideoFilterType; + OSSpinLock spinlockVfSrcBuffer; +} + +@property (retain) id delegate; +@property (assign) CocoaVideoFilter *vf; + +- (void) handleResizeView:(NSData *)rectData; +- (void) handleRedrawView; +- (void) handleChangeDisplayOrientation:(NSData *)displayOrientationIdData; +- (void) handleChangeDisplayOrder:(NSData *)displayOrderIdData; +- (void) handleChangeBilinearOutput:(NSData *)bilinearStateData; +- (void) handleChangeVerticalSync:(NSData *)verticalSyncStateData; +- (void) handleChangeVideoFilter:(NSData *)videoFilterTypeIdData; + +@end + #ifdef __cplusplus extern "C" { diff --git a/desmume/src/cocoa/cocoa_output.mm b/desmume/src/cocoa/cocoa_output.mm index eb2b4f0b3..8753a470d 100644 --- a/desmume/src/cocoa/cocoa_output.mm +++ b/desmume/src/cocoa/cocoa_output.mm @@ -434,9 +434,9 @@ GPU3DInterface *core3DList[] = { @implementation CocoaDSDisplay @synthesize gpuStateFlags; -@synthesize delegate; -@synthesize displayType; -@synthesize vf; +@dynamic delegate; +@dynamic displayType; +@dynamic frameSize; @synthesize mutexRender3D; - (id)init @@ -453,8 +453,6 @@ GPU3DInterface *core3DList[] = { spinlockDelegate = OS_SPINLOCK_INIT; spinlockGpuState = OS_SPINLOCK_INIT; spinlockDisplayType = OS_SPINLOCK_INIT; - spinlockVideoFilterType = OS_SPINLOCK_INIT; - spinlockVfSrcBuffer = OS_SPINLOCK_INIT; spinlockRender3DRenderingEngine = OS_SPINLOCK_INIT; spinlockRender3DHighPrecisionColorInterpolation = OS_SPINLOCK_INIT; spinlockRender3DEdgeMarking = OS_SPINLOCK_INIT; @@ -465,7 +463,7 @@ GPU3DInterface *core3DList[] = { spinlockRender3DLineHack = OS_SPINLOCK_INIT; displayType = DS_DISPLAY_TYPE_COMBO; - vf = [[CocoaVideoFilter alloc] initWithSize:NSMakeSize(GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT * 2) typeID:VideoFilterTypeID_None numberThreads:2]; + frameSize = NSMakeSize((CGFloat)GPU_DISPLAY_WIDTH, (CGFloat)GPU_DISPLAY_HEIGHT * 2); gpuStateFlags = GPUSTATE_MAIN_GPU_MASK | GPUSTATE_MAIN_BG0_MASK | @@ -498,8 +496,6 @@ GPU3DInterface *core3DList[] = { [property setValue:[NSNumber numberWithBool:YES] forKey:@"gpuStateSubOBJ"]; [property setValue:[NSNumber numberWithInteger:displayType] forKey:@"displayMode"]; [property setValue:NSSTRING_DISPLAYMODE_MAIN forKey:@"displayModeString"]; - [property setValue:[NSNumber numberWithInteger:(NSInteger)VideoFilterTypeID_None] forKey:@"videoFilterType"]; - [property setValue:[CocoaVideoFilter typeStringByID:VideoFilterTypeID_None] forKey:@"videoFilterTypeString"]; [property setValue:[NSNumber numberWithInteger:CORE3DLIST_NULL] forKey:@"render3DRenderingEngine"]; [property setValue:[NSNumber numberWithBool:YES] forKey:@"render3DHighPrecisionColorInterpolation"]; [property setValue:[NSNumber numberWithBool:YES] forKey:@"render3DEdgeMarking"]; @@ -515,7 +511,6 @@ GPU3DInterface *core3DList[] = { - (void)dealloc { self.delegate = nil; - [vf release]; pthread_mutex_destroy(self.mutexRender3D); free(self.mutexRender3D); @@ -710,7 +705,7 @@ GPU3DInterface *core3DList[] = { - (void) setDisplayType:(NSInteger)dispType { NSString *newDispString = nil; - NSSize newSrcSize = NSMakeSize((CGFloat)GPU_DISPLAY_WIDTH, (CGFloat)GPU_DISPLAY_HEIGHT); + NSSize newFrameSize = NSMakeSize((CGFloat)GPU_DISPLAY_WIDTH, (CGFloat)GPU_DISPLAY_HEIGHT); switch (dispType) { @@ -724,7 +719,7 @@ GPU3DInterface *core3DList[] = { case DS_DISPLAY_TYPE_COMBO: newDispString = NSSTRING_DISPLAYMODE_COMBO; - newSrcSize.height *= 2; + newFrameSize.height *= 2; break; default: @@ -734,13 +729,10 @@ GPU3DInterface *core3DList[] = { OSSpinLockLock(&spinlockDisplayType); displayType = dispType; + frameSize = newFrameSize; [property setValue:[NSNumber numberWithInteger:dispType] forKey:@"displayMode"]; [property setValue:newDispString forKey:@"displayModeString"]; OSSpinLockUnlock(&spinlockDisplayType); - - OSSpinLockLock(&spinlockVfSrcBuffer); - [vf setSourceSize:newSrcSize]; - OSSpinLockUnlock(&spinlockVfSrcBuffer); } - (NSInteger) displayType @@ -752,23 +744,13 @@ GPU3DInterface *core3DList[] = { return dispType; } -- (void) setVfType:(NSInteger)videoFilterTypeID +- (NSSize) frameSize { - [vf changeFilter:(VideoFilterTypeID)videoFilterTypeID]; + OSSpinLockLock(&spinlockDisplayType); + NSSize size = frameSize; + OSSpinLockUnlock(&spinlockDisplayType); - OSSpinLockLock(&spinlockVideoFilterType); - [property setValue:[NSNumber numberWithInteger:videoFilterTypeID] forKey:@"videoFilterType"]; - [property setValue:NSLocalizedString([vf typeString], nil) forKey:@"videoFilterTypeString"]; - OSSpinLockUnlock(&spinlockVideoFilterType); -} - -- (NSInteger) vfType -{ - OSSpinLockLock(&spinlockVideoFilterType); - NSInteger theType = [(NSNumber *)[property valueForKey:@"videoFilterType"] integerValue]; - OSSpinLockUnlock(&spinlockVideoFilterType); - - return theType; + return size; } - (void) setRender3DRenderingEngine:(NSInteger)methodID @@ -943,15 +925,14 @@ GPU3DInterface *core3DList[] = { } pthread_mutex_lock(self.mutexProducer); - CommonSettings.num_cores = numberCores; - pthread_mutex_unlock(self.mutexProducer); + CommonSettings.num_cores = numberCores; if ([self render3DRenderingEngine] == CORE3DLIST_SWRASTERIZE) { - pthread_mutex_lock(self.mutexProducer); NDS_3D_ChangeCore(CORE3DLIST_SWRASTERIZE); - pthread_mutex_unlock(self.mutexProducer); } + + pthread_mutex_unlock(self.mutexProducer); } - (NSUInteger) render3DThreads @@ -989,15 +970,6 @@ GPU3DInterface *core3DList[] = { return state; } -- (void) runThread:(id)object -{ - NSAutoreleasePool *tempPool = [[NSAutoreleasePool alloc] init]; - [delegate doInitVideoOutput:self.property]; - [tempPool release]; - - [super runThread:object]; -} - - (void) doCoreEmuFrame { NSData *gpuData = nil; @@ -1037,14 +1009,6 @@ GPU3DInterface *core3DList[] = { [self handleEmuFrameProcessed:[messageComponents objectAtIndex:0]]; break; - case MESSAGE_RESIZE_VIEW: - [self handleResizeView:[messageComponents objectAtIndex:0]]; - break; - - case MESSAGE_REDRAW_VIEW: - [self handleRedrawView]; - break; - case MESSAGE_SET_GPU_STATE_FLAGS: [self handleChangeGpuStateFlags:[messageComponents objectAtIndex:0]]; break; @@ -1053,26 +1017,6 @@ GPU3DInterface *core3DList[] = { [self handleChangeDisplayType:[messageComponents objectAtIndex:0]]; break; - case MESSAGE_CHANGE_DISPLAY_ORIENTATION: - [self handleChangeDisplayOrientation:[messageComponents objectAtIndex:0]]; - break; - - case MESSAGE_CHANGE_DISPLAY_ORDER: - [self handleChangeDisplayOrder:[messageComponents objectAtIndex:0]]; - break; - - case MESSAGE_CHANGE_BILINEAR_OUTPUT: - [self handleChangeBilinearOutput:[messageComponents objectAtIndex:0]]; - break; - - case MESSAGE_CHANGE_VERTICAL_SYNC: - [self handleChangeVerticalSync:[messageComponents objectAtIndex:0]]; - break; - - case MESSAGE_CHANGE_VIDEO_FILTER: - [self handleChangeVideoFilter:[messageComponents objectAtIndex:0]]; - break; - case MESSAGE_SET_RENDER3D_METHOD: [self handleSetRender3DRenderingEngine:[messageComponents objectAtIndex:0]]; break; @@ -1129,47 +1073,9 @@ GPU3DInterface *core3DList[] = { - (void) handleEmuFrameProcessed:(NSData *)theData { - // Tell the video output object to process the video frame with our copied GPU data. - if ([vf typeID] == VideoFilterTypeID_None) - { - [delegate doProcessVideoFrame:[theData bytes] frameSize:[vf destSize]]; - } - else - { - NSSize srcSize = [vf srcSize]; - - OSSpinLockLock(&spinlockVfSrcBuffer); - RGBA5551ToRGBA8888Buffer((const uint16_t *)[theData bytes], (uint32_t *)[vf srcBufferPtr], ((unsigned int)srcSize.width * (unsigned int)srcSize.height)); - OSSpinLockUnlock(&spinlockVfSrcBuffer); - - const UInt32 *vfDestBufferPtr = [vf runFilter]; - [delegate doProcessVideoFrame:vfDestBufferPtr frameSize:[vf destSize]]; - } - [super handleEmuFrameProcessed:theData]; } -- (void) handleResizeView:(NSData *)rectData -{ - if (delegate == nil || ![delegate respondsToSelector:@selector(doResizeView:)]) - { - return; - } - - const NSRect *resizeRect = (NSRect *)[rectData bytes]; - [delegate doResizeView:*resizeRect]; -} - -- (void) handleRedrawView -{ - if (delegate == nil || ![delegate respondsToSelector:@selector(doRedraw)]) - { - return; - } - - [delegate doRedraw]; -} - - (void) handleChangeGpuStateFlags:(NSData *)flagsData { const NSInteger *flags = (NSInteger *)[flagsData bytes]; @@ -1189,64 +1095,6 @@ GPU3DInterface *core3DList[] = { [delegate doDisplayTypeChanged:*theType]; } -- (void) handleChangeDisplayOrientation:(NSData *)displayOrientationIdData -{ - if (delegate == nil || ![delegate respondsToSelector:@selector(doDisplayOrientationChanged:)]) - { - return; - } - - const NSInteger *theOrientation = (NSInteger *)[displayOrientationIdData bytes]; - [delegate doDisplayOrientationChanged:*theOrientation]; -} - -- (void) handleChangeDisplayOrder:(NSData *)displayOrderIdData -{ - if (delegate == nil || ![delegate respondsToSelector:@selector(doDisplayOrderChanged:)]) - { - return; - } - - const NSInteger *theOrder = (NSInteger *)[displayOrderIdData bytes]; - [delegate doDisplayOrderChanged:*theOrder]; -} - -- (void) handleChangeBilinearOutput:(NSData *)bilinearStateData -{ - if (delegate == nil || ![delegate respondsToSelector:@selector(doBilinearOutputChanged:)]) - { - return; - } - - const BOOL *theState = (BOOL *)[bilinearStateData bytes]; - [delegate doBilinearOutputChanged:*theState]; - [self handleEmuFrameProcessed:self.frameData]; -} - -- (void) handleChangeVerticalSync:(NSData *)verticalSyncStateData -{ - if (delegate == nil || ![delegate respondsToSelector:@selector(doVerticalSyncChanged:)]) - { - return; - } - - const BOOL *theState = (BOOL *)[verticalSyncStateData bytes]; - [delegate doVerticalSyncChanged:*theState]; -} - -- (void) handleChangeVideoFilter:(NSData *)videoFilterTypeIdData -{ - if (delegate == nil || ![delegate respondsToSelector:@selector(doVideoFilterChanged:)]) - { - return; - } - - const NSInteger *theType = (NSInteger *)[videoFilterTypeIdData bytes]; - [self setVfType:*theType]; - [delegate doVideoFilterChanged:*theType]; - [self handleEmuFrameProcessed:self.frameData]; -} - - (void) handleSetRender3DRenderingEngine:(NSData *)methodIdData { const NSInteger *methodID = (NSInteger *)[methodIdData bytes]; @@ -1356,7 +1204,7 @@ GPU3DInterface *core3DList[] = { - (NSImage *) image { - NSImage *newImage = [[NSImage alloc] initWithSize:[vf srcSize]]; + NSImage *newImage = [[NSImage alloc] initWithSize:self.frameSize]; if (newImage == nil) { return newImage; @@ -1384,7 +1232,7 @@ GPU3DInterface *core3DList[] = { return nil; } - NSSize srcSize = [vf srcSize]; + NSSize srcSize = self.frameSize; NSUInteger w = (NSUInteger)srcSize.width; NSUInteger h = (NSUInteger)srcSize.height; NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL @@ -1519,6 +1367,269 @@ GPU3DInterface *core3DList[] = { @end +@implementation CocoaDSDisplayVideo + +@synthesize vf; + +- (id)init +{ + self = [super init]; + if (self == nil) + { + return self; + } + + videoDelegate = nil; + + spinlockVideoFilterType = OS_SPINLOCK_INIT; + spinlockVfSrcBuffer = OS_SPINLOCK_INIT; + + vf = [[CocoaVideoFilter alloc] initWithSize:frameSize typeID:VideoFilterTypeID_None numberThreads:2]; + + [property setValue:[NSNumber numberWithInteger:(NSInteger)VideoFilterTypeID_None] forKey:@"videoFilterType"]; + [property setValue:[CocoaVideoFilter typeStringByID:VideoFilterTypeID_None] forKey:@"videoFilterTypeString"]; + + return self; +} + +- (void)dealloc +{ + [vf release]; + + [super dealloc]; +} + +- (void) setDelegate:(id )theDelegate +{ + OSSpinLockLock(&spinlockDelegate); + + if (theDelegate == videoDelegate) + { + OSSpinLockUnlock(&spinlockDelegate); + return; + } + + if (theDelegate != nil) + { + [theDelegate retain]; + [theDelegate setSendPortDisplay:self.receivePort]; + } + + [videoDelegate release]; + videoDelegate = theDelegate; + + OSSpinLockUnlock(&spinlockDelegate); + + [super setDelegate:theDelegate]; +} + +- (id ) delegate +{ + OSSpinLockLock(&spinlockDelegate); + id theDelegate = videoDelegate; + OSSpinLockUnlock(&spinlockDelegate); + + return theDelegate; +} + +- (void) setDisplayType:(NSInteger)dispType +{ + [super setDisplayType:dispType]; + + OSSpinLockLock(&spinlockVfSrcBuffer); + [vf setSourceSize:self.frameSize]; + OSSpinLockUnlock(&spinlockVfSrcBuffer); +} + +- (void) setVfType:(NSInteger)videoFilterTypeID +{ + [vf changeFilter:(VideoFilterTypeID)videoFilterTypeID]; + + OSSpinLockLock(&spinlockVideoFilterType); + [property setValue:[NSNumber numberWithInteger:videoFilterTypeID] forKey:@"videoFilterType"]; + [property setValue:NSLocalizedString([vf typeString], nil) forKey:@"videoFilterTypeString"]; + OSSpinLockUnlock(&spinlockVideoFilterType); +} + +- (NSInteger) vfType +{ + OSSpinLockLock(&spinlockVideoFilterType); + NSInteger theType = [(NSNumber *)[property valueForKey:@"videoFilterType"] integerValue]; + OSSpinLockUnlock(&spinlockVideoFilterType); + + return theType; +} + +- (void) runThread:(id)object +{ + NSAutoreleasePool *tempPool = [[NSAutoreleasePool alloc] init]; + [videoDelegate doInitVideoOutput:self.property]; + [tempPool release]; + + [super runThread:object]; +} + +- (void)handlePortMessage:(NSPortMessage *)portMessage +{ + NSInteger message = (NSInteger)[portMessage msgid]; + NSArray *messageComponents = [portMessage components]; + + switch (message) + { + case MESSAGE_EMU_FRAME_PROCESSED: + [self handleEmuFrameProcessed:[messageComponents objectAtIndex:0]]; + break; + + case MESSAGE_RESIZE_VIEW: + [self handleResizeView:[messageComponents objectAtIndex:0]]; + break; + + case MESSAGE_REDRAW_VIEW: + [self handleRedrawView]; + break; + + case MESSAGE_CHANGE_DISPLAY_ORIENTATION: + [self handleChangeDisplayOrientation:[messageComponents objectAtIndex:0]]; + break; + + case MESSAGE_CHANGE_DISPLAY_ORDER: + [self handleChangeDisplayOrder:[messageComponents objectAtIndex:0]]; + break; + + case MESSAGE_CHANGE_BILINEAR_OUTPUT: + [self handleChangeBilinearOutput:[messageComponents objectAtIndex:0]]; + break; + + case MESSAGE_CHANGE_VERTICAL_SYNC: + [self handleChangeVerticalSync:[messageComponents objectAtIndex:0]]; + break; + + case MESSAGE_CHANGE_VIDEO_FILTER: + [self handleChangeVideoFilter:[messageComponents objectAtIndex:0]]; + break; + + default: + [super handlePortMessage:portMessage]; + break; + } +} + +- (void) handleEmuFrameProcessed:(NSData *)theData +{ + if (theData == nil) + { + return; + } + + NSSize destSize = [vf destSize]; + size_t dataSize = (size_t)destSize.width * (size_t)destSize.height * sizeof(UInt32); + if ([vf typeID] == VideoFilterTypeID_None) + { + destSize = self.frameSize; + dataSize = (size_t)destSize.width * (size_t)destSize.height * sizeof(UInt16); + } + + // Tell the video delegate to process the video frame with our copied GPU data. + if ([vf typeID] == VideoFilterTypeID_None) + { + [videoDelegate doProcessVideoFrame:[theData bytes] frameSize:self.frameSize]; + } + else + { + NSSize srcSize = [vf srcSize]; + + OSSpinLockLock(&spinlockVfSrcBuffer); + RGBA5551ToRGBA8888Buffer((const uint16_t *)[theData bytes], (uint32_t *)[vf srcBufferPtr], ((unsigned int)srcSize.width * (unsigned int)srcSize.height)); + OSSpinLockUnlock(&spinlockVfSrcBuffer); + + UInt32 *vfDestBuffer = [vf runFilter]; + [videoDelegate doProcessVideoFrame:vfDestBuffer frameSize:[vf destSize]]; + } + + [super handleEmuFrameProcessed:theData]; +} + +- (void) handleResizeView:(NSData *)rectData +{ + if (videoDelegate == nil || ![videoDelegate respondsToSelector:@selector(doResizeView:)]) + { + return; + } + + const NSRect *resizeRect = (NSRect *)[rectData bytes]; + [videoDelegate doResizeView:*resizeRect]; +} + +- (void) handleRedrawView +{ + if (videoDelegate == nil || ![videoDelegate respondsToSelector:@selector(doRedraw)]) + { + return; + } + + [videoDelegate doRedraw]; +} + +- (void) handleChangeDisplayOrientation:(NSData *)displayOrientationIdData +{ + if (videoDelegate == nil || ![videoDelegate respondsToSelector:@selector(doDisplayOrientationChanged:)]) + { + return; + } + + const NSInteger *theOrientation = (NSInteger *)[displayOrientationIdData bytes]; + [videoDelegate doDisplayOrientationChanged:*theOrientation]; +} + +- (void) handleChangeDisplayOrder:(NSData *)displayOrderIdData +{ + if (videoDelegate == nil || ![videoDelegate respondsToSelector:@selector(doDisplayOrderChanged:)]) + { + return; + } + + const NSInteger *theOrder = (NSInteger *)[displayOrderIdData bytes]; + [videoDelegate doDisplayOrderChanged:*theOrder]; +} + +- (void) handleChangeBilinearOutput:(NSData *)bilinearStateData +{ + if (videoDelegate == nil || ![videoDelegate respondsToSelector:@selector(doBilinearOutputChanged:)]) + { + return; + } + + const BOOL *theState = (BOOL *)[bilinearStateData bytes]; + [videoDelegate doBilinearOutputChanged:*theState]; + [self handleEmuFrameProcessed:self.frameData]; +} + +- (void) handleChangeVerticalSync:(NSData *)verticalSyncStateData +{ + if (videoDelegate == nil || ![videoDelegate respondsToSelector:@selector(doVerticalSyncChanged:)]) + { + return; + } + + const BOOL *theState = (BOOL *)[verticalSyncStateData bytes]; + [videoDelegate doVerticalSyncChanged:*theState]; +} + +- (void) handleChangeVideoFilter:(NSData *)videoFilterTypeIdData +{ + if (videoDelegate == nil || ![videoDelegate respondsToSelector:@selector(doVideoFilterChanged:frameSize:)]) + { + return; + } + + const NSInteger *theType = (NSInteger *)[videoFilterTypeIdData bytes]; + [self setVfType:*theType]; + [videoDelegate doVideoFilterChanged:*theType frameSize:[vf destSize]]; + [self handleEmuFrameProcessed:self.frameData]; +} + +@end + void HandleMessageEchoResponse(NSPortMessage *portMessage) { NSPortMessage *echo = [[NSPortMessage alloc] initWithSendPort:[portMessage receivePort] receivePort:[portMessage sendPort] components:nil]; diff --git a/desmume/src/cocoa/userinterface/appDelegate.mm b/desmume/src/cocoa/userinterface/appDelegate.mm index 66a8fd4d7..e3e66d567 100644 --- a/desmume/src/cocoa/userinterface/appDelegate.mm +++ b/desmume/src/cocoa/userinterface/appDelegate.mm @@ -181,9 +181,9 @@ [newDispViewDelegate setCdsController:newController]; // Init the DS displays. - CocoaDSDisplay *newComboDisplay = [[[CocoaDSDisplay alloc] init] autorelease]; - [newComboDisplay setDelegate:newDispViewDelegate]; - [newCore addOutput:newComboDisplay]; + CocoaDSDisplayVideo *newVideoDisplay = [[[CocoaDSDisplayVideo alloc] init] autorelease]; + [newVideoDisplay setDelegate:newDispViewDelegate]; + [newCore addOutput:newVideoDisplay]; NSPort *guiPort = [NSPort port]; [[NSRunLoop currentRunLoop] addPort:guiPort forMode:NSDefaultRunLoopMode]; @@ -202,11 +202,11 @@ } // Start up the threads for our outputs. - [NSThread detachNewThreadSelector:@selector(runThread:) toTarget:newComboDisplay withObject:nil]; + [NSThread detachNewThreadSelector:@selector(runThread:) toTarget:newVideoDisplay withObject:nil]; [NSThread detachNewThreadSelector:@selector(runThread:) toTarget:newSpeaker withObject:nil]; // Wait until the GPU and SPU are finished starting up. - while ([newComboDisplay thread] == nil || [newSpeaker thread] == nil) + while ([newVideoDisplay thread] == nil || [newSpeaker thread] == nil) { [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]]; } diff --git a/desmume/src/cocoa/userinterface/displayView.h b/desmume/src/cocoa/userinterface/displayView.h index cfaed29f8..279f01f74 100644 --- a/desmume/src/cocoa/userinterface/displayView.h +++ b/desmume/src/cocoa/userinterface/displayView.h @@ -42,11 +42,11 @@ - (void) doDisplayOrderChanged:(NSInteger)displayOrderID; - (void) doBilinearOutputChanged:(BOOL)useBilinear; - (void) doVerticalSyncChanged:(BOOL)useVerticalSync; -- (void) doVideoFilterChanged:(NSInteger)videoFilterTypeID; +- (void) doVideoFilterChanged:(NSInteger)videoFilterTypeID frameSize:(NSSize)videoFilterDestSize; @end -@interface DisplayViewDelegate : NSObject +@interface DisplayViewDelegate : NSObject { NSView *view; NSPort *sendPortDisplay; @@ -130,14 +130,14 @@ GLfloat swRasterizerMainVertex[4][2]; GLfloat swRasterizerTouchTexCoord[4][2]; GLfloat swRasterizerTouchVertex[4][2]; + GLuint swRasterizerDisplayListIndex; } - (void) drawVideoFrame; -- (void) uploadSWRasterizerTexturesUsingSize:(NSSize)textureSize - mainBytes:(const GLvoid *)mainBytes - touchBytes:(const GLvoid *)touchBytes; +- (void) uploadSWRasterizerTextureData:(const GLvoid *)textureData textureSize:(NSSize)textureSize; - (void) renderSWRasterizer; - (void) setupSWRasterizerVertices; +- (void) updateDisplayLists; @end diff --git a/desmume/src/cocoa/userinterface/displayView.mm b/desmume/src/cocoa/userinterface/displayView.mm index 1715d0a11..6300f5595 100644 --- a/desmume/src/cocoa/userinterface/displayView.mm +++ b/desmume/src/cocoa/userinterface/displayView.mm @@ -650,14 +650,14 @@ NSOpenGLContext *OSXDefaultOpenGLContext = nil; [view doVerticalSyncChanged:useVerticalSync]; } -- (void) doVideoFilterChanged:(NSInteger)videoFilterTypeID +- (void) doVideoFilterChanged:(NSInteger)videoFilterTypeID frameSize:(NSSize)videoFilterDestSize { - if (view == nil || ![view respondsToSelector:@selector(doVideoFilterChanged:)]) + if (view == nil || ![view respondsToSelector:@selector(doVideoFilterChanged:frameSize:)]) { return; } - [view doVideoFilterChanged:videoFilterTypeID]; + [view doVideoFilterChanged:videoFilterTypeID frameSize:videoFilterDestSize]; } @end @@ -902,14 +902,45 @@ NSOpenGLContext *OSXDefaultOpenGLContext = nil; glTexBackSize = NSMakeSize(w, h); OSXDefaultOpenGLContext = [[self openGLContext] retain]; + + NSOpenGLContext *prevContext = [NSOpenGLContext currentContext]; [OSXDefaultOpenGLContext makeCurrentContext]; + glGenTextures(2, swRasterizerDrawTexture); + swRasterizerDisplayListIndex = glGenLists(3); + + SetOpenGLRendererFunctions(&OSXOpenGLRendererInit, + &OSXOpenGLRendererBegin, + &OSXOpenGLRendererEnd); + + if (prevContext != nil) + { + [prevContext makeCurrentContext]; + } + else + { + [NSOpenGLContext clearCurrentContext]; + } + return self; } - (void)dealloc { - [NSOpenGLContext clearCurrentContext]; + NSOpenGLContext *prevContext = [NSOpenGLContext currentContext]; + [[self openGLContext] makeCurrentContext]; + + glDeleteTextures(2, swRasterizerDrawTexture); + glDeleteLists(swRasterizerDisplayListIndex, 3); + + if (prevContext != nil) + { + [prevContext makeCurrentContext]; + } + else + { + [NSOpenGLContext clearCurrentContext]; + } free(glTexBack); glTexBack = NULL; @@ -950,12 +981,6 @@ NSOpenGLContext *OSXDefaultOpenGLContext = nil; glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glGenTextures(2, &swRasterizerDrawTexture[0]); - - SetOpenGLRendererFunctions(&OSXOpenGLRendererInit, - &OSXOpenGLRendererBegin, - &OSXOpenGLRendererEnd); } - (void) drawVideoFrame @@ -963,100 +988,75 @@ NSOpenGLContext *OSXDefaultOpenGLContext = nil; CGLFlushDrawable((CGLContextObj)[[self openGLContext] CGLContextObj]); } -- (void) uploadSWRasterizerTexturesUsingSize:(NSSize)textureSize - mainBytes:(const GLvoid *)mainBytes - touchBytes:(const GLvoid *)touchBytes +- (void) uploadSWRasterizerTextureData:(const GLvoid *)textureData textureSize:(NSSize)textureSize { - uint32_t w = GetNearestPositivePOT((uint32_t)textureSize.width); - uint32_t h = GetNearestPositivePOT((uint32_t)textureSize.height); + NSInteger displayType = [dispViewDelegate displayType]; - size_t bitDepth = sizeof(uint32_t); - - if (glTexPixelFormat == GL_UNSIGNED_SHORT_1_5_5_5_REV) + if (textureData == NULL) { - bitDepth = sizeof(uint16_t); + return; } - if (glTexBackSize.width != w || glTexBackSize.height != h) + switch (displayType) { - glTexBackSize.width = w; - glTexBackSize.height = h; - - free(glTexBack); - glTexBack = (GLvoid *)calloc((size_t)w * (size_t)h, bitDepth); - if (glTexBack == NULL) + case DS_DISPLAY_TYPE_MAIN: + glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[0]); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, (GLsizei)textureSize.width, (GLsizei)textureSize.height, GL_RGBA, glTexPixelFormat, textureData); + break; + + case DS_DISPLAY_TYPE_TOUCH: + glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[1]); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, (GLsizei)textureSize.width, (GLsizei)textureSize.height, GL_RGBA, glTexPixelFormat, textureData); + break; + + case DS_DISPLAY_TYPE_COMBO: { - return; + textureSize.height /= 2; + size_t offset = (size_t)textureSize.width * (size_t)textureSize.height; + + glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[0]); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, (GLsizei)textureSize.width, (GLsizei)textureSize.height, GL_RGBA, glTexPixelFormat, textureData); + + glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[1]); + if (glTexPixelFormat == GL_UNSIGNED_SHORT_1_5_5_5_REV) + { + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, (GLsizei)textureSize.width, (GLsizei)textureSize.height, GL_RGBA, glTexPixelFormat, (uint16_t *)textureData + offset); + } + else + { + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, (GLsizei)textureSize.width, (GLsizei)textureSize.height, GL_RGBA, glTexPixelFormat, (uint32_t *)textureData + offset); + } + + break; } + + default: + break; } - swRasterizerMainTexCoord[0][0] = 0.0f; - swRasterizerMainTexCoord[0][1] = 0.0f; - swRasterizerMainTexCoord[1][0] = (GLfloat)(textureSize.width / w); - swRasterizerMainTexCoord[1][1] = 0.0f; - swRasterizerMainTexCoord[2][0] = (GLfloat)(textureSize.width / w); - swRasterizerMainTexCoord[2][1] = (GLfloat)(textureSize.height / h); - swRasterizerMainTexCoord[3][0] = 0.0f; - swRasterizerMainTexCoord[3][1] = (GLfloat)(textureSize.height / h); - - swRasterizerTouchTexCoord[0][0] = 0.0f; - swRasterizerTouchTexCoord[0][1] = 0.0f; - swRasterizerTouchTexCoord[1][0] = (GLfloat)(textureSize.width / w); - swRasterizerTouchTexCoord[1][1] = 0.0f; - swRasterizerTouchTexCoord[2][0] = (GLfloat)(textureSize.width / w); - swRasterizerTouchTexCoord[2][1] = (GLfloat)(textureSize.height / h); - swRasterizerTouchTexCoord[3][0] = 0.0f; - swRasterizerTouchTexCoord[3][1] = (GLfloat)(textureSize.height / h); - - // 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, 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); + glBindTexture(GL_TEXTURE_2D, NULL); } - (void) renderSWRasterizer { NSInteger displayType = [dispViewDelegate displayType]; - glClear(GL_COLOR_BUFFER_BIT); - - // Render the main screen - if (displayType == DS_DISPLAY_TYPE_MAIN || displayType == DS_DISPLAY_TYPE_COMBO) + switch (displayType) { - glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[0]); - glBegin(GL_QUADS); - - for (unsigned int i = 0; i < 4; i++) - { - glTexCoord2f(swRasterizerMainTexCoord[i][0], swRasterizerMainTexCoord[i][1]); - glVertex2f(swRasterizerMainVertex[i][0], swRasterizerMainVertex[i][1]); - } - - glEnd(); - } - - // Render the touch screen - if (displayType == DS_DISPLAY_TYPE_TOUCH || displayType == DS_DISPLAY_TYPE_COMBO) - { - glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[1]); - glBegin(GL_QUADS); - - for (unsigned int i = 0; i < 4; i++) - { - glTexCoord2f(swRasterizerTouchTexCoord[i][0], swRasterizerTouchTexCoord[i][1]); - glVertex2f(swRasterizerTouchVertex[i][0], swRasterizerTouchVertex[i][1]); - } - - glEnd(); + case DS_DISPLAY_TYPE_MAIN: + glCallList(swRasterizerDisplayListIndex); + break; + + case DS_DISPLAY_TYPE_TOUCH: + glCallList(swRasterizerDisplayListIndex + 1); + break; + + case DS_DISPLAY_TYPE_COMBO: + glCallList(swRasterizerDisplayListIndex + 2); + break; + + default: + break; } } @@ -1158,7 +1158,7 @@ NSOpenGLContext *OSXDefaultOpenGLContext = nil; } } } - else + else // displayType == DS_DISPLAY_TYPE_MAIN || displayType == DS_DISPLAY_TYPE_TOUCH { swRasterizerMainVertex[0][0] = -w/2.0f; swRasterizerMainVertex[0][1] = h/2.0f; @@ -1180,6 +1180,71 @@ NSOpenGLContext *OSXDefaultOpenGLContext = nil; } } +- (void) updateDisplayLists +{ + // Main screen only + glNewList(swRasterizerDisplayListIndex, GL_COMPILE); + glClear(GL_COLOR_BUFFER_BIT); + + glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[0]); + glBegin(GL_QUADS); + + for (unsigned int i = 0; i < 4; i++) + { + glTexCoord2f(swRasterizerMainTexCoord[i][0], swRasterizerMainTexCoord[i][1]); + glVertex2f(swRasterizerMainVertex[i][0], swRasterizerMainVertex[i][1]); + } + + glEnd(); + glBindTexture(GL_TEXTURE_2D, NULL); + glEndList(); + + // Touch screen only + glNewList(swRasterizerDisplayListIndex + 1, GL_COMPILE); + glClear(GL_COLOR_BUFFER_BIT); + + glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[1]); + glBegin(GL_QUADS); + + for (unsigned int i = 0; i < 4; i++) + { + glTexCoord2f(swRasterizerTouchTexCoord[i][0], swRasterizerTouchTexCoord[i][1]); + glVertex2f(swRasterizerTouchVertex[i][0], swRasterizerTouchVertex[i][1]); + } + + glEnd(); + glBindTexture(GL_TEXTURE_2D, NULL); + glEndList(); + + // Combo screens + glNewList(swRasterizerDisplayListIndex + 2, GL_COMPILE); + glClear(GL_COLOR_BUFFER_BIT); + + glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[0]); + glBegin(GL_QUADS); + + for (unsigned int i = 0; i < 4; i++) + { + glTexCoord2f(swRasterizerMainTexCoord[i][0], swRasterizerMainTexCoord[i][1]); + glVertex2f(swRasterizerMainVertex[i][0], swRasterizerMainVertex[i][1]); + } + + glEnd(); + + glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[1]); + glBegin(GL_QUADS); + + for (unsigned int i = 0; i < 4; i++) + { + glTexCoord2f(swRasterizerTouchTexCoord[i][0], swRasterizerTouchTexCoord[i][1]); + glVertex2f(swRasterizerTouchVertex[i][0], swRasterizerTouchVertex[i][1]); + } + + glEnd(); + glBindTexture(GL_TEXTURE_2D, NULL); + glEndList(); +} + - (void)keyDown:(NSEvent *)theEvent { BOOL isHandled = [dispViewDelegate handleKeyPress:theEvent keyPressed:YES]; @@ -1292,10 +1357,9 @@ NSOpenGLContext *OSXDefaultOpenGLContext = nil; [[self openGLContext] makeCurrentContext]; SetupOpenGLView((GLsizei)rect.size.width, (GLsizei)rect.size.height, scale, rotation); + [[self openGLContext] update]; CGLUnlockContext((CGLContextObj)[[self openGLContext] CGLContextObj]); - - [dispViewDelegate setViewToBlack]; } - (void)doProcessVideoFrame:(const void *)videoFrameData frameSize:(NSSize)frameSize @@ -1304,44 +1368,7 @@ NSOpenGLContext *OSXDefaultOpenGLContext = nil; [[self openGLContext] makeCurrentContext]; - 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 uploadSWRasterizerTextureData:videoFrameData textureSize:frameSize]; [self renderSWRasterizer]; [self drawVideoFrame]; @@ -1359,6 +1386,7 @@ NSOpenGLContext *OSXDefaultOpenGLContext = nil; CGLUnlockContext((CGLContextObj)[[self openGLContext] CGLContextObj]); [self setupSWRasterizerVertices]; + [self updateDisplayLists]; } - (void)doRedraw @@ -1375,6 +1403,7 @@ NSOpenGLContext *OSXDefaultOpenGLContext = nil; - (void)doDisplayTypeChanged:(NSInteger)displayTypeID { [self setupSWRasterizerVertices]; + [self updateDisplayLists]; } - (void)doBilinearOutputChanged:(BOOL)useBilinear @@ -1384,16 +1413,28 @@ NSOpenGLContext *OSXDefaultOpenGLContext = nil; { glTexRenderStyle = GL_LINEAR; } + + glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glTexRenderStyle); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glTexRenderStyle); + + glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[1]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glTexRenderStyle); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glTexRenderStyle); + + glBindTexture(GL_TEXTURE_2D, NULL); } - (void) doDisplayOrientationChanged:(NSInteger)displayOrientationID { [self setupSWRasterizerVertices]; + [self updateDisplayLists]; } - (void) doDisplayOrderChanged:(NSInteger)displayOrderID { [self setupSWRasterizerVertices]; + [self updateDisplayLists]; if ([dispViewDelegate displayType] == DS_DISPLAY_TYPE_COMBO) { @@ -1413,13 +1454,67 @@ NSOpenGLContext *OSXDefaultOpenGLContext = nil; [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval]; } -- (void)doVideoFilterChanged:(NSInteger)videoFilterTypeID +- (void)doVideoFilterChanged:(NSInteger)videoFilterTypeID frameSize:(NSSize)videoFilterDestSize { + size_t colorDepth = sizeof(uint32_t); glTexPixelFormat = GL_UNSIGNED_INT_8_8_8_8_REV; + if (videoFilterTypeID == VideoFilterTypeID_None) { + colorDepth = sizeof(uint16_t); glTexPixelFormat = GL_UNSIGNED_SHORT_1_5_5_5_REV; } + + if ([dispViewDelegate displayType] == DS_DISPLAY_TYPE_COMBO) + { + videoFilterDestSize.height /= 2.0; + } + + uint32_t w = GetNearestPositivePOT((uint32_t)videoFilterDestSize.width); + uint32_t h = GetNearestPositivePOT((uint32_t)videoFilterDestSize.height); + + if (glTexBackSize.width != w || glTexBackSize.height != h) + { + glTexBackSize.width = w; + glTexBackSize.height = h; + + free(glTexBack); + glTexBack = (GLvoid *)calloc((size_t)w * (size_t)h, colorDepth); + if (glTexBack == NULL) + { + return; + } + } + + // Main screen + swRasterizerMainTexCoord[0][0] = 0.0f; + swRasterizerMainTexCoord[0][1] = 0.0f; + swRasterizerMainTexCoord[1][0] = (GLfloat)(videoFilterDestSize.width / w); + swRasterizerMainTexCoord[1][1] = 0.0f; + swRasterizerMainTexCoord[2][0] = (GLfloat)(videoFilterDestSize.width / w); + swRasterizerMainTexCoord[2][1] = (GLfloat)(videoFilterDestSize.height / h); + swRasterizerMainTexCoord[3][0] = 0.0f; + swRasterizerMainTexCoord[3][1] = (GLfloat)(videoFilterDestSize.height / h); + + glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (GLsizei)w, (GLsizei)h, 0, GL_RGBA, glTexPixelFormat, glTexBack); + + // Touch screen + swRasterizerTouchTexCoord[0][0] = 0.0f; + swRasterizerTouchTexCoord[0][1] = 0.0f; + swRasterizerTouchTexCoord[1][0] = (GLfloat)(videoFilterDestSize.width / w); + swRasterizerTouchTexCoord[1][1] = 0.0f; + swRasterizerTouchTexCoord[2][0] = (GLfloat)(videoFilterDestSize.width / w); + swRasterizerTouchTexCoord[2][1] = (GLfloat)(videoFilterDestSize.height / h); + swRasterizerTouchTexCoord[3][0] = 0.0f; + swRasterizerTouchTexCoord[3][1] = (GLfloat)(videoFilterDestSize.height / h); + + glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[1]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (GLsizei)w, (GLsizei)h, 0, GL_RGBA, glTexPixelFormat, glTexBack); + + glBindTexture(GL_TEXTURE_2D, NULL); + + [self updateDisplayLists]; } @end