Stub in Mac viewer code.

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2164683002

patch from issue 2164683002 at patchset 1 (http://crrev.com/2164683002#ps1)

Review-Url: https://codereview.chromium.org/2167503002
This commit is contained in:
jvanverth 2016-07-19 14:17:20 -07:00 committed by Commit bot
parent 9ecaa1d9f0
commit a3f3caccdf
7 changed files with 608 additions and 1 deletions

View File

@ -67,7 +67,7 @@
'skiaserve.gyp:skiaserve',
],
}],
[ 'skia_os in ["win", "linux", "android"]', {
[ 'skia_os in ["win", "linux", "android", "mac"]', {
'dependencies': [
'viewer.gyp:viewer',
],

View File

@ -101,6 +101,10 @@
'sources/': [ ['exclude', '_win.(h|cpp)$'],
],
}],
['skia_os != "mac"', {
'sources/': [ ['exclude', '_mac.(h|cpp)$'],
],
}],
['skia_vulkan == 0', {
'sources/': [ ['exclude', 'Vulkan']
],

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}