示例#1
0
static void
_compile_shader (GstGLContext * context, struct _compile_shader *data)
{
  GstGLShader *shader;
  GstGLSLStage *vert, *frag;
  GError *error = NULL;

  shader = gst_gl_shader_new (context);

  if (data->vertex_src) {
    vert = gst_glsl_stage_new_with_string (context, GL_VERTEX_SHADER,
        GST_GLSL_VERSION_NONE,
        GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY, data->vertex_src);
    if (!gst_glsl_stage_compile (vert, &error)) {
      GST_ERROR_OBJECT (vert, "%s", error->message);
      gst_object_unref (vert);
      gst_object_unref (shader);
      return;
    }
    if (!gst_gl_shader_attach (shader, vert)) {
      gst_object_unref (shader);
      return;
    }
  }

  if (data->fragment_src) {
    frag = gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER,
        GST_GLSL_VERSION_NONE,
        GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY,
        data->fragment_src);
    if (!gst_glsl_stage_compile (frag, &error)) {
      GST_ERROR_OBJECT (frag, "%s", error->message);
      gst_object_unref (frag);
      gst_object_unref (shader);
      return;
    }
    if (!gst_gl_shader_attach (shader, frag)) {
      gst_object_unref (shader);
      return;
    }
  }

  if (!gst_gl_shader_link (shader, &error)) {
    GST_ERROR_OBJECT (shader, "%s", error->message);
    g_error_free (error);
    error = NULL;
    gst_gl_context_clear_shader (context);
    gst_object_unref (shader);
    return;
  }

  *data->shader = shader;
}
示例#2
0
static void
_test_separate_compile_attach_gl (GstGLContext * context, gpointer data)
{
  GstGLShader *shader;
  GstGLSLStage *vert;
  GError *error = NULL;

  shader = gst_gl_shader_new (context);
  vert = gst_glsl_stage_new_default_vertex (context);

  fail_unless (gst_glsl_stage_compile (vert, &error));
  fail_unless (gst_gl_shader_attach (shader, vert));
  fail_unless (gst_gl_shader_attach (shader, vert));

  gst_object_unref (shader);
}
示例#3
0
/**
 * gst_gl_shader_compile_attach_stage:
 * @shader: a #GstGLShader
 * @stage: a #GstGLSLStage to attach
 * @error: a #GError
 *
 * Compiles @stage and attaches it to @shader.
 *
 * Note: must be called in the GL thread
 *
 * Returns: whether @stage could be compiled and attached to @shader
 *
 * Since: 1.8
 */
gboolean
gst_gl_shader_compile_attach_stage (GstGLShader * shader, GstGLSLStage * stage,
    GError ** error)
{
  g_return_val_if_fail (GST_IS_GLSL_STAGE (stage), FALSE);

  if (!gst_glsl_stage_compile (stage, error)) {
    return FALSE;
  }

  if (!gst_gl_shader_attach (shader, stage)) {
    g_set_error (error, GST_GLSL_ERROR, GST_GLSL_ERROR_COMPILE,
        "Failed to attach stage to shader");
    return FALSE;
  }

  return TRUE;
}
示例#4
0
static GstGLShader *
_new_with_stages_va_list (GstGLContext * context, GError ** error,
    va_list varargs)
{
  GstGLShader *shader;
  GstGLSLStage *stage;
  gboolean to_unref_and_out = FALSE;

  g_return_val_if_fail (GST_IS_GL_CONTEXT (context), NULL);

  shader = g_object_new (GST_TYPE_GL_SHADER, NULL);
  gst_object_ref_sink (shader);
  shader->context = gst_object_ref (context);

  while ((stage = va_arg (varargs, GstGLSLStage *))) {
    if (to_unref_and_out) {
      gst_object_unref (stage);
      continue;
    }

    if (!gst_glsl_stage_compile (stage, error)) {
      gst_object_unref (stage);
      to_unref_and_out = TRUE;
      continue;
    }
    if (!gst_gl_shader_attach (shader, stage)) {
      g_set_error (error, GST_GLSL_ERROR, GST_GLSL_ERROR_PROGRAM,
          "Failed to attach stage to program");
      to_unref_and_out = TRUE;
      continue;
    }
  }

  if (to_unref_and_out) {
    gst_object_unref (shader);
    return NULL;
  }

  return shader;
}
示例#5
0
/**
 * gst_gl_shader_link:
 * @shader: a #GstGLShader
 * @error: a #GError
 *
 * Links the current list of #GstGLSLStage's in @shader.
 *
 * Note: must be called in the GL thread
 *
 * Returns: whether @shader could be linked together.
 *
 * Since: 1.8
 */
gboolean
gst_gl_shader_link (GstGLShader * shader, GError ** error)
{
  GstGLShaderPrivate *priv;
  const GstGLFuncs *gl;
  gchar info_buffer[2048];
  GLint status = GL_FALSE;
  gint len = 0;
  gboolean ret;
  GList *elem;

  g_return_val_if_fail (GST_IS_GL_SHADER (shader), FALSE);

  GST_OBJECT_LOCK (shader);

  priv = shader->priv;
  gl = shader->context->gl_vtable;

  if (priv->linked) {
    GST_OBJECT_UNLOCK (shader);
    return TRUE;
  }

  if (!_gst_glsl_funcs_fill (&shader->priv->vtable, shader->context)) {
    g_set_error (error, GST_GLSL_ERROR, GST_GLSL_ERROR_PROGRAM,
        "Failed to retreive required GLSL functions");
    GST_OBJECT_UNLOCK (shader);
    return FALSE;
  }

  if (!_ensure_program (shader)) {
    g_set_error (error, GST_GLSL_ERROR, GST_GLSL_ERROR_PROGRAM,
        "Failed to create GL program object");
    GST_OBJECT_UNLOCK (shader);
    return FALSE;
  }

  GST_TRACE ("shader created %u", shader->priv->program_handle);

  for (elem = shader->priv->stages; elem; elem = elem->next) {
    GstGLSLStage *stage = elem->data;

    if (!gst_glsl_stage_compile (stage, error)) {
      GST_OBJECT_UNLOCK (shader);
      return FALSE;
    }

    if (!gst_gl_shader_attach_unlocked (shader, stage)) {
      g_set_error (error, GST_GLSL_ERROR, GST_GLSL_ERROR_COMPILE,
          "Failed to attach shader %" GST_PTR_FORMAT "to program %"
          GST_PTR_FORMAT, stage, shader);
      GST_OBJECT_UNLOCK (shader);
      return FALSE;
    }
  }

  /* if nothing failed link shaders */
  gl->LinkProgram (priv->program_handle);
  status = GL_FALSE;
  priv->vtable.GetProgramiv (priv->program_handle, GL_LINK_STATUS, &status);

  priv->vtable.GetProgramInfoLog (priv->program_handle,
      sizeof (info_buffer) - 1, &len, info_buffer);
  info_buffer[len] = '\0';

  if (status != GL_TRUE) {
    GST_ERROR ("Shader linking failed:\n%s", info_buffer);

    g_set_error (error, GST_GLSL_ERROR, GST_GLSL_ERROR_LINK,
        "Shader Linking failed:\n%s", info_buffer);
    ret = priv->linked = FALSE;
    GST_OBJECT_UNLOCK (shader);
    return ret;
  } else if (len > 1) {
    GST_FIXME ("shader link log:\n%s\n", info_buffer);
  }

  ret = priv->linked = TRUE;
  GST_OBJECT_UNLOCK (shader);

  g_object_notify (G_OBJECT (shader), "linked");

  return ret;
}