*/
#include "context.h"
-
#include "metrics.h"
+#include "xmalloc.h"
-void
-context_enter (fips_api_t api, void *system_context_id unused)
+typedef struct context
{
+ /* Pointer to the system's context ID, (such as a GLXContext) */
+ void *system_id;
+
+ /* Does this context have the AMD_performance_monitor extension? */
+ bool have_perfmon;
+
+ 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;
+
+ ctx = xcalloc (1, sizeof (*ctx));
+
+ ctx->system_id = system_context_id;
+
fips_dispatch_init (api);
- metrics_info_init ();
+ 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);
- metrics_set_current_op (METRICS_OP_SHADER + 0);
- metrics_counter_start ();
+ return ctx;
+}
+
+static void
+context_destroy (context_t *ctx)
+{
+ metrics_info_fini (&ctx->metrics_info);
+}
+
+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)
{
- metrics_info_fini ();
+ context_t *ctx = current_context;
+
+ if (ctx == NULL)
+ return;
+
+ metrics_destroy (ctx->metrics);
+}
+
+void
+context_counter_start (void)
+{
+ metrics_counter_start (current_context->metrics);
+}
+
+void
+context_counter_stop (void)
+{
+ metrics_counter_stop (current_context->metrics);
+}
+
+void
+context_set_current_op (metrics_op_t op)
+{
+ metrics_set_current_op (current_context->metrics, op);
+}
+
+metrics_op_t
+context_get_current_op (void)
+{
+ return metrics_get_current_op (current_context->metrics);
+}
+
+void
+context_end_frame (void)
+{
+ return metrics_end_frame (current_context->metrics);
+}
+
+/* Is the given extension available? */
+static bool
+check_extension (const char *extension)
+{
+ 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;
}