diff --git a/src/cairo-gl-dispatch-private.h b/src/cairo-gl-dispatch-private.h
index 0795e70..751913c 100644
--- a/src/cairo-gl-dispatch-private.h
+++ b/src/cairo-gl-dispatch-private.h
@@ -35,26 +35,34 @@
 #include "cairo-gl-private.h"
 #include <stddef.h>
 
+typedef enum _cairo_gl_dispatch_name {
+    CAIRO_GL_DISPATCH_NAME_CORE,
+    CAIRO_GL_DISPATCH_NAME_EXT,
+    CAIRO_GL_DISPATCH_NAME_ES,
+    CAIRO_GL_DISPATCH_NAME_COUNT
+} cairo_gl_dispatch_name_t;
+
 typedef struct _cairo_gl_dispatch_entry {
-    const char *name_core;
-    const char *name_ext;
+    const char *name[CAIRO_GL_DISPATCH_NAME_COUNT];
     size_t offset;
 } cairo_gl_dispatch_entry_t;
 
-#define DISPATCH_ENTRY_ARB(name) { "gl"#name, "gl"#name"ARB", \
+#define DISPATCH_ENTRY_ARB(name) { { "gl"#name, "gl"#name"ARB", "gl"#name }, \
 				   offsetof(cairo_gl_dispatch_t, name) }
-#define DISPATCH_ENTRY_EXT(name) { "gl"#name, "gl"#name"EXT", \
+#define DISPATCH_ENTRY_EXT(name) { { "gl"#name, "gl"#name"EXT", "gl"#name }, \
 				   offsetof(cairo_gl_dispatch_t, name) }
-#define DISPATCH_ENTRY_CUSTOM(name, name2) { "gl"#name, "gl"#name2, \
+#define DISPATCH_ENTRY_ARB_OES(name) { { "gl"#name, "gl"#name"ARB", "gl"#name"OES" }, \
+				       offsetof(cairo_gl_dispatch_t, name) }
+#define DISPATCH_ENTRY_CUSTOM(name, name2) { { "gl"#name, "gl"#name2, "gl"#name }, \
 			                     offsetof(cairo_gl_dispatch_t, name)}
-#define DISPATCH_ENTRY_LAST { NULL, NULL, 0 }
+#define DISPATCH_ENTRY_LAST { { NULL, NULL, NULL }, 0 }
 
 cairo_private cairo_gl_dispatch_entry_t dispatch_buffers_entries[] = {
-    DISPATCH_ENTRY_ARB (GenBuffers),
-    DISPATCH_ENTRY_ARB (BindBuffer),
-    DISPATCH_ENTRY_ARB (BufferData),
-    DISPATCH_ENTRY_ARB (MapBuffer),
-    DISPATCH_ENTRY_ARB (UnmapBuffer),
+    DISPATCH_ENTRY_ARB     (GenBuffers),
+    DISPATCH_ENTRY_ARB     (BindBuffer),
+    DISPATCH_ENTRY_ARB     (BufferData),
+    DISPATCH_ENTRY_ARB_OES (MapBuffer),
+    DISPATCH_ENTRY_ARB_OES (UnmapBuffer),
     DISPATCH_ENTRY_LAST
 };
 
