mirror of
https://github.com/Feodor2/Mypal68.git
synced 2025-06-18 14:55:44 -04:00
Webgl Opengl fix
This commit is contained in:
parent
32172d9123
commit
3e5993cc08
@ -32,21 +32,10 @@ using namespace mozilla::widget;
|
||||
|
||||
WGLLibrary sWGLLib;
|
||||
|
||||
/*
|
||||
ScopedWindow::~ScopedWindow()
|
||||
{
|
||||
if (mDC) {
|
||||
MOZ_ALWAYS_TRUE( ReleaseDC(mDC) );
|
||||
}
|
||||
if (mWindow) {
|
||||
MOZ_ALWAYS_TRUE( DestroyWindow(mWindow) );
|
||||
}
|
||||
}
|
||||
*/
|
||||
static HWND CreateDummyWindow() {
|
||||
WNDCLASSW wc{};
|
||||
HWND WGLLibrary::CreateDummyWindow(HDC* aWindowDC) {
|
||||
WNDCLASSW wc;
|
||||
if (!GetClassInfoW(GetModuleHandle(nullptr), L"GLContextWGLClass", &wc)) {
|
||||
wc = {};
|
||||
ZeroMemory(&wc, sizeof(WNDCLASSW));
|
||||
wc.style = CS_OWNDC;
|
||||
wc.hInstance = GetModuleHandle(nullptr);
|
||||
wc.lpfnWndProc = DefWindowProc;
|
||||
@ -58,8 +47,43 @@ static HWND CreateDummyWindow() {
|
||||
}
|
||||
}
|
||||
|
||||
return CreateWindowW(L"GLContextWGLClass", L"GLContextWGL", 0, 0, 0, 1, 1,
|
||||
nullptr, nullptr, GetModuleHandle(nullptr), nullptr);
|
||||
HWND win =
|
||||
CreateWindowW(L"GLContextWGLClass", L"GLContextWGL", 0, 0, 0, 16, 16,
|
||||
nullptr, nullptr, GetModuleHandle(nullptr), nullptr);
|
||||
NS_ENSURE_TRUE(win, nullptr);
|
||||
|
||||
HDC dc = GetDC(win);
|
||||
NS_ENSURE_TRUE(dc, nullptr);
|
||||
|
||||
if (mWindowPixelFormat == 0) {
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR));
|
||||
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
||||
pfd.nVersion = 1;
|
||||
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
||||
pfd.iPixelType = PFD_TYPE_RGBA;
|
||||
pfd.cColorBits = 24;
|
||||
pfd.cRedBits = 8;
|
||||
pfd.cGreenBits = 8;
|
||||
pfd.cBlueBits = 8;
|
||||
pfd.cAlphaBits = 8;
|
||||
pfd.cDepthBits = gfxVars::UseWebRender() ? 24 : 0;
|
||||
pfd.iLayerType = PFD_MAIN_PLANE;
|
||||
|
||||
mWindowPixelFormat = ChoosePixelFormat(dc, &pfd);
|
||||
}
|
||||
|
||||
if (!mWindowPixelFormat || !SetPixelFormat(dc, mWindowPixelFormat, nullptr)) {
|
||||
NS_WARNING("SetPixelFormat failed!");
|
||||
DestroyWindow(win);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aWindowDC) {
|
||||
*aWindowDC = dc;
|
||||
}
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
static inline bool HasExtension(const char* aExtensions,
|
||||
@ -119,129 +143,124 @@ bool WGLLibrary::EnsureInitialized() {
|
||||
}
|
||||
}
|
||||
|
||||
mDummyWindow = CreateDummyWindow();
|
||||
MOZ_ASSERT(mDummyWindow);
|
||||
if (!mDummyWindow) return false;
|
||||
auto cleanup = MakeScopeExit([&]() { Reset(); });
|
||||
|
||||
mRootDc = GetDC(mDummyWindow);
|
||||
MOZ_ASSERT(mRootDc);
|
||||
if (!mRootDc) return false;
|
||||
|
||||
// --
|
||||
|
||||
{
|
||||
PIXELFORMATDESCRIPTOR pfd{};
|
||||
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
||||
pfd.nVersion = 1;
|
||||
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
|
||||
// pfd.iPixelType = PFD_TYPE_RGBA;
|
||||
// pfd.cColorBits = 24;
|
||||
// pfd.cRedBits = 8;
|
||||
// pfd.cGreenBits = 8;
|
||||
// pfd.cBlueBits = 8;
|
||||
// pfd.cAlphaBits = 8;
|
||||
pfd.iLayerType = PFD_MAIN_PLANE;
|
||||
|
||||
const auto pixelFormat = ChoosePixelFormat(mRootDc, &pfd);
|
||||
MOZ_ASSERT(pixelFormat);
|
||||
if (!pixelFormat) return false;
|
||||
const bool setPixelFormatOk = SetPixelFormat(mRootDc, pixelFormat, nullptr);
|
||||
MOZ_ASSERT(setPixelFormatOk);
|
||||
if (!setPixelFormatOk) return false;
|
||||
}
|
||||
|
||||
// --
|
||||
// This is ridiculous -- we have to actually create a context to
|
||||
// get the OpenGL ICD to load.
|
||||
mWindow = CreateDummyWindow(&mWindowDC);
|
||||
NS_ENSURE_TRUE(mWindow, false);
|
||||
|
||||
// create rendering context
|
||||
mDummyGlrc = mSymbols.fCreateContext(mRootDc);
|
||||
if (!mDummyGlrc) return false;
|
||||
mWindowGLContext = mSymbols.fCreateContext(mWindowDC);
|
||||
NS_ENSURE_TRUE(mWindowGLContext, false);
|
||||
|
||||
const auto curCtx = mSymbols.fGetCurrentContext();
|
||||
const auto curDC = mSymbols.fGetCurrentDC();
|
||||
|
||||
if (!mSymbols.fMakeCurrent(mRootDc, mDummyGlrc)) {
|
||||
if (!mSymbols.fMakeCurrent(mWindowDC, mWindowGLContext)) {
|
||||
NS_WARNING("wglMakeCurrent failed");
|
||||
return false;
|
||||
}
|
||||
const auto resetContext =
|
||||
MakeScopeExit([&]() { mSymbols.fMakeCurrent(curDC, curCtx); });
|
||||
|
||||
const auto loader = GetSymbolLoader();
|
||||
const auto& curCtx = mSymbols.fGetCurrentContext();
|
||||
const auto& curDC = mSymbols.fGetCurrentDC();
|
||||
|
||||
const auto& loader = GetSymbolLoader();
|
||||
|
||||
// Now we can grab all the other symbols that we couldn't without having
|
||||
// a context current.
|
||||
// clang-format off
|
||||
const SymLoadStruct reqExtSymbols[] = {
|
||||
const SymLoadStruct pbufferSymbols[] = {
|
||||
{ (PRFuncPtr*)&mSymbols.fCreatePbuffer, {{ "wglCreatePbufferARB", "wglCreatePbufferEXT" }} },
|
||||
{ (PRFuncPtr*)&mSymbols.fDestroyPbuffer, {{ "wglDestroyPbufferARB", "wglDestroyPbufferEXT" }} },
|
||||
{ (PRFuncPtr*)&mSymbols.fGetPbufferDC, {{ "wglGetPbufferDCARB", "wglGetPbufferDCEXT" }} },
|
||||
{ (PRFuncPtr*)&mSymbols.fReleasePbufferDC, {{ "wglReleasePbufferDCARB", "wglReleasePbufferDCEXT" }} },
|
||||
// { (PRFuncPtr*)&mSymbols.fBindTexImage, {{ "wglBindTexImageARB", "wglBindTexImageEXT" }} },
|
||||
// { (PRFuncPtr*)&mSymbols.fReleaseTexImage, {{ "wglReleaseTexImageARB", "wglReleaseTexImageEXT" }} },
|
||||
{ (PRFuncPtr*)&mSymbols.fBindTexImage, {{ "wglBindTexImageARB", "wglBindTexImageEXT" }} },
|
||||
{ (PRFuncPtr*)&mSymbols.fReleaseTexImage, {{ "wglReleaseTexImageARB", "wglReleaseTexImageEXT" }} },
|
||||
END_OF_SYMBOLS
|
||||
};
|
||||
|
||||
const SymLoadStruct pixFmtSymbols[] = {
|
||||
{ (PRFuncPtr*)&mSymbols.fChoosePixelFormat, {{ "wglChoosePixelFormatARB", "wglChoosePixelFormatEXT" }} },
|
||||
// { (PRFuncPtr*)&mSymbols.fGetPixelFormatAttribiv, {{ "wglGetPixelFormatAttribivARB", "wglGetPixelFormatAttribivEXT" }} },
|
||||
SYMBOL(GetExtensionsStringARB),
|
||||
{ (PRFuncPtr*)&mSymbols.fGetPixelFormatAttribiv, {{ "wglGetPixelFormatAttribivARB", "wglGetPixelFormatAttribivEXT" }} },
|
||||
END_OF_SYMBOLS
|
||||
};
|
||||
// clang-format on
|
||||
if (!loader.LoadSymbols(reqExtSymbols)) {
|
||||
NS_WARNING("reqExtSymbols missing");
|
||||
return false;
|
||||
|
||||
if (!loader.LoadSymbols(pbufferSymbols)) {
|
||||
// this isn't an error, just means that pbuffers aren't supported
|
||||
ClearSymbols(pbufferSymbols);
|
||||
}
|
||||
|
||||
// --
|
||||
if (!loader.LoadSymbols(pixFmtSymbols)) {
|
||||
// this isn't an error, just means that we don't have the pixel format
|
||||
// extension
|
||||
ClearSymbols(pixFmtSymbols);
|
||||
}
|
||||
|
||||
const auto extString = mSymbols.fGetExtensionsStringARB(mRootDc);
|
||||
MOZ_ASSERT(extString);
|
||||
MOZ_ASSERT(HasExtension(extString, "WGL_ARB_extensions_string"));
|
||||
const SymLoadStruct extensionsSymbols[] = {SYMBOL(GetExtensionsStringARB),
|
||||
END_OF_SYMBOLS};
|
||||
|
||||
// --
|
||||
const SymLoadStruct robustnessSymbols[] = {SYMBOL(CreateContextAttribsARB),
|
||||
END_OF_SYMBOLS};
|
||||
|
||||
if (HasExtension(extString, "WGL_ARB_create_context")) {
|
||||
const SymLoadStruct createContextSymbols[] = {
|
||||
SYMBOL(CreateContextAttribsARB), END_OF_SYMBOLS};
|
||||
if (loader.LoadSymbols(createContextSymbols)) {
|
||||
if (HasExtension(extString, "WGL_ARB_create_context_robustness")) {
|
||||
mHasRobustness = true;
|
||||
const SymLoadStruct dxInteropSymbols[] = {SYMBOL(DXSetResourceShareHandleNV),
|
||||
SYMBOL(DXOpenDeviceNV),
|
||||
SYMBOL(DXCloseDeviceNV),
|
||||
SYMBOL(DXRegisterObjectNV),
|
||||
SYMBOL(DXUnregisterObjectNV),
|
||||
SYMBOL(DXObjectAccessNV),
|
||||
SYMBOL(DXLockObjectsNV),
|
||||
SYMBOL(DXUnlockObjectsNV),
|
||||
END_OF_SYMBOLS};
|
||||
|
||||
if (loader.LoadSymbols(extensionsSymbols)) {
|
||||
const char* extString = mSymbols.fGetExtensionsStringARB(mWindowDC);
|
||||
MOZ_ASSERT(extString);
|
||||
MOZ_ASSERT(HasExtension(extString, "WGL_ARB_extensions_string"));
|
||||
|
||||
if (HasExtension(extString, "WGL_ARB_create_context")) {
|
||||
if (loader.LoadSymbols(robustnessSymbols)) {
|
||||
if (HasExtension(extString, "WGL_ARB_create_context_robustness")) {
|
||||
mHasRobustness = true;
|
||||
}
|
||||
} else {
|
||||
NS_ERROR(
|
||||
"WGL supports ARB_create_context without supplying its functions.");
|
||||
ClearSymbols(robustnessSymbols);
|
||||
}
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
bool hasDXInterop2 = HasExtension(extString, "WGL_NV_DX_interop2");
|
||||
if (gfxVars::DXInterop2Blocked() &&
|
||||
!StaticPrefs::gl_ignore_dx_interop2_blacklist()) {
|
||||
hasDXInterop2 = false;
|
||||
}
|
||||
|
||||
if (hasDXInterop2) {
|
||||
if (!loader.LoadSymbols(dxInteropSymbols)) {
|
||||
NS_ERROR(
|
||||
"WGL supports NV_DX_interop(2) without supplying its functions.");
|
||||
ClearSymbols(dxInteropSymbols);
|
||||
}
|
||||
} else {
|
||||
NS_ERROR(
|
||||
"WGL_ARB_create_context announced without supplying its functions.");
|
||||
ClearSymbols(createContextSymbols);
|
||||
}
|
||||
}
|
||||
|
||||
// --
|
||||
// reset back to the previous context, just in case
|
||||
mSymbols.fMakeCurrent(curDC, curCtx);
|
||||
|
||||
bool hasDXInterop2 = HasExtension(extString, "WGL_NV_DX_interop2");
|
||||
if (gfxVars::DXInterop2Blocked() &&
|
||||
!StaticPrefs::gl_ignore_dx_interop2_blacklist()) {
|
||||
hasDXInterop2 = false;
|
||||
}
|
||||
if (mHasRobustness) {
|
||||
mSymbols.fDeleteContext(mWindowGLContext);
|
||||
|
||||
if (hasDXInterop2) {
|
||||
const SymLoadStruct dxInteropSymbols[] = {
|
||||
SYMBOL(DXSetResourceShareHandleNV),
|
||||
SYMBOL(DXOpenDeviceNV),
|
||||
SYMBOL(DXCloseDeviceNV),
|
||||
SYMBOL(DXRegisterObjectNV),
|
||||
SYMBOL(DXUnregisterObjectNV),
|
||||
SYMBOL(DXObjectAccessNV),
|
||||
SYMBOL(DXLockObjectsNV),
|
||||
SYMBOL(DXUnlockObjectsNV),
|
||||
END_OF_SYMBOLS};
|
||||
if (!loader.LoadSymbols(dxInteropSymbols)) {
|
||||
NS_ERROR(
|
||||
"WGL_NV_DX_interop2 announceed without supplying its functions.");
|
||||
ClearSymbols(dxInteropSymbols);
|
||||
const int attribs[] = {LOCAL_WGL_CONTEXT_FLAGS_ARB,
|
||||
LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
|
||||
LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||
LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB, 0};
|
||||
|
||||
mWindowGLContext =
|
||||
mSymbols.fCreateContextAttribsARB(mWindowDC, nullptr, attribs);
|
||||
if (!mWindowGLContext) {
|
||||
mHasRobustness = false;
|
||||
mWindowGLContext = mSymbols.fCreateContext(mWindowDC);
|
||||
}
|
||||
}
|
||||
|
||||
// --
|
||||
|
||||
cleanup.release();
|
||||
|
||||
mInitialized = true;
|
||||
|
||||
reporter.SetSuccessful();
|
||||
@ -251,21 +270,6 @@ bool WGLLibrary::EnsureInitialized() {
|
||||
#undef SYMBOL
|
||||
#undef END_OF_SYMBOLS
|
||||
|
||||
void WGLLibrary::Reset() {
|
||||
if (mDummyGlrc) {
|
||||
(void)mSymbols.fDeleteContext(mDummyGlrc);
|
||||
mDummyGlrc = nullptr;
|
||||
}
|
||||
if (mRootDc) {
|
||||
(void)ReleaseDC(mDummyWindow, mRootDc);
|
||||
mRootDc = nullptr;
|
||||
}
|
||||
if (mDummyWindow) {
|
||||
(void)DestroyWindow(mDummyWindow);
|
||||
mDummyWindow = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
GLContextWGL::GLContextWGL(CreateContextFlags flags, const SurfaceCaps& caps,
|
||||
bool isOffscreen, HDC aDC, HGLRC aContext,
|
||||
HWND aWindow)
|
||||
@ -289,16 +293,10 @@ GLContextWGL::GLContextWGL(CreateContextFlags flags, const SurfaceCaps& caps,
|
||||
GLContextWGL::~GLContextWGL() {
|
||||
MarkDestroyed();
|
||||
|
||||
(void)sWGLLib.mSymbols.fDeleteContext(mContext);
|
||||
sWGLLib.mSymbols.fDeleteContext(mContext);
|
||||
|
||||
if (mPBuffer) {
|
||||
(void)sWGLLib.mSymbols.fReleasePbufferDC(mPBuffer, mDC);
|
||||
(void)sWGLLib.mSymbols.fDestroyPbuffer(mPBuffer);
|
||||
}
|
||||
if (mWnd) {
|
||||
(void)ReleaseDC(mWnd, mDC);
|
||||
DestroyWindow(mWnd);
|
||||
}
|
||||
if (mPBuffer) sWGLLib.mSymbols.fDestroyPbuffer(mPBuffer);
|
||||
if (mWnd) DestroyWindow(mWnd);
|
||||
}
|
||||
|
||||
bool GLContextWGL::MakeCurrentImpl() const {
|
||||
@ -311,6 +309,12 @@ bool GLContextWGL::IsCurrentImpl() const {
|
||||
return sWGLLib.mSymbols.fGetCurrentContext() == mContext;
|
||||
}
|
||||
|
||||
void GLContextWGL::SetIsDoubleBuffered(bool aIsDB) {
|
||||
mIsDoubleBuffered = aIsDB;
|
||||
}
|
||||
|
||||
bool GLContextWGL::IsDoubleBuffered() const { return mIsDoubleBuffered; }
|
||||
|
||||
bool GLContextWGL::SwapBuffers() {
|
||||
if (!mIsDoubleBuffered) return false;
|
||||
return ::SwapBuffers(mDC);
|
||||
@ -321,145 +325,80 @@ void GLContextWGL::GetWSIInfo(nsCString* const out) const {
|
||||
out->Append(sWGLLib.mSymbols.fGetExtensionsStringARB(mDC));
|
||||
}
|
||||
|
||||
static bool GetMaxSize(HDC hDC, int format, IntSize& size) {
|
||||
int query[] = {LOCAL_WGL_MAX_PBUFFER_WIDTH_ARB,
|
||||
LOCAL_WGL_MAX_PBUFFER_HEIGHT_ARB};
|
||||
int result[2];
|
||||
|
||||
// (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int*
|
||||
// piAttributes, int* piValues)
|
||||
if (!sWGLLib.mSymbols.fGetPixelFormatAttribiv(hDC, format, 0, 2, query,
|
||||
result))
|
||||
return false;
|
||||
|
||||
size.width = result[0];
|
||||
size.height = result[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool IsValidSizeForFormat(HDC hDC, int format,
|
||||
const IntSize& requested) {
|
||||
IntSize max;
|
||||
if (!GetMaxSize(hDC, format, max)) return true;
|
||||
|
||||
if (requested.width > max.width) return false;
|
||||
if (requested.height > max.height) return false;
|
||||
|
||||
return true;
|
||||
} // namespace gl
|
||||
|
||||
already_AddRefed<GLContext> GLContextProviderWGL::CreateWrappingExisting(
|
||||
void*, void*) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
HGLRC
|
||||
WGLLibrary::CreateContextWithFallback(const HDC dc,
|
||||
const bool tryRobustBuffers) const {
|
||||
if (mHasRobustness) {
|
||||
if (tryRobustBuffers) {
|
||||
const int attribs[] = {LOCAL_WGL_CONTEXT_FLAGS_ARB,
|
||||
LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
|
||||
LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||
LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB, 0};
|
||||
const auto context =
|
||||
mSymbols.fCreateContextAttribsARB(dc, nullptr, attribs);
|
||||
if (context) return context;
|
||||
}
|
||||
|
||||
const int attribs[] = {LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||
LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB, 0};
|
||||
const auto context =
|
||||
mSymbols.fCreateContextAttribsARB(dc, nullptr, attribs);
|
||||
if (context) return context;
|
||||
already_AddRefed<GLContext> CreateForWidget(HWND aHwnd,
|
||||
#ifdef MOZ_BUILD_WEBRENDER
|
||||
bool aWebRender,
|
||||
#endif
|
||||
bool aForceAccelerated) {
|
||||
if (!sWGLLib.EnsureInitialized()) {
|
||||
return nullptr;
|
||||
}
|
||||
if (mSymbols.fCreateContextAttribsARB) {
|
||||
const auto context =
|
||||
mSymbols.fCreateContextAttribsARB(dc, nullptr, nullptr);
|
||||
if (context) return context;
|
||||
|
||||
/**
|
||||
* We need to make sure we call SetPixelFormat -after- calling
|
||||
* EnsureInitialized, otherwise it can load/unload the dll and
|
||||
* wglCreateContext will fail.
|
||||
*/
|
||||
|
||||
HDC dc = ::GetDC(aHwnd);
|
||||
|
||||
SetPixelFormat(dc, sWGLLib.GetWindowPixelFormat(), nullptr);
|
||||
HGLRC context;
|
||||
|
||||
if (sWGLLib.HasRobustness()) {
|
||||
int attribs[] = {LOCAL_WGL_CONTEXT_FLAGS_ARB,
|
||||
LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
|
||||
LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||
LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB, 0};
|
||||
context = sWGLLib.mSymbols.fCreateContextAttribsARB(dc, nullptr, attribs);
|
||||
} else {
|
||||
context = sWGLLib.mSymbols.fCreateContext(dc);
|
||||
}
|
||||
return mSymbols.fCreateContext(dc);
|
||||
}
|
||||
|
||||
static RefPtr<GLContext> CreateForWidget(const HWND window,
|
||||
#ifdef MOZ_BUILD_WEBRENDER
|
||||
const bool isWebRender,
|
||||
#endif
|
||||
const bool requireAccelerated) {
|
||||
auto& wgl = sWGLLib;
|
||||
if (!wgl.EnsureInitialized()) return nullptr;
|
||||
|
||||
const auto dc = GetDC(window);
|
||||
if (!dc) return nullptr;
|
||||
auto cleanupDc = MakeScopeExit([&]() { (void)ReleaseDC(window, dc); });
|
||||
|
||||
int chosenFormat;
|
||||
UINT foundFormats = 0;
|
||||
|
||||
if (!foundFormats) {
|
||||
const int kAttribs[] = {LOCAL_WGL_DRAW_TO_WINDOW_ARB,
|
||||
true,
|
||||
LOCAL_WGL_SUPPORT_OPENGL_ARB,
|
||||
true,
|
||||
LOCAL_WGL_DOUBLE_BUFFER_ARB,
|
||||
true,
|
||||
LOCAL_WGL_ACCELERATION_ARB,
|
||||
LOCAL_WGL_FULL_ACCELERATION_ARB,
|
||||
0};
|
||||
const int* attribs;
|
||||
#ifdef MOZ_BUILD_WEBRENDER
|
||||
const int kAttribsForWebRender[] = {LOCAL_WGL_DRAW_TO_WINDOW_ARB,
|
||||
true,
|
||||
LOCAL_WGL_SUPPORT_OPENGL_ARB,
|
||||
true,
|
||||
LOCAL_WGL_DOUBLE_BUFFER_ARB,
|
||||
true,
|
||||
LOCAL_WGL_DEPTH_BITS_ARB,
|
||||
24,
|
||||
LOCAL_WGL_ACCELERATION_ARB,
|
||||
LOCAL_WGL_FULL_ACCELERATION_ARB,
|
||||
0};
|
||||
if (wr::RenderThread::IsInRenderThread()) {
|
||||
attribs = kAttribsForWebRender;
|
||||
} else {
|
||||
#endif
|
||||
attribs = kAttribs;
|
||||
#ifdef MOZ_BUILD_WEBRENDER
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!wgl.mSymbols.fChoosePixelFormat(wgl.RootDc(), attribs, nullptr, 1,
|
||||
&chosenFormat, &foundFormats)) {
|
||||
foundFormats = 0;
|
||||
}
|
||||
}
|
||||
if (!foundFormats) {
|
||||
if (requireAccelerated) return nullptr;
|
||||
|
||||
const int kAttribs[] = {LOCAL_WGL_DRAW_TO_WINDOW_ARB,
|
||||
true,
|
||||
LOCAL_WGL_SUPPORT_OPENGL_ARB,
|
||||
true,
|
||||
LOCAL_WGL_DOUBLE_BUFFER_ARB,
|
||||
true,
|
||||
0};
|
||||
const int* attribs;
|
||||
#ifdef MOZ_BUILD_WEBRENDER
|
||||
const int kAttribsForWebRender[] = {LOCAL_WGL_DRAW_TO_WINDOW_ARB,
|
||||
true,
|
||||
LOCAL_WGL_SUPPORT_OPENGL_ARB,
|
||||
true,
|
||||
LOCAL_WGL_DOUBLE_BUFFER_ARB,
|
||||
true,
|
||||
LOCAL_WGL_DEPTH_BITS_ARB,
|
||||
24,
|
||||
0};
|
||||
|
||||
if (wr::RenderThread::IsInRenderThread()) {
|
||||
attribs = kAttribsForWebRender;
|
||||
} else {
|
||||
#endif
|
||||
attribs = kAttribs;
|
||||
#ifdef MOZ_BUILD_WEBRENDER
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!wgl.mSymbols.fChoosePixelFormat(wgl.RootDc(), attribs, nullptr, 1,
|
||||
&chosenFormat, &foundFormats)) {
|
||||
foundFormats = 0;
|
||||
}
|
||||
}
|
||||
if (!foundFormats) return nullptr;
|
||||
|
||||
// We need to make sure we call SetPixelFormat -after- calling
|
||||
// EnsureInitialized, otherwise it can load/unload the dll and
|
||||
// wglCreateContext will fail.
|
||||
|
||||
SetPixelFormat(dc, chosenFormat, nullptr);
|
||||
const auto context = sWGLLib.CreateContextWithFallback(dc, false);
|
||||
if (!context) return nullptr;
|
||||
|
||||
SurfaceCaps caps = SurfaceCaps::ForRGBA();
|
||||
const RefPtr<GLContextWGL> gl = new GLContextWGL(
|
||||
CreateContextFlags::NONE, SurfaceCaps::ForRGBA(), false, dc, context);
|
||||
cleanupDc.release();
|
||||
gl->mIsDoubleBuffered = true;
|
||||
if (!gl->Init()) return nullptr;
|
||||
RefPtr<GLContextWGL> glContext =
|
||||
new GLContextWGL(CreateContextFlags::NONE, caps, false, dc, context);
|
||||
if (!glContext->Init()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return gl;
|
||||
glContext->SetIsDoubleBuffered(true);
|
||||
|
||||
return glContext.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<GLContext> GLContextProviderWGL::CreateForCompositorWidget(
|
||||
@ -476,8 +415,7 @@ already_AddRefed<GLContext> GLContextProviderWGL::CreateForCompositorWidget(
|
||||
#ifdef MOZ_BUILD_WEBRENDER
|
||||
aWebRender,
|
||||
#endif
|
||||
aForceAccelerated)
|
||||
.forget();
|
||||
aForceAccelerated);
|
||||
}
|
||||
|
||||
already_AddRefed<GLContext> GLContextProviderWGL::CreateForWindow(
|
||||
@ -490,77 +428,141 @@ already_AddRefed<GLContext> GLContextProviderWGL::CreateForWindow(
|
||||
#ifdef MOZ_BUILD_WEBRENDER
|
||||
aWebRender,
|
||||
#endif
|
||||
aForceAccelerated)
|
||||
.forget();
|
||||
aForceAccelerated);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
already_AddRefed<GLContext> GLContextProviderWGL::CreateHeadless(
|
||||
const CreateContextFlags flags, nsACString* const out_failureId) {
|
||||
auto& wgl = sWGLLib;
|
||||
if (!wgl.EnsureInitialized()) return nullptr;
|
||||
static already_AddRefed<GLContextWGL> CreatePBufferOffscreenContext(
|
||||
CreateContextFlags flags, const IntSize& aSize) {
|
||||
WGLLibrary& wgl = sWGLLib;
|
||||
|
||||
int chosenFormat;
|
||||
UINT foundFormats = 0;
|
||||
const int pfAttribs[] = {LOCAL_WGL_SUPPORT_OPENGL_ARB,
|
||||
LOCAL_GL_TRUE,
|
||||
LOCAL_WGL_ACCELERATION_ARB,
|
||||
LOCAL_WGL_FULL_ACCELERATION_ARB,
|
||||
|
||||
if (!foundFormats) {
|
||||
const int kAttribs[] = {LOCAL_WGL_DRAW_TO_PBUFFER_ARB,
|
||||
true,
|
||||
LOCAL_WGL_SUPPORT_OPENGL_ARB,
|
||||
true,
|
||||
LOCAL_WGL_ACCELERATION_ARB,
|
||||
LOCAL_WGL_FULL_ACCELERATION_ARB,
|
||||
0};
|
||||
if (!wgl.mSymbols.fChoosePixelFormat(wgl.RootDc(), kAttribs, nullptr, 1,
|
||||
&chosenFormat, &foundFormats)) {
|
||||
foundFormats = 0;
|
||||
}
|
||||
LOCAL_WGL_DRAW_TO_PBUFFER_ARB,
|
||||
LOCAL_GL_TRUE,
|
||||
LOCAL_WGL_DOUBLE_BUFFER_ARB,
|
||||
LOCAL_GL_FALSE,
|
||||
LOCAL_WGL_STEREO_ARB,
|
||||
LOCAL_GL_FALSE,
|
||||
|
||||
0};
|
||||
|
||||
// We only need one!
|
||||
static const uint32_t kMaxFormats = 1024;
|
||||
int formats[kMaxFormats];
|
||||
uint32_t foundFormats;
|
||||
HDC windowDC = wgl.GetWindowDC();
|
||||
if (!wgl.mSymbols.fChoosePixelFormat(windowDC, pfAttribs, nullptr,
|
||||
kMaxFormats, formats, &foundFormats) ||
|
||||
foundFormats == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!foundFormats) {
|
||||
const int kAttribs[] = {LOCAL_WGL_DRAW_TO_PBUFFER_ARB, true,
|
||||
LOCAL_WGL_SUPPORT_OPENGL_ARB, true, 0};
|
||||
if (!wgl.mSymbols.fChoosePixelFormat(wgl.RootDc(), kAttribs, nullptr, 1,
|
||||
&chosenFormat, &foundFormats)) {
|
||||
foundFormats = 0;
|
||||
}
|
||||
|
||||
// We don't care; just pick the first one.
|
||||
int chosenFormat = formats[0];
|
||||
if (!IsValidSizeForFormat(windowDC, chosenFormat, aSize)) return nullptr;
|
||||
|
||||
const int pbAttribs[] = {0};
|
||||
HANDLE pbuffer = wgl.mSymbols.fCreatePbuffer(
|
||||
windowDC, chosenFormat, aSize.width, aSize.height, pbAttribs);
|
||||
if (!pbuffer) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!foundFormats) return nullptr;
|
||||
const int kPbufferAttribs[] = {0};
|
||||
const auto pbuffer = wgl.mSymbols.fCreatePbuffer(wgl.RootDc(), chosenFormat,
|
||||
1, 1, kPbufferAttribs);
|
||||
if (!pbuffer) return nullptr;
|
||||
auto cleanupPbuffer =
|
||||
MakeScopeExit([&]() { (void)wgl.mSymbols.fDestroyPbuffer(pbuffer); });
|
||||
|
||||
const auto dc = wgl.mSymbols.fGetPbufferDC(pbuffer);
|
||||
if (!dc) return nullptr;
|
||||
auto cleanupDc = MakeScopeExit(
|
||||
[&]() { (void)wgl.mSymbols.fReleasePbufferDC(pbuffer, dc); });
|
||||
HDC pbdc = wgl.mSymbols.fGetPbufferDC(pbuffer);
|
||||
NS_ASSERTION(pbdc, "expected a dc");
|
||||
|
||||
const auto context = wgl.CreateContextWithFallback(dc, true);
|
||||
if (!context) return nullptr;
|
||||
HGLRC context;
|
||||
if (wgl.HasRobustness()) {
|
||||
const int attribs[] = {LOCAL_WGL_CONTEXT_FLAGS_ARB,
|
||||
LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
|
||||
LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||
LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB, 0};
|
||||
context = wgl.mSymbols.fCreateContextAttribsARB(pbdc, nullptr, attribs);
|
||||
} else {
|
||||
context = wgl.mSymbols.fCreateContext(pbdc);
|
||||
}
|
||||
|
||||
const bool isOffscreen = true;
|
||||
const RefPtr<GLContextWGL> gl =
|
||||
new GLContextWGL(flags, SurfaceCaps::Any(), isOffscreen, pbuffer, dc,
|
||||
context, chosenFormat);
|
||||
cleanupPbuffer.release();
|
||||
cleanupDc.release();
|
||||
if (!gl->Init()) return nullptr;
|
||||
if (!context) {
|
||||
wgl.mSymbols.fDestroyPbuffer(pbuffer);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return RefPtr<GLContext>(gl.get()).forget();
|
||||
SurfaceCaps dummyCaps = SurfaceCaps::Any();
|
||||
RefPtr<GLContextWGL> glContext = new GLContextWGL(
|
||||
flags, dummyCaps, true, pbuffer, pbdc, context, chosenFormat);
|
||||
return glContext.forget();
|
||||
}
|
||||
|
||||
static already_AddRefed<GLContextWGL> CreateWindowOffscreenContext() {
|
||||
HDC dc;
|
||||
HWND win = sWGLLib.CreateDummyWindow(&dc);
|
||||
if (!win) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
HGLRC context = sWGLLib.mSymbols.fCreateContext(dc);
|
||||
if (sWGLLib.HasRobustness()) {
|
||||
int attribs[] = {LOCAL_WGL_CONTEXT_FLAGS_ARB,
|
||||
LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
|
||||
LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||
LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB, 0};
|
||||
|
||||
context = sWGLLib.mSymbols.fCreateContextAttribsARB(dc, nullptr, attribs);
|
||||
} else {
|
||||
context = sWGLLib.mSymbols.fCreateContext(dc);
|
||||
}
|
||||
|
||||
if (!context) {
|
||||
}
|
||||
|
||||
SurfaceCaps caps = SurfaceCaps::ForRGBA();
|
||||
RefPtr<GLContextWGL> glContext =
|
||||
new GLContextWGL(CreateContextFlags::NONE, caps, true, dc, context, win);
|
||||
return glContext.forget();
|
||||
}
|
||||
|
||||
/*static*/ already_AddRefed<GLContext> GLContextProviderWGL::CreateHeadless(
|
||||
CreateContextFlags flags, nsACString* const out_failureId) {
|
||||
if (!sWGLLib.EnsureInitialized()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<GLContextWGL> glContext;
|
||||
|
||||
// Always try to create a pbuffer context first, because we
|
||||
// want the context isolation.
|
||||
if (sWGLLib.mSymbols.fCreatePbuffer && sWGLLib.mSymbols.fChoosePixelFormat) {
|
||||
IntSize dummySize = IntSize(16, 16);
|
||||
glContext = CreatePBufferOffscreenContext(flags, dummySize);
|
||||
}
|
||||
|
||||
// If it failed, then create a window context and use a FBO.
|
||||
if (!glContext) {
|
||||
glContext = CreateWindowOffscreenContext();
|
||||
}
|
||||
|
||||
if (!glContext || !glContext->Init()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<GLContext> retGL = glContext.get();
|
||||
return retGL.forget();
|
||||
}
|
||||
|
||||
/*static*/
|
||||
already_AddRefed<GLContext> GLContextProviderWGL::CreateOffscreen(
|
||||
const IntSize& size, const SurfaceCaps& minCaps, CreateContextFlags flags,
|
||||
nsACString* const out_failureId) {
|
||||
*out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WGL_INIT");
|
||||
|
||||
RefPtr<GLContext> gl = CreateHeadless(flags, out_failureId);
|
||||
if (!gl) return nullptr;
|
||||
|
||||
if (!gl->InitOffscreen(size, minCaps)) return nullptr;
|
||||
if (!gl->InitOffscreen(size, minCaps)) {
|
||||
*out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WGL_INIT");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return gl.forget();
|
||||
}
|
||||
@ -571,5 +573,5 @@ GLContext* GLContextProviderWGL::GetGlobalContext() { return nullptr; }
|
||||
/*static*/
|
||||
void GLContextProviderWGL::Shutdown() {}
|
||||
|
||||
} /* namespace gl */
|
||||
} // namespace gl
|
||||
} /* namespace mozilla */
|
||||
|
@ -11,7 +11,7 @@
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
||||
class GLContextWGL final : public GLContext {
|
||||
class GLContextWGL : public GLContext {
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GLContextWGL, override)
|
||||
// From Window: (possibly for offscreen!)
|
||||
@ -30,10 +30,21 @@ class GLContextWGL final : public GLContext {
|
||||
return GLContextType::WGL;
|
||||
}
|
||||
|
||||
static GLContextWGL* Cast(GLContext* gl) {
|
||||
MOZ_ASSERT(gl->GetContextType() == GLContextType::WGL);
|
||||
return static_cast<GLContextWGL*>(gl);
|
||||
}
|
||||
|
||||
virtual bool MakeCurrentImpl() const override;
|
||||
|
||||
virtual bool IsCurrentImpl() const override;
|
||||
virtual bool IsDoubleBuffered() const override { return mIsDoubleBuffered; }
|
||||
|
||||
void SetIsDoubleBuffered(bool aIsDB);
|
||||
|
||||
virtual bool IsDoubleBuffered() const override;
|
||||
|
||||
virtual bool SwapBuffers() override;
|
||||
|
||||
virtual void GetWSIInfo(nsCString* const out) const override;
|
||||
|
||||
Maybe<SymbolLoader> GetSymbolLoader() const override {
|
||||
@ -51,7 +62,6 @@ class GLContextWGL final : public GLContext {
|
||||
HANDLE mPBuffer;
|
||||
int mPixelFormat;
|
||||
|
||||
public:
|
||||
bool mIsDoubleBuffered = false;
|
||||
};
|
||||
|
||||
|
@ -4,46 +4,23 @@
|
||||
|
||||
#include "GLContextTypes.h"
|
||||
#include "GLLibraryLoader.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include <windows.h>
|
||||
|
||||
struct PRLibrary;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
/*
|
||||
struct ScopedDC
|
||||
{
|
||||
const HDC mDC;
|
||||
|
||||
ScopedDC() = delete;
|
||||
virtual ~ScopedDC() = 0;
|
||||
};
|
||||
|
||||
struct WindowDC final : public ScopedDC
|
||||
{
|
||||
const HWND mWindow;
|
||||
|
||||
WindowDC() = delete;
|
||||
~WindowDC();
|
||||
};
|
||||
|
||||
struct PBufferDC final : public ScopedDC
|
||||
{
|
||||
const HWND mWindow;
|
||||
|
||||
PBufferDC() = delete;
|
||||
~PBufferDC();
|
||||
};
|
||||
*/
|
||||
class WGLLibrary {
|
||||
public:
|
||||
~WGLLibrary() { Reset(); }
|
||||
WGLLibrary()
|
||||
: mInitialized(false),
|
||||
mHasRobustness(false),
|
||||
mWindow(0),
|
||||
mWindowDC(0),
|
||||
mWindowGLContext(0),
|
||||
mWindowPixelFormat(0) {}
|
||||
|
||||
private:
|
||||
void Reset();
|
||||
|
||||
public:
|
||||
struct {
|
||||
HGLRC(GLAPIENTRY* fCreateContext)(HDC);
|
||||
BOOL(GLAPIENTRY* fDeleteContext)(HGLRC);
|
||||
@ -51,24 +28,20 @@ class WGLLibrary {
|
||||
PROC(GLAPIENTRY* fGetProcAddress)(LPCSTR);
|
||||
HGLRC(GLAPIENTRY* fGetCurrentContext)(void);
|
||||
HDC(GLAPIENTRY* fGetCurrentDC)(void);
|
||||
// BOOL (GLAPIENTRY * fShareLists) (HGLRC oldContext, HGLRC newContext);
|
||||
BOOL(GLAPIENTRY* fShareLists)(HGLRC oldContext, HGLRC newContext);
|
||||
HANDLE(GLAPIENTRY* fCreatePbuffer)
|
||||
(HDC hDC, int iPixelFormat, int iWidth, int iHeight,
|
||||
const int* piAttribList);
|
||||
BOOL(GLAPIENTRY* fDestroyPbuffer)(HANDLE hPbuffer);
|
||||
HDC(GLAPIENTRY* fGetPbufferDC)(HANDLE hPbuffer);
|
||||
int(GLAPIENTRY* fReleasePbufferDC)(HANDLE hPbuffer, HDC dc);
|
||||
// BOOL (GLAPIENTRY * fBindTexImage) (HANDLE hPbuffer, int iBuffer);
|
||||
// BOOL (GLAPIENTRY * fReleaseTexImage) (HANDLE hPbuffer, int iBuffer);
|
||||
BOOL(GLAPIENTRY* fBindTexImage)(HANDLE hPbuffer, int iBuffer);
|
||||
BOOL(GLAPIENTRY* fReleaseTexImage)(HANDLE hPbuffer, int iBuffer);
|
||||
BOOL(GLAPIENTRY* fChoosePixelFormat)
|
||||
(HDC hdc, const int* piAttribIList, const FLOAT* pfAttribFList,
|
||||
UINT nMaxFormats, int* piFormats, UINT* nNumFormats);
|
||||
// BOOL (GLAPIENTRY * fGetPixelFormatAttribiv) (HDC hdc,
|
||||
// int iPixelFormat,
|
||||
// int iLayerPlane,
|
||||
// UINT nAttributes,
|
||||
// int* piAttributes,
|
||||
// int* piValues);
|
||||
BOOL(GLAPIENTRY* fGetPixelFormatAttribiv)
|
||||
(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes,
|
||||
int* piAttributes, int* piValues);
|
||||
const char*(GLAPIENTRY* fGetExtensionsStringARB)(HDC hdc);
|
||||
HGLRC(GLAPIENTRY* fCreateContextAttribsARB)
|
||||
(HDC hdc, HGLRC hShareContext, const int* attribList);
|
||||
@ -88,22 +61,27 @@ class WGLLibrary {
|
||||
} mSymbols = {};
|
||||
|
||||
bool EnsureInitialized();
|
||||
// UniquePtr<WindowDC> CreateDummyWindow();
|
||||
HGLRC CreateContextWithFallback(HDC dc, bool tryRobustBuffers) const;
|
||||
HWND CreateDummyWindow(HDC* aWindowDC = nullptr);
|
||||
|
||||
bool HasRobustness() const { return mHasRobustness; }
|
||||
bool HasDXInterop2() const { return bool(mSymbols.fDXOpenDeviceNV); }
|
||||
bool IsInitialized() const { return mInitialized; }
|
||||
auto GetOGLLibrary() const { return mOGLLibrary; }
|
||||
auto RootDc() const { return mRootDc; }
|
||||
SymbolLoader GetSymbolLoader() const;
|
||||
HWND GetWindow() const { return mWindow; }
|
||||
HDC GetWindowDC() const { return mWindowDC; }
|
||||
HGLRC GetWindowGLContext() const { return mWindowGLContext; }
|
||||
int GetWindowPixelFormat() const { return mWindowPixelFormat; }
|
||||
PRLibrary* GetOGLLibrary() { return mOGLLibrary; }
|
||||
|
||||
private:
|
||||
bool mInitialized = false;
|
||||
bool mInitialized;
|
||||
PRLibrary* mOGLLibrary;
|
||||
bool mHasRobustness;
|
||||
HWND mDummyWindow;
|
||||
HDC mRootDc;
|
||||
HGLRC mDummyGlrc;
|
||||
|
||||
HWND mWindow;
|
||||
HDC mWindowDC;
|
||||
HGLRC mWindowGLContext;
|
||||
int mWindowPixelFormat;
|
||||
};
|
||||
|
||||
// a global WGLLibrary instance
|
||||
|
@ -7376,7 +7376,7 @@
|
||||
|
||||
- name: webgl.disable-angle
|
||||
type: RelaxedAtomicBool
|
||||
value: false
|
||||
value: true
|
||||
mirror: always
|
||||
|
||||
- name: webgl.disable-wgl
|
||||
@ -7441,7 +7441,7 @@
|
||||
|
||||
- name: webgl.force-enabled
|
||||
type: RelaxedAtomicBool
|
||||
value: false
|
||||
value: true
|
||||
mirror: always
|
||||
|
||||
- name: webgl.force-layers-readback
|
||||
|
Loading…
Reference in New Issue
Block a user