/*
 * GStreamer
 * Copyright (C) 2016 Matthew Waters <matthew@centricular.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:gstglquery
 * @short_description: OpenGL query abstraction
 * @title: GstGLQuery
 * @see_also: 
 *
 * A #GstGLQuery represents and holds an OpenGL query object.  Various types of
 * queries can be run or counters retrieved.
 *
 * Since: 1.10
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gst/gl/gl.h>

#include <string.h>

#include "gstglquery.h"

#ifndef GL_TIME_ELAPSED
#define GL_TIME_ELAPSED 0x88BF
#endif

#ifndef GL_TIMESTAMP
#define GL_TIMESTAMP 0x8E28
#endif

#ifndef GL_QUERY_RESULT
#define GL_QUERY_RESULT 0x8866
#endif

#define GST_CAT_DEFAULT gst_gl_query_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);

static void
_init_debug (void)
{
  static volatile gsize _init = 0;

  if (g_once_init_enter (&_init)) {
    GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "glquery", 0, "glquery element");
    g_once_init_leave (&_init, 1);
  }
}

static const gchar *
_query_type_to_string (guint query_type)
{
  switch (query_type) {
    case GST_GL_QUERY_TIME_ELAPSED:
    case GL_TIME_ELAPSED:
      return "time elapsed";
    case GL_TIMESTAMP:
    case GST_GL_QUERY_TIMESTAMP:
      return "timestamp";
    default:
      return "unknown";
  }
}

static guint
_gst_gl_query_type_to_gl (GstGLQueryType query_type)
{
  if (query_type == GST_GL_QUERY_TIME_ELAPSED)
    return GL_TIME_ELAPSED;
  if (query_type == GST_GL_QUERY_TIMESTAMP)
    return GL_TIMESTAMP;

  g_assert_not_reached ();
  return 0;
}

static gboolean
_query_type_supports_counter (guint gl_query_type)
{
  return gl_query_type == GL_TIMESTAMP;
}

static gboolean
_query_type_supports_begin_end (guint gl_query_type)
{
  return gl_query_type == GL_TIME_ELAPSED;
}

static gboolean
_context_supports_query_type (GstGLContext * context, guint gl_query_type)
{
  return gl_query_type != 0 && context->gl_vtable->GenQueries != NULL;
}

static gchar *
_log_time (gpointer user_data)
{
  GstGLQuery *query = user_data;
  gint64 result;

  result = gst_gl_query_result (query);

  return gst_info_strdup_printf ("%" GST_TIME_FORMAT, GST_TIME_ARGS (result));
}

/**
 * gst_gl_query_init:
 * @query: a #GstGLQuery
 * @context: a #GstGLContext
 * @query_type: the #GstGLQueryType
 *
 * Since: 1.10
 */
void
gst_gl_query_init (GstGLQuery * query, GstGLContext * context,
    GstGLQueryType query_type)
{
  const GstGLFuncs *gl;

  g_return_if_fail (query != NULL);
  g_return_if_fail (GST_IS_GL_CONTEXT (context));
  gl = context->gl_vtable;

  memset (query, 0, sizeof (*query));

  _init_debug ();

  query->context = gst_object_ref (context);
  query->query_type = _gst_gl_query_type_to_gl (query_type);
  query->supported = _context_supports_query_type (context, query->query_type);

  if (query->supported)
    gl->GenQueries (1, &query->query_id);

  gst_gl_async_debug_init (&query->debug);
  query->debug.callback = _log_time;
  query->debug.user_data = query;
}

/**
 * gst_gl_query_unset:
 * @query: a #GstGLQuery
 *
 * Free any dynamically allocated resources
 *
 * Since: 1.10
 */
void
gst_gl_query_unset (GstGLQuery * query)
{
  const GstGLFuncs *gl;

  g_return_if_fail (query != NULL);
  if (query->start_called)
    g_critical ("Unsetting a running query. This may not be what you wanted."
        "Be sure to pair calls to gst_gl_query_start() and gst_gl_query_end()");

  GST_TRACE ("%p unsetting query %u", query, query->query_id);

  gl = query->context->gl_vtable;

  /* unset the debug object as it may callback to print the last message */
  gst_gl_async_debug_unset (&query->debug);

  if (query->query_id)
    gl->DeleteQueries (1, &query->query_id);

  gst_object_unref (query->context);
}

