diff --git a/src/platform/opengl/gles2.c b/src/platform/opengl/gles2.c
index 168858241..82215cce4 100644
--- a/src/platform/opengl/gles2.c
+++ b/src/platform/opengl/gles2.c
@@ -134,15 +134,17 @@ static void mGLES2ContextInit(struct VideoBackend* v, WHandle handle) {
 	mGLES2ShaderInit(&context->initialShader, _vertexShader, _fragmentShader, -1, -1, false, uniforms, 4);
 	mGLES2ShaderInit(&context->finalShader, 0, 0, 0, 0, false, 0, 0);
 
-	glBindVertexArray(context->initialShader.vao);
-	glBindBuffer(GL_ARRAY_BUFFER, context->vbo);
-	glEnableVertexAttribArray(context->initialShader.positionLocation);
-	glVertexAttribPointer(context->initialShader.positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL);
-	glBindVertexArray(context->finalShader.vao);
-	glBindBuffer(GL_ARRAY_BUFFER, context->vbo);
-	glEnableVertexAttribArray(context->finalShader.positionLocation);
-	glVertexAttribPointer(context->finalShader.positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL);
-	glBindVertexArray(0);
+	if (context->initialShader.vao != (GLuint) -1) {
+		glBindVertexArray(context->initialShader.vao);
+		glBindBuffer(GL_ARRAY_BUFFER, context->vbo);
+		glEnableVertexAttribArray(context->initialShader.positionLocation);
+		glVertexAttribPointer(context->initialShader.positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL);
+		glBindVertexArray(context->finalShader.vao);
+		glBindBuffer(GL_ARRAY_BUFFER, context->vbo);
+		glEnableVertexAttribArray(context->finalShader.positionLocation);
+		glVertexAttribPointer(context->finalShader.positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL);
+		glBindVertexArray(0);
+	}
 
 	glDeleteFramebuffers(1, &context->finalShader.fbo);
 	glDeleteTextures(1, &context->finalShader.tex);
@@ -253,7 +255,13 @@ void _drawShader(struct mGLES2Context* context, struct mGLES2Shader* shader) {
 	glUseProgram(shader->program);
 	glUniform1i(shader->texLocation, 0);
 	glUniform2f(shader->texSizeLocation, context->d.width - padW, context->d.height - padH);
-	glBindVertexArray(shader->vao);
+	if (shader->vao != (GLuint) -1) {
+		glBindVertexArray(shader->vao);
+	} else {
+		glBindBuffer(GL_ARRAY_BUFFER, context->vbo);
+		glEnableVertexAttribArray(shader->positionLocation);
+		glVertexAttribPointer(shader->positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL);
+	}
 	size_t u;
 	for (u = 0; u < shader->nUniforms; ++u) {
 		struct mGLES2Uniform* uniform = &shader->uniforms[u];
@@ -328,7 +336,9 @@ void mGLES2ContextDrawFrame(struct VideoBackend* v) {
 	_drawShader(context, &context->finalShader);
 	glBindFramebuffer(GL_FRAMEBUFFER, 0);
 	glUseProgram(0);
-	glBindVertexArray(0);
+	if (context->finalShader.vao != (GLuint) -1) {
+		glBindVertexArray(0);
+	}
 }
 
 void mGLES2ContextPostFrame(struct VideoBackend* v, const void* frame) {
@@ -435,7 +445,12 @@ void mGLES2ShaderInit(struct mGLES2Shader* shader, const char* vs, const char* f
 		shader->uniforms[i].location = glGetUniformLocation(shader->program, shader->uniforms[i].name);
 	}
 
-	glGenVertexArrays(1, &shader->vao);
+	const GLubyte* extensions = glGetString(GL_EXTENSIONS);
+	if (shaderBuffer[0] == _gles2Header || version[0] == '3' || strstr((const char*) extensions, "_vertex_array_object") != NULL) {
+		glGenVertexArrays(1, &shader->vao);
+	} else {
+		shader->vao = -1;
+	}
 
 	glBindFramebuffer(GL_FRAMEBUFFER, 0);
 }
@@ -445,7 +460,9 @@ void mGLES2ShaderDeinit(struct mGLES2Shader* shader) {
 	glDeleteShader(shader->fragmentShader);
 	glDeleteProgram(shader->program);
 	glDeleteFramebuffers(1, &shader->fbo);
-	glDeleteVertexArrays(1, &shader->vao);
+	if (shader->vao != (GLuint) -1) {
+		glDeleteVertexArrays(1, &shader->vao);
+	}
 }
 
 void mGLES2ShaderAttach(struct mGLES2Context* context, struct mGLES2Shader* shaders, size_t nShaders) {
@@ -463,12 +480,16 @@ void mGLES2ShaderAttach(struct mGLES2Context* context, struct mGLES2Shader* shad
 		glClearColor(0.f, 0.f, 0.f, 1.f);
 		glClear(GL_COLOR_BUFFER_BIT);
 
-		glBindVertexArray(context->shaders[i].vao);
-		glBindBuffer(GL_ARRAY_BUFFER, context->vbo);
-		glEnableVertexAttribArray(context->shaders[i].positionLocation);
-		glVertexAttribPointer(context->shaders[i].positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL);
+		if (context->shaders[i].vao != (GLuint) -1) {
+			glBindVertexArray(context->shaders[i].vao);
+			glBindBuffer(GL_ARRAY_BUFFER, context->vbo);
+			glEnableVertexAttribArray(context->shaders[i].positionLocation);
+			glVertexAttribPointer(context->shaders[i].positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL);
+		}
+	}
+	if (context->initialShader.vao != (GLuint) -1) {
+		glBindVertexArray(0);
 	}
-	glBindVertexArray(0);
 	glBindFramebuffer(GL_FRAMEBUFFER, 0);
 }
 
diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp
index 12da1bdb1..135e591f8 100644
--- a/src/platform/qt/DisplayGL.cpp
+++ b/src/platform/qt/DisplayGL.cpp
@@ -47,11 +47,11 @@ DisplayGL::DisplayGL(const QSurfaceFormat& format, QWidget* parent)
 #if defined(_WIN32) && defined(USE_EPOXY)
 	epoxy_handle_external_wglMakeCurrent();
 #endif
-	int majorVersion = m_gl->format().majorVersion();
+	auto version = m_gl->format().version();
 	QStringList extensions = QString(reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))).split(' ');
 	m_gl->doneCurrent();
 
-	if (majorVersion == 2 && !extensions.contains("GL_ARB_framebuffer_object")) {
+	if ((version == qMakePair(2, 1) && !extensions.contains("GL_ARB_framebuffer_object")) || version == qMakePair(2, 0)) {
 		QSurfaceFormat newFormat(format);
 		newFormat.setVersion(1, 4);
 		m_gl->setFormat(newFormat);
@@ -238,12 +238,11 @@ PainterGL::PainterGL(VideoProxy* proxy, QWindow* surface, QOpenGLContext* parent
 #if defined(_WIN32) && defined(USE_EPOXY)
 	epoxy_handle_external_wglMakeCurrent();
 #endif
-	int majorVersion = m_gl->format().majorVersion();
-
-	QStringList extensions = QString(reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))).split(' ');
 
 #ifdef BUILD_GLES2
-	if ((majorVersion == 2 && extensions.contains("GL_ARB_framebuffer_object")) || majorVersion > 2) {
+	auto version = m_gl->format().version();
+	QStringList extensions = QString(reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))).split(' ');
+	if ((version == qMakePair(2, 1) && extensions.contains("GL_ARB_framebuffer_object")) || version.first > 2) {
 		gl2Backend = static_cast<mGLES2Context*>(malloc(sizeof(mGLES2Context)));
 		mGLES2ContextCreate(gl2Backend);
 		m_backend = &gl2Backend->d;