Skip to content

Commit

Permalink
Make progress in Skia/OSX port
Browse files Browse the repository at this point in the history
It includes:
- Use ARC instead of GC (compiling with -fobjc-arc flag)
- Implement GLContextCGL::getStencilBits/getSampleCount functions
- Modify OSXEventQueue to avoid creating a thread for app_main()
- NativeDialogs class can be compiled in 10.4 (with GC) and 10.6 (with
ARC)
- Split she/osx/view.h into view.h and view.mm
- get_local_mouse_pos() takes care of the window scale
- Temporal she::clock_value() impl
- Working SkiaWindow with Quartz and some progress with OpenGL
  • Loading branch information
dacap committed Oct 9, 2015
1 parent f38fd4e commit 247a8a7
Show file tree
Hide file tree
Showing 17 changed files with 573 additions and 274 deletions.
4 changes: 4 additions & 0 deletions src/she/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ if(USE_SKIA_BACKEND)
elseif(APPLE)
add_definitions(-DSK_BUILD_FOR_MAC)
add_definitions(-Wno-ignored-attributes -Wno-unused-result)

# Use Automatic Reference Counting
add_definitions(-fobjc-arc)
endif()

if(CMAKE_BUILD_TYPE STREQUAL Debug)
Expand Down Expand Up @@ -144,6 +147,7 @@ if(USE_SKIA_BACKEND)
osx/app.mm
osx/app_delegate.mm
osx/event_queue.mm
osx/view.mm
osx/window.mm
skia/skia_window_osx.mm)
endif()
Expand Down
32 changes: 21 additions & 11 deletions src/she/gl/gl_context_cgl.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ class GLContextCGL : public GLContext {
public:
typedef void* NativeHandle;

GLContextCGL(void*)
: m_glctx(nullptr) {
GLContextCGL(NativeHandle window)
: m_glctx(nullptr)
, m_stencilBits(0)
, m_sampleCount(0) {
}

~GLContextCGL() {
Expand All @@ -29,21 +31,23 @@ class GLContextCGL : public GLContext {

bool createGLContext() override {
CGLPixelFormatAttribute attributes[] = {
#if MAC_OS_X_VERSION_10_7
kCGLPFAOpenGLProfile,
(CGLPixelFormatAttribute)kCGLOGLPVersion_3_2_Core,
#endif
kCGLPFAAccelerated,
kCGLPFADoubleBuffer,
(CGLPixelFormatAttribute)0
};
CGLPixelFormatObj pixFormat;
CGLPixelFormatObj format;
GLint npix;
CGLChoosePixelFormat(attributes, &pixFormat, &npix);
if (!pixFormat)
CGLChoosePixelFormat(attributes, &format, &npix);
if (!format)
return false;

CGLCreateContext(pixFormat, nullptr, &m_glctx);
CGLReleasePixelFormat(pixFormat);
CGLDescribePixelFormat(format, 0, kCGLPFASamples, &m_sampleCount);
CGLDescribePixelFormat(format, 0, kCGLPFAStencilSize, &m_stencilBits);

CGLCreateContext(format, nullptr, &m_glctx);
CGLReleasePixelFormat(format);
if (!m_glctx)
return false;

Expand All @@ -59,15 +63,21 @@ class GLContextCGL : public GLContext {
}

int getStencilBits() override {
return 0;
return m_stencilBits;
}

int getSampleCount() override {
return 0;
return m_sampleCount;
}

CGLContextObj cglContext() {
return m_glctx;
}

private:
CGLContextObj m_glctx;
int m_stencilBits;
int m_sampleCount;
};

} // namespace she
Expand Down
4 changes: 0 additions & 4 deletions src/she/osx/app.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,9 @@ namespace she {
~OSXApp();

int run(int argc, char* argv[]);
void joinUserThread();

void stopUIEventLoop();

private:
static OSXApp* g_instance;
base::thread* m_userThread;
};

} // namespace she
Expand Down
52 changes: 2 additions & 50 deletions src/she/osx/app.mm
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
OSXApp* OSXApp::g_instance = nullptr;

OSXApp::OSXApp()
: m_userThread(nullptr)
{
g_instance = this;
}
Expand All @@ -36,61 +35,14 @@

int OSXApp::run(int argc, char* argv[])
{
NSAutoreleasePool* pool = [NSAutoreleasePool new];
(void)pool;

NSApplication* app = [NSApplication sharedApplication];
OSXAppDelegate* appDelegate = [OSXAppDelegate new];

// Create default main menu
NSMenu* mainMenu = [[NSMenu new] autorelease];
{
NSMenu* appMenu = [[NSMenu new] autorelease];
NSMenuItem* quitItem = [appMenu addItemWithTitle:@"Quit " PACKAGE
action:@selector(quit:)
keyEquivalent:@"q"];
[quitItem setKeyEquivalentModifierMask:NSCommandKeyMask];
[quitItem setTarget:appDelegate];

NSMenuItem* appMenuItem = [[NSMenuItem new] autorelease];
[appMenuItem setSubmenu:appMenu];

[mainMenu setTitle:@PACKAGE];
[mainMenu addItem:appMenuItem];
}
id appDelegate = [OSXAppDelegate new];

[app setActivationPolicy:NSApplicationActivationPolicyRegular];
[app setDelegate:appDelegate];
[app setMainMenu:mainMenu];

// The whole application runs in a background thread (non-main UI thread).
m_userThread = new base::thread([&]() {
// Ignore return value, as [NSApp run] doesn't return we cannot use it.
app_main(argc, argv);
});

[app run];

// In this case, the main NSRunLoop was stopped, so we have to terminate here.
//if (m_userThread)
// joinUserThread();

app_main(argc, argv);
return 0;
}

void OSXApp::joinUserThread()
{
// Join the user background thread to call all destructors and close everything properly.
m_userThread->join();
delete m_userThread;
m_userThread = nullptr;
}

void OSXApp::stopUIEventLoop()
{
// Stop the main NSRunLoop and post a dummy event to wake it up.
[NSApp stop:nil];
[NSApp postEvent:[NSEvent new] atStart:true];
}

} // namespace she
5 changes: 2 additions & 3 deletions src/she/osx/app_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@
#include <AppKit/AppKit.h>

@interface OSXAppDelegate : NSObject
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication;
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender;
- (void)applicationWillTerminate:(NSNotification*)aNotification;
- (void)quit:(id)sender;
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)app;
- (void)applicationWillTerminate:(NSNotification*)notification;
@end

