GLWindowContext_win.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. * Copyright 2015 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "include/gpu/gl/GrGLInterface.h"
  8. #include "src/utils/win/SkWGL.h"
  9. #include "tools/sk_app/GLWindowContext.h"
  10. #include "tools/sk_app/win/WindowContextFactory_win.h"
  11. #include <Windows.h>
  12. #include <GL/gl.h>
  13. using sk_app::GLWindowContext;
  14. using sk_app::DisplayParams;
  15. #if defined(_M_ARM64)
  16. namespace sk_app {
  17. namespace window_context_factory {
  18. WindowContext* NewGLForWin(HWND, const DisplayParams&) { return nullptr; }
  19. } // namespace window_context_factory
  20. } // namespace sk_app
  21. #else
  22. namespace {
  23. class GLWindowContext_win : public GLWindowContext {
  24. public:
  25. GLWindowContext_win(HWND, const DisplayParams&);
  26. ~GLWindowContext_win() override;
  27. protected:
  28. void onSwapBuffers() override;
  29. sk_sp<const GrGLInterface> onInitializeContext() override;
  30. void onDestroyContext() override;
  31. private:
  32. HWND fHWND;
  33. HGLRC fHGLRC;
  34. typedef GLWindowContext INHERITED;
  35. };
  36. GLWindowContext_win::GLWindowContext_win(HWND wnd, const DisplayParams& params)
  37. : INHERITED(params)
  38. , fHWND(wnd)
  39. , fHGLRC(NULL) {
  40. // any config code here (particularly for msaa)?
  41. this->initializeContext();
  42. }
  43. GLWindowContext_win::~GLWindowContext_win() {
  44. this->destroyContext();
  45. }
  46. sk_sp<const GrGLInterface> GLWindowContext_win::onInitializeContext() {
  47. HDC dc = GetDC(fHWND);
  48. fHGLRC = SkCreateWGLContext(dc, fDisplayParams.fMSAASampleCount, false /* deepColor */,
  49. kGLPreferCompatibilityProfile_SkWGLContextRequest);
  50. if (NULL == fHGLRC) {
  51. return nullptr;
  52. }
  53. SkWGLExtensions extensions;
  54. if (extensions.hasExtension(dc, "WGL_EXT_swap_control")) {
  55. extensions.swapInterval(fDisplayParams.fDisableVsync ? 0 : 1);
  56. }
  57. // Look to see if RenderDoc is attached. If so, re-create the context with a core profile
  58. if (wglMakeCurrent(dc, fHGLRC)) {
  59. auto interface = GrGLMakeNativeInterface();
  60. bool renderDocAttached = interface->hasExtension("GL_EXT_debug_tool");
  61. interface.reset(nullptr);
  62. if (renderDocAttached) {
  63. wglDeleteContext(fHGLRC);
  64. fHGLRC = SkCreateWGLContext(dc, fDisplayParams.fMSAASampleCount, false /* deepColor */,
  65. kGLPreferCoreProfile_SkWGLContextRequest);
  66. if (NULL == fHGLRC) {
  67. return nullptr;
  68. }
  69. }
  70. }
  71. if (wglMakeCurrent(dc, fHGLRC)) {
  72. glClearStencil(0);
  73. glClearColor(0, 0, 0, 0);
  74. glStencilMask(0xffffffff);
  75. glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
  76. // use DescribePixelFormat to get the stencil and color bit depth.
  77. int pixelFormat = GetPixelFormat(dc);
  78. PIXELFORMATDESCRIPTOR pfd;
  79. DescribePixelFormat(dc, pixelFormat, sizeof(pfd), &pfd);
  80. fStencilBits = pfd.cStencilBits;
  81. // Get sample count if the MSAA WGL extension is present
  82. if (extensions.hasExtension(dc, "WGL_ARB_multisample")) {
  83. static const int kSampleCountAttr = SK_WGL_SAMPLES;
  84. extensions.getPixelFormatAttribiv(dc,
  85. pixelFormat,
  86. 0,
  87. 1,
  88. &kSampleCountAttr,
  89. &fSampleCount);
  90. fSampleCount = SkTMax(fSampleCount, 1);
  91. } else {
  92. fSampleCount = 1;
  93. }
  94. RECT rect;
  95. GetClientRect(fHWND, &rect);
  96. fWidth = rect.right - rect.left;
  97. fHeight = rect.bottom - rect.top;
  98. glViewport(0, 0, fWidth, fHeight);
  99. }
  100. return GrGLMakeNativeInterface();
  101. }
  102. void GLWindowContext_win::onDestroyContext() {
  103. wglDeleteContext(fHGLRC);
  104. fHGLRC = NULL;
  105. }
  106. void GLWindowContext_win::onSwapBuffers() {
  107. HDC dc = GetDC((HWND)fHWND);
  108. SwapBuffers(dc);
  109. ReleaseDC((HWND)fHWND, dc);
  110. }
  111. } // anonymous namespace
  112. namespace sk_app {
  113. namespace window_context_factory {
  114. WindowContext* NewGLForWin(HWND wnd, const DisplayParams& params) {
  115. GLWindowContext_win* ctx = new GLWindowContext_win(wnd, params);
  116. if (!ctx->isValid()) {
  117. delete ctx;
  118. return nullptr;
  119. }
  120. return ctx;
  121. }
  122. } // namespace window_context_factory
  123. } // namespace sk_app
  124. #endif