devdraw: fix for OS X 10.8 (Mountain Lion)

In MacOS 10.8, the NSBitmapImageRep class appears to cache the specified
image data at the time of construction. As a result updates to the
backing memimage object do not get pushed to the screen in flushimg.

This patch creates the NSBitmapImageRep object over again for each
flushimg which would appear to fix the problem.

R=rsc
CC=plan9port.codebot
http://codereview.appspot.com/6443063
diff --git a/src/cmd/devdraw/cocoa-screen.m b/src/cmd/devdraw/cocoa-screen.m
index 81ee039..f7a9dc6 100644
--- a/src/cmd/devdraw/cocoa-screen.m
+++ b/src/cmd/devdraw/cocoa-screen.m
@@ -95,10 +95,10 @@
 	int			isofs;
 	int			isnfs;
 	NSView		*content;
-	NSBitmapImageRep	*img;
 	int			needimg;
 	int			deferflush;
 	NSCursor		*cursor;
+        Memimage *memimage;
 } win;
 
 struct
@@ -348,7 +348,6 @@
 static Memimage*
 initimg(void)
 {
-	Memimage *i;
 	NSSize size;
 	Rectangle r;
 
@@ -356,32 +355,19 @@
 	LOG(@"initimg %.0f %.0f", size.width, size.height);
 
 	r = Rect(0, 0, size.width, size.height);
-	i = allocmemimage(r, XBGR32);
-	if(i == nil)
+	win.memimage = allocmemimage(r, XBGR32);
+	if(win.memimage == nil)
 		panic("allocmemimage: %r");
-	if(i->data == nil)
+	if(win.memimage->data == nil)
 		panic("i->data == nil");
 
-	win.img = [[NSBitmapImageRep alloc]
-		initWithBitmapDataPlanes:&i->data->bdata
-		pixelsWide:Dx(r)
-		pixelsHigh:Dy(r)
-		bitsPerSample:8
-		samplesPerPixel:3
-		hasAlpha:NO
-		isPlanar:NO
-		colorSpaceName:NSDeviceRGBColorSpace
-		bytesPerRow:bytesperline(r, 32)
-		bitsPerPixel:32];
-	return i;
+	return win.memimage;
 }
 
 static void
 resizeimg()
 {
-	[win.img release];
 	_drawreplacescreenimage(initimg());
-
 	mouseresized = 1;
 	sendmouse();
 }
@@ -441,7 +427,7 @@
 			@"waiting image", nil]];
 }
 
-static void drawimg(NSRect, uint);
+static void drawimg(NSBitmapImageRep*, NSRect, uint);
 static void drawresizehandle(void);
 
 enum
@@ -456,12 +442,17 @@
 flushimg(NSRect rect)
 {
 	NSRect dr, r;
+	NSBitmapImageRep *image;
+	Rectangle rrect;
+	NSSize size;
 
 	if([win.content lockFocusIfCanDraw] == 0)
 		return;
 
 	if(win.needimg){
-		if(!NSEqualSizes(rect.size, [win.img size])){
+	  size.width = win.memimage->r.max.x - win.memimage->r.min.x;
+	  size.height = win.memimage->r.max.y - win.memimage->r.min.y;
+		if(!NSEqualSizes(rect.size, size)){
 			LOG(@"flushimg reject %.0f %.0f",
 				rect.size.width, rect.size.height);
 			[win.content unlockFocus];
@@ -473,6 +464,24 @@
 
 	LOG(@"flushimg ok %.0f %.0f", rect.size.width, rect.size.height);
 
+
+	size = [win.content bounds].size;
+	LOG(@"initimg %.0f %.0f", size.width, size.height);
+	rrect = Rect(0, 0, size.width, size.height);
+
+	// FIXME: It is possible that we could do a smaller pixel copy here.
+	image = [[NSBitmapImageRep alloc]
+		initWithBitmapDataPlanes:&win.memimage->data->bdata
+		pixelsWide:Dx(rrect)
+		pixelsHigh:Dy(rrect)
+		bitsPerSample:8
+		samplesPerPixel:3
+		hasAlpha:NO
+		isPlanar:NO
+		colorSpaceName:NSDeviceRGBColorSpace
+		bytesPerRow:bytesperline(rrect, 32)
+		bitsPerPixel:32];
+
 	/*
 	 * Unless we are inside "drawRect", we have to round
 	 * the corners ourselves, if this is the custom.
@@ -484,25 +493,25 @@
 	r = [win.content bounds];
 	r.size.height -= Cornersize;
 	dr = NSIntersectionRect(r, rect);
-	drawimg(dr, NSCompositeCopy);
+	drawimg(image, dr, NSCompositeCopy);
 
 	r.origin.y = r.size.height;
 	r.size = NSMakeSize(Cornersize, Cornersize);
 	dr = NSIntersectionRect(r, rect);
-	drawimg(dr, NSCompositeSourceIn);
+	drawimg(image, dr, NSCompositeSourceIn);
 
-	r.origin.x = [win.img size].width - Cornersize;
+	r.origin.x = size.width - Cornersize;
 	dr = NSIntersectionRect(r, rect);
-	drawimg(dr, NSCompositeSourceIn);
+	drawimg(image, dr, NSCompositeSourceIn);
 
 	r.size.width = r.origin.x - Cornersize;
 	r.origin.x -= r.size.width;
 	dr = NSIntersectionRect(r, rect);
-	drawimg(dr, NSCompositeCopy);
+	drawimg(image, dr, NSCompositeCopy);
 
 	if(OSX_VERSION<100700 && win.isofs==0){
-		r.origin.x = [win.img size].width - Handlesize;
-		r.origin.y = [win.img size].height - Handlesize;
+		r.origin.x = size.width - Handlesize;
+		r.origin.y = size.height - Handlesize;
 		r.size = NSMakeSize(Handlesize, Handlesize);
 		if(NSIntersectsRect(r, rect))
 			drawresizehandle();
@@ -546,7 +555,7 @@
 }
 
 static void
-drawimg(NSRect dr, uint op)
+drawimg(NSBitmapImageRep* image, NSRect dr, uint op)
 {
 	NSRect sr;
 
@@ -555,7 +564,7 @@
 
 	sr =  [win.content convertRect:dr fromView:nil];
 
-	[win.img drawInRect:dr fromRect:sr
+	[image drawInRect:dr fromRect:sr
 		operation:op fraction:1
 		respectFlipped:YES hints:nil];
 
@@ -570,7 +579,7 @@
 	Point c;
 	int i,j;
 
-	c = Pt([win.img size].width, [win.img size].height);
+	c = Pt(win.memimage->r.max.x - win.memimage->r.min.x, win.memimage->r.max.y - win.memimage->r.min.y);
 
 	[[WIN graphicsContext] setShouldAntialias:NO];