Bug 1874684 - Part 28: Return DateDuration from DifferenceISODateTime. r=mgaudet
[gecko.git] / gfx / gl / GLContextProviderEAGL.mm
blob648d6642d42ead82d931e3a088f46fb1bd4ec5b1
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
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 "GLContextEAGL.h"
8 #include "GLLibraryLoader.h"
9 #include "nsDebug.h"
10 #include "nsIWidget.h"
11 #include "gfxFailure.h"
12 #include "prenv.h"
13 #include "mozilla/Preferences.h"
14 #include "mozilla/ProfilerLabels.h"
15 #include "mozilla/layers/CompositorOptions.h"
16 #include "mozilla/widget/CompositorWidget.h"
18 #import <UIKit/UIKit.h>
20 namespace mozilla {
21 namespace gl {
23 using namespace mozilla::widget;
25 GLContextEAGL::GLContextEAGL(const GLContextDesc& desc, EAGLContext* context,
26                              GLContext* sharedContext)
27     : GLContext(desc, sharedContext), mContext(context) {}
29 GLContextEAGL::~GLContextEAGL() {
30   MakeCurrent();
32   if (mBackbufferFB) {
33     fDeleteFramebuffers(1, &mBackbufferFB);
34   }
36   if (mBackbufferRB) {
37     fDeleteRenderbuffers(1, &mBackbufferRB);
38   }
40   MarkDestroyed();
42   if (mContext) {
43     [EAGLContext setCurrentContext:nil];
44     [mContext release];
45   }
48 bool GLContextEAGL::MakeCurrentImpl() const {
49   if (mContext) {
50     GLContext::ResetTLSCurrentContext();
52     if (![EAGLContext setCurrentContext:mContext]) {
53       return false;
54     }
55   }
56   return true;
59 bool GLContextEAGL::IsCurrentImpl() const {
60   return [EAGLContext currentContext] == mContext;
63 static PRFuncPtr GLAPIENTRY GetLoadedProcAddress(const char* const name) {
64   PRLibrary* lib = nullptr;
65   const auto& ret = PR_FindFunctionSymbolAndLibrary(name, &lib);
66   if (lib) {
67     PR_UnloadLibrary(lib);
68   }
69   return ret;
72 Maybe<SymbolLoader> GLContextEAGL::GetSymbolLoader() const {
73   return Some(SymbolLoader(&GetLoadedProcAddress));
76 bool GLContextEAGL::IsDoubleBuffered() const { return true; }
78 bool GLContextEAGL::SwapBuffers() {
79   AUTO_PROFILER_LABEL("GLContextEAGL::SwapBuffers", GRAPHICS);
81   [mContext presentRenderbuffer:LOCAL_GL_RENDERBUFFER];
82   return true;
85 void GLContextEAGL::GetWSIInfo(nsCString* const out) const {
86   out->AppendLiteral("EAGL");
89 static GLContextEAGL* GetGlobalContextEAGL() {
90   return static_cast<GLContextEAGL*>(GLContextProviderEAGL::GetGlobalContext());
93 static RefPtr<GLContext> CreateEAGLContext(const GLContextDesc& desc,
94                                            GLContextEAGL* sharedContext) {
95   EAGLRenderingAPI apis[] = {kEAGLRenderingAPIOpenGLES3,
96                              kEAGLRenderingAPIOpenGLES2};
98   // Try to create a GLES3 context if we can, otherwise fall back to GLES2
99   EAGLContext* context = nullptr;
100   for (EAGLRenderingAPI api : apis) {
101     if (sharedContext) {
102       context = [[EAGLContext alloc]
103           initWithAPI:api
104            sharegroup:sharedContext->GetEAGLContext().sharegroup];
105     } else {
106       context = [[EAGLContext alloc] initWithAPI:api];
107     }
109     if (context) {
110       break;
111     }
112   }
114   if (!context) {
115     return nullptr;
116   }
118   RefPtr<GLContextEAGL> glContext =
119       new GLContextEAGL(desc, context, sharedContext);
120   if (!glContext->Init()) {
121     glContext = nullptr;
122     return nullptr;
123   }
125   return glContext;
128 already_AddRefed<GLContext> GLContextProviderEAGL::CreateForCompositorWidget(
129     CompositorWidget* aCompositorWidget, bool aHardwareWebRender,
130     bool aForceAccelerated) {
131   CreateContextFlags flags = CreateContextFlags::ALLOW_OFFLINE_RENDERER;
132   if (aForceAccelerated) {
133     flags |= CreateContextFlags::FORBID_SOFTWARE;
134   }
135   nsCString failureUnused;
136   return CreateHeadless({flags}, &failureUnused);
139 already_AddRefed<GLContext> GLContextProviderEAGL::CreateHeadless(
140     const GLContextCreateDesc& createDesc, nsACString* const out_failureId) {
141   auto desc = GLContextDesc{createDesc};
142   return CreateEAGLContext(desc, GetGlobalContextEAGL()).forget();
145 static RefPtr<GLContext> gGlobalContext;
147 GLContext* GLContextProviderEAGL::GetGlobalContext() {
148   static bool triedToCreateContext = false;
149   if (!triedToCreateContext) {
150     triedToCreateContext = true;
152     MOZ_RELEASE_ASSERT(!gGlobalContext,
153                        "GFX: Global GL context already initialized.");
154     nsCString discardFailureId;
155     RefPtr<GLContext> temp = CreateHeadless({}, &discardFailureId);
156     gGlobalContext = temp;
158     if (!gGlobalContext) {
159       MOZ_CRASH("Failed to create global context");
160     }
161   }
163   return gGlobalContext;
166 void GLContextProviderEAGL::Shutdown() { gGlobalContext = nullptr; }
168 } /* namespace gl */
169 } /* namespace mozilla */