# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1299810799 0 # Node ID b793008314957778b3c6e31cb8ca194745854995 # Parent e19f69a78f2135c36d8c0348f43073ab4a906557 Offload some drawing functions to the main thread to prevent focus deadlocks. diff -r e19f69a78f21 -r b79300831495 mac/dw.m --- a/mac/dw.m Fri Mar 11 01:49:09 2011 +0000 +++ b/mac/dw.m Fri Mar 11 02:33:19 2011 +0000 @@ -239,10 +239,25 @@ DWTID DWThread = (DWTID)-1; DWTID _dw_mutex_locked = (DWTID)-1; +/* Used for doing bitblts from the main thread */ +typedef struct _bitbltinfo +{ + id src; + id dest; + int xdest; + int ydest; + int width; + int height; + int xsrc; + int ysrc; +} DWBitBlt; + /* Subclass for a test object type */ @interface DWObject : NSObject {} -(void)uselessThread:(id)sender; -(void)synchronizeThread:(id)param; +-(void)doBitBlt:(id)param; +-(void)doFlush:(id)param; @end @implementation DWObject @@ -256,6 +271,41 @@ pthread_mutex_lock(DWRunMutex); //NSLog(@"Main thread reacquiring lock"); } +-(void)doBitBlt:(id)param +{ + NSValue *bi = (NSValue *)param; + DWBitBlt *bltinfo = (DWBitBlt *)[bi pointerValue]; + id bltdest = bltinfo->dest; + id bltsrc = bltinfo->src; + + if([bltdest isMemberOfClass:[NSImage class]]) + { + [bltdest lockFocus]; + } + else + { + [bltdest lockFocusIfCanDraw]; + _DWLastDrawable = bltinfo->dest; + } + if([bltsrc isMemberOfClass:[NSImage class]]) + { + NSImage *image = bltsrc; + [image drawAtPoint:NSMakePoint(bltinfo->xdest, bltinfo->ydest) fromRect:NSMakeRect(bltinfo->xsrc, bltinfo->ysrc, bltinfo->width, bltinfo->height) + operation:NSCompositeCopy fraction:1.0]; + [bltsrc release]; + } + [bltdest unlockFocus]; + free(bltinfo); +} +-(void)doFlush:(id)param +{ + if(_DWLastDrawable) + { + id object = _DWLastDrawable; + NSWindow *window = [object window]; + [window flushWindow]; + } +} @end DWObject *DWObj; @@ -4663,28 +4713,29 @@ */ void API dw_pixmap_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc) { - int _locked_by_me = FALSE; - DW_MUTEX_LOCK; - id bltdest = dest; - id bltsrc = src; - if(destp) - { - bltdest = (id)destp->handle; - [bltdest lockFocus]; - } - else - { - [bltdest lockFocusIfCanDraw]; - _DWLastDrawable = dest; - } - if(srcp) - { - bltsrc = (id)srcp->handle; - NSImage *image = bltsrc; - [image drawAtPoint:NSMakePoint(xdest, ydest) fromRect:NSMakeRect(xsrc, ysrc, width, height) operation:NSCompositeCopy fraction:1.0]; - } - [bltdest unlockFocus]; - DW_MUTEX_UNLOCK; + DWBitBlt *bltinfo = calloc(1, sizeof(DWBitBlt)); + NSValue* bi = [NSValue valueWithPointer:bltinfo]; + + /* Fill in the information */ + bltinfo->dest = dest; + bltinfo->src = src; + bltinfo->xdest = xdest; + bltinfo->ydest = ydest; + bltinfo->width = width; + bltinfo->height = height; + bltinfo->xsrc = xsrc; + bltinfo->ysrc = ysrc; + + if(destp) + { + bltinfo->dest = (id)destp->handle; + } + if(srcp) + { + id object = bltinfo->src = (id)srcp->handle; + [object retain]; + } + [DWObj performSelectorOnMainThread:@selector(doBitBlt:) withObject:bi waitUntilDone:YES]; } /* @@ -5960,15 +6011,7 @@ void API dw_flush(void) { /* This may need to be thread specific */ - if(_DWLastDrawable) - { - int _locked_by_me = FALSE; - DW_MUTEX_LOCK; - id object = _DWLastDrawable; - NSWindow *window = [object window]; - [window flushWindow]; - DW_MUTEX_UNLOCK; - } + [DWObj performSelectorOnMainThread:@selector(doFlush:) withObject:nil waitUntilDone:NO]; } /* Functions for managing the user data lists that are associated with