1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/views/win/SkOSWindow_win.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,618 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2011 Google Inc. 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 +#include "SkTypes.h" 1.12 + 1.13 +#if defined(SK_BUILD_FOR_WIN) 1.14 + 1.15 +#include <GL/gl.h> 1.16 +#include <WindowsX.h> 1.17 +#include "SkWGL.h" 1.18 +#include "SkWindow.h" 1.19 +#include "SkCanvas.h" 1.20 +#include "SkOSMenu.h" 1.21 +#include "SkTime.h" 1.22 +#include "SkUtils.h" 1.23 + 1.24 +#include "SkGraphics.h" 1.25 + 1.26 +#if SK_ANGLE 1.27 +#include "gl/GrGLInterface.h" 1.28 + 1.29 +#include "GLES2/gl2.h" 1.30 + 1.31 +#define ANGLE_GL_CALL(IFACE, X) \ 1.32 + do { \ 1.33 + (IFACE)->fFunctions.f##X; \ 1.34 + } while (false) 1.35 + 1.36 +#endif 1.37 + 1.38 +#define INVALIDATE_DELAY_MS 200 1.39 + 1.40 +static SkOSWindow* gCurrOSWin; 1.41 +static HWND gEventTarget; 1.42 + 1.43 +#define WM_EVENT_CALLBACK (WM_USER+0) 1.44 + 1.45 +void post_skwinevent() 1.46 +{ 1.47 + PostMessage(gEventTarget, WM_EVENT_CALLBACK, 0, 0); 1.48 +} 1.49 + 1.50 +SkOSWindow::SkOSWindow(void* hWnd) { 1.51 + fHWND = hWnd; 1.52 +#if SK_SUPPORT_GPU 1.53 +#if SK_ANGLE 1.54 + fDisplay = EGL_NO_DISPLAY; 1.55 + fContext = EGL_NO_CONTEXT; 1.56 + fSurface = EGL_NO_SURFACE; 1.57 +#endif 1.58 + fHGLRC = NULL; 1.59 +#endif 1.60 + fAttached = kNone_BackEndType; 1.61 + gEventTarget = (HWND)hWnd; 1.62 +} 1.63 + 1.64 +SkOSWindow::~SkOSWindow() { 1.65 +#if SK_SUPPORT_GPU 1.66 + if (NULL != fHGLRC) { 1.67 + wglDeleteContext((HGLRC)fHGLRC); 1.68 + } 1.69 +#if SK_ANGLE 1.70 + if (EGL_NO_CONTEXT != fContext) { 1.71 + eglDestroyContext(fDisplay, fContext); 1.72 + fContext = EGL_NO_CONTEXT; 1.73 + } 1.74 + 1.75 + if (EGL_NO_SURFACE != fSurface) { 1.76 + eglDestroySurface(fDisplay, fSurface); 1.77 + fSurface = EGL_NO_SURFACE; 1.78 + } 1.79 + 1.80 + if (EGL_NO_DISPLAY != fDisplay) { 1.81 + eglTerminate(fDisplay); 1.82 + fDisplay = EGL_NO_DISPLAY; 1.83 + } 1.84 +#endif // SK_ANGLE 1.85 +#endif // SK_SUPPORT_GPU 1.86 +} 1.87 + 1.88 +static SkKey winToskKey(WPARAM vk) { 1.89 + static const struct { 1.90 + WPARAM fVK; 1.91 + SkKey fKey; 1.92 + } gPair[] = { 1.93 + { VK_BACK, kBack_SkKey }, 1.94 + { VK_CLEAR, kBack_SkKey }, 1.95 + { VK_RETURN, kOK_SkKey }, 1.96 + { VK_UP, kUp_SkKey }, 1.97 + { VK_DOWN, kDown_SkKey }, 1.98 + { VK_LEFT, kLeft_SkKey }, 1.99 + { VK_RIGHT, kRight_SkKey } 1.100 + }; 1.101 + for (size_t i = 0; i < SK_ARRAY_COUNT(gPair); i++) { 1.102 + if (gPair[i].fVK == vk) { 1.103 + return gPair[i].fKey; 1.104 + } 1.105 + } 1.106 + return kNONE_SkKey; 1.107 +} 1.108 + 1.109 +static unsigned getModifiers(UINT message) { 1.110 + return 0; // TODO 1.111 +} 1.112 + 1.113 +bool SkOSWindow::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { 1.114 + switch (message) { 1.115 + case WM_KEYDOWN: { 1.116 + SkKey key = winToskKey(wParam); 1.117 + if (kNONE_SkKey != key) { 1.118 + this->handleKey(key); 1.119 + return true; 1.120 + } 1.121 + } break; 1.122 + case WM_KEYUP: { 1.123 + SkKey key = winToskKey(wParam); 1.124 + if (kNONE_SkKey != key) { 1.125 + this->handleKeyUp(key); 1.126 + return true; 1.127 + } 1.128 + } break; 1.129 + case WM_UNICHAR: 1.130 + this->handleChar((SkUnichar) wParam); 1.131 + return true; 1.132 + case WM_CHAR: { 1.133 + this->handleChar(SkUTF8_ToUnichar((char*)&wParam)); 1.134 + return true; 1.135 + } break; 1.136 + case WM_SIZE: { 1.137 + INT width = LOWORD(lParam); 1.138 + INT height = HIWORD(lParam); 1.139 + this->resize(width, height); 1.140 + break; 1.141 + } 1.142 + case WM_PAINT: { 1.143 + PAINTSTRUCT ps; 1.144 + HDC hdc = BeginPaint(hWnd, &ps); 1.145 + this->doPaint(hdc); 1.146 + EndPaint(hWnd, &ps); 1.147 + return true; 1.148 + } break; 1.149 + 1.150 + case WM_TIMER: { 1.151 + RECT* rect = (RECT*)wParam; 1.152 + InvalidateRect(hWnd, rect, FALSE); 1.153 + KillTimer(hWnd, (UINT_PTR)rect); 1.154 + delete rect; 1.155 + return true; 1.156 + } break; 1.157 + 1.158 + case WM_LBUTTONDOWN: 1.159 + this->handleClick(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 1.160 + Click::kDown_State, NULL, getModifiers(message)); 1.161 + return true; 1.162 + 1.163 + case WM_MOUSEMOVE: 1.164 + this->handleClick(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 1.165 + Click::kMoved_State, NULL, getModifiers(message)); 1.166 + return true; 1.167 + 1.168 + case WM_LBUTTONUP: 1.169 + this->handleClick(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 1.170 + Click::kUp_State, NULL, getModifiers(message)); 1.171 + return true; 1.172 + 1.173 + case WM_EVENT_CALLBACK: 1.174 + if (SkEvent::ProcessEvent()) { 1.175 + post_skwinevent(); 1.176 + } 1.177 + return true; 1.178 + } 1.179 + return false; 1.180 +} 1.181 + 1.182 +void SkOSWindow::doPaint(void* ctx) { 1.183 + this->update(NULL); 1.184 + 1.185 + if (kNone_BackEndType == fAttached) 1.186 + { 1.187 + HDC hdc = (HDC)ctx; 1.188 + const SkBitmap& bitmap = this->getBitmap(); 1.189 + 1.190 + BITMAPINFO bmi; 1.191 + memset(&bmi, 0, sizeof(bmi)); 1.192 + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 1.193 + bmi.bmiHeader.biWidth = bitmap.width(); 1.194 + bmi.bmiHeader.biHeight = -bitmap.height(); // top-down image 1.195 + bmi.bmiHeader.biPlanes = 1; 1.196 + bmi.bmiHeader.biBitCount = 32; 1.197 + bmi.bmiHeader.biCompression = BI_RGB; 1.198 + bmi.bmiHeader.biSizeImage = 0; 1.199 + 1.200 + // 1.201 + // Do the SetDIBitsToDevice. 1.202 + // 1.203 + // TODO(wjmaclean): 1.204 + // Fix this call to handle SkBitmaps that have rowBytes != width, 1.205 + // i.e. may have padding at the end of lines. The SkASSERT below 1.206 + // may be ignored by builds, and the only obviously safe option 1.207 + // seems to be to copy the bitmap to a temporary (contiguous) 1.208 + // buffer before passing to SetDIBitsToDevice(). 1.209 + SkASSERT(bitmap.width() * bitmap.bytesPerPixel() == bitmap.rowBytes()); 1.210 + bitmap.lockPixels(); 1.211 + int ret = SetDIBitsToDevice(hdc, 1.212 + 0, 0, 1.213 + bitmap.width(), bitmap.height(), 1.214 + 0, 0, 1.215 + 0, bitmap.height(), 1.216 + bitmap.getPixels(), 1.217 + &bmi, 1.218 + DIB_RGB_COLORS); 1.219 + (void)ret; // we're ignoring potential failures for now. 1.220 + bitmap.unlockPixels(); 1.221 + } 1.222 +} 1.223 + 1.224 +#if 0 1.225 +void SkOSWindow::updateSize() 1.226 +{ 1.227 + RECT r; 1.228 + GetWindowRect((HWND)this->getHWND(), &r); 1.229 + this->resize(r.right - r.left, r.bottom - r.top); 1.230 +} 1.231 +#endif 1.232 + 1.233 +void SkOSWindow::onHandleInval(const SkIRect& r) { 1.234 + RECT* rect = new RECT; 1.235 + rect->left = r.fLeft; 1.236 + rect->top = r.fTop; 1.237 + rect->right = r.fRight; 1.238 + rect->bottom = r.fBottom; 1.239 + SetTimer((HWND)fHWND, (UINT_PTR)rect, INVALIDATE_DELAY_MS, NULL); 1.240 +} 1.241 + 1.242 +void SkOSWindow::onAddMenu(const SkOSMenu* sk_menu) 1.243 +{ 1.244 +} 1.245 + 1.246 +void SkOSWindow::onSetTitle(const char title[]){ 1.247 + SetWindowTextA((HWND)fHWND, title); 1.248 +} 1.249 + 1.250 +enum { 1.251 + SK_MacReturnKey = 36, 1.252 + SK_MacDeleteKey = 51, 1.253 + SK_MacEndKey = 119, 1.254 + SK_MacLeftKey = 123, 1.255 + SK_MacRightKey = 124, 1.256 + SK_MacDownKey = 125, 1.257 + SK_MacUpKey = 126, 1.258 + 1.259 + SK_Mac0Key = 0x52, 1.260 + SK_Mac1Key = 0x53, 1.261 + SK_Mac2Key = 0x54, 1.262 + SK_Mac3Key = 0x55, 1.263 + SK_Mac4Key = 0x56, 1.264 + SK_Mac5Key = 0x57, 1.265 + SK_Mac6Key = 0x58, 1.266 + SK_Mac7Key = 0x59, 1.267 + SK_Mac8Key = 0x5b, 1.268 + SK_Mac9Key = 0x5c 1.269 +}; 1.270 + 1.271 +static SkKey raw2key(uint32_t raw) 1.272 +{ 1.273 + static const struct { 1.274 + uint32_t fRaw; 1.275 + SkKey fKey; 1.276 + } gKeys[] = { 1.277 + { SK_MacUpKey, kUp_SkKey }, 1.278 + { SK_MacDownKey, kDown_SkKey }, 1.279 + { SK_MacLeftKey, kLeft_SkKey }, 1.280 + { SK_MacRightKey, kRight_SkKey }, 1.281 + { SK_MacReturnKey, kOK_SkKey }, 1.282 + { SK_MacDeleteKey, kBack_SkKey }, 1.283 + { SK_MacEndKey, kEnd_SkKey }, 1.284 + { SK_Mac0Key, k0_SkKey }, 1.285 + { SK_Mac1Key, k1_SkKey }, 1.286 + { SK_Mac2Key, k2_SkKey }, 1.287 + { SK_Mac3Key, k3_SkKey }, 1.288 + { SK_Mac4Key, k4_SkKey }, 1.289 + { SK_Mac5Key, k5_SkKey }, 1.290 + { SK_Mac6Key, k6_SkKey }, 1.291 + { SK_Mac7Key, k7_SkKey }, 1.292 + { SK_Mac8Key, k8_SkKey }, 1.293 + { SK_Mac9Key, k9_SkKey } 1.294 + }; 1.295 + 1.296 + for (unsigned i = 0; i < SK_ARRAY_COUNT(gKeys); i++) 1.297 + if (gKeys[i].fRaw == raw) 1.298 + return gKeys[i].fKey; 1.299 + return kNONE_SkKey; 1.300 +} 1.301 + 1.302 +/////////////////////////////////////////////////////////////////////////////////////// 1.303 + 1.304 +void SkEvent::SignalNonEmptyQueue() 1.305 +{ 1.306 + post_skwinevent(); 1.307 + //SkDebugf("signal nonempty\n"); 1.308 +} 1.309 + 1.310 +static UINT_PTR gTimer; 1.311 + 1.312 +VOID CALLBACK sk_timer_proc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) 1.313 +{ 1.314 + SkEvent::ServiceQueueTimer(); 1.315 + //SkDebugf("timer task fired\n"); 1.316 +} 1.317 + 1.318 +void SkEvent::SignalQueueTimer(SkMSec delay) 1.319 +{ 1.320 + if (gTimer) 1.321 + { 1.322 + KillTimer(NULL, gTimer); 1.323 + gTimer = NULL; 1.324 + } 1.325 + if (delay) 1.326 + { 1.327 + gTimer = SetTimer(NULL, 0, delay, sk_timer_proc); 1.328 + //SkDebugf("SetTimer of %d returned %d\n", delay, gTimer); 1.329 + } 1.330 +} 1.331 + 1.332 +#if SK_SUPPORT_GPU 1.333 + 1.334 +bool SkOSWindow::attachGL(int msaaSampleCount, AttachmentInfo* info) { 1.335 + HDC dc = GetDC((HWND)fHWND); 1.336 + if (NULL == fHGLRC) { 1.337 + fHGLRC = SkCreateWGLContext(dc, msaaSampleCount, false); 1.338 + if (NULL == fHGLRC) { 1.339 + return false; 1.340 + } 1.341 + glClearStencil(0); 1.342 + glClearColor(0, 0, 0, 0); 1.343 + glStencilMask(0xffffffff); 1.344 + glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 1.345 + } 1.346 + if (wglMakeCurrent(dc, (HGLRC)fHGLRC)) { 1.347 + // use DescribePixelFormat to get the stencil bit depth. 1.348 + int pixelFormat = GetPixelFormat(dc); 1.349 + PIXELFORMATDESCRIPTOR pfd; 1.350 + DescribePixelFormat(dc, pixelFormat, sizeof(pfd), &pfd); 1.351 + info->fStencilBits = pfd.cStencilBits; 1.352 + 1.353 + // Get sample count if the MSAA WGL extension is present 1.354 + SkWGLExtensions extensions; 1.355 + if (extensions.hasExtension(dc, "WGL_ARB_multisample")) { 1.356 + static const int kSampleCountAttr = SK_WGL_SAMPLES; 1.357 + extensions.getPixelFormatAttribiv(dc, 1.358 + pixelFormat, 1.359 + 0, 1.360 + 1, 1.361 + &kSampleCountAttr, 1.362 + &info->fSampleCount); 1.363 + } else { 1.364 + info->fSampleCount = 0; 1.365 + } 1.366 + 1.367 + glViewport(0, 0, 1.368 + SkScalarRoundToInt(this->width()), 1.369 + SkScalarRoundToInt(this->height())); 1.370 + return true; 1.371 + } 1.372 + return false; 1.373 +} 1.374 + 1.375 +void SkOSWindow::detachGL() { 1.376 + wglMakeCurrent(GetDC((HWND)fHWND), 0); 1.377 + wglDeleteContext((HGLRC)fHGLRC); 1.378 + fHGLRC = NULL; 1.379 +} 1.380 + 1.381 +void SkOSWindow::presentGL() { 1.382 + glFlush(); 1.383 + HDC dc = GetDC((HWND)fHWND); 1.384 + SwapBuffers(dc); 1.385 + ReleaseDC((HWND)fHWND, dc); 1.386 +} 1.387 + 1.388 +#if SK_ANGLE 1.389 +bool create_ANGLE(EGLNativeWindowType hWnd, 1.390 + int msaaSampleCount, 1.391 + EGLDisplay* eglDisplay, 1.392 + EGLContext* eglContext, 1.393 + EGLSurface* eglSurface, 1.394 + EGLConfig* eglConfig) { 1.395 + static const EGLint contextAttribs[] = { 1.396 + EGL_CONTEXT_CLIENT_VERSION, 2, 1.397 + EGL_NONE, EGL_NONE 1.398 + }; 1.399 + static const EGLint configAttribList[] = { 1.400 + EGL_RED_SIZE, 8, 1.401 + EGL_GREEN_SIZE, 8, 1.402 + EGL_BLUE_SIZE, 8, 1.403 + EGL_ALPHA_SIZE, 8, 1.404 + EGL_DEPTH_SIZE, 8, 1.405 + EGL_STENCIL_SIZE, 8, 1.406 + EGL_NONE 1.407 + }; 1.408 + static const EGLint surfaceAttribList[] = { 1.409 + EGL_NONE, EGL_NONE 1.410 + }; 1.411 + 1.412 + EGLDisplay display = eglGetDisplay(GetDC(hWnd)); 1.413 + if (display == EGL_NO_DISPLAY ) { 1.414 + return false; 1.415 + } 1.416 + 1.417 + // Initialize EGL 1.418 + EGLint majorVersion, minorVersion; 1.419 + if (!eglInitialize(display, &majorVersion, &minorVersion)) { 1.420 + return false; 1.421 + } 1.422 + 1.423 + EGLint numConfigs; 1.424 + if (!eglGetConfigs(display, NULL, 0, &numConfigs)) { 1.425 + return false; 1.426 + } 1.427 + 1.428 + // Choose config 1.429 + bool foundConfig = false; 1.430 + if (msaaSampleCount) { 1.431 + static const int kConfigAttribListCnt = 1.432 + SK_ARRAY_COUNT(configAttribList); 1.433 + EGLint msaaConfigAttribList[kConfigAttribListCnt + 4]; 1.434 + memcpy(msaaConfigAttribList, 1.435 + configAttribList, 1.436 + sizeof(configAttribList)); 1.437 + SkASSERT(EGL_NONE == msaaConfigAttribList[kConfigAttribListCnt - 1]); 1.438 + msaaConfigAttribList[kConfigAttribListCnt - 1] = EGL_SAMPLE_BUFFERS; 1.439 + msaaConfigAttribList[kConfigAttribListCnt + 0] = 1; 1.440 + msaaConfigAttribList[kConfigAttribListCnt + 1] = EGL_SAMPLES; 1.441 + msaaConfigAttribList[kConfigAttribListCnt + 2] = msaaSampleCount; 1.442 + msaaConfigAttribList[kConfigAttribListCnt + 3] = EGL_NONE; 1.443 + if (eglChooseConfig(display, configAttribList, eglConfig, 1, &numConfigs)) { 1.444 + SkASSERT(numConfigs > 0); 1.445 + foundConfig = true; 1.446 + } 1.447 + } 1.448 + if (!foundConfig) { 1.449 + if (!eglChooseConfig(display, configAttribList, eglConfig, 1, &numConfigs)) { 1.450 + return false; 1.451 + } 1.452 + } 1.453 + 1.454 + // Create a surface 1.455 + EGLSurface surface = eglCreateWindowSurface(display, *eglConfig, 1.456 + (EGLNativeWindowType)hWnd, 1.457 + surfaceAttribList); 1.458 + if (surface == EGL_NO_SURFACE) { 1.459 + return false; 1.460 + } 1.461 + 1.462 + // Create a GL context 1.463 + EGLContext context = eglCreateContext(display, *eglConfig, 1.464 + EGL_NO_CONTEXT, 1.465 + contextAttribs ); 1.466 + if (context == EGL_NO_CONTEXT ) { 1.467 + return false; 1.468 + } 1.469 + 1.470 + // Make the context current 1.471 + if (!eglMakeCurrent(display, surface, surface, context)) { 1.472 + return false; 1.473 + } 1.474 + 1.475 + *eglDisplay = display; 1.476 + *eglContext = context; 1.477 + *eglSurface = surface; 1.478 + return true; 1.479 +} 1.480 + 1.481 +bool SkOSWindow::attachANGLE(int msaaSampleCount, AttachmentInfo* info) { 1.482 + if (EGL_NO_DISPLAY == fDisplay) { 1.483 + bool bResult = create_ANGLE((HWND)fHWND, 1.484 + msaaSampleCount, 1.485 + &fDisplay, 1.486 + &fContext, 1.487 + &fSurface, 1.488 + &fConfig); 1.489 + if (false == bResult) { 1.490 + return false; 1.491 + } 1.492 + SkAutoTUnref<const GrGLInterface> intf(GrGLCreateANGLEInterface()); 1.493 + 1.494 + if (intf) { 1.495 + ANGLE_GL_CALL(intf, ClearStencil(0)); 1.496 + ANGLE_GL_CALL(intf, ClearColor(0, 0, 0, 0)); 1.497 + ANGLE_GL_CALL(intf, StencilMask(0xffffffff)); 1.498 + ANGLE_GL_CALL(intf, Clear(GL_STENCIL_BUFFER_BIT |GL_COLOR_BUFFER_BIT)); 1.499 + } 1.500 + } 1.501 + if (eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { 1.502 + eglGetConfigAttrib(fDisplay, fConfig, EGL_STENCIL_SIZE, &info->fStencilBits); 1.503 + eglGetConfigAttrib(fDisplay, fConfig, EGL_SAMPLES, &info->fSampleCount); 1.504 + 1.505 + SkAutoTUnref<const GrGLInterface> intf(GrGLCreateANGLEInterface()); 1.506 + 1.507 + if (intf ) { 1.508 + ANGLE_GL_CALL(intf, Viewport(0, 0, 1.509 + SkScalarRoundToInt(this->width()), 1.510 + SkScalarRoundToInt(this->height()))); 1.511 + } 1.512 + return true; 1.513 + } 1.514 + return false; 1.515 +} 1.516 + 1.517 +void SkOSWindow::detachANGLE() { 1.518 + eglMakeCurrent(fDisplay, EGL_NO_SURFACE , EGL_NO_SURFACE , EGL_NO_CONTEXT); 1.519 + 1.520 + eglDestroyContext(fDisplay, fContext); 1.521 + fContext = EGL_NO_CONTEXT; 1.522 + 1.523 + eglDestroySurface(fDisplay, fSurface); 1.524 + fSurface = EGL_NO_SURFACE; 1.525 + 1.526 + eglTerminate(fDisplay); 1.527 + fDisplay = EGL_NO_DISPLAY; 1.528 +} 1.529 + 1.530 +void SkOSWindow::presentANGLE() { 1.531 + SkAutoTUnref<const GrGLInterface> intf(GrGLCreateANGLEInterface()); 1.532 + 1.533 + if (intf) { 1.534 + ANGLE_GL_CALL(intf, Flush()); 1.535 + } 1.536 + 1.537 + eglSwapBuffers(fDisplay, fSurface); 1.538 +} 1.539 +#endif // SK_ANGLE 1.540 +#endif // SK_SUPPORT_GPU 1.541 + 1.542 +// return true on success 1.543 +bool SkOSWindow::attach(SkBackEndTypes attachType, int msaaSampleCount, AttachmentInfo* info) { 1.544 + 1.545 + // attach doubles as "windowResize" so we need to allo 1.546 + // already bound states to pass through again 1.547 + // TODO: split out the resize functionality 1.548 +// SkASSERT(kNone_BackEndType == fAttached); 1.549 + bool result = true; 1.550 + 1.551 + switch (attachType) { 1.552 + case kNone_BackEndType: 1.553 + // nothing to do 1.554 + break; 1.555 +#if SK_SUPPORT_GPU 1.556 + case kNativeGL_BackEndType: 1.557 + result = attachGL(msaaSampleCount, info); 1.558 + break; 1.559 +#if SK_ANGLE 1.560 + case kANGLE_BackEndType: 1.561 + result = attachANGLE(msaaSampleCount, info); 1.562 + break; 1.563 +#endif // SK_ANGLE 1.564 +#endif // SK_SUPPORT_GPU 1.565 + default: 1.566 + SkASSERT(false); 1.567 + result = false; 1.568 + break; 1.569 + } 1.570 + 1.571 + if (result) { 1.572 + fAttached = attachType; 1.573 + } 1.574 + 1.575 + return result; 1.576 +} 1.577 + 1.578 +void SkOSWindow::detach() { 1.579 + switch (fAttached) { 1.580 + case kNone_BackEndType: 1.581 + // nothing to do 1.582 + break; 1.583 +#if SK_SUPPORT_GPU 1.584 + case kNativeGL_BackEndType: 1.585 + detachGL(); 1.586 + break; 1.587 +#if SK_ANGLE 1.588 + case kANGLE_BackEndType: 1.589 + detachANGLE(); 1.590 + break; 1.591 +#endif // SK_ANGLE 1.592 +#endif // SK_SUPPORT_GPU 1.593 + default: 1.594 + SkASSERT(false); 1.595 + break; 1.596 + } 1.597 + fAttached = kNone_BackEndType; 1.598 +} 1.599 + 1.600 +void SkOSWindow::present() { 1.601 + switch (fAttached) { 1.602 + case kNone_BackEndType: 1.603 + // nothing to do 1.604 + return; 1.605 +#if SK_SUPPORT_GPU 1.606 + case kNativeGL_BackEndType: 1.607 + presentGL(); 1.608 + break; 1.609 +#if SK_ANGLE 1.610 + case kANGLE_BackEndType: 1.611 + presentANGLE(); 1.612 + break; 1.613 +#endif // SK_ANGLE 1.614 +#endif // SK_SUPPORT_GPU 1.615 + default: 1.616 + SkASSERT(false); 1.617 + break; 1.618 + } 1.619 +} 1.620 + 1.621 +#endif