180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc. 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkWGL.h" 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTDArray.h" 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTSearch.h" 137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkTSort.h" 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkWGLExtensions::hasExtension(HDC dc, const char* ext) const { 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == this->fGetExtensionsString) { 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!strcmp("WGL_ARB_extensions_string", ext)) { 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char* extensionString = this->getExtensionsString(dc); 230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger size_t extLength = strlen(ext); 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (true) { 260a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger size_t n = strcspn(extensionString, " "); 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (n == extLength && 0 == strncmp(ext, extensionString, n)) { 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 == extensionString[n]) { 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru extensionString += n+1; 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst char* SkWGLExtensions::getExtensionsString(HDC hdc) const { 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fGetExtensionsString(hdc); 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruBOOL SkWGLExtensions::choosePixelFormat(HDC hdc, 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const int* piAttribIList, 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const FLOAT* pfAttribFList, 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru UINT nMaxFormats, 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int* piFormats, 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru UINT* nNumFormats) const { 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fChoosePixelFormat(hdc, piAttribIList, pfAttribFList, 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru nMaxFormats, piFormats, nNumFormats); 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruBOOL SkWGLExtensions::getPixelFormatAttribiv(HDC hdc, 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int iPixelFormat, 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int iLayerPlane, 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru UINT nAttributes, 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const int *piAttributes, 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int *piValues) const { 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fGetPixelFormatAttribiv(hdc, iPixelFormat, iLayerPlane, 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru nAttributes, piAttributes, piValues); 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruBOOL SkWGLExtensions::getPixelFormatAttribfv(HDC hdc, 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int iPixelFormat, 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int iLayerPlane, 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru UINT nAttributes, 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const int *piAttributes, 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float *pfValues) const { 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fGetPixelFormatAttribfv(hdc, iPixelFormat, iLayerPlane, 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru nAttributes, piAttributes, pfValues); 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHGLRC SkWGLExtensions::createContextAttribs(HDC hDC, 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru HGLRC hShareContext, 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const int *attribList) const { 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fCreateContextAttribs(hDC, hShareContext, attribList); 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace { 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustruct PixelFormat { 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int fFormat; 820a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger int fSampleCnt; 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int fChoosePixelFormatRank; 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerbool pf_less(const PixelFormat& a, const PixelFormat& b) { 870a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger if (a.fSampleCnt < b.fSampleCnt) { 887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return true; 890a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } else if (b.fSampleCnt < a.fSampleCnt) { 907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return false; 917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } else if (a.fChoosePixelFormatRank < b.fChoosePixelFormatRank) { 927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return true; 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return false; 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint SkWGLExtensions::selectFormat(const int formats[], 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int formatCount, 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru HDC dc, 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int desiredSampleCount) { 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru PixelFormat desiredFormat = { 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 0, 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desiredSampleCount, 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 0, 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkTDArray<PixelFormat> rankedFormats; 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rankedFormats.setCount(formatCount); 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < formatCount; ++i) { 1100a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger static const int kQueryAttr = SK_WGL_SAMPLES; 1110a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger int numSamples; 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->getPixelFormatAttribiv(dc, 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru formats[i], 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 0, 1150a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 1, 1160a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger &kQueryAttr, 1170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger &numSamples); 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rankedFormats[i].fFormat = formats[i]; 1190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger rankedFormats[i].fSampleCnt = numSamples; 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rankedFormats[i].fChoosePixelFormatRank = i; 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 1227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkTQSort(rankedFormats.begin(), 1237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger rankedFormats.begin() + rankedFormats.count() - 1, 1247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkTLessFunctionToFunctorAdaptor<PixelFormat, pf_less>()); 1257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int idx = SkTSearch<PixelFormat, pf_less>(rankedFormats.begin(), 1267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger rankedFormats.count(), 1277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger desiredFormat, 1287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger sizeof(PixelFormat)); 12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (idx < 0) { 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru idx = ~idx; 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return rankedFormats[idx].fFormat; 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace { 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if defined(UNICODE) 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru #define STR_LIT(X) L## #X 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru #define STR_LIT(X) #X 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define DUMMY_CLASS STR_LIT("DummyClass") 14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHWND create_dummy_window() { 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru HMODULE module = GetModuleHandle(NULL); 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru HWND dummy; 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru RECT windowRect; 15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru windowRect.left = 0; 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru windowRect.right = 8; 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru windowRect.top = 0; 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru windowRect.bottom = 8; 15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru WNDCLASS wc; 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru wc.lpfnWndProc = (WNDPROC) DefWindowProc; 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru wc.cbClsExtra = 0; 16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru wc.cbWndExtra = 0; 16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru wc.hInstance = module; 16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); 16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru wc.hCursor = LoadCursor(NULL, IDC_ARROW); 16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru wc.hbrBackground = NULL; 16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru wc.lpszMenuName = NULL; 16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru wc.lpszClassName = DUMMY_CLASS; 16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if(!RegisterClass(&wc)) { 16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return 0; 17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru DWORD style, exStyle; 17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru exStyle = WS_EX_CLIENTEDGE; 17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru style = WS_SYSMENU; 17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru AdjustWindowRectEx(&windowRect, style, false, exStyle); 17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if(!(dummy = CreateWindowEx(exStyle, 17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru DUMMY_CLASS, 17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru STR_LIT("DummyWindow"), 18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru WS_CLIPSIBLINGS | WS_CLIPCHILDREN | style, 18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 0, 0, 18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru windowRect.right-windowRect.left, 18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru windowRect.bottom-windowRect.top, 18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru NULL, NULL, 18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru module, 18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru NULL))) { 18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru UnregisterClass(DUMMY_CLASS, module); 18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return NULL; 18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ShowWindow(dummy, SW_HIDE); 19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return dummy; 19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid destroy_dummy_window(HWND dummy) { 19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru DestroyWindow(dummy); 19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru HMODULE module = GetModuleHandle(NULL); 19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru UnregisterClass(DUMMY_CLASS, module); 19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define GET_PROC(NAME, SUFFIX) f##NAME = \ 20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (##NAME##Proc) wglGetProcAddress("wgl" #NAME #SUFFIX) 20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkWGLExtensions::SkWGLExtensions() 20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru : fGetExtensionsString(NULL) 20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru , fChoosePixelFormat(NULL) 20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru , fGetPixelFormatAttribfv(NULL) 20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru , fGetPixelFormatAttribiv(NULL) 21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru , fCreateContextAttribs(NULL) { 21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru HDC prevDC = wglGetCurrentDC(); 21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru HGLRC prevGLRC = wglGetCurrentContext(); 21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru PIXELFORMATDESCRIPTOR dummyPFD; 21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ZeroMemory(&dummyPFD, sizeof(dummyPFD)); 21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dummyPFD.nSize = sizeof(dummyPFD); 21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dummyPFD.nVersion = 1; 21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dummyPFD.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; 22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dummyPFD.iPixelType = PFD_TYPE_RGBA; 22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dummyPFD.cColorBits = 32; 22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dummyPFD.cDepthBits = 0; 22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dummyPFD.cStencilBits = 8; 22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dummyPFD.iLayerType = PFD_MAIN_PLANE; 22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru HWND dummyWND = create_dummy_window(); 22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (dummyWND) { 22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru HDC dummyDC = GetDC(dummyWND); 22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int dummyFormat = ChoosePixelFormat(dummyDC, &dummyPFD); 22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SetPixelFormat(dummyDC, dummyFormat, &dummyPFD); 23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru HGLRC dummyGLRC = wglCreateContext(dummyDC); 23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(dummyGLRC); 23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru wglMakeCurrent(dummyDC, dummyGLRC); 23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GET_PROC(GetExtensionsString, ARB); 23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GET_PROC(ChoosePixelFormat, ARB); 23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GET_PROC(GetPixelFormatAttribiv, ARB); 23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GET_PROC(GetPixelFormatAttribfv, ARB); 23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GET_PROC(CreateContextAttribs, ARB); 23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru wglMakeCurrent(dummyDC, NULL); 24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru wglDeleteContext(dummyGLRC); 24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru destroy_dummy_window(dummyWND); 24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru wglMakeCurrent(prevDC, prevGLRC); 24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 247096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 248096defe64d408e54474fe19f418c95bf1a554fc7Derek SollenbergerHGLRC SkCreateWGLContext(HDC dc, int msaaSampleCount, bool preferCoreProfile) { 249096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkWGLExtensions extensions; 250096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (!extensions.hasExtension(dc, "WGL_ARB_pixel_format")) { 251096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return NULL; 252096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 253096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 254096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger HDC prevDC = wglGetCurrentDC(); 255096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger HGLRC prevGLRC = wglGetCurrentContext(); 256096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger PIXELFORMATDESCRIPTOR pfd; 257096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 258096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger int format = 0; 259096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 260096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger static const int iAttrs[] = { 261096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SK_WGL_DRAW_TO_WINDOW, TRUE, 262096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SK_WGL_DOUBLE_BUFFER, TRUE, 263096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SK_WGL_ACCELERATION, SK_WGL_FULL_ACCELERATION, 264096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SK_WGL_SUPPORT_OPENGL, TRUE, 265096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SK_WGL_COLOR_BITS, 24, 266096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SK_WGL_ALPHA_BITS, 8, 267096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SK_WGL_STENCIL_BITS, 8, 268096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 0, 0 269096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger }; 270096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 271096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger float fAttrs[] = {0, 0}; 272096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 273096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (msaaSampleCount > 0 && 274096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger extensions.hasExtension(dc, "WGL_ARB_multisample")) { 275096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger static const int kIAttrsCount = SK_ARRAY_COUNT(iAttrs); 2760a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger int msaaIAttrs[kIAttrsCount + 4]; 277096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger memcpy(msaaIAttrs, iAttrs, sizeof(int) * kIAttrsCount); 278096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkASSERT(0 == msaaIAttrs[kIAttrsCount - 2] && 279096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 0 == msaaIAttrs[kIAttrsCount - 1]); 280096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger msaaIAttrs[kIAttrsCount - 2] = SK_WGL_SAMPLE_BUFFERS; 281096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger msaaIAttrs[kIAttrsCount - 1] = TRUE; 282096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger msaaIAttrs[kIAttrsCount + 0] = SK_WGL_SAMPLES; 283096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger msaaIAttrs[kIAttrsCount + 1] = msaaSampleCount; 2840a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger msaaIAttrs[kIAttrsCount + 2] = 0; 2850a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger msaaIAttrs[kIAttrsCount + 3] = 0; 286096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger unsigned int num; 287096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger int formats[64]; 288096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger extensions.choosePixelFormat(dc, msaaIAttrs, fAttrs, 64, formats, &num); 289e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger num = SkTMin(num, 64U); 290096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger int formatToTry = extensions.selectFormat(formats, 291096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger num, 292096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger dc, 293096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger msaaSampleCount); 294096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger DescribePixelFormat(dc, formatToTry, sizeof(pfd), &pfd); 295096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (SetPixelFormat(dc, formatToTry, &pfd)) { 296096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger format = formatToTry; 297096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 298096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 299096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 300096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (0 == format) { 301096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // Either MSAA wasn't requested or creation failed 302096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger unsigned int num; 303096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger extensions.choosePixelFormat(dc, iAttrs, fAttrs, 1, &format, &num); 304096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger DescribePixelFormat(dc, format, sizeof(pfd), &pfd); 305e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger SkDEBUGCODE(BOOL set =) SetPixelFormat(dc, format, &pfd); 306096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkASSERT(TRUE == set); 307096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 308096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 309096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger HGLRC glrc = NULL; 310096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (preferCoreProfile && extensions.hasExtension(dc, "WGL_ARB_create_context")) { 311096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger static const int kCoreGLVersions[] = { 312096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 4, 3, 313096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 4, 2, 314096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 4, 1, 315096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 4, 0, 316096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 3, 3, 317096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 3, 2, 318096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger }; 319096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger int coreProfileAttribs[] = { 320096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SK_WGL_CONTEXT_MAJOR_VERSION, -1, 321096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SK_WGL_CONTEXT_MINOR_VERSION, -1, 322096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SK_WGL_CONTEXT_PROFILE_MASK, SK_WGL_CONTEXT_CORE_PROFILE_BIT, 323096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 0, 324096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger }; 325096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger for (int v = 0; v < SK_ARRAY_COUNT(kCoreGLVersions) / 2; ++v) { 326096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger coreProfileAttribs[1] = kCoreGLVersions[2 * v]; 327096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger coreProfileAttribs[3] = kCoreGLVersions[2 * v + 1]; 328096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger glrc = extensions.createContextAttribs(dc, NULL, coreProfileAttribs); 329096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (NULL != glrc) { 330096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger break; 331096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 332096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 333096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 334096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 335096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (NULL == glrc) { 336096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger glrc = wglCreateContext(dc); 337096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 338096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkASSERT(glrc); 339096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 340096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger wglMakeCurrent(prevDC, prevGLRC); 341096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return glrc; 342096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger} 343