2018-11-30 22:52:05 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
2012-05-21 15:12:37 +04:00
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2010-04-28 02:29:29 +04:00
|
|
|
|
|
|
|
#include "GLContextProvider.h"
|
2014-01-08 00:02:18 +04:00
|
|
|
#include "GLContextCGL.h"
|
2020-11-23 19:21:38 +03:00
|
|
|
#include "GLLibraryLoader.h"
|
2010-04-28 02:29:29 +04:00
|
|
|
#include "nsDebug.h"
|
|
|
|
#include "nsIWidget.h"
|
|
|
|
#include <OpenGL/gl.h>
|
2011-02-07 23:15:46 +03:00
|
|
|
#include "gfxFailure.h"
|
2020-02-11 04:23:37 +03:00
|
|
|
#include "mozilla/IntegerRange.h"
|
2019-07-26 04:10:23 +03:00
|
|
|
#include "mozilla/StaticPrefs_gfx.h"
|
|
|
|
#include "mozilla/StaticPrefs_gl.h"
|
|
|
|
#include "mozilla/StaticPrefs_layout.h"
|
2010-09-21 22:39:38 +04:00
|
|
|
#include "prenv.h"
|
2020-11-23 19:21:38 +03:00
|
|
|
#include "prlink.h"
|
Bug 1691589 - Reduce reliance on GeckoProfiler.h when only labels (and maybe markers) are needed - r=necko-reviewers,geckoview-reviewers,sg,agi,florian
There are no code changes, only #include changes.
It was a fairly mechanical process: Search for all "AUTO_PROFILER_LABEL", and in each file, if only labels are used, convert "GeckoProfiler.h" into "ProfilerLabels.h" (or just add that last one where needed).
In some files, there were also some marker calls but no other profiler-related calls, in these cases "GeckoProfiler.h" was replaced with both "ProfilerLabels.h" and "ProfilerMarkers.h", which still helps in reducing the use of the all-encompassing "GeckoProfiler.h".
Differential Revision: https://phabricator.services.mozilla.com/D104588
2021-02-16 07:44:19 +03:00
|
|
|
#include "mozilla/ProfilerLabels.h"
|
2019-07-17 23:44:44 +03:00
|
|
|
#include "MozFramebuffer.h"
|
2017-01-13 23:16:52 +03:00
|
|
|
#include "mozilla/layers/CompositorOptions.h"
|
2016-07-25 21:41:00 +03:00
|
|
|
#include "mozilla/widget/CompositorWidget.h"
|
2019-07-17 23:44:44 +03:00
|
|
|
#include "ScopedGLHelpers.h"
|
2010-04-28 02:29:29 +04:00
|
|
|
|
2015-11-11 00:14:24 +03:00
|
|
|
#include <OpenGL/OpenGL.h>
|
|
|
|
|
2010-04-28 02:29:29 +04:00
|
|
|
namespace mozilla {
|
|
|
|
namespace gl {
|
|
|
|
|
2014-05-22 14:11:45 +04:00
|
|
|
using namespace mozilla::gfx;
|
2016-07-25 21:41:00 +03:00
|
|
|
using namespace mozilla::widget;
|
2014-05-22 14:11:45 +04:00
|
|
|
|
2010-04-28 02:29:29 +04:00
|
|
|
class CGLLibrary {
|
|
|
|
public:
|
2011-09-29 10:19:26 +04:00
|
|
|
bool EnsureInitialized() {
|
2010-04-28 02:29:29 +04:00
|
|
|
if (mInitialized) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2010-04-28 02:29:29 +04:00
|
|
|
}
|
|
|
|
if (!mOGLLibrary) {
|
|
|
|
mOGLLibrary = PR_LoadLibrary("/System/Library/Frameworks/OpenGL.framework/OpenGL");
|
|
|
|
if (!mOGLLibrary) {
|
|
|
|
NS_WARNING("Couldn't load OpenGL Framework.");
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2015-02-13 06:00:41 +03:00
|
|
|
}
|
2010-04-28 02:29:29 +04:00
|
|
|
}
|
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
mInitialized = true;
|
|
|
|
return true;
|
2019-01-21 20:18:16 +03:00
|
|
|
}
|
|
|
|
|
2019-02-23 00:17:28 +03:00
|
|
|
const auto& Library() const { return mOGLLibrary; }
|
|
|
|
|
2010-04-28 02:29:29 +04:00
|
|
|
private:
|
2018-08-18 01:21:26 +03:00
|
|
|
bool mInitialized = false;
|
|
|
|
PRLibrary* mOGLLibrary = nullptr;
|
2014-03-04 06:47:43 +04:00
|
|
|
};
|
2010-04-28 02:29:29 +04:00
|
|
|
|
|
|
|
CGLLibrary sCGLLibrary;
|
|
|
|
|
2020-06-15 21:25:55 +03:00
|
|
|
GLContextCGL::GLContextCGL(const GLContextDesc& desc, NSOpenGLContext* context)
|
|
|
|
: GLContext(desc), mContext(context) {
|
2019-11-19 11:52:00 +03:00
|
|
|
CGDisplayRegisterReconfigurationCallback(DisplayReconfigurationCallback, this);
|
|
|
|
}
|
2019-01-21 20:18:16 +03:00
|
|
|
|
2015-02-13 06:00:41 +03:00
|
|
|
GLContextCGL::~GLContextCGL() {
|
|
|
|
MarkDestroyed();
|
2010-04-28 02:29:29 +04:00
|
|
|
|
2019-11-19 11:52:00 +03:00
|
|
|
CGDisplayRemoveReconfigurationCallback(DisplayReconfigurationCallback, this);
|
|
|
|
|
2018-10-26 19:30:48 +03:00
|
|
|
if (mContext) {
|
|
|
|
if ([NSOpenGLContext currentContext] == mContext) {
|
|
|
|
// Clear the current context before releasing. If we don't do
|
|
|
|
// this, the next time we call [NSOpenGLContext currentContext],
|
|
|
|
// "invalid context" will be printed to the console.
|
|
|
|
[NSOpenGLContext clearCurrentContext];
|
|
|
|
}
|
|
|
|
[mContext release];
|
2019-01-21 20:18:16 +03:00
|
|
|
}
|
2014-01-08 00:02:18 +04:00
|
|
|
}
|
2010-04-28 02:29:29 +04:00
|
|
|
|
2014-01-08 00:02:18 +04:00
|
|
|
CGLContextObj GLContextCGL::GetCGLContext() const {
|
|
|
|
return static_cast<CGLContextObj>([mContext CGLContextObj]);
|
|
|
|
}
|
2012-05-13 03:23:56 +04:00
|
|
|
|
2017-08-15 23:21:37 +03:00
|
|
|
bool GLContextCGL::MakeCurrentImpl() const {
|
2014-01-08 00:02:18 +04:00
|
|
|
if (mContext) {
|
|
|
|
[mContext makeCurrentContext];
|
2017-08-15 23:21:37 +03:00
|
|
|
MOZ_ASSERT(IsCurrentImpl());
|
2014-01-08 00:02:18 +04:00
|
|
|
// Use non-blocking swap in "ASAP mode".
|
|
|
|
// ASAP mode means that rendering is iterated as fast as possible.
|
|
|
|
// ASAP mode is entered when layout.frame_rate=0 (requires restart).
|
|
|
|
// If swapInt is 1, then glSwapBuffers will block and wait for a vblank signal.
|
|
|
|
// When we're iterating as fast as possible, however, we want a non-blocking
|
|
|
|
// glSwapBuffers, which will happen when swapInt==0.
|
2019-06-27 09:28:25 +03:00
|
|
|
GLint swapInt = StaticPrefs::layout_frame_rate() == 0 ? 0 : 1;
|
2014-01-08 00:02:18 +04:00
|
|
|
[mContext setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
|
2012-08-22 07:30:20 +04:00
|
|
|
}
|
2014-01-08 00:02:18 +04:00
|
|
|
return true;
|
|
|
|
}
|
2012-08-22 07:30:20 +04:00
|
|
|
|
2014-01-08 00:02:18 +04:00
|
|
|
bool GLContextCGL::IsCurrentImpl() const { return [NSOpenGLContext currentContext] == mContext; }
|
2013-07-09 18:13:33 +04:00
|
|
|
|
2019-11-19 11:52:00 +03:00
|
|
|
/* static */ void GLContextCGL::DisplayReconfigurationCallback(CGDirectDisplayID aDisplay,
|
|
|
|
CGDisplayChangeSummaryFlags aFlags,
|
|
|
|
void* aUserInfo) {
|
|
|
|
if (aFlags & kCGDisplaySetModeFlag) {
|
|
|
|
static_cast<GLContextCGL*>(aUserInfo)->mActiveGPUSwitchMayHaveOccurred = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static NSOpenGLContext* CreateWithFormat(const NSOpenGLPixelFormatAttribute* attribs) {
|
|
|
|
NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
|
|
|
|
if (!format) {
|
|
|
|
NS_WARNING("Failed to create NSOpenGLPixelFormat.");
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
NSOpenGLContext* context = [[NSOpenGLContext alloc] initWithFormat:format shareContext:nullptr];
|
|
|
|
|
|
|
|
[format release];
|
|
|
|
|
|
|
|
return context;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the "OpenGL display mask" for a fresh context. The return value of this
|
|
|
|
// function depends on the time at which this function is called.
|
|
|
|
// In practice, on a Macbook Pro with an integrated and a discrete GPU, this function returns the
|
|
|
|
// display mask for the GPU that currently drives the internal display.
|
|
|
|
//
|
|
|
|
// Quick reference of the concepts involved in the code below:
|
|
|
|
// GPU switch: On Mac devices with an integrated and a discrete GPU, a GPU switch changes which
|
|
|
|
// GPU drives the internal display. Both GPUs are still usable at all times. (When the
|
|
|
|
// integrated GPU is driving the internal display, using the discrete GPU can incur a longer
|
|
|
|
// warm-up cost.)
|
|
|
|
// Virtual screen: A CGL concept. A "virtual screen" corresponds to a GL renderer. There's one
|
|
|
|
// for the integrated GPU, one for each discrete GPU, and one for the Apple software renderer.
|
|
|
|
// The list of virtual screens is per-NSOpenGLPixelFormat; it is filtered down to only the
|
|
|
|
// renderers that support the requirements from the pixel format attributes. Indexes into this
|
|
|
|
// list (such as currentVirtualScreen) cannot be used interchangably across different
|
|
|
|
// NSOpenGLPixelFormat instances.
|
|
|
|
// Display mask: A bitset per GL renderer. Different renderers have disjoint display masks. The
|
|
|
|
// Apple software renderer has all bits zeroed. For each CGDirectDisplayID,
|
|
|
|
// CGDisplayIDToOpenGLDisplayMask(displayID) returns a single bit in the display mask.
|
|
|
|
// CGDirectDisplayID: An ID for each (physical screen, GPU which can drive this screen) pair. The
|
|
|
|
// current CGDirectDisplayID for an NSScreen object can be obtained using [[[screen
|
|
|
|
// deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue]; it changes depending on
|
|
|
|
// which GPU is currently driving the screen.
|
|
|
|
static CGOpenGLDisplayMask GetFreshContextDisplayMask() {
|
|
|
|
NSOpenGLPixelFormatAttribute attribs[] = {NSOpenGLPFAAllowOfflineRenderers, 0};
|
2019-12-11 00:57:23 +03:00
|
|
|
NSOpenGLPixelFormat* pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
|
|
|
|
MOZ_RELEASE_ASSERT(pixelFormat);
|
|
|
|
NSOpenGLContext* context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat
|
|
|
|
shareContext:nullptr];
|
2019-11-19 11:52:00 +03:00
|
|
|
GLint displayMask = 0;
|
|
|
|
[pixelFormat getValues:&displayMask
|
|
|
|
forAttribute:NSOpenGLPFAScreenMask
|
|
|
|
forVirtualScreen:[context currentVirtualScreen]];
|
2019-12-11 00:57:23 +03:00
|
|
|
[pixelFormat release];
|
2019-11-19 11:52:00 +03:00
|
|
|
[context release];
|
|
|
|
return static_cast<CGOpenGLDisplayMask>(displayMask);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool IsSameGPU(CGOpenGLDisplayMask mask1, CGOpenGLDisplayMask mask2) {
|
|
|
|
if ((mask1 & mask2) != 0) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
// Both masks can be zero, when using the Apple software renderer.
|
|
|
|
return !mask1 && !mask2;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GLContextCGL::MigrateToActiveGPU() {
|
|
|
|
if (!mActiveGPUSwitchMayHaveOccurred.compareExchange(true, false)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
CGOpenGLDisplayMask newPreferredDisplayMask = GetFreshContextDisplayMask();
|
2021-04-06 17:33:13 +03:00
|
|
|
NSOpenGLPixelFormat* pixelFormat = [mContext pixelFormat];
|
2019-11-19 11:52:00 +03:00
|
|
|
GLint currentVirtualScreen = [mContext currentVirtualScreen];
|
|
|
|
GLint currentDisplayMask = 0;
|
|
|
|
[pixelFormat getValues:¤tDisplayMask
|
|
|
|
forAttribute:NSOpenGLPFAScreenMask
|
|
|
|
forVirtualScreen:currentVirtualScreen];
|
|
|
|
if (IsSameGPU(currentDisplayMask, newPreferredDisplayMask)) {
|
|
|
|
// No "virtual screen" change needed.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Find the "virtual screen" with a display mask that matches newPreferredDisplayMask, if
|
|
|
|
// available, and switch the context over to it.
|
|
|
|
// This code was inspired by equivalent functionality in -[NSOpenGLContext update] which only
|
|
|
|
// kicks in for contexts that present via a CAOpenGLLayer.
|
|
|
|
for (const auto i : IntegerRange([pixelFormat numberOfVirtualScreens])) {
|
|
|
|
GLint displayMask = 0;
|
|
|
|
[pixelFormat getValues:&displayMask forAttribute:NSOpenGLPFAScreenMask forVirtualScreen:i];
|
|
|
|
if (IsSameGPU(displayMask, newPreferredDisplayMask)) {
|
|
|
|
CGLSetVirtualScreen([mContext CGLContextObj], i);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-04 06:47:43 +04:00
|
|
|
GLenum GLContextCGL::GetPreferredARGB32Format() const { return LOCAL_GL_BGRA; }
|
2010-04-28 02:29:29 +04:00
|
|
|
|
2014-01-08 00:02:18 +04:00
|
|
|
bool GLContextCGL::SwapBuffers() {
|
Bug 1375392 - Tweak the PROFILER_LABEL* macros. r=mstange.
This patch makes the following changes to the macros.
- Removes PROFILER_LABEL_FUNC. It's only suitable for use in functions outside
classes, due to PROFILER_FUNCTION_NAME not getting class names, and it was
mostly misused.
- Removes PROFILER_FUNCTION_NAME. It's no longer used, and __func__ is
universally available now anyway.
- Combines the first two string literal arguments of PROFILER_LABEL and
PROFILER_LABEL_DYNAMIC into a single argument. There was no good reason for
them to be separate, and it forced a '::' in the label, which isn't always
appropriate. Also, the meaning of the "name_space" argument was interpreted
in an interesting variety of ways.
- Adds an "AUTO_" prefix to PROFILER_LABEL and PROFILER_LABEL_DYNAMIC, to make
it clearer they construct RAII objects rather than just being function calls.
(I myself have screwed up the scoping because of this in the past.)
- Fills in the 'js::ProfileEntry::Category::' qualifier within the macro, so
the caller doesn't need to. This makes a *lot* more of the uses fit onto a
single line.
The patch also makes the following changes to the macro uses (beyond those
required by the changes described above).
- Fixes a bunch of labels that had gotten out of sync with the name of the
class and/or function that encloses them.
- Removes a useless PROFILER_LABEL use within a trivial scope in
EventStateManager::DispatchMouseOrPointerEvent(). It clearly wasn't serving
any useful purpose. It also serves as extra evidence that the AUTO_ prefix is
a good idea.
- Tweaks DecodePool::SyncRunIf{Preferred,Possible} so that the labelling is
done within them, instead of at their callsites, because that's a more
standard way of doing things.
--HG--
extra : rebase_source : 318d1bc6fc1425a94aacbf489dd46e4f83211de4
2017-06-22 10:08:53 +03:00
|
|
|
AUTO_PROFILER_LABEL("GLContextCGL::SwapBuffers", GRAPHICS);
|
2014-05-24 01:12:29 +04:00
|
|
|
|
2019-11-13 22:07:37 +03:00
|
|
|
// We do not have a default framebuffer. Just do a flush.
|
|
|
|
// Flushing is necessary if we want our IOSurfaces to have the correct
|
|
|
|
// content once they're picked up by the WindowServer from our CALayers.
|
|
|
|
fFlush();
|
2019-07-17 23:44:44 +03:00
|
|
|
|
2014-01-08 00:02:18 +04:00
|
|
|
return true;
|
|
|
|
}
|
2010-07-19 09:01:14 +04:00
|
|
|
|
2017-01-31 05:58:52 +03:00
|
|
|
void GLContextCGL::GetWSIInfo(nsCString* const out) const { out->AppendLiteral("CGL"); }
|
2010-04-28 02:29:29 +04:00
|
|
|
|
2019-02-23 00:17:28 +03:00
|
|
|
Maybe<SymbolLoader> GLContextCGL::GetSymbolLoader() const {
|
|
|
|
const auto& lib = sCGLLibrary.Library();
|
|
|
|
return Some(SymbolLoader(*lib));
|
|
|
|
}
|
|
|
|
|
2016-07-25 21:41:00 +03:00
|
|
|
already_AddRefed<GLContext> GLContextProviderCGL::CreateForCompositorWidget(
|
2021-04-07 10:04:43 +03:00
|
|
|
CompositorWidget* aCompositorWidget, bool aHardwareWebRender, bool aForceAccelerated) {
|
2019-11-19 06:49:06 +03:00
|
|
|
CreateContextFlags flags = CreateContextFlags::ALLOW_OFFLINE_RENDERER;
|
|
|
|
if (aForceAccelerated) {
|
|
|
|
flags |= CreateContextFlags::FORCE_ENABLE_HARDWARE;
|
2019-01-21 20:18:16 +03:00
|
|
|
}
|
2021-04-07 10:04:43 +03:00
|
|
|
if (!aHardwareWebRender) {
|
2019-11-19 06:49:06 +03:00
|
|
|
flags |= CreateContextFlags::REQUIRE_COMPAT_PROFILE;
|
2012-03-13 02:10:38 +04:00
|
|
|
}
|
2019-11-19 06:49:06 +03:00
|
|
|
nsCString failureUnused;
|
2020-06-15 21:25:55 +03:00
|
|
|
return CreateHeadless({flags}, &failureUnused);
|
2010-04-28 02:29:29 +04:00
|
|
|
}
|
|
|
|
|
2020-06-15 21:25:55 +03:00
|
|
|
static RefPtr<GLContextCGL> CreateOffscreenFBOContext(GLContextCreateDesc desc) {
|
2010-07-19 09:01:14 +04:00
|
|
|
if (!sCGLLibrary.EnsureInitialized()) {
|
2012-07-30 18:20:58 +04:00
|
|
|
return nullptr;
|
2010-05-18 08:04:22 +04:00
|
|
|
}
|
2019-01-21 20:18:16 +03:00
|
|
|
|
2015-02-13 06:00:41 +03:00
|
|
|
NSOpenGLContext* context = nullptr;
|
2019-01-21 20:18:16 +03:00
|
|
|
|
2018-06-23 02:47:02 +03:00
|
|
|
std::vector<NSOpenGLPixelFormatAttribute> attribs;
|
2020-06-15 21:25:55 +03:00
|
|
|
auto& flags = desc.flags;
|
2019-01-21 20:18:16 +03:00
|
|
|
|
2019-06-26 06:05:06 +03:00
|
|
|
if (!StaticPrefs::gl_allow_high_power()) {
|
2019-02-08 01:35:50 +03:00
|
|
|
flags &= ~CreateContextFlags::HIGH_POWER;
|
|
|
|
}
|
2018-06-23 02:47:02 +03:00
|
|
|
if (flags & CreateContextFlags::ALLOW_OFFLINE_RENDERER ||
|
|
|
|
!(flags & CreateContextFlags::HIGH_POWER)) {
|
|
|
|
// This is really poorly named on Apple's part, but "AllowOfflineRenderers" means
|
|
|
|
// that we want to allow running on the iGPU instead of requiring the dGPU.
|
|
|
|
attribs.push_back(NSOpenGLPFAAllowOfflineRenderers);
|
|
|
|
}
|
2019-01-21 20:18:16 +03:00
|
|
|
|
2019-11-19 20:57:35 +03:00
|
|
|
if (flags & CreateContextFlags::FORCE_ENABLE_HARDWARE) {
|
2018-06-23 02:47:02 +03:00
|
|
|
attribs.push_back(NSOpenGLPFAAccelerated);
|
|
|
|
}
|
2019-01-21 20:18:16 +03:00
|
|
|
|
2015-07-29 23:35:55 +03:00
|
|
|
if (!(flags & CreateContextFlags::REQUIRE_COMPAT_PROFILE)) {
|
2018-06-23 02:47:02 +03:00
|
|
|
auto coreAttribs = attribs;
|
|
|
|
coreAttribs.push_back(NSOpenGLPFAOpenGLProfile);
|
|
|
|
coreAttribs.push_back(NSOpenGLProfileVersion3_2Core);
|
|
|
|
coreAttribs.push_back(0);
|
|
|
|
context = CreateWithFormat(coreAttribs.data());
|
2015-02-13 06:00:41 +03:00
|
|
|
}
|
2019-01-21 20:18:16 +03:00
|
|
|
|
2018-06-23 02:47:02 +03:00
|
|
|
if (!context) {
|
|
|
|
attribs.push_back(0);
|
|
|
|
context = CreateWithFormat(attribs.data());
|
2018-06-26 04:21:08 +03:00
|
|
|
}
|
2019-01-21 20:18:16 +03:00
|
|
|
|
2010-07-19 09:01:14 +04:00
|
|
|
if (!context) {
|
2015-04-03 03:59:47 +03:00
|
|
|
NS_WARNING("Failed to create NSOpenGLContext.");
|
2012-07-30 18:20:58 +04:00
|
|
|
return nullptr;
|
2010-05-18 08:04:22 +04:00
|
|
|
}
|
|
|
|
|
2020-06-15 21:25:55 +03:00
|
|
|
RefPtr<GLContextCGL> glContext = new GLContextCGL({desc, true}, context);
|
2012-03-13 02:10:38 +04:00
|
|
|
|
2019-11-20 00:49:01 +03:00
|
|
|
if (flags & CreateContextFlags::PREFER_MULTITHREADED) {
|
2015-11-11 00:14:24 +03:00
|
|
|
CGLEnable(glContext->GetCGLContext(), kCGLCEMPEngine);
|
|
|
|
}
|
2020-06-15 21:25:55 +03:00
|
|
|
return glContext;
|
2010-07-19 09:01:14 +04:00
|
|
|
}
|
|
|
|
|
2020-06-15 21:25:55 +03:00
|
|
|
already_AddRefed<GLContext> GLContextProviderCGL::CreateHeadless(const GLContextCreateDesc& desc,
|
2016-06-11 05:01:00 +03:00
|
|
|
nsACString* const out_failureId) {
|
2020-06-15 21:25:55 +03:00
|
|
|
auto gl = CreateOffscreenFBOContext(desc);
|
2016-06-06 23:52:42 +03:00
|
|
|
if (!gl) {
|
2016-06-11 05:01:00 +03:00
|
|
|
*out_failureId = "FEATURE_FAILURE_CGL_FBO"_ns;
|
2014-08-28 03:16:22 +04:00
|
|
|
return nullptr;
|
2016-06-06 23:52:42 +03:00
|
|
|
}
|
2014-08-28 03:16:22 +04:00
|
|
|
|
2015-04-03 03:59:47 +03:00
|
|
|
if (!gl->Init()) {
|
2016-06-11 05:01:00 +03:00
|
|
|
*out_failureId = "FEATURE_FAILURE_CGL_INIT"_ns;
|
2015-04-03 03:59:47 +03:00
|
|
|
NS_WARNING("Failed during Init.");
|
2014-08-28 03:16:22 +04:00
|
|
|
return nullptr;
|
2015-04-03 03:59:47 +03:00
|
|
|
}
|
2014-08-28 03:16:22 +04:00
|
|
|
|
2015-02-13 06:00:41 +03:00
|
|
|
return gl.forget();
|
2014-08-28 03:16:22 +04:00
|
|
|
}
|
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
static RefPtr<GLContext> gGlobalContext;
|
2010-07-19 09:01:14 +04:00
|
|
|
|
2014-01-10 22:55:23 +04:00
|
|
|
GLContext* GLContextProviderCGL::GetGlobalContext() {
|
2016-04-22 02:32:18 +03:00
|
|
|
static bool triedToCreateContext = false;
|
|
|
|
if (!triedToCreateContext) {
|
|
|
|
triedToCreateContext = true;
|
2019-01-21 20:18:16 +03:00
|
|
|
|
2016-04-22 02:32:18 +03:00
|
|
|
MOZ_RELEASE_ASSERT(!gGlobalContext);
|
2016-06-06 23:52:42 +03:00
|
|
|
nsCString discardFailureId;
|
2020-06-15 21:25:55 +03:00
|
|
|
RefPtr<GLContext> temp = CreateHeadless({}, &discardFailureId);
|
2016-04-22 02:32:18 +03:00
|
|
|
gGlobalContext = temp;
|
2019-01-21 20:18:16 +03:00
|
|
|
|
2016-04-22 02:32:18 +03:00
|
|
|
if (!gGlobalContext) {
|
2010-07-25 04:10:58 +04:00
|
|
|
NS_WARNING("Couldn't init gGlobalContext.");
|
2010-07-19 09:01:14 +04:00
|
|
|
}
|
2019-01-21 20:18:16 +03:00
|
|
|
}
|
2010-07-19 09:01:14 +04:00
|
|
|
|
|
|
|
return gGlobalContext;
|
|
|
|
}
|
|
|
|
|
2010-07-20 08:05:42 +04:00
|
|
|
void GLContextProviderCGL::Shutdown() { gGlobalContext = nullptr; }
|
|
|
|
|
2010-04-28 02:29:29 +04:00
|
|
|
} /* namespace gl */
|
|
|
|
} /* namespace mozilla */
|