Add OpenGL context to Viewer.
authorjvanverth <jvanverth@google.com>
Tue, 17 May 2016 19:15:48 +0000 (12:15 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 17 May 2016 19:15:48 +0000 (12:15 -0700)
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1978573003

Review-Url: https://codereview.chromium.org/1978573003

19 files changed:
src/gpu/vk/GrVkBuffer.cpp
tools/viewer/Viewer.cpp
tools/viewer/Viewer.h
tools/viewer/sk_app/DisplayParams.h
tools/viewer/sk_app/GLWindowContext.cpp [new file with mode: 0644]
tools/viewer/sk_app/GLWindowContext.h [new file with mode: 0644]
tools/viewer/sk_app/VulkanWindowContext.cpp
tools/viewer/sk_app/VulkanWindowContext.h
tools/viewer/sk_app/Window.cpp
tools/viewer/sk_app/Window.h
tools/viewer/sk_app/WindowContext.h
tools/viewer/sk_app/android/Window_android.cpp
tools/viewer/sk_app/android/Window_android.h
tools/viewer/sk_app/win/GLWindowContext_win.cpp [new file with mode: 0644]
tools/viewer/sk_app/win/GLWindowContext_win.h [new file with mode: 0644]
tools/viewer/sk_app/win/VulkanWindowContext_win.cpp
tools/viewer/sk_app/win/VulkanWindowContext_win.h [deleted file]
tools/viewer/sk_app/win/Window_win.cpp
tools/viewer/sk_app/win/Window_win.h

index 9b54dee..6fbdaac 100644 (file)
@@ -126,6 +126,7 @@ void GrVkBuffer::vkRelease(const GrVkGpu* gpu) {
 
 void GrVkBuffer::vkAbandon() {
     fResource->unrefAndAbandon();
+    fResource = nullptr;
     fMapPtr = nullptr;
     VALIDATE();
 }
index 7dd265e..644dd22 100644 (file)
@@ -41,9 +41,15 @@ DEFINE_string2(match, m, nullptr,
                "it is skipped unless some list entry starts with ~");
 DEFINE_string(skps, "skps", "Directory to read skps from.");
 
+const char *kBackendTypeStrings[sk_app::Window::kBackendTypeCount] = {
+    " [OpenGL]",
+    " [Vulkan]"
+};
+
 Viewer::Viewer(int argc, char** argv, void* platformData)
     : fCurrentMeasurement(0)
     , fDisplayStats(false)
+    , fBackendType(sk_app::Window::kVulkan_BackendType)
     , fZoomCenterX(0.0f)
     , fZoomCenterY(0.0f)
     , fZoomLevel(0.0f)
@@ -60,7 +66,7 @@ Viewer::Viewer(int argc, char** argv, void* platformData)
     SkCommandLineFlags::Parse(argc, argv);
 
     fWindow = Window::CreateNativeWindow(platformData);
-    fWindow->attach(Window::kVulkan_BackendType, DisplayParams());
+    fWindow->attach(fBackendType, DisplayParams());
 
     // register callbacks
     fCommands.attach(fWindow);
@@ -103,6 +109,22 @@ Viewer::Viewer(int argc, char** argv, void* platformData)
         this->changeZoomLevel(-1.f / 32.f);
         fWindow->inval();
     });
+#ifndef SK_BUILD_FOR_ANDROID
+    fCommands.addCommand('d', "Modes", "Change rendering backend", [this]() {
+        fWindow->detach();
+
+        if (sk_app::Window::kVulkan_BackendType == fBackendType) {
+            fBackendType = sk_app::Window::kNativeGL_BackendType;
+        } 
+        // TODO: get Vulkan -> OpenGL working without swapchain creation failure
+        //else if (sk_app::Window::kNativeGL_BackendType == fBackendType) {
+        //    fBackendType = sk_app::Window::kVulkan_BackendType;
+        //}
+
+        fWindow->attach(fBackendType, DisplayParams());
+        this->updateTitle();
+    });
+#endif
 
     // set up slides
     this->initSlides();
@@ -179,6 +201,7 @@ void Viewer::updateTitle() {
     if (kSRGB_SkColorProfileType == fWindow->getDisplayParams().fProfileType) {
         title.append(" sRGB");
     }
+    title.append(kBackendTypeStrings[fBackendType]);
     fWindow->setTitle(title.c_str());
 }
 
