summaryrefslogtreecommitdiff
path: root/Sources/Compositor/OwlIOSurfaceBuffer.m
diff options
context:
space:
mode:
Diffstat (limited to 'Sources/Compositor/OwlIOSurfaceBuffer.m')
-rw-r--r--Sources/Compositor/OwlIOSurfaceBuffer.m140
1 files changed, 140 insertions, 0 deletions
diff --git a/Sources/Compositor/OwlIOSurfaceBuffer.m b/Sources/Compositor/OwlIOSurfaceBuffer.m
new file mode 100644
index 0000000..eb25021
--- /dev/null
+++ b/Sources/Compositor/OwlIOSurfaceBuffer.m
@@ -0,0 +1,140 @@
+/* This file is part of Owl.
+ *
+ * Copyright © 2019-2021 Sergey Bugaev <bugaevc@gmail.com>
+ *
+ * Owl is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Owl is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Owl. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#import "OwlFeatures.h"
+#ifdef OWL_PLATFORM_APPLE
+
+#import "OwlIOSurfaceBuffer.h"
+#import <OpenGL/gl.h>
+#import <OpenGL/CGLIOSurface.h>
+
+
+@implementation OwlIOSurfaceBuffer
+
+- (id) initWithResource: (struct wl_resource *) resource
+ surfacePort: (mach_port_t) surfacePort
+{
+ self = [super initWithResource: resource];
+ _surface = IOSurfaceLookupFromMachPort(surfacePort);
+ return self;
+}
+
+- (void) dealloc {
+ IOSurfaceDecrementUseCount(_surface);
+ [super dealloc];
+}
+
+- (void) invalidate {
+ // ???
+}
+
+- (NSSize) size {
+ size_t width = IOSurfaceGetWidth(_surface);
+ size_t height = IOSurfaceGetHeight(_surface);
+ return NSMakeSize(width, height);
+}
+
+- (BOOL) needsGLForRendering {
+ return YES;
+}
+
+- (void) setupTextureWithCGLContext: (CGLContextObj) context {
+ glGenTextures(1, &_tex);
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _tex);
+
+ size_t width = IOSurfaceGetWidth(_surface);
+ size_t height = IOSurfaceGetHeight(_surface);
+
+ CGLTexImageIOSurface2D(
+ context,
+ GL_TEXTURE_RECTANGLE_ARB, // target
+ GL_RGBA, // internal_format
+ width,
+ height,
+ GL_BGRA, // format
+ GL_UNSIGNED_INT_8_8_8_8_REV, // type
+ _surface,
+ 0 // plane
+ );
+
+ glTexParameteri(
+ GL_TEXTURE_RECTANGLE_ARB,
+ GL_TEXTURE_MIN_FILTER,
+ GL_LINEAR
+ );
+ glTexParameteri(
+ GL_TEXTURE_RECTANGLE_ARB,
+ GL_TEXTURE_MAG_FILTER,
+ GL_LINEAR
+ );
+ 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
+ );
+}
+
+- (void) drawInRect: (NSRect) rect {
+ glViewport(0, 0, rect.size.width, rect.size.height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, rect.size.width, 0, rect.size.height, -1, 1);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ struct {
+ GLfloat x, y;
+ } coord[4] = {
+ {0, 0},
+ {rect.size.width, 0},
+ {0, rect.size.height},
+ {rect.size.width, rect.size.height}
+ };
+
+ glEnable(GL_TEXTURE_RECTANGLE_ARB);
+
+ NSOpenGLContext *currentContext = [NSOpenGLContext currentContext];
+ [self setupTextureWithCGLContext: [currentContext CGLContextObj]];
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ glPushMatrix();
+ glTexCoordPointer(2, GL_FLOAT, 0, coord);
+ glVertexPointer(2, GL_FLOAT, 0, coord);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ glPopMatrix();
+
+ glFlush();
+}
+
+- (void) notifyDetached {
+ [self sendRelease];
+}
+
+@end
+
+#endif /* OWL_PLATFORM_APPLE */