gfx/gl/GLContextProviderWGL.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "GLContextProvider.h"
     7 #include "GLContextWGL.h"
     8 #include "GLLibraryLoader.h"
     9 #include "nsDebug.h"
    10 #include "nsIWidget.h"
    11 #include "gfxPlatform.h"
    12 #include "gfxWindowsSurface.h"
    14 #include "gfxCrashReporterUtils.h"
    16 #include "prenv.h"
    18 #include "mozilla/Preferences.h"
    20 using namespace mozilla::gfx;
    22 namespace mozilla {
    23 namespace gl {
    25 WGLLibrary sWGLLib;
    27 HWND
    28 WGLLibrary::CreateDummyWindow(HDC *aWindowDC)
    29 {
    30     WNDCLASSW wc;
    31     if (!GetClassInfoW(GetModuleHandle(nullptr), L"GLContextWGLClass", &wc)) {
    32         ZeroMemory(&wc, sizeof(WNDCLASSW));
    33         wc.style = CS_OWNDC;
    34         wc.hInstance = GetModuleHandle(nullptr);
    35         wc.lpfnWndProc = DefWindowProc;
    36         wc.lpszClassName = L"GLContextWGLClass";
    37         if (!RegisterClassW(&wc)) {
    38             NS_WARNING("Failed to register GLContextWGLClass?!");
    39             // er. failed to register our class?
    40             return nullptr;
    41         }
    42     }
    44     HWND win = CreateWindowW(L"GLContextWGLClass", L"GLContextWGL", 0,
    45                              0, 0, 16, 16,
    46                              nullptr, nullptr, GetModuleHandle(nullptr),
    47                              nullptr);
    48     NS_ENSURE_TRUE(win, nullptr);
    50     HDC dc = GetDC(win);
    51     NS_ENSURE_TRUE(dc, nullptr);
    53     if (mWindowPixelFormat == 0) {
    54         PIXELFORMATDESCRIPTOR pfd;
    55         ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR));
    56         pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
    57         pfd.nVersion = 1;
    58         pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    59         pfd.iPixelType = PFD_TYPE_RGBA;
    60         pfd.cColorBits = 24;
    61         pfd.cRedBits = 8;
    62         pfd.cGreenBits = 8;
    63         pfd.cBlueBits = 8;
    64         pfd.cAlphaBits = 8;
    65         pfd.cDepthBits = 0;
    66         pfd.iLayerType = PFD_MAIN_PLANE;
    68         mWindowPixelFormat = ChoosePixelFormat(dc, &pfd);
    69     }
    71     if (!mWindowPixelFormat ||
    72         !SetPixelFormat(dc, mWindowPixelFormat, nullptr))
    73     {
    74         NS_WARNING("SetPixelFormat failed!");
    75         DestroyWindow(win);
    76         return nullptr;
    77     }
    79     if (aWindowDC) {
    80         *aWindowDC = dc;
    81     }
    83     return win;
    84 }
    86 static inline bool
    87 HasExtension(const char* aExtensions, const char* aRequiredExtension)
    88 {
    89     return GLContext::ListHasExtension(
    90         reinterpret_cast<const GLubyte*>(aExtensions), aRequiredExtension);
    91 }
    93 bool
    94 WGLLibrary::EnsureInitialized()
    95 {
    96     if (mInitialized)
    97         return true;
    99     mozilla::ScopedGfxFeatureReporter reporter("WGL");
   101     std::string libGLFilename = "Opengl32.dll";
   102     // SU_SPIES_DIRECTORY is for AMD CodeXL/gDEBugger
   103     if (PR_GetEnv("SU_SPIES_DIRECTORY")) {
   104         libGLFilename = std::string(PR_GetEnv("SU_SPIES_DIRECTORY")) + "\\opengl32.dll";
   105     }
   107     if (!mOGLLibrary) {
   108         mOGLLibrary = PR_LoadLibrary(&libGLFilename[0]);
   109         if (!mOGLLibrary) {
   110             NS_WARNING("Couldn't load OpenGL library.");
   111             return false;
   112         }
   113     }
   115     GLLibraryLoader::SymLoadStruct earlySymbols[] = {
   116         { (PRFuncPtr*) &fCreateContext, { "wglCreateContext", nullptr } },
   117         { (PRFuncPtr*) &fMakeCurrent, { "wglMakeCurrent", nullptr } },
   118         { (PRFuncPtr*) &fGetProcAddress, { "wglGetProcAddress", nullptr } },
   119         { (PRFuncPtr*) &fDeleteContext, { "wglDeleteContext", nullptr } },
   120         { (PRFuncPtr*) &fGetCurrentContext, { "wglGetCurrentContext", nullptr } },
   121         { (PRFuncPtr*) &fGetCurrentDC, { "wglGetCurrentDC", nullptr } },
   122         { (PRFuncPtr*) &fShareLists, { "wglShareLists", nullptr } },
   123         { nullptr, { nullptr } }
   124     };
   126     if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, &earlySymbols[0])) {
   127         NS_WARNING("Couldn't find required entry points in OpenGL DLL (early init)");
   128         return false;
   129     }
   131     // This is ridiculous -- we have to actually create a context to
   132     // get the OpenGL ICD to load.
   133     mWindow = CreateDummyWindow(&mWindowDC);
   134     NS_ENSURE_TRUE(mWindow, false);
   136     // create rendering context
   137     mWindowGLContext = fCreateContext(mWindowDC);
   138     NS_ENSURE_TRUE(mWindowGLContext, false);
   140     HGLRC curCtx = fGetCurrentContext();
   141     HDC curDC = fGetCurrentDC();
   143     if (!fMakeCurrent((HDC)mWindowDC, (HGLRC)mWindowGLContext)) {
   144         NS_WARNING("wglMakeCurrent failed");
   145         return false;
   146     }
   148     // Now we can grab all the other symbols that we couldn't without having
   149     // a context current.
   151     GLLibraryLoader::SymLoadStruct pbufferSymbols[] = {
   152         { (PRFuncPtr*) &fCreatePbuffer, { "wglCreatePbufferARB", "wglCreatePbufferEXT", nullptr } },
   153         { (PRFuncPtr*) &fDestroyPbuffer, { "wglDestroyPbufferARB", "wglDestroyPbufferEXT", nullptr } },
   154         { (PRFuncPtr*) &fGetPbufferDC, { "wglGetPbufferDCARB", "wglGetPbufferDCEXT", nullptr } },
   155         { (PRFuncPtr*) &fBindTexImage, { "wglBindTexImageARB", "wglBindTexImageEXT", nullptr } },
   156         { (PRFuncPtr*) &fReleaseTexImage, { "wglReleaseTexImageARB", "wglReleaseTexImageEXT", nullptr } },
   157         { nullptr, { nullptr } }
   158     };
   160     GLLibraryLoader::SymLoadStruct pixFmtSymbols[] = {
   161         { (PRFuncPtr*) &fChoosePixelFormat, { "wglChoosePixelFormatARB", "wglChoosePixelFormatEXT", nullptr } },
   162         { (PRFuncPtr*) &fGetPixelFormatAttribiv, { "wglGetPixelFormatAttribivARB", "wglGetPixelFormatAttribivEXT", nullptr } },
   163         { nullptr, { nullptr } }
   164     };
   166     if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, &pbufferSymbols[0],
   167          (GLLibraryLoader::PlatformLookupFunction)fGetProcAddress))
   168     {
   169         // this isn't an error, just means that pbuffers aren't supported
   170         fCreatePbuffer = nullptr;
   171     }
   173     if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, &pixFmtSymbols[0],
   174          (GLLibraryLoader::PlatformLookupFunction)fGetProcAddress))
   175     {
   176         // this isn't an error, just means that we don't have the pixel format extension
   177         fChoosePixelFormat = nullptr;
   178     }
   180     GLLibraryLoader::SymLoadStruct extensionsSymbols[] = {
   181         { (PRFuncPtr *) &fGetExtensionsString, { "wglGetExtensionsStringARB", nullptr} },
   182         { nullptr, { nullptr } }
   183     };
   185     GLLibraryLoader::SymLoadStruct robustnessSymbols[] = {
   186         { (PRFuncPtr *) &fCreateContextAttribs, { "wglCreateContextAttribsARB", nullptr} },
   187         { nullptr, { nullptr } }
   188     };
   190     if (GLLibraryLoader::LoadSymbols(mOGLLibrary, &extensionsSymbols[0],
   191         (GLLibraryLoader::PlatformLookupFunction)fGetProcAddress)) {
   192         const char *wglExts = fGetExtensionsString(mWindowDC);
   193         if (wglExts && HasExtension(wglExts, "WGL_ARB_create_context")) {
   194             GLLibraryLoader::LoadSymbols(mOGLLibrary, &robustnessSymbols[0],
   195             (GLLibraryLoader::PlatformLookupFunction)fGetProcAddress);
   196             if (HasExtension(wglExts, "WGL_ARB_create_context_robustness")) {
   197                 mHasRobustness = true;
   198             }
   199         }
   200     }
   202     // reset back to the previous context, just in case
   203     fMakeCurrent(curDC, curCtx);
   205     if (mHasRobustness) {
   206         fDeleteContext(mWindowGLContext);
   208         int attribs[] = {
   209             LOCAL_WGL_CONTEXT_FLAGS_ARB, LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
   210             LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB,
   211             0
   212         };
   214         mWindowGLContext = fCreateContextAttribs(mWindowDC, nullptr, attribs);
   215         if (!mWindowGLContext) {
   216             mHasRobustness = false;
   217             mWindowGLContext = fCreateContext(mWindowDC);
   218         }
   219     }
   221     mInitialized = true;
   223     // Call this to create the global GLContext instance,
   224     // and to check for errors.  Note that this must happen /after/
   225     // setting mInitialized to TRUE, or an infinite loop results.
   226     if (GLContextProviderWGL::GetGlobalContext() == nullptr) {
   227         mInitialized = false;
   228         return false;
   229     }
   231     reporter.SetSuccessful();
   232     return true;
   233 }
   235 GLContextWGL::GLContextWGL(
   236                   const SurfaceCaps& caps,
   237                   GLContext* sharedContext,
   238                   bool isOffscreen,
   239                   HDC aDC,
   240                   HGLRC aContext,
   241                   HWND aWindow)
   242     : GLContext(caps, sharedContext, isOffscreen),
   243       mDC(aDC),
   244       mContext(aContext),
   245       mWnd(aWindow),
   246       mPBuffer(nullptr),
   247       mPixelFormat(0),
   248       mIsDoubleBuffered(false)
   249 {
   250     // See 899855
   251     SetProfileVersion(ContextProfile::OpenGLCompatibility, 200);
   252 }
   254 GLContextWGL::GLContextWGL(
   255                   const SurfaceCaps& caps,
   256                   GLContext* sharedContext,
   257                   bool isOffscreen,
   258                   HANDLE aPbuffer,
   259                   HDC aDC,
   260                   HGLRC aContext,
   261                   int aPixelFormat)
   262     : GLContext(caps, sharedContext, isOffscreen),
   263       mDC(aDC),
   264       mContext(aContext),
   265       mWnd(nullptr),
   266       mPBuffer(aPbuffer),
   267       mPixelFormat(aPixelFormat),
   268       mIsDoubleBuffered(false)
   269 {
   270     // See 899855
   271     SetProfileVersion(ContextProfile::OpenGLCompatibility, 200);
   272 }
   274 GLContextWGL::~GLContextWGL()
   275 {
   276     MarkDestroyed();
   278     sWGLLib.fDeleteContext(mContext);
   280     if (mPBuffer)
   281         sWGLLib.fDestroyPbuffer(mPBuffer);
   282     if (mWnd)
   283         DestroyWindow(mWnd);
   284 }
   286 bool
   287 GLContextWGL::Init()
   288 {
   289     if (!mDC || !mContext)
   290         return false;
   292     // see bug 929506 comment 29. wglGetProcAddress requires a current context.
   293     if (!sWGLLib.fMakeCurrent(mDC, mContext))
   294         return false;
   296     SetupLookupFunction();
   297     if (!InitWithPrefix("gl", true))
   298         return false;
   300     return true;
   301 }
   303 bool
   304 GLContextWGL::MakeCurrentImpl(bool aForce)
   305 {
   306     BOOL succeeded = true;
   308     // wglGetCurrentContext seems to just pull the HGLRC out
   309     // of its TLS slot, so no need to do our own tls slot.
   310     // You would think that wglMakeCurrent would avoid doing
   311     // work if mContext was already current, but not so much..
   312     if (aForce || sWGLLib.fGetCurrentContext() != mContext) {
   313         succeeded = sWGLLib.fMakeCurrent(mDC, mContext);
   314         NS_ASSERTION(succeeded, "Failed to make GL context current!");
   315     }
   317     return succeeded;
   318 }
   320 bool
   321 GLContextWGL::IsCurrent()
   322 {
   323     return sWGLLib.fGetCurrentContext() == mContext;
   324 }
   326 void
   327 GLContextWGL::SetIsDoubleBuffered(bool aIsDB)
   328 {
   329     mIsDoubleBuffered = aIsDB;
   330 }
   332 bool
   333 GLContextWGL::IsDoubleBuffered() const
   334 {
   335     return mIsDoubleBuffered;
   336 }
   338 bool
   339 GLContextWGL::SupportsRobustness() const
   340 {
   341     return sWGLLib.HasRobustness();
   342 }
   344 bool
   345 GLContextWGL::SwapBuffers() {
   346     if (!mIsDoubleBuffered)
   347         return false;
   348     return ::SwapBuffers(mDC);
   349 }
   351 bool
   352 GLContextWGL::SetupLookupFunction()
   353 {
   354     // Make sure that we have a ref to the OGL library;
   355     // when run under CodeXL, wglGetProcAddress won't return
   356     // the right thing for some core functions.
   357     MOZ_ASSERT(mLibrary == nullptr);
   359     mLibrary = sWGLLib.GetOGLLibrary();
   360     mLookupFunc = (PlatformLookupFunction)sWGLLib.fGetProcAddress;
   361     return true;
   362 }
   364 static bool
   365 GetMaxSize(HDC hDC, int format, gfxIntSize& size)
   366 {
   367     int query[] = {LOCAL_WGL_MAX_PBUFFER_WIDTH_ARB, LOCAL_WGL_MAX_PBUFFER_HEIGHT_ARB};
   368     int result[2];
   370     // (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, int *piValues)
   371     if (!sWGLLib.fGetPixelFormatAttribiv(hDC, format, 0, 2, query, result))
   372         return false;
   374     size.width = result[0];
   375     size.height = result[1];
   376     return true;
   377 }
   379 static bool
   380 IsValidSizeForFormat(HDC hDC, int format,
   381                      const gfxIntSize& requested)
   382 {
   383     gfxIntSize max;
   384     if (!GetMaxSize(hDC, format, max))
   385         return true;
   387     if (requested.width > max.width)
   388         return false;
   389     if (requested.height > max.height)
   390         return false;
   392     return true;
   393 }
   395 static GLContextWGL *
   396 GetGlobalContextWGL()
   397 {
   398     return static_cast<GLContextWGL*>(GLContextProviderWGL::GetGlobalContext());
   399 }
   401 already_AddRefed<GLContext>
   402 GLContextProviderWGL::CreateWrappingExisting(void*, void*)
   403 {
   404     return nullptr;
   405 }
   407 already_AddRefed<GLContext>
   408 GLContextProviderWGL::CreateForWindow(nsIWidget *aWidget)
   409 {
   410     if (!sWGLLib.EnsureInitialized()) {
   411         return nullptr;
   412     }
   414     /**
   415        * We need to make sure we call SetPixelFormat -after- calling
   416        * EnsureInitialized, otherwise it can load/unload the dll and
   417        * wglCreateContext will fail.
   418        */
   420     HDC dc = (HDC)aWidget->GetNativeData(NS_NATIVE_GRAPHIC);
   422     SetPixelFormat(dc, sWGLLib.GetWindowPixelFormat(), nullptr);
   423     HGLRC context;
   425     GLContextWGL *shareContext = GetGlobalContextWGL();
   427     if (sWGLLib.HasRobustness()) {
   428         int attribs[] = {
   429             LOCAL_WGL_CONTEXT_FLAGS_ARB, LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
   430             LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB,
   431             0
   432         };
   434         context = sWGLLib.fCreateContextAttribs(dc,
   435                                                           shareContext ? shareContext->Context() : nullptr,
   436                                                           attribs);
   437     } else {
   438         context = sWGLLib.fCreateContext(dc);
   439         if (context &&
   440             shareContext &&
   441             !sWGLLib.fShareLists(shareContext->Context(), context))
   442         {
   443             printf_stderr("WGL context creation failed for window: wglShareLists returned false!");
   444             sWGLLib.fDeleteContext(context);
   445             context = nullptr;
   446         }
   447     }
   449     if (!context) {
   450         return nullptr;
   451     }
   453     SurfaceCaps caps = SurfaceCaps::ForRGBA();
   454     nsRefPtr<GLContextWGL> glContext = new GLContextWGL(caps,
   455                                                         shareContext,
   456                                                         false,
   457                                                         dc,
   458                                                         context);
   459     if (!glContext->Init()) {
   460         return nullptr;
   461     }
   463     glContext->SetIsDoubleBuffered(true);
   465     return glContext.forget();
   466 }
   468 static already_AddRefed<GLContextWGL>
   469 CreatePBufferOffscreenContext(const gfxIntSize& aSize,
   470                               GLContextWGL *aShareContext)
   471 {
   472     WGLLibrary& wgl = sWGLLib;
   474 #define A1(_a,_x)  do { _a.AppendElement(_x); } while(0)
   475 #define A2(_a,_x,_y)  do { _a.AppendElement(_x); _a.AppendElement(_y); } while(0)
   477     nsTArray<int> attrs;
   479     A2(attrs, LOCAL_WGL_SUPPORT_OPENGL_ARB, LOCAL_GL_TRUE);
   480     A2(attrs, LOCAL_WGL_DRAW_TO_PBUFFER_ARB, LOCAL_GL_TRUE);
   481     A2(attrs, LOCAL_WGL_DOUBLE_BUFFER_ARB, LOCAL_GL_FALSE);
   483     A2(attrs, LOCAL_WGL_ACCELERATION_ARB, LOCAL_WGL_FULL_ACCELERATION_ARB);
   485     A2(attrs, LOCAL_WGL_DOUBLE_BUFFER_ARB, LOCAL_GL_FALSE);
   486     A2(attrs, LOCAL_WGL_STEREO_ARB, LOCAL_GL_FALSE);
   488     A1(attrs, 0);
   490     nsTArray<int> pbattrs;
   491     A1(pbattrs, 0);
   493 #undef A1
   494 #undef A2
   496     // We only need one!
   497     UINT numFormats = 1;
   498     int formats[1];
   499     HDC windowDC = wgl.GetWindowDC();
   500     if (!wgl.fChoosePixelFormat(windowDC,
   501                                 attrs.Elements(), nullptr,
   502                                 numFormats, formats, &numFormats)
   503         || numFormats == 0)
   504     {
   505         return nullptr;
   506     }
   508     // We don't care; just pick the first one.
   509     int chosenFormat = formats[0];
   510     if (!IsValidSizeForFormat(windowDC, chosenFormat, aSize))
   511         return nullptr;
   513     HANDLE pbuffer = wgl.fCreatePbuffer(windowDC, chosenFormat,
   514                                         aSize.width, aSize.height,
   515                                         pbattrs.Elements());
   516     if (!pbuffer) {
   517         return nullptr;
   518     }
   520     HDC pbdc = wgl.fGetPbufferDC(pbuffer);
   521     NS_ASSERTION(pbdc, "expected a dc");
   523     HGLRC context;
   524     if (wgl.HasRobustness()) {
   525         int attribs[] = {
   526             LOCAL_WGL_CONTEXT_FLAGS_ARB, LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
   527             LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB,
   528             0
   529         };
   531         context = wgl.fCreateContextAttribs(pbdc, aShareContext->Context(), attribs);
   532     } else {
   533         context = wgl.fCreateContext(pbdc);
   534         if (context && aShareContext) {
   535             if (!wgl.fShareLists(aShareContext->Context(), context)) {
   536                 wgl.fDeleteContext(context);
   537                 context = nullptr;
   538                 printf_stderr("ERROR - creating pbuffer context failed because wglShareLists returned FALSE");
   539             }
   540         }
   541     }
   543     if (!context) {
   544         wgl.fDestroyPbuffer(pbuffer);
   545         return nullptr;
   546     }
   548     SurfaceCaps dummyCaps = SurfaceCaps::Any();
   549     nsRefPtr<GLContextWGL> glContext = new GLContextWGL(dummyCaps,
   550                                                         aShareContext,
   551                                                         true,
   552                                                         pbuffer,
   553                                                         pbdc,
   554                                                         context,
   555                                                         chosenFormat);
   557     return glContext.forget();
   558 }
   560 static already_AddRefed<GLContextWGL>
   561 CreateWindowOffscreenContext()
   562 {
   563     // CreateWindowOffscreenContext must return a global-shared context
   564     GLContextWGL *shareContext = GetGlobalContextWGL();
   565     if (!shareContext) {
   566         return nullptr;
   567     }
   569     HDC dc;
   570     HWND win = sWGLLib.CreateDummyWindow(&dc);
   571     if (!win) {
   572         return nullptr;
   573     }
   575     HGLRC context = sWGLLib.fCreateContext(dc);
   576     if (sWGLLib.HasRobustness()) {
   577         int attribs[] = {
   578             LOCAL_WGL_CONTEXT_FLAGS_ARB, LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
   579             LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB,
   580             0
   581         };
   583         context = sWGLLib.fCreateContextAttribs(dc, shareContext->Context(), attribs);
   584     } else {
   585         context = sWGLLib.fCreateContext(dc);
   586         if (context && shareContext &&
   587             !sWGLLib.fShareLists(shareContext->Context(), context))
   588         {
   589             NS_WARNING("wglShareLists failed!");
   591             sWGLLib.fDeleteContext(context);
   592             DestroyWindow(win);
   593             return nullptr;
   594         }
   595     }
   597     if (!context) {
   598         return nullptr;
   599     }
   601     SurfaceCaps caps = SurfaceCaps::ForRGBA();
   602     nsRefPtr<GLContextWGL> glContext = new GLContextWGL(caps,
   603                                                         shareContext, true,
   604                                                         dc, context, win);
   606     return glContext.forget();
   607 }
   609 already_AddRefed<GLContext>
   610 GLContextProviderWGL::CreateOffscreen(const gfxIntSize& size,
   611                                       const SurfaceCaps& caps)
   612 {
   613     if (!sWGLLib.EnsureInitialized()) {
   614         return nullptr;
   615     }
   617     nsRefPtr<GLContextWGL> glContext;
   619     // Always try to create a pbuffer context first, because we
   620     // want the context isolation.
   621     if (sWGLLib.fCreatePbuffer &&
   622         sWGLLib.fChoosePixelFormat)
   623     {
   624         gfxIntSize dummySize = gfxIntSize(16, 16);
   625         glContext = CreatePBufferOffscreenContext(dummySize, GetGlobalContextWGL());
   626     }
   628     // If it failed, then create a window context and use a FBO.
   629     if (!glContext) {
   630         glContext = CreateWindowOffscreenContext();
   631     }
   633     if (!glContext ||
   634         !glContext->Init())
   635     {
   636         return nullptr;
   637     }
   639     if (!glContext->InitOffscreen(ToIntSize(size), caps))
   640         return nullptr;
   642     return glContext.forget();
   643 }
   645 static nsRefPtr<GLContextWGL> gGlobalContext;
   647 GLContext *
   648 GLContextProviderWGL::GetGlobalContext()
   649 {
   650     if (!sWGLLib.EnsureInitialized()) {
   651         return nullptr;
   652     }
   654     static bool triedToCreateContext = false;
   656     if (!triedToCreateContext && !gGlobalContext) {
   657         triedToCreateContext = true;
   659         // conveniently, we already have what we need...
   660         SurfaceCaps dummyCaps = SurfaceCaps::Any();
   661         gGlobalContext = new GLContextWGL(dummyCaps,
   662                                           nullptr, true,
   663                                           sWGLLib.GetWindowDC(),
   664                                           sWGLLib.GetWindowGLContext());
   665         if (!gGlobalContext->Init()) {
   666             NS_WARNING("Global context GLContext initialization failed?");
   667             gGlobalContext = nullptr;
   668             return nullptr;
   669         }
   670     }
   672     return static_cast<GLContext*>(gGlobalContext);
   673 }
   675 void
   676 GLContextProviderWGL::Shutdown()
   677 {
   678     gGlobalContext = nullptr;
   679 }
   681 } /* namespace gl */
   682 } /* namespace mozilla */

mercurial