glwindow: pass display to implementation's _new()
[platform/upstream/gstreamer.git] / gst-libs / gst / gl / eagl / gstglwindow_eagl.m
1 /*
2  * GStreamer
3  * Copyright (C) 2014 Sebastian Dröge <sebastian@centricular.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it un der the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #import <OpenGLES/EAGL.h>
26 #import <QuartzCore/QuartzCore.h>
27 #import <UIKit/UIKit.h>
28
29 #include "gstglwindow_eagl.h"
30 #include "gstglcontext_eagl.h"
31
32 #define GST_GL_WINDOW_EAGL_GET_PRIVATE(o)  \
33   (G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_WINDOW_EAGL, GstGLWindowEaglPrivate))
34
35 #define GST_CAT_DEFAULT gst_gl_window_eagl_debug
36 GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
37
38 #define DEBUG_INIT \
39   GST_DEBUG_CATEGORY_GET (GST_CAT_DEFAULT, "glwindow");
40 #define gst_gl_window_eagl_parent_class parent_class
41 G_DEFINE_TYPE_WITH_CODE (GstGLWindowEagl, gst_gl_window_eagl,
42     GST_GL_TYPE_WINDOW, DEBUG_INIT);
43
44 static guintptr gst_gl_window_eagl_get_display (GstGLWindow * window);
45 static guintptr gst_gl_window_eagl_get_window_handle (GstGLWindow * window);
46 static void gst_gl_window_eagl_set_window_handle (GstGLWindow * window,
47     guintptr handle);
48 static void gst_gl_window_eagl_set_preferred_size (GstGLWindow * window,
49     gint width, gint height);
50 static void gst_gl_window_eagl_draw (GstGLWindow * window);
51
52 struct _GstGLWindowEaglPrivate
53 {
54   UIView *view;
55   gint window_width, window_height;
56   gint preferred_width, preferred_height;
57 };
58
59 static void
60 gst_gl_window_eagl_class_init (GstGLWindowEaglClass * klass)
61 {
62   GstGLWindowClass *window_class = (GstGLWindowClass *) klass;
63
64   g_type_class_add_private (klass, sizeof (GstGLWindowEaglPrivate));
65
66   window_class->get_display =
67       GST_DEBUG_FUNCPTR (gst_gl_window_eagl_get_display);
68   window_class->get_window_handle =
69       GST_DEBUG_FUNCPTR (gst_gl_window_eagl_get_window_handle);
70   window_class->set_window_handle =
71       GST_DEBUG_FUNCPTR (gst_gl_window_eagl_set_window_handle);
72   window_class->draw_unlocked = GST_DEBUG_FUNCPTR (gst_gl_window_eagl_draw);
73   window_class->draw = GST_DEBUG_FUNCPTR (gst_gl_window_eagl_draw);
74   window_class->set_preferred_size =
75       GST_DEBUG_FUNCPTR (gst_gl_window_eagl_set_preferred_size);
76 }
77
78 static void
79 gst_gl_window_eagl_init (GstGLWindowEagl * window)
80 {
81   window->priv = GST_GL_WINDOW_EAGL_GET_PRIVATE (window);
82
83 }
84
85 /* Must be called in the gl thread */
86 GstGLWindowEagl *
87 gst_gl_window_eagl_new (GstGLDisplay * display)
88 {
89   /* there isn't an eagl display type */
90   return g_object_new (GST_GL_TYPE_WINDOW_EAGL, NULL);
91 }
92
93 static guintptr
94 gst_gl_window_eagl_get_display (GstGLWindow * window)
95 {
96   return 0;
97 }
98
99 static guintptr
100 gst_gl_window_eagl_get_window_handle (GstGLWindow * window)
101 {
102   return (guintptr) GST_GL_WINDOW_EAGL (window)->priv->view;
103 }
104
105 static void
106 gst_gl_window_eagl_set_window_handle (GstGLWindow * window, guintptr handle)
107 {
108   GstGLWindowEagl *window_eagl;
109   GstGLContext *context;
110
111   window_eagl = GST_GL_WINDOW_EAGL (window);
112   context = gst_gl_window_get_context (window);
113
114   window_eagl->priv->view = (UIView *) handle;
115   GST_INFO_OBJECT (context, "handle set, updating layer");
116   gst_gl_context_eagl_update_layer (context);
117 }
118
119 static void
120 gst_gl_window_eagl_set_preferred_size (GstGLWindow * window, gint width, gint height)
121 {
122   GstGLWindowEagl *window_eagl = GST_GL_WINDOW_EAGL (window);
123
124   window_eagl->priv->preferred_width = width;
125   window_eagl->priv->preferred_height = height;
126 }
127
128 static void
129 draw_cb (gpointer data)
130 {
131   GstGLWindowEagl *window_eagl = data;
132   GstGLWindow *window = GST_GL_WINDOW (window_eagl);
133   GstGLContext *context = gst_gl_window_get_context (window);
134   GstGLContextEagl *eagl_context = GST_GL_CONTEXT_EAGL (context);
135   GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context);
136
137   if (window_eagl->priv->view) {
138     CGSize size;
139     CAEAGLLayer *eagl_layer;
140
141     eagl_layer = (CAEAGLLayer *)[window_eagl->priv->view layer];
142     size = eagl_layer.frame.size;
143
144     if (window_eagl->priv->window_width != size.width ||
145         window_eagl->priv->window_height != size.height) {
146
147       window_eagl->priv->window_width = size.width;
148       window_eagl->priv->window_height = size.height;
149
150       gst_gl_context_eagl_resize (eagl_context);
151
152       if (window->resize)
153         window->resize (window->resize_data, window_eagl->priv->window_width,
154             window_eagl->priv->window_height);
155     }
156   }
157
158   gst_gl_context_eagl_prepare_draw (eagl_context);
159
160   if (window->draw)
161     window->draw (window->draw_data);
162
163   context_class->swap_buffers (context);
164
165   gst_gl_context_eagl_finish_draw (eagl_context);
166
167   gst_object_unref (context);
168 }
169
170 static void
171 gst_gl_window_eagl_draw (GstGLWindow * window)
172 {
173   gst_gl_window_send_message (window, (GstGLWindowCB) draw_cb, window);
174 }