Add null egl/gles stub support

Change-Id: I41372585202f69ef31a4ef95efc75fb7a1ff7289
diff --git a/libs/hwui/Android.common.mk b/libs/hwui/Android.common.mk
index 5dacbb5..ecb625b 100644
--- a/libs/hwui/Android.common.mk
+++ b/libs/hwui/Android.common.mk
@@ -104,6 +104,14 @@
     LOCAL_CFLAGS += -fno-omit-frame-pointer -marm -mapcs
 endif
 
+ifeq (true, $(HWUI_NULL_GPU))
+    LOCAL_SRC_FILES += \
+        tests/nullegl.cpp \
+        tests/nullgles.cpp
+
+    LOCAL_CFLAGS += -DHWUI_NULL_GPU
+endif
+
 # Defaults for ATRACE_TAG and LOG_TAG for libhwui
 LOCAL_CFLAGS += -DATRACE_TAG=ATRACE_TAG_VIEW -DLOG_TAG=\"OpenGLRenderer\"
 
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index f4fc068..7ab7a6a 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -107,14 +107,6 @@
         startMark = startMarkNull;
         endMark = endMarkNull;
     }
-
-    if (mExtensions.hasDebugLabel() && (drawDeferDisabled || drawReorderDisabled)) {
-        setLabel = glLabelObjectEXT;
-        getLabel = glGetObjectLabelEXT;
-    } else {
-        setLabel = setLabelNull;
-        getLabel = getLabelNull;
-    }
 }
 
 void Caches::initConstraints() {
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 18bb5e6..5563937 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -207,9 +207,6 @@
     PFNGLPUSHGROUPMARKEREXTPROC startMark;
     PFNGLPOPGROUPMARKEREXTPROC endMark;
 
-    PFNGLLABELOBJECTEXTPROC setLabel;
-    PFNGLGETOBJECTLABELEXTPROC getLabel;
-
     // TEMPORARY properties
     void initTempProperties();
     void setTempProperty(const char* name, const char* value);
@@ -244,14 +241,6 @@
     static void startMarkNull(GLsizei length, const GLchar* marker) { }
     static void endMarkNull() { }
 
-    static void setLabelNull(GLenum type, uint object, GLsizei length,
-            const char* label) { }
-    static void getLabelNull(GLenum type, uint object, GLsizei bufferSize,
-            GLsizei* length, char* label) {
-        if (length) *length = 0;
-        if (label) *label = '\0';
-    }
-
     RenderState* mRenderState;
 
     // Used to render layers
diff --git a/libs/hwui/Extensions.cpp b/libs/hwui/Extensions.cpp
index c68822b..2a82216 100644
--- a/libs/hwui/Extensions.cpp
+++ b/libs/hwui/Extensions.cpp
@@ -55,7 +55,6 @@
     mHasFramebufferFetch = hasGlExtension("GL_NV_shader_framebuffer_fetch");
     mHasDiscardFramebuffer = hasGlExtension("GL_EXT_discard_framebuffer");
     mHasDebugMarker = hasGlExtension("GL_EXT_debug_marker");
-    mHasDebugLabel = hasGlExtension("GL_EXT_debug_label");
     mHasTiledRendering = hasGlExtension("GL_QCOM_tiled_rendering");
     mHas1BitStencil = hasGlExtension("GL_OES_stencil1");
     mHas4BitStencil = hasGlExtension("GL_OES_stencil4");
diff --git a/libs/hwui/Extensions.h b/libs/hwui/Extensions.h
index 731001a..e7d317d 100644
--- a/libs/hwui/Extensions.h
+++ b/libs/hwui/Extensions.h
@@ -40,7 +40,6 @@
     inline bool hasFramebufferFetch() const { return mHasFramebufferFetch; }
     inline bool hasDiscardFramebuffer() const { return mHasDiscardFramebuffer; }
     inline bool hasDebugMarker() const { return mHasDebugMarker; }
-    inline bool hasDebugLabel() const { return mHasDebugLabel; }
     inline bool hasTiledRendering() const { return mHasTiledRendering; }
     inline bool has1BitStencil() const { return mHas1BitStencil; }
     inline bool has4BitStencil() const { return mHas4BitStencil; }
@@ -68,7 +67,6 @@
     bool mHasFramebufferFetch;
     bool mHasDiscardFramebuffer;
     bool mHasDebugMarker;
-    bool mHasDebugLabel;
     bool mHasTiledRendering;
     bool mHas1BitStencil;
     bool mHas4BitStencil;
diff --git a/libs/hwui/tests/Android.mk b/libs/hwui/tests/Android.mk
index a69f3fb..51898d2 100644
--- a/libs/hwui/tests/Android.mk
+++ b/libs/hwui/tests/Android.mk
@@ -25,6 +25,8 @@
 LOCAL_MODULE_STEM_32 := hwuitest
 LOCAL_MODULE_STEM_64 := hwuitest64
 
+HWUI_NULL_GPU := false
+
 include $(LOCAL_PATH)/Android.common.mk
 
 LOCAL_SRC_FILES += \
diff --git a/libs/hwui/tests/main.cpp b/libs/hwui/tests/main.cpp
index 0431e22..bffbbef 100644
--- a/libs/hwui/tests/main.cpp
+++ b/libs/hwui/tests/main.cpp
@@ -95,16 +95,16 @@
         animation.createContent(width, height, renderer);
         endRecording(renderer, rootNode);
 
-        for (int i = 0; i < 150; i++) {
+        for (int i = 0; i < animation.getFrameCount(); i++) {
+#if !HWUI_NULL_GPU
             testContext.waitForVsync();
+#endif
 
             ATRACE_NAME("UI-Draw Frame");
             animation.doFrame(i);
             proxy->syncAndDrawFrame();
         }
 
-        sleep(5);
-
         rootNode->decStrong(nullptr);
     }
 };
