# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1303308540 0 # Node ID c092eab43ae340638e09c4a5eff66c423ad8e458 # Parent 850b2e6cfeabc50f723bf26c308837b5542deba1 Experimental change to pixmap rendering. Switch from using NSImage to NSBitmapImageRef to store the image. This is closer to the core backing store used to display images. Using this I was able to avoid using lockFocus on the images and instead set the graphics context manually allowing us to draw directly on the backing image. However NSBitmapImageRef is a more simple format and didn't work with the flipped Y axis... so... I had to perform some voodoo to get the flipping to work with the graphics context. Not sure it is 100% right. diff -r 850b2e6cfeab -r c092eab43ae3 mac/dw.m --- a/mac/dw.m Tue Apr 19 08:24:52 2011 +0000 +++ b/mac/dw.m Wed Apr 20 14:09:00 2011 +0000 @@ -418,9 +418,14 @@ id bltdest = bltinfo->dest; id bltsrc = bltinfo->src; - if([bltdest isMemberOfClass:[NSImage class]]) - { - [bltdest lockFocus]; + if([bltdest isMemberOfClass:[NSBitmapImageRep class]]) + { + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext + graphicsContextWithBitmapImageRep:bltdest]]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext + graphicsContextWithGraphicsPort:[[NSGraphicsContext currentContext] graphicsPort] flipped:YES]]; + [[NSDictionary alloc] initWithObjectsAndKeys:bltdest, NSGraphicsContextDestinationAttributeName, nil]; } else { @@ -430,14 +435,33 @@ } _DWLastDrawable = bltinfo->dest; } - if([bltsrc isMemberOfClass:[NSImage class]]) - { - NSImage *image = bltsrc; + if([bltsrc isMemberOfClass:[NSBitmapImageRep class]]) + { + NSImage *image = [[NSImage alloc] initWithCGImage:[(NSBitmapImageRep *)bltsrc CGImage] size:NSZeroSize]; + // make a new transform: + NSAffineTransform *t = [NSAffineTransform transform]; + + // by scaling Y negatively, we effectively flip the image: + [t scaleXBy:1.0 yBy:-1.0]; + + // but we also have to translate it back by its height: + [t translateXBy:0.0 yBy:-bltinfo->height]; + + // apply the transform: + [t concat]; [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]; + [image release]; + } + if([bltdest isMemberOfClass:[NSBitmapImageRep class]]) + { + [NSGraphicsContext restoreGraphicsState]; + } + else + { + [bltdest unlockFocus]; + } free(bltinfo); } -(void)doFlush:(id)param @@ -4354,7 +4378,11 @@ if(pixmap) { image = (id)pixmap->image; - [image lockFocus]; + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext + graphicsContextWithBitmapImageRep:image]]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext + graphicsContextWithGraphicsPort:[[NSGraphicsContext currentContext] graphicsPort] flipped:YES]]; } else { @@ -4372,7 +4400,14 @@ [aPath moveToPoint:NSMakePoint(x, y)]; [aPath stroke]; - [image unlockFocus]; + if(pixmap) + { + [NSGraphicsContext restoreGraphicsState]; + } + else + { + [image unlockFocus]; + } DW_MUTEX_UNLOCK; } @@ -4393,7 +4428,11 @@ if(pixmap) { image = (id)pixmap->image; - [image lockFocus]; + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext + graphicsContextWithBitmapImageRep:image]]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext + graphicsContextWithGraphicsPort:[[NSGraphicsContext currentContext] graphicsPort] flipped:YES]]; } else { @@ -4413,7 +4452,14 @@ [aPath lineToPoint:NSMakePoint(x2, y2)]; [aPath stroke]; - [image unlockFocus]; + if(pixmap) + { + [NSGraphicsContext restoreGraphicsState]; + } + else + { + [image unlockFocus]; + } DW_MUTEX_UNLOCK; } @@ -4468,7 +4514,11 @@ font = [render font]; } image = (id)pixmap->image; - [image lockFocus]; + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext + graphicsContextWithBitmapImageRep:image]]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext + graphicsContextWithGraphicsPort:[[NSGraphicsContext currentContext] graphicsPort] flipped:YES]]; NSColor *fgcolor = pthread_getspecific(_dw_fg_color_key); NSColor *bgcolor = pthread_getspecific(_dw_bg_color_key); NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:fgcolor, NSForegroundColorAttributeName, nil]; @@ -4481,7 +4531,7 @@ [dict setValue:font forKey:NSFontAttributeName]; } [nstr drawAtPoint:NSMakePoint(x, y) withAttributes:dict]; - [image unlockFocus]; + [NSGraphicsContext restoreGraphicsState]; [dict release]; } DW_MUTEX_UNLOCK; @@ -4544,7 +4594,11 @@ if(pixmap) { image = (id)pixmap->image; - [image lockFocus]; + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext + graphicsContextWithBitmapImageRep:image]]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext + graphicsContextWithGraphicsPort:[[NSGraphicsContext currentContext] graphicsPort] flipped:YES]]; } else { @@ -4571,7 +4625,14 @@ [aPath fill]; } [aPath stroke]; - [image unlockFocus]; + if(pixmap) + { + [NSGraphicsContext restoreGraphicsState]; + } + else + { + [image unlockFocus]; + } DW_MUTEX_UNLOCK; } @@ -4593,7 +4654,11 @@ if(pixmap) { image = (id)pixmap->image; - [image lockFocus]; + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext + graphicsContextWithBitmapImageRep:image]]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext + graphicsContextWithGraphicsPort:[[NSGraphicsContext currentContext] graphicsPort] flipped:YES]]; } else { @@ -4617,7 +4682,14 @@ if(fill) [aPath fill]; [aPath stroke]; - [image unlockFocus]; + if(pixmap) + { + [NSGraphicsContext restoreGraphicsState]; + } + else + { + [image unlockFocus]; + } DW_MUTEX_UNLOCK; } @@ -5728,7 +5800,6 @@ */ HPIXMAP API dw_pixmap_new(HWND handle, unsigned long width, unsigned long height, int depth) { - NSSize size = { (float)width, (float)height }; HPIXMAP pixmap; if(!(pixmap = calloc(1,sizeof(struct _hpixmap)))) @@ -5736,8 +5807,18 @@ pixmap->width = width; pixmap->height = height; pixmap->handle = handle; - NSImage *image = pixmap->image = [[NSImage alloc] initWithSize:size]; - [image setFlipped:YES]; + id image = pixmap->image = [[NSBitmapImageRep alloc] + initWithBitmapDataPlanes:NULL + pixelsWide:width + pixelsHigh:height + bitsPerSample:8 + samplesPerPixel:4 + hasAlpha:YES + isPlanar:NO + colorSpaceName:@"NSCalibratedRGBColorSpace" + bytesPerRow:0 + bitsPerPixel:0]; + [image retain]; return pixmap; } @@ -5758,18 +5839,17 @@ if(!(pixmap = calloc(1,sizeof(struct _hpixmap)))) return NULL; NSString *nstr = [ NSString stringWithUTF8String:filename ]; - NSImage *image = [[NSImage alloc] initWithContentsOfFile:nstr]; + NSBitmapImageRep *image = [[NSBitmapImageRep alloc] initWithContentsOfFile:nstr]; if(!image) { nstr = [nstr stringByAppendingString:@".png"]; - image = [[NSImage alloc] initWithContentsOfFile:nstr]; + image = [[NSBitmapImageRep alloc] initWithContentsOfFile:nstr]; } NSSize size = [image size]; pixmap->width = size.width; pixmap->height = size.height; pixmap->image = image; pixmap->handle = handle; - [image setFlipped:YES]; return pixmap; } @@ -5790,13 +5870,12 @@ if(!(pixmap = calloc(1,sizeof(struct _hpixmap)))) return NULL; NSData *thisdata = [NSData dataWithBytes:data length:len]; - NSImage *image = [[NSImage alloc] initWithData:thisdata]; + NSBitmapImageRep *image = [[NSBitmapImageRep alloc] initWithData:thisdata]; NSSize size = [image size]; pixmap->width = size.width; pixmap->height = size.height; pixmap->image = image; pixmap->handle = handle; - [image setFlipped:YES]; return pixmap; } @@ -5832,13 +5911,12 @@ NSBundle *bundle = [NSBundle mainBundle]; NSString *respath = [bundle resourcePath]; NSString *filepath = [respath stringByAppendingFormat:@"/%u.png", resid]; - NSImage *image = [[NSImage alloc] initWithContentsOfFile:filepath]; + NSBitmapImageRep *image = [[NSBitmapImageRep alloc] initWithContentsOfFile:filepath]; NSSize size = [image size]; pixmap->width = size.width; pixmap->height = size.height; pixmap->image = image; pixmap->handle = handle; - [image setFlipped:YES]; return pixmap; } @@ -5850,8 +5928,8 @@ */ void API dw_pixmap_destroy(HPIXMAP pixmap) { - NSImage *image = (NSImage *)pixmap->image; - [image dealloc]; + NSBitmapImageRep *image = (NSBitmapImageRep *)pixmap->image; + [image release]; free(pixmap); }