diff options
author | jvanverth <jvanverth@google.com> | 2016-05-27 05:47:00 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-05-27 05:47:00 -0700 |
commit | 10b3815a11c39b154ec7b74a2af43e019b50d48c (patch) | |
tree | f49279543bab25ff8d991ecb025749353ebc5e9b /tools/viewer/sk_app | |
parent | 41457927364d23ed363bc3ba25025f8a36f1b8d4 (diff) |
Add OpenGL support to Linux viewer
Also adds a command line option (--vulkan) to choose between
Vulkan and OpenGL.
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2011473003
Review-Url: https://codereview.chromium.org/2011473003
Diffstat (limited to 'tools/viewer/sk_app')
-rw-r--r-- | tools/viewer/sk_app/VulkanWindowContext.cpp | 1 | ||||
-rw-r--r-- | tools/viewer/sk_app/Window.cpp | 1 | ||||
-rw-r--r-- | tools/viewer/sk_app/unix/VulkanWindowContext_unix.cpp | 5 | ||||
-rw-r--r-- | tools/viewer/sk_app/unix/Window_unix.cpp | 128 | ||||
-rw-r--r-- | tools/viewer/sk_app/unix/Window_unix.h | 29 |
5 files changed, 132 insertions, 32 deletions
diff --git a/tools/viewer/sk_app/VulkanWindowContext.cpp b/tools/viewer/sk_app/VulkanWindowContext.cpp index 2e2b8a988c..f192c697e8 100644 --- a/tools/viewer/sk_app/VulkanWindowContext.cpp +++ b/tools/viewer/sk_app/VulkanWindowContext.cpp @@ -388,6 +388,7 @@ void VulkanWindowContext::destroyContext() { return; } + GR_VK_CALL(fBackendContext->fInterface, QueueWaitIdle(fPresentQueue)); GR_VK_CALL(fBackendContext->fInterface, DeviceWaitIdle(fBackendContext->fDevice)); this->destroyBuffers(); diff --git a/tools/viewer/sk_app/Window.cpp b/tools/viewer/sk_app/Window.cpp index a02e993d21..1c798df399 100644 --- a/tools/viewer/sk_app/Window.cpp +++ b/tools/viewer/sk_app/Window.cpp @@ -83,6 +83,7 @@ void Window::onPaint() { fWindowContext->swapBuffers(); } else { + printf("no backbuffer!?\n"); // try recreating testcontext } } diff --git a/tools/viewer/sk_app/unix/VulkanWindowContext_unix.cpp b/tools/viewer/sk_app/unix/VulkanWindowContext_unix.cpp index ddfc8e3068..02bf516b22 100644 --- a/tools/viewer/sk_app/unix/VulkanWindowContext_unix.cpp +++ b/tools/viewer/sk_app/unix/VulkanWindowContext_unix.cpp @@ -39,7 +39,7 @@ VkSurfaceKHR VulkanWindowContext::createVkSurface(VkInstance instance, void* pla surfaceCreateInfo.pNext = nullptr; surfaceCreateInfo.flags = 0; surfaceCreateInfo.connection = XGetXCBConnection(unixPlatformData->fDisplay); - surfaceCreateInfo.window = unixPlatformData->fHWnd; + surfaceCreateInfo.window = unixPlatformData->fWindow; VkResult res = createXcbSurfaceKHR(instance, &surfaceCreateInfo, nullptr, &surface); if (VK_SUCCESS != res) { @@ -64,10 +64,11 @@ bool VulkanWindowContext::canPresent(VkInstance instance, VkPhysicalDevice physD reinterpret_cast<ContextPlatformData_unix*>(platformData); Display* display = unixPlatformData->fDisplay; + VisualID visualID = unixPlatformData->fVisualInfo->visualid; VkBool32 check = getPhysicalDeviceXcbPresentationSupportKHR(physDev, queueFamilyIndex, XGetXCBConnection(display), - unixPlatformData->fVisualID); + visualID); return (VK_FALSE != check); } diff --git a/tools/viewer/sk_app/unix/Window_unix.cpp b/tools/viewer/sk_app/unix/Window_unix.cpp index 953eb36d74..431f156491 100644 --- a/tools/viewer/sk_app/unix/Window_unix.cpp +++ b/tools/viewer/sk_app/unix/Window_unix.cpp @@ -9,6 +9,7 @@ #include "SkUtils.h" #include "Timer.h" +#include "../GLWindowContext.h" #include "../VulkanWindowContext.h" #include "Window_unix.h" @@ -26,7 +27,7 @@ Window* Window::CreateNativeWindow(void* platformData) { Display* display = (Display*)platformData; Window_unix* window = new Window_unix(); - if (!window->init(display)) { + if (!window->initWindow(display, nullptr)) { delete window; return nullptr; } @@ -34,27 +35,87 @@ Window* Window::CreateNativeWindow(void* platformData) { return window; } -bool Window_unix::init(Display* display) { +const long kEventMask = ExposureMask | StructureNotifyMask | + KeyPressMask | KeyReleaseMask | + PointerMotionMask | ButtonPressMask | ButtonReleaseMask; + +bool Window_unix::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; - fHWnd = XCreateSimpleWindow(display, DefaultRootWindow(display), 0, 0, fWidth, fHeight, - 0, BlackPixel(display, DefaultScreen(display)), - BlackPixel(display, DefaultScreen(display))); - if (!fHWnd) { - return false; + // 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; } - // choose the events we care about - XSelectInput(display, fHWnd, - ExposureMask | StructureNotifyMask | KeyPressMask | KeyReleaseMask | - PointerMotionMask | ButtonPressMask | ButtonReleaseMask); + 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, fHWnd, &fWmDeleteMessage, 1); + XSetWMProtocols(display, fWindow, &fWmDeleteMessage, 1); // add to hashtable of windows gWindowMap.add(this); @@ -66,6 +127,21 @@ bool Window_unix::init(Display* display) { return true; } +void Window_unix::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; @@ -108,6 +184,12 @@ static uint32_t get_modifiers(const XEvent& event) { bool Window_unix::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) { @@ -179,25 +261,29 @@ bool Window_unix::handleEvent(const XEvent& event) { void Window_unix::setTitle(const char* title) { XTextProperty textproperty; XStringListToTextProperty(const_cast<char**>(&title), 1, &textproperty); - XSetWMName(fDisplay, fHWnd, &textproperty); + XSetWMName(fDisplay, fWindow, &textproperty); } void Window_unix::show() { - XMapWindow(fDisplay, fHWnd); + XMapWindow(fDisplay, fWindow); } bool Window_unix::attach(BackendType attachType, const DisplayParams& params) { + this->initWindow(fDisplay, ¶ms); + ContextPlatformData_unix platformData; platformData.fDisplay = fDisplay; - platformData.fHWnd = fHWnd; - XWindowAttributes attribs; - XGetWindowAttributes(fDisplay, fHWnd, &attribs); - platformData.fVisualID = XVisualIDFromVisual(attribs.visual); + platformData.fWindow = fWindow; + platformData.fVisualInfo = fVisualInfo; switch (attachType) { case kVulkan_BackendType: - default: fWindowContext = VulkanWindowContext::Create((void*)&platformData, params); break; + + case kNativeGL_BackendType: + default: + fWindowContext = GLWindowContext::Create((void*)&platformData, params); + break; } return (SkToBool(fWindowContext)); @@ -208,14 +294,14 @@ void Window_unix::onInval() { event.type = Expose; event.xexpose.send_event = True; event.xexpose.display = fDisplay; - event.xexpose.window = fHWnd; + 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, fHWnd, False, 0, &event); + XSendEvent(fDisplay, fWindow, False, 0, &event); } } // namespace sk_app diff --git a/tools/viewer/sk_app/unix/Window_unix.h b/tools/viewer/sk_app/unix/Window_unix.h index c2156fc6ae..fb6b22d413 100644 --- a/tools/viewer/sk_app/unix/Window_unix.h +++ b/tools/viewer/sk_app/unix/Window_unix.h @@ -9,6 +9,7 @@ #define Window_unix_DEFINED #include <X11/Xlib.h> +#include <GL/glx.h> #include "../Window.h" #include "SkChecksum.h" #include "SkTDynamicHash.h" @@ -18,17 +19,22 @@ typedef Window XWindow; namespace sk_app { struct ContextPlatformData_unix { - Display* fDisplay; - XWindow fHWnd; - VisualID fVisualID; + Display* fDisplay; + XWindow fWindow; + XVisualInfo* fVisualInfo; }; class Window_unix : public Window { public: - Window_unix() : Window() {} - ~Window_unix() override {} + Window_unix() : Window() + , fDisplay(nullptr) + , fWindow(0) + , fGC(nullptr) + , fVisualInfo(nullptr) + , fMSAASampleCount(0) {} + ~Window_unix() override { this->closeWindow(); } - bool init(Display* display); + bool initWindow(Display* display, const DisplayParams* params); void setTitle(const char*) override; void show() override; @@ -40,7 +46,7 @@ public: bool handleEvent(const XEvent& event); static const XWindow& GetKey(const Window_unix& w) { - return w.fHWnd; + return w.fWindow; } static uint32_t Hash(const XWindow& w) { @@ -70,8 +76,13 @@ public: } private: - Display* fDisplay; - XWindow fHWnd; + void closeWindow(); + + Display* fDisplay; + XWindow fWindow; + GC fGC; + XVisualInfo* fVisualInfo; + int fMSAASampleCount; Atom fWmDeleteMessage; |