blob: 150be6aa70ba869eece22026631aeb2050c0ba64 [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 { \
30 (IFACE)->f##X; \
31 } 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
106bool SkOSWindow::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
107 switch (message) {
108 case WM_KEYDOWN: {
109 SkKey key = winToskKey(wParam);
110 if (kNONE_SkKey != key) {
111 this->handleKey(key);
112 return true;
113 }
114 } break;
115 case WM_KEYUP: {
116 SkKey key = winToskKey(wParam);
117 if (kNONE_SkKey != key) {
118 this->handleKeyUp(key);
119 return true;
120 }
121 } break;
122 case WM_UNICHAR:
123 this->handleChar(wParam);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000124 return true;
bsalomon@google.com2858b312012-04-02 20:44:38 +0000125 case WM_CHAR: {
126 this->handleChar(SkUTF8_ToUnichar((char*)&wParam));
127 return true;
128 } break;
129 case WM_SIZE:
130 this->resize(lParam & 0xFFFF, lParam >> 16);
131 break;
132 case WM_PAINT: {
133 PAINTSTRUCT ps;
134 HDC hdc = BeginPaint(hWnd, &ps);
135 this->doPaint(hdc);
136 EndPaint(hWnd, &ps);
137 return true;
138 } break;
139
140 case WM_TIMER: {
141 RECT* rect = (RECT*)wParam;
142 InvalidateRect(hWnd, rect, FALSE);
143 KillTimer(hWnd, (UINT_PTR)rect);
144 delete rect;
145 return true;
146 } break;
rmistry@google.comd6176b02012-08-23 18:14:13 +0000147
148 case WM_LBUTTONDOWN:
bsalomon@google.com2858b312012-04-02 20:44:38 +0000149 this->handleClick(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), Click::kDown_State);
150 return true;
rmistry@google.comd6176b02012-08-23 18:14:13 +0000151
bsalomon@google.com2858b312012-04-02 20:44:38 +0000152 case WM_MOUSEMOVE:
153 this->handleClick(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), Click::kMoved_State);
154 return true;
155
156 case WM_LBUTTONUP:
157 this->handleClick(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), Click::kUp_State);
158 return true;
159
160 case WM_EVENT_CALLBACK:
161 if (SkEvent::ProcessEvent()) {
162 post_skwinevent();
163 }
164 return true;
165 }
166 return false;
167}
168
169void SkOSWindow::doPaint(void* ctx) {
170 this->update(NULL);
171
172 if (kNone_BackEndType == fAttached)
173 {
174 HDC hdc = (HDC)ctx;
175 const SkBitmap& bitmap = this->getBitmap();
176
177 BITMAPINFO bmi;
178 memset(&bmi, 0, sizeof(bmi));
179 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
180 bmi.bmiHeader.biWidth = bitmap.width();
rmistry@google.comd6176b02012-08-23 18:14:13 +0000181 bmi.bmiHeader.biHeight = -bitmap.height(); // top-down image
bsalomon@google.com2858b312012-04-02 20:44:38 +0000182 bmi.bmiHeader.biPlanes = 1;
183 bmi.bmiHeader.biBitCount = 32;
184 bmi.bmiHeader.biCompression = BI_RGB;
185 bmi.bmiHeader.biSizeImage = 0;
186
rmistry@google.comd6176b02012-08-23 18:14:13 +0000187 //
188 // Do the SetDIBitsToDevice.
189 //
bsalomon@google.com2858b312012-04-02 20:44:38 +0000190 // TODO(wjmaclean):
191 // Fix this call to handle SkBitmaps that have rowBytes != width,
192 // i.e. may have padding at the end of lines. The SkASSERT below
193 // may be ignored by builds, and the only obviously safe option
194 // seems to be to copy the bitmap to a temporary (contiguous)
195 // buffer before passing to SetDIBitsToDevice().
196 SkASSERT(bitmap.width() * bitmap.bytesPerPixel() == bitmap.rowBytes());
197 bitmap.lockPixels();
198 int iRet = SetDIBitsToDevice(hdc,
199 0, 0,
200 bitmap.width(), bitmap.height(),
201 0, 0,
202 0, bitmap.height(),
203 bitmap.getPixels(),
204 &bmi,
205 DIB_RGB_COLORS);
206 bitmap.unlockPixels();
207 }
208}
209
210#if 0
211void SkOSWindow::updateSize()
212{
213 RECT r;
214 GetWindowRect((HWND)this->getHWND(), &r);
215 this->resize(r.right - r.left, r.bottom - r.top);
216}
217#endif
218
219void SkOSWindow::onHandleInval(const SkIRect& r) {
220 RECT* rect = new RECT;
221 rect->left = r.fLeft;
222 rect->top = r.fTop;
223 rect->right = r.fRight;
224 rect->bottom = r.fBottom;
225 SetTimer((HWND)fHWND, (UINT_PTR)rect, INVALIDATE_DELAY_MS, NULL);
226}
227
228void SkOSWindow::onAddMenu(const SkOSMenu* sk_menu)
229{
230}
231
232void SkOSWindow::onSetTitle(const char title[]){
233 SetWindowTextA((HWND)fHWND, title);
234}
235
236enum {
237 SK_MacReturnKey = 36,
238 SK_MacDeleteKey = 51,
239 SK_MacEndKey = 119,
240 SK_MacLeftKey = 123,
241 SK_MacRightKey = 124,
242 SK_MacDownKey = 125,
243 SK_MacUpKey = 126,
rmistry@google.comd6176b02012-08-23 18:14:13 +0000244
bsalomon@google.com2858b312012-04-02 20:44:38 +0000245 SK_Mac0Key = 0x52,
246 SK_Mac1Key = 0x53,
247 SK_Mac2Key = 0x54,
248 SK_Mac3Key = 0x55,
249 SK_Mac4Key = 0x56,
250 SK_Mac5Key = 0x57,
251 SK_Mac6Key = 0x58,
252 SK_Mac7Key = 0x59,
253 SK_Mac8Key = 0x5b,
254 SK_Mac9Key = 0x5c
255};
rmistry@google.comd6176b02012-08-23 18:14:13 +0000256
bsalomon@google.com2858b312012-04-02 20:44:38 +0000257static SkKey raw2key(uint32_t raw)
258{
259 static const struct {
260 uint32_t fRaw;
261 SkKey fKey;
262 } gKeys[] = {
263 { SK_MacUpKey, kUp_SkKey },
264 { SK_MacDownKey, kDown_SkKey },
265 { SK_MacLeftKey, kLeft_SkKey },
266 { SK_MacRightKey, kRight_SkKey },
267 { SK_MacReturnKey, kOK_SkKey },
268 { SK_MacDeleteKey, kBack_SkKey },
269 { SK_MacEndKey, kEnd_SkKey },
270 { SK_Mac0Key, k0_SkKey },
271 { SK_Mac1Key, k1_SkKey },
272 { SK_Mac2Key, k2_SkKey },
273 { SK_Mac3Key, k3_SkKey },
274 { SK_Mac4Key, k4_SkKey },
275 { SK_Mac5Key, k5_SkKey },
276 { SK_Mac6Key, k6_SkKey },
277 { SK_Mac7Key, k7_SkKey },
278 { SK_Mac8Key, k8_SkKey },
279 { SK_Mac9Key, k9_SkKey }
280 };
rmistry@google.comd6176b02012-08-23 18:14:13 +0000281
bsalomon@google.com2858b312012-04-02 20:44:38 +0000282 for (unsigned i = 0; i < SK_ARRAY_COUNT(gKeys); i++)
283 if (gKeys[i].fRaw == raw)
284 return gKeys[i].fKey;
285 return kNONE_SkKey;
286}
287
288///////////////////////////////////////////////////////////////////////////////////////
289
290void SkEvent::SignalNonEmptyQueue()
291{
292 post_skwinevent();
293 //SkDebugf("signal nonempty\n");
294}
295
296static UINT_PTR gTimer;
297
298VOID CALLBACK sk_timer_proc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
299{
300 SkEvent::ServiceQueueTimer();
301 //SkDebugf("timer task fired\n");
302}
303
304void SkEvent::SignalQueueTimer(SkMSec delay)
305{
306 if (gTimer)
307 {
308 KillTimer(NULL, gTimer);
309 gTimer = NULL;
310 }
311 if (delay)
rmistry@google.comd6176b02012-08-23 18:14:13 +0000312 {
bsalomon@google.com2858b312012-04-02 20:44:38 +0000313 gTimer = SetTimer(NULL, 0, delay, sk_timer_proc);
314 //SkDebugf("SetTimer of %d returned %d\n", delay, gTimer);
315 }
316}
317
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000318#if SK_SUPPORT_GPU
bsalomon@google.com11959252012-04-06 20:13:38 +0000319HGLRC create_gl(HWND hwnd, int msaaSampleCount) {
bsalomon@google.com2858b312012-04-02 20:44:38 +0000320
321 HDC dc = GetDC(hwnd);
322
323 SkWGLExtensions extensions;
324 if (!extensions.hasExtension(dc, "WGL_ARB_pixel_format")) {
325 return NULL;
326 }
327
328 HDC prevDC = wglGetCurrentDC();
329 HGLRC prevGLRC = wglGetCurrentContext();
330 PIXELFORMATDESCRIPTOR pfd;
331
332 int format = 0;
333
bsalomon@google.com11959252012-04-06 20:13:38 +0000334 static const GLint iAttrs[] = {
bsalomon@google.com2858b312012-04-02 20:44:38 +0000335 SK_WGL_DRAW_TO_WINDOW, TRUE,
336 SK_WGL_DOUBLE_BUFFER, TRUE,
337 SK_WGL_ACCELERATION, SK_WGL_FULL_ACCELERATION,
338 SK_WGL_SUPPORT_OPENGL, TRUE,
339 SK_WGL_COLOR_BITS, 24,
340 SK_WGL_ALPHA_BITS, 8,
341 SK_WGL_STENCIL_BITS, 8,
bsalomon@google.com11959252012-04-06 20:13:38 +0000342 0, 0
bsalomon@google.com2858b312012-04-02 20:44:38 +0000343 };
344
bsalomon@google.com11959252012-04-06 20:13:38 +0000345 GLfloat fAttrs[] = {0, 0};
346
347 if (msaaSampleCount > 0 &&
348 extensions.hasExtension(dc, "WGL_ARB_multisample")) {
349 static const int kIAttrsCount = SK_ARRAY_COUNT(iAttrs);
bsalomon@google.com8a189b02012-04-17 12:43:00 +0000350 GLint msaaIAttrs[kIAttrsCount + 6];
bsalomon@google.com11959252012-04-06 20:13:38 +0000351 memcpy(msaaIAttrs, iAttrs, sizeof(GLint) * kIAttrsCount);
352 SkASSERT(0 == msaaIAttrs[kIAttrsCount - 2] &&
353 0 == msaaIAttrs[kIAttrsCount - 1]);
354 msaaIAttrs[kIAttrsCount - 2] = SK_WGL_SAMPLE_BUFFERS;
355 msaaIAttrs[kIAttrsCount - 1] = TRUE;
356 msaaIAttrs[kIAttrsCount + 0] = SK_WGL_SAMPLES;
357 msaaIAttrs[kIAttrsCount + 1] = msaaSampleCount;
bsalomon@google.com8a189b02012-04-17 12:43:00 +0000358 if (extensions.hasExtension(dc, "WGL_NV_multisample_coverage")) {
359 msaaIAttrs[kIAttrsCount + 2] = SK_WGL_COLOR_SAMPLES;
360 // We want the fewest number of color samples possible.
361 // Passing 0 gives only the formats where all samples are color
362 // samples.
363 msaaIAttrs[kIAttrsCount + 3] = 1;
364 msaaIAttrs[kIAttrsCount + 4] = 0;
365 msaaIAttrs[kIAttrsCount + 5] = 0;
366 } else {
367 msaaIAttrs[kIAttrsCount + 2] = 0;
368 msaaIAttrs[kIAttrsCount + 3] = 0;
369 }
bsalomon@google.com11959252012-04-06 20:13:38 +0000370 GLuint num;
371 int formats[64];
372 extensions.choosePixelFormat(dc, msaaIAttrs, fAttrs, 64, formats, &num);
373 num = min(num,64);
bsalomon@google.com8a189b02012-04-17 12:43:00 +0000374 int formatToTry = extensions.selectFormat(formats,
375 num,
376 dc,
377 msaaSampleCount);
378 DescribePixelFormat(dc, formatToTry, sizeof(pfd), &pfd);
379 if (SetPixelFormat(dc, formatToTry, &pfd)) {
380 format = formatToTry;
bsalomon@google.com2858b312012-04-02 20:44:38 +0000381 }
382 }
383
384 if (0 == format) {
bsalomon@google.com2858b312012-04-02 20:44:38 +0000385 GLuint num;
bsalomon@google.com11959252012-04-06 20:13:38 +0000386 extensions.choosePixelFormat(dc, iAttrs, fAttrs, 1, &format, &num);
bsalomon@google.com2858b312012-04-02 20:44:38 +0000387 DescribePixelFormat(dc, format, sizeof(pfd), &pfd);
388 BOOL set = SetPixelFormat(dc, format, &pfd);
389 SkASSERT(TRUE == set);
390 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000391
bsalomon@google.com2858b312012-04-02 20:44:38 +0000392 HGLRC glrc = wglCreateContext(dc);
393 SkASSERT(glrc);
394
395 wglMakeCurrent(prevDC, prevGLRC);
396 return glrc;
397}
398
bsalomon@google.com11959252012-04-06 20:13:38 +0000399bool SkOSWindow::attachGL(int msaaSampleCount) {
bsalomon@google.com2858b312012-04-02 20:44:38 +0000400 if (NULL == fHGLRC) {
bsalomon@google.com11959252012-04-06 20:13:38 +0000401 fHGLRC = create_gl((HWND)fHWND, msaaSampleCount);
bsalomon@google.com2858b312012-04-02 20:44:38 +0000402 if (NULL == fHGLRC) {
403 return false;
404 }
405 glClearStencil(0);
406 glClearColor(0, 0, 0, 0);
407 glStencilMask(0xffffffff);
408 glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
409 }
410 if (wglMakeCurrent(GetDC((HWND)fHWND), (HGLRC)fHGLRC)) {
411 glViewport(0, 0, SkScalarRound(this->width()),
412 SkScalarRound(this->height()));
413 return true;
414 }
415 return false;
416}
417
418void SkOSWindow::detachGL() {
419 wglMakeCurrent(GetDC((HWND)fHWND), 0);
420 wglDeleteContext((HGLRC)fHGLRC);
421 fHGLRC = NULL;
422}
423
424void SkOSWindow::presentGL() {
425 glFlush();
426 SwapBuffers(GetDC((HWND)fHWND));
427}
428
429#if SK_ANGLE
bsalomon@google.com11959252012-04-06 20:13:38 +0000430bool create_ANGLE(EGLNativeWindowType hWnd,
431 int msaaSampleCount,
432 EGLDisplay* eglDisplay,
433 EGLContext* eglContext,
434 EGLSurface* eglSurface) {
435 static const EGLint contextAttribs[] = {
436 EGL_CONTEXT_CLIENT_VERSION, 2,
rmistry@google.comd6176b02012-08-23 18:14:13 +0000437 EGL_NONE, EGL_NONE
bsalomon@google.com2858b312012-04-02 20:44:38 +0000438 };
bsalomon@google.com11959252012-04-06 20:13:38 +0000439 static const EGLint configAttribList[] = {
bsalomon@google.com2858b312012-04-02 20:44:38 +0000440 EGL_RED_SIZE, 8,
441 EGL_GREEN_SIZE, 8,
442 EGL_BLUE_SIZE, 8,
443 EGL_ALPHA_SIZE, 8,
444 EGL_DEPTH_SIZE, 8,
445 EGL_STENCIL_SIZE, 8,
446 EGL_NONE
447 };
bsalomon@google.com11959252012-04-06 20:13:38 +0000448 static const EGLint surfaceAttribList[] = {
bsalomon@google.com2858b312012-04-02 20:44:38 +0000449 EGL_NONE, EGL_NONE
450 };
451
452 EGLDisplay display = eglGetDisplay(GetDC(hWnd));
453 if (display == EGL_NO_DISPLAY ) {
454 return false;
455 }
456
457 // Initialize EGL
458 EGLint majorVersion, minorVersion;
459 if (!eglInitialize(display, &majorVersion, &minorVersion)) {
460 return false;
461 }
462
463 EGLint numConfigs;
464 if (!eglGetConfigs(display, NULL, 0, &numConfigs)) {
465 return false;
466 }
467
468 // Choose config
469 EGLConfig config;
bsalomon@google.com11959252012-04-06 20:13:38 +0000470 bool foundConfig = false;
471 if (msaaSampleCount) {
472 static const int kConfigAttribListCnt =
473 SK_ARRAY_COUNT(configAttribList);
474 EGLint msaaConfigAttribList[kConfigAttribListCnt + 4];
475 memcpy(msaaConfigAttribList,
476 configAttribList,
477 sizeof(configAttribList));
478 SkASSERT(EGL_NONE == msaaConfigAttribList[kConfigAttribListCnt - 1]);
479 msaaConfigAttribList[kConfigAttribListCnt - 1] = EGL_SAMPLE_BUFFERS;
480 msaaConfigAttribList[kConfigAttribListCnt + 0] = 1;
481 msaaConfigAttribList[kConfigAttribListCnt + 1] = EGL_SAMPLES;
482 msaaConfigAttribList[kConfigAttribListCnt + 2] = msaaSampleCount;
483 msaaConfigAttribList[kConfigAttribListCnt + 3] = EGL_NONE;
484 if (eglChooseConfig(display, configAttribList,
485 &config, 1, &numConfigs)) {
486 SkASSERT(numConfigs > 0);
487 foundConfig = true;
488 }
489 }
490 if (!foundConfig) {
rmistry@google.comd6176b02012-08-23 18:14:13 +0000491 if (!eglChooseConfig(display, configAttribList,
bsalomon@google.com11959252012-04-06 20:13:38 +0000492 &config, 1, &numConfigs)) {
493 return false;
494 }
bsalomon@google.com2858b312012-04-02 20:44:38 +0000495 }
496
497 // Create a surface
rmistry@google.comd6176b02012-08-23 18:14:13 +0000498 EGLSurface surface = eglCreateWindowSurface(display, config,
499 (EGLNativeWindowType)hWnd,
bsalomon@google.com2858b312012-04-02 20:44:38 +0000500 surfaceAttribList);
501 if (surface == EGL_NO_SURFACE) {
502 return false;
503 }
504
505 // Create a GL context
rmistry@google.comd6176b02012-08-23 18:14:13 +0000506 EGLContext context = eglCreateContext(display, config,
bsalomon@google.com2858b312012-04-02 20:44:38 +0000507 EGL_NO_CONTEXT,
508 contextAttribs );
509 if (context == EGL_NO_CONTEXT ) {
510 return false;
rmistry@google.comd6176b02012-08-23 18:14:13 +0000511 }
512
bsalomon@google.com2858b312012-04-02 20:44:38 +0000513 // Make the context current
514 if (!eglMakeCurrent(display, surface, surface, context)) {
515 return false;
516 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000517
bsalomon@google.com2858b312012-04-02 20:44:38 +0000518 *eglDisplay = display;
519 *eglContext = context;
520 *eglSurface = surface;
521 return true;
522}
523
bsalomon@google.com11959252012-04-06 20:13:38 +0000524bool SkOSWindow::attachANGLE(int msaaSampleCount) {
bsalomon@google.com2858b312012-04-02 20:44:38 +0000525 if (EGL_NO_DISPLAY == fDisplay) {
bsalomon@google.com11959252012-04-06 20:13:38 +0000526 bool bResult = create_ANGLE((HWND)fHWND,
527 msaaSampleCount,
528 &fDisplay,
529 &fContext,
530 &fSurface);
bsalomon@google.com2858b312012-04-02 20:44:38 +0000531 if (false == bResult) {
532 return false;
533 }
534 const GrGLInterface* intf = GrGLCreateANGLEInterface();
535
536 if (intf) {
borenet@google.com0dd5ceb2012-08-28 15:15:49 +0000537 ANGLE_GL_CALL(intf, ClearStencil(0));
538 ANGLE_GL_CALL(intf, ClearColor(0, 0, 0, 0));
539 ANGLE_GL_CALL(intf, StencilMask(0xffffffff));
540 ANGLE_GL_CALL(intf, Clear(GL_STENCIL_BUFFER_BIT |GL_COLOR_BUFFER_BIT));
bsalomon@google.com2858b312012-04-02 20:44:38 +0000541 }
542 }
543 if (eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) {
544 const GrGLInterface* intf = GrGLCreateANGLEInterface();
545
546 if (intf ) {
borenet@google.com0dd5ceb2012-08-28 15:15:49 +0000547 ANGLE_GL_CALL(intf, Viewport(0, 0, SkScalarRound(this->width()),
bsalomon@google.com2858b312012-04-02 20:44:38 +0000548 SkScalarRound(this->height())));
549 }
550 return true;
551 }
552 return false;
553}
554
555void SkOSWindow::detachANGLE() {
556 eglMakeCurrent(fDisplay, EGL_NO_SURFACE , EGL_NO_SURFACE , EGL_NO_CONTEXT);
557
558 eglDestroyContext(fDisplay, fContext);
559 fContext = EGL_NO_CONTEXT;
560
561 eglDestroySurface(fDisplay, fSurface);
562 fSurface = EGL_NO_SURFACE;
563
564 eglTerminate(fDisplay);
565 fDisplay = EGL_NO_DISPLAY;
566}
567
568void SkOSWindow::presentANGLE() {
569 const GrGLInterface* intf = GrGLCreateANGLEInterface();
570
571 if (intf) {
borenet@google.com0dd5ceb2012-08-28 15:15:49 +0000572 ANGLE_GL_CALL(intf, Flush());
bsalomon@google.com2858b312012-04-02 20:44:38 +0000573 }
574
575 eglSwapBuffers(fDisplay, fSurface);
576}
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000577#endif // SK_ANGLE
578#endif // SK_SUPPORT_GPU
bsalomon@google.com2858b312012-04-02 20:44:38 +0000579
bsalomon@google.com2858b312012-04-02 20:44:38 +0000580// return true on success
bsalomon@google.com11959252012-04-06 20:13:38 +0000581bool SkOSWindow::attach(SkBackEndTypes attachType, int msaaSampleCount) {
bsalomon@google.com2858b312012-04-02 20:44:38 +0000582
583 // attach doubles as "windowResize" so we need to allo
584 // already bound states to pass through again
585 // TODO: split out the resize functionality
586// SkASSERT(kNone_BackEndType == fAttached);
587 bool result = true;
588
589 switch (attachType) {
590 case kNone_BackEndType:
591 // nothing to do
rmistry@google.comd6176b02012-08-23 18:14:13 +0000592 break;
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000593#if SK_SUPPORT_GPU
bsalomon@google.com2858b312012-04-02 20:44:38 +0000594 case kNativeGL_BackEndType:
bsalomon@google.com11959252012-04-06 20:13:38 +0000595 result = attachGL(msaaSampleCount);
bsalomon@google.com2858b312012-04-02 20:44:38 +0000596 break;
597#if SK_ANGLE
598 case kANGLE_BackEndType:
bsalomon@google.com11959252012-04-06 20:13:38 +0000599 result = attachANGLE(msaaSampleCount);
bsalomon@google.com2858b312012-04-02 20:44:38 +0000600 break;
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000601#endif // SK_ANGLE
602#endif // SK_SUPPORT_GPU
bsalomon@google.com2858b312012-04-02 20:44:38 +0000603 default:
604 SkASSERT(false);
605 result = false;
606 break;
607 }
608
609 if (result) {
610 fAttached = attachType;
611 }
612
613 return result;
614}
615
616void SkOSWindow::detach() {
617 switch (fAttached) {
618 case kNone_BackEndType:
619 // nothing to do
rmistry@google.comd6176b02012-08-23 18:14:13 +0000620 break;
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000621#if SK_SUPPORT_GPU
bsalomon@google.com2858b312012-04-02 20:44:38 +0000622 case kNativeGL_BackEndType:
623 detachGL();
624 break;
625#if SK_ANGLE
626 case kANGLE_BackEndType:
627 detachANGLE();
628 break;
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000629#endif // SK_ANGLE
630#endif // SK_SUPPORT_GPU
bsalomon@google.com2858b312012-04-02 20:44:38 +0000631 default:
632 SkASSERT(false);
633 break;
634 }
635 fAttached = kNone_BackEndType;
636}
637
638void SkOSWindow::present() {
639 switch (fAttached) {
640 case kNone_BackEndType:
641 // nothing to do
rmistry@google.comd6176b02012-08-23 18:14:13 +0000642 return;
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000643#if SK_SUPPORT_GPU
bsalomon@google.com2858b312012-04-02 20:44:38 +0000644 case kNativeGL_BackEndType:
645 presentGL();
646 break;
647#if SK_ANGLE
648 case kANGLE_BackEndType:
649 presentANGLE();
650 break;
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000651#endif // SK_ANGLE
652#endif // SK_SUPPORT_GPU
bsalomon@google.com2858b312012-04-02 20:44:38 +0000653 default:
654 SkASSERT(false);
655 break;
656 }
657}
658
659#endif