Sat, 03 Jan 2015 20:18:00 +0100
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 "GLContextCGL.h"
8 #include "TextureImageCGL.h"
9 #include "nsDebug.h"
10 #include "nsIWidget.h"
11 #include <OpenGL/gl.h>
12 #include "gfxPrefs.h"
13 #include "gfxFailure.h"
14 #include "prenv.h"
15 #include "mozilla/Preferences.h"
16 #include "GeckoProfiler.h"
17 #include "mozilla/gfx/MacIOSurface.h"
19 using namespace mozilla::gfx;
21 namespace mozilla {
22 namespace gl {
24 static bool gUseDoubleBufferedWindows = true;
26 class CGLLibrary
27 {
28 public:
29 CGLLibrary()
30 : mInitialized(false),
31 mOGLLibrary(nullptr),
32 mPixelFormat(nullptr)
33 { }
35 bool EnsureInitialized()
36 {
37 if (mInitialized) {
38 return true;
39 }
40 if (!mOGLLibrary) {
41 mOGLLibrary = PR_LoadLibrary("/System/Library/Frameworks/OpenGL.framework/OpenGL");
42 if (!mOGLLibrary) {
43 NS_WARNING("Couldn't load OpenGL Framework.");
44 return false;
45 }
46 }
48 const char* db = PR_GetEnv("MOZ_CGL_DB");
49 gUseDoubleBufferedWindows = (!db || *db != '0');
51 mInitialized = true;
52 return true;
53 }
55 NSOpenGLPixelFormat *PixelFormat()
56 {
57 if (mPixelFormat == nullptr) {
58 NSOpenGLPixelFormatAttribute attribs[] = {
59 NSOpenGLPFAAccelerated,
60 NSOpenGLPFAAllowOfflineRenderers,
61 NSOpenGLPFADoubleBuffer,
62 0
63 };
65 if (!gUseDoubleBufferedWindows) {
66 attribs[2] = 0;
67 }
69 mPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
70 }
72 return mPixelFormat;
73 }
74 private:
75 bool mInitialized;
76 PRLibrary *mOGLLibrary;
77 NSOpenGLPixelFormat *mPixelFormat;
78 };
80 CGLLibrary sCGLLibrary;
82 GLContextCGL::GLContextCGL(
83 const SurfaceCaps& caps,
84 GLContext *shareContext,
85 NSOpenGLContext *context,
86 bool isOffscreen)
87 : GLContext(caps, shareContext, isOffscreen),
88 mContext(context)
89 {
90 SetProfileVersion(ContextProfile::OpenGLCompatibility, 210);
91 }
93 GLContextCGL::~GLContextCGL()
94 {
95 MarkDestroyed();
97 if (mContext) {
98 if ([NSOpenGLContext currentContext] == mContext) {
99 // Clear the current context before releasing. If we don't do
100 // this, the next time we call [NSOpenGLContext currentContext],
101 // "invalid context" will be printed to the console.
102 [NSOpenGLContext clearCurrentContext];
103 }
104 [mContext release];
105 }
107 }
109 bool
110 GLContextCGL::Init()
111 {
112 if (!InitWithPrefix("gl", true))
113 return false;
115 return true;
116 }
118 CGLContextObj
119 GLContextCGL::GetCGLContext() const
120 {
121 return static_cast<CGLContextObj>([mContext CGLContextObj]);
122 }
124 bool
125 GLContextCGL::MakeCurrentImpl(bool aForce)
126 {
127 if (!aForce && [NSOpenGLContext currentContext] == mContext) {
128 return true;
129 }
131 if (mContext) {
132 [mContext makeCurrentContext];
133 // Use non-blocking swap in "ASAP mode".
134 // ASAP mode means that rendering is iterated as fast as possible.
135 // ASAP mode is entered when layout.frame_rate=0 (requires restart).
136 // If swapInt is 1, then glSwapBuffers will block and wait for a vblank signal.
137 // When we're iterating as fast as possible, however, we want a non-blocking
138 // glSwapBuffers, which will happen when swapInt==0.
139 GLint swapInt = gfxPrefs::LayoutFrameRate() == 0 ? 0 : 1;
140 [mContext setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
141 }
142 return true;
143 }
145 bool
146 GLContextCGL::IsCurrent() {
147 return [NSOpenGLContext currentContext] == mContext;
148 }
150 GLenum
151 GLContextCGL::GetPreferredARGB32Format() const
152 {
153 return LOCAL_GL_BGRA;
154 }
156 bool
157 GLContextCGL::SetupLookupFunction()
158 {
159 return false;
160 }
162 bool
163 GLContextCGL::IsDoubleBuffered() const
164 {
165 return gUseDoubleBufferedWindows;
166 }
168 bool
169 GLContextCGL::SupportsRobustness() const
170 {
171 return false;
172 }
174 bool
175 GLContextCGL::SwapBuffers()
176 {
177 PROFILER_LABEL("GLContext", "SwapBuffers");
178 [mContext flushBuffer];
179 return true;
180 }
183 static GLContextCGL *
184 GetGlobalContextCGL()
185 {
186 return static_cast<GLContextCGL*>(GLContextProviderCGL::GetGlobalContext());
187 }
189 already_AddRefed<GLContext>
190 GLContextProviderCGL::CreateWrappingExisting(void*, void*)
191 {
192 return nullptr;
193 }
195 already_AddRefed<GLContext>
196 GLContextProviderCGL::CreateForWindow(nsIWidget *aWidget)
197 {
198 GLContextCGL *shareContext = GetGlobalContextCGL();
200 NSOpenGLContext *context = [[NSOpenGLContext alloc]
201 initWithFormat:sCGLLibrary.PixelFormat()
202 shareContext:(shareContext ? shareContext->mContext : NULL)];
203 if (!context) {
204 return nullptr;
205 }
207 // make the context transparent
208 GLint opaque = 0;
209 [context setValues:&opaque forParameter:NSOpenGLCPSurfaceOpacity];
211 SurfaceCaps caps = SurfaceCaps::ForRGBA();
212 nsRefPtr<GLContextCGL> glContext = new GLContextCGL(caps,
213 shareContext,
214 context);
215 if (!glContext->Init()) {
216 return nullptr;
217 }
219 return glContext.forget();
220 }
222 static already_AddRefed<GLContextCGL>
223 CreateOffscreenFBOContext(bool aShare = true)
224 {
225 if (!sCGLLibrary.EnsureInitialized()) {
226 return nullptr;
227 }
229 GLContextCGL *shareContext = aShare ? GetGlobalContextCGL() : nullptr;
230 if (aShare && !shareContext) {
231 // if there is no share context, then we can't use FBOs.
232 return nullptr;
233 }
235 NSOpenGLContext *context = [[NSOpenGLContext alloc]
236 initWithFormat:sCGLLibrary.PixelFormat()
237 shareContext:shareContext ? shareContext->GetNSOpenGLContext() : NULL];
238 if (!context) {
239 return nullptr;
240 }
242 SurfaceCaps dummyCaps = SurfaceCaps::Any();
243 nsRefPtr<GLContextCGL> glContext = new GLContextCGL(dummyCaps, shareContext, context, true);
245 return glContext.forget();
246 }
248 already_AddRefed<GLContext>
249 GLContextProviderCGL::CreateOffscreen(const gfxIntSize& size,
250 const SurfaceCaps& caps)
251 {
252 nsRefPtr<GLContextCGL> glContext = CreateOffscreenFBOContext();
253 if (glContext &&
254 glContext->Init() &&
255 glContext->InitOffscreen(ToIntSize(size), caps))
256 {
257 return glContext.forget();
258 }
260 // everything failed
261 return nullptr;
262 }
264 static nsRefPtr<GLContext> gGlobalContext;
266 GLContext *
267 GLContextProviderCGL::GetGlobalContext()
268 {
269 if (!sCGLLibrary.EnsureInitialized()) {
270 return nullptr;
271 }
273 if (!gGlobalContext) {
274 // There are bugs in some older drivers with pbuffers less
275 // than 16x16 in size; also 16x16 is POT so that we can do
276 // a FBO with it on older video cards. A FBO context for
277 // sharing is preferred since it has no associated target.
278 gGlobalContext = CreateOffscreenFBOContext(false);
279 if (!gGlobalContext || !static_cast<GLContextCGL*>(gGlobalContext.get())->Init()) {
280 NS_WARNING("Couldn't init gGlobalContext.");
281 gGlobalContext = nullptr;
282 return nullptr;
283 }
284 }
286 return gGlobalContext;
287 }
289 void
290 GLContextProviderCGL::Shutdown()
291 {
292 gGlobalContext = nullptr;
293 }
295 } /* namespace gl */
296 } /* namespace mozilla */