[gtk/wip/chergert/macos-iosurface] start porting to GL with IOSurface
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/macos-iosurface] start porting to GL with IOSurface
- Date: Fri, 11 Feb 2022 02:53:20 +0000 (UTC)
commit b00b83f230ef7e102abdb30a7b3c3684bc9cb6be
Author: Christian Hergert <christian hergert me>
Date: Thu Feb 10 18:51:58 2022 -0800
start porting to GL with IOSurface
stuff stil doesn't work, however, still need to figure out the process
for GL_TEXTURE_RECTANGLE_ARB and how to make that work
with newer GL, even if only when rendering to it as a FBO.
gdk/macos/GdkMacosGLView.c | 125 --------
gdk/macos/GdkMacosGLView.h | 41 ---
gdk/macos/GdkMacosWindow.c | 4 +-
gdk/macos/gdkmacosglcontext-private.h | 17 +-
gdk/macos/gdkmacosglcontext.c | 575 +++++++++++++++++++---------------
gdk/macos/meson.build | 2 -
6 files changed, 338 insertions(+), 426 deletions(-)
---
diff --git a/gdk/macos/GdkMacosWindow.c b/gdk/macos/GdkMacosWindow.c
index 9ed2147ed8..8401f45860 100644
--- a/gdk/macos/GdkMacosWindow.c
+++ b/gdk/macos/GdkMacosWindow.c
@@ -24,7 +24,6 @@
#include <gdk/gdk.h>
#import "GdkMacosBaseView.h"
-#import "GdkMacosGLView.h"
#import "GdkMacosView.h"
#import "GdkMacosWindow.h"
@@ -150,8 +149,7 @@ typedef NSString *CALayerContentsGravity;
_gdk_macos_display_break_all_grabs (GDK_MACOS_DISPLAY (display), time);
/* Reset gravity */
- if (GDK_IS_MACOS_GL_VIEW ([self contentView]))
- [[[self contentView] layer] setContentsGravity:kCAGravityBottomLeft];
+ [[[self contentView] layer] setContentsGravity:kCAGravityBottomLeft];
break;
}
diff --git a/gdk/macos/gdkmacosglcontext-private.h b/gdk/macos/gdkmacosglcontext-private.h
index 781035677a..9d9b378b16 100644
--- a/gdk/macos/gdkmacosglcontext-private.h
+++ b/gdk/macos/gdkmacosglcontext-private.h
@@ -29,7 +29,7 @@
#include "gdkmacossurface.h"
#import <OpenGL/OpenGL.h>
-#import <OpenGL/gl.h>
+#import <OpenGL/gl3.h>
#import <AppKit/AppKit.h>
G_BEGIN_DECLS
@@ -38,17 +38,15 @@ struct _GdkMacosGLContext
{
GdkGLContext parent_instance;
+ cairo_region_t *damage;
+
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
- NSOpenGLContext *gl_context;
+ CGLContextObj cgl_context;
G_GNUC_END_IGNORE_DEPRECATIONS
- NSWindow *dummy_window;
- NSView *dummy_view;
-
- cairo_region_t *damage;
-
- guint is_attached : 1;
- guint needs_resize : 1;
+ GLuint texture;
+ GLuint target;
+ GLuint fbo;
};
struct _GdkMacosGLContextClass
@@ -56,7 +54,6 @@ struct _GdkMacosGLContextClass
GdkGLContextClass parent_class;
};
-
G_END_DECLS
#endif /* __GDK_MACOS_GL_CONTEXT_PRIVATE_H__ */
diff --git a/gdk/macos/gdkmacosglcontext.c b/gdk/macos/gdkmacosglcontext.c
index 1800815786..0686ae048c 100644
--- a/gdk/macos/gdkmacosglcontext.c
+++ b/gdk/macos/gdkmacosglcontext.c
@@ -25,14 +25,108 @@
#include "gdkintl.h"
-#include <OpenGL/gl.h>
+#include <OpenGL/gl3.h>
+#include <OpenGL/glext.h>
+#include <OpenGL/CGLIOSurface.h>
-#import "GdkMacosGLView.h"
+#include "gdkmacosbuffer-private.h"
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
G_DEFINE_TYPE (GdkMacosGLContext, gdk_macos_gl_context, GDK_TYPE_GL_CONTEXT)
+static inline gboolean
+_CHECK (GError **error,
+ const char *location,
+ CGLError cgl_error)
+{
+ if (cgl_error != kCGLNoError)
+ {
+ g_log ("Core OpenGL",
+ G_LOG_LEVEL_CRITICAL,
+ "%s: %s",
+ location, CGLErrorString (cgl_error));
+ g_set_error (error,
+ GDK_GL_ERROR,
+ GDK_GL_ERROR_NOT_AVAILABLE,
+ "%s",
+ CGLErrorString (cgl_error));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static inline gboolean
+_CHECK_GL (GError **error,
+ const char *location,
+ GLenum gl_error)
+{
+ const char *msg;
+
+ switch (gl_error)
+ {
+ case GL_INVALID_ENUM:
+ msg = "invalid enum";
+ break;
+ case GL_INVALID_VALUE:
+ msg = "invalid value";
+ break;
+ case GL_INVALID_OPERATION:
+ msg = "invalid operation";
+ break;
+ case GL_INVALID_FRAMEBUFFER_OPERATION:
+ msg = "invalid framebuffer operation";
+ break;
+ case GL_OUT_OF_MEMORY:
+ msg = "out of memory";
+ break;
+ default:
+ msg = "unknown error";
+ break;
+ }
+
+ if (gl_error != GL_NO_ERROR)
+ {
+ g_log ("OpenGL",
+ G_LOG_LEVEL_CRITICAL,
+ "%s: %s", location, msg);
+ g_set_error (error,
+ GDK_GL_ERROR,
+ GDK_GL_ERROR_NOT_AVAILABLE,
+ "%s", msg);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+#define CHECK(error,cgl_error) _CHECK(error, G_STRLOC, cgl_error)
+#define CHECK_GL(error,func) _CHECK_GL(error, G_STRLOC, ({ func; glGetError(); }))
+
+static inline gboolean
+is_opaque_surface (GdkMacosGLContext *self)
+{
+ GdkSurface *surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self));
+ cairo_region_t *region = GDK_MACOS_SURFACE (surface)->opaque_region;
+
+ if (region != NULL && cairo_region_num_rectangles (region) == 1)
+ {
+ cairo_rectangle_int_t extents;
+
+ cairo_region_get_extents (region, &extents);
+
+ if (extents.x == 0 &&
+ extents.y == 0 &&
+ extents.width == surface->width &&
+ extents.height == surface->height)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
static const char *
get_renderer_name (GLint id)
{
@@ -72,95 +166,166 @@ get_renderer_name (GLint id)
}
}
-static NSOpenGLContext *
-get_ns_open_gl_context (GdkMacosGLContext *self,
- GError **error)
+static GLuint
+create_texture (GLuint target)
{
- g_assert (GDK_IS_MACOS_GL_CONTEXT (self));
-
- if (self->gl_context == nil)
+ GLuint texture = 0;
+
+ if (!CHECK_GL (NULL, glGenTextures (1, &texture)) ||
+ !CHECK_GL (NULL, glBindTexture (target, texture)) ||
+ !CHECK_GL (NULL, glTexParameteri (target, GL_TEXTURE_BASE_LEVEL, 0)) ||
+ !CHECK_GL (NULL, glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_NEAREST)) ||
+ !CHECK_GL (NULL, glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_NEAREST)) ||
+ !CHECK_GL (NULL, glTexParameteri (target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)) ||
+ !CHECK_GL (NULL, glTexParameteri (target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE)) ||
+ !CHECK_GL (NULL, glTexParameteri (target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)))
{
- g_set_error_literal (error,
- GDK_GL_ERROR,
- GDK_GL_ERROR_NOT_AVAILABLE,
- "Cannot access NSOpenGLContext for surface");
- return NULL;
+ glDeleteTextures (1, &texture);
+ return 0;
}
- return self->gl_context;
+ return texture;
}
-static NSOpenGLPixelFormat *
-create_pixel_format (int major,
- int minor,
- GError **error)
+static void
+gdk_macos_gl_context_allocate (GdkMacosGLContext *self)
{
- NSOpenGLPixelFormatAttribute attrs[] = {
- NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersionLegacy,
- NSOpenGLPFAAccelerated,
- NSOpenGLPFADoubleBuffer,
- NSOpenGLPFABackingStore,
- NSOpenGLPFAColorSize, 24,
- NSOpenGLPFAAlphaSize, 8,
- 0
- };
+ GdkSurface *surface;
- if (major == 3 && minor == 2)
- attrs[1] = NSOpenGLProfileVersion3_2Core;
- else if (major == 4 && minor == 1)
- attrs[1] = NSOpenGLProfileVersion4_1Core;
+ g_assert (GDK_IS_MACOS_GL_CONTEXT (self));
+ g_assert (self->cgl_context != NULL);
- NSOpenGLPixelFormat *format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
+ if (!(surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self))))
+ return;
- if (format == NULL)
- g_set_error (error,
- GDK_GL_ERROR,
- GDK_GL_ERROR_NOT_AVAILABLE,
- "Failed to create pixel format");
+ if (self->texture == 0)
+ {
+ GdkMacosBuffer *buffer;
+ IOSurfaceRef io_surface;
+ guint width;
+ guint height;
+
+ buffer = _gdk_macos_surface_get_buffer (GDK_MACOS_SURFACE (surface));
+ io_surface = _gdk_macos_buffer_get_native (buffer);
+ width = _gdk_macos_buffer_get_width (buffer);
+ height = _gdk_macos_buffer_get_height (buffer);
+
+ self->texture = create_texture (self->target);
+ if (!CHECK_GL (NULL, glGenFramebuffers (1, &self->fbo)) ||
+ !CHECK_GL (NULL, glBindFramebuffer (GL_FRAMEBUFFER, self->fbo)) ||
+ !CHECK_GL (NULL, glBindTexture (self->target, self->texture)))
+ return;
+
+ if (!CHECK (NULL, CGLTexImageIOSurface2D (self->cgl_context,
+ self->target,
+ GL_RGBA,
+ width,
+ height,
+ GL_BGRA,
+ GL_UNSIGNED_INT_8_8_8_8_REV,
+ io_surface,
+ 0)))
+ return;
+ }
- return g_steal_pointer (&format);
+ glBindTexture (self->target, self->texture);
+ glBindFramebuffer (GL_FRAMEBUFFER, self->fbo);
+
+ if (!CHECK_GL (NULL, glFramebufferTexture2D (GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ self->target,
+ self->texture,
+ 0)))
+ return;
+
+ switch (glCheckFramebufferStatus (GL_FRAMEBUFFER))
+ {
+ case GL_FRAMEBUFFER_COMPLETE:
+ break;
+
+ case GL_FRAMEBUFFER_UNDEFINED:
+ g_critical ("Framebuffer is undefined");
+ break;
+
+ case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
+ g_critical ("Framebuffer has incomplete attachment");
+ break;
+
+ case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
+ g_critical ("Framebuffer has missing attachment");
+ break;
+
+ case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
+ g_critical ("Framebuffer has incomplete draw buffer");
+ break;
+
+ case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
+ g_critical ("Framebuffer has incomplete read buffer");
+ break;
+
+ case GL_FRAMEBUFFER_UNSUPPORTED:
+ g_critical ("Framebuffer is unsupported");
+ break;
+
+ case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
+ g_critical ("Framebuffer has incomplete multisample");
+ break;
+
+ default:
+ g_critical ("Framebuffer has unknown error");
+ break;
+ }
}
-static NSView *
-ensure_gl_view (GdkMacosGLContext *self)
+static void
+gdk_macos_gl_context_release (GdkMacosGLContext *self)
{
- GdkMacosSurface *surface;
- NSWindow *nswindow;
- NSView *nsview;
-
g_assert (GDK_IS_MACOS_GL_CONTEXT (self));
- surface = GDK_MACOS_SURFACE (gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self)));
- nsview = _gdk_macos_surface_get_view (surface);
- nswindow = _gdk_macos_surface_get_native (surface);
+ glBindTexture (self->target, 0);
- if G_UNLIKELY (!GDK_IS_MACOS_GL_VIEW (nsview))
+ if (self->fbo != 0)
{
- NSRect frame;
-
- frame = [[nswindow contentView] bounds];
- nsview = [[GdkMacosGLView alloc] initWithFrame:frame];
- [nsview setWantsBestResolutionOpenGLSurface:YES];
- [nsview setPostsFrameChangedNotifications: YES];
- [nsview setNeedsDisplay:YES];
- [nswindow setContentView:nsview];
- [nswindow makeFirstResponder:nsview];
- [nsview release];
-
- if (self->dummy_view != NULL)
- {
- NSView *dummy_view = g_steal_pointer (&self->dummy_view);
- [dummy_view release];
- }
+ glDeleteFramebuffers (1, &self->fbo);
+ self->fbo = 0;
+ }
- if (self->dummy_window != NULL)
- {
- NSWindow *dummy_window = g_steal_pointer (&self->dummy_window);
- [dummy_window release];
- }
+ if (self->texture != 0)
+ {
+ glDeleteTextures (1, &self->texture);
+ self->texture = 0;
}
+}
+
+static CGLPixelFormatObj
+create_pixel_format (int major,
+ int minor,
+ GError **error)
+{
+ CGLPixelFormatAttribute attrs[] = {
+ kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute)kCGLOGLPVersion_Legacy,
+ kCGLPFAAccelerated,
+ //kCGLPFAAllowOfflineRenderers,
+ //kCGLPFADoubleBuffer,
+ //kCGLPFABackingStore,
+ kCGLPFAColorSize, 24,
+ kCGLPFAAlphaSize, 8,
+ 0
+ };
+ CGLPixelFormatObj format = NULL;
+ GLint n_format = 1;
- return [nswindow contentView];
+ if (major == 3 && minor == 2)
+ attrs[1] = (CGLPixelFormatAttribute)kCGLOGLPVersion_GL3_Core;
+ else if (major == 4 && minor == 1)
+ attrs[1] = (CGLPixelFormatAttribute)kCGLOGLPVersion_GL4_Core;
+
+ g_print (">>> GL %d.%d\n", major, minor);
+
+ if (!CHECK (error, CGLChoosePixelFormat (attrs, &format, &n_format)))
+ return NULL;
+
+ return g_steal_pointer (&format);
}
static GdkGLAPI
@@ -170,26 +335,25 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
GdkMacosGLContext *self = (GdkMacosGLContext *)context;
GdkSurface *surface;
GdkDisplay *display;
- NSOpenGLContext *shared_gl_context = nil;
- NSOpenGLContext *gl_context;
- NSOpenGLPixelFormat *pixelFormat;
+ CGLPixelFormatObj pixelFormat;
+ CGLContextObj shared_gl_context = nil;
CGLContextObj cgl_context;
+ CGLContextObj existing;
GdkGLContext *shared;
- NSOpenGLContext *existing;
GLint sync_to_framerate = 1;
GLint validate = 0;
- GLint swapRect[4];
+ GLint renderer_id = 0;
int major, minor;
g_assert (GDK_IS_MACOS_GL_CONTEXT (self));
- if (self->gl_context != nil)
+ if (self->cgl_context != nil)
return GDK_GL_API_GL;
if (!gdk_gl_context_is_api_allowed (context, GDK_GL_API_GL, error))
return 0;
- existing = [NSOpenGLContext currentContext];
+ existing = CGLGetCurrentContext ();
gdk_gl_context_get_required_version (context, &major, &minor);
@@ -199,99 +363,59 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
if (shared != NULL)
{
- if (!(shared_gl_context = get_ns_open_gl_context (GDK_MACOS_GL_CONTEXT (shared), error)))
- return 0;
+ if (!(shared_gl_context = GDK_MACOS_GL_CONTEXT (shared)->cgl_context))
+ {
+ g_set_error_literal (error,
+ GDK_GL_ERROR,
+ GDK_GL_ERROR_NOT_AVAILABLE,
+ "Cannot access shared CGLContextObj");
+ return 0;
+ }
}
GDK_DISPLAY_NOTE (display,
OPENGL,
- g_message ("Creating NSOpenGLContext (version %d.%d)",
+ g_message ("Creating CGLContextObj (version %d.%d)",
major, minor));
if (!(pixelFormat = create_pixel_format (major, minor, error)))
return 0;
- gl_context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat
- shareContext:shared_gl_context];
-
- [pixelFormat release];
-
- if (gl_context == nil)
+ if (!CHECK (error, CGLCreateContext (pixelFormat, shared_gl_context, &cgl_context)))
{
- g_set_error_literal (error,
- GDK_GL_ERROR,
- GDK_GL_ERROR_NOT_AVAILABLE,
- "Failed to create NSOpenGLContext");
+ CGLReleasePixelFormat (pixelFormat);
return 0;
}
- cgl_context = [gl_context CGLContextObj];
+ CGLSetCurrentContext (cgl_context);
+ CGLReleasePixelFormat (pixelFormat);
- swapRect[0] = 0;
- swapRect[1] = 0;
- swapRect[2] = surface ? surface->width : 0;
- swapRect[3] = surface ? surface->height : 0;
-
- CGLSetParameter (cgl_context, kCGLCPSwapRectangle, swapRect);
- CGLSetParameter (cgl_context, kCGLCPSwapInterval, &sync_to_framerate);
-
- CGLEnable (cgl_context, kCGLCESwapRectangle);
if (validate)
- CGLEnable (cgl_context, kCGLCEStateValidation);
+ CHECK (NULL, CGLEnable (cgl_context, kCGLCEStateValidation));
- self->dummy_window = [[NSWindow alloc] initWithContentRect:NSZeroRect
- styleMask:0
- backing:NSBackingStoreBuffered
- defer:NO
- screen:nil];
- self->dummy_view = [[NSView alloc] initWithFrame:NSZeroRect];
- [self->dummy_window setContentView:self->dummy_view];
- [gl_context setView:self->dummy_view];
+ if (!CHECK (error, CGLSetParameter (cgl_context, kCGLCPSwapInterval, &sync_to_framerate)) ||
+ !CHECK (error, CGLGetParameter (cgl_context, kCGLCPCurrentRendererID, &renderer_id)))
+ {
+ CGLReleaseContext (cgl_context);
+ return 0;
+ }
- GLint renderer_id = 0;
- [gl_context getValues:&renderer_id forParameter:NSOpenGLContextParameterCurrentRendererID];
GDK_DISPLAY_NOTE (display,
OPENGL,
- g_message ("Created NSOpenGLContext[%p] using %s",
- gl_context,
+ g_message ("Created CGLContextObj@%p using %s",
+ cgl_context,
get_renderer_name (renderer_id)));
- self->gl_context = g_steal_pointer (&gl_context);
+ self->cgl_context = g_steal_pointer (&cgl_context);
+
+ gdk_macos_gl_context_allocate (self);
if (existing != NULL)
- [existing makeCurrentContext];
+ CGLSetCurrentContext (existing);
return GDK_GL_API_GL;
}
-static gboolean
-opaque_region_covers_surface (GdkMacosGLContext *self)
-{
- GdkSurface *surface;
- cairo_region_t *region;
-
- g_assert (GDK_IS_MACOS_GL_CONTEXT (self));
-
- surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self));
- region = GDK_MACOS_SURFACE (surface)->opaque_region;
-
- if (region != NULL &&
- cairo_region_num_rectangles (region) == 1)
- {
- cairo_rectangle_int_t extents;
-
- cairo_region_get_extents (region, &extents);
-
- if (extents.x == 0 &&
- extents.y == 0 &&
- extents.width == surface->width &&
- extents.height == surface->height)
- return TRUE;
- }
-
- return FALSE;
-}
-
static void
gdk_macos_gl_context_begin_frame (GdkDrawContext *context,
gboolean prefers_high_depth,
@@ -299,66 +423,32 @@ gdk_macos_gl_context_begin_frame (GdkDrawContext *context,
{
GdkMacosGLContext *self = (GdkMacosGLContext *)context;
GdkSurface *surface;
+ GLint opaque;
g_assert (GDK_IS_MACOS_GL_CONTEXT (self));
- surface = gdk_draw_context_get_surface (context);
+ g_print ("Begin frame\n");
+
+ gdk_gl_context_make_current (GDK_GL_CONTEXT (self));
g_clear_pointer (&self->damage, cairo_region_destroy);
self->damage = cairo_region_copy (painted);
- /* If begin frame is called, that means we are trying to draw to
- * the NSWindow using our view. That might be a GdkMacosCairoView
- * but we need it to be a GL view. Also, only in this case do we
- * want to replace our damage region for the next frame (to avoid
- * doing it multiple times).
- */
- ensure_gl_view (self);
-
- if (self->needs_resize)
- {
- CGLContextObj cgl_context = [self->gl_context CGLContextObj];
- GLint opaque;
-
- self->needs_resize = FALSE;
-
- if (self->dummy_view != NULL)
- {
- NSRect frame = NSMakeRect (0, 0, surface->width, surface->height);
-
- [self->dummy_window setFrame:frame display:NO];
- [self->dummy_view setFrame:frame];
- }
-
- /* Possibly update our opaque setting depending on a resize. We can
- * rely on getting a resize if decoarated is changed, so this reduces
- * how much we adjust the parameter.
- */
- if (GDK_IS_MACOS_TOPLEVEL_SURFACE (surface))
- opaque = GDK_MACOS_TOPLEVEL_SURFACE (surface)->decorated;
- else
- opaque = FALSE;
+ surface = gdk_draw_context_get_surface (context);
+ opaque = is_opaque_surface (self);
- /* If we are maximized, we might be able to make it opaque */
- if (opaque == FALSE)
- opaque = opaque_region_covers_surface (self);
+ /* If the whole surface is opaque, we can help CGL out a bit */
+ if (!CHECK (NULL, CGLSetParameter (self->cgl_context, kCGLCPSurfaceOpacity, &opaque)))
+ return;
- CGLSetParameter (cgl_context, kCGLCPSurfaceOpacity, &opaque);
+ gdk_macos_gl_context_allocate (self);
- [self->gl_context update];
- }
+ //if (!CHECK (NULL, CGLUpdateContext (self->cgl_context)))
+ //return;
GDK_DRAW_CONTEXT_CLASS (gdk_macos_gl_context_parent_class)->begin_frame (context, prefers_high_depth,
painted);
- if (!self->is_attached)
- {
- NSView *nsview = _gdk_macos_surface_get_view (GDK_MACOS_SURFACE (surface));
-
- g_assert (self->gl_context != NULL);
- g_assert (GDK_IS_MACOS_GL_VIEW (nsview));
-
- [(GdkMacosGLView *)nsview setOpenGLContext:self->gl_context];
- }
+ g_print ("Begin frame\n");
}
static void
@@ -366,32 +456,34 @@ gdk_macos_gl_context_end_frame (GdkDrawContext *context,
cairo_region_t *painted)
{
GdkMacosGLContext *self = GDK_MACOS_GL_CONTEXT (context);
+ GdkSurface *surface;
+ cairo_rectangle_int_t flush_rect;
+ GLint swapRect[4];
g_assert (GDK_IS_MACOS_GL_CONTEXT (self));
- g_assert (self->gl_context != nil);
+ g_assert (self->cgl_context != nil);
GDK_DRAW_CONTEXT_CLASS (gdk_macos_gl_context_parent_class)->end_frame (context, painted);
- if (!self->is_attached)
- {
- GdkSurface *surface = gdk_draw_context_get_surface (context);
- CGLContextObj glctx = [self->gl_context CGLContextObj];
- cairo_rectangle_int_t flush_rect;
- GLint swapRect[4];
-
- /* Coordinates are in display coordinates, where as flush_rect is
- * in GDK coordinates. Must flip Y to match display coordinates where
- * 0,0 is the bottom-left corner.
- */
- cairo_region_get_extents (painted, &flush_rect);
- swapRect[0] = flush_rect.x; /* left */
- swapRect[1] = surface->height - flush_rect.y; /* bottom */
- swapRect[2] = flush_rect.width; /* width */
- swapRect[3] = flush_rect.height; /* height */
- CGLSetParameter (glctx, kCGLCPSwapRectangle, swapRect);
-
- [self->gl_context flushBuffer];
- }
+ surface = gdk_draw_context_get_surface (context);
+
+ /* Coordinates are in display coordinates, where as flush_rect is
+ * in GDK coordinates. Must flip Y to match display coordinates where
+ * 0,0 is the bottom-left corner.
+ */
+ cairo_region_get_extents (painted, &flush_rect);
+ swapRect[0] = flush_rect.x; /* left */
+ swapRect[1] = surface->height - flush_rect.y; /* bottom */
+ swapRect[2] = flush_rect.width; /* width */
+ swapRect[3] = flush_rect.height; /* height */
+ CGLSetParameter (self->cgl_context, kCGLCPSwapRectangle, swapRect);
+ CGLEnable (self->cgl_context, kCGLCESwapRectangle);
+
+ glFlush ();
+
+ g_print ("End frame\n");
+
+ _gdk_macos_surface_swap_buffers (GDK_MACOS_SURFACE (surface), painted);
}
static void
@@ -401,7 +493,10 @@ gdk_macos_gl_context_surface_resized (GdkDrawContext *draw_context)
g_assert (GDK_IS_MACOS_GL_CONTEXT (self));
- self->needs_resize = TRUE;
+ gdk_gl_context_make_current (GDK_GL_CONTEXT (self));
+
+ gdk_macos_gl_context_release (self);
+ gdk_macos_gl_context_allocate (self);
g_clear_pointer (&self->damage, cairo_region_destroy);
}
@@ -410,22 +505,13 @@ static gboolean
gdk_macos_gl_context_clear_current (GdkGLContext *context)
{
GdkMacosGLContext *self = GDK_MACOS_GL_CONTEXT (context);
- NSOpenGLContext *current;
g_return_val_if_fail (GDK_IS_MACOS_GL_CONTEXT (self), FALSE);
- current = [NSOpenGLContext currentContext];
-
- if (self->gl_context == current)
+ if (self->cgl_context == CGLGetCurrentContext ())
{
- /* The OpenGL mac programming guide suggests that glFlush() is called
- * before switching current contexts to ensure that the drawing commands
- * are submitted.
- */
- if (current != NULL)
- glFlush ();
-
- [NSOpenGLContext clearCurrentContext];
+ glFlush ();
+ CGLSetCurrentContext (NULL);
}
return TRUE;
@@ -436,22 +522,26 @@ gdk_macos_gl_context_make_current (GdkGLContext *context,
gboolean surfaceless)
{
GdkMacosGLContext *self = GDK_MACOS_GL_CONTEXT (context);
- NSOpenGLContext *current;
+ CGLContextObj current;
g_return_val_if_fail (GDK_IS_MACOS_GL_CONTEXT (self), FALSE);
- current = [NSOpenGLContext currentContext];
+ current = CGLGetCurrentContext ();
- if (self->gl_context != current)
+ if (self->cgl_context != current)
{
/* The OpenGL mac programming guide suggests that glFlush() is called
* before switching current contexts to ensure that the drawing commands
* are submitted.
+ *
+ * TODO: investigate if we need this because we may switch contexts
+ * durring composition and only need it when returning to a
+ * previous context that uses the other context.
*/
if (current != NULL)
glFlush ();
- [self->gl_context makeCurrentContext];
+ CGLSetCurrentContext (self->cgl_context);
}
return TRUE;
@@ -475,27 +565,18 @@ gdk_macos_gl_context_dispose (GObject *gobject)
{
GdkMacosGLContext *self = GDK_MACOS_GL_CONTEXT (gobject);
- if (self->dummy_view != nil)
- {
- NSView *nsview = g_steal_pointer (&self->dummy_view);
- [nsview release];
- }
-
- if (self->dummy_window != nil)
- {
- NSWindow *nswindow = g_steal_pointer (&self->dummy_window);
- [nswindow release];
- }
+ self->texture = 0;
+ self->fbo = 0;
- if (self->gl_context != nil)
+ if (self->cgl_context != nil)
{
- NSOpenGLContext *gl_context = g_steal_pointer (&self->gl_context);
+ CGLContextObj cgl_context = g_steal_pointer (&self->cgl_context);
- if (gl_context == [NSOpenGLContext currentContext])
- [NSOpenGLContext clearCurrentContext];
+ if (cgl_context == CGLGetCurrentContext ())
+ CGLSetCurrentContext (NULL);
- [gl_context clearDrawable];
- [gl_context release];
+ CGLClearDrawable (cgl_context);
+ CGLDestroyContext (cgl_context);
}
g_clear_pointer (&self->damage, cairo_region_destroy);
@@ -527,6 +608,10 @@ gdk_macos_gl_context_class_init (GdkMacosGLContextClass *klass)
static void
gdk_macos_gl_context_init (GdkMacosGLContext *self)
{
+ /* We must use GL_TEXTURE_RECTANGLE_ARB to be able to bind an
+ * IOSurfaceRef to the GL texture/framebuffer.
+ */
+ self->target = GL_TEXTURE_RECTANGLE_ARB;
}
G_GNUC_END_IGNORE_DEPRECATIONS
diff --git a/gdk/macos/meson.build b/gdk/macos/meson.build
index f42914a9d0..86f20bd2ea 100644
--- a/gdk/macos/meson.build
+++ b/gdk/macos/meson.build
@@ -26,8 +26,6 @@ gdk_macos_sources = files([
'GdkMacosTile.c',
'GdkMacosView.c',
'GdkMacosWindow.c',
-
- 'GdkMacosGLView.c',
])
gdk_macos_public_headers = files([
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]