/*
 * 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: (skip)
 * @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;
}
