2
0
mirror of synced 2025-02-21 14:08:14 +00:00

go.mobile/app: darwin window drawing support for debugging

This lets you run really simple apps in a window on an OS X
machine. It's not an official target, but slightly more
productive than waiting for an apk install when working on
the sprite package.

LGTM=adg
R=golang-codereviews, adg
CC=golang-codereviews
https://golang.org/cl/147910043
This commit is contained in:
David Crawshaw 2014-09-29 13:22:23 +10:00
parent 659ad767f0
commit 5217175bab
2 changed files with 237 additions and 0 deletions

110
app/darwin.go Normal file
View File

@ -0,0 +1,110 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Simple on-screen app debugging for OS X. Not an officially supported
// development target for apps, as screens with mice are very different
// than screens with touch panels.
// +build darwin
package app
/*
#cgo CFLAGS: -x objective-c
#cgo LDFLAGS: -framework Cocoa -framework OpenGL -framework QuartzCore
#import <Cocoa/Cocoa.h>
#import <OpenGL/gl.h>
void glGenVertexArrays(GLsizei n, GLuint* array);
void glBindVertexArray(GLuint array);
void runApp(void);
void lockContext(GLintptr);
void unlockContext(GLintptr);
double backingScaleFactor();
*/
import "C"
import (
"log"
"runtime"
"sync"
"code.google.com/p/go.mobile/event"
"code.google.com/p/go.mobile/geom"
"code.google.com/p/go.mobile/gl"
)
func init() {
runtime.LockOSThread()
}
func run(callbacks Callbacks) {
cb = callbacks
C.runApp()
}
//export setGeom
func setGeom(scale, width, height float64) {
// Macs default to 72 DPI, so scales are equivalent.
geom.Scale = float32(scale)
geom.Width = geom.Pt(width)
geom.Height = geom.Pt(height)
log.Printf("geom: Scale=%.2f, Width=%v, Height=%v", geom.Scale, geom.Width, geom.Height)
}
func initGL() {
// Using attribute arrays in OpenGL 3.3 requires the use of a VBA.
// But VBAs don't exist in ES 2. So we bind one default one.
var id C.GLuint
C.glGenVertexArrays(1, &id)
C.glBindVertexArray(id)
}
var cb Callbacks
var initGLOnce sync.Once
var events = make(chan event.Touch, 1<<6)
func sendTouch(ty event.TouchType, x, y float32) {
events <- event.Touch{
Type: ty,
Loc: geom.Point{
X: geom.Pt(x),
Y: geom.Height - geom.Pt(y),
},
}
}
//export eventMouseDown
func eventMouseDown(x, y float32) { sendTouch(event.TouchStart, x, y) }
//export eventMouseMove
func eventMouseMove(x, y float32) { sendTouch(event.TouchMove, x, y) }
//export eventMouseEnd
func eventMouseEnd(x, y float32) { sendTouch(event.TouchEnd, x, y) }
//export drawgl
func drawgl(ctx C.GLintptr) {
runtime.LockOSThread()
C.lockContext(ctx)
initGLOnce.Do(initGL)
loop:
for {
select {
case e := <-events:
cb.Touch(e)
default:
break loop
}
}
gl.ClearColor(0, 0, 0, 1)
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
cb.Draw()
C.unlockContext(ctx)
runtime.UnlockOSThread()
}

127
app/darwin.m Normal file
View File

@ -0,0 +1,127 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin
#include "_cgo_export.h"
#include <stdio.h>
#import <Cocoa/Cocoa.h>
#import <Foundation/Foundation.h>
#import <OpenGL/gl.h>
#import <QuartzCore/CVReturn.h>
#import <QuartzCore/CVBase.h>
static CVReturn displayLinkDraw(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext)
{
NSOpenGLView* view = displayLinkContext;
NSOpenGLContext *currentContext = [view openGLContext];
drawgl((GLintptr)currentContext);
return kCVReturnSuccess;
}
void lockContext(GLintptr context) {
NSOpenGLContext* ctx = (NSOpenGLContext*)context;
[ctx makeCurrentContext];
CGLLockContext([ctx CGLContextObj]);
}
void unlockContext(GLintptr context) {
NSOpenGLContext* ctx = (NSOpenGLContext*)context;
[ctx flushBuffer];
CGLUnlockContext([ctx CGLContextObj]);
}
@interface MobileGLView : NSOpenGLView
{
CVDisplayLinkRef displayLink;
}
@end
@implementation MobileGLView
- (void)prepareOpenGL {
[self setWantsBestResolutionOpenGLSurface:true];
GLint swapInt = 1;
[[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
CVDisplayLinkCreateWithActiveCGDisplays(&displayLink);
CVDisplayLinkSetOutputCallback(displayLink, &displayLinkDraw, self);
CGLContextObj cglContext = [[self openGLContext] CGLContextObj];
CGLPixelFormatObj cglPixelFormat = [[self pixelFormat] CGLPixelFormatObj];
CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, cglContext, cglPixelFormat);
CVDisplayLinkStart(displayLink);
}
- (void)reshape {
NSRect r = [self bounds];
double scale = [[NSScreen mainScreen] backingScaleFactor];
setGeom(scale, r.size.width, r.size.height);
}
- (void)mouseDown:(NSEvent *)theEvent {
NSPoint p = [theEvent locationInWindow];
eventMouseDown(p.x, p.y);
}
- (void)mouseUp:(NSEvent *)theEvent {
NSPoint p = [theEvent locationInWindow];
eventMouseEnd(p.x, p.y);
}
- (void)mouseMoved:(NSEvent *)theEvent {
NSPoint p = [theEvent locationInWindow];
eventMouseMove(p.x, p.y);
}
@end
void
runApp(void) {
[NSAutoreleasePool new];
[NSApplication sharedApplication];
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
id menuBar = [[NSMenu new] autorelease];
id menuItem = [[NSMenuItem new] autorelease];
[menuBar addItem:menuItem];
[NSApp setMainMenu:menuBar];
id menu = [[NSMenu new] autorelease];
id name = [[NSProcessInfo processInfo] processName];
id quitMenuItem = [[[NSMenuItem alloc] initWithTitle:@"Quit"
action:@selector(terminate:) keyEquivalent:@"q"]
autorelease];
[menu addItem:quitMenuItem];
[menuItem setSubmenu:menu];
NSRect rect = NSMakeRect(0, 0, 200, 200);
id window = [[[NSWindow alloc] initWithContentRect:rect
styleMask:NSTitledWindowMask
backing:NSBackingStoreBuffered
defer:NO]
autorelease];
[window setStyleMask:[window styleMask] | NSResizableWindowMask];
[window cascadeTopLeftFromPoint:NSMakePoint(20,20)];
[window makeKeyAndOrderFront:nil];
[window setTitle:name];
NSOpenGLPixelFormatAttribute attr[] = {
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
NSOpenGLPFAColorSize, 24,
NSOpenGLPFAAlphaSize, 8,
NSOpenGLPFADepthSize, 16,
NSOpenGLPFAAccelerated,
NSOpenGLPFADoubleBuffer,
0
};
id pixFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr];
id view = [[MobileGLView alloc] initWithFrame:rect pixelFormat:pixFormat];
[window setContentView:view];
[NSApp activateIgnoringOtherApps:YES];
[NSApp run];
}