diff --git a/libs/hwui/tests/nullegl.cpp b/libs/hwui/tests/nullegl.cpp
new file mode 100644
index 0000000..b6cc2f2
--- /dev/null
+++ b/libs/hwui/tests/nullegl.cpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+
+static EGLDisplay gDisplay = (EGLDisplay) 1;
+
+typedef struct {
+    EGLSurface surface;
+    EGLContext context;
+} ThreadState;
+
+static pthread_key_t ThreadStateKey;
+static pthread_once_t ThreadStateSetupOnce = PTHREAD_ONCE_INIT;
+
+static void destroyThreadState(void* state) {
+    free(state);
+}
+
+static void makeThreadState() {
+    pthread_key_create(&ThreadStateKey, destroyThreadState);
+}
+
+ThreadState* getThreadState() {
+    ThreadState* ptr;
+    pthread_once(&ThreadStateSetupOnce, makeThreadState);
+    if ((ptr = (ThreadState*) pthread_getspecific(ThreadStateKey)) == NULL) {
+        ptr = (ThreadState*) calloc(1, sizeof(ThreadState));
+        ptr->context = EGL_NO_CONTEXT;
+        ptr->surface = EGL_NO_SURFACE;
+        pthread_setspecific(ThreadStateKey, ptr);
+    }
+    return ptr;
+}
+
+EGLint eglGetError(void) {
+    return EGL_SUCCESS;
+}
+
+EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id) {
+    return gDisplay;
+}
+
+EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) {
+    return EGL_TRUE;
+}
+
+EGLBoolean eglTerminate(EGLDisplay dpy) {
+    return EGL_TRUE;
+}
+
+const char * eglQueryString(EGLDisplay dpy, EGLint name) {
+    return "";
+}
+
+EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
+               EGLConfig *configs, EGLint config_size,
+               EGLint *num_config) {
+    memset(configs, 9, sizeof(EGLConfig) * config_size);
+    *num_config = config_size;
+    return EGL_TRUE;
+}
+
+EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
+                  EGLNativeWindowType win,
+                  const EGLint *attrib_list) {
+    return (EGLSurface) malloc(sizeof(void*));
+}
+
+EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
+                   const EGLint *attrib_list) {
+    return (EGLSurface) malloc(sizeof(void*));
+}
+
+EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface) {
+    free(surface);
+    return EGL_TRUE;
+}
+
+EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
+               EGLint attribute, EGLint *value) {
+    *value = 1000;
+    return EGL_TRUE;
+}
+
+EGLBoolean eglReleaseThread(void) {
+    return EGL_TRUE;
+}
+
+EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
+                EGLint attribute, EGLint value) {
+    return EGL_TRUE;
+}
+
+EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) {
+    return EGL_TRUE;
+}
+
+EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
+                EGLContext share_context,
+                const EGLint *attrib_list) {
+    return (EGLContext) malloc(sizeof(void*));
+}
+EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) {
+    free(ctx);
+    return EGL_TRUE;
+}
+
+EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw,
+              EGLSurface read, EGLContext ctx) {
+    ThreadState* state = getThreadState();
+    state->surface = draw;
+    state->context = ctx;
+    return EGL_TRUE;
+}
+
+EGLContext eglGetCurrentContext(void) {
+    return getThreadState()->context;
+}
+
+EGLSurface eglGetCurrentSurface(EGLint readdraw) {
+    return getThreadState()->surface;
+}
+
+EGLDisplay eglGetCurrentDisplay(void) {
+    return gDisplay;
+}
+
+EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) {
+    return EGL_TRUE;
+}
+
+EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list) {
+    return (EGLImageKHR) malloc(sizeof(EGLImageKHR));
+}
+
+EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) {
+    free(image);
+    return EGL_TRUE;
+}
+
+void eglBeginFrame(EGLDisplay dpy, EGLSurface surface) {}
diff --git a/libs/hwui/tests/nullgles.cpp b/libs/hwui/tests/nullgles.cpp
new file mode 100644
index 0000000..8ca7598
--- /dev/null
+++ b/libs/hwui/tests/nullgles.cpp
@@ -0,0 +1,275 @@
+/*
+ * Copyright(C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0(the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <GLES3/gl3.h>
+#include <GLES2/gl2ext.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+struct {
+    GLboolean scissorEnabled;
+} gState;
+
+void glGenCommon(GLsizei n, GLuint *buffers) {
+    static GLuint nextId = 0;
+    int i;
+    for(i = 0; i < n; i++) {
+        buffers[i] = ++nextId;
+    }
+}
+
+void glGenBuffers(GLsizei n, GLuint *buffers) {
+    glGenCommon(n, buffers);
+}
+
+void glGenFramebuffers(GLsizei n, GLuint *framebuffers) {
+    glGenCommon(n, framebuffers);
+}
+
+void glGenRenderbuffers(GLsizei n, GLuint *renderbuffers) {
+    glGenCommon(n, renderbuffers);
+}
+
+void glGenTextures(GLsizei n, GLuint *textures) {
+    glGenCommon(n, textures);
+}
+
+GLuint glCreateProgram(void) {
+    static GLuint nextProgram = 0;
+    return ++nextProgram;
+}
+
+GLuint glCreateShader(GLenum type) {
+    static GLuint nextShader = 0;
+    return ++nextShader;
+}
+
+void glGetProgramiv(GLuint program, GLenum pname, GLint *params) {
+    switch (pname) {
+    case GL_DELETE_STATUS:
+    case GL_LINK_STATUS:
+    case GL_VALIDATE_STATUS:
+        *params = GL_TRUE;
+        break;
+    case GL_INFO_LOG_LENGTH:
+        *params = 16;
+        break;
+    }
+}
+
+void glGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog) {
+    *length = snprintf(infoLog, bufSize, "success");
+    if (*length >= bufSize) {
+        *length = bufSize - 1;
+    }
+}
+
+void glGetShaderiv(GLuint shader, GLenum pname, GLint *params) {
+    switch (pname) {
+    case GL_COMPILE_STATUS:
+    case GL_DELETE_STATUS:
+        *params = GL_TRUE;
+    }
+}
+
+void glGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog) {
+    *length = snprintf(infoLog, bufSize, "success");
+    if (*length >= bufSize) {
+        *length = bufSize - 1;
+    }
+}
+
+void setBooleanState(GLenum cap, GLboolean value) {
+    switch (cap) {
+    case GL_SCISSOR_TEST:
+        gState.scissorEnabled = value;
+        break;
+    }
+}
+
+void glEnable(GLenum cap) {
+    setBooleanState(cap, GL_TRUE);
+}
+
+void glDisable(GLenum cap) {
+    setBooleanState(cap, GL_FALSE);
+}
+
+GLboolean glIsEnabled(GLenum cap) {
+    switch (cap) {
+    case GL_SCISSOR_TEST:
+        return gState.scissorEnabled;
+    default:
+        return GL_FALSE;
+    }
+}
+
+void glGetIntegerv(GLenum pname, GLint *data) {
+    switch (pname) {
+    case GL_MAX_TEXTURE_SIZE:
+        *data = 2048;
+        break;
+    case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
+        *data = 4;
+        break;
+    default:
+        *data = 0;
+    }
+}
+
+const char* getString(GLenum name) {
+    switch (name) {
+    case GL_VENDOR:
+        return "android";
+    case GL_RENDERER:
+        return "null";
+    case GL_VERSION:
+        return "OpenGL ES 2.0 rev1";
+    case GL_SHADING_LANGUAGE_VERSION:
+        return "OpenGL ES GLSL ES 2.0 rev1";
+    case GL_EXTENSIONS:
+    default:
+        return "";
+    }
+}
+
+const GLubyte* glGetString(GLenum name) {
+    return (GLubyte*) getString(name);
+}
+
+void glActiveTexture(GLenum texture) {}
+void glAttachShader(GLuint program, GLuint shader) {}
+void glBindAttribLocation(GLuint program, GLuint index, const GLchar *name) {}
+void glBindBuffer(GLenum target, GLuint buffer) {}
+void glBindFramebuffer(GLenum target, GLuint framebuffer) {}
+void glBindRenderbuffer(GLenum target, GLuint renderbuffer) {}
+void glBindTexture(GLenum target, GLuint texture) {}
+void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {}
+void glBlendEquation(GLenum mode) {}
+void glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) {}
+void glBlendFunc(GLenum sfactor, GLenum dfactor) {}
+void glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) {}
+void glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage) {}
+void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data) {}
+void glClear(GLbitfield mask) {}
+void glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {}
+void glClearDepthf(GLfloat d) {}
+void glClearStencil(GLint s) {}
+void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {}
+void glCompileShader(GLuint shader) {}
+void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data) {}
+void glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data) {}
+void glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {}
+void glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {}
+void glCullFace(GLenum mode) {}
+void glDeleteBuffers(GLsizei n, const GLuint *buffers) {}
+void glDeleteFramebuffers(GLsizei n, const GLuint *framebuffers) {}
+void glDeleteProgram(GLuint program) {}
+void glDeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers) {}
+void glDeleteShader(GLuint shader) {}
+void glDeleteTextures(GLsizei n, const GLuint *textures) {}
+void glDepthFunc(GLenum func) {}
+void glDepthMask(GLboolean flag) {}
+void glDepthRangef(GLfloat n, GLfloat f) {}
+void glDetachShader(GLuint program, GLuint shader) {}
+void glDisableVertexAttribArray(GLuint index) {}
+void glDrawArrays(GLenum mode, GLint first, GLsizei count) {}
+void glDrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) {}
+void glEnableVertexAttribArray(GLuint index) {}
+void glFinish(void) {}
+void glFlush(void) {}
+void glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) {}
+void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {}
+void glFrontFace(GLenum mode) {}
+void glGenerateMipmap(GLenum target) {}
+GLint glGetAttribLocation(GLuint program, const GLchar *name) { return 1; }
+GLenum glGetError(void) { return GL_NO_ERROR; }
+GLint glGetUniformLocation(GLuint program, const GLchar *name) { return 2; }
+void glHint(GLenum target, GLenum mode) {}
+void glLineWidth(GLfloat width) {}
+void glLinkProgram(GLuint program) {}
+void glPixelStorei(GLenum pname, GLint param) {}
+void glPolygonOffset(GLfloat factor, GLfloat units) {}
+void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels) {}
+void glReleaseShaderCompiler(void) {}
+void glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {}
+void glSampleCoverage(GLfloat value, GLboolean invert) {}
+void glScissor(GLint x, GLint y, GLsizei width, GLsizei height) {}
+void glShaderBinary(GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length) {}
+void glShaderSource(GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length) {}
+void glStencilFunc(GLenum func, GLint ref, GLuint mask) {}
+void glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) {}
+void glStencilMask(GLuint mask) {}
+void glStencilMaskSeparate(GLenum face, GLuint mask) {}
+void glStencilOp(GLenum fail, GLenum zfail, GLenum zpass) {}
+void glStencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) {}
+void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels) {}
+void glTexParameterf(GLenum target, GLenum pname, GLfloat param) {}
+void glTexParameterfv(GLenum target, GLenum pname, const GLfloat *params) {}
+void glTexParameteri(GLenum target, GLenum pname, GLint param) {}
+void glTexParameteriv(GLenum target, GLenum pname, const GLint *params) {}
+void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) {}
+void glUniform1f(GLint location, GLfloat v0) {}
+void glUniform1fv(GLint location, GLsizei count, const GLfloat *value) {}
+void glUniform1i(GLint location, GLint v0) {}
+void glUniform1iv(GLint location, GLsizei count, const GLint *value) {}
+void glUniform2f(GLint location, GLfloat v0, GLfloat v1) {}
+void glUniform2fv(GLint location, GLsizei count, const GLfloat *value) {}
+void glUniform2i(GLint location, GLint v0, GLint v1) {}
+void glUniform2iv(GLint location, GLsizei count, const GLint *value) {}
+void glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {}
+void glUniform3fv(GLint location, GLsizei count, const GLfloat *value) {}
+void glUniform3i(GLint location, GLint v0, GLint v1, GLint v2) {}
+void glUniform3iv(GLint location, GLsizei count, const GLint *value) {}
+void glUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {}
+void glUniform4fv(GLint location, GLsizei count, const GLfloat *value) {}
+void glUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) {}
+void glUniform4iv(GLint location, GLsizei count, const GLint *value) {}
+void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {}
+void glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {}
+void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {}
+void glUseProgram(GLuint program) {}
+void glValidateProgram(GLuint program) {}
+void glVertexAttrib1f(GLuint index, GLfloat x) {}
+void glVertexAttrib1fv(GLuint index, const GLfloat *v) {}
+void glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) {}
+void glVertexAttrib2fv(GLuint index, const GLfloat *v) {}
+void glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) {}
+void glVertexAttrib3fv(GLuint index, const GLfloat *v) {}
+void glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {}
+void glVertexAttrib4fv(GLuint index, const GLfloat *v) {}
+void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer) {}
+void glViewport(GLint x, GLint y, GLsizei width, GLsizei height) {}
+
+
+// gles2 ext
+void glInsertEventMarkerEXT(GLsizei length, const GLchar *marker) {}
+void glPushGroupMarkerEXT(GLsizei length, const GLchar *marker) {}
+void glPopGroupMarkerEXT(void) {}
+void glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum *attachments) {}
+void glStartTilingQCOM(GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask) {}
+void glEndTilingQCOM(GLbitfield preserveMask) {}
+void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image) {}
+
+// GLES3
+void* glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) {
+    return 0;
+}
+
+GLboolean glUnmapBuffer(GLenum target) {
+    return GL_FALSE;
+}