mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
eagl: fix handling of surface dimension changes
Detect when the eagl surface changed its dimension (when the user rotates the device for example) and adapt the egl internals to draw to that, preventing that ios resizes the image again when drawing. This is particularly harmful when eagl would scale down a image to draw and the ios screen would scale it back up because the surface is now bigger than when the element was configured.
This commit is contained in:
parent
27d726fbfa
commit
ef66e39d03
2 changed files with 49 additions and 20 deletions
|
@ -56,11 +56,15 @@ struct _GstEaglContext
|
|||
EAGLContext *eagl_context;
|
||||
GLuint framebuffer;
|
||||
GLuint color_renderbuffer;
|
||||
GLuint depth_renderbuffer;
|
||||
|
||||
UIView *window;
|
||||
UIView *used_window;
|
||||
};
|
||||
|
||||
static gboolean
|
||||
gst_egl_adaptation_update_surface (GstEglAdaptationContext * ctx);
|
||||
|
||||
void
|
||||
gst_egl_adaptation_init (GstEglAdaptationContext * ctx)
|
||||
{
|
||||
|
@ -179,8 +183,13 @@ gst_egl_adaptation_create_surface (GstEglAdaptationContext * ctx)
|
|||
__block CAEAGLLayer *eaglLayer = (CAEAGLLayer *)[ctx->eaglctx->window layer];
|
||||
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
/* Allocate framebuffer */
|
||||
glGenFramebuffers(1, &framebuffer);
|
||||
|
||||
if (ctx->eaglctx->framebuffer) {
|
||||
framebuffer = ctx->eaglctx->framebuffer;
|
||||
} else {
|
||||
/* Allocate framebuffer */
|
||||
glGenFramebuffers(1, &framebuffer);
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||
|
||||
/* Allocate color render buffer */
|
||||
|
@ -212,6 +221,9 @@ gst_egl_adaptation_create_surface (GstEglAdaptationContext * ctx)
|
|||
|
||||
ctx->eaglctx->framebuffer = framebuffer;
|
||||
ctx->eaglctx->color_renderbuffer = colorRenderbuffer;
|
||||
ctx->eaglctx->depth_renderbuffer = colorRenderbuffer;
|
||||
ctx->surface_width = width;
|
||||
ctx->surface_height = height;
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, ctx->eaglctx->color_renderbuffer);
|
||||
|
||||
return TRUE;
|
||||
|
@ -260,18 +272,18 @@ gboolean
|
|||
gst_egl_adaptation_update_surface_dimensions (GstEglAdaptationContext *
|
||||
ctx)
|
||||
{
|
||||
GLint width;
|
||||
GLint height;
|
||||
CAEAGLLayer *layer = (CAEAGLLayer *)[ctx->eaglctx->window layer];
|
||||
CGSize size = layer.frame.size;
|
||||
|
||||
/* Get renderbuffer width/height */
|
||||
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width);
|
||||
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height);
|
||||
|
||||
if (width != ctx->surface_width || height != ctx->surface_height) {
|
||||
ctx->surface_width = width;
|
||||
ctx->surface_height = height;
|
||||
GST_INFO_OBJECT (ctx->element, "Got surface of %dx%d pixels", width,
|
||||
height);
|
||||
if (size.width != ctx->surface_width || size.height != ctx->surface_height) {
|
||||
ctx->surface_width = size.width;
|
||||
ctx->surface_height = size.height;
|
||||
GST_INFO_OBJECT (ctx->element, "Got surface of %dx%d pixels",
|
||||
(gint) size.width, (gint) size.height);
|
||||
if (!gst_egl_adaptation_update_surface (ctx)) {
|
||||
GST_WARNING_OBJECT (ctx->element, "Failed to update surface "
|
||||
"to new dimensions");
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -302,6 +314,23 @@ gst_egl_adaptation_destroy_surface (GstEglAdaptationContext * ctx)
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_egl_adaptation_update_surface (GstEglAdaptationContext * ctx)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, ctx->eaglctx->framebuffer);
|
||||
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
|
||||
GL_RENDERBUFFER, 0);
|
||||
glDeleteRenderbuffers(1, &ctx->eaglctx->depth_renderbuffer);
|
||||
|
||||
glBindRenderbuffer (GL_RENDERBUFFER, 0);
|
||||
glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||
GL_RENDERBUFFER, 0);
|
||||
glDeleteRenderbuffers(1, &ctx->eaglctx->color_renderbuffer);
|
||||
|
||||
return gst_egl_adaptation_create_surface (ctx);
|
||||
}
|
||||
|
||||
void
|
||||
gst_egl_adaptation_destroy_context (GstEglAdaptationContext * ctx)
|
||||
{
|
||||
|
|
|
@ -204,8 +204,7 @@ static void gst_eglglessink_set_render_rectangle (GstVideoOverlay * overlay,
|
|||
/* Utility */
|
||||
static gboolean gst_eglglessink_create_window (GstEglGlesSink *
|
||||
eglglessink, gint width, gint height);
|
||||
static gboolean gst_eglglessink_setup_vbo (GstEglGlesSink * eglglessink,
|
||||
gboolean reset);
|
||||
static gboolean gst_eglglessink_setup_vbo (GstEglGlesSink * eglglessink);
|
||||
static gboolean
|
||||
gst_eglglessink_configure_caps (GstEglGlesSink * eglglessink, GstCaps * caps);
|
||||
static GstFlowReturn gst_eglglessink_upload (GstEglGlesSink * sink,
|
||||
|
@ -740,17 +739,17 @@ gst_eglglessink_expose (GstVideoOverlay * overlay)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_eglglessink_setup_vbo (GstEglGlesSink * eglglessink, gboolean reset)
|
||||
gst_eglglessink_setup_vbo (GstEglGlesSink * eglglessink)
|
||||
{
|
||||
gdouble render_width, render_height;
|
||||
gdouble texture_width, texture_height;
|
||||
gdouble x1, x2, y1, y2;
|
||||
gdouble tx1, tx2, ty1, ty2;
|
||||
|
||||
GST_INFO_OBJECT (eglglessink, "VBO setup. have_vbo:%d, should reset %d",
|
||||
eglglessink->egl_context->have_vbo, reset);
|
||||
GST_INFO_OBJECT (eglglessink, "VBO setup. have_vbo:%d",
|
||||
eglglessink->egl_context->have_vbo);
|
||||
|
||||
if (eglglessink->egl_context->have_vbo && reset) {
|
||||
if (eglglessink->egl_context->have_vbo) {
|
||||
glDeleteBuffers (1, &eglglessink->egl_context->position_buffer);
|
||||
glDeleteBuffers (1, &eglglessink->egl_context->index_buffer);
|
||||
eglglessink->egl_context->have_vbo = FALSE;
|
||||
|
@ -929,6 +928,7 @@ gst_eglglessink_setup_vbo (GstEglGlesSink * eglglessink, gboolean reset)
|
|||
goto HANDLE_ERROR_LOCKED;
|
||||
|
||||
eglglessink->egl_context->have_vbo = TRUE;
|
||||
|
||||
GST_DEBUG_OBJECT (eglglessink, "VBO setup done");
|
||||
|
||||
return TRUE;
|
||||
|
@ -1673,7 +1673,7 @@ gst_eglglessink_render (GstEglGlesSink * eglglessink)
|
|||
glClear (GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
if (!gst_eglglessink_setup_vbo (eglglessink, FALSE)) {
|
||||
if (!gst_eglglessink_setup_vbo (eglglessink)) {
|
||||
GST_OBJECT_UNLOCK (eglglessink);
|
||||
GST_ERROR_OBJECT (eglglessink, "VBO setup failed");
|
||||
goto HANDLE_ERROR;
|
||||
|
|
Loading…
Reference in a new issue