/**
 * gst_gl_query_new:
 * @context: a #GstGLContext
 * @query_type: the #GstGLQueryType to create
 *
 * Free with gst_gl_query_free()
 *
 * Returns: a new #GstGLQuery
 *
 * Since: 1.10
 */
GstGLQuery *
gst_gl_query_new (GstGLContext * context, GstGLQueryType query_type)
{
  GstGLQuery *query = g_new0 (GstGLQuery, 1);

  gst_gl_query_init (query, context, query_type);

  return query;
}

/**
 * gst_gl_query_free:
 * @query: a #GstGLQuery
 *
 * Frees a #GstGLQuery
 *
 * Since: 1.10
 */
void
gst_gl_query_free (GstGLQuery * query)
{
  g_return_if_fail (query != NULL);

  gst_gl_query_unset (query);
  g_free (query);
}

/**
 * gst_gl_query_start:
 * @query: a #GstGLQuery
 *
 * Start counting the query
 *
 * Since: 1.10
 */
void
gst_gl_query_start (GstGLQuery * query)
{
  const GstGLFuncs *gl;

  g_return_if_fail (query != NULL);
  g_return_if_fail (_query_type_supports_begin_end (query->query_type));

  if (!query->supported)
    return;

  query->start_called = TRUE;
  gst_gl_async_debug_output_log_msg (&query->debug);

  GST_TRACE ("%p start query type \'%s\' id %u", query,
      _query_type_to_string (query->query_type), query->query_id);

  gl = query->context->gl_vtable;
  gl->BeginQuery (query->query_type, query->query_id);
}

/**
 * gst_gl_query_end:
 * @query: a #GstGLQuery
 *
 * End counting the query
 *
 * Since: 1.10
 */
void
gst_gl_query_end (GstGLQuery * query)
{
  const GstGLFuncs *gl;

  g_return_if_fail (query != NULL);
  g_return_if_fail (_query_type_supports_begin_end (query->query_type));

  if (!query->supported)
    return;
  g_return_if_fail (query->start_called);

  GST_TRACE ("%p end query type \'%s\' id %u", query,
      _query_type_to_string (query->query_type), query->query_id);

  gl = query->context->gl_vtable;

  gl->EndQuery (query->query_type);
  query->start_called = FALSE;
}

/**
 * gst_gl_query_counter:
 * @query: a #GstGLQuery
 *
 * Record the result of a counter
 *
 * Since: 1.10
 */
void
gst_gl_query_counter (GstGLQuery * query)
{
  const GstGLFuncs *gl;

  g_return_if_fail (query != NULL);
  g_return_if_fail (_query_type_supports_counter (query->query_type));

  if (!query->supported)
    return;

  GST_TRACE ("%p query counter type \'%s\' id %u", query,
      _query_type_to_string (query->query_type), query->query_id);

  gst_gl_async_debug_output_log_msg (&query->debug);

  gl = query->context->gl_vtable;
  gl->QueryCounter (query->query_id, query->query_type);
}

/**
 * gst_gl_query_result:
 * @query: a #GstGLQuery
 *
 * Returns: the result of the query
 *
 * Since: 1.10
 */
guint64
gst_gl_query_result (GstGLQuery * query)
{
  const GstGLFuncs *gl;
  guint64 ret;

  g_return_val_if_fail (query != NULL, 0);
  g_return_val_if_fail (!query->start_called, 0);

  if (!query->supported)
    return 0;

  gl = query->context->gl_vtable;
  if (gl->GetQueryObjectui64v) {
    gl->GetQueryObjectui64v (query->query_id, GL_QUERY_RESULT,
        (GLuint64 *) & ret);
  } else {
    guint tmp;
    gl->GetQueryObjectuiv (query->query_id, GL_QUERY_RESULT, &tmp);
    ret = tmp;
  }

  GST_TRACE ("%p get result %" G_GUINT64_FORMAT " type \'%s\' id %u", query,
      ret, _query_type_to_string (query->query_type), query->query_id);

  return ret;
}
