]> git.cworth.org Git - fips/blobdiff - context.c
Add explicit link to libpthread, to work around debugging issues
[fips] / context.c
index f4694c1ae8052152c9d36383e64170ccca2a0832..3c58a60e6b2fbd76ca7a13dfaa3248f67fd43828 100644 (file)
--- a/context.c
+++ b/context.c
  */
 
 #include "context.h"
-
 #include "metrics.h"
+#include "xmalloc.h"
 
-/* FIXME: Need a map from integers to context objects and track the
- * current context with glXMakeContextCurrent, eglMakeCurrent, etc. */
+typedef struct context
+{
+       /* Pointer to the system's context ID, (such as a GLXContext) */
+       void *system_id;
 
-context_t current_context;
+       /* Does this context have the AMD_performance_monitor extension? */
+       bool have_perfmon;
 
-void
-context_enter (fips_api_t api, void *system_context_id unused)
+       metrics_info_t metrics_info;
+       metrics_t *metrics;
+} context_t;
+
+context_t *current_context;
+
+static bool
+check_extension (const char *extension);
+
+static context_t *
+context_create (fips_api_t api, void *system_context_id)
 {
-       context_t *ctx = &current_context;
+       context_t *ctx;
+
+       ctx = xcalloc (1, sizeof (*ctx));
+
+       ctx->system_id = system_context_id;
 
        fips_dispatch_init (api);
 
-       metrics_info_init (&ctx->metrics_info);
+       ctx->have_perfmon = check_extension ("GL_AMD_performance_monitor");
+
+       metrics_info_init (&ctx->metrics_info, ctx->have_perfmon);
+       ctx->metrics = metrics_create (&ctx->metrics_info);
+
+       return ctx;
+}
+
+static void
+context_destroy (context_t *ctx)
+{
+       metrics_info_fini (&ctx->metrics_info);
+}
 
-       metrics_set_current_op (METRICS_OP_SHADER + 0);
-       metrics_counter_start ();
+void
+context_enter (fips_api_t api, void *system_context_id)
+{
+       /* Do nothing if the application is setting the same context
+        * as is already current. */
+       if (current_context && current_context->system_id == system_context_id)
+               return;
+
+       if (current_context)
+               context_destroy (current_context);
+
+       current_context = context_create (api, system_context_id);
+
+       metrics_set_current_op (current_context->metrics,
+                               METRICS_OP_SHADER + 0);
+       metrics_counter_start (current_context->metrics);
 }
 
 void
 context_leave (void)
 {
-       context_t *ctx = &current_context;
-       timer_query_t *timer, *timer_next;
-       monitor_t *monitor, *monitor_next;
+       context_t *ctx = current_context;
 
-       metrics_collect_available ();
+       if (ctx == NULL)
+               return;
 
-       if (ctx->timer_begun_id) {
-               glEndQuery (GL_TIME_ELAPSED);
-               glDeleteQueries (1, &ctx->timer_begun_id);
-               ctx->timer_begun_id = 0;
-       }
+       metrics_destroy (ctx->metrics);
+}
 
-       for (timer = ctx->timer_head;
-            timer;
-            timer = timer_next)
-       {
-               glDeleteQueries (1, &timer->id);
-               timer_next = timer->next;
-               free (timer);
-       }
-       ctx->timer_head = NULL;
-       ctx->timer_tail = NULL;
+void
+context_counter_start (void)
+{
+       metrics_counter_start (current_context->metrics);
+}
 
-       if (ctx->monitor_begun_id) {
-               glEndPerfMonitorAMD (ctx->monitor_begun_id);
-               glDeletePerfMonitorsAMD (1, &ctx->monitor_begun_id);
-               ctx->monitor_begun_id = 0;
-       }
+void
+context_counter_stop (void)
+{
+       metrics_counter_stop (current_context->metrics);
+}
 
-       for (monitor = ctx->monitor_head;
-            monitor;
-            monitor = monitor_next)
-       {
-               glDeletePerfMonitorsAMD (1, &monitor->id);
-               monitor_next = monitor->next;
-               free (monitor);
-       }
-       ctx->monitor_head = NULL;
-       ctx->monitor_tail = NULL;
+void
+context_set_current_op (metrics_op_t op)
+{
+       metrics_set_current_op (current_context->metrics, op);
+}
 
-       current_context.monitors_in_flight = 0;
+metrics_op_t
+context_get_current_op (void)
+{
+       return metrics_get_current_op (current_context->metrics);
+}
 
-       metrics_info_fini (&ctx->metrics_info);
+void
+context_end_frame (void)
+{
+       return metrics_end_frame (current_context->metrics);
 }
 
-context_t *
-context_get_current (void)
+/* Is the given extension available? */
+static bool
+check_extension (const char *extension)
 {
-       return &current_context;
+       int i, num_extensions;
+       const char *available;
+
+       glGetIntegerv (GL_NUM_EXTENSIONS, &num_extensions);
+
+       for (i = 0; i < num_extensions; i++) {
+               available = (char *) glGetStringi (GL_EXTENSIONS, i);
+               if (strcmp (extension, available) == 0) {
+                       return true;
+               }
+       }
+
+       return false;
 }