aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gyp/most.gyp2
-rw-r--r--gyp/viewer.gyp4
-rw-r--r--tools/viewer/sk_app/mac/GLWindowContext_mac.cpp111
-rw-r--r--tools/viewer/sk_app/mac/GLWindowContext_mac.h42
-rw-r--r--tools/viewer/sk_app/mac/Window_mac.cpp308
-rw-r--r--tools/viewer/sk_app/mac/Window_mac.h67
-rw-r--r--tools/viewer/sk_app/mac/main_mac.cpp75
7 files changed, 608 insertions, 1 deletions
diff --git a/gyp/most.gyp b/gyp/most.gyp
index 37c802b841..5b5392618e 100644
--- a/gyp/most.gyp
+++ b/gyp/most.gyp
@@ -67,7 +67,7 @@
'skiaserve.gyp:skiaserve',
],
}],
- [ 'skia_os in ["win", "linux", "android"]', {
+ [ 'skia_os in ["win", "linux", "android", "mac"]', {
'dependencies': [
'viewer.gyp:viewer',
],
diff --git a/gyp/viewer.gyp b/gyp/viewer.gyp
index 5bec25c756..b2563ef537 100644
--- a/gyp/viewer.gyp
+++ b/gyp/viewer.gyp
@@ -101,6 +101,10 @@
'sources/': [ ['exclude', '_win.(h|cpp)$'],
],
}],
+ ['skia_os != "mac"', {
+ 'sources/': [ ['exclude', '_mac.(h|cpp)$'],
+ ],
+ }],
['skia_vulkan == 0', {
'sources/': [ ['exclude', 'Vulkan']
],
diff --git a/tools/viewer/sk_app/mac/GLWindowContext_mac.cpp b/tools/viewer/sk_app/mac/GLWindowContext_mac.cpp
new file mode 100644
index 0000000000..aa700e3165
--- /dev/null
+++ b/tools/viewer/sk_app/mac/GLWindowContext_mac.cpp
@@ -0,0 +1,111 @@
+
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GLWindowContext_mac.h"
+
+//#include <GL/gl.h>
+
+#include "Window_mac.h"
+
+namespace sk_app {
+
+// platform-dependent create
+GLWindowContext* GLWindowContext::Create(void* platformData, const DisplayParams& params) {
+ GLWindowContext_mac* ctx = new GLWindowContext_mac(platformData, params);
+ if (!ctx->isValid()) {
+ delete ctx;
+ return nullptr;
+ }
+ return ctx;
+}
+
+GLWindowContext_mac::GLWindowContext_mac(void* platformData, const DisplayParams& params)
+ : GLWindowContext(platformData, params)
+#if 0
+ // TODO: init Mac-specific OpenGL objects
+ , fDisplay(nullptr)
+ , fWindow(0)
+ , fGLContext(0)
+#endif
+ {
+
+ // any config code here (particularly for msaa)?
+
+ this->initializeContext(platformData, params);
+}
+
+GLWindowContext_mac::~GLWindowContext_mac() {
+ this->destroyContext();
+}
+
+void GLWindowContext_mac::onInitializeContext(void* platformData, const DisplayParams& params) {
+#if 0
+ // TODO: Init for Mac
+ ContextPlatformData_mac* unixPlatformData =
+ reinterpret_cast<ContextPlatformData_mac*>(platformData);
+
+ if (unixPlatformData) {
+ fDisplay = unixPlatformData->fDisplay;
+ fWindow = unixPlatformData->fWindow;
+ fVisualInfo = unixPlatformData->fVisualInfo;
+ }
+ SkASSERT(fDisplay);
+
+ fGLContext = glXCreateContext(fDisplay, fVisualInfo, nullptr, GL_TRUE);
+ if (!fGLContext) {
+ return;
+ }
+
+ if (glXMakeCurrent(fDisplay, fWindow, fGLContext)) {
+ glClearStencil(0);
+ glClearColor(0, 0, 0, 0);
+ glStencilMask(0xffffffff);
+ glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+
+ int redBits, greenBits, blueBits;
+ glXGetConfig(fDisplay, fVisualInfo, GLX_RED_SIZE, &redBits);
+ glXGetConfig(fDisplay, fVisualInfo, GLX_GREEN_SIZE, &greenBits);
+ glXGetConfig(fDisplay, fVisualInfo, GLX_BLUE_SIZE, &blueBits);
+ fColorBits = redBits + greenBits + blueBits;
+ glXGetConfig(fDisplay, fVisualInfo, GLX_STENCIL_SIZE, &fStencilBits);
+ glXGetConfig(fDisplay, fVisualInfo, GLX_SAMPLES_ARB, &fSampleCount);
+
+ XWindow root;
+ int x, y;
+ unsigned int border_width, depth;
+ XGetGeometry(fDisplay, fWindow, &root, &x, &y,
+ (unsigned int*)&fWidth, (unsigned int*)&fHeight, &border_width, &depth);
+ glViewport(0, 0, fWidth, fHeight);
+ }
+#endif
+}
+
+void GLWindowContext_mac::onDestroyContext() {
+#if 0
+ // TODO: teardown for Mac
+ if (!fDisplay || !fGLContext) {
+ return;
+ }
+ glXMakeCurrent(fDisplay, None, nullptr);
+ glXDestroyContext(fDisplay, fGLContext);
+ fGLContext = nullptr;
+#endif
+}
+
+
+void GLWindowContext_mac::onSwapBuffers() {
+#if 0
+ // TODO: swap for Mac
+ if (fDisplay && fGLContext) {
+ glXSwapBuffers(fDisplay, fWindow);
+ }
+#endif
+}
+
+
+} //namespace sk_app
diff --git a/tools/viewer/sk_app/mac/GLWindowContext_mac.h b/tools/viewer/sk_app/mac/GLWindowContext_mac.h
new file mode 100644
index 0000000000..e889c4cd31
--- /dev/null
+++ b/tools/viewer/sk_app/mac/GLWindowContext_mac.h
@@ -0,0 +1,42 @@
+
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef GLWindowContext_mac_DEFINED
+#define GLWindowContext_mac_DEFINED
+
+#include "../GLWindowContext.h"
+#include "Window_mac.h"
+
+namespace sk_app {
+
+class GLWindowContext_mac : public GLWindowContext {
+public:
+ friend GLWindowContext* GLWindowContext::Create(void* platformData, const DisplayParams&);
+
+ ~GLWindowContext_mac() override;
+
+ void onSwapBuffers() override;
+
+ void onInitializeContext(void*, const DisplayParams&) override;
+ void onDestroyContext() override;
+
+private:
+ GLWindowContext_mac(void*, const DisplayParams&);
+
+#if 0
+ // TODO: add Mac-specific GL display objects
+ Display* fDisplay;
+ XWindow fWindow;
+ XVisualInfo* fVisualInfo;
+ GLXContext fGLContext;
+#endif
+};
+
+
+}
+
+#endif
diff --git a/tools/viewer/sk_app/mac/Window_mac.cpp b/tools/viewer/sk_app/mac/Window_mac.cpp
new file mode 100644
index 0000000000..fdc6f80bd6
--- /dev/null
+++ b/tools/viewer/sk_app/mac/Window_mac.cpp
@@ -0,0 +1,308 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+//#include <tchar.h>
+
+#include "SkUtils.h"
+#include "Timer.h"
+#include "../GLWindowContext.h"
+#include "Window_mac.h"
+
+namespace sk_app {
+
+Window* Window::CreateNativeWindow(void* platformData) {
+#if 0
+ // TODO: platform-specific window creation
+ Display* display = (Display*)platformData;
+
+ Window_mac* window = new Window_mac();
+ if (!window->initWindow(display, nullptr)) {
+ delete window;
+ return nullptr;
+ }
+
+ return window;
+#else
+ return nullptr;
+#endif
+}
+
+#if 0
+ // TODO: Implement Mac window code
+
+const long kEventMask = ExposureMask | StructureNotifyMask |
+ KeyPressMask | KeyReleaseMask |
+ PointerMotionMask | ButtonPressMask | ButtonReleaseMask;
+
+bool Window_mac::initWindow(Display* display, const DisplayParams* params) {
+ if (params && params->fMSAASampleCount != fMSAASampleCount) {
+ this->closeWindow();
+ }
+ // we already have a window
+ if (fDisplay) {
+ return true;
+ }
+ fDisplay = display;
+
+ fWidth = 1280;
+ fHeight = 960;
+
+ // Attempt to create a window that supports GL
+ GLint att[] = {
+ GLX_RGBA,
+ GLX_DEPTH_SIZE, 24,
+ GLX_DOUBLEBUFFER,
+ GLX_STENCIL_SIZE, 8,
+ None
+ };
+ SkASSERT(nullptr == fVisualInfo);
+ if (params && params->fMSAASampleCount > 0) {
+ static const GLint kAttCount = SK_ARRAY_COUNT(att);
+ GLint msaaAtt[kAttCount + 4];
+ memcpy(msaaAtt, att, sizeof(att));
+ SkASSERT(None == msaaAtt[kAttCount - 1]);
+ msaaAtt[kAttCount - 1] = GLX_SAMPLE_BUFFERS_ARB;
+ msaaAtt[kAttCount + 0] = 1;
+ msaaAtt[kAttCount + 1] = GLX_SAMPLES_ARB;
+ msaaAtt[kAttCount + 2] = params->fMSAASampleCount;
+ msaaAtt[kAttCount + 3] = None;
+ fVisualInfo = glXChooseVisual(display, DefaultScreen(display), msaaAtt);
+ fMSAASampleCount = params->fMSAASampleCount;
+ }
+ if (nullptr == fVisualInfo) {
+ fVisualInfo = glXChooseVisual(display, DefaultScreen(display), att);
+ fMSAASampleCount = 0;
+ }
+
+ if (fVisualInfo) {
+ Colormap colorMap = XCreateColormap(display,
+ RootWindow(display, fVisualInfo->screen),
+ fVisualInfo->visual,
+ AllocNone);
+ XSetWindowAttributes swa;
+ swa.colormap = colorMap;
+ swa.event_mask = kEventMask;
+ fWindow = XCreateWindow(display,
+ RootWindow(display, fVisualInfo->screen),
+ 0, 0, // x, y
+ fWidth, fHeight,
+ 0, // border width
+ fVisualInfo->depth,
+ InputOutput,
+ fVisualInfo->visual,
+ CWEventMask | CWColormap,
+ &swa);
+ } else {
+ // Create a simple window instead. We will not be able to show GL
+ fWindow = XCreateSimpleWindow(display,
+ DefaultRootWindow(display),
+ 0, 0, // x, y
+ fWidth, fHeight,
+ 0, // border width
+ 0, // border value
+ 0); // background value
+ XSelectInput(display, fWindow, kEventMask);
+ }
+
+ if (!fWindow) {
+ return false;
+ }
+
+ // set up to catch window delete message
+ fWmDeleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", False);
+ XSetWMProtocols(display, fWindow, &fWmDeleteMessage, 1);
+
+ // add to hashtable of windows
+ gWindowMap.add(this);
+
+ // init event variables
+ fPendingPaint = false;
+ fPendingResize = false;
+
+ return true;
+}
+
+void Window_mac::closeWindow() {
+ if (fDisplay) {
+ this->detach();
+ SkASSERT(fGC);
+ XFreeGC(fDisplay, fGC);
+ fGC = nullptr;
+ gWindowMap.remove(fWindow);
+ XDestroyWindow(fDisplay, fWindow);
+ fWindow = 0;
+ fVisualInfo = nullptr;
+ fDisplay = nullptr;
+ fMSAASampleCount = 0;
+ }
+}
+
+static Window::Key get_key(KeySym keysym) {
+ static const struct {
+ KeySym fXK;
+ Window::Key fKey;
+ } gPair[] = {
+ { XK_BackSpace, Window::Key::kBack },
+ { XK_Clear, Window::Key::kBack },
+ { XK_Return, Window::Key::kOK },
+ { XK_Up, Window::Key::kUp },
+ { XK_Down, Window::Key::kDown },
+ { XK_Left, Window::Key::kLeft },
+ { XK_Right, Window::Key::kRight }
+ };
+ for (size_t i = 0; i < SK_ARRAY_COUNT(gPair); i++) {
+ if (gPair[i].fXK == keysym) {
+ return gPair[i].fKey;
+ }
+ }
+ return Window::Key::kNONE;
+}
+
+static uint32_t get_modifiers(const XEvent& event) {
+ static const struct {
+ unsigned fXMask;
+ unsigned fSkMask;
+ } gModifiers[] = {
+ { ShiftMask, Window::kShift_ModifierKey },
+ { ControlMask, Window::kControl_ModifierKey },
+ { Mod1Mask, Window::kOption_ModifierKey },
+ };
+
+ auto modifiers = 0;
+ for (size_t i = 0; i < SK_ARRAY_COUNT(gModifiers); ++i) {
+ if (event.xkey.state & gModifiers[i].fXMask) {
+ modifiers |= gModifiers[i].fSkMask;
+ }
+ }
+ return modifiers;
+}
+
+bool Window_mac::handleEvent(const XEvent& event) {
+ switch (event.type) {
+ case MapNotify:
+ if (!fGC) {
+ fGC = XCreateGC(fDisplay, fWindow, 0, nullptr);
+ }
+ break;
+
+ case ClientMessage:
+ if ((Atom)event.xclient.data.l[0] == fWmDeleteMessage &&
+ gWindowMap.count() == 1) {
+ return true;
+ }
+ break;
+
+ case ButtonPress:
+ if (event.xbutton.button == Button1) {
+ this->onMouse(event.xbutton.x, event.xbutton.y,
+ Window::kDown_InputState, get_modifiers(event));
+ }
+ break;
+
+ case ButtonRelease:
+ if (event.xbutton.button == Button1) {
+ this->onMouse(event.xbutton.x, event.xbutton.y,
+ Window::kUp_InputState, get_modifiers(event));
+ }
+ break;
+
+ case MotionNotify:
+ // only track if left button is down
+ if (event.xmotion.state & Button1Mask) {
+ this->onMouse(event.xmotion.x, event.xmotion.y,
+ Window::kMove_InputState, get_modifiers(event));
+ }
+ break;
+
+ case KeyPress: {
+ int shiftLevel = (event.xkey.state & ShiftMask) ? 1 : 0;
+ KeySym keysym = XkbKeycodeToKeysym(fDisplay, event.xkey.keycode,
+ 0, shiftLevel);
+ if (keysym == XK_Escape) {
+ return true;
+ }
+ Window::Key key = get_key(keysym);
+ if (key != Window::Key::kNONE) {
+ (void) this->onKey(key, Window::kDown_InputState,
+ get_modifiers(event));
+ } else {
+ long uni = keysym2ucs(keysym);
+ if (uni != -1) {
+ (void) this->onChar((SkUnichar) uni,
+ get_modifiers(event));
+ }
+ }
+ } break;
+
+ case KeyRelease: {
+ int shiftLevel = (event.xkey.state & ShiftMask) ? 1 : 0;
+ KeySym keysym = XkbKeycodeToKeysym(fDisplay, event.xkey.keycode,
+ 0, shiftLevel);
+ Window::Key key = get_key(keysym);
+ (void) this->onKey(key, Window::kUp_InputState,
+ get_modifiers(event));
+ } break;
+
+
+ default:
+ // these events should be handled in the main event loop
+ SkASSERT(event.type != Expose && event.type != ConfigureNotify);
+ break;
+ }
+
+ return false;
+}
+
+void Window_mac::setTitle(const char* title) {
+ XTextProperty textproperty;
+ XStringListToTextProperty(const_cast<char**>(&title), 1, &textproperty);
+ XSetWMName(fDisplay, fWindow, &textproperty);
+}
+
+void Window_mac::show() {
+ XMapWindow(fDisplay, fWindow);
+}
+
+bool Window_mac::attach(BackendType attachType, const DisplayParams& params) {
+ this->initWindow(fDisplay, &params);
+
+ ContextPlatformData_mac platformData;
+ platformData.fDisplay = fDisplay;
+ platformData.fWindow = fWindow;
+ platformData.fVisualInfo = fVisualInfo;
+ switch (attachType) {
+#ifdef SK_VULKAN
+ case kVulkan_BackendType:
+ fWindowContext = VulkanWindowContext::Create((void*)&platformData, params);
+ break;
+#endif
+ case kNativeGL_BackendType:
+ default:
+ fWindowContext = GLWindowContext::Create((void*)&platformData, params);
+ break;
+ }
+
+ return (SkToBool(fWindowContext));
+}
+
+void Window_mac::onInval() {
+ XEvent event;
+ event.type = Expose;
+ event.xexpose.send_event = True;
+ event.xexpose.display = fDisplay;
+ event.xexpose.window = fWindow;
+ event.xexpose.x = 0;
+ event.xexpose.y = 0;
+ event.xexpose.width = fWidth;
+ event.xexpose.height = fHeight;
+ event.xexpose.count = 0;
+
+ XSendEvent(fDisplay, fWindow, False, 0, &event);
+}
+#endif
+
+} // namespace sk_app
diff --git a/tools/viewer/sk_app/mac/Window_mac.h b/tools/viewer/sk_app/mac/Window_mac.h
new file mode 100644
index 0000000000..016b134465
--- /dev/null
+++ b/tools/viewer/sk_app/mac/Window_mac.h
@@ -0,0 +1,67 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#ifndef Window_mac_DEFINED
+#define Window_mac_DEFINED
+
+#include "../Window.h"
+#include "SkChecksum.h"
+#include "SkTDynamicHash.h"
+
+namespace sk_app {
+
+struct ContextPlatformData_mac {
+#if 0
+ // TODO: use Mac-specific objects
+ Display* fDisplay;
+ XWindow fWindow;
+ XVisualInfo* fVisualInfo;
+#endif
+};
+
+class Window_mac : public Window {
+public:
+ Window_mac() : Window()
+#if 0
+ // TODO: use Mac-specific objects
+ , fDisplay(nullptr)
+ , fWindow(0)
+ , fGC(nullptr)
+ , fVisualInfo(nullptr)
+#endif
+ , fMSAASampleCount(0) {}
+ ~Window_mac() override { this->closeWindow(); }
+
+#if 0
+ // TODO: need to init with Mac-specific data
+ bool initWindow(Display* display, const DisplayParams* params);
+#endif
+
+ void setTitle(const char*) override;
+ void show() override;
+
+ bool attach(BackendType attachType, const DisplayParams& params) override;
+
+ void onInval() override;
+
+private:
+ void closeWindow();
+
+#if 0
+ // TODO: use Mac-specific window data
+ Display* fDisplay;
+ XWindow fWindow;
+ GC fGC;
+ XVisualInfo* fVisualInfo;
+#endif
+
+ int fMSAASampleCount;
+};
+
+} // namespace sk_app
+
+#endif
diff --git a/tools/viewer/sk_app/mac/main_mac.cpp b/tools/viewer/sk_app/mac/main_mac.cpp
new file mode 100644
index 0000000000..94bc99e01e
--- /dev/null
+++ b/tools/viewer/sk_app/mac/main_mac.cpp
@@ -0,0 +1,75 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#include "SkTypes.h"
+#include "SkTHash.h"
+#include "Timer.h"
+#include "Window_mac.h"
+#include "../Application.h"
+
+using sk_app::Application;
+
+int main(int argc, char**argv) {
+#if 0
+ // TODO: use Mac main loop
+
+ Display* display = XOpenDisplay(nullptr);
+
+ Application* app = Application::Create(argc, argv, (void*)display);
+
+ // Get the file descriptor for the X display
+ int x11_fd = ConnectionNumber(display);
+ fd_set in_fds;
+
+ SkTHashSet<sk_app::Window_mac*> pendingWindows;
+ bool done = false;
+ while (!done) {
+ // Create a file description set containing x11_fd
+ FD_ZERO(&in_fds);
+ FD_SET(x11_fd, &in_fds);
+
+ // Set a sleep timer
+ struct timeval tv;
+ tv.tv_usec = 100;
+ tv.tv_sec = 0;
+
+ // Wait for an event on the file descriptor or for timer expiration
+ (void) select(1, &in_fds, NULL, NULL, &tv);
+
+ // Handle XEvents (if any) and flush the input
+ XEvent event;
+ while (XPending(display) && !done) {
+ XNextEvent(display, &event);
+
+ sk_app::Window_mac* win = sk_app::Window_mac::gWindowMap.find(event.xany.window);
+ // paint and resize events get collapsed
+ switch (event.type) {
+ case Expose:
+ win->markPendingPaint();
+ pendingWindows.add(win);
+ break;
+ case ConfigureNotify:
+ win->markPendingResize(event.xconfigurerequest.width,
+ event.xconfigurerequest.height);
+ pendingWindows.add(win);
+ break;
+ default:
+ if (win->handleEvent(event)) {
+ done = true;
+ }
+ break;
+ }
+ }
+ }
+
+ delete app;
+
+ XCloseDisplay(display);
+#endif
+
+ return 0;
+}