Skip to content

Commit

Permalink
- added support for softpoly backend on macOS
Browse files Browse the repository at this point in the history
Grabbed most of code from old Cocoa backend with separate code path for software rendering
  • Loading branch information
alexey-lysiuk committed Dec 7, 2019
1 parent 75248cf commit e458713
Showing 1 changed file with 112 additions and 14 deletions.
126 changes: 112 additions & 14 deletions src/posix/cocoa/i_video.mm
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@

#include "gl/system/gl_framebuffer.h"
#include "vulkan/system/vk_framebuffer.h"
#include "rendering/polyrenderer/backend/poly_framebuffer.h"


@implementation NSWindow(ExitAppOnClose)
Expand Down Expand Up @@ -293,7 +294,13 @@ -(BOOL) isOpaque
return window;
}

NSOpenGLPixelFormat* CreatePixelFormat()
enum class OpenGLProfile
{
Core,
Legacy
};

NSOpenGLPixelFormat* CreatePixelFormat(const OpenGLProfile profile)
{
NSOpenGLPixelFormatAttribute attributes[16];
size_t i = 0;
Expand All @@ -305,22 +312,28 @@ -(BOOL) isOpaque
attributes[i++] = NSOpenGLPixelFormatAttribute(24);
attributes[i++] = NSOpenGLPFAStencilSize;
attributes[i++] = NSOpenGLPixelFormatAttribute(8);
attributes[i++] = NSOpenGLPFAOpenGLProfile;
attributes[i++] = NSOpenGLProfileVersion3_2Core;


if (profile == OpenGLProfile::Core)
{
attributes[i++] = NSOpenGLPFAOpenGLProfile;
attributes[i++] = NSOpenGLProfileVersion3_2Core;
}

if (!vid_autoswitch)
{
attributes[i++] = NSOpenGLPFAAllowOfflineRenderers;
}

attributes[i] = NSOpenGLPixelFormatAttribute(0);

assert(i < sizeof attributes / sizeof attributes[0]);

return [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
}

void SetupOpenGLView(CocoaWindow* window)
void SetupOpenGLView(CocoaWindow* const window, const OpenGLProfile profile)
{
NSOpenGLPixelFormat* pixelFormat = CreatePixelFormat();
NSOpenGLPixelFormat* pixelFormat = CreatePixelFormat(profile);

if (nil == pixelFormat)
{
Expand Down Expand Up @@ -364,13 +377,12 @@ void SetupOpenGLView(CocoaWindow* window)
assert(ms_window == nil);
ms_window = CreateWindow(STYLE_MASK_WINDOWED);

const NSRect contentRect = [ms_window contentRectForFrameRect:[ms_window frame]];
SystemBaseFrameBuffer *fb = nullptr;

#ifdef HAVE_VULKAN
if (ms_isVulkanEnabled)
{
const NSRect contentRect = [ms_window contentRectForFrameRect:[ms_window frame]];

NSView* vulkanView = [[VulkanCocoaView alloc] initWithFrame:contentRect];
vulkanView.wantsLayer = YES;
vulkanView.layer.backgroundColor = NSColor.blackColor.CGColor;
Expand Down Expand Up @@ -417,13 +429,20 @@ void SetupOpenGLView(CocoaWindow* window)
{
ms_isVulkanEnabled = false;

SetupOpenGLView(ms_window);
SetupOpenGLView(ms_window, OpenGLProfile::Core);
}
}
else
#endif
if (vid_preferbackend == 2)
{
SetupOpenGLView(ms_window);
SetupOpenGLView(ms_window, OpenGLProfile::Legacy);

fb = new PolyFrameBuffer(nullptr, fullscreen);
}
else
{
SetupOpenGLView(ms_window, OpenGLProfile::Core);
}

if (fb == nullptr)
Expand Down Expand Up @@ -603,9 +622,17 @@ void SetupOpenGLView(CocoaWindow* window)

void SystemBaseFrameBuffer::SetMode(const bool fullscreen, const bool hiDPI)
{
assert(m_window.screen != nil);
assert(m_window.contentView.layer != nil);
[m_window.contentView layer].contentsScale = hiDPI ? m_window.screen.backingScaleFactor : 1.0;
if ([m_window.contentView isKindOfClass:[OpenGLCocoaView class]])
{
NSOpenGLView* const glView = [m_window contentView];
[glView setWantsBestResolutionOpenGLSurface:hiDPI];
}
else
{
assert(m_window.screen != nil);
assert(m_window.contentView.layer != nil);
[m_window.contentView layer].contentsScale = hiDPI ? m_window.screen.backingScaleFactor : 1.0;
}

if (fullscreen)
{
Expand Down Expand Up @@ -956,19 +983,90 @@ bool I_CreateVulkanSurface(VkInstance instance, VkSurfaceKHR *surface)
}
#endif


namespace
{
TArray<uint8_t> polyPixelBuffer;
GLuint polyTexture;

int polyWidth = -1;
int polyHeight = -1;
int polyVSync = -1;
}

void I_PolyPresentInit()
{
ogl_LoadFunctions();

glGenTextures(1, &polyTexture);
assert(polyTexture != 0);

glEnable(GL_TEXTURE_RECTANGLE_ARB);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, polyTexture);

glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}

uint8_t *I_PolyPresentLock(int w, int h, bool vsync, int &pitch)
{
return nullptr;
static const int PIXEL_BYTES = 4;

if (polyPixelBuffer.Size() == 0 || w != polyWidth || h != polyHeight)
{
polyPixelBuffer.Resize(w * h * PIXEL_BYTES);

polyWidth = w;
polyHeight = h;

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, w, h, 0.0, -1.0, 1.0);

glViewport(0, 0, w, h);
}

if (vsync != polyVSync)
{
const GLint value = vsync ? 1 : 0;

[[NSOpenGLContext currentContext] setValues:&value
forParameter:NSOpenGLCPSwapInterval];
}

pitch = w * PIXEL_BYTES;

return &polyPixelBuffer[0];
}

void I_PolyPresentUnlock(int x, int y, int w, int h)
{
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, &polyPixelBuffer[0]);

glBegin(GL_QUADS);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(0.0f, 0.0f);
glTexCoord2f(w, 0.0f);
glVertex2f(w, 0.0f);
glTexCoord2f(w, h);
glVertex2f(w, h);
glTexCoord2f(0.0f, h);
glVertex2f(0.0f, h);
glEnd();

glFlush();

[[NSOpenGLContext currentContext] flushBuffer];
}

void I_PolyPresentDeinit()
{
glBindTexture(GL_TEXTURE_2D, 0);
glDeleteTextures(1, &polyTexture);
}

0 comments on commit e458713

Please sign in to comment.