diff --git a/gst-libs/gst/gl/gstgldisplay.c b/gst-libs/gst/gl/gstgldisplay.c index ca605fd231..7a373f3444 100644 --- a/gst-libs/gst/gl/gstgldisplay.c +++ b/gst-libs/gst/gl/gstgldisplay.c @@ -62,7 +62,6 @@ void gst_gl_display_on_draw (void); void gst_gl_display_on_close (void); void gst_gl_display_glgen_texture (GstGLDisplay* display, GLuint* pTexture); void gst_gl_display_gldel_texture (GstGLDisplay* display, GLuint* pTexture); -GLhandleARB gst_gl_display_load_fragment_shader (gchar* textFProgram); void gst_gl_display_check_framebuffer_status (void); /* To not make gst_gl_display_thread_do_upload @@ -212,24 +211,24 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass) //action gen and del shader display->gen_text_shader = NULL; - display->gen_handle_shader = 0; - display->del_handle_shader = 0; + display->gen_shader = NULL; + display->del_shader = NULL; //fragement shader upload - display->GLSLProgram_YUY2 = 0; - display->GLSLProgram_UYVY = 0; - display->GLSLProgram_I420_YV12 = 0; - display->GLSLProgram_AYUV = 0; + display->shader_upload_YUY2 = NULL; + display->shader_upload_UYVY = NULL; + display->shader_upload_I420_YV12 = NULL; + display->shader_upload_AYUV = NULL; //fragement shader download - display->GLSLProgram_to_YUY2 = 0; - display->GLSLProgram_to_UYVY = 0; - display->GLSLProgram_to_I420_YV12 = 0; - display->GLSLProgram_to_AYUV = 0; + display->shader_download_YUY2 = NULL; + display->shader_download_UYVY = NULL; + display->shader_download_I420_YV12 = NULL; + display->shader_download_AYUV = NULL; //YUY2:r,g,a //UYVY:a,b,r - display->textFProgram_YUY2_UYVY = + display->text_shader_upload_YUY2_UYVY = "uniform sampler2DRect Ytex, UVtex;\n" "void main(void) {\n" " float fx, fy, y, u, v, r, g, b;\n" @@ -247,7 +246,7 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass) " gl_FragColor = vec4(r, g, b, 1.0);\n" "}\n"; - display->textFProgram_I420_YV12 = + display->text_shader_upload_I420_YV12 = "uniform sampler2DRect Ytex,Utex,Vtex;\n" "void main(void) {\n" " float r,g,b,y,u,v;\n" @@ -264,7 +263,7 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass) " gl_FragColor=vec4(r,g,b,1.0);\n" "}\n"; - display->textFProgram_AYUV = + display->text_shader_upload_AYUV = "uniform sampler2DRect tex;\n" "void main(void) {\n" " float r,g,b,y,u,v;\n" @@ -283,7 +282,7 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass) //YUY2:y2,u,y1,v //UYVY:v,y1,u,y2 - display->textFProgram_to_YUY2_UYVY = + display->text_shader_download_YUY2_UYVY = "uniform sampler2DRect tex;\n" "void main(void) {\n" " float fx,fy,r,g,b,r2,g2,b2,y1,y2,u,v;\n" @@ -306,7 +305,7 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass) " gl_FragColor=vec4(%s);\n" "}\n"; - display->textFProgram_to_I420_YV12 = + display->text_shader_download_I420_YV12 = "uniform sampler2DRect tex;\n" "uniform float w, h;\n" "void main(void) {\n" @@ -330,7 +329,7 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass) " gl_FragData[2] = vec4(v, 0.0, 0.0, 1.0);\n" "}\n"; - display->textFProgram_to_AYUV = + display->text_shader_download_AYUV = "uniform sampler2DRect tex;\n" "void main(void) {\n" " float r,g,b,y,u,v;\n" @@ -728,14 +727,46 @@ gst_gl_display_thread_destroy_context (GstGLDisplay *display) case GST_GL_DISPLAY_CONVERSION_GLSL: { glUseProgramObjectARB (0); - glDeleteObjectARB (display->GLSLProgram_YUY2); - glDeleteObjectARB (display->GLSLProgram_UYVY); - glDeleteObjectARB (display->GLSLProgram_I420_YV12); - glDeleteObjectARB (display->GLSLProgram_AYUV); - glDeleteObjectARB (display->GLSLProgram_to_YUY2); - glDeleteObjectARB (display->GLSLProgram_to_UYVY); - glDeleteObjectARB (display->GLSLProgram_to_I420_YV12); - glDeleteObjectARB (display->GLSLProgram_to_AYUV); + if (display->shader_upload_YUY2) + { + g_object_unref (G_OBJECT (display->shader_upload_YUY2)); + display->shader_upload_YUY2 = NULL; + } + if (display->shader_upload_UYVY) + { + g_object_unref (G_OBJECT (display->shader_upload_UYVY)); + display->shader_upload_UYVY = NULL; + } + if (display->shader_upload_I420_YV12) + { + g_object_unref (G_OBJECT (display->shader_upload_I420_YV12)); + display->shader_upload_I420_YV12 = NULL; + } + if (display->shader_upload_AYUV) + { + g_object_unref (G_OBJECT (display->shader_upload_AYUV)); + display->shader_upload_AYUV = NULL; + } + if (display->shader_download_YUY2) + { + g_object_unref (G_OBJECT (display->shader_download_YUY2)); + display->shader_download_YUY2 = NULL; + } + if (display->shader_download_UYVY) + { + g_object_unref (G_OBJECT (display->shader_download_UYVY)); + display->shader_download_UYVY = NULL; + } + if (display->shader_download_I420_YV12) + { + g_object_unref (G_OBJECT (display->shader_download_I420_YV12)); + display->shader_download_I420_YV12 = NULL; + } + if (display->shader_download_AYUV) + { + g_object_unref (G_OBJECT (display->shader_download_AYUV)); + display->shader_download_AYUV = NULL; + } } break; default: @@ -921,28 +952,58 @@ gst_gl_display_thread_init_upload (GstGLDisplay *display) { case GST_VIDEO_FORMAT_YUY2: { - gchar program[2048]; - sprintf (program, display->textFProgram_YUY2_UYVY, 'r', 'g', 'a'); - display->GLSLProgram_YUY2 = gst_gl_display_load_fragment_shader (program); + gchar text_shader_upload_YUY2[2048]; + sprintf (text_shader_upload_YUY2, display->text_shader_upload_YUY2_UYVY, 'r', 'g', 'a'); + + display->shader_upload_YUY2 = gst_gl_shader_new (); + if(!gst_gl_shader_compile_and_check (display->shader_upload_YUY2, + text_shader_upload_YUY2, GST_GL_SHADER_FRAGMENT_SOURCE)) + { + display->isAlive = FALSE; + g_object_unref (G_OBJECT (display->shader_upload_YUY2)); + display->shader_upload_YUY2 = NULL; + } } break; case GST_VIDEO_FORMAT_UYVY: { - gchar program[2048]; - sprintf (program, display->textFProgram_YUY2_UYVY, 'a', 'b', 'r'); - display->GLSLProgram_UYVY = gst_gl_display_load_fragment_shader (program); + gchar text_shader_upload_UYVY[2048]; + sprintf (text_shader_upload_UYVY, display->text_shader_upload_YUY2_UYVY, 'a', 'b', 'r'); + + display->shader_upload_UYVY = gst_gl_shader_new (); + if(!gst_gl_shader_compile_and_check (display->shader_upload_UYVY, + text_shader_upload_UYVY, GST_GL_SHADER_FRAGMENT_SOURCE)) + { + display->isAlive = FALSE; + g_object_unref (G_OBJECT (display->shader_upload_UYVY)); + display->shader_upload_UYVY = NULL; + } } break; case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_YV12: - display->GLSLProgram_I420_YV12 = gst_gl_display_load_fragment_shader (display->textFProgram_I420_YV12); + display->shader_upload_I420_YV12 = gst_gl_shader_new (); + if(!gst_gl_shader_compile_and_check (display->shader_upload_I420_YV12, + display->text_shader_upload_I420_YV12, GST_GL_SHADER_FRAGMENT_SOURCE)) + { + display->isAlive = FALSE; + g_object_unref (G_OBJECT (display->shader_upload_I420_YV12)); + display->shader_upload_I420_YV12 = NULL; + } break; case GST_VIDEO_FORMAT_AYUV: - display->GLSLProgram_AYUV = gst_gl_display_load_fragment_shader (display->textFProgram_AYUV); + display->shader_upload_AYUV = gst_gl_shader_new (); + if(!gst_gl_shader_compile_and_check (display->shader_upload_AYUV, + display->text_shader_upload_AYUV, GST_GL_SHADER_FRAGMENT_SOURCE)) + { + display->isAlive = FALSE; + g_object_unref (G_OBJECT (display->shader_upload_AYUV)); + display->shader_upload_AYUV = NULL; + } break; default: g_assert_not_reached (); - } + } } //check if YCBCR MESA is available else if (GLEW_MESA_ycbcr_texture) @@ -978,6 +1039,9 @@ gst_gl_display_thread_init_upload (GstGLDisplay *display) g_print ("Context %d, GLEW_ARB_imaging supported: yes\n", display->glutWinId); display->colorspace_conversion = GST_GL_DISPLAY_CONVERSION_MATRIX; + + //turn off the pipeline because we do not support it yet + display->isAlive = FALSE; } else { @@ -1164,24 +1228,54 @@ gst_gl_display_thread_init_download (GstGLDisplay *display) { case GST_VIDEO_FORMAT_YUY2: { - gchar program[2048]; - sprintf (program, display->textFProgram_to_YUY2_UYVY, "y2,u,y1,v"); - display->GLSLProgram_to_YUY2 = gst_gl_display_load_fragment_shader (program); + gchar text_shader_download_YUY2[2048]; + sprintf (text_shader_download_YUY2, display->text_shader_download_YUY2_UYVY, "y2,u,y1,v"); + + display->shader_download_YUY2 = gst_gl_shader_new (); + if(!gst_gl_shader_compile_and_check (display->shader_download_YUY2, + text_shader_download_YUY2, GST_GL_SHADER_FRAGMENT_SOURCE)) + { + display->isAlive = FALSE; + g_object_unref (G_OBJECT (display->shader_download_YUY2)); + display->shader_download_YUY2 = NULL; + } } break; case GST_VIDEO_FORMAT_UYVY: { - gchar program[2048]; - sprintf (program, display->textFProgram_to_YUY2_UYVY, "v,y1,u,y2"); - display->GLSLProgram_to_UYVY = gst_gl_display_load_fragment_shader (program); + gchar text_shader_download_UYVY[2048]; + sprintf (text_shader_download_UYVY, display->text_shader_download_YUY2_UYVY, "v,y1,u,y2"); + + display->shader_download_UYVY = gst_gl_shader_new (); + if(!gst_gl_shader_compile_and_check (display->shader_download_UYVY, + text_shader_download_UYVY, GST_GL_SHADER_FRAGMENT_SOURCE)) + { + display->isAlive = FALSE; + g_object_unref (G_OBJECT (display->shader_download_UYVY)); + display->shader_download_UYVY = NULL; + } } break; case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_YV12: - display->GLSLProgram_to_I420_YV12 = gst_gl_display_load_fragment_shader (display->textFProgram_to_I420_YV12); + display->shader_download_I420_YV12 = gst_gl_shader_new (); + if(!gst_gl_shader_compile_and_check (display->shader_download_I420_YV12, + display->text_shader_download_I420_YV12, GST_GL_SHADER_FRAGMENT_SOURCE)) + { + display->isAlive = FALSE; + g_object_unref (G_OBJECT (display->shader_download_I420_YV12)); + display->shader_download_I420_YV12 = NULL; + } break; case GST_VIDEO_FORMAT_AYUV: - display->GLSLProgram_to_AYUV = gst_gl_display_load_fragment_shader (display->textFProgram_to_AYUV); + display->shader_download_AYUV = gst_gl_shader_new (); + if(!gst_gl_shader_compile_and_check (display->shader_download_AYUV, + display->text_shader_download_AYUV, GST_GL_SHADER_FRAGMENT_SOURCE)) + { + display->isAlive = FALSE; + g_object_unref (G_OBJECT (display->shader_download_AYUV)); + display->shader_download_AYUV = NULL; + } break; default: g_assert_not_reached (); @@ -1356,8 +1450,18 @@ gst_gl_display_thread_gen_shader (GstGLDisplay* display) { glutSetWindow (display->glutWinId); if (GLEW_ARB_fragment_shader) - display->gen_handle_shader = - gst_gl_display_load_fragment_shader (display->gen_text_shader); + { + display->gen_shader = gst_gl_shader_new (); + + if (!gst_gl_shader_compile_and_check (display->gen_shader, + display->gen_text_shader, + GST_GL_SHADER_FRAGMENT_SOURCE)) + { + display->isAlive = FALSE; + g_object_unref (G_OBJECT (display->gen_shader)); + display->gen_shader = NULL; + } + } else { g_print ("One of the filter required ARB_fragment_shader\n"); @@ -1372,7 +1476,8 @@ static void gst_gl_display_thread_del_shader (GstGLDisplay* display) { glutSetWindow (display->glutWinId); - glDeleteObjectARB (display->del_handle_shader); + g_object_unref (G_OBJECT (display->del_shader)); + display->del_shader = NULL; g_cond_signal (display->cond_del_shader); } @@ -1587,40 +1692,6 @@ gst_gl_display_gldel_texture (GstGLDisplay* display, GLuint* pTexture) } -/* called in the gl thread */ -GLhandleARB -gst_gl_display_load_fragment_shader (gchar* textFProgram) -{ - GLhandleARB FHandle = 0; - GLhandleARB PHandle = 0; - gchar s[32768]; - GLint i = 0; - - //Set up program objects - PHandle = glCreateProgramObjectARB (); - - //Compile the shader - FHandle = glCreateShaderObjectARB (GL_FRAGMENT_SHADER_ARB); - glShaderSourceARB (FHandle, 1, (const GLcharARB**)&textFProgram, NULL); - glCompileShaderARB (FHandle); - - //Print the compilation log - glGetObjectParameterivARB (FHandle, GL_OBJECT_COMPILE_STATUS_ARB, &i); - glGetInfoLogARB (FHandle, sizeof(s)/sizeof(char), NULL, s); - GST_DEBUG ("Compile Log: %s", s); - - //link the shader - glAttachObjectARB (PHandle, FHandle); - glLinkProgramARB (PHandle); - - //Print the link log - glGetInfoLogARB (PHandle, sizeof(s)/sizeof(char), NULL, s); - GST_DEBUG ("Link Log: %s", s); - - return PHandle; -} - - /* called in the gl thread */ void gst_gl_display_check_framebuffer_status(void) @@ -1897,23 +1968,23 @@ gst_gl_display_del_fbo (GstGLDisplay* display, GLuint fbo, /* Called by glfilter */ void -gst_gl_display_gen_shader (GstGLDisplay* display, gchar* textShader, GLhandleARB* handleShader) +gst_gl_display_gen_shader (GstGLDisplay* display, const gchar* textShader, GstGLShader** shader) { gst_gl_display_lock (display); display->gen_text_shader = textShader; gst_gl_display_post_message (GST_GL_DISPLAY_ACTION_GEN_SHADER, display); g_cond_wait (display->cond_gen_shader, display->mutex); - *handleShader = display->gen_handle_shader; + *shader = display->gen_shader; gst_gl_display_unlock (display); } /* Called by glfilter */ void -gst_gl_display_del_shader (GstGLDisplay* display, GLhandleARB shader) +gst_gl_display_del_shader (GstGLDisplay* display, GstGLShader* shader) { gst_gl_display_lock (display); - display->del_handle_shader = shader; + display->del_shader = shader; gst_gl_display_post_message (GST_GL_DISPLAY_ACTION_DEL_SHADER, display); g_cond_wait (display->cond_del_shader, display->mutex); gst_gl_display_unlock (display); @@ -2251,28 +2322,28 @@ gst_gl_display_thread_do_upload_draw (GstGLDisplay* display, GLuint texture, case GST_VIDEO_FORMAT_UYVY: { gint i=0; - GLhandleARB GLSLProgram_YUY2_UYVY = 0; + + GstGLShader* shader_upload_YUY2_UYVY = NULL; switch (video_format) { case GST_VIDEO_FORMAT_YUY2: - GLSLProgram_YUY2_UYVY = display->GLSLProgram_YUY2; + shader_upload_YUY2_UYVY = display->shader_upload_YUY2; break; case GST_VIDEO_FORMAT_UYVY: - GLSLProgram_YUY2_UYVY = display->GLSLProgram_UYVY; + shader_upload_YUY2_UYVY = display->shader_upload_UYVY; break; default: g_assert_not_reached (); } - glUseProgramObjectARB (GLSLProgram_YUY2_UYVY); + gst_gl_shader_use (shader_upload_YUY2_UYVY); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glActiveTextureARB(GL_TEXTURE1_ARB); - i = glGetUniformLocationARB (GLSLProgram_YUY2_UYVY, "UVtex"); - glUniform1iARB (i, 1); + gst_gl_shader_set_uniform_1i (shader_upload_YUY2_UYVY, "UVtex", 1); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture_u); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -2280,8 +2351,7 @@ gst_gl_display_thread_do_upload_draw (GstGLDisplay* display, GLuint texture, glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glActiveTextureARB(GL_TEXTURE0_ARB); - i = glGetUniformLocationARB (GLSLProgram_YUY2_UYVY, "Ytex"); - glUniform1iARB (i, 0); + gst_gl_shader_set_uniform_1i (shader_upload_YUY2_UYVY, "Ytex", 0); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -2295,14 +2365,13 @@ gst_gl_display_thread_do_upload_draw (GstGLDisplay* display, GLuint texture, { gint i=0; - glUseProgramObjectARB (display->GLSLProgram_I420_YV12); + gst_gl_shader_use (display->shader_upload_I420_YV12); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glActiveTextureARB(GL_TEXTURE1_ARB); - i = glGetUniformLocationARB (display->GLSLProgram_I420_YV12, "Utex"); - glUniform1iARB (i, 1); + gst_gl_shader_set_uniform_1i (display->shader_upload_I420_YV12, "Utex", 1); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture_u); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -2310,8 +2379,7 @@ gst_gl_display_thread_do_upload_draw (GstGLDisplay* display, GLuint texture, glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glActiveTextureARB(GL_TEXTURE2_ARB); - i = glGetUniformLocationARB (display->GLSLProgram_I420_YV12, "Vtex"); - glUniform1iARB (i, 2); + gst_gl_shader_set_uniform_1i (display->shader_upload_I420_YV12, "Vtex", 2); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture_v); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -2319,8 +2387,7 @@ gst_gl_display_thread_do_upload_draw (GstGLDisplay* display, GLuint texture, glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glActiveTextureARB(GL_TEXTURE0_ARB); - i = glGetUniformLocationARB (display->GLSLProgram_I420_YV12, "Ytex"); - glUniform1iARB (i, 0); + gst_gl_shader_set_uniform_1i (display->shader_upload_I420_YV12, "Ytex", 0); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -2333,14 +2400,13 @@ gst_gl_display_thread_do_upload_draw (GstGLDisplay* display, GLuint texture, { gint i=0; - glUseProgramObjectARB (display->GLSLProgram_AYUV); + gst_gl_shader_use (display->shader_upload_AYUV); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glActiveTextureARB(GL_TEXTURE0_ARB); - i = glGetUniformLocationARB (display->GLSLProgram_AYUV, "tex"); - glUniform1iARB (i, 0); + gst_gl_shader_set_uniform_1i (display->shader_upload_AYUV, "tex", 0); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -2433,15 +2499,15 @@ gst_gl_display_thread_do_download_draw (GstGLDisplay* display) case GST_VIDEO_FORMAT_UYVY: { gint i=0; - GLhandleARB GLSLProgram_to_YUY2_UYVY = 0; + GstGLShader* shader_download_YUY2_UYVY = NULL; switch (video_format) { case GST_VIDEO_FORMAT_YUY2: - GLSLProgram_to_YUY2_UYVY = display->GLSLProgram_to_YUY2; + shader_download_YUY2_UYVY = display->shader_download_YUY2; break; case GST_VIDEO_FORMAT_UYVY: - GLSLProgram_to_YUY2_UYVY = display->GLSLProgram_to_UYVY; + shader_download_YUY2_UYVY = display->shader_download_UYVY; break; default: g_assert_not_reached (); @@ -2452,14 +2518,13 @@ gst_gl_display_thread_do_download_draw (GstGLDisplay* display) glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glUseProgramObjectARB (GLSLProgram_to_YUY2_UYVY); + gst_gl_shader_use (shader_download_YUY2_UYVY); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glActiveTextureARB(GL_TEXTURE0_ARB); - i = glGetUniformLocationARB (GLSLProgram_to_YUY2_UYVY, "tex"); - glUniform1iARB (i, 0); + gst_gl_shader_set_uniform_1i (shader_download_YUY2_UYVY, "tex", 0); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->ouput_texture); } break; @@ -2474,18 +2539,17 @@ gst_gl_display_thread_do_download_draw (GstGLDisplay* display) glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glUseProgramObjectARB (display->GLSLProgram_to_I420_YV12); + gst_gl_shader_use (display->shader_download_I420_YV12); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glActiveTextureARB(GL_TEXTURE0_ARB); - i = glGetUniformLocationARB (display->GLSLProgram_to_I420_YV12, "tex"); - glUniform1iARB (i, 0); - i = glGetUniformLocationARB (display->GLSLProgram_to_I420_YV12, "w"); - glUniform1fARB (i, (gfloat)display->ouput_texture_width); - i = glGetUniformLocationARB (display->GLSLProgram_to_I420_YV12, "h"); - glUniform1fARB (i, (gfloat)display->ouput_texture_height); + gst_gl_shader_set_uniform_1i (display->shader_download_I420_YV12, "tex", 0); + gst_gl_shader_set_uniform_1f (display->shader_download_I420_YV12, "w", + (gfloat)display->ouput_texture_width); + gst_gl_shader_set_uniform_1f (display->shader_download_I420_YV12, "h", + (gfloat)display->ouput_texture_height); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->ouput_texture); } break; @@ -2499,14 +2563,13 @@ gst_gl_display_thread_do_download_draw (GstGLDisplay* display) glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glUseProgramObjectARB (display->GLSLProgram_to_AYUV); + gst_gl_shader_use (display->shader_download_AYUV); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glActiveTextureARB(GL_TEXTURE0_ARB); - i = glGetUniformLocationARB (display->GLSLProgram_to_AYUV, "tex"); - glUniform1iARB (i, 0); + gst_gl_shader_set_uniform_1i (display->shader_download_AYUV, "tex", 0); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->ouput_texture); } break; @@ -2529,6 +2592,9 @@ gst_gl_display_thread_do_download_draw (GstGLDisplay* display) glDrawBuffer(GL_NONE); + //dot not check if GLSL is available + //because for now download is not available + //without GLSL glUseProgramObjectARB (0); glDisable(GL_TEXTURE_RECTANGLE_ARB); diff --git a/gst-libs/gst/gl/gstgldisplay.h b/gst-libs/gst/gl/gstgldisplay.h index e0cf8c7424..371bcbae91 100644 --- a/gst-libs/gst/gl/gstgldisplay.h +++ b/gst-libs/gst/gl/gstgldisplay.h @@ -27,6 +27,8 @@ #include #include +#include "gstglshader.h" + #define GST_TYPE_GL_DISPLAY \ (gst_gl_display_get_type()) #define GST_GL_DISPLAY(obj) \ @@ -204,31 +206,31 @@ struct _GstGLDisplay { GLuint ouput_texture_height; //action gen and del shader - gchar* gen_text_shader; - GLhandleARB gen_handle_shader; - GLhandleARB del_handle_shader; + const gchar* gen_text_shader; + GstGLShader* gen_shader; + GstGLShader* del_shader; //fragement shader upload - gchar* textFProgram_YUY2_UYVY; - GLhandleARB GLSLProgram_YUY2; - GLhandleARB GLSLProgram_UYVY; + gchar* text_shader_upload_YUY2_UYVY; + GstGLShader* shader_upload_YUY2; + GstGLShader* shader_upload_UYVY; - gchar* textFProgram_I420_YV12; - GLhandleARB GLSLProgram_I420_YV12; + gchar* text_shader_upload_I420_YV12; + GstGLShader* shader_upload_I420_YV12; - gchar* textFProgram_AYUV; - GLhandleARB GLSLProgram_AYUV; + gchar* text_shader_upload_AYUV; + GstGLShader* shader_upload_AYUV; //fragement shader download - gchar* textFProgram_to_YUY2_UYVY; - GLhandleARB GLSLProgram_to_YUY2; - GLhandleARB GLSLProgram_to_UYVY; + gchar* text_shader_download_YUY2_UYVY; + GstGLShader* shader_download_YUY2; + GstGLShader* shader_download_UYVY; - gchar* textFProgram_to_I420_YV12; - GLhandleARB GLSLProgram_to_I420_YV12; + gchar* text_shader_download_I420_YV12; + GstGLShader* shader_download_I420_YV12; - gchar* textFProgram_to_AYUV; - GLhandleARB GLSLProgram_to_AYUV; + gchar* text_shader_download_AYUV; + GstGLShader* shader_download_AYUV; }; @@ -278,8 +280,8 @@ void gst_gl_display_use_fbo (GstGLDisplay* display, gint texture_fbo_width, gint void gst_gl_display_del_fbo (GstGLDisplay* display, GLuint fbo, GLuint depth_buffer); -void gst_gl_display_gen_shader (GstGLDisplay* display, gchar* textShader, GLhandleARB* handleShader); -void gst_gl_display_del_shader (GstGLDisplay* display, GLhandleARB shader); +void gst_gl_display_gen_shader (GstGLDisplay* display, const gchar* textShader, GstGLShader** shader); +void gst_gl_display_del_shader (GstGLDisplay* display, GstGLShader* shader); void gst_gl_display_set_window_id (GstGLDisplay* display, gulong winId); void gst_gl_display_set_client_reshape_callback (GstGLDisplay* display, CRCB cb); diff --git a/gst/gl/gstglfilteredge.c b/gst/gl/gstglfilteredge.c index bdc6acb709..c4ee4a7be5 100644 --- a/gst/gl/gstglfilteredge.c +++ b/gst/gl/gstglfilteredge.c @@ -55,6 +55,37 @@ static gboolean gst_gl_filter_edge_filter (GstGLFilter * filter, GstGLBuffer * inbuf, GstGLBuffer * outbuf); static void gst_gl_filter_edge_callback (gint width, gint height, guint texture, gpointer stuff); +static const gchar *sobel_fragment_source = + "uniform sampler2DRect tex;\n" + "void main(void) {\n" + " const int N = 8;\n" + " const vec2 delta[N] = vec2[N](\n" + " vec2( -1.0, -1.0 ),\n" + " vec2( -1.0 , 0.0 ),\n" + " vec2( -1.0 , 1.0 ),\n" + " vec2( 0.0 , 1.0 ),\n" + " vec2( 1.0 , 1.0 ),\n" + " vec2( 1.0 , 0.0 ),\n" + " vec2( 1.0 , -1.0 ),\n" + " vec2( 0.0 , -1.0 )\n" + " );\n" + " const float filterH[N] = float[N]\n" + " (-1.0, 0.0, 1.0, 2.0, 1.0, 0.0, -1.0, -2.0);\n" + " const float filterV[N] = float[N]\n" + " (-1.0, -2.0, -1.0, 0.0, 1.0, 2.0, 1.0, 0.0);\n" + " float gH = 0.0;\n" + " float gV = 0.0;\n" + " int i;\n" + " vec2 nxy = gl_TexCoord[0].xy;\n" + " for (i = 0; i < N; i++) {\n" + " vec4 vcolor_i = texture2DRect(tex, nxy + delta[i]);\n" + " float gray_i = (vcolor_i.r + vcolor_i.g + vcolor_i.b) / 3.0;\n" + " gH += gH + filterH[i] * gray_i;\n" + " gV += gV + filterV[i] * gray_i;\n" + " }\n" + " float g = sqrt(gH * gH + gV * gV) / 256.0;\n" + " gl_FragColor = vec4(g, g, g, 1.0);\n" + "}\n"; static void gst_gl_filter_edge_base_init (gpointer klass) @@ -82,38 +113,7 @@ static void gst_gl_filter_edge_init (GstGLFilterEdge* filter, GstGLFilterEdgeClass* klass) { - filter->handleShader = 0; - filter->textShader = - "uniform sampler2DRect tex;\n" - "void main(void) {\n" - " const int N = 8;\n" - " const vec2 delta[N] = vec2[N](\n" - " vec2( -1.0, -1.0 ),\n" - " vec2( -1.0 , 0.0 ),\n" - " vec2( -1.0 , 1.0 ),\n" - " vec2( 0.0 , 1.0 ),\n" - " vec2( 1.0 , 1.0 ),\n" - " vec2( 1.0 , 0.0 ),\n" - " vec2( 1.0 , -1.0 ),\n" - " vec2( 0.0 , -1.0 )\n" - " );\n" - " const float filterH[N] = float[N]\n" - " (-1.0, 0.0, 1.0, 2.0, 1.0, 0.0, -1.0, -2.0);\n" - " const float filterV[N] = float[N]\n" - " (-1.0, -2.0, -1.0, 0.0, 1.0, 2.0, 1.0, 0.0);\n" - " float gH = 0.0;\n" - " float gV = 0.0;\n" - " int i;\n" - " vec2 nxy = gl_TexCoord[0].xy;\n" - " for (i = 0; i < N; i++) {\n" - " vec4 vcolor_i = texture2DRect(tex, nxy + delta[i]);\n" - " float gray_i = (vcolor_i.r + vcolor_i.g + vcolor_i.b) / 3.0;\n" - " gH += gH + filterH[i] * gray_i;\n" - " gV += gV + filterV[i] * gray_i;\n" - " }\n" - " float g = sqrt(gH * gH + gV * gV) / 256.0;\n" - " gl_FragColor = vec4(g, g, g, 1.0);\n" - "}\n"; + filter->shader = NULL; } static void @@ -121,8 +121,8 @@ gst_gl_filter_edge_reset (GstGLFilter* filter) { GstGLFilterEdge* edge_filter = GST_GL_FILTER_EDGE(filter); - //blocking call, wait the opengl thread has destroyed the shader program - gst_gl_display_del_shader (filter->display, edge_filter->handleShader); + //blocking call, wait the opengl thread has destroyed the shader + gst_gl_display_del_shader (filter->display, edge_filter->shader); } static void @@ -159,7 +159,7 @@ gst_gl_filter_edge_init_shader (GstGLFilter* filter) GstGLFilterEdge* edge_filter = GST_GL_FILTER_EDGE (filter); //blocking call, wait the opengl thread has compiled the shader program - gst_gl_display_gen_shader (filter->display, edge_filter->textShader, &edge_filter->handleShader); + gst_gl_display_gen_shader (filter->display, sobel_fragment_source, &edge_filter->shader); } static gboolean @@ -188,11 +188,10 @@ gst_gl_filter_edge_callback (gint width, gint height, guint texture, gpointer st glMatrixMode (GL_PROJECTION); glLoadIdentity (); - glUseProgramObjectARB (edge_filter->handleShader); + gst_gl_shader_use (edge_filter->shader); glActiveTextureARB(GL_TEXTURE0_ARB); - i = glGetUniformLocationARB (edge_filter->handleShader, "tex"); - glUniform1iARB (i, 0); + gst_gl_shader_set_uniform_1i (edge_filter->shader, "tex", 0); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); glBegin (GL_QUADS); diff --git a/gst/gl/gstglfilteredge.h b/gst/gl/gstglfilteredge.h index 9f153425fe..682e2fe085 100644 --- a/gst/gl/gstglfilteredge.h +++ b/gst/gl/gstglfilteredge.h @@ -38,9 +38,7 @@ typedef struct _GstGLFilterEdgeClass GstGLFilterEdgeClass; struct _GstGLFilterEdge { GstGLFilter filter; - - gchar* textShader; - GLhandleARB handleShader; + GstGLShader *shader; }; struct _GstGLFilterEdgeClass diff --git a/gst/gl/gstglfilterlaplacian.c b/gst/gl/gstglfilterlaplacian.c index 11127281fb..2f2115d426 100644 --- a/gst/gl/gstglfilterlaplacian.c +++ b/gst/gl/gstglfilterlaplacian.c @@ -62,8 +62,7 @@ static const gchar *convolution_fragment_source = "uniform float norm_offset;" "uniform float kernel[9];" "void main () {" - " const int N = 9;" - " const vec2 offset[N] = vec2[N] (" + " vec2 offset[9] = vec2[9] (" " vec2(-1.0,-1.0), vec2( 0.0,-1.0), vec2( 1.0,-1.0)," " vec2(-1.0, 0.0), vec2( 0.0, 0.0), vec2( 1.0, 0.0)," " vec2(-1.0, 1.0), vec2( 0.0, 1.0), vec2( 1.0, 1.0) );" @@ -105,26 +104,16 @@ static void gst_gl_filter_laplacian_init (GstGLFilterLaplacian* filter, GstGLFilterLaplacianClass* klass) { + filter->shader = NULL; } static void gst_gl_filter_laplacian_reset (GstGLFilter* filter) { - //GstGLFilterLaplacian* laplacian_filter = GST_GL_FILTER_LAPLACIAN(filter); + GstGLFilterLaplacian* laplacian_filter = GST_GL_FILTER_LAPLACIAN(filter); - //I commented the following line to avoid a crash for now - //It crashs because when unreferencing the GstGLShader - //if ref is down to 0 it causes a finalize then a gst_gl_shader_release - //then a glDeleteObjectARB - //and this glDeleteObjectARB must be executed in by (in) the gl thread - //How to do that so ? Easy, using the gst_gl_display_del_shader method - //but I have not modified it yet (*1*) to use GstGLShader - //I'll do that soon so just comment the following line for now - //g_object_unref (G_OBJECT (laplacian_filter->shader)); - - //blocking call, wait the opengl thread has destroyed the GstGLShader - //Commented for the reason *1* - //gst_gl_display_del_shader (filter->display, laplacian_filter->shader); + //blocking call, wait the opengl thread has destroyed the shader + gst_gl_display_del_shader (filter->display, laplacian_filter->shader); } static void @@ -158,14 +147,10 @@ gst_gl_filter_laplacian_get_property (GObject* object, guint prop_id, static void gst_gl_filter_laplacian_init_shader (GstGLFilter* filter) { -// GstGLFilterLaplacian* laplacian_filter = GST_GL_FILTER_LAPLACIAN (filter); + GstGLFilterLaplacian* laplacian_filter = GST_GL_FILTER_LAPLACIAN (filter); - // at the moment I do everything in the laplacian_callback - // ok, then for the same reason *1* explained in the - // gst_gl_filter_laplacian_reset method I comment the following line - - //blocking call, wait the opengl thread has destroyed the shader program - //gst_gl_display_del_shader (filter->display, laplacian_filter->shader); + //blocking call, wait the opengl thread has compiled the shader + gst_gl_display_gen_shader (filter->display, convolution_fragment_source, &laplacian_filter->shader); } static gboolean @@ -197,17 +182,6 @@ gst_gl_filter_laplacian_callback (gint width, gint height, guint texture, gpoint glMatrixMode (GL_PROJECTION); glLoadIdentity (); - /* compile and link the shader (if not done previously) */ - //FIXME: do it in the gst_gl_filter_laplacian_init_shader method - if (!laplacian_filter->shader) - { - laplacian_filter->shader = gst_gl_shader_new (); - - g_return_if_fail ( - gst_gl_shader_compile_and_check (laplacian_filter->shader, convolution_fragment_source, - GST_GL_SHADER_FRAGMENT_SOURCE)); - } - gst_gl_shader_use (laplacian_filter->shader); glActiveTexture (GL_TEXTURE0); diff --git a/gst/gl/gstglfilterlaplacian.h b/gst/gl/gstglfilterlaplacian.h index ffa243f50c..3d6d0c8eb9 100644 --- a/gst/gl/gstglfilterlaplacian.h +++ b/gst/gl/gstglfilterlaplacian.h @@ -22,7 +22,6 @@ #define _GST_GL_FILTERLAPLACIAN_H_ #include -#include G_BEGIN_DECLS