aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Third2020-02-01 21:17:29 +0000
committerAlan Third2020-02-13 18:26:20 +0000
commit44298ea6aa006ed227e539b02279bd3fc11fd2a6 (patch)
treec6381b6fecb47fa8751662535e42f1727fc7945b
parenta13d1f953980b516470d03ab23250760c581c05b (diff)
downloademacs-44298ea6aa006ed227e539b02279bd3fc11fd2a6.tar.gz
emacs-44298ea6aa006ed227e539b02279bd3fc11fd2a6.zip
Use CGImage instead of NSBitmapImageRep (bug#32932)
* src/nsterm.m (ns_update_end): (ns_clear_frame): Remove forced draws. (ns_draw_fringe_bitmap): (ns_dumpglyphs_image): No longer need to invert images as the context is already flipped. ([EmacsView updateFrameSize:]): ([EmacsView initFrameFromEmacs:]): Use new function. ([EmacsView createDrawingBuffer]): Replaces createDrawingBufferWithRect:. ([EmacsView focusOnDrawingBuffer]): Set CGImage context. ([EmacsView windowDidChangeBackingProperties:]): Use new function. ([EmacsView copyRect:to:]): Copy using CGImages. ([EmacsView wantsUpdateLayer]): ([EmacsView updateLayer]): New Functions. ([EmacsView drawRect:]): We no longer do anything special here for Cocoa. ([EmacsView windowDidChangeBackingProperties:]): Fix indentation and add NSTRACE.
-rw-r--r--src/nsterm.h4
-rw-r--r--src/nsterm.m152
2 files changed, 90 insertions, 66 deletions
diff --git a/src/nsterm.h b/src/nsterm.h
index 980ca534cfa..7c6197f1288 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -418,7 +418,7 @@ typedef id instancetype;
418 NSWindow *nonfs_window; 418 NSWindow *nonfs_window;
419 BOOL fs_is_native; 419 BOOL fs_is_native;
420#ifdef NS_IMPL_COCOA 420#ifdef NS_IMPL_COCOA
421 NSBitmapImageRep *drawingBuffer; 421 CGContextRef drawingBuffer;
422#endif 422#endif
423@public 423@public
424 struct frame *emacsframe; 424 struct frame *emacsframe;
@@ -464,7 +464,7 @@ typedef id instancetype;
464- (void)focusOnDrawingBuffer; 464- (void)focusOnDrawingBuffer;
465#endif 465#endif
466- (void)copyRect:(NSRect)srcRect to:(NSRect)dstRect; 466- (void)copyRect:(NSRect)srcRect to:(NSRect)dstRect;
467- (void)createDrawingBufferWithRect:(NSRect)rect; 467- (void)createDrawingBuffer;
468 468
469/* Non-notification versions of NSView methods. Used for direct calls. */ 469/* Non-notification versions of NSView methods. Used for direct calls. */
470- (void)windowWillEnterFullScreen; 470- (void)windowWillEnterFullScreen;
diff --git a/src/nsterm.m b/src/nsterm.m
index 9d427b9b38d..2cf6774a1f1 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -1141,7 +1141,6 @@ ns_update_end (struct frame *f)
1141 1141
1142#ifdef NS_IMPL_COCOA 1142#ifdef NS_IMPL_COCOA
1143 [NSGraphicsContext setCurrentContext:nil]; 1143 [NSGraphicsContext setCurrentContext:nil];
1144 [view display];
1145#else 1144#else
1146 block_input (); 1145 block_input ();
1147 1146
@@ -2853,7 +2852,9 @@ ns_clear_frame (struct frame *f)
2853 ns_unfocus (f); 2852 ns_unfocus (f);
2854 2853
2855 /* as of 2006/11 or so this is now needed */ 2854 /* as of 2006/11 or so this is now needed */
2856 ns_redraw_scroll_bars (f); 2855 /* FIXME: I don't see any reason for this and removing it makes no
2856 difference here. Do we need it for GNUstep? */
2857 //ns_redraw_scroll_bars (f);
2857 unblock_input (); 2858 unblock_input ();
2858} 2859}
2859 2860
@@ -3169,18 +3170,6 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
3169 3170
3170 NSTRACE_RECT ("fromRect", fromRect); 3171 NSTRACE_RECT ("fromRect", fromRect);
3171 3172
3172 /* Because we're drawing into an offscreen buffer which isn't
3173 flipped, the images come out upside down. To work around it
3174 we need to do some fancy transforms. */
3175 {
3176 NSAffineTransform *transform = [NSAffineTransform transform];
3177 [transform translateXBy:0 yBy:NSMaxY(imageRect)];
3178 [transform scaleXBy:1 yBy:-1];
3179 [transform concat];
3180
3181 imageRect.origin.y = 0;
3182 }
3183
3184 [img drawInRect: imageRect 3173 [img drawInRect: imageRect
3185 fromRect: fromRect 3174 fromRect: fromRect
3186 operation: NSCompositingOperationSourceOver 3175 operation: NSCompositingOperationSourceOver
@@ -3938,11 +3927,6 @@ ns_dumpglyphs_image (struct glyph_string *s, NSRect r)
3938 3927
3939 NSAffineTransform *doTransform = [NSAffineTransform transform]; 3928 NSAffineTransform *doTransform = [NSAffineTransform transform];
3940 3929
3941 /* We have to flip the image around the X axis as the offscreen
3942 bitmap we're drawing to is flipped. */
3943 [doTransform scaleXBy:1 yBy:-1];
3944 [doTransform translateXBy:0 yBy:-[img size].height];
3945
3946 /* ImageMagick images don't have transforms. */ 3930 /* ImageMagick images don't have transforms. */
3947 if (img->transform) 3931 if (img->transform)
3948 [doTransform appendTransform:img->transform]; 3932 [doTransform appendTransform:img->transform];
@@ -7104,7 +7088,7 @@ not_in_argv (NSString *arg)
7104 from non-native fullscreen, in other circumstances it appears 7088 from non-native fullscreen, in other circumstances it appears
7105 to be a noop. (bug#28872) */ 7089 to be a noop. (bug#28872) */
7106 wr = NSMakeRect (0, 0, neww, newh); 7090 wr = NSMakeRect (0, 0, neww, newh);
7107 [self createDrawingBufferWithRect:wr]; 7091 [self createDrawingBuffer];
7108 [view setFrame: wr]; 7092 [view setFrame: wr];
7109 7093
7110 // To do: consider using [NSNotificationCenter postNotificationName:]. 7094 // To do: consider using [NSNotificationCenter postNotificationName:].
@@ -7444,7 +7428,7 @@ not_in_argv (NSString *arg)
7444 maximizing_resize = NO; 7428 maximizing_resize = NO;
7445#endif 7429#endif
7446 7430
7447 [self createDrawingBufferWithRect:r]; 7431 [self createDrawingBuffer];
7448 7432
7449 win = [[EmacsWindow alloc] 7433 win = [[EmacsWindow alloc]
7450 initWithContentRect: r 7434 initWithContentRect: r
@@ -8229,52 +8213,65 @@ not_in_argv (NSString *arg)
8229} 8213}
8230 8214
8231 8215
8232- (void)createDrawingBufferWithRect:(NSRect)rect 8216#ifdef NS_IMPL_COCOA
8233 /* Create and store a new NSBitmapImageRep for Emacs to draw 8217- (void)createDrawingBuffer
8234 into. 8218 /* Create and store a new CGGraphicsContext for Emacs to draw into.
8235 8219
8236 Drawing to an offscreen bitmap doesn't work in GNUstep as there's 8220 We can't do this in GNUstep as there's no equivalent, so under
8237 a bug in graphicsContextWithBitmapImageRep 8221 GNUstep we retain the old method of drawing direct to the
8238 (https://savannah.gnu.org/bugs/?38405). So under GNUstep we 8222 EmacsView. */
8239 retain the old method of drawing direct to the EmacsView. */
8240{ 8223{
8241#ifdef NS_IMPL_COCOA 8224 NSTRACE ("EmacsView createDrawingBuffer]");
8225
8226 NSGraphicsContext *screen;
8227 CGColorSpaceRef colorSpace = [[[self window] colorSpace] CGColorSpace];
8228 CGFloat scale = [[self window] backingScaleFactor];
8229 NSRect frame = [self frame];
8230
8242 if (drawingBuffer != nil) 8231 if (drawingBuffer != nil)
8243 [drawingBuffer release]; 8232 CGContextRelease (drawingBuffer);
8244 8233
8245 drawingBuffer = [[self bitmapImageRepForCachingDisplayInRect:rect] retain]; 8234 drawingBuffer = CGBitmapContextCreate (nil, NSWidth (frame) * scale, NSHeight (frame) * scale,
8246#endif 8235 8, 0, colorSpace,
8236 kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host);
8237
8238 /* This fixes the scale to match the backing scale factor, and flips the image. */
8239 CGContextTranslateCTM(drawingBuffer, 0, NSHeight (frame) * scale);
8240 CGContextScaleCTM(drawingBuffer, scale, -scale);
8247} 8241}
8248 8242
8249 8243
8250#ifdef NS_IMPL_COCOA
8251- (void)focusOnDrawingBuffer 8244- (void)focusOnDrawingBuffer
8252{ 8245{
8253 /* Creating the graphics context each time is very slow, but it 8246 NSTRACE ("EmacsView focusOnDrawingBuffer]");
8254 doesn't seem possible to cache and reuse it. */ 8247
8255 [NSGraphicsContext 8248 NSGraphicsContext *buf =
8256 setCurrentContext: 8249 [NSGraphicsContext
8257 [NSGraphicsContext graphicsContextWithBitmapImageRep:drawingBuffer]]; 8250 graphicsContextWithCGContext:drawingBuffer flipped:YES];
8251
8252 [NSGraphicsContext setCurrentContext:buf];
8258} 8253}
8259 8254
8260 8255
8261- (void)windowDidChangeBackingProperties:(NSNotification *)notification 8256- (void)windowDidChangeBackingProperties:(NSNotification *)notification
8262 /* Update the drawing buffer when the backing scale factor changes. */ 8257 /* Update the drawing buffer when the backing scale factor changes. */
8263{ 8258{
8264 CGFloat old = [[[notification userInfo] 8259 NSTRACE ("EmacsView windowDidChangeBackingProperties:]");
8260
8261 CGFloat old = [[[notification userInfo]
8265 objectForKey:@"NSBackingPropertyOldScaleFactorKey"] 8262 objectForKey:@"NSBackingPropertyOldScaleFactorKey"]
8266 doubleValue]; 8263 doubleValue];
8267 CGFloat new = [[self window] backingScaleFactor]; 8264 CGFloat new = [[self window] backingScaleFactor];
8268 8265
8269 if (old != new) 8266 if (old != new)
8270 { 8267 {
8271 NSRect frame = [self frame]; 8268 NSRect frame = [self frame];
8272 [self createDrawingBufferWithRect:frame]; 8269 [self createDrawingBuffer];
8273 ns_clear_frame (emacsframe); 8270 ns_clear_frame (emacsframe);
8274 expose_frame (emacsframe, 0, 0, NSWidth (frame), NSHeight (frame)); 8271 expose_frame (emacsframe, 0, 0, NSWidth (frame), NSHeight (frame));
8275 } 8272 }
8276} 8273}
8277#endif 8274#endif /* NS_IMPL_COCOA */
8278 8275
8279 8276
8280- (void)copyRect:(NSRect)srcRect to:(NSRect)dstRect 8277- (void)copyRect:(NSRect)srcRect to:(NSRect)dstRect
@@ -8284,13 +8281,31 @@ not_in_argv (NSString *arg)
8284 NSTRACE_RECT ("Destination", dstRect); 8281 NSTRACE_RECT ("Destination", dstRect);
8285 8282
8286#ifdef NS_IMPL_COCOA 8283#ifdef NS_IMPL_COCOA
8287 [drawingBuffer drawInRect:dstRect 8284 CGImageRef copy;
8288 fromRect:srcRect 8285 NSRect frame = [self frame];
8289 operation:NSCompositingOperationCopy 8286 NSAffineTransform *setOrigin = [NSAffineTransform transform];
8290 fraction:1.0 8287
8291 respectFlipped:NO 8288 [[NSGraphicsContext currentContext] saveGraphicsState];
8292 hints:nil]; 8289
8290 /* Set the clipping before messing with the buffer's
8291 orientation. */
8292 NSRectClip (dstRect);
8293
8294 /* Unflip the buffer as the copied image will be unflipped, and
8295 offset the top left so when we draw back into the buffer the
8296 correct part of the image is drawn. */
8297 CGContextScaleCTM(drawingBuffer, 1, -1);
8298 CGContextTranslateCTM(drawingBuffer, 0, -NSHeight (frame)
8299 - (NSMinY (dstRect) - NSMinY (srcRect)));
8300
8301 /* Take a copy of the buffer and then draw it back to the buffer,
8302 limited by the clipping rectangle. */
8303 copy = CGBitmapContextCreateImage (drawingBuffer);
8304 CGContextDrawImage (drawingBuffer, frame, copy);
8305
8306 CGImageRelease (copy);
8293 8307
8308 [[NSGraphicsContext currentContext] restoreGraphicsState];
8294 [self setNeedsDisplayInRect:dstRect]; 8309 [self setNeedsDisplayInRect:dstRect];
8295#else 8310#else
8296 hide_bell(); // Ensure the bell image isn't scrolled. 8311 hide_bell(); // Ensure the bell image isn't scrolled.
@@ -8304,6 +8319,24 @@ not_in_argv (NSString *arg)
8304} 8319}
8305 8320
8306 8321
8322#ifdef NS_IMPL_COCOA
8323- (BOOL)wantsUpdateLayer
8324{
8325 return YES;
8326}
8327
8328
8329- (void)updateLayer
8330{
8331 NSTRACE ("EmacsView updateLayer]");
8332
8333 CGImageRef contentsImage = CGBitmapContextCreateImage(drawingBuffer);
8334 [[self layer] setContents:(id)contentsImage];
8335 CGImageRelease(contentsImage);
8336}
8337#endif
8338
8339
8307- (void)drawRect: (NSRect)rect 8340- (void)drawRect: (NSRect)rect
8308{ 8341{
8309 NSTRACE ("[EmacsView drawRect:" NSTRACE_FMT_RECT "]", 8342 NSTRACE ("[EmacsView drawRect:" NSTRACE_FMT_RECT "]",
@@ -8312,14 +8345,6 @@ not_in_argv (NSString *arg)
8312 if (!emacsframe || !emacsframe->output_data.ns) 8345 if (!emacsframe || !emacsframe->output_data.ns)
8313 return; 8346 return;
8314 8347
8315#ifdef NS_IMPL_COCOA
8316 [drawingBuffer drawInRect:rect
8317 fromRect:rect
8318 operation:NSCompositingOperationSourceOver
8319 fraction:1
8320 respectFlipped:NO
8321 hints:nil];
8322#else
8323 int x = NSMinX (rect), y = NSMinY (rect); 8348 int x = NSMinX (rect), y = NSMinY (rect);
8324 int width = NSWidth (rect), height = NSHeight (rect); 8349 int width = NSWidth (rect), height = NSHeight (rect);
8325 8350
@@ -8327,7 +8352,6 @@ not_in_argv (NSString *arg)
8327 block_input (); 8352 block_input ();
8328 expose_frame (emacsframe, x, y, width, height); 8353 expose_frame (emacsframe, x, y, width, height);
8329 unblock_input (); 8354 unblock_input ();
8330#endif
8331} 8355}
8332 8356
8333 8357