forked from AuroraMiddleware/gtk
a546ae32d7
Those property features don't seem to be in use anywhere. They are redundant since the docs cover the same information and more. They also created unnecessary translation work. Closes #4904
180 lines
4.3 KiB
C
180 lines
4.3 KiB
C
#include "config.h"
|
|
|
|
#include "gskglprofilerprivate.h"
|
|
|
|
#include <epoxy/gl.h>
|
|
|
|
#define N_QUERIES 4
|
|
|
|
struct _GskGLProfiler
|
|
{
|
|
GObject parent_instance;
|
|
|
|
GdkGLContext *gl_context;
|
|
|
|
/* Creating GL queries is kind of expensive, so we pay the
|
|
* price upfront and create a circular buffer of queries
|
|
*/
|
|
GLuint gl_queries[N_QUERIES];
|
|
GLuint active_query;
|
|
|
|
gboolean has_queries : 1;
|
|
gboolean has_timer : 1;
|
|
gboolean first_frame : 1;
|
|
};
|
|
|
|
enum {
|
|
PROP_GL_CONTEXT = 1,
|
|
|
|
N_PROPERTIES
|
|
};
|
|
|
|
static GParamSpec *gsk_gl_profiler_properties[N_PROPERTIES];
|
|
|
|
G_DEFINE_TYPE (GskGLProfiler, gsk_gl_profiler, G_TYPE_OBJECT)
|
|
|
|
static void
|
|
gsk_gl_profiler_finalize (GObject *gobject)
|
|
{
|
|
GskGLProfiler *self = GSK_GL_PROFILER (gobject);
|
|
|
|
if (self->has_queries)
|
|
glDeleteQueries (N_QUERIES, self->gl_queries);
|
|
|
|
g_clear_object (&self->gl_context);
|
|
|
|
G_OBJECT_CLASS (gsk_gl_profiler_parent_class)->finalize (gobject);
|
|
}
|
|
|
|
static void
|
|
gsk_gl_profiler_set_property (GObject *gobject,
|
|
guint prop_id,
|
|
const GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
GskGLProfiler *self = GSK_GL_PROFILER (gobject);
|
|
|
|
switch (prop_id)
|
|
{
|
|
case PROP_GL_CONTEXT:
|
|
self->gl_context = g_value_dup_object (value);
|
|
break;
|
|
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
|
}
|
|
}
|
|
|
|
static void
|
|
gsk_gl_profiler_get_property (GObject *gobject,
|
|
guint prop_id,
|
|
GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
GskGLProfiler *self = GSK_GL_PROFILER (gobject);
|
|
|
|
switch (prop_id)
|
|
{
|
|
case PROP_GL_CONTEXT:
|
|
g_value_set_object (value, self->gl_context);
|
|
break;
|
|
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
|
}
|
|
}
|
|
|
|
static void
|
|
gsk_gl_profiler_class_init (GskGLProfilerClass *klass)
|
|
{
|
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
|
|
|
gobject_class->set_property = gsk_gl_profiler_set_property;
|
|
gobject_class->get_property = gsk_gl_profiler_get_property;
|
|
gobject_class->finalize = gsk_gl_profiler_finalize;
|
|
|
|
gsk_gl_profiler_properties[PROP_GL_CONTEXT] =
|
|
g_param_spec_object ("gl-context", NULL, NULL,
|
|
GDK_TYPE_GL_CONTEXT,
|
|
G_PARAM_READWRITE |
|
|
G_PARAM_CONSTRUCT_ONLY |
|
|
G_PARAM_STATIC_STRINGS);
|
|
|
|
g_object_class_install_properties (gobject_class, N_PROPERTIES, gsk_gl_profiler_properties);
|
|
}
|
|
|
|
static void
|
|
gsk_gl_profiler_init (GskGLProfiler *self)
|
|
{
|
|
self->has_queries = epoxy_is_desktop_gl();
|
|
self->has_timer = epoxy_is_desktop_gl() && (epoxy_gl_version () >= 33 || epoxy_has_gl_extension ("GL_ARB_timer_query"));
|
|
|
|
if (!self->has_queries)
|
|
return;
|
|
|
|
glGenQueries (N_QUERIES, self->gl_queries);
|
|
self->first_frame = TRUE;
|
|
}
|
|
|
|
GskGLProfiler *
|
|
gsk_gl_profiler_new (GdkGLContext *context)
|
|
{
|
|
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), NULL);
|
|
|
|
return g_object_new (GSK_TYPE_GL_PROFILER, "gl-context", context, NULL);
|
|
}
|
|
|
|
void
|
|
gsk_gl_profiler_begin_gpu_region (GskGLProfiler *profiler)
|
|
{
|
|
GLuint query_id;
|
|
|
|
g_return_if_fail (GSK_IS_GL_PROFILER (profiler));
|
|
|
|
if (!profiler->has_timer || !profiler->has_queries)
|
|
return;
|
|
|
|
query_id = profiler->gl_queries[profiler->active_query];
|
|
glBeginQuery (GL_TIME_ELAPSED, query_id);
|
|
}
|
|
|
|
guint64
|
|
gsk_gl_profiler_end_gpu_region (GskGLProfiler *profiler)
|
|
{
|
|
GLuint last_query_id;
|
|
GLint res;
|
|
GLuint64 elapsed;
|
|
|
|
g_return_val_if_fail (GSK_IS_GL_PROFILER (profiler), 0);
|
|
|
|
if (!profiler->has_timer || !profiler->has_queries)
|
|
return 0;
|
|
|
|
glEndQuery (GL_TIME_ELAPSED);
|
|
|
|
if (profiler->active_query == 0)
|
|
last_query_id = N_QUERIES - 1;
|
|
else
|
|
last_query_id = profiler->active_query - 1;
|
|
|
|
/* Advance iterator */
|
|
profiler->active_query += 1;
|
|
if (profiler->active_query == N_QUERIES)
|
|
profiler->active_query = 0;
|
|
|
|
/* If this is the first frame we already have a result */
|
|
if (profiler->first_frame)
|
|
{
|
|
profiler->first_frame = FALSE;
|
|
return 0;
|
|
}
|
|
|
|
glGetQueryObjectiv (profiler->gl_queries[last_query_id], GL_QUERY_RESULT_AVAILABLE, &res);
|
|
if (res == 1)
|
|
glGetQueryObjectui64v (profiler->gl_queries[last_query_id], GL_QUERY_RESULT, &elapsed);
|
|
else
|
|
elapsed = 0;
|
|
|
|
return elapsed / 1000; /* Convert to usec to match other profiler APIs */
|
|
}
|