| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 #include "SkTypes.h" | 7 #include "SkTypes.h" |
| 8 | 8 |
| 9 #if defined(SK_BUILD_FOR_WIN) | 9 #if defined(SK_BUILD_FOR_WIN) |
| 10 | 10 |
| 11 #include <GL/gl.h> | 11 #include <GL/gl.h> |
| 12 #include <WindowsX.h> | 12 #include <WindowsX.h> |
| 13 #include "win/SkWGL.h" | 13 #include "win/SkWGL.h" |
| 14 #include "SkWindow.h" | 14 #include "SkWindow.h" |
| 15 #include "SkCanvas.h" | 15 #include "SkCanvas.h" |
| 16 #include "SkOSMenu.h" | 16 #include "SkOSMenu.h" |
| 17 #include "SkTime.h" | 17 #include "SkTime.h" |
| 18 #include "SkUtils.h" | 18 #include "SkUtils.h" |
| 19 | 19 |
| 20 #include "SkGraphics.h" | 20 #include "SkGraphics.h" |
| 21 | 21 |
| 22 #if SK_ANGLE | 22 #if SK_ANGLE |
| 23 #include "gl/angle/SkANGLEGLContext.h" | 23 #include "gl/GrGLAssembleInterface.h" |
| 24 #include "gl/GrGLInterface.h" | 24 #include "gl/GrGLInterface.h" |
| 25 #include "GLES2/gl2.h" | 25 #include "GLES2/gl2.h" |
| 26 | 26 #include <EGL/egl.h> |
| 27 #define ANGLE_GL_CALL(IFACE, X) \ | 27 #include <EGL/eglext.h> |
| 28 do { \ | |
| 29 (IFACE)->fFunctions.f##X; \ | |
| 30 } while (false) | |
| 31 | |
| 32 #endif // SK_ANGLE | 28 #endif // SK_ANGLE |
| 33 | 29 |
| 34 #if SK_COMMAND_BUFFER | 30 #if SK_COMMAND_BUFFER |
| 35 #include "gl/command_buffer/SkCommandBufferGLContext.h" | 31 #include "gl/command_buffer/SkCommandBufferGLContext.h" |
| 32 #endif // SK_COMMAND_BUFFER |
| 36 | 33 |
| 37 #define COMMAND_BUFFER_GL_CALL(IFACE, X) \ | 34 #define GL_CALL(IFACE, X) \ |
| 38 do { \ | 35 SkASSERT(IFACE); \ |
| 39 (IFACE)->fFunctions.f##X; \ | 36 do { \ |
| 37 (IFACE)->fFunctions.f##X; \ |
| 40 } while (false) | 38 } while (false) |
| 41 | 39 |
| 42 #endif // SK_COMMAND_BUFFER | |
| 43 | |
| 44 #define WM_EVENT_CALLBACK (WM_USER+0) | 40 #define WM_EVENT_CALLBACK (WM_USER+0) |
| 45 | 41 |
| 46 void post_skwinevent(HWND hwnd) | 42 void post_skwinevent(HWND hwnd) |
| 47 { | 43 { |
| 48 PostMessage(hwnd, WM_EVENT_CALLBACK, 0, 0); | 44 PostMessage(hwnd, WM_EVENT_CALLBACK, 0, 0); |
| 49 } | 45 } |
| 50 | 46 |
| 51 SkTHashMap<void*, SkOSWindow*> SkOSWindow::gHwndToOSWindowMap; | 47 SkTHashMap<void*, SkOSWindow*> SkOSWindow::gHwndToOSWindowMap; |
| 52 | 48 |
| 53 SkOSWindow::SkOSWindow(const void* winInit) { | 49 SkOSWindow::SkOSWindow(const void* winInit) { |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 } | 384 } |
| 389 | 385 |
| 390 void SkOSWindow::presentGL() { | 386 void SkOSWindow::presentGL() { |
| 391 HDC dc = GetDC((HWND)fHWND); | 387 HDC dc = GetDC((HWND)fHWND); |
| 392 SwapBuffers(dc); | 388 SwapBuffers(dc); |
| 393 ReleaseDC((HWND)fHWND, dc); | 389 ReleaseDC((HWND)fHWND, dc); |
| 394 } | 390 } |
| 395 | 391 |
| 396 #if SK_ANGLE | 392 #if SK_ANGLE |
| 397 | 393 |
| 394 static void* get_angle_egl_display(void* nativeDisplay) { |
| 395 PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT; |
| 396 eglGetPlatformDisplayEXT = |
| 397 (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDispla
yEXT"); |
| 398 |
| 399 // We expect ANGLE to support this extension |
| 400 if (!eglGetPlatformDisplayEXT) { |
| 401 return EGL_NO_DISPLAY; |
| 402 } |
| 403 |
| 404 EGLDisplay display = EGL_NO_DISPLAY; |
| 405 // Try for an ANGLE D3D11 context, fall back to D3D9, and finally GL. |
| 406 EGLint attribs[3][3] = { |
| 407 { |
| 408 EGL_PLATFORM_ANGLE_TYPE_ANGLE, |
| 409 EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, |
| 410 EGL_NONE |
| 411 }, |
| 412 { |
| 413 EGL_PLATFORM_ANGLE_TYPE_ANGLE, |
| 414 EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, |
| 415 EGL_NONE |
| 416 }, |
| 417 }; |
| 418 for (int i = 0; i < 3 && display == EGL_NO_DISPLAY; ++i) { |
| 419 display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE,nativeDispla
y, attribs[i]); |
| 420 } |
| 421 return display; |
| 422 } |
| 423 |
| 424 struct ANGLEAssembleContext { |
| 425 ANGLEAssembleContext() { |
| 426 fEGL = GetModuleHandle("libEGL.dll"); |
| 427 fGL = GetModuleHandle("libEGLESv2.dll"); |
| 428 } |
| 429 |
| 430 bool isValid() const { return SkToBool(fEGL) && SkToBool(fGL); } |
| 431 |
| 432 HMODULE fEGL; |
| 433 HMODULE fGL; |
| 434 }; |
| 435 |
| 436 static GrGLFuncPtr angle_get_gl_proc(void* ctx, const char name[]) { |
| 437 const ANGLEAssembleContext& context = *reinterpret_cast<const ANGLEAssembleC
ontext*>(ctx); |
| 438 GrGLFuncPtr proc = (GrGLFuncPtr) GetProcAddress(context.fGL, name); |
| 439 if (proc) { |
| 440 return proc; |
| 441 } |
| 442 proc = (GrGLFuncPtr) GetProcAddress(context.fEGL, name); |
| 443 if (proc) { |
| 444 return proc; |
| 445 } |
| 446 return eglGetProcAddress(name); |
| 447 } |
| 448 |
| 449 static const GrGLInterface* get_angle_gl_interface() { |
| 450 ANGLEAssembleContext context; |
| 451 if (!context.isValid()) { |
| 452 return nullptr; |
| 453 } |
| 454 return GrGLAssembleGLESInterface(&context, angle_get_gl_proc); |
| 455 } |
| 456 |
| 398 bool create_ANGLE(EGLNativeWindowType hWnd, | 457 bool create_ANGLE(EGLNativeWindowType hWnd, |
| 399 int msaaSampleCount, | 458 int msaaSampleCount, |
| 400 EGLDisplay* eglDisplay, | 459 EGLDisplay* eglDisplay, |
| 401 EGLContext* eglContext, | 460 EGLContext* eglContext, |
| 402 EGLSurface* eglSurface, | 461 EGLSurface* eglSurface, |
| 403 EGLConfig* eglConfig) { | 462 EGLConfig* eglConfig) { |
| 404 static const EGLint contextAttribs[] = { | 463 static const EGLint contextAttribs[] = { |
| 405 EGL_CONTEXT_CLIENT_VERSION, 2, | 464 EGL_CONTEXT_CLIENT_VERSION, 2, |
| 406 EGL_NONE, EGL_NONE | 465 EGL_NONE, EGL_NONE |
| 407 }; | 466 }; |
| 408 static const EGLint configAttribList[] = { | 467 static const EGLint configAttribList[] = { |
| 409 EGL_RED_SIZE, 8, | 468 EGL_RED_SIZE, 8, |
| 410 EGL_GREEN_SIZE, 8, | 469 EGL_GREEN_SIZE, 8, |
| 411 EGL_BLUE_SIZE, 8, | 470 EGL_BLUE_SIZE, 8, |
| 412 EGL_ALPHA_SIZE, 8, | 471 EGL_ALPHA_SIZE, 8, |
| 413 EGL_DEPTH_SIZE, 8, | 472 EGL_DEPTH_SIZE, 8, |
| 414 EGL_STENCIL_SIZE, 8, | 473 EGL_STENCIL_SIZE, 8, |
| 415 EGL_NONE | 474 EGL_NONE |
| 416 }; | 475 }; |
| 417 static const EGLint surfaceAttribList[] = { | 476 static const EGLint surfaceAttribList[] = { |
| 418 EGL_NONE, EGL_NONE | 477 EGL_NONE, EGL_NONE |
| 419 }; | 478 }; |
| 420 | 479 |
| 421 EGLDisplay display = SkANGLEGLContext::GetD3DEGLDisplay(GetDC(hWnd), false); | 480 EGLDisplay display = get_angle_egl_display(GetDC(hWnd)); |
| 422 | 481 |
| 423 if (EGL_NO_DISPLAY == display) { | 482 if (EGL_NO_DISPLAY == display) { |
| 424 SkDebugf("Could not create ANGLE egl display!\n"); | 483 SkDebugf("Could not create ANGLE egl display!\n"); |
| 425 return false; | 484 return false; |
| 426 } | 485 } |
| 427 | 486 |
| 428 // Initialize EGL | 487 // Initialize EGL |
| 429 EGLint majorVersion, minorVersion; | 488 EGLint majorVersion, minorVersion; |
| 430 if (!eglInitialize(display, &majorVersion, &minorVersion)) { | 489 if (!eglInitialize(display, &majorVersion, &minorVersion)) { |
| 431 return false; | 490 return false; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 if (EGL_NO_DISPLAY == fDisplay) { | 552 if (EGL_NO_DISPLAY == fDisplay) { |
| 494 bool bResult = create_ANGLE((HWND)fHWND, | 553 bool bResult = create_ANGLE((HWND)fHWND, |
| 495 msaaSampleCount, | 554 msaaSampleCount, |
| 496 &fDisplay, | 555 &fDisplay, |
| 497 &fContext, | 556 &fContext, |
| 498 &fSurface, | 557 &fSurface, |
| 499 &fConfig); | 558 &fConfig); |
| 500 if (false == bResult) { | 559 if (false == bResult) { |
| 501 return false; | 560 return false; |
| 502 } | 561 } |
| 503 SkAutoTUnref<const GrGLInterface> intf(GrGLCreateANGLEInterface()); | 562 fANGLEInterface.reset(get_angle_gl_interface()); |
| 504 | 563 if (!fANGLEInterface) { |
| 505 if (intf) { | 564 this->detachANGLE(); |
| 506 ANGLE_GL_CALL(intf, ClearStencil(0)); | 565 return false; |
| 507 ANGLE_GL_CALL(intf, ClearColor(0, 0, 0, 0)); | |
| 508 ANGLE_GL_CALL(intf, StencilMask(0xffffffff)); | |
| 509 ANGLE_GL_CALL(intf, Clear(GL_STENCIL_BUFFER_BIT |GL_COLOR_BUFFER_BIT
)); | |
| 510 } | 566 } |
| 511 } | 567 GL_CALL(fANGLEInterface, ClearStencil(0)); |
| 512 if (eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { | 568 GL_CALL(fANGLEInterface, ClearColor(0, 0, 0, 0)); |
| 569 GL_CALL(fANGLEInterface, StencilMask(0xffffffff)); |
| 570 GL_CALL(fANGLEInterface, Clear(GL_STENCIL_BUFFER_BIT |GL_COLOR_BUFFER_BI
T)); |
| 571 if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { |
| 572 this->detachANGLE(); |
| 573 return false; |
| 574 } |
| 513 eglGetConfigAttrib(fDisplay, fConfig, EGL_STENCIL_SIZE, &info->fStencilB
its); | 575 eglGetConfigAttrib(fDisplay, fConfig, EGL_STENCIL_SIZE, &info->fStencilB
its); |
| 514 eglGetConfigAttrib(fDisplay, fConfig, EGL_SAMPLES, &info->fSampleCount); | 576 eglGetConfigAttrib(fDisplay, fConfig, EGL_SAMPLES, &info->fSampleCount); |
| 515 | 577 |
| 516 SkAutoTUnref<const GrGLInterface> intf(GrGLCreateANGLEInterface()); | 578 GL_CALL(fANGLEInterface, Viewport(0, 0, SkScalarRoundToInt(this->width()
), |
| 517 | 579 SkScalarRoundToInt(this->height(
)))); |
| 518 if (intf ) { | |
| 519 ANGLE_GL_CALL(intf, Viewport(0, 0, | |
| 520 SkScalarRoundToInt(this->width()), | |
| 521 SkScalarRoundToInt(this->height()))); | |
| 522 } | |
| 523 return true; | 580 return true; |
| 524 } | 581 } |
| 525 return false; | 582 return false; |
| 526 } | 583 } |
| 527 | 584 |
| 528 void SkOSWindow::detachANGLE() { | 585 void SkOSWindow::detachANGLE() { |
| 586 fANGLEInterface.reset(nullptr); |
| 529 eglMakeCurrent(fDisplay, EGL_NO_SURFACE , EGL_NO_SURFACE , EGL_NO_CONTEXT); | 587 eglMakeCurrent(fDisplay, EGL_NO_SURFACE , EGL_NO_SURFACE , EGL_NO_CONTEXT); |
| 530 | 588 |
| 531 eglDestroyContext(fDisplay, fContext); | 589 eglDestroyContext(fDisplay, fContext); |
| 532 fContext = EGL_NO_CONTEXT; | 590 fContext = EGL_NO_CONTEXT; |
| 533 | 591 |
| 534 eglDestroySurface(fDisplay, fSurface); | 592 eglDestroySurface(fDisplay, fSurface); |
| 535 fSurface = EGL_NO_SURFACE; | 593 fSurface = EGL_NO_SURFACE; |
| 536 | 594 |
| 537 eglTerminate(fDisplay); | 595 eglTerminate(fDisplay); |
| 538 fDisplay = EGL_NO_DISPLAY; | 596 fDisplay = EGL_NO_DISPLAY; |
| 539 } | 597 } |
| 540 | 598 |
| 541 void SkOSWindow::presentANGLE() { | 599 void SkOSWindow::presentANGLE() { |
| 542 SkAutoTUnref<const GrGLInterface> intf(GrGLCreateANGLEInterface()); | 600 GL_CALL(fANGLEInterface, Flush()); |
| 543 | |
| 544 if (intf) { | |
| 545 ANGLE_GL_CALL(intf, Flush()); | |
| 546 } | |
| 547 | 601 |
| 548 eglSwapBuffers(fDisplay, fSurface); | 602 eglSwapBuffers(fDisplay, fSurface); |
| 549 } | 603 } |
| 550 #endif // SK_ANGLE | 604 #endif // SK_ANGLE |
| 551 | 605 |
| 552 #if SK_COMMAND_BUFFER | 606 #if SK_COMMAND_BUFFER |
| 553 | 607 |
| 554 bool SkOSWindow::attachCommandBuffer(int msaaSampleCount, AttachmentInfo* info)
{ | 608 bool SkOSWindow::attachCommandBuffer(int msaaSampleCount, AttachmentInfo* info)
{ |
| 555 if (!fCommandBuffer) { | 609 if (!fCommandBuffer) { |
| 556 fCommandBuffer = SkCommandBufferGLContext::Create((HWND)fHWND, msaaSampl
eCount); | 610 fCommandBuffer = SkCommandBufferGLContext::Create((HWND)fHWND, msaaSampl
eCount); |
| 557 if (!fCommandBuffer) | 611 if (!fCommandBuffer) |
| 558 return false; | 612 return false; |
| 559 | 613 |
| 560 SkAutoTUnref<const GrGLInterface> intf(GrGLCreateCommandBufferInterface(
)); | 614 SkAutoTUnref<const GrGLInterface> intf(GrGLCreateCommandBufferInterface(
)); |
| 561 if (intf) { | 615 if (intf) { |
| 562 COMMAND_BUFFER_GL_CALL(intf, ClearStencil(0)); | 616 GL_CALL(intf, ClearStencil(0)); |
| 563 COMMAND_BUFFER_GL_CALL(intf, ClearColor(0, 0, 0, 0)); | 617 GL_CALL(intf, ClearColor(0, 0, 0, 0)); |
| 564 COMMAND_BUFFER_GL_CALL(intf, StencilMask(0xffffffff)); | 618 GL_CALL(intf, StencilMask(0xffffffff)); |
| 565 COMMAND_BUFFER_GL_CALL(intf, Clear(GL_STENCIL_BUFFER_BIT |GL_COLOR_B
UFFER_BIT)); | 619 GL_CALL(intf, Clear(GL_STENCIL_BUFFER_BIT |GL_COLOR_BUFFER_BIT)); |
| 566 } | 620 } |
| 567 } | 621 } |
| 568 | 622 |
| 569 if (fCommandBuffer->makeCurrent()) { | 623 if (fCommandBuffer->makeCurrent()) { |
| 570 info->fStencilBits = fCommandBuffer->getStencilBits(); | 624 info->fStencilBits = fCommandBuffer->getStencilBits(); |
| 571 info->fSampleCount = fCommandBuffer->getSampleCount(); | 625 info->fSampleCount = fCommandBuffer->getSampleCount(); |
| 572 | 626 |
| 573 SkAutoTUnref<const GrGLInterface> intf(GrGLCreateCommandBufferInterface(
)); | 627 SkAutoTUnref<const GrGLInterface> intf(GrGLCreateCommandBufferInterface(
)); |
| 574 | 628 |
| 575 if (intf ) { | 629 if (intf ) { |
| 576 COMMAND_BUFFER_GL_CALL(intf, Viewport(0, 0, | 630 GL_CALL(intf, Viewport(0, 0, SkScalarRoundToInt(this->width()), |
| 577 SkScalarRoundToInt(this->width()), | |
| 578 SkScalarRoundToInt(this->height()))); | 631 SkScalarRoundToInt(this->height()))); |
| 579 } | 632 } |
| 580 return true; | 633 return true; |
| 581 } | 634 } |
| 582 return false; | 635 return false; |
| 583 } | 636 } |
| 584 | 637 |
| 585 void SkOSWindow::detachCommandBuffer() { | 638 void SkOSWindow::detachCommandBuffer() { |
| 586 delete fCommandBuffer; | 639 delete fCommandBuffer; |
| 587 fCommandBuffer = nullptr; | 640 fCommandBuffer = nullptr; |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 770 } | 823 } |
| 771 | 824 |
| 772 void SkOSWindow::closeWindow() { | 825 void SkOSWindow::closeWindow() { |
| 773 DestroyWindow((HWND)fHWND); | 826 DestroyWindow((HWND)fHWND); |
| 774 if (fFullscreen) { | 827 if (fFullscreen) { |
| 775 DestroyWindow((HWND)fSavedWindowState.fHWND); | 828 DestroyWindow((HWND)fSavedWindowState.fHWND); |
| 776 } | 829 } |
| 777 gHwndToOSWindowMap.remove(fHWND); | 830 gHwndToOSWindowMap.remove(fHWND); |
| 778 } | 831 } |
| 779 #endif | 832 #endif |
| OLD | NEW |