@@ -233,7 +256,6 @@ void Viewer::updateMatrix(){
 }
 
 void Viewer::onPaint(SkCanvas* canvas) {
-
     int count = canvas->save();
 
     if (fWindow->supportsContentRect()) {
index 033bd69..3579e4d 100644 (file)
@@ -47,6 +47,8 @@ private:
 
     bool                   fDisplayStats;
 
+    sk_app::Window::BackendType fBackendType;
+
     // transform data
     SkMatrix               fLocalMatrix;
     SkScalar               fZoomCenterX;
index 836b02e..8756ff0 100644 (file)
@@ -15,11 +15,13 @@ struct DisplayParams {
     DisplayParams()
         : fColorType(kN32_SkColorType)
         , fProfileType(kLinear_SkColorProfileType)
-        , fMSAASampleCount(0) {}
+        , fMSAASampleCount(0)
+        , fDeepColor(false) {}
 
-    SkColorType fColorType;
+    SkColorType        fColorType;
     SkColorProfileType fProfileType;
-    int fMSAASampleCount;
+    int                fMSAASampleCount;
+    bool               fDeepColor;
 };
 
 }   // namespace sk_app
diff --git a/tools/viewer/sk_app/GLWindowContext.cpp b/tools/viewer/sk_app/GLWindowContext.cpp
new file mode 100644 (file)
index 0000000..a491321
--- /dev/null
@@ -0,0 +1,112 @@
+
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrContext.h"
+#include "SkSurface.h"
+#include "GLWindowContext.h"
+
+#include "gl/GrGLDefines.h"
+
+#include "gl/GrGLUtil.h"
+#include "GrRenderTarget.h"
+#include "GrContext.h"
+
+#include "SkCanvas.h"
+#include "SkImage_Base.h"
+
+namespace sk_app {
+
+GLWindowContext::GLWindowContext(void* platformData, const DisplayParams& params) 
+    : WindowContext()
+    , fBackendContext(nullptr)
+    , fRenderTarget(nullptr)
+    , fSurface(nullptr) {
+}
+
+void GLWindowContext::initializeContext(void* platformData, const DisplayParams& params) {
+
+    this->onInitializeContext(platformData, params);
+
+    fDisplayParams = params;
+
+    SkAutoTUnref<const GrGLInterface> glInterface;
+    glInterface.reset(GrGLCreateNativeInterface());
+    fBackendContext.reset(GrGLInterfaceRemoveNVPR(glInterface.get()));
+
+    SkASSERT(nullptr == fContext);
+    fContext = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)fBackendContext.get());
+
+    // We may not have real sRGB support (ANGLE, in particular), so check for
+    // that, and fall back to L32:
+    //
+    // ... and, if we're using a 10-bit/channel FB0, it doesn't do sRGB conversion on write,
+    // so pretend that it's non-sRGB 8888:
+    fPixelConfig = fContext->caps()->srgbSupport() &&
+                   SkColorAndProfileAreGammaCorrect(fDisplayParams.fColorType,
+                                                    fDisplayParams.fProfileType) &&
+                   (fColorBits != 30) ? kSkiaGamma8888_GrPixelConfig : kSkia8888_GrPixelConfig;
+}
+
+void GLWindowContext::destroyContext() {
+    fSurface.reset(nullptr);
+    fRenderTarget.reset(nullptr);
+
+    if (fContext) {
+        // in case we have outstanding refs to this guy (lua?)
+        fContext->abandonContext();
+        fContext->unref();
+        fContext = nullptr;
+    }
+    
+    fBackendContext.reset(nullptr);
+
+    this->onDestroyContext();
+}
+
+sk_sp<SkSurface> GLWindowContext::getBackbufferSurface() {
+    if (nullptr == fSurface) {
+        fActualColorBits = SkTMax(fColorBits, 24);
+
+        if (fContext) {
+            GrBackendRenderTargetDesc desc;
+            desc.fWidth = this->fWidth;
+            desc.fHeight = this->fHeight;
+            desc.fConfig = fPixelConfig;
+            desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
+            desc.fSampleCnt = fSampleCount;
+            desc.fStencilBits = fStencilBits;
+            GrGLint buffer;
+            GR_GL_CALL(fBackendContext, GetIntegerv(GR_GL_FRAMEBUFFER_BINDING, &buffer));
+            desc.fRenderTargetHandle = buffer;
+            fRenderTarget.reset(fContext->textureProvider()->wrapBackendRenderTarget(desc));
+
+            fSurface = this->createRenderSurface(fRenderTarget, fActualColorBits);
+        }
+    }
+
+    return fSurface;
+}
+
+void GLWindowContext::swapBuffers() {
+    this->presentRenderSurface(fSurface, fRenderTarget, fActualColorBits);
+    this->onSwapBuffers();
+}
+
+void GLWindowContext::resize(uint32_t w, uint32_t h) {
+    this->destroyContext();
+
+    this->initializeContext(nullptr, fDisplayParams);
+}
+
+void GLWindowContext::setDisplayParams(const DisplayParams& params) {
+    this->destroyContext();
+
+    this->initializeContext(nullptr, params);
+}
+
+}   //namespace sk_app
diff --git a/tools/viewer/sk_app/GLWindowContext.h b/tools/viewer/sk_app/GLWindowContext.h
new file mode 100644 (file)
index 0000000..6fb5e09
--- /dev/null
@@ -0,0 +1,63 @@
+
+/*
+ * 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_DEFINED
+#define GLWindowContext_DEFINED
+
+
+#include "gl/GrGLInterface.h"
+
+#include "SkRefCnt.h"
+#include "GrRenderTarget.h"
+#include "SkSurface.h"
+
+#include "WindowContext.h"
+
+class GrContext;
+
+namespace sk_app {
+
+class GLWindowContext : public WindowContext {
+public:
+    // This is defined in the platform .cpp file
+    static GLWindowContext* Create(void* platformData, const DisplayParams& params);
+
+    sk_sp<SkSurface> getBackbufferSurface() override;
+
+    bool isValid() override { return SkToBool(fBackendContext.get()); }
+
+    void resize(uint32_t w, uint32_t h) override;
+    void swapBuffers() override;
+
+    void setDisplayParams(const DisplayParams& params) override;
+
+    GrBackendContext getBackendContext() override {
+        return (GrBackendContext) fBackendContext.get();
+    }
+
+protected:
+    GLWindowContext(void*, const DisplayParams&);
+    void initializeContext(void*, const DisplayParams&);
+    virtual void onInitializeContext(void*, const DisplayParams&) = 0;
+    void destroyContext();
+    virtual void onDestroyContext() = 0;
+    virtual void onSwapBuffers() = 0;
+
+    SkAutoTUnref<const GrGLInterface> fBackendContext;
+    sk_sp<GrRenderTarget>             fRenderTarget;
+    sk_sp<SkSurface>                  fSurface;
+
+    // parameters obtained from the native window
+    int                               fSampleCount;
+    int                               fStencilBits;
+    int                               fColorBits;
+    int                               fActualColorBits;
+};
+
+}   // namespace sk_app
+
+#endif
index 2570e82..bc200de 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include "GrContext.h"
+#include "GrRenderTarget.h"
 #include "SkSurface.h"
 #include "VulkanWindowContext.h"
 
 namespace sk_app {
 
 VulkanWindowContext::VulkanWindowContext(void* platformData, const DisplayParams& params)
-    : fSurface(VK_NULL_HANDLE)
+    : WindowContext()
+    , fSurface(VK_NULL_HANDLE)
     , fSwapchain(VK_NULL_HANDLE)
+    , fImages(nullptr)
+    , fImageLayouts(nullptr)
+    , fSurfaces(nullptr)
     , fCommandPool(VK_NULL_HANDLE)
     , fBackbuffers(nullptr) {
 
@@ -250,6 +255,7 @@ void VulkanWindowContext::createBuffers(VkFormat format) {
 
     // set up initial image layouts and create surfaces
     fImageLayouts = new VkImageLayout[fImageCount];
+    fRenderTargets = new sk_sp<GrRenderTarget>[fImageCount];
     fSurfaces = new sk_sp<SkSurface>[fImageCount];
     for (uint32_t i = 0; i < fImageCount; ++i) {
         fImageLayouts[i] = VK_IMAGE_LAYOUT_UNDEFINED;
@@ -269,10 +275,9 @@ void VulkanWindowContext::createBuffers(VkFormat format) {
         desc.fSampleCnt = 0;
         desc.fStencilBits = 0;
         desc.fRenderTargetHandle = (GrBackendObject) &info;
-        SkSurfaceProps props(GrPixelConfigIsSRGB(fPixelConfig)
-                             ? SkSurfaceProps::kGammaCorrect_Flag : 0,
-                             kUnknown_SkPixelGeometry);
-        fSurfaces[i] = SkSurface::MakeFromBackendRenderTarget(fContext, desc, &props);
+        fRenderTargets[i].reset(fContext->textureProvider()->wrapBackendRenderTarget(desc));
+
+        fSurfaces[i] = this->createRenderSurface(fRenderTargets[i], 24);
     }
 
     // create the command pool for the command buffers
@@ -361,8 +366,11 @@ void VulkanWindowContext::destroyBuffers() {
     delete[] fBackbuffers;
     fBackbuffers = nullptr;
 
+    // Does this actually free the surfaces?
     delete[] fSurfaces;
     fSurfaces = nullptr;
+    delete[] fRenderTargets;
+    fRenderTargets = nullptr;
     delete[] fImageLayouts;
     fImageLayouts = nullptr;
     delete[] fImages;
@@ -398,7 +406,8 @@ void VulkanWindowContext::destroyContext() {
         fSurface = VK_NULL_HANDLE;
     }
 
-    delete fContext;
+    fContext->abandonContext();
+    fContext->unref();
 
     fBackendContext.reset(nullptr);
 }
@@ -419,7 +428,7 @@ VulkanWindowContext::BackbufferInfo* VulkanWindowContext::getAvailableBackbuffer
     return backbuffer;
 }
 
-SkSurface* VulkanWindowContext::getBackbufferSurface() {
+sk_sp<SkSurface> VulkanWindowContext::getBackbufferSurface() {
     BackbufferInfo* backbuffer = this->getAvailableBackbuffer();
     SkASSERT(backbuffer);
 
@@ -510,14 +519,16 @@ SkSurface* VulkanWindowContext::getBackbufferSurface() {
                         QueueSubmit(fBackendContext->fQueue, 1, &submitInfo,
                                     backbuffer->fUsageFences[0]));
 
-    return fSurfaces[backbuffer->fImageIndex].get();
+    return sk_ref_sp(fSurfaces[backbuffer->fImageIndex].get());
 }
 
-
 void VulkanWindowContext::swapBuffers() {
 
     BackbufferInfo* backbuffer = fBackbuffers + fCurrentBackbufferIndex;
 
+    this->presentRenderSurface(fSurfaces[backbuffer->fImageIndex],
+                               fRenderTargets[backbuffer->fImageIndex], 24);
+
     VkImageLayout layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
     VkPipelineStageFlags srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
     VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
index ec80a32..8480a9e 100644 (file)
@@ -13,8 +13,7 @@
 #include "vk/GrVkBackendContext.h"
 #include "WindowContext.h"
 
-class SkSurface;
-class GrContext;
+class GrRenderTarget;
 
 namespace sk_app {
 
@@ -35,18 +34,15 @@ public:
         return ctx;
     }
 
-    SkSurface* getBackbufferSurface() override;
+    sk_sp<SkSurface> getBackbufferSurface() override;
     void swapBuffers() override;
 
-    bool makeCurrent() override { return true; }
-
     bool isValid() override { return SkToBool(fBackendContext.get()); }
 
     void resize(uint32_t w, uint32_t h) override {
         this->createSwapchain(w, h, fDisplayParams);
     }
 
-    const DisplayParams& getDisplayParams() override { return fDisplayParams; }
     void setDisplayParams(const DisplayParams& params) override {
         this->createSwapchain(fWidth, fHeight, params);
     }
@@ -99,23 +95,21 @@ private:
     VkPtr<PFN_vkQueuePresentKHR> fQueuePresentKHR;
     VkPtr<PFN_vkCreateSharedSwapchainsKHR> fCreateSharedSwapchainsKHR;
 
-    GrContext*        fContext;
     VkSurfaceKHR      fSurface;
     VkSwapchainKHR    fSwapchain;
     uint32_t          fPresentQueueIndex;
     VkQueue           fPresentQueue;
     int               fWidth;
     int               fHeight;
-    DisplayParams     fDisplayParams;
-    GrPixelConfig     fPixelConfig;
-
-    uint32_t          fImageCount;
-    VkImage*          fImages;         // images in the swapchain
-    VkImageLayout*    fImageLayouts;   // layouts of these images when not color attachment
-    sk_sp<SkSurface>* fSurfaces;       // wrapped surface for those images
-    VkCommandPool     fCommandPool;
-    BackbufferInfo*   fBackbuffers;
-    uint32_t          fCurrentBackbufferIndex;
+
+    uint32_t               fImageCount;
+    VkImage*               fImages;         // images in the swapchain
+    VkImageLayout*         fImageLayouts;   // layouts of these images when not color attachment
+    sk_sp<GrRenderTarget>* fRenderTargets;  // wrapped rendertargets for those images
+    sk_sp<SkSurface>*      fSurfaces;       // surfaces client renders to (may not be based on rts)
+    VkCommandPool          fCommandPool;
+    BackbufferInfo*        fBackbuffers;
+    uint32_t               fCurrentBackbufferIndex;
 };
 
 }   // namespace sk_app
index 47053be..dc0bf99 100644 (file)
@@ -53,7 +53,7 @@ bool Window::onMouse(int x, int y, InputState state, uint32_t modifiers) {
 }
 
 void Window::onPaint() {
-    SkSurface* backbuffer = fWindowContext->getBackbufferSurface();
+    sk_sp<SkSurface> backbuffer = fWindowContext->getBackbufferSurface();
     if (backbuffer) {
         // draw into the canvas of this surface
         SkCanvas* canvas = backbuffer->getCanvas();
@@ -66,7 +66,6 @@ void Window::onPaint() {
     } else {
         // try recreating testcontext
     }
-
 }
 
 void Window::onResize(uint32_t w, uint32_t h) {
index f233f13..5b41f87 100644 (file)
@@ -32,12 +32,17 @@ public:
     virtual bool supportsContentRect() const { return false; }
     virtual SkRect getContentRect() { return SkRect::MakeEmpty(); }
 
-    enum BackEndType {
+    enum BackendType {
         kNativeGL_BackendType,
-        kVulkan_BackendType
+        kVulkan_BackendType,
+
+        kLast_BackendType = kVulkan_BackendType
+    };
+    enum {
+        kBackendTypeCount = kLast_BackendType + 1
     };
 
-    virtual bool attach(BackEndType attachType,  const DisplayParams& params) = 0;
+    virtual bool attach(BackendType attachType,  const DisplayParams& params) = 0;
     void detach();
 
     // input handling
index d48e38e..1fd921a 100644 (file)
@@ -9,30 +9,54 @@
 
 #include "DisplayParams.h"
 #include "GrTypes.h"
+#include "SkRefCnt.h"
+#include "SkSurfaceProps.h"
 
+class GrContext;
 class SkSurface;
+class GrRenderTarget;
 
 namespace sk_app {
 
-// TODO: fill this out with an interface
 class WindowContext {
 public:
+    WindowContext() : fContext(nullptr)
+                    , fSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType) {}
+
     virtual ~WindowContext() {}
 
-    virtual SkSurface* getBackbufferSurface() = 0;
+    virtual sk_sp<SkSurface> getBackbufferSurface() = 0;
 
     virtual void swapBuffers() = 0;
 
-    virtual bool makeCurrent() = 0;
-
     virtual bool isValid() = 0;
 
     virtual void resize(uint32_t w, uint32_t h) = 0;
 
-    virtual const DisplayParams& getDisplayParams() = 0;
+    const DisplayParams& getDisplayParams() { return fDisplayParams; }
     virtual void setDisplayParams(const DisplayParams& params) = 0;
 
+    SkSurfaceProps getSurfaceProps() const { return fSurfaceProps; }
+    void setSurfaceProps(const SkSurfaceProps& props) {
+        fSurfaceProps = props;
+    }
+
     virtual GrBackendContext getBackendContext() = 0;
+
+    sk_sp<SkSurface> createRenderSurface(sk_sp<GrRenderTarget>, int colorBits);
+    void presentRenderSurface(sk_sp<SkSurface> renderSurface, sk_sp<GrRenderTarget> rt,
+                              int colorBits);
+
+protected:
+    virtual bool isGpuContext() { return true;  }
+
+    GrContext*        fContext;
+
+    int               fWidth;
+    int               fHeight;
+    DisplayParams     fDisplayParams;
+    GrPixelConfig     fPixelConfig;
+    SkSurfaceProps    fSurfaceProps;
 };
 
 }   // namespace sk_app
index f16e567..21998d5 100644 (file)
@@ -41,7 +41,7 @@ void Window_android::setTitle(const char* title) {
     fSkiaAndroidApp->setTitle(title);
 }
 
-bool Window_android::attach(BackEndType attachType, const DisplayParams& params) {
+bool Window_android::attach(BackendType attachType, const DisplayParams& params) {
     if (kVulkan_BackendType != attachType) {
         return false;
     }
index 2bf7bfe..c1cd1eb 100644 (file)
@@ -26,7 +26,7 @@ public:
     void setTitle(const char*) override;
     void show() override {}
 
-    bool attach(BackEndType attachType, const DisplayParams& params) override;
+    bool attach(BackendType attachType, const DisplayParams& params) override;
     void inval() override;
 
     bool scaleContentToFit() const override { return true; }
diff --git a/tools/viewer/sk_app/win/GLWindowContext_win.cpp b/tools/viewer/sk_app/win/GLWindowContext_win.cpp
new file mode 100644 (file)
index 0000000..0694db3
--- /dev/null
@@ -0,0 +1,110 @@
+
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GLWindowContext_win.h"
+
+#include <GL/gl.h>
+
+ // windows stuff
+#include "win/SkWGL.h"
+#include "Window_win.h"
+
+namespace sk_app {
+
+// platform-dependent create
+GLWindowContext* GLWindowContext::Create(void* platformData, const DisplayParams& params) {
+    GLWindowContext_win* ctx = new GLWindowContext_win(platformData, params);
+    if (!ctx->isValid()) {
+        delete ctx;
+        return nullptr;
+    }
+    return ctx;
+}
+
+GLWindowContext_win::GLWindowContext_win(void* platformData, const DisplayParams& params)
+    : GLWindowContext(platformData, params)
+    , fHWND(0)
+    , fHGLRC(NULL) {
+
+    // any config code here (particularly for msaa)?
+
+    this->initializeContext(platformData, params);
+}
+
+GLWindowContext_win::~GLWindowContext_win() {
+    this->destroyContext();
+}
+
+void GLWindowContext_win::onInitializeContext(void* platformData, const DisplayParams& params) {
+
+    ContextPlatformData_win* winPlatformData =
+        reinterpret_cast<ContextPlatformData_win*>(platformData);
+
+    if (winPlatformData) {
+        fHWND = winPlatformData->fHWnd;
+    }
+    HDC dc = GetDC(fHWND);
+
+    fHGLRC = SkCreateWGLContext(dc, params.fMSAASampleCount, params.fDeepColor,
+                                kGLPreferCompatibilityProfile_SkWGLContextRequest);
+    if (NULL == fHGLRC) {
+        return;
+    }
+
+    if (wglMakeCurrent(dc, fHGLRC)) {
+        glClearStencil(0);
+        glClearColor(0, 0, 0, 0);
+        glStencilMask(0xffffffff);
+        glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+
+        // use DescribePixelFormat to get the stencil and color bit depth.
+        int pixelFormat = GetPixelFormat(dc);
+        PIXELFORMATDESCRIPTOR pfd;
+        DescribePixelFormat(dc, pixelFormat, sizeof(pfd), &pfd);
+        fStencilBits = pfd.cStencilBits;
+        // pfd.cColorBits includes alpha, so it will be 32 in 8/8/8/8 and 10/10/10/2
+        fColorBits = pfd.cRedBits + pfd.cGreenBits + pfd.cBlueBits;
+
+        // Get sample count if the MSAA WGL extension is present
+        SkWGLExtensions extensions;
+        if (extensions.hasExtension(dc, "WGL_ARB_multisample")) {
+            static const int kSampleCountAttr = SK_WGL_SAMPLES;
+            extensions.getPixelFormatAttribiv(dc,
+                                              pixelFormat,
+                                              0,
+                                              1,
+                                              &kSampleCountAttr,
+                                              &fSampleCount);
+        } else {
+            fSampleCount = 0;
+        }
+
+        RECT rect;
+        GetClientRect(fHWND, &rect);
+        fWidth = rect.right - rect.left;
+        fHeight = rect.bottom - rect.top;
+        glViewport(0, 0, fWidth, fHeight);
+    }
+}
+
+
+void GLWindowContext_win::onDestroyContext() {
+    wglMakeCurrent(wglGetCurrentDC(), NULL);
+    wglDeleteContext(fHGLRC);
+    fHGLRC = NULL;
+}
+
+
+void GLWindowContext_win::onSwapBuffers() {
+    HDC dc = GetDC((HWND)fHWND);
+    SwapBuffers(dc);
+    ReleaseDC((HWND)fHWND, dc);
+}
+
+
+}   //namespace sk_app
diff --git a/tools/viewer/sk_app/win/GLWindowContext_win.h b/tools/viewer/sk_app/win/GLWindowContext_win.h
new file mode 100644 (file)
index 0000000..f30a805
--- /dev/null
@@ -0,0 +1,37 @@
+
+/*
+ * 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_win_DEFINED
+#define GLWindowContext_win_DEFINED
+
+#include <windows.h>
+#include "../GLWindowContext.h"
+
+namespace sk_app {
+
+class GLWindowContext_win : public GLWindowContext {
+public:
+    friend GLWindowContext* GLWindowContext::Create(void* platformData, const DisplayParams&);
+
+    ~GLWindowContext_win() override;
+
+    void onSwapBuffers() override;
+
+    void onInitializeContext(void*, const DisplayParams&) override;
+    void onDestroyContext() override;
+
+private:
+    GLWindowContext_win(void*, const DisplayParams&);
+
+    HWND              fHWND;
+    HGLRC             fHGLRC;
+};
+
+
+}
+
+#endif
index 05f3bdd..460dba1 100644 (file)
@@ -6,7 +6,8 @@
  * found in the LICENSE file.
  */
 
