diff --git a/cogl/cogl/cogl-context.c b/cogl/cogl/cogl-context.c
index 50b4b68ae..bc92ec38e 100644
--- a/cogl/cogl/cogl-context.c
+++ b/cogl/cogl/cogl-context.c
@@ -593,3 +593,9 @@ cogl_get_graphics_reset_status (CoglContext *context)
       return COGL_GRAPHICS_RESET_STATUS_NO_ERROR;
     }
 }
+
+gboolean
+cogl_context_is_hardware_accelerated (CoglContext *context)
+{
+  return context->driver_vtable->is_hardware_accelerated (context);
+}
diff --git a/cogl/cogl/cogl-context.h b/cogl/cogl/cogl-context.h
index 2807f2a5a..e0d79d927 100644
--- a/cogl/cogl/cogl-context.h
+++ b/cogl/cogl/cogl-context.h
@@ -357,6 +357,16 @@ typedef enum _CoglGraphicsResetStatus
 COGL_EXPORT CoglGraphicsResetStatus
 cogl_get_graphics_reset_status (CoglContext *context);
 
+/**
+ * cogl_context_is_hardware_accelerated:
+ * @context: a #CoglContext pointer
+ *
+ * Returns: %TRUE if the @context is hardware accelerated, or %FALSE if
+ * not.
+ */
+COGL_EXPORT gboolean
+cogl_context_is_hardware_accelerated (CoglContext *context);
+
 G_END_DECLS
 
 #endif /* __COGL_CONTEXT_H__ */
diff --git a/cogl/cogl/cogl-driver.h b/cogl/cogl/cogl-driver.h
index 5dcecf862..e52a99cfb 100644
--- a/cogl/cogl/cogl-driver.h
+++ b/cogl/cogl/cogl-driver.h
@@ -46,6 +46,9 @@ struct _CoglDriverVtable
   void
   (* context_deinit) (CoglContext *context);
 
+  gboolean
+  (* is_hardware_accelerated) (CoglContext *context);
+
   /* TODO: factor this out since this is OpenGL specific and
    * so can be ignored by non-OpenGL drivers. */
   gboolean
diff --git a/cogl/cogl/driver/gl/cogl-util-gl-private.h b/cogl/cogl/driver/gl/cogl-util-gl-private.h
index 52279be67..c434ebde0 100644
--- a/cogl/cogl/driver/gl/cogl-util-gl-private.h
+++ b/cogl/cogl/driver/gl/cogl-util-gl-private.h
@@ -91,6 +91,9 @@ _cogl_gl_util_clear_gl_errors (CoglContext *ctx);
 gboolean
 _cogl_gl_util_catch_out_of_memory (CoglContext *ctx, GError **error);
 
+gboolean
+_cogl_driver_gl_is_hardware_accelerated (CoglContext *context);
+
 /* Parses a GL version number stored in a string. @version_string must
  * point to the beginning of the version number (ie, it can't point to
  * the "OpenGL ES" part on GLES). The version number can be followed
diff --git a/cogl/cogl/driver/gl/cogl-util-gl.c b/cogl/cogl/driver/gl/cogl-util-gl.c
index 34488c7d8..d21ee0124 100644
--- a/cogl/cogl/driver/gl/cogl-util-gl.c
+++ b/cogl/cogl/driver/gl/cogl-util-gl.c
@@ -179,3 +179,28 @@ _cogl_gl_util_parse_gl_version (const char *version_string,
 
   return TRUE;
 }
+
+/*
+ * This should arguably use something like GLX_MESA_query_renderer, but
+ * a) that's GLX-only, and you could add it to EGL too but
+ * b) that'd make this a winsys query when really it's not a property of
+ *    the winsys but the renderer, and
+ * c) only Mesa really supports it anyway, and
+ * d) Mesa is the only software renderer of interest.
+ *
+ * So instead just check a list of known software renderer strings.
+ */
+gboolean
+_cogl_driver_gl_is_hardware_accelerated (CoglContext *ctx)
+{
+  const char *renderer = (const char *) ctx->glGetString (GL_RENDERER);
+  gboolean software;
+
+  software = strstr (renderer, "llvmpipe") != NULL ||
+             strstr (renderer, "softpipe") != NULL ||
+             strstr (renderer, "software rasterizer") != NULL ||
+             strstr (renderer, "Software Rasterizer") != NULL ||
+             strstr (renderer, "SWR");
+
+  return !software;
+}
diff --git a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c
index 220c581e9..29492b04c 100644
--- a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c
+++ b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c
@@ -532,6 +532,7 @@ _cogl_driver_gl =
   {
     _cogl_driver_gl_real_context_init,
     _cogl_driver_gl_context_deinit,
+    _cogl_driver_gl_is_hardware_accelerated,
     _cogl_driver_pixel_format_from_gl_internal,
     _cogl_driver_pixel_format_to_gl,
     _cogl_driver_update_features,
diff --git a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c
index daaaec44f..04e35c56a 100644
--- a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c
+++ b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c
@@ -396,6 +396,7 @@ _cogl_driver_gles =
   {
     _cogl_driver_gl_context_init,
     _cogl_driver_gl_context_deinit,
+    _cogl_driver_gl_is_hardware_accelerated,
     _cogl_driver_pixel_format_from_gl_internal,
     _cogl_driver_pixel_format_to_gl,
     _cogl_driver_update_features,
diff --git a/cogl/cogl/driver/nop/cogl-driver-nop.c b/cogl/cogl/driver/nop/cogl-driver-nop.c
index 3594a966b..664c653db 100644
--- a/cogl/cogl/driver/nop/cogl-driver-nop.c
+++ b/cogl/cogl/driver/nop/cogl-driver-nop.c
@@ -63,11 +63,18 @@ _cogl_driver_nop_context_deinit (CoglContext *context)
 {
 }
 
+static gboolean
+_cogl_driver_nop_is_hardware_accelerated (CoglContext *context)
+{
+  return FALSE;
+}
+
 const CoglDriverVtable
 _cogl_driver_nop =
   {
     _cogl_driver_nop_context_init,
     _cogl_driver_nop_context_deinit,
+    _cogl_driver_nop_is_hardware_accelerated,
     NULL, /* pixel_format_from_gl_internal */
     NULL, /* pixel_format_to_gl */
     _cogl_driver_update_features,
diff --git a/src/backends/meta-renderer.c b/src/backends/meta-renderer.c
index 983a570e1..b5cc37efb 100644
--- a/src/backends/meta-renderer.c
+++ b/src/backends/meta-renderer.c
@@ -194,23 +194,8 @@ meta_renderer_is_hardware_accelerated (MetaRenderer *renderer)
   ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
   CoglContext *cogl_context =
     clutter_backend_get_cogl_context (clutter_backend);
-  CoglGpuInfo *info = &cogl_context->gpu;
 
-  switch (info->architecture)
-    {
-    case COGL_GPU_INFO_ARCHITECTURE_UNKNOWN:
-    case COGL_GPU_INFO_ARCHITECTURE_SANDYBRIDGE:
-    case COGL_GPU_INFO_ARCHITECTURE_SGX:
-    case COGL_GPU_INFO_ARCHITECTURE_MALI:
-      return TRUE;
-    case COGL_GPU_INFO_ARCHITECTURE_LLVMPIPE:
-    case COGL_GPU_INFO_ARCHITECTURE_SOFTPIPE:
-    case COGL_GPU_INFO_ARCHITECTURE_SWRAST:
-      return FALSE;
-    }
-
-  g_assert_not_reached ();
-  return FALSE;
+  return cogl_context_is_hardware_accelerated (cogl_context);
 }
 
 static void