|
1 |
|
2 /* |
|
3 * Copyright 2011 Google Inc. |
|
4 * |
|
5 * Use of this source code is governed by a BSD-style license that can be |
|
6 * found in the LICENSE file. |
|
7 */ |
|
8 #include "SkTypes.h" |
|
9 |
|
10 #if defined(SK_BUILD_FOR_WIN) |
|
11 |
|
12 #include <GL/gl.h> |
|
13 #include <WindowsX.h> |
|
14 #include "SkWGL.h" |
|
15 #include "SkWindow.h" |
|
16 #include "SkCanvas.h" |
|
17 #include "SkOSMenu.h" |
|
18 #include "SkTime.h" |
|
19 #include "SkUtils.h" |
|
20 |
|
21 #include "SkGraphics.h" |
|
22 |
|
23 #if SK_ANGLE |
|
24 #include "gl/GrGLInterface.h" |
|
25 |
|
26 #include "GLES2/gl2.h" |
|
27 |
|
28 #define ANGLE_GL_CALL(IFACE, X) \ |
|
29 do { \ |
|
30 (IFACE)->fFunctions.f##X; \ |
|
31 } while (false) |
|
32 |
|
33 #endif |
|
34 |
|
35 #define INVALIDATE_DELAY_MS 200 |
|
36 |
|
37 static SkOSWindow* gCurrOSWin; |
|
38 static HWND gEventTarget; |
|
39 |
|
40 #define WM_EVENT_CALLBACK (WM_USER+0) |
|
41 |
|
42 void post_skwinevent() |
|
43 { |
|
44 PostMessage(gEventTarget, WM_EVENT_CALLBACK, 0, 0); |
|
45 } |
|
46 |
|
47 SkOSWindow::SkOSWindow(void* hWnd) { |
|
48 fHWND = hWnd; |
|
49 #if SK_SUPPORT_GPU |
|
50 #if SK_ANGLE |
|
51 fDisplay = EGL_NO_DISPLAY; |
|
52 fContext = EGL_NO_CONTEXT; |
|
53 fSurface = EGL_NO_SURFACE; |
|
54 #endif |
|
55 fHGLRC = NULL; |
|
56 #endif |
|
57 fAttached = kNone_BackEndType; |
|
58 gEventTarget = (HWND)hWnd; |
|
59 } |
|
60 |
|
61 SkOSWindow::~SkOSWindow() { |
|
62 #if SK_SUPPORT_GPU |
|
63 if (NULL != fHGLRC) { |
|
64 wglDeleteContext((HGLRC)fHGLRC); |
|
65 } |
|
66 #if SK_ANGLE |
|
67 if (EGL_NO_CONTEXT != fContext) { |
|
68 eglDestroyContext(fDisplay, fContext); |
|
69 fContext = EGL_NO_CONTEXT; |
|
70 } |
|
71 |
|
72 if (EGL_NO_SURFACE != fSurface) { |
|
73 eglDestroySurface(fDisplay, fSurface); |
|
74 fSurface = EGL_NO_SURFACE; |
|
75 } |
|
76 |
|
77 if (EGL_NO_DISPLAY != fDisplay) { |
|
78 eglTerminate(fDisplay); |
|
79 fDisplay = EGL_NO_DISPLAY; |
|
80 } |
|
81 #endif // SK_ANGLE |
|
82 #endif // SK_SUPPORT_GPU |
|
83 } |
|
84 |
|
85 static SkKey winToskKey(WPARAM vk) { |
|
86 static const struct { |
|
87 WPARAM fVK; |
|
88 SkKey fKey; |
|
89 } gPair[] = { |
|
90 { VK_BACK, kBack_SkKey }, |
|
91 { VK_CLEAR, kBack_SkKey }, |
|
92 { VK_RETURN, kOK_SkKey }, |
|
93 { VK_UP, kUp_SkKey }, |
|
94 { VK_DOWN, kDown_SkKey }, |
|
95 { VK_LEFT, kLeft_SkKey }, |
|
96 { VK_RIGHT, kRight_SkKey } |
|
97 }; |
|
98 for (size_t i = 0; i < SK_ARRAY_COUNT(gPair); i++) { |
|
99 if (gPair[i].fVK == vk) { |
|
100 return gPair[i].fKey; |
|
101 } |
|
102 } |
|
103 return kNONE_SkKey; |
|
104 } |
|
105 |
|
106 static unsigned getModifiers(UINT message) { |
|
107 return 0; // TODO |
|
108 } |
|
109 |
|
110 bool SkOSWindow::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { |
|
111 switch (message) { |
|
112 case WM_KEYDOWN: { |
|
113 SkKey key = winToskKey(wParam); |
|
114 if (kNONE_SkKey != key) { |
|
115 this->handleKey(key); |
|
116 return true; |
|
117 } |
|
118 } break; |
|
119 case WM_KEYUP: { |
|
120 SkKey key = winToskKey(wParam); |
|
121 if (kNONE_SkKey != key) { |
|
122 this->handleKeyUp(key); |
|
123 return true; |
|
124 } |
|
125 } break; |
|
126 case WM_UNICHAR: |
|
127 this->handleChar((SkUnichar) wParam); |
|
128 return true; |
|
129 case WM_CHAR: { |
|
130 this->handleChar(SkUTF8_ToUnichar((char*)&wParam)); |
|
131 return true; |
|
132 } break; |
|
133 case WM_SIZE: { |
|
134 INT width = LOWORD(lParam); |
|
135 INT height = HIWORD(lParam); |
|
136 this->resize(width, height); |
|
137 break; |
|
138 } |
|
139 case WM_PAINT: { |
|
140 PAINTSTRUCT ps; |
|
141 HDC hdc = BeginPaint(hWnd, &ps); |
|
142 this->doPaint(hdc); |
|
143 EndPaint(hWnd, &ps); |
|
144 return true; |
|
145 } break; |
|
146 |
|
147 case WM_TIMER: { |
|
148 RECT* rect = (RECT*)wParam; |
|
149 InvalidateRect(hWnd, rect, FALSE); |
|
150 KillTimer(hWnd, (UINT_PTR)rect); |
|
151 delete rect; |
|
152 return true; |
|
153 } break; |
|
154 |
|
155 case WM_LBUTTONDOWN: |
|
156 this->handleClick(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), |
|
157 Click::kDown_State, NULL, getModifiers(message)); |
|
158 return true; |
|
159 |
|
160 case WM_MOUSEMOVE: |
|
161 this->handleClick(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), |
|
162 Click::kMoved_State, NULL, getModifiers(message)); |
|
163 return true; |
|
164 |
|
165 case WM_LBUTTONUP: |
|
166 this->handleClick(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), |
|
167 Click::kUp_State, NULL, getModifiers(message)); |
|
168 return true; |
|
169 |
|
170 case WM_EVENT_CALLBACK: |
|
171 if (SkEvent::ProcessEvent()) { |
|
172 post_skwinevent(); |
|
173 } |
|
174 return true; |
|
175 } |
|
176 return false; |
|
177 } |
|
178 |
|
179 void SkOSWindow::doPaint(void* ctx) { |
|
180 this->update(NULL); |
|
181 |
|
182 if (kNone_BackEndType == fAttached) |
|
183 { |
|
184 HDC hdc = (HDC)ctx; |
|
185 const SkBitmap& bitmap = this->getBitmap(); |
|
186 |
|
187 BITMAPINFO bmi; |
|
188 memset(&bmi, 0, sizeof(bmi)); |
|
189 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); |
|
190 bmi.bmiHeader.biWidth = bitmap.width(); |
|
191 bmi.bmiHeader.biHeight = -bitmap.height(); // top-down image |
|
192 bmi.bmiHeader.biPlanes = 1; |
|
193 bmi.bmiHeader.biBitCount = 32; |
|
194 bmi.bmiHeader.biCompression = BI_RGB; |
|
195 bmi.bmiHeader.biSizeImage = 0; |
|
196 |
|
197 // |
|
198 // Do the SetDIBitsToDevice. |
|
199 // |
|
200 // TODO(wjmaclean): |
|
201 // Fix this call to handle SkBitmaps that have rowBytes != width, |
|
202 // i.e. may have padding at the end of lines. The SkASSERT below |
|
203 // may be ignored by builds, and the only obviously safe option |
|
204 // seems to be to copy the bitmap to a temporary (contiguous) |
|
205 // buffer before passing to SetDIBitsToDevice(). |
|
206 SkASSERT(bitmap.width() * bitmap.bytesPerPixel() == bitmap.rowBytes()); |
|
207 bitmap.lockPixels(); |
|
208 int ret = SetDIBitsToDevice(hdc, |
|
209 0, 0, |
|
210 bitmap.width(), bitmap.height(), |
|
211 0, 0, |
|
212 0, bitmap.height(), |
|
213 bitmap.getPixels(), |
|
214 &bmi, |
|
215 DIB_RGB_COLORS); |
|
216 (void)ret; // we're ignoring potential failures for now. |
|
217 bitmap.unlockPixels(); |
|
218 } |
|
219 } |
|
220 |
|
221 #if 0 |
|
222 void SkOSWindow::updateSize() |
|
223 { |
|
224 RECT r; |
|
225 GetWindowRect((HWND)this->getHWND(), &r); |
|
226 this->resize(r.right - r.left, r.bottom - r.top); |
|
227 } |
|
228 #endif |
|
229 |
|
230 void SkOSWindow::onHandleInval(const SkIRect& r) { |
|
231 RECT* rect = new RECT; |
|
232 rect->left = r.fLeft; |
|
233 rect->top = r.fTop; |
|
234 rect->right = r.fRight; |
|
235 rect->bottom = r.fBottom; |
|
236 SetTimer((HWND)fHWND, (UINT_PTR)rect, INVALIDATE_DELAY_MS, NULL); |
|
237 } |
|
238 |
|
239 void SkOSWindow::onAddMenu(const SkOSMenu* sk_menu) |
|
240 { |
|
241 } |
|
242 |
|
243 void SkOSWindow::onSetTitle(const char title[]){ |
|
244 SetWindowTextA((HWND)fHWND, title); |
|
245 } |
|
246 |
|
247 enum { |
|
248 SK_MacReturnKey = 36, |
|
249 SK_MacDeleteKey = 51, |
|
250 SK_MacEndKey = 119, |
|
251 SK_MacLeftKey = 123, |
|
252 SK_MacRightKey = 124, |
|
253 SK_MacDownKey = 125, |
|
254 SK_MacUpKey = 126, |
|
255 |
|
256 SK_Mac0Key = 0x52, |
|
257 SK_Mac1Key = 0x53, |
|
258 SK_Mac2Key = 0x54, |
|
259 SK_Mac3Key = 0x55, |
|
260 SK_Mac4Key = 0x56, |
|
261 SK_Mac5Key = 0x57, |
|
262 SK_Mac6Key = 0x58, |
|
263 SK_Mac7Key = 0x59, |
|
264 SK_Mac8Key = 0x5b, |
|
265 SK_Mac9Key = 0x5c |
|
266 }; |
|
267 |
|
268 static SkKey raw2key(uint32_t raw) |
|
269 { |
|
270 static const struct { |
|
271 uint32_t fRaw; |
|
272 SkKey fKey; |
|
273 } gKeys[] = { |
|
274 { SK_MacUpKey, kUp_SkKey }, |
|
275 { SK_MacDownKey, kDown_SkKey }, |
|
276 { SK_MacLeftKey, kLeft_SkKey }, |
|
277 { SK_MacRightKey, kRight_SkKey }, |
|
278 { SK_MacReturnKey, kOK_SkKey }, |
|
279 { SK_MacDeleteKey, kBack_SkKey }, |
|
280 { SK_MacEndKey, kEnd_SkKey }, |
|
281 { SK_Mac0Key, k0_SkKey }, |
|
282 { SK_Mac1Key, k1_SkKey }, |
|
283 { SK_Mac2Key, k2_SkKey }, |
|
284 { SK_Mac3Key, k3_SkKey }, |
|
285 { SK_Mac4Key, k4_SkKey }, |
|
286 { SK_Mac5Key, k5_SkKey }, |
|
287 { SK_Mac6Key, k6_SkKey }, |
|
288 { SK_Mac7Key, k7_SkKey }, |
|
289 { SK_Mac8Key, k8_SkKey }, |
|
290 { SK_Mac9Key, k9_SkKey } |
|
291 }; |
|
292 |
|
293 for (unsigned i = 0; i < SK_ARRAY_COUNT(gKeys); i++) |
|
294 if (gKeys[i].fRaw == raw) |
|
295 return gKeys[i].fKey; |
|
296 return kNONE_SkKey; |
|
297 } |
|
298 |
|
299 /////////////////////////////////////////////////////////////////////////////////////// |
|
300 |
|
301 void SkEvent::SignalNonEmptyQueue() |
|
302 { |
|
303 post_skwinevent(); |
|
304 //SkDebugf("signal nonempty\n"); |
|
305 } |
|
306 |
|
307 static UINT_PTR gTimer; |
|
308 |
|
309 VOID CALLBACK sk_timer_proc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) |
|
310 { |
|
311 SkEvent::ServiceQueueTimer(); |
|
312 //SkDebugf("timer task fired\n"); |
|
313 } |
|
314 |
|
315 void SkEvent::SignalQueueTimer(SkMSec delay) |
|
316 { |
|
317 if (gTimer) |
|
318 { |
|
319 KillTimer(NULL, gTimer); |
|
320 gTimer = NULL; |
|
321 } |
|
322 if (delay) |
|
323 { |
|
324 gTimer = SetTimer(NULL, 0, delay, sk_timer_proc); |
|
325 //SkDebugf("SetTimer of %d returned %d\n", delay, gTimer); |
|
326 } |
|
327 } |
|
328 |
|
329 #if SK_SUPPORT_GPU |
|
330 |
|
331 bool SkOSWindow::attachGL(int msaaSampleCount, AttachmentInfo* info) { |
|
332 HDC dc = GetDC((HWND)fHWND); |
|
333 if (NULL == fHGLRC) { |
|
334 fHGLRC = SkCreateWGLContext(dc, msaaSampleCount, false); |
|
335 if (NULL == fHGLRC) { |
|
336 return false; |
|
337 } |
|
338 glClearStencil(0); |
|
339 glClearColor(0, 0, 0, 0); |
|
340 glStencilMask(0xffffffff); |
|
341 glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); |
|
342 } |
|
343 if (wglMakeCurrent(dc, (HGLRC)fHGLRC)) { |
|
344 // use DescribePixelFormat to get the stencil bit depth. |
|
345 int pixelFormat = GetPixelFormat(dc); |
|
346 PIXELFORMATDESCRIPTOR pfd; |
|
347 DescribePixelFormat(dc, pixelFormat, sizeof(pfd), &pfd); |
|
348 info->fStencilBits = pfd.cStencilBits; |
|
349 |
|
350 // Get sample count if the MSAA WGL extension is present |
|
351 SkWGLExtensions extensions; |
|
352 if (extensions.hasExtension(dc, "WGL_ARB_multisample")) { |
|
353 static const int kSampleCountAttr = SK_WGL_SAMPLES; |
|
354 extensions.getPixelFormatAttribiv(dc, |
|
355 pixelFormat, |
|
356 0, |
|
357 1, |
|
358 &kSampleCountAttr, |
|
359 &info->fSampleCount); |
|
360 } else { |
|
361 info->fSampleCount = 0; |
|
362 } |
|
363 |
|
364 glViewport(0, 0, |
|
365 SkScalarRoundToInt(this->width()), |
|
366 SkScalarRoundToInt(this->height())); |
|
367 return true; |
|
368 } |
|
369 return false; |
|
370 } |
|
371 |
|
372 void SkOSWindow::detachGL() { |
|
373 wglMakeCurrent(GetDC((HWND)fHWND), 0); |
|
374 wglDeleteContext((HGLRC)fHGLRC); |
|
375 fHGLRC = NULL; |
|
376 } |
|
377 |
|
378 void SkOSWindow::presentGL() { |
|
379 glFlush(); |
|
380 HDC dc = GetDC((HWND)fHWND); |
|
381 SwapBuffers(dc); |
|
382 ReleaseDC((HWND)fHWND, dc); |
|
383 } |
|
384 |
|
385 #if SK_ANGLE |
|
386 bool create_ANGLE(EGLNativeWindowType hWnd, |
|
387 int msaaSampleCount, |
|
388 EGLDisplay* eglDisplay, |
|
389 EGLContext* eglContext, |
|
390 EGLSurface* eglSurface, |
|
391 EGLConfig* eglConfig) { |
|
392 static const EGLint contextAttribs[] = { |
|
393 EGL_CONTEXT_CLIENT_VERSION, 2, |
|
394 EGL_NONE, EGL_NONE |
|
395 }; |
|
396 static const EGLint configAttribList[] = { |
|
397 EGL_RED_SIZE, 8, |
|
398 EGL_GREEN_SIZE, 8, |
|
399 EGL_BLUE_SIZE, 8, |
|
400 EGL_ALPHA_SIZE, 8, |
|
401 EGL_DEPTH_SIZE, 8, |
|
402 EGL_STENCIL_SIZE, 8, |
|
403 EGL_NONE |
|
404 }; |
|
405 static const EGLint surfaceAttribList[] = { |
|
406 EGL_NONE, EGL_NONE |
|
407 }; |
|
408 |
|
409 EGLDisplay display = eglGetDisplay(GetDC(hWnd)); |
|
410 if (display == EGL_NO_DISPLAY ) { |
|
411 return false; |
|
412 } |
|
413 |
|
414 // Initialize EGL |
|
415 EGLint majorVersion, minorVersion; |
|
416 if (!eglInitialize(display, &majorVersion, &minorVersion)) { |
|
417 return false; |
|
418 } |
|
419 |
|
420 EGLint numConfigs; |
|
421 if (!eglGetConfigs(display, NULL, 0, &numConfigs)) { |
|
422 return false; |
|
423 } |
|
424 |
|
425 // Choose config |
|
426 bool foundConfig = false; |
|
427 if (msaaSampleCount) { |
|
428 static const int kConfigAttribListCnt = |
|
429 SK_ARRAY_COUNT(configAttribList); |
|
430 EGLint msaaConfigAttribList[kConfigAttribListCnt + 4]; |
|
431 memcpy(msaaConfigAttribList, |
|
432 configAttribList, |
|
433 sizeof(configAttribList)); |
|
434 SkASSERT(EGL_NONE == msaaConfigAttribList[kConfigAttribListCnt - 1]); |
|
435 msaaConfigAttribList[kConfigAttribListCnt - 1] = EGL_SAMPLE_BUFFERS; |
|
436 msaaConfigAttribList[kConfigAttribListCnt + 0] = 1; |
|
437 msaaConfigAttribList[kConfigAttribListCnt + 1] = EGL_SAMPLES; |
|
438 msaaConfigAttribList[kConfigAttribListCnt + 2] = msaaSampleCount; |
|
439 msaaConfigAttribList[kConfigAttribListCnt + 3] = EGL_NONE; |
|
440 if (eglChooseConfig(display, configAttribList, eglConfig, 1, &numConfigs)) { |
|
441 SkASSERT(numConfigs > 0); |
|
442 foundConfig = true; |
|
443 } |
|
444 } |
|
445 if (!foundConfig) { |
|
446 if (!eglChooseConfig(display, configAttribList, eglConfig, 1, &numConfigs)) { |
|
447 return false; |
|
448 } |
|
449 } |
|
450 |
|
451 // Create a surface |
|
452 EGLSurface surface = eglCreateWindowSurface(display, *eglConfig, |
|
453 (EGLNativeWindowType)hWnd, |
|
454 surfaceAttribList); |
|
455 if (surface == EGL_NO_SURFACE) { |
|
456 return false; |
|
457 } |
|
458 |
|
459 // Create a GL context |
|
460 EGLContext context = eglCreateContext(display, *eglConfig, |
|
461 EGL_NO_CONTEXT, |
|
462 contextAttribs ); |
|
463 if (context == EGL_NO_CONTEXT ) { |
|
464 return false; |
|
465 } |
|
466 |
|
467 // Make the context current |
|
468 if (!eglMakeCurrent(display, surface, surface, context)) { |
|
469 return false; |
|
470 } |
|
471 |
|
472 *eglDisplay = display; |
|
473 *eglContext = context; |
|
474 *eglSurface = surface; |
|
475 return true; |
|
476 } |
|
477 |
|
478 bool SkOSWindow::attachANGLE(int msaaSampleCount, AttachmentInfo* info) { |
|
479 if (EGL_NO_DISPLAY == fDisplay) { |
|
480 bool bResult = create_ANGLE((HWND)fHWND, |
|
481 msaaSampleCount, |
|
482 &fDisplay, |
|
483 &fContext, |
|
484 &fSurface, |
|
485 &fConfig); |
|
486 if (false == bResult) { |
|
487 return false; |
|
488 } |
|
489 SkAutoTUnref<const GrGLInterface> intf(GrGLCreateANGLEInterface()); |
|
490 |
|
491 if (intf) { |
|
492 ANGLE_GL_CALL(intf, ClearStencil(0)); |
|
493 ANGLE_GL_CALL(intf, ClearColor(0, 0, 0, 0)); |
|
494 ANGLE_GL_CALL(intf, StencilMask(0xffffffff)); |
|
495 ANGLE_GL_CALL(intf, Clear(GL_STENCIL_BUFFER_BIT |GL_COLOR_BUFFER_BIT)); |
|
496 } |
|
497 } |
|
498 if (eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { |
|
499 eglGetConfigAttrib(fDisplay, fConfig, EGL_STENCIL_SIZE, &info->fStencilBits); |
|
500 eglGetConfigAttrib(fDisplay, fConfig, EGL_SAMPLES, &info->fSampleCount); |
|
501 |
|
502 SkAutoTUnref<const GrGLInterface> intf(GrGLCreateANGLEInterface()); |
|
503 |
|
504 if (intf ) { |
|
505 ANGLE_GL_CALL(intf, Viewport(0, 0, |
|
506 SkScalarRoundToInt(this->width()), |
|
507 SkScalarRoundToInt(this->height()))); |
|
508 } |
|
509 return true; |
|
510 } |
|
511 return false; |
|
512 } |
|
513 |
|
514 void SkOSWindow::detachANGLE() { |
|
515 eglMakeCurrent(fDisplay, EGL_NO_SURFACE , EGL_NO_SURFACE , EGL_NO_CONTEXT); |
|
516 |
|
517 eglDestroyContext(fDisplay, fContext); |
|
518 fContext = EGL_NO_CONTEXT; |
|
519 |
|
520 eglDestroySurface(fDisplay, fSurface); |
|
521 fSurface = EGL_NO_SURFACE; |
|
522 |
|
523 eglTerminate(fDisplay); |
|
524 fDisplay = EGL_NO_DISPLAY; |
|
525 } |
|
526 |
|
527 void SkOSWindow::presentANGLE() { |
|
528 SkAutoTUnref<const GrGLInterface> intf(GrGLCreateANGLEInterface()); |
|
529 |
|
530 if (intf) { |
|
531 ANGLE_GL_CALL(intf, Flush()); |
|
532 } |
|
533 |
|
534 eglSwapBuffers(fDisplay, fSurface); |
|
535 } |
|
536 #endif // SK_ANGLE |
|
537 #endif // SK_SUPPORT_GPU |
|
538 |
|
539 // return true on success |
|
540 bool SkOSWindow::attach(SkBackEndTypes attachType, int msaaSampleCount, AttachmentInfo* info) { |
|
541 |
|
542 // attach doubles as "windowResize" so we need to allo |
|
543 // already bound states to pass through again |
|
544 // TODO: split out the resize functionality |
|
545 // SkASSERT(kNone_BackEndType == fAttached); |
|
546 bool result = true; |
|
547 |
|
548 switch (attachType) { |
|
549 case kNone_BackEndType: |
|
550 // nothing to do |
|
551 break; |
|
552 #if SK_SUPPORT_GPU |
|
553 case kNativeGL_BackEndType: |
|
554 result = attachGL(msaaSampleCount, info); |
|
555 break; |
|
556 #if SK_ANGLE |
|
557 case kANGLE_BackEndType: |
|
558 result = attachANGLE(msaaSampleCount, info); |
|
559 break; |
|
560 #endif // SK_ANGLE |
|
561 #endif // SK_SUPPORT_GPU |
|
562 default: |
|
563 SkASSERT(false); |
|
564 result = false; |
|
565 break; |
|
566 } |
|
567 |
|
568 if (result) { |
|
569 fAttached = attachType; |
|
570 } |
|
571 |
|
572 return result; |
|
573 } |
|
574 |
|
575 void SkOSWindow::detach() { |
|
576 switch (fAttached) { |
|
577 case kNone_BackEndType: |
|
578 // nothing to do |
|
579 break; |
|
580 #if SK_SUPPORT_GPU |
|
581 case kNativeGL_BackEndType: |
|
582 detachGL(); |
|
583 break; |
|
584 #if SK_ANGLE |
|
585 case kANGLE_BackEndType: |
|
586 detachANGLE(); |
|
587 break; |
|
588 #endif // SK_ANGLE |
|
589 #endif // SK_SUPPORT_GPU |
|
590 default: |
|
591 SkASSERT(false); |
|
592 break; |
|
593 } |
|
594 fAttached = kNone_BackEndType; |
|
595 } |
|
596 |
|
597 void SkOSWindow::present() { |
|
598 switch (fAttached) { |
|
599 case kNone_BackEndType: |
|
600 // nothing to do |
|
601 return; |
|
602 #if SK_SUPPORT_GPU |
|
603 case kNativeGL_BackEndType: |
|
604 presentGL(); |
|
605 break; |
|
606 #if SK_ANGLE |
|
607 case kANGLE_BackEndType: |
|
608 presentANGLE(); |
|
609 break; |
|
610 #endif // SK_ANGLE |
|
611 #endif // SK_SUPPORT_GPU |
|
612 default: |
|
613 SkASSERT(false); |
|
614 break; |
|
615 } |
|
616 } |
|
617 |
|
618 #endif |