blob: 1b47dea3298d9f3ffd641cbd2e19f57f9fd13bcf [file] [log] [blame]
bsalomon@google.com2858b312012-04-02 20:44:38 +00001
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>
bsalomon@google.com2858b312012-04-02 20:44:38 +000013#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"
borenet@google.com0dd5ceb2012-08-28 15:15:49 +000027
28#define ANGLE_GL_CALL(IFACE, X) \
29 do { \
commit-bot@chromium.orgc72425a2014-01-21 16:09:18 +000030 (IFACE)->fFunctions.f##X; \
borenet@google.com0dd5ceb2012-08-28 15:15:49 +000031 } while (false)
32
bsalomon@google.com2858b312012-04-02 20:44:38 +000033#endif
34
35#define INVALIDATE_DELAY_MS 200
36
37static SkOSWindow* gCurrOSWin;
38static HWND gEventTarget;
39
40#define WM_EVENT_CALLBACK (WM_USER+0)
41
42void post_skwinevent()
43{
44 PostMessage(gEventTarget, WM_EVENT_CALLBACK, 0, 0);
45}
46
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +000047SkOSWindow::SkOSWindow(void* hWnd) {
48 fHWND = hWnd;
49#if SK_SUPPORT_GPU
bsalomon@google.com2858b312012-04-02 20:44:38 +000050#if SK_ANGLE
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +000051 fDisplay = EGL_NO_DISPLAY;
52 fContext = EGL_NO_CONTEXT;
53 fSurface = EGL_NO_SURFACE;
bsalomon@google.com2858b312012-04-02 20:44:38 +000054#endif
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +000055 fHGLRC = NULL;
56#endif
57 fAttached = kNone_BackEndType;
bsalomon@google.com2858b312012-04-02 20:44:38 +000058 gEventTarget = (HWND)hWnd;
59}
60
61SkOSWindow::~SkOSWindow() {
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +000062#if SK_SUPPORT_GPU
bsalomon@google.com2858b312012-04-02 20:44:38 +000063 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 }
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +000081#endif // SK_ANGLE
82#endif // SK_SUPPORT_GPU
bsalomon@google.com2858b312012-04-02 20:44:38 +000083}
84
85static 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
reed@google.com4d5c26d2013-01-08 16:17:50 +0000106static unsigned getModifiers(UINT message) {
107 return 0; // TODO
108}
109
bsalomon@google.com2858b312012-04-02 20:44:38 +0000110bool 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:
robertphillips@google.com8b169312013-10-15 17:47:36 +0000127 this->handleChar((SkUnichar) wParam);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000128 return true;
bsalomon@google.com2858b312012-04-02 20:44:38 +0000129 case WM_CHAR: {
130 this->handleChar(SkUTF8_ToUnichar((char*)&wParam));
131 return true;
132 } break;
robertphillips@google.coma4662862013-11-21 14:24:16 +0000133 case WM_SIZE: {
134 INT width = LOWORD(lParam);
135 INT height = HIWORD(lParam);
136 this->resize(width, height);
bsalomon@google.com2858b312012-04-02 20:44:38 +0000137 break;
robertphillips@google.coma4662862013-11-21 14:24:16 +0000138 }
bsalomon@google.com2858b312012-04-02 20:44:38 +0000139 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;
rmistry@google.comd6176b02012-08-23 18:14:13 +0000154
155 case WM_LBUTTONDOWN:
reed@google.com4d5c26d2013-01-08 16:17:50 +0000156 this->handleClick(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam),
reed@google.com72708fa2013-01-08 16:22:44 +0000157 Click::kDown_State, NULL, getModifiers(message));
bsalomon@google.com2858b312012-04-02 20:44:38 +0000158 return true;
rmistry@google.comd6176b02012-08-23 18:14:13 +0000159
bsalomon@google.com2858b312012-04-02 20:44:38 +0000160 case WM_MOUSEMOVE:
reed@google.com4d5c26d2013-01-08 16:17:50 +0000161 this->handleClick(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam),
reed@google.com72708fa2013-01-08 16:22:44 +0000162 Click::kMoved_State, NULL, getModifiers(message));
bsalomon@google.com2858b312012-04-02 20:44:38 +0000163 return true;
164
165 case WM_LBUTTONUP:
reed@google.com4d5c26d2013-01-08 16:17:50 +0000166 this->handleClick(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam),
reed@google.com72708fa2013-01-08 16:22:44 +0000167 Click::kUp_State, NULL, getModifiers(message));
bsalomon@google.com2858b312012-04-02 20:44:38 +0000168 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
179void 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();
rmistry@google.comd6176b02012-08-23 18:14:13 +0000191 bmi.bmiHeader.biHeight = -bitmap.height(); // top-down image
bsalomon@google.com2858b312012-04-02 20:44:38 +0000192 bmi.bmiHeader.biPlanes = 1;
193 bmi.bmiHeader.biBitCount = 32;
194 bmi.bmiHeader.biCompression = BI_RGB;
195 bmi.bmiHeader.biSizeImage = 0;
196
rmistry@google.comd6176b02012-08-23 18:14:13 +0000197 //
198 // Do the SetDIBitsToDevice.
199 //
bsalomon@google.com2858b312012-04-02 20:44:38 +0000200 // 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();
bsalomon@google.comb58a6392013-03-21 20:29:05 +0000208 int ret = SetDIBitsToDevice(hdc,
bsalomon@google.com2858b312012-04-02 20:44:38 +0000209 0, 0,
210 bitmap.width(), bitmap.height(),
211 0, 0,
212 0, bitmap.height(),
213 bitmap.getPixels(),
214 &bmi,
215 DIB_RGB_COLORS);
bsalomon@google.comb58a6392013-03-21 20:29:05 +0000216 (void)ret; // we're ignoring potential failures for now.
bsalomon@google.com2858b312012-04-02 20:44:38 +0000217 bitmap.unlockPixels();
218 }
219}
220
221#if 0
222void 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
230void 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
239void SkOSWindow::onAddMenu(const SkOSMenu* sk_menu)
240{
241}
242
243void SkOSWindow::onSetTitle(const char title[]){
244 SetWindowTextA((HWND)fHWND, title);
245}
246
247enum {
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,
rmistry@google.comd6176b02012-08-23 18:14:13 +0000255
bsalomon@google.com2858b312012-04-02 20:44:38 +0000256 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};
rmistry@google.comd6176b02012-08-23 18:14:13 +0000267
bsalomon@google.com2858b312012-04-02 20:44:38 +0000268static 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 };
rmistry@google.comd6176b02012-08-23 18:14:13 +0000292
bsalomon@google.com2858b312012-04-02 20:44:38 +0000293 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
301void SkEvent::SignalNonEmptyQueue()
302{
303 post_skwinevent();
304 //SkDebugf("signal nonempty\n");
305}
306
307static UINT_PTR gTimer;
308
309VOID 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
315void SkEvent::SignalQueueTimer(SkMSec delay)
316{
317 if (gTimer)
318 {
319 KillTimer(NULL, gTimer);
320 gTimer = NULL;
321 }
322 if (delay)
rmistry@google.comd6176b02012-08-23 18:14:13 +0000323 {
bsalomon@google.com2858b312012-04-02 20:44:38 +0000324 gTimer = SetTimer(NULL, 0, delay, sk_timer_proc);
325 //SkDebugf("SetTimer of %d returned %d\n", delay, gTimer);
326 }
327}
328
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000329#if SK_SUPPORT_GPU
bsalomon@google.com2858b312012-04-02 20:44:38 +0000330
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000331bool SkOSWindow::attachGL(int msaaSampleCount, AttachmentInfo* info) {
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000332 HDC dc = GetDC((HWND)fHWND);
bsalomon@google.com2858b312012-04-02 20:44:38 +0000333 if (NULL == fHGLRC) {
kkinnunen80549fc2014-06-30 06:36:31 -0700334 fHGLRC = SkCreateWGLContext(dc, msaaSampleCount,
335 kGLPreferCompatibilityProfile_SkWGLContextRequest);
bsalomon@google.com2858b312012-04-02 20:44:38 +0000336 if (NULL == fHGLRC) {
337 return false;
338 }
339 glClearStencil(0);
340 glClearColor(0, 0, 0, 0);
341 glStencilMask(0xffffffff);
342 glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
343 }
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000344 if (wglMakeCurrent(dc, (HGLRC)fHGLRC)) {
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000345 // use DescribePixelFormat to get the stencil bit depth.
346 int pixelFormat = GetPixelFormat(dc);
347 PIXELFORMATDESCRIPTOR pfd;
348 DescribePixelFormat(dc, pixelFormat, sizeof(pfd), &pfd);
349 info->fStencilBits = pfd.cStencilBits;
350
351 // Get sample count if the MSAA WGL extension is present
352 SkWGLExtensions extensions;
353 if (extensions.hasExtension(dc, "WGL_ARB_multisample")) {
354 static const int kSampleCountAttr = SK_WGL_SAMPLES;
355 extensions.getPixelFormatAttribiv(dc,
356 pixelFormat,
357 0,
358 1,
359 &kSampleCountAttr,
360 &info->fSampleCount);
361 } else {
362 info->fSampleCount = 0;
363 }
364
reed@google.come1ca7052013-12-17 19:22:07 +0000365 glViewport(0, 0,
366 SkScalarRoundToInt(this->width()),
367 SkScalarRoundToInt(this->height()));
bsalomon@google.com2858b312012-04-02 20:44:38 +0000368 return true;
369 }
370 return false;
371}
372
373void SkOSWindow::detachGL() {
374 wglMakeCurrent(GetDC((HWND)fHWND), 0);
375 wglDeleteContext((HGLRC)fHGLRC);
376 fHGLRC = NULL;
377}
378
379void SkOSWindow::presentGL() {
380 glFlush();
bungeman@google.comf44957e2013-03-12 17:27:10 +0000381 HDC dc = GetDC((HWND)fHWND);
382 SwapBuffers(dc);
383 ReleaseDC((HWND)fHWND, dc);
bsalomon@google.com2858b312012-04-02 20:44:38 +0000384}
385
386#if SK_ANGLE
bsalomon@google.com11959252012-04-06 20:13:38 +0000387bool create_ANGLE(EGLNativeWindowType hWnd,
388 int msaaSampleCount,
389 EGLDisplay* eglDisplay,
390 EGLContext* eglContext,
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000391 EGLSurface* eglSurface,
392 EGLConfig* eglConfig) {
bsalomon@google.com11959252012-04-06 20:13:38 +0000393 static const EGLint contextAttribs[] = {
394 EGL_CONTEXT_CLIENT_VERSION, 2,
rmistry@google.comd6176b02012-08-23 18:14:13 +0000395 EGL_NONE, EGL_NONE
bsalomon@google.com2858b312012-04-02 20:44:38 +0000396 };
bsalomon@google.com11959252012-04-06 20:13:38 +0000397 static const EGLint configAttribList[] = {
bsalomon@google.com2858b312012-04-02 20:44:38 +0000398 EGL_RED_SIZE, 8,
399 EGL_GREEN_SIZE, 8,
400 EGL_BLUE_SIZE, 8,
401 EGL_ALPHA_SIZE, 8,
402 EGL_DEPTH_SIZE, 8,
403 EGL_STENCIL_SIZE, 8,
404 EGL_NONE
405 };
bsalomon@google.com11959252012-04-06 20:13:38 +0000406 static const EGLint surfaceAttribList[] = {
bsalomon@google.com2858b312012-04-02 20:44:38 +0000407 EGL_NONE, EGL_NONE
408 };
409
410 EGLDisplay display = eglGetDisplay(GetDC(hWnd));
411 if (display == EGL_NO_DISPLAY ) {
412 return false;
413 }
414
415 // Initialize EGL
416 EGLint majorVersion, minorVersion;
417 if (!eglInitialize(display, &majorVersion, &minorVersion)) {
418 return false;
419 }
420
421 EGLint numConfigs;
422 if (!eglGetConfigs(display, NULL, 0, &numConfigs)) {
423 return false;
424 }
425
426 // Choose config
bsalomon@google.com11959252012-04-06 20:13:38 +0000427 bool foundConfig = false;
428 if (msaaSampleCount) {
429 static const int kConfigAttribListCnt =
430 SK_ARRAY_COUNT(configAttribList);
431 EGLint msaaConfigAttribList[kConfigAttribListCnt + 4];
432 memcpy(msaaConfigAttribList,
433 configAttribList,
434 sizeof(configAttribList));
435 SkASSERT(EGL_NONE == msaaConfigAttribList[kConfigAttribListCnt - 1]);
436 msaaConfigAttribList[kConfigAttribListCnt - 1] = EGL_SAMPLE_BUFFERS;
437 msaaConfigAttribList[kConfigAttribListCnt + 0] = 1;
438 msaaConfigAttribList[kConfigAttribListCnt + 1] = EGL_SAMPLES;
439 msaaConfigAttribList[kConfigAttribListCnt + 2] = msaaSampleCount;
440 msaaConfigAttribList[kConfigAttribListCnt + 3] = EGL_NONE;
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000441 if (eglChooseConfig(display, configAttribList, eglConfig, 1, &numConfigs)) {
bsalomon@google.com11959252012-04-06 20:13:38 +0000442 SkASSERT(numConfigs > 0);
443 foundConfig = true;
444 }
445 }
446 if (!foundConfig) {
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000447 if (!eglChooseConfig(display, configAttribList, eglConfig, 1, &numConfigs)) {
bsalomon@google.com11959252012-04-06 20:13:38 +0000448 return false;
449 }
bsalomon@google.com2858b312012-04-02 20:44:38 +0000450 }
451
452 // Create a surface
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000453 EGLSurface surface = eglCreateWindowSurface(display, *eglConfig,
rmistry@google.comd6176b02012-08-23 18:14:13 +0000454 (EGLNativeWindowType)hWnd,
bsalomon@google.com2858b312012-04-02 20:44:38 +0000455 surfaceAttribList);
456 if (surface == EGL_NO_SURFACE) {
457 return false;
458 }
459
460 // Create a GL context
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000461 EGLContext context = eglCreateContext(display, *eglConfig,
bsalomon@google.com2858b312012-04-02 20:44:38 +0000462 EGL_NO_CONTEXT,
463 contextAttribs );
464 if (context == EGL_NO_CONTEXT ) {
465 return false;
rmistry@google.comd6176b02012-08-23 18:14:13 +0000466 }
467
bsalomon@google.com2858b312012-04-02 20:44:38 +0000468 // Make the context current
469 if (!eglMakeCurrent(display, surface, surface, context)) {
470 return false;
471 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000472
bsalomon@google.com2858b312012-04-02 20:44:38 +0000473 *eglDisplay = display;
474 *eglContext = context;
475 *eglSurface = surface;
476 return true;
477}
478
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000479bool SkOSWindow::attachANGLE(int msaaSampleCount, AttachmentInfo* info) {
bsalomon@google.com2858b312012-04-02 20:44:38 +0000480 if (EGL_NO_DISPLAY == fDisplay) {
bsalomon@google.com11959252012-04-06 20:13:38 +0000481 bool bResult = create_ANGLE((HWND)fHWND,
482 msaaSampleCount,
483 &fDisplay,
484 &fContext,
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000485 &fSurface,
486 &fConfig);
bsalomon@google.com2858b312012-04-02 20:44:38 +0000487 if (false == bResult) {
488 return false;
489 }
bsalomon@google.com82502e22013-01-24 20:47:18 +0000490 SkAutoTUnref<const GrGLInterface> intf(GrGLCreateANGLEInterface());
bsalomon@google.com2858b312012-04-02 20:44:38 +0000491
492 if (intf) {
borenet@google.com0dd5ceb2012-08-28 15:15:49 +0000493 ANGLE_GL_CALL(intf, ClearStencil(0));
494 ANGLE_GL_CALL(intf, ClearColor(0, 0, 0, 0));
495 ANGLE_GL_CALL(intf, StencilMask(0xffffffff));
496 ANGLE_GL_CALL(intf, Clear(GL_STENCIL_BUFFER_BIT |GL_COLOR_BUFFER_BIT));
bsalomon@google.com2858b312012-04-02 20:44:38 +0000497 }
498 }
499 if (eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) {
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000500 eglGetConfigAttrib(fDisplay, fConfig, EGL_STENCIL_SIZE, &info->fStencilBits);
501 eglGetConfigAttrib(fDisplay, fConfig, EGL_SAMPLES, &info->fSampleCount);
502
bsalomon@google.com82502e22013-01-24 20:47:18 +0000503 SkAutoTUnref<const GrGLInterface> intf(GrGLCreateANGLEInterface());
bsalomon@google.com2858b312012-04-02 20:44:38 +0000504
505 if (intf ) {
reed@google.come1ca7052013-12-17 19:22:07 +0000506 ANGLE_GL_CALL(intf, Viewport(0, 0,
507 SkScalarRoundToInt(this->width()),
508 SkScalarRoundToInt(this->height())));
bsalomon@google.com2858b312012-04-02 20:44:38 +0000509 }
510 return true;
511 }
512 return false;
513}
514
515void SkOSWindow::detachANGLE() {
516 eglMakeCurrent(fDisplay, EGL_NO_SURFACE , EGL_NO_SURFACE , EGL_NO_CONTEXT);
517
518 eglDestroyContext(fDisplay, fContext);
519 fContext = EGL_NO_CONTEXT;
520
521 eglDestroySurface(fDisplay, fSurface);
522 fSurface = EGL_NO_SURFACE;
523
524 eglTerminate(fDisplay);
525 fDisplay = EGL_NO_DISPLAY;
526}
527
528void SkOSWindow::presentANGLE() {
bsalomon@google.com82502e22013-01-24 20:47:18 +0000529 SkAutoTUnref<const GrGLInterface> intf(GrGLCreateANGLEInterface());
bsalomon@google.com2858b312012-04-02 20:44:38 +0000530
531 if (intf) {
borenet@google.com0dd5ceb2012-08-28 15:15:49 +0000532 ANGLE_GL_CALL(intf, Flush());
bsalomon@google.com2858b312012-04-02 20:44:38 +0000533 }
534
535 eglSwapBuffers(fDisplay, fSurface);
536}
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000537#endif // SK_ANGLE
538#endif // SK_SUPPORT_GPU
bsalomon@google.com2858b312012-04-02 20:44:38 +0000539
bsalomon@google.com2858b312012-04-02 20:44:38 +0000540// return true on success
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000541bool SkOSWindow::attach(SkBackEndTypes attachType, int msaaSampleCount, AttachmentInfo* info) {
bsalomon@google.com2858b312012-04-02 20:44:38 +0000542
543 // attach doubles as "windowResize" so we need to allo
544 // already bound states to pass through again
545 // TODO: split out the resize functionality
546// SkASSERT(kNone_BackEndType == fAttached);
547 bool result = true;
548
549 switch (attachType) {
550 case kNone_BackEndType:
551 // nothing to do
rmistry@google.comd6176b02012-08-23 18:14:13 +0000552 break;
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000553#if SK_SUPPORT_GPU
bsalomon@google.com2858b312012-04-02 20:44:38 +0000554 case kNativeGL_BackEndType:
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000555 result = attachGL(msaaSampleCount, info);
bsalomon@google.com2858b312012-04-02 20:44:38 +0000556 break;
557#if SK_ANGLE
558 case kANGLE_BackEndType:
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000559 result = attachANGLE(msaaSampleCount, info);
bsalomon@google.com2858b312012-04-02 20:44:38 +0000560 break;
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000561#endif // SK_ANGLE
562#endif // SK_SUPPORT_GPU
bsalomon@google.com2858b312012-04-02 20:44:38 +0000563 default:
564 SkASSERT(false);
565 result = false;
566 break;
567 }
568
569 if (result) {
570 fAttached = attachType;
571 }
572
573 return result;
574}
575
576void SkOSWindow::detach() {
577 switch (fAttached) {
578 case kNone_BackEndType:
579 // nothing to do
rmistry@google.comd6176b02012-08-23 18:14:13 +0000580 break;
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000581#if SK_SUPPORT_GPU
bsalomon@google.com2858b312012-04-02 20:44:38 +0000582 case kNativeGL_BackEndType:
583 detachGL();
584 break;
585#if SK_ANGLE
586 case kANGLE_BackEndType:
587 detachANGLE();
588 break;
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000589#endif // SK_ANGLE
590#endif // SK_SUPPORT_GPU
bsalomon@google.com2858b312012-04-02 20:44:38 +0000591 default:
592 SkASSERT(false);
593 break;
594 }
595 fAttached = kNone_BackEndType;
596}
597
598void SkOSWindow::present() {
599 switch (fAttached) {
600 case kNone_BackEndType:
601 // nothing to do
rmistry@google.comd6176b02012-08-23 18:14:13 +0000602 return;
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000603#if SK_SUPPORT_GPU
bsalomon@google.com2858b312012-04-02 20:44:38 +0000604 case kNativeGL_BackEndType:
605 presentGL();
606 break;
607#if SK_ANGLE
608 case kANGLE_BackEndType:
609 presentANGLE();
610 break;
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000611#endif // SK_ANGLE
612#endif // SK_SUPPORT_GPU
bsalomon@google.com2858b312012-04-02 20:44:38 +0000613 default:
614 SkASSERT(false);
615 break;
616 }
617}
618
619#endif