mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-10-29 15:26:04 +03:00
391 lines
10 KiB
Plaintext
391 lines
10 KiB
Plaintext
#include "gx/gll/GLContext.h"
|
|
#include "gx/gll/GLDevice.h"
|
|
#include "util/Autorelease.hpp"
|
|
#include <bc/Debug.hpp>
|
|
|
|
NSOpenGLContext* GLContext::s_MainContext;
|
|
Blizzard::Thread::TLSSlot GLContext::s_CurrentContext;
|
|
Blizzard::Thread::TLSSlot GLContext::s_CurrentGLContext;
|
|
CFDictionaryRef GLContext::s_DesktopMode;
|
|
|
|
void* Sub2A1E0(void* ptr) {
|
|
NSOpenGLContext** ptrptr = new NSOpenGLContext*;
|
|
*ptrptr = nullptr;
|
|
return ptrptr;
|
|
}
|
|
|
|
void Sub2A200(void* ptr) {
|
|
delete static_cast<NSOpenGLContext**>(ptr);
|
|
}
|
|
|
|
void* Sub720A0(void* ptr) {
|
|
GLContext** ptrptr = new GLContext*;
|
|
*ptrptr = nullptr;
|
|
return ptrptr;
|
|
}
|
|
|
|
void Sub720C0(void* ptr) {
|
|
delete static_cast<GLContext**>(ptr);
|
|
}
|
|
|
|
GLContext::Context::~Context() {
|
|
if (this->context) {
|
|
glFlush();
|
|
|
|
[this->context clearDrawable];
|
|
|
|
if (GLContext::GetCurrentContext() == context) {
|
|
[NSOpenGLContext clearCurrentContext];
|
|
GLContext::SetCurrentContext(nullptr);
|
|
}
|
|
|
|
[this->context release];
|
|
}
|
|
|
|
[this->pixelFormat release];
|
|
}
|
|
|
|
NSOpenGLContext* GLContext::GetNSOpenGLCurrentContext() {
|
|
return [NSOpenGLContext currentContext];
|
|
}
|
|
|
|
NSOpenGLContext* GLContext::GetCurrentContext() {
|
|
return *static_cast<NSOpenGLContext**>(
|
|
Blizzard::Thread::RegisterLocalStorage(&GLContext::s_CurrentContext, Sub2A1E0, 0, Sub2A200)
|
|
);
|
|
}
|
|
|
|
void GLContext::SetCurrentContext(NSOpenGLContext* context) {
|
|
*static_cast<NSOpenGLContext**>(
|
|
Blizzard::Thread::RegisterLocalStorage(&GLContext::s_CurrentContext, Sub2A1E0, 0, Sub2A200)
|
|
) = context;
|
|
}
|
|
|
|
GLContext* GLContext::GetCurrentGLContext() {
|
|
return *static_cast<GLContext**>(
|
|
Blizzard::Thread::RegisterLocalStorage(&GLContext::s_CurrentGLContext, Sub720A0, 0, Sub720C0)
|
|
);
|
|
}
|
|
|
|
void GLContext::SetCurrentGLContext(GLContext* context) {
|
|
*static_cast<GLContext**>(
|
|
Blizzard::Thread::RegisterLocalStorage(&GLContext::s_CurrentGLContext, Sub720A0, 0, Sub720C0)
|
|
) = context;
|
|
}
|
|
|
|
GLContext::GLContext(GLDevice* a2, const char* a3) {
|
|
this->m_Context = nullptr;
|
|
this->m_Window = nullptr;
|
|
this->m_Windowed = false;
|
|
this->m_MTGLEnabled = false;
|
|
this->m_Device = a2;
|
|
this->m_Width = 0;
|
|
this->m_Height = 0;
|
|
this->m_RefreshRate = 0;
|
|
}
|
|
|
|
int32_t GLContext::GetBackingWidth() {
|
|
if (this->m_Windowed) {
|
|
return this->m_Window->GetBackingWidth();
|
|
} else {
|
|
return this->m_Width;
|
|
}
|
|
}
|
|
|
|
int32_t GLContext::GetBackingHeight() {
|
|
if (this->m_Windowed) {
|
|
return this->m_Window->GetBackingHeight();
|
|
} else {
|
|
return this->m_Height;
|
|
}
|
|
}
|
|
|
|
int32_t GLContext::GetWidth() {
|
|
if (this->m_Windowed) {
|
|
return this->m_Window->GetWidth();
|
|
} else {
|
|
return this->m_Width;
|
|
}
|
|
}
|
|
|
|
int32_t GLContext::GetHeight() {
|
|
if (this->m_Windowed) {
|
|
return this->m_Window->GetHeight();
|
|
} else {
|
|
return this->m_Height;
|
|
}
|
|
}
|
|
|
|
bool GLContext::IsCurrentContext() {
|
|
return GLContext::GetCurrentGLContext() == this;
|
|
}
|
|
|
|
void GLContext::MakeCurrent(bool a2) {
|
|
BLIZZARD_ASSERT(this->m_Context->context != nullptr);
|
|
|
|
if (a2) {
|
|
NSOpenGLContext* v6 = GLContext::GetNSOpenGLCurrentContext();
|
|
GLContext::SetCurrentContext(v6);
|
|
}
|
|
|
|
if (this->m_Context->context != GLContext::GetCurrentContext()) {
|
|
int32_t mtglEnabled = 0;
|
|
|
|
if (GLContext::GetCurrentContext()) {
|
|
mtglEnabled = this->m_MTGLEnabled;
|
|
|
|
// TODO
|
|
// this->ToggleMTGL(0);
|
|
// GLOcclusionQuery::DeleteAllQueries();
|
|
// GLFence::DeleteAllFences();
|
|
|
|
glFlush();
|
|
}
|
|
|
|
[this->m_Context->context makeCurrentContext];
|
|
|
|
GLContext::SetCurrentContext(this->m_Context->context);
|
|
GLContext::SetCurrentGLContext(this);
|
|
|
|
// TODO
|
|
// GLOcclusionQuery::RecreateAllQueries();
|
|
// GLFence::RecreateAllFences();
|
|
// this->ToggleMTGL(mtglEnabled);
|
|
|
|
GLDevice* device = GLDevice::Get();
|
|
|
|
if (device && this->m_Contexts.size() > 1) {
|
|
device->ApplyGLStates(device->m_States, 1);
|
|
device->ApplyGLBindings(device->m_States, 1);
|
|
device->m_DefaultVertexArrayObject.ApplyGLStates(device->m_DefaultVertexArrayObject.m_GLStates);
|
|
}
|
|
}
|
|
}
|
|
|
|
void GLContext::SetContextFormat(GLTextureFormat a2, uint32_t sampleCount) {
|
|
System_Autorelease::ScopedPool autorelease;
|
|
|
|
uint32_t v61 = sampleCount | (a2 << 8);
|
|
|
|
if (this->m_Contexts.find(v61) != this->m_Contexts.end()) {
|
|
this->m_Context = &this->m_Contexts[v61];
|
|
|
|
if (this->m_Window) {
|
|
this->m_Window->SetOpenGLContext(this);
|
|
}
|
|
} else {
|
|
auto& context = this->m_Contexts[v61];
|
|
|
|
CGDirectDisplayID v6 = CGMainDisplayID();
|
|
|
|
NSOpenGLPixelFormatAttribute formatAttributes[] = {
|
|
NSOpenGLPFADoubleBuffer,
|
|
NSOpenGLPFANoRecovery,
|
|
NSOpenGLPFAAccelerated,
|
|
NSOpenGLPFADepthSize, 0,
|
|
NSOpenGLPFAStencilSize, 0,
|
|
NSOpenGLPFAColorSize, 32,
|
|
NSOpenGLPFAWindow,
|
|
NSOpenGLPFAFullScreen,
|
|
NSOpenGLPFAScreenMask, CGDisplayIDToOpenGLDisplayMask(v6),
|
|
0, 0, 0, 0, 0
|
|
};
|
|
|
|
switch (a2) {
|
|
case GLTF_INVALID:
|
|
break;
|
|
|
|
case GLTF_D32:
|
|
formatAttributes[4] = 32;
|
|
break;
|
|
|
|
case GLTF_D24:
|
|
formatAttributes[4] = 24;
|
|
break;
|
|
|
|
case GLTF_D16:
|
|
formatAttributes[4] = 16;
|
|
break;
|
|
|
|
case GLTF_D24S8:
|
|
formatAttributes[4] = 24;
|
|
formatAttributes[6] = 8;
|
|
break;
|
|
|
|
default:
|
|
BLIZZARD_ASSERT(false);
|
|
break;
|
|
}
|
|
|
|
if (sampleCount > 1) {
|
|
BLIZZARD_ASSERT(sampleCount % 2 == 0);
|
|
BLIZZARD_ASSERT(formatAttributes[13] == 0);
|
|
BLIZZARD_ASSERT(formatAttributes[14] == 0);
|
|
BLIZZARD_ASSERT(formatAttributes[15] == 0);
|
|
BLIZZARD_ASSERT(formatAttributes[16] == 0);
|
|
BLIZZARD_ASSERT(formatAttributes[17] == 0);
|
|
|
|
formatAttributes[13] = NSOpenGLPFASampleBuffers;
|
|
formatAttributes[14] = 1;
|
|
formatAttributes[15] = NSOpenGLPFASamples;
|
|
formatAttributes[16] = sampleCount;
|
|
}
|
|
|
|
context.sampleCount = sampleCount;
|
|
|
|
context.pixelFormat = [[NSOpenGLPixelFormat alloc]
|
|
initWithAttributes: formatAttributes
|
|
];
|
|
|
|
BLIZZARD_ASSERT(context.pixelFormat != nullptr);
|
|
|
|
context.context = [[NSOpenGLContext alloc]
|
|
initWithFormat: context.pixelFormat
|
|
shareContext: GLContext::s_MainContext
|
|
];
|
|
|
|
BLIZZARD_ASSERT(context.context != nullptr);
|
|
|
|
this->m_Context = &context;
|
|
|
|
auto contextObj = [context.context CGLContextObj];
|
|
|
|
int32_t vsyncEnabled = this->m_VSyncEnabled;
|
|
CGLSetParameter(contextObj, kCGLCPSwapInterval, &vsyncEnabled);
|
|
|
|
auto result = this->m_MTGLEnabled
|
|
? CGLEnable(contextObj, kCGLCEMPEngine)
|
|
: CGLDisable(contextObj, kCGLCEMPEngine);
|
|
BLIZZARD_ASSERT(result == kCGLNoError);
|
|
|
|
if (this->m_Window) {
|
|
this->m_Window->SetOpenGLContext(this);
|
|
}
|
|
}
|
|
|
|
if (this->m_Context->context != GLContext::GetCurrentContext()) {
|
|
this->MakeCurrent(0);
|
|
}
|
|
}
|
|
|
|
void GLContext::SetFullscreenMode(uint32_t, uint32_t, uint32_t, bool) {
|
|
// TODO
|
|
}
|
|
|
|
void GLContext::SetWindow(GLAbstractWindow* a2, bool a3) {
|
|
if (!a2) {
|
|
if (this->m_Window) {
|
|
this->m_Window->SetOpenGLContext(nullptr);
|
|
}
|
|
|
|
this->m_Window = nullptr;
|
|
|
|
return;
|
|
}
|
|
|
|
if (this->m_Windowed && a2 == this->m_Window) {
|
|
if (a3) {
|
|
a2->Show();
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
NSView* v5;
|
|
|
|
if (this->m_Window) {
|
|
v5 = this->m_Window->GetNSView();
|
|
|
|
if (v5 && this->m_Windowed && a2 != this->m_Window) {
|
|
this->m_Window = a2;
|
|
this->m_Window->SetOpenGLContext(this);
|
|
|
|
return;
|
|
}
|
|
} else {
|
|
v5 = nullptr;
|
|
}
|
|
|
|
this->m_Window = a2;
|
|
|
|
if (!a2->GetNSView()) {
|
|
this->m_Window->CreateView();
|
|
}
|
|
|
|
float v15;
|
|
bool v16 = false;
|
|
CGDisplayFadeReservationToken v17 = 0;
|
|
|
|
if (v5 && GLDevice::GetRendererInfo().unk100 > 2639 && this->m_Window->CanEnterFullscreenMode()) {
|
|
if (!this->m_Windowed) {
|
|
if (!GLContext::s_DesktopMode) {
|
|
// TODO
|
|
// Blizzard::Debug::Assert(
|
|
// "s_DesktopMode",
|
|
// "/Users/Shared/BuildServer/wow2.old/work/WoW-code/branches/wow-patch-3_3_5-BNet/WoW/Source/Mac/../../../"
|
|
// "Engine/Source/Gx/CGxDeviceGLL/GLLayer/GLContext.cpp",
|
|
// 215
|
|
// );
|
|
}
|
|
|
|
v15 = 1.25;
|
|
v16 = false;
|
|
CGDisplayFadeReservationToken v8 = 0;
|
|
|
|
CGError v7 = CGAcquireDisplayFadeReservation(2.25, &v17);
|
|
|
|
if (!v7) {
|
|
v8 = v17;
|
|
}
|
|
|
|
v17 = v8;
|
|
|
|
if (v8) {
|
|
v16 = CGDisplayFade(v8, 0.25, 0, 1.0, 0, 0, 0, 1) == kCGErrorSuccess;
|
|
}
|
|
|
|
CGDirectDisplayID v10 = CGMainDisplayID();
|
|
CGDisplaySwitchToMode(v10, GLContext::s_DesktopMode);
|
|
|
|
this->m_Window->ExitFullscreenMode();
|
|
|
|
// TODO
|
|
// SetSystemUIMode(0, 0);
|
|
}
|
|
|
|
CGReleaseAllDisplays();
|
|
}
|
|
|
|
if (a3) {
|
|
this->m_Window->Show();
|
|
}
|
|
|
|
this->m_Windowed = 1;
|
|
CGDisplayRestoreColorSyncSettings();
|
|
|
|
if (v17) {
|
|
if (v16) {
|
|
float v6 = v15;
|
|
|
|
if (v15 > 1.0) {
|
|
usleep(1000);
|
|
v6 = v15 - 1.0;
|
|
}
|
|
|
|
CGDisplayFade(v17, v6, 1.0, 0, 0, 0, 0, 0);
|
|
}
|
|
|
|
CGReleaseDisplayFadeReservation(v17);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void GLContext::Swap() {
|
|
[this->m_Context->context flushBuffer];
|
|
}
|
|
|
|
void GLContext::Update() {
|
|
[this->m_Context->context update];
|
|
}
|