1cb93a386Sopenharmony_ci 2cb93a386Sopenharmony_ci/* 3cb93a386Sopenharmony_ci * Copyright 2015 Google Inc. 4cb93a386Sopenharmony_ci * 5cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 6cb93a386Sopenharmony_ci * found in the LICENSE file. 7cb93a386Sopenharmony_ci */ 8cb93a386Sopenharmony_ci 9cb93a386Sopenharmony_ci#define EGL_EGL_PROTOTYPES 1 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci#include <EGL/egl.h> 12cb93a386Sopenharmony_ci#include <EGL/eglext.h> 13cb93a386Sopenharmony_ci#include "include/gpu/gl/GrGLAssembleInterface.h" 14cb93a386Sopenharmony_ci#include "src/gpu/gl/GrGLDefines.h" 15cb93a386Sopenharmony_ci#include "tools/sk_app/GLWindowContext.h" 16cb93a386Sopenharmony_ci#include "tools/sk_app/win/WindowContextFactory_win.h" 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_ciusing sk_app::GLWindowContext; 19cb93a386Sopenharmony_ciusing sk_app::DisplayParams; 20cb93a386Sopenharmony_ci 21cb93a386Sopenharmony_cinamespace { 22cb93a386Sopenharmony_ci 23cb93a386Sopenharmony_ciEGLDisplay get_angle_egl_display(HDC hdc) { 24cb93a386Sopenharmony_ci PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT; 25cb93a386Sopenharmony_ci eglGetPlatformDisplayEXT = 26cb93a386Sopenharmony_ci (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT"); 27cb93a386Sopenharmony_ci 28cb93a386Sopenharmony_ci // We expect ANGLE to support this extension 29cb93a386Sopenharmony_ci if (!eglGetPlatformDisplayEXT) { 30cb93a386Sopenharmony_ci return EGL_NO_DISPLAY; 31cb93a386Sopenharmony_ci } 32cb93a386Sopenharmony_ci 33cb93a386Sopenharmony_ci // We currently only support D3D11 ANGLE. 34cb93a386Sopenharmony_ci static constexpr EGLint kType = EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE; 35cb93a386Sopenharmony_ci static constexpr EGLint attribs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, kType, EGL_NONE}; 36cb93a386Sopenharmony_ci return eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, hdc, attribs); 37cb93a386Sopenharmony_ci} 38cb93a386Sopenharmony_ci 39cb93a386Sopenharmony_ciclass ANGLEGLWindowContext_win : public GLWindowContext { 40cb93a386Sopenharmony_cipublic: 41cb93a386Sopenharmony_ci ANGLEGLWindowContext_win(HWND, const DisplayParams&); 42cb93a386Sopenharmony_ci ~ANGLEGLWindowContext_win() override; 43cb93a386Sopenharmony_ci 44cb93a386Sopenharmony_ciprotected: 45cb93a386Sopenharmony_ci void onSwapBuffers() override; 46cb93a386Sopenharmony_ci 47cb93a386Sopenharmony_ci sk_sp<const GrGLInterface> onInitializeContext() override; 48cb93a386Sopenharmony_ci void onDestroyContext() override; 49cb93a386Sopenharmony_ci 50cb93a386Sopenharmony_ciprivate: 51cb93a386Sopenharmony_ci HWND fHWND; 52cb93a386Sopenharmony_ci EGLDisplay fDisplay = EGL_NO_DISPLAY; 53cb93a386Sopenharmony_ci EGLContext fEGLContext = EGL_NO_CONTEXT; 54cb93a386Sopenharmony_ci EGLSurface fEGLSurface = EGL_NO_SURFACE; 55cb93a386Sopenharmony_ci 56cb93a386Sopenharmony_ci using INHERITED = GLWindowContext; 57cb93a386Sopenharmony_ci}; 58cb93a386Sopenharmony_ci 59cb93a386Sopenharmony_ciANGLEGLWindowContext_win::ANGLEGLWindowContext_win(HWND wnd, const DisplayParams& params) 60cb93a386Sopenharmony_ci : INHERITED(params), fHWND(wnd) { 61cb93a386Sopenharmony_ci this->initializeContext(); 62cb93a386Sopenharmony_ci} 63cb93a386Sopenharmony_ci 64cb93a386Sopenharmony_ciANGLEGLWindowContext_win::~ANGLEGLWindowContext_win() { this->destroyContext(); } 65cb93a386Sopenharmony_ci 66cb93a386Sopenharmony_cisk_sp<const GrGLInterface> ANGLEGLWindowContext_win::onInitializeContext() { 67cb93a386Sopenharmony_ci HDC dc = GetDC(fHWND); 68cb93a386Sopenharmony_ci fDisplay = get_angle_egl_display(dc); 69cb93a386Sopenharmony_ci if (EGL_NO_DISPLAY == fDisplay) { 70cb93a386Sopenharmony_ci return nullptr; 71cb93a386Sopenharmony_ci } 72cb93a386Sopenharmony_ci 73cb93a386Sopenharmony_ci EGLint majorVersion; 74cb93a386Sopenharmony_ci EGLint minorVersion; 75cb93a386Sopenharmony_ci if (!eglInitialize(fDisplay, &majorVersion, &minorVersion)) { 76cb93a386Sopenharmony_ci SkDebugf("Could not initialize display!\n"); 77cb93a386Sopenharmony_ci return nullptr; 78cb93a386Sopenharmony_ci } 79cb93a386Sopenharmony_ci EGLint numConfigs; 80cb93a386Sopenharmony_ci fSampleCount = this->getDisplayParams().fMSAASampleCount; 81cb93a386Sopenharmony_ci const int sampleBuffers = fSampleCount > 1 ? 1 : 0; 82cb93a386Sopenharmony_ci const int eglSampleCnt = fSampleCount > 1 ? fSampleCount : 0; 83cb93a386Sopenharmony_ci const EGLint configAttribs[] = {EGL_RENDERABLE_TYPE, 84cb93a386Sopenharmony_ci // We currently only support ES3. 85cb93a386Sopenharmony_ci EGL_OPENGL_ES3_BIT, 86cb93a386Sopenharmony_ci EGL_RED_SIZE, 87cb93a386Sopenharmony_ci 8, 88cb93a386Sopenharmony_ci EGL_GREEN_SIZE, 89cb93a386Sopenharmony_ci 8, 90cb93a386Sopenharmony_ci EGL_BLUE_SIZE, 91cb93a386Sopenharmony_ci 8, 92cb93a386Sopenharmony_ci EGL_ALPHA_SIZE, 93cb93a386Sopenharmony_ci 8, 94cb93a386Sopenharmony_ci EGL_SAMPLE_BUFFERS, 95cb93a386Sopenharmony_ci sampleBuffers, 96cb93a386Sopenharmony_ci EGL_SAMPLES, 97cb93a386Sopenharmony_ci eglSampleCnt, 98cb93a386Sopenharmony_ci EGL_NONE}; 99cb93a386Sopenharmony_ci 100cb93a386Sopenharmony_ci EGLConfig surfaceConfig; 101cb93a386Sopenharmony_ci if (!eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs)) { 102cb93a386Sopenharmony_ci SkDebugf("Could not create choose config!\n"); 103cb93a386Sopenharmony_ci return nullptr; 104cb93a386Sopenharmony_ci } 105cb93a386Sopenharmony_ci // We currently only support ES3. 106cb93a386Sopenharmony_ci const EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE}; 107cb93a386Sopenharmony_ci fEGLContext = eglCreateContext(fDisplay, surfaceConfig, nullptr, contextAttribs); 108cb93a386Sopenharmony_ci if (EGL_NO_CONTEXT == fEGLContext) { 109cb93a386Sopenharmony_ci SkDebugf("Could not create context!\n"); 110cb93a386Sopenharmony_ci return nullptr; 111cb93a386Sopenharmony_ci } 112cb93a386Sopenharmony_ci fEGLSurface = eglCreateWindowSurface(fDisplay, surfaceConfig, fHWND, nullptr); 113cb93a386Sopenharmony_ci if (EGL_NO_SURFACE == fEGLSurface) { 114cb93a386Sopenharmony_ci SkDebugf("Could not create surface!\n"); 115cb93a386Sopenharmony_ci return nullptr; 116cb93a386Sopenharmony_ci } 117cb93a386Sopenharmony_ci if (!eglMakeCurrent(fDisplay, fEGLSurface, fEGLSurface, fEGLContext)) { 118cb93a386Sopenharmony_ci SkDebugf("Could not make contxt current!\n"); 119cb93a386Sopenharmony_ci return nullptr; 120cb93a386Sopenharmony_ci } 121cb93a386Sopenharmony_ci 122cb93a386Sopenharmony_ci sk_sp<const GrGLInterface> interface(GrGLMakeAssembledInterface( 123cb93a386Sopenharmony_ci nullptr, 124cb93a386Sopenharmony_ci [](void* ctx, const char name[]) -> GrGLFuncPtr { return eglGetProcAddress(name); })); 125cb93a386Sopenharmony_ci if (interface) { 126cb93a386Sopenharmony_ci interface->fFunctions.fClearStencil(0); 127cb93a386Sopenharmony_ci interface->fFunctions.fClearColor(0, 0, 0, 0); 128cb93a386Sopenharmony_ci interface->fFunctions.fStencilMask(0xffffffff); 129cb93a386Sopenharmony_ci interface->fFunctions.fClear(GR_GL_STENCIL_BUFFER_BIT | GR_GL_COLOR_BUFFER_BIT); 130cb93a386Sopenharmony_ci 131cb93a386Sopenharmony_ci // use DescribePixelFormat to get the stencil depth. 132cb93a386Sopenharmony_ci int pixelFormat = GetPixelFormat(dc); 133cb93a386Sopenharmony_ci PIXELFORMATDESCRIPTOR pfd; 134cb93a386Sopenharmony_ci DescribePixelFormat(dc, pixelFormat, sizeof(pfd), &pfd); 135cb93a386Sopenharmony_ci fStencilBits = pfd.cStencilBits; 136cb93a386Sopenharmony_ci 137cb93a386Sopenharmony_ci RECT rect; 138cb93a386Sopenharmony_ci GetClientRect(fHWND, &rect); 139cb93a386Sopenharmony_ci fWidth = rect.right - rect.left; 140cb93a386Sopenharmony_ci fHeight = rect.bottom - rect.top; 141cb93a386Sopenharmony_ci interface->fFunctions.fViewport(0, 0, fWidth, fHeight); 142cb93a386Sopenharmony_ci } 143cb93a386Sopenharmony_ci return interface; 144cb93a386Sopenharmony_ci} 145cb93a386Sopenharmony_ci 146cb93a386Sopenharmony_civoid ANGLEGLWindowContext_win::onDestroyContext() { 147cb93a386Sopenharmony_ci eglMakeCurrent(fDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 148cb93a386Sopenharmony_ci if (EGL_NO_CONTEXT != fEGLContext) { 149cb93a386Sopenharmony_ci eglDestroyContext(fDisplay, fEGLContext); 150cb93a386Sopenharmony_ci } 151cb93a386Sopenharmony_ci if (EGL_NO_SURFACE != fEGLSurface) { 152cb93a386Sopenharmony_ci eglDestroySurface(fDisplay, fEGLSurface); 153cb93a386Sopenharmony_ci } 154cb93a386Sopenharmony_ci if (EGL_NO_DISPLAY != fDisplay) { 155cb93a386Sopenharmony_ci eglTerminate(fDisplay); 156cb93a386Sopenharmony_ci } 157cb93a386Sopenharmony_ci} 158cb93a386Sopenharmony_ci 159cb93a386Sopenharmony_civoid ANGLEGLWindowContext_win::onSwapBuffers() { 160cb93a386Sopenharmony_ci if (!eglSwapBuffers(fDisplay, fEGLSurface)) { 161cb93a386Sopenharmony_ci SkDebugf("Could not complete eglSwapBuffers.\n"); 162cb93a386Sopenharmony_ci } 163cb93a386Sopenharmony_ci} 164cb93a386Sopenharmony_ci 165cb93a386Sopenharmony_ci} // anonymous namespace 166cb93a386Sopenharmony_ci 167cb93a386Sopenharmony_cinamespace sk_app { 168cb93a386Sopenharmony_cinamespace window_context_factory { 169cb93a386Sopenharmony_ci 170cb93a386Sopenharmony_cistd::unique_ptr<WindowContext> MakeANGLEForWin(HWND wnd, const DisplayParams& params) { 171cb93a386Sopenharmony_ci std::unique_ptr<WindowContext> ctx(new ANGLEGLWindowContext_win(wnd, params)); 172cb93a386Sopenharmony_ci if (!ctx->isValid()) { 173cb93a386Sopenharmony_ci return nullptr; 174cb93a386Sopenharmony_ci } 175cb93a386Sopenharmony_ci return ctx; 176cb93a386Sopenharmony_ci} 177cb93a386Sopenharmony_ci 178cb93a386Sopenharmony_ci} // namespace window_context_factory 179cb93a386Sopenharmony_ci} // namespace sk_app 180