-#include "VulkanWindowContext_win.h"
+#include "../VulkanWindowContext.h"
+#include "Window_win.h"
 
 #include "vk/GrVkInterface.h"
 #include "vk/GrVkUtil.h"
diff --git a/tools/viewer/sk_app/win/VulkanWindowContext_win.h b/tools/viewer/sk_app/win/VulkanWindowContext_win.h
deleted file mode 100644 (file)
index e0b5a15..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-
-/*
- * 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 VULKANTESTCONTEXT_WIN_DEFINED
-#define VULKANTESTCONTEXT_WIN_DEFINED
-
-#ifdef SK_VULKAN
-
-#include <windows.h>
-#include "../VulkanWindowContext.h"
-
-namespace sk_app {
-
-// for Windows
-struct ContextPlatformData_win {
-    HINSTANCE fHInstance;
-    HWND      fHWnd;
-};
-
-}
-
-#endif // SK_VULKAN
-
-#endif
index 241a41c..8355c72 100644 (file)
@@ -12,7 +12,8 @@
 #include <windowsx.h>
 
 #include "SkUtils.h"
-#include "VulkanWindowContext_win.h"
+#include "../GLWindowContext.h"
+#include "../VulkanWindowContext.h"
 
 namespace sk_app {
 
@@ -264,16 +265,21 @@ void Window_win::show() {
 }
 
 
-bool Window_win::attach(BackEndType attachType, const DisplayParams& params) {
-    if (kVulkan_BackendType != attachType) {
-        return false;
-    }
-
+bool Window_win::attach(BackendType attachType, const DisplayParams& params) {
     ContextPlatformData_win platformData;
     platformData.fHInstance = fHInstance;
     platformData.fHWnd = fHWnd;
 
-    fWindowContext = VulkanWindowContext::Create((void*)&platformData, params);
+    switch (attachType) {
+        case kNativeGL_BackendType:
+        default:
+            fWindowContext = GLWindowContext::Create((void*)&platformData, params);
+            break;
+
+        case kVulkan_BackendType:
+            fWindowContext = VulkanWindowContext::Create((void*)&platformData, params);
+            break;
+    }
 
     return (SkToBool(fWindowContext));
 }
index 3501b06..4dd829a 100644 (file)
 
 namespace sk_app {
 
+// for Windows
+struct ContextPlatformData_win {
+    HINSTANCE fHInstance;
+    HWND      fHWnd;
+};
+
 class Window_win : public Window {
 public:
     Window_win() : Window() {}
@@ -23,7 +29,7 @@ public:
     void setTitle(const char*) override;
     void show() override;
 
-    bool attach(BackEndType attachType, const DisplayParams& params) override;
+    bool attach(BackendType attachType, const DisplayParams& params) override;
 
     void inval() override;