diff --git a/src/cairo-gl-dispatch.c b/src/cairo-gl-dispatch.c
index 0f64731..6277f53 100644
--- a/src/cairo-gl-dispatch.c
+++ b/src/cairo-gl-dispatch.c
@@ -37,14 +37,13 @@ static void
 _cairo_gl_dispatch_init_entries (cairo_gl_dispatch_t *dispatch,
 				 cairo_gl_get_proc_addr_func_t get_proc_addr,
 				 cairo_gl_dispatch_entry_t *entries,
-				 cairo_bool_t use_ext)
+				 cairo_gl_dispatch_name_t dispatch_name)
 {
     cairo_gl_dispatch_entry_t *entry = entries;
 
-    while (entry->name_core != NULL) {
+    while (entry->name[CAIRO_GL_DISPATCH_NAME_CORE] != NULL) {
 	void *dispatch_ptr = &((char *) dispatch)[entry->offset];
-	const char *name = use_ext ? entry->name_ext :
-				     entry->name_core;
+	const char *name = entry->name[dispatch_name];
 
 	cairo_gl_generic_func_t func = get_proc_addr (name);
 
@@ -58,19 +57,32 @@ _cairo_gl_dispatch_init_entries (cairo_gl_dispatch_t *dispatch,
 static cairo_status_t
 _cairo_gl_dispatch_init_buffers (cairo_gl_dispatch_t *dispatch,
 				 cairo_gl_get_proc_addr_func_t get_proc_addr,
-				 int gl_version)
+				 int gl_version, cairo_gl_flavor_t gl_flavor)
 {
-    cairo_bool_t use_ext;
-
-    if (gl_version >= CAIRO_GL_VERSION_ENCODE (1, 5))
-	use_ext = 0;
-    else if (_cairo_gl_has_extension ("GL_ARB_vertex_buffer_object"))
-	use_ext = 1;
+    cairo_gl_dispatch_name_t dispatch_name;
+
+    if (gl_flavor == CAIRO_GL_FLAVOR_DESKTOP)
+    {
+	if (gl_version >= CAIRO_GL_VERSION_ENCODE (1, 5))
+	    dispatch_name = CAIRO_GL_DISPATCH_NAME_CORE;
+	else if (_cairo_gl_has_extension ("GL_ARB_vertex_buffer_object"))
+	    dispatch_name = CAIRO_GL_DISPATCH_NAME_EXT;
+	else
+	    return CAIRO_STATUS_DEVICE_ERROR;
+    }
+    else if (gl_flavor == CAIRO_GL_FLAVOR_ES &&
+	     gl_version >= CAIRO_GL_VERSION_ENCODE (2, 0) &&
+	     _cairo_gl_has_extension ("GL_OES_mapbuffer"))
+    {
+	dispatch_name = CAIRO_GL_DISPATCH_NAME_ES;
+    }
     else
+    {
 	return CAIRO_STATUS_DEVICE_ERROR;
+    }
 
     _cairo_gl_dispatch_init_entries (dispatch, get_proc_addr,
-				     dispatch_buffers_entries, use_ext);
+				     dispatch_buffers_entries, dispatch_name);
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -78,20 +90,31 @@ _cairo_gl_dispatch_init_buffers (cairo_gl_dispatch_t *dispatch,
 static cairo_status_t
 _cairo_gl_dispatch_init_shaders (cairo_gl_dispatch_t *dispatch,
 				 cairo_gl_get_proc_addr_func_t get_proc_addr,
-				 int gl_version)
+				 int gl_version, cairo_gl_flavor_t gl_flavor)
 {
-    cairo_bool_t use_ext;
-
-    /* Note: shader support is not necessary at the moment */
-    if (gl_version >= CAIRO_GL_VERSION_ENCODE (2, 0))
-	use_ext = 0;
-    else if (_cairo_gl_has_extension ("GL_ARB_shader_objects"))
-	use_ext = 1;
+    cairo_gl_dispatch_name_t dispatch_name;
+
+    if (gl_flavor == CAIRO_GL_FLAVOR_DESKTOP)
+    {
+	if (gl_version >= CAIRO_GL_VERSION_ENCODE (2, 0))
+	    dispatch_name = CAIRO_GL_DISPATCH_NAME_CORE;
+	else if (_cairo_gl_has_extension ("GL_ARB_shader_objects"))
+	    dispatch_name = CAIRO_GL_DISPATCH_NAME_EXT;
+	else
+	    return CAIRO_STATUS_DEVICE_ERROR;
+    }
+    else if (gl_flavor == CAIRO_GL_FLAVOR_ES &&
+	     gl_version >= CAIRO_GL_VERSION_ENCODE (2, 0))
+    {
+	dispatch_name = CAIRO_GL_DISPATCH_NAME_ES;
+    }
     else
-	return CAIRO_STATUS_SUCCESS;
+    {
+	return CAIRO_STATUS_DEVICE_ERROR;
+    }
 
     _cairo_gl_dispatch_init_entries (dispatch, get_proc_addr,
-				     dispatch_shaders_entries, use_ext);
+				     dispatch_shaders_entries, dispatch_name);
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -99,20 +122,32 @@ _cairo_gl_dispatch_init_shaders (cairo_gl_dispatch_t *dispatch,
 static cairo_status_t
 _cairo_gl_dispatch_init_fbo (cairo_gl_dispatch_t *dispatch,
 			     cairo_gl_get_proc_addr_func_t get_proc_addr,
-			     int gl_version)
+			     int gl_version, cairo_gl_flavor_t gl_flavor)
 {
-    cairo_bool_t use_ext;
-
-    if (gl_version >= CAIRO_GL_VERSION_ENCODE (3, 0) ||
-	_cairo_gl_has_extension ("GL_ARB_framebuffer_object"))
-	use_ext = 0;
-    else if (_cairo_gl_has_extension ("GL_EXT_framebuffer_object"))
-	use_ext = 1;
+    cairo_gl_dispatch_name_t dispatch_name;
+
+    if (gl_flavor == CAIRO_GL_FLAVOR_DESKTOP)
+    {
+	if (gl_version >= CAIRO_GL_VERSION_ENCODE (3, 0) ||
+	    _cairo_gl_has_extension ("GL_ARB_framebuffer_object"))
+	    dispatch_name = CAIRO_GL_DISPATCH_NAME_CORE;
+	else if (_cairo_gl_has_extension ("GL_EXT_framebuffer_object"))
+	    dispatch_name = CAIRO_GL_DISPATCH_NAME_EXT;
+	else
+	    return CAIRO_STATUS_DEVICE_ERROR;
+    }
+    else if (gl_flavor == CAIRO_GL_FLAVOR_ES &&
+	     gl_version >= CAIRO_GL_VERSION_ENCODE (2, 0))
+    {
+	dispatch_name = CAIRO_GL_DISPATCH_NAME_ES;
+    }
     else
+    {
 	return CAIRO_STATUS_DEVICE_ERROR;
+    }
 
     _cairo_gl_dispatch_init_entries (dispatch, get_proc_addr,
-				     dispatch_fbo_entries, use_ext);
+				     dispatch_fbo_entries, dispatch_name);
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -123,21 +158,23 @@ _cairo_gl_dispatch_init (cairo_gl_dispatch_t *dispatch,
 {
     cairo_status_t status;
     int gl_version;
+    cairo_gl_flavor_t gl_flavor;
 
     gl_version = _cairo_gl_get_version ();
+    gl_flavor = _cairo_gl_get_flavor ();
 
     status = _cairo_gl_dispatch_init_buffers (dispatch, get_proc_addr,
-					      gl_version);
+					      gl_version, gl_flavor);
     if (status != CAIRO_STATUS_SUCCESS)
 	return status;
 
     status = _cairo_gl_dispatch_init_shaders (dispatch, get_proc_addr,
-					      gl_version);
+					      gl_version, gl_flavor);
     if (status != CAIRO_STATUS_SUCCESS)
 	return status;
 
     status = _cairo_gl_dispatch_init_fbo (dispatch, get_proc_addr,
-					  gl_version);
+					  gl_version, gl_flavor);
     if (status != CAIRO_STATUS_SUCCESS)
 	return status;
 
