OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #import "SkNSView.h" | 9 #import "SkNSView.h" |
10 #include "SkCanvas.h" | 10 #include "SkCanvas.h" |
11 #include "SkCGUtils.h" | 11 #include "SkCGUtils.h" |
12 #include "SkEvent.h" | 12 #include "SkEvent.h" |
13 SK_COMPILE_ASSERT(SK_SUPPORT_GPU, not_implemented_for_non_gpu_build); | 13 SK_COMPILE_ASSERT(SK_SUPPORT_GPU, not_implemented_for_non_gpu_build); |
14 | 14 |
15 //#define FORCE_REDRAW | 15 //#define FORCE_REDRAW |
| 16 // Can be dropped when we no longer support 10.6. |
| 17 #define RETINA_API_AVAILABLE (defined(MAC_OS_X_VERSION_10_7) && \ |
| 18 MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_1
0_7) |
16 @implementation SkNSView | 19 @implementation SkNSView |
17 @synthesize fWind, fTitle, fOptionsDelegate, fGLContext; | 20 @synthesize fWind, fTitle, fOptionsDelegate, fGLContext; |
18 | 21 |
19 - (id)initWithCoder:(NSCoder*)coder { | 22 - (id)initWithCoder:(NSCoder*)coder { |
20 if ((self = [super initWithCoder:coder])) { | 23 if ((self = [super initWithCoder:coder])) { |
21 self = [self initWithDefaults]; | 24 self = [self initWithDefaults]; |
22 [self setUpWindow]; | 25 [self setUpWindow]; |
23 } | 26 } |
24 return self; | 27 return self; |
25 } | 28 } |
26 | 29 |
27 - (id)initWithFrame:(NSRect)frameRect { | 30 - (id)initWithFrame:(NSRect)frameRect { |
28 if ((self = [super initWithFrame:frameRect])) { | 31 if ((self = [super initWithFrame:frameRect])) { |
29 self = [self initWithDefaults]; | 32 self = [self initWithDefaults]; |
30 [self setUpWindow]; | 33 [self setUpWindow]; |
31 } | 34 } |
32 return self; | 35 return self; |
33 } | 36 } |
34 | 37 |
35 - (id)initWithDefaults { | 38 - (id)initWithDefaults { |
| 39 #if RETINA_API_AVAILABLE |
| 40 [self setWantsBestResolutionOpenGLSurface:YES]; |
| 41 #endif |
36 fRedrawRequestPending = false; | 42 fRedrawRequestPending = false; |
37 fWind = NULL; | 43 fWind = NULL; |
38 return self; | 44 return self; |
39 } | 45 } |
40 | 46 |
41 - (void)setUpWindow { | 47 - (void)setUpWindow { |
| 48 [[NSNotificationCenter defaultCenter] addObserver:self |
| 49 selector:@selector(backingPropertiesCh
anged:) |
| 50 name:@"NSWindowDidChangeBackingPropert
iesNotification" |
| 51 object:[self window]]; |
42 if (NULL != fWind) { | 52 if (NULL != fWind) { |
43 fWind->setVisibleP(true); | 53 fWind->setVisibleP(true); |
44 fWind->resize((int) self.frame.size.width, (int) self.frame.size.height,
| 54 NSSize size = self.frame.size; |
| 55 #if RETINA_API_AVAILABLE |
| 56 size = [self convertSizeToBacking:self.frame.size]; |
| 57 #endif |
| 58 fWind->resize((int) size.width, (int) size.height, |
45 SkBitmap::kARGB_8888_Config); | 59 SkBitmap::kARGB_8888_Config); |
46 } | 60 } |
47 } | 61 } |
48 | 62 |
49 -(BOOL) isFlipped { | 63 -(BOOL) isFlipped { |
50 return YES; | 64 return YES; |
51 } | 65 } |
52 | 66 |
53 - (BOOL)acceptsFirstResponder { | 67 - (BOOL)acceptsFirstResponder { |
54 return YES; | 68 return YES; |
55 } | 69 } |
56 | 70 |
| 71 - (float)scaleFactor { |
| 72 NSWindow *window = [self window]; |
| 73 #if RETINA_API_AVAILABLE |
| 74 if (window) { |
| 75 return [window backingScaleFactor]; |
| 76 } |
| 77 return [[NSScreen mainScreen] backingScaleFactor]; |
| 78 #else |
| 79 if (window) { |
| 80 return [window userSpaceScaleFactor]; |
| 81 } |
| 82 return [[NSScreen mainScreen] userSpaceScaleFactor]; |
| 83 #endif |
| 84 } |
| 85 |
| 86 - (void)backingPropertiesChanged:(NSNotification *)notification { |
| 87 CGFloat oldBackingScaleFactor = [ |
| 88 [notification.userInfo objectForKey:@"NSBackingPropertyOldScaleFactorKey
"] doubleValue |
| 89 ]; |
| 90 CGFloat newBackingScaleFactor = [self scaleFactor]; |
| 91 if (oldBackingScaleFactor == newBackingScaleFactor) { |
| 92 return; |
| 93 } |
| 94 |
| 95 // TODO: need a better way to force a refresh (that works). |
| 96 // [fGLContext update] does not appear to update if the point size has not c
hanged, |
| 97 // even if the backing size has changed. |
| 98 [self setFrameSize:NSMakeSize(self.frame.size.width + 1, self.frame.size.hei
ght + 1)]; |
| 99 } |
| 100 |
57 - (void)resizeSkView:(NSSize)newSize { | 101 - (void)resizeSkView:(NSSize)newSize { |
58 if (NULL != fWind && (fWind->width() != newSize.width || fWind->height() !=
newSize.height)) { | 102 #if RETINA_API_AVAILABLE |
| 103 newSize = [self convertSizeToBacking:newSize]; |
| 104 #endif |
| 105 if (NULL != fWind && |
| 106 (fWind->width() != newSize.width || |
| 107 fWind->height() != newSize.height)) |
| 108 { |
59 fWind->resize((int) newSize.width, (int) newSize.height); | 109 fWind->resize((int) newSize.width, (int) newSize.height); |
60 if (NULL != fGLContext) { | 110 if (NULL != fGLContext) { |
61 glClear(GL_STENCIL_BUFFER_BIT); | 111 glClear(GL_STENCIL_BUFFER_BIT); |
| 112 [fGLContext update]; |
62 } | 113 } |
63 [fGLContext update]; | |
64 } | 114 } |
65 } | 115 } |
66 | 116 |
67 - (void) setFrameSize:(NSSize)newSize { | 117 - (void) setFrameSize:(NSSize)newSize { |
68 [super setFrameSize:newSize]; | 118 [super setFrameSize:newSize]; |
69 [self resizeSkView:newSize]; | 119 [self resizeSkView:newSize]; |
70 } | 120 } |
71 | 121 |
72 - (void)dealloc { | 122 - (void)dealloc { |
73 delete fWind; | 123 delete fWind; |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 } | 262 } |
213 return skModi; | 263 return skModi; |
214 } | 264 } |
215 | 265 |
216 - (void)mouseDown:(NSEvent *)event { | 266 - (void)mouseDown:(NSEvent *)event { |
217 NSPoint p = [event locationInWindow]; | 267 NSPoint p = [event locationInWindow]; |
218 unsigned modi = convertNSModifiersToSk([event modifierFlags]); | 268 unsigned modi = convertNSModifiersToSk([event modifierFlags]); |
219 | 269 |
220 if ([self mouse:p inRect:[self bounds]] && NULL != fWind) { | 270 if ([self mouse:p inRect:[self bounds]] && NULL != fWind) { |
221 NSPoint loc = [self convertPoint:p fromView:nil]; | 271 NSPoint loc = [self convertPoint:p fromView:nil]; |
| 272 #if RETINA_API_AVAILABLE |
| 273 loc = [self convertPointToBacking:loc]; //y-up |
| 274 loc.y = -loc.y; |
| 275 #endif |
222 fWind->handleClick((int) loc.x, (int) loc.y, | 276 fWind->handleClick((int) loc.x, (int) loc.y, |
223 SkView::Click::kDown_State, self, modi); | 277 SkView::Click::kDown_State, self, modi); |
224 } | 278 } |
225 } | 279 } |
226 | 280 |
227 - (void)mouseDragged:(NSEvent *)event { | 281 - (void)mouseDragged:(NSEvent *)event { |
228 NSPoint p = [event locationInWindow]; | 282 NSPoint p = [event locationInWindow]; |
229 unsigned modi = convertNSModifiersToSk([event modifierFlags]); | 283 unsigned modi = convertNSModifiersToSk([event modifierFlags]); |
230 | 284 |
231 if ([self mouse:p inRect:[self bounds]] && NULL != fWind) { | 285 if ([self mouse:p inRect:[self bounds]] && NULL != fWind) { |
232 NSPoint loc = [self convertPoint:p fromView:nil]; | 286 NSPoint loc = [self convertPoint:p fromView:nil]; |
| 287 #if RETINA_API_AVAILABLE |
| 288 loc = [self convertPointToBacking:loc]; //y-up |
| 289 loc.y = -loc.y; |
| 290 #endif |
233 fWind->handleClick((int) loc.x, (int) loc.y, | 291 fWind->handleClick((int) loc.x, (int) loc.y, |
234 SkView::Click::kMoved_State, self, modi); | 292 SkView::Click::kMoved_State, self, modi); |
235 } | 293 } |
236 } | 294 } |
237 | 295 |
238 - (void)mouseMoved:(NSEvent *)event { | 296 - (void)mouseMoved:(NSEvent *)event { |
239 NSPoint p = [event locationInWindow]; | 297 NSPoint p = [event locationInWindow]; |
240 unsigned modi = convertNSModifiersToSk([event modifierFlags]); | 298 unsigned modi = convertNSModifiersToSk([event modifierFlags]); |
241 | 299 |
242 if ([self mouse:p inRect:[self bounds]] && NULL != fWind) { | 300 if ([self mouse:p inRect:[self bounds]] && NULL != fWind) { |
243 NSPoint loc = [self convertPoint:p fromView:nil]; | 301 NSPoint loc = [self convertPoint:p fromView:nil]; |
| 302 #if RETINA_API_AVAILABLE |
| 303 loc = [self convertPointToBacking:loc]; //y-up |
| 304 loc.y = -loc.y; |
| 305 #endif |
244 fWind->handleClick((int) loc.x, (int) loc.y, | 306 fWind->handleClick((int) loc.x, (int) loc.y, |
245 SkView::Click::kMoved_State, self, modi); | 307 SkView::Click::kMoved_State, self, modi); |
246 } | 308 } |
247 } | 309 } |
248 | 310 |
249 - (void)mouseUp:(NSEvent *)event { | 311 - (void)mouseUp:(NSEvent *)event { |
250 NSPoint p = [event locationInWindow]; | 312 NSPoint p = [event locationInWindow]; |
251 unsigned modi = convertNSModifiersToSk([event modifierFlags]); | 313 unsigned modi = convertNSModifiersToSk([event modifierFlags]); |
252 | 314 |
253 if ([self mouse:p inRect:[self bounds]] && NULL != fWind) { | 315 if ([self mouse:p inRect:[self bounds]] && NULL != fWind) { |
254 NSPoint loc = [self convertPoint:p fromView:nil]; | 316 NSPoint loc = [self convertPoint:p fromView:nil]; |
| 317 #if RETINA_API_AVAILABLE |
| 318 loc = [self convertPointToBacking:loc]; //y-up |
| 319 loc.y = -loc.y; |
| 320 #endif |
255 fWind->handleClick((int) loc.x, (int) loc.y, | 321 fWind->handleClick((int) loc.x, (int) loc.y, |
256 SkView::Click::kUp_State, self, modi); | 322 SkView::Click::kUp_State, self, modi); |
257 } | 323 } |
258 } | 324 } |
259 | 325 |
260 /////////////////////////////////////////////////////////////////////////////// | 326 /////////////////////////////////////////////////////////////////////////////// |
261 #include <OpenGL/OpenGL.h> | 327 #include <OpenGL/OpenGL.h> |
262 | 328 |
263 namespace { | 329 namespace { |
264 CGLContextObj createGLContext(int msaaSampleCount) { | 330 CGLContextObj createGLContext(int msaaSampleCount) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 if (NULL == fGLContext) { | 388 if (NULL == fGLContext) { |
323 return false; | 389 return false; |
324 } | 390 } |
325 [fGLContext setView:self]; | 391 [fGLContext setView:self]; |
326 } | 392 } |
327 | 393 |
328 [fGLContext makeCurrentContext]; | 394 [fGLContext makeCurrentContext]; |
329 CGLPixelFormatObj format = CGLGetPixelFormat((CGLContextObj)[fGLContext CGLC
ontextObj]); | 395 CGLPixelFormatObj format = CGLGetPixelFormat((CGLContextObj)[fGLContext CGLC
ontextObj]); |
330 CGLDescribePixelFormat(format, 0, kCGLPFASamples, &info->fSampleCount); | 396 CGLDescribePixelFormat(format, 0, kCGLPFASamples, &info->fSampleCount); |
331 CGLDescribePixelFormat(format, 0, kCGLPFAStencilSize, &info->fStencilBits); | 397 CGLDescribePixelFormat(format, 0, kCGLPFAStencilSize, &info->fStencilBits); |
332 glViewport(0, 0, (int) self.bounds.size.width, (int) self.bounds.size.width)
; | 398 NSSize size = self.bounds.size; |
| 399 #if RETINA_API_AVAILABLE |
| 400 size = [self convertSizeToBacking:size]; |
| 401 #endif |
| 402 glViewport(0, 0, (int) size.width, (int) size.height); |
333 glClearColor(0, 0, 0, 0); | 403 glClearColor(0, 0, 0, 0); |
334 glClearStencil(0); | 404 glClearStencil(0); |
335 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | 405 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |
336 return true; | 406 return true; |
337 } | 407 } |
338 | 408 |
339 - (void)detach { | 409 - (void)detach { |
340 [fGLContext release]; | 410 [fGLContext release]; |
341 fGLContext = nil; | 411 fGLContext = nil; |
342 } | 412 } |
343 | 413 |
344 - (void)present { | 414 - (void)present { |
345 if (nil != fGLContext) { | 415 if (nil != fGLContext) { |
346 [fGLContext flushBuffer]; | 416 [fGLContext flushBuffer]; |
347 } | 417 } |
348 } | 418 } |
349 @end | 419 @end |
OLD | NEW |