#endif
17 changes: 5 additions & 12 deletions src/she/osx/app_delegate.mm
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,21 @@

@implementation OSXAppDelegate

- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender
{
return YES;
return NSTerminateNow;
}

- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)app
{
return NSTerminateNow;
return YES;
}

- (void)applicationWillTerminate:(NSNotification*)aNotification
- (void)applicationWillTerminate:(NSNotification*)notification
{
she::Event ev;
ev.setType(she::Event::CloseDisplay);
she::instance()->eventQueue()->queueEvent(ev);

she::OSXApp::instance()->joinUserThread();
}

- (void)quit:(id)sender
{
[[NSApp mainWindow] performClose:self];
}

@end
29 changes: 28 additions & 1 deletion src/she/osx/event_queue.mm
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,37 @@

namespace she {

static NSWindow* g_window = nil;

void OSXEventQueue::getEvent(Event& ev, bool canWait)
{
ev.setType(Event::None);

retry:;
NSApplication* app = [NSApplication sharedApplication];
if (!app)
return;

// Pump the whole queue of Cocoa events
NSEvent* event;
do {
event = [app nextEventMatchingMask:NSAnyEventMask
untilDate:[NSDate distantPast]
inMode:NSDefaultRunLoopMode
dequeue:YES];
if (event)
[app sendEvent: event];
} while (event);

if (!m_events.try_pop(ev)) {
ev.setType(Event::None);
if (canWait) {
// Wait until there is a Cocoa event in queue
[NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:[NSDate distantFuture]
inMode:NSDefaultRunLoopMode
dequeue:NO];
goto retry;
}
}
}

Expand Down
18 changes: 12 additions & 6 deletions src/she/osx/native_dialogs.mm
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

#include "base/path.h"

@interface OpenSaveHelper : NSObject
{
@interface OpenSaveHelper : NSObject {
@private
NSSavePanel* panel;
she::Display* display;
int result;
Expand Down Expand Up @@ -56,13 +56,17 @@ - (void)runModal
she::NativeCursor oldCursor = display->nativeMouseCursor();
display->setNativeMouseCursor(she::kArrowCursor);

#ifndef __MAC_10_6 // runModalForTypes is deprecated in 10.6
if ([panel isKindOfClass:[NSOpenPanel class]]) {
// As we're using OS X 10.4 framework, it looks like runModal
// doesn't recognize the allowedFileTypes property. So we force it
// using runModalForTypes: selector.
result = [panel runModalForTypes:[panel allowedFileTypes]];

result = [(NSOpenPanel*)panel runModalForTypes:[panel allowedFileTypes]];
}
else {
else
#endif
{
result = [panel runModal];
}

Expand Down Expand Up @@ -128,12 +132,12 @@ bool show(Display* display) override {
}
else {
panel = [NSOpenPanel openPanel];
[panel setAllowsMultipleSelection:NO];
[(NSOpenPanel*)panel setAllowsMultipleSelection:NO];
[(NSOpenPanel*)panel setCanChooseDirectories:NO];
}

[panel setTitle:[NSString stringWithUTF8String:m_title.c_str()]];
[panel setCanCreateDirectories:YES];
[panel setCanChooseDirectories:NO];

std::string defPath = base::get_file_path(m_filename);
std::string defName = base::get_file_name(m_filename);
Expand Down Expand Up @@ -164,8 +168,10 @@ bool show(Display* display) override {
else
retValue = false;

#if !__has_feature(objc_arc)
[helper release];
[types release];
#endif
return retValue;
}

Expand Down
Loading

0 comments on commit 247a8a7

Please sign in to comment.