1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2011 RĂ©mi Denis-Courmont
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
28 #include <vlc_common.h>
29 #include <vlc_atomic.h>
30 #include <vlc_opengl.h>
32 #include <vlc_modules.h>
37 atomic_uint ref_count
;
41 * Creates an OpenGL context (and its underlying surface).
43 * @note In most cases, you should vlc_gl_MakeCurrent() afterward.
45 * @param wnd window to use as OpenGL surface
46 * @param flags OpenGL context type
47 * @param name module name (or NULL for auto)
48 * @return a new context, or NULL on failure
50 vlc_gl_t
*vlc_gl_Create(struct vout_window_t
*wnd
, unsigned flags
,
53 vlc_object_t
*parent
= (vlc_object_t
*)wnd
;
54 struct vlc_gl_priv_t
*glpriv
;
57 switch (flags
/*& VLC_OPENGL_API_MASK*/)
69 glpriv
= vlc_custom_create(parent
, sizeof (*glpriv
), "gl");
70 if (unlikely(glpriv
== NULL
))
73 glpriv
->gl
.surface
= wnd
;
74 glpriv
->gl
.module
= module_need(&glpriv
->gl
, type
, name
, true);
75 if (glpriv
->gl
.module
== NULL
)
77 vlc_object_release(&glpriv
->gl
);
80 atomic_init(&glpriv
->ref_count
, 1);
85 void vlc_gl_Hold(vlc_gl_t
*gl
)
87 struct vlc_gl_priv_t
*glpriv
= (struct vlc_gl_priv_t
*)gl
;
88 atomic_fetch_add(&glpriv
->ref_count
, 1);
91 void vlc_gl_Release(vlc_gl_t
*gl
)
93 struct vlc_gl_priv_t
*glpriv
= (struct vlc_gl_priv_t
*)gl
;
94 if (atomic_fetch_sub(&glpriv
->ref_count
, 1) != 1)
96 module_unneed(gl
, gl
->module
);
97 vlc_object_release(gl
);
100 #include <vlc_vout_window.h>
102 typedef struct vlc_gl_surface
109 static void vlc_gl_surface_ResizeNotify(vout_window_t
*surface
,
110 unsigned width
, unsigned height
)
112 vlc_gl_surface_t
*sys
= surface
->owner
.sys
;
114 msg_Dbg(surface
, "resized to %ux%u", width
, height
);
116 vlc_mutex_lock(&sys
->lock
);
118 sys
->height
= height
;
119 vlc_mutex_unlock(&sys
->lock
);
122 vlc_gl_t
*vlc_gl_surface_Create(vlc_object_t
*obj
,
123 const vout_window_cfg_t
*cfg
,
124 struct vout_window_t
**restrict wp
)
126 vlc_gl_surface_t
*sys
= malloc(sizeof (*sys
));
127 if (unlikely(sys
== NULL
))
130 sys
->width
= cfg
->width
;
131 sys
->height
= cfg
->height
;
132 vlc_mutex_init(&sys
->lock
);
134 vout_window_owner_t owner
= {
136 .resized
= vlc_gl_surface_ResizeNotify
,
139 vout_window_t
*surface
= vout_window_New(obj
, "$window", cfg
, &owner
);
145 /* TODO: support ES? */
146 vlc_gl_t
*gl
= vlc_gl_Create(surface
, VLC_OPENGL
, NULL
);
148 vout_window_Delete(surface
);
152 vlc_gl_Resize(gl
, cfg
->width
, cfg
->height
);
156 vlc_mutex_destroy(&sys
->lock
);
162 * Checks if the dimensions of the surface used by the OpenGL context have
163 * changed (since the previous call), and the OpenGL viewport should be
165 * \return true if at least one dimension has changed, false otherwise
166 * \warning This function is intrinsically race-prone.
167 * The dimensions can change asynchronously.
169 bool vlc_gl_surface_CheckSize(vlc_gl_t
*gl
, unsigned *restrict width
,
170 unsigned *restrict height
)
172 vout_window_t
*surface
= gl
->surface
;
173 vlc_gl_surface_t
*sys
= surface
->owner
.sys
;
176 vlc_mutex_lock(&sys
->lock
);
177 if (sys
->width
>= 0 && sys
->height
>= 0)
180 *height
= sys
->height
;
184 vlc_gl_Resize(gl
, *width
, *height
);
187 vlc_mutex_unlock(&sys
->lock
);
191 void vlc_gl_surface_Destroy(vlc_gl_t
*gl
)
193 vout_window_t
*surface
= gl
->surface
;
194 vlc_gl_surface_t
*sys
= surface
->owner
.sys
;
197 vout_window_Delete(surface
);
198 vlc_mutex_destroy(&sys
->lock
);