Add a sample showing how to use OpenGL ES 3.0

Change-Id: If834a23ad3ad2164e6fdc40f865ee28cfa93de7e
diff --git a/ndk/platforms/android-18/samples/gles3jni/AndroidManifest-11.xml b/ndk/platforms/android-18/samples/gles3jni/AndroidManifest-11.xml
new file mode 100644
index 0000000..9213c58
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/AndroidManifest-11.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2013 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.gles3jni">
+    <application
+            android:label="@string/gles3jni_activity">
+        <activity android:name="GLES3JNIActivity"
+                android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+                android:launchMode="singleTask"
+                android:configChanges="orientation|keyboardHidden">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+    <uses-feature android:glEsVersion="0x00020000"/>
+    <uses-sdk android:minSdkVersion="11"/>
+</manifest>
diff --git a/ndk/platforms/android-18/samples/gles3jni/AndroidManifest-18.xml b/ndk/platforms/android-18/samples/gles3jni/AndroidManifest-18.xml
new file mode 100644
index 0000000..7eea32f
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/AndroidManifest-18.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2013 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.gles3jni">
+    <application
+            android:label="@string/gles3jni_activity">
+        <activity android:name="GLES3JNIActivity"
+                android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+                android:launchMode="singleTask"
+                android:configChanges="orientation|keyboardHidden">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+    <uses-feature android:glEsVersion="0x00030000"/>
+    <uses-sdk android:minSdkVersion="18"/>
+</manifest>
diff --git a/ndk/platforms/android-18/samples/gles3jni/README b/ndk/platforms/android-18/samples/gles3jni/README
new file mode 100644
index 0000000..517eec3
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/README
@@ -0,0 +1,33 @@
+This sample demonstrates how to use OpenGL ES 3.0 from JNI/native code.
+
+The sample can be built two different ways:
+  * Compatible with API level 11 and later [*1]
+  * Require API level 18 or later.
+Both versions include an OpenGL ES 2.0 fallback path for devices that don't
+support OpenGL ES 3.0.
+
+To build and install the sample:
+$ ln -s AndroidManifest-$N.xml AndroidManifest.xml
+$ ln -s Android-$N.mk jni/Android.mk
+$ $ANDROID_SDK/tools/android update project --path . --target android-$N
+$ ../../ndk-build
+$ ant debug
+$ adb install bin/GLES3JNIActivity-debug.apk
+where $N is '11' or '18' and
+ANDROID_SDK is the root of your SDK installation.
+
+The OpenGL ES 3.0 rendering path uses a few new features compared to the
+OpenGL ES 2.0 path:
+
+* Instanced rendering and vertex attribute divisor to reduce the number of
+  draw calls and uniform changes.
+* Vertex array objects to reduce the number of calls required to set up
+  vertex attribute state on each frame.
+* Explicit assignment of attribute locations, eliminating the need to query
+  assignments.
+
+
+[*1] The only dependency on API level 11 is the call to
+     setEGLContextClientVersion in GLES3JNIView. With a custom
+     EGLConfigChooser and EGLContextFactory the sample would be compatible
+     with older API levels.
\ No newline at end of file
diff --git a/ndk/platforms/android-18/samples/gles3jni/jni/Android-11.mk b/ndk/platforms/android-18/samples/gles3jni/jni/Android-11.mk
new file mode 100644
index 0000000..baf17d2
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/jni/Android-11.mk
@@ -0,0 +1,27 @@
+# Copyright 2013 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE     := libgles3jni
+LOCAL_CFLAGS     := -Werror -DDYNAMIC_ES3
+LOCAL_SRC_FILES  := gles3jni.cpp \
+				   RendererES2.cpp \
+				   RendererES3.cpp \
+				   gl3stub.c
+LOCAL_LDLIBS     := -llog -lGLESv2 -lEGL
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/ndk/platforms/android-18/samples/gles3jni/jni/Android-18.mk b/ndk/platforms/android-18/samples/gles3jni/jni/Android-18.mk
new file mode 100644
index 0000000..5111de5
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/jni/Android-18.mk
@@ -0,0 +1,26 @@
+# Copyright 2013 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE    := libgles3jni
+LOCAL_CFLAGS    := -Werror
+LOCAL_SRC_FILES := gles3jni.cpp \
+				   RendererES2.cpp \
+				   RendererES3.cpp
+LOCAL_LDLIBS    := -llog -lGLESv3 -lEGL
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/ndk/platforms/android-18/samples/gles3jni/jni/RendererES2.cpp b/ndk/platforms/android-18/samples/gles3jni/jni/RendererES2.cpp
new file mode 100644
index 0000000..d5f8d48
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/jni/RendererES2.cpp
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2013 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 "gles3jni.h"
+#include <EGL/egl.h>
+
+static const char VERTEX_SHADER[] =
+    "#version 100\n"
+    "uniform mat2 scaleRot;\n"
+    "uniform vec2 offset;\n"
+    "attribute vec2 pos;\n"
+    "attribute vec4 color;\n"
+    "varying vec4 vColor;\n"
+    "void main() {\n"
+    "    gl_Position = vec4(scaleRot*pos + offset, 0.0, 1.0);\n"
+    "    vColor = color;\n"
+    "}\n";
+
+static const char FRAGMENT_SHADER[] =
+    "#version 100\n"
+    "precision mediump float;\n"
+    "varying vec4 vColor;\n"
+    "void main() {\n"
+    "    gl_FragColor = vColor;\n"
+    "}\n";
+
+class RendererES2: public Renderer {
+public:
+    RendererES2();
+    virtual ~RendererES2();
+    bool init();
+
+private:
+    virtual float* mapOffsetBuf();
+    virtual void unmapOffsetBuf();
+    virtual float* mapTransformBuf();
+    virtual void unmapTransformBuf();
+    virtual void draw(unsigned int numInstances);
+
+    const EGLContext mEglContext;
+    GLuint mProgram;
+    GLuint mVB;
+    GLint mPosAttrib;
+    GLint mColorAttrib;
+    GLint mScaleRotUniform;
+    GLint mOffsetUniform;
+
+    float mOffsets[2*MAX_INSTANCES];
+    float mScaleRot[4*MAX_INSTANCES];   // array of 2x2 column-major matrices
+};
+
+Renderer* createES2Renderer() {
+    RendererES2* renderer = new RendererES2;
+    if (!renderer->init()) {
+        delete renderer;
+        return NULL;
+    }
+    return renderer;
+}
+
+RendererES2::RendererES2()
+:   mEglContext(eglGetCurrentContext()),
+    mProgram(0),
+    mVB(0),
+    mPosAttrib(-1),
+    mColorAttrib(-1),
+    mScaleRotUniform(-1),
+    mOffsetUniform(-1)
+{}
+
+bool RendererES2::init() {
+    mProgram = createProgram(VERTEX_SHADER, FRAGMENT_SHADER);
+    if (!mProgram)
+        return false;
+    mPosAttrib = glGetAttribLocation(mProgram, "pos");
+    mColorAttrib = glGetAttribLocation(mProgram, "color");
+    mScaleRotUniform = glGetUniformLocation(mProgram, "scaleRot");
+    mOffsetUniform = glGetUniformLocation(mProgram, "offset");
+
+    glGenBuffers(1, &mVB);
+    glBindBuffer(GL_ARRAY_BUFFER, mVB);
+    glBufferData(GL_ARRAY_BUFFER, sizeof(QUAD), &QUAD[0], GL_STATIC_DRAW);
+
+    ALOGV("Using OpenGL ES 2.0 renderer");
+    return true;
+}
+
+RendererES2::~RendererES2() {
+    /* The destructor may be called after the context has already been
+     * destroyed, in which case our objects have already been destroyed.
+     *
+     * If the context exists, it must be current. This only happens when we're
+     * cleaning up after a failed init().
+     */
+    if (eglGetCurrentContext() != mEglContext)
+        return;
+    glDeleteBuffers(1, &mVB);
+    glDeleteProgram(mProgram);
+}
+
+float* RendererES2::mapOffsetBuf() {
+    return mOffsets;
+}
+
+void RendererES2::unmapOffsetBuf() {
+}
+
+float* RendererES2::mapTransformBuf() {
+    return mScaleRot;
+}
+
+void RendererES2::unmapTransformBuf() {
+}
+
+void RendererES2::draw(unsigned int numInstances) {
+    glUseProgram(mProgram);
+
+    glBindBuffer(GL_ARRAY_BUFFER, mVB);
+    glVertexAttribPointer(mPosAttrib, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)offsetof(Vertex, pos));
+    glVertexAttribPointer(mColorAttrib, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (const GLvoid*)offsetof(Vertex, rgba));
+    glEnableVertexAttribArray(mPosAttrib);
+    glEnableVertexAttribArray(mColorAttrib);
+
+    for (unsigned int i = 0; i < numInstances; i++) {
+        glUniformMatrix2fv(mScaleRotUniform, 1, GL_FALSE, mScaleRot + 4*i);
+        glUniform2fv(mOffsetUniform, 1, mOffsets + 2*i);
+        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+    }
+}
diff --git a/ndk/platforms/android-18/samples/gles3jni/jni/RendererES3.cpp b/ndk/platforms/android-18/samples/gles3jni/jni/RendererES3.cpp
new file mode 100644
index 0000000..a6e617b
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/jni/RendererES3.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2013 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 "gles3jni.h"
+#include <EGL/egl.h>
+
+#define STR(s) #s
+#define STRV(s) STR(s)
+
+#define POS_ATTRIB 0
+#define COLOR_ATTRIB 1
+#define SCALEROT_ATTRIB 2
+#define OFFSET_ATTRIB 3
+
+static const char VERTEX_SHADER[] =
+    "#version 300 es\n"
+    "layout(location = " STRV(POS_ATTRIB) ") in vec2 pos;\n"
+    "layout(location=" STRV(COLOR_ATTRIB) ") in vec4 color;\n"
+    "layout(location=" STRV(SCALEROT_ATTRIB) ") in vec4 scaleRot;\n"
+    "layout(location=" STRV(OFFSET_ATTRIB) ") in vec2 offset;\n"
+    "out vec4 vColor;\n"
+    "void main() {\n"
+    "    mat2 sr = mat2(scaleRot.xy, scaleRot.zw);\n"
+    "    gl_Position = vec4(sr*pos + offset, 0.0, 1.0);\n"
+    "    vColor = color;\n"
+    "}\n";
+
+static const char FRAGMENT_SHADER[] =
+    "#version 300 es\n"
+    "precision mediump float;\n"
+    "in vec4 vColor;\n"
+    "out vec4 outColor;\n"
+    "void main() {\n"
+    "    outColor = vColor;\n"
+    "}\n";
+
+class RendererES3: public Renderer {
+public:
+    RendererES3();
+    virtual ~RendererES3();
+    bool init();
+
+private:
+    enum {VB_INSTANCE, VB_SCALEROT, VB_OFFSET, VB_COUNT};
+
+    virtual float* mapOffsetBuf();
+    virtual void unmapOffsetBuf();
+    virtual float* mapTransformBuf();
+    virtual void unmapTransformBuf();
+    virtual void draw(unsigned int numInstances);
+
+    const EGLContext mEglContext;
+    GLuint mProgram;
+    GLuint mVB[VB_COUNT];
+    GLuint mVBState;
+};
+
+Renderer* createES3Renderer() {
+    RendererES3* renderer = new RendererES3;
+    if (!renderer->init()) {
+        delete renderer;
+        return NULL;
+    }
+    return renderer;
+}
+
+RendererES3::RendererES3()
+:   mEglContext(eglGetCurrentContext()),
+    mProgram(0),
+    mVBState(0)
+{
+    for (int i = 0; i < VB_COUNT; i++)
+        mVB[i] = 0;
+}
+
+bool RendererES3::init() {
+    mProgram = createProgram(VERTEX_SHADER, FRAGMENT_SHADER);
+    if (!mProgram)
+        return false;
+
+    glGenBuffers(VB_COUNT, mVB);
+    glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_INSTANCE]);
+    glBufferData(GL_ARRAY_BUFFER, sizeof(QUAD), &QUAD[0], GL_STATIC_DRAW);
+    glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_SCALEROT]);
+    glBufferData(GL_ARRAY_BUFFER, MAX_INSTANCES * 4*sizeof(float), NULL, GL_DYNAMIC_DRAW);
+    glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_OFFSET]);
+    glBufferData(GL_ARRAY_BUFFER, MAX_INSTANCES * 2*sizeof(float), NULL, GL_STATIC_DRAW);
+
+    glGenVertexArrays(1, &mVBState);
+    glBindVertexArray(mVBState);
+
+    glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_INSTANCE]);
+    glVertexAttribPointer(POS_ATTRIB, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)offsetof(Vertex, pos));
+    glVertexAttribPointer(COLOR_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (const GLvoid*)offsetof(Vertex, rgba));
+    glEnableVertexAttribArray(POS_ATTRIB);
+    glEnableVertexAttribArray(COLOR_ATTRIB);
+
+    glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_SCALEROT]);
+    glVertexAttribPointer(SCALEROT_ATTRIB, 4, GL_FLOAT, GL_FALSE, 4*sizeof(float), 0);
+    glEnableVertexAttribArray(SCALEROT_ATTRIB);
+    glVertexAttribDivisor(SCALEROT_ATTRIB, 1);
+
+    glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_OFFSET]);
+    glVertexAttribPointer(OFFSET_ATTRIB, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), 0);
+    glEnableVertexAttribArray(OFFSET_ATTRIB);
+    glVertexAttribDivisor(OFFSET_ATTRIB, 1);
+
+    ALOGV("Using OpenGL ES 3.0 renderer");
+    return true;
+}
+
+RendererES3::~RendererES3() {
+    /* The destructor may be called after the context has already been
+     * destroyed, in which case our objects have already been destroyed.
+     *
+     * If the context exists, it must be current. This only happens when we're
+     * cleaning up after a failed init().
+     */
+    if (eglGetCurrentContext() != mEglContext)
+        return;
+    glDeleteVertexArrays(1, &mVBState);
+    glDeleteBuffers(VB_COUNT, mVB);
+    glDeleteProgram(mProgram);
+}
+
+float* RendererES3::mapOffsetBuf() {
+    glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_OFFSET]);
+    return (float*)glMapBufferRange(GL_ARRAY_BUFFER,
+            0, MAX_INSTANCES * 2*sizeof(float),
+            GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
+}
+
+void RendererES3::unmapOffsetBuf() {
+    glUnmapBuffer(GL_ARRAY_BUFFER);
+}
+
+float* RendererES3::mapTransformBuf() {
+    glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_SCALEROT]);
+    return (float*)glMapBufferRange(GL_ARRAY_BUFFER,
+            0, MAX_INSTANCES * 4*sizeof(float),
+            GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
+}
+
+void RendererES3::unmapTransformBuf() {
+    glUnmapBuffer(GL_ARRAY_BUFFER);
+}
+
+void RendererES3::draw(unsigned int numInstances) {
+    glUseProgram(mProgram);
+    glBindVertexArray(mVBState);
+    glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, numInstances);
+}
diff --git a/ndk/platforms/android-18/samples/gles3jni/jni/gl3stub.c b/ndk/platforms/android-18/samples/gles3jni/jni/gl3stub.c
new file mode 100644
index 0000000..b579f23
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/jni/gl3stub.c
@@ -0,0 +1,349 @@
+/*
+ * Copyright 2013 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 "gl3stub.h"
+#include <dlfcn.h>
+
+
+GLboolean gl3stubInit() {
+    void* so = dlopen("libGLESv3.so", RTLD_NOW | RTLD_GLOBAL);
+    if (!so)
+        return GL_FALSE;
+
+    #define DLSYM(s) s = dlsym(so, #s)
+    DLSYM(glReadBuffer);
+    DLSYM(glDrawRangeElements);
+    DLSYM(glTexImage3D);
+    DLSYM(glTexSubImage3D);
+    DLSYM(glCopyTexSubImage3D);
+    DLSYM(glCompressedTexImage3D);
+    DLSYM(glCompressedTexSubImage3D);
+    DLSYM(glGenQueries);
+    DLSYM(glDeleteQueries);
+    DLSYM(glIsQuery);
+    DLSYM(glBeginQuery);
+    DLSYM(glEndQuery);
+    DLSYM(glGetQueryiv);
+    DLSYM(glGetQueryObjectuiv);
+    DLSYM(glUnmapBuffer);
+    DLSYM(glGetBufferPointerv);
+    DLSYM(glDrawBuffers);
+    DLSYM(glUniformMatrix2x3fv);
+    DLSYM(glUniformMatrix3x2fv);
+    DLSYM(glUniformMatrix2x4fv);
+    DLSYM(glUniformMatrix4x2fv);
+    DLSYM(glUniformMatrix3x4fv);
+    DLSYM(glUniformMatrix4x3fv);
+    DLSYM(glBlitFramebuffer);
+    DLSYM(glRenderbufferStorageMultisample);
+    DLSYM(glFramebufferTextureLayer);
+    DLSYM(glMapBufferRange);
+    DLSYM(glFlushMappedBufferRange);
+    DLSYM(glBindVertexArray);
+    DLSYM(glDeleteVertexArrays);
+    DLSYM(glGenVertexArrays);
+    DLSYM(glIsVertexArray);
+    DLSYM(glGetIntegeri_v);
+    DLSYM(glBeginTransformFeedback);
+    DLSYM(glEndTransformFeedback);
+    DLSYM(glBindBufferRange);
+    DLSYM(glBindBufferBase);
+    DLSYM(glTransformFeedbackVaryings);
+    DLSYM(glGetTransformFeedbackVarying);
+    DLSYM(glVertexAttribIPointer);
+    DLSYM(glGetVertexAttribIiv);
+    DLSYM(glGetVertexAttribIuiv);
+    DLSYM(glVertexAttribI4i);
+    DLSYM(glVertexAttribI4ui);
+    DLSYM(glVertexAttribI4iv);
+    DLSYM(glVertexAttribI4uiv);
+    DLSYM(glGetUniformuiv);
+    DLSYM(glGetFragDataLocation);
+    DLSYM(glUniform1ui);
+    DLSYM(glUniform2ui);
+    DLSYM(glUniform3ui);
+    DLSYM(glUniform4ui);
+    DLSYM(glUniform1uiv);
+    DLSYM(glUniform2uiv);
+    DLSYM(glUniform3uiv);
+    DLSYM(glUniform4uiv);
+    DLSYM(glClearBufferiv);
+    DLSYM(glClearBufferuiv);
+    DLSYM(glClearBufferfv);
+    DLSYM(glClearBufferfi);
+    DLSYM(glGetStringi);
+    DLSYM(glCopyBufferSubData);
+    DLSYM(glGetUniformIndices);
+    DLSYM(glGetActiveUniformsiv);
+    DLSYM(glGetUniformBlockIndex);
+    DLSYM(glGetActiveUniformBlockiv);
+    DLSYM(glGetActiveUniformBlockName);
+    DLSYM(glUniformBlockBinding);
+    DLSYM(glDrawArraysInstanced);
+    DLSYM(glDrawElementsInstanced);
+    DLSYM(glFenceSync);
+    DLSYM(glIsSync);
+    DLSYM(glDeleteSync);
+    DLSYM(glClientWaitSync);
+    DLSYM(glWaitSync);
+    DLSYM(glGetInteger64v);
+    DLSYM(glGetSynciv);
+    DLSYM(glGetInteger64i_v);
+    DLSYM(glGetBufferParameteri64v);
+    DLSYM(glGenSamplers);
+    DLSYM(glDeleteSamplers);
+    DLSYM(glIsSampler);
+    DLSYM(glBindSampler);
+    DLSYM(glSamplerParameteri);
+    DLSYM(glSamplerParameteriv);
+    DLSYM(glSamplerParameterf);
+    DLSYM(glSamplerParameterfv);
+    DLSYM(glGetSamplerParameteriv);
+    DLSYM(glGetSamplerParameterfv);
+    DLSYM(glVertexAttribDivisor);
+    DLSYM(glBindTransformFeedback);
+    DLSYM(glDeleteTransformFeedbacks);
+    DLSYM(glGenTransformFeedbacks);
+    DLSYM(glIsTransformFeedback);
+    DLSYM(glPauseTransformFeedback);
+    DLSYM(glResumeTransformFeedback);
+    DLSYM(glGetProgramBinary);
+    DLSYM(glProgramBinary);
+    DLSYM(glProgramParameteri);
+    DLSYM(glInvalidateFramebuffer);
+    DLSYM(glInvalidateSubFramebuffer);
+    DLSYM(glTexStorage2D);
+    DLSYM(glTexStorage3D);
+    DLSYM(glGetInternalformativ);
+    #undef DLSYM
+
+    if (!glReadBuffer ||
+        !glDrawRangeElements ||
+        !glTexImage3D ||
+        !glTexSubImage3D ||
+        !glCopyTexSubImage3D ||
+        !glCompressedTexImage3D ||
+        !glCompressedTexSubImage3D ||
+        !glGenQueries ||
+        !glDeleteQueries ||
+        !glIsQuery ||
+        !glBeginQuery ||
+        !glEndQuery ||
+        !glGetQueryiv ||
+        !glGetQueryObjectuiv ||
+        !glUnmapBuffer ||
+        !glGetBufferPointerv ||
+        !glDrawBuffers ||
+        !glUniformMatrix2x3fv ||
+        !glUniformMatrix3x2fv ||
+        !glUniformMatrix2x4fv ||
+        !glUniformMatrix4x2fv ||
+        !glUniformMatrix3x4fv ||
+        !glUniformMatrix4x3fv ||
+        !glBlitFramebuffer ||
+        !glRenderbufferStorageMultisample ||
+        !glFramebufferTextureLayer ||
+        !glMapBufferRange ||
+        !glFlushMappedBufferRange ||
+        !glBindVertexArray ||
+        !glDeleteVertexArrays ||
+        !glGenVertexArrays ||
+        !glIsVertexArray ||
+        !glGetIntegeri_v ||
+        !glBeginTransformFeedback ||
+        !glEndTransformFeedback ||
+        !glBindBufferRange ||
+        !glBindBufferBase ||
+        !glTransformFeedbackVaryings ||
+        !glGetTransformFeedbackVarying ||
+        !glVertexAttribIPointer ||
+        !glGetVertexAttribIiv ||
+        !glGetVertexAttribIuiv ||
+        !glVertexAttribI4i ||
+        !glVertexAttribI4ui ||
+        !glVertexAttribI4iv ||
+        !glVertexAttribI4uiv ||
+        !glGetUniformuiv ||
+        !glGetFragDataLocation ||
+        !glUniform1ui ||
+        !glUniform2ui ||
+        !glUniform3ui ||
+        !glUniform4ui ||
+        !glUniform1uiv ||
+        !glUniform2uiv ||
+        !glUniform3uiv ||
+        !glUniform4uiv ||
+        !glClearBufferiv ||
+        !glClearBufferuiv ||
+        !glClearBufferfv ||
+        !glClearBufferfi ||
+        !glGetStringi ||
+        !glCopyBufferSubData ||
+        !glGetUniformIndices ||
+        !glGetActiveUniformsiv ||
+        !glGetUniformBlockIndex ||
+        !glGetActiveUniformBlockiv ||
+        !glGetActiveUniformBlockName ||
+        !glUniformBlockBinding ||
+        !glDrawArraysInstanced ||
+        !glDrawElementsInstanced ||
+        !glFenceSync ||
+        !glIsSync ||
+        !glDeleteSync ||
+        !glClientWaitSync ||
+        !glWaitSync ||
+        !glGetInteger64v ||
+        !glGetSynciv ||
+        !glGetInteger64i_v ||
+        !glGetBufferParameteri64v ||
+        !glGenSamplers ||
+        !glDeleteSamplers ||
+        !glIsSampler ||
+        !glBindSampler ||
+        !glSamplerParameteri ||
+        !glSamplerParameteriv ||
+        !glSamplerParameterf ||
+        !glSamplerParameterfv ||
+        !glGetSamplerParameteriv ||
+        !glGetSamplerParameterfv ||
+        !glVertexAttribDivisor ||
+        !glBindTransformFeedback ||
+        !glDeleteTransformFeedbacks ||
+        !glGenTransformFeedbacks ||
+        !glIsTransformFeedback ||
+        !glPauseTransformFeedback ||
+        !glResumeTransformFeedback ||
+        !glGetProgramBinary ||
+        !glProgramBinary ||
+        !glProgramParameteri ||
+        !glInvalidateFramebuffer ||
+        !glInvalidateSubFramebuffer ||
+        !glTexStorage2D ||
+        !glTexStorage3D ||
+        !glGetInternalformativ)
+    {
+        dlclose(so);
+        return GL_FALSE;
+    }
+
+    return GL_TRUE;
+}
+
+/* Function pointer definitions */
+GL_APICALL void           (* GL_APIENTRY glReadBuffer) (GLenum mode);
+GL_APICALL void           (* GL_APIENTRY glDrawRangeElements) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices);
+GL_APICALL void           (* GL_APIENTRY glTexImage3D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+GL_APICALL void           (* GL_APIENTRY glTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels);
+GL_APICALL void           (* GL_APIENTRY glCopyTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void           (* GL_APIENTRY glCompressedTexImage3D) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data);
+GL_APICALL void           (* GL_APIENTRY glCompressedTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data);
+GL_APICALL void           (* GL_APIENTRY glGenQueries) (GLsizei n, GLuint* ids);
+GL_APICALL void           (* GL_APIENTRY glDeleteQueries) (GLsizei n, const GLuint* ids);
+GL_APICALL GLboolean      (* GL_APIENTRY glIsQuery) (GLuint id);
+GL_APICALL void           (* GL_APIENTRY glBeginQuery) (GLenum target, GLuint id);
+GL_APICALL void           (* GL_APIENTRY glEndQuery) (GLenum target);
+GL_APICALL void           (* GL_APIENTRY glGetQueryiv) (GLenum target, GLenum pname, GLint* params);
+GL_APICALL void           (* GL_APIENTRY glGetQueryObjectuiv) (GLuint id, GLenum pname, GLuint* params);
+GL_APICALL GLboolean      (* GL_APIENTRY glUnmapBuffer) (GLenum target);
+GL_APICALL void           (* GL_APIENTRY glGetBufferPointerv) (GLenum target, GLenum pname, GLvoid** params);
+GL_APICALL void           (* GL_APIENTRY glDrawBuffers) (GLsizei n, const GLenum* bufs);
+GL_APICALL void           (* GL_APIENTRY glUniformMatrix2x3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void           (* GL_APIENTRY glUniformMatrix3x2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void           (* GL_APIENTRY glUniformMatrix2x4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void           (* GL_APIENTRY glUniformMatrix4x2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void           (* GL_APIENTRY glUniformMatrix3x4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void           (* GL_APIENTRY glUniformMatrix4x3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void           (* GL_APIENTRY glBlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+GL_APICALL void           (* GL_APIENTRY glRenderbufferStorageMultisample) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void           (* GL_APIENTRY glFramebufferTextureLayer) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+GL_APICALL GLvoid*        (* GL_APIENTRY glMapBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+GL_APICALL void           (* GL_APIENTRY glFlushMappedBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length);
+GL_APICALL void           (* GL_APIENTRY glBindVertexArray) (GLuint array);
+GL_APICALL void           (* GL_APIENTRY glDeleteVertexArrays) (GLsizei n, const GLuint* arrays);
+GL_APICALL void           (* GL_APIENTRY glGenVertexArrays) (GLsizei n, GLuint* arrays);
+GL_APICALL GLboolean      (* GL_APIENTRY glIsVertexArray) (GLuint array);
+GL_APICALL void           (* GL_APIENTRY glGetIntegeri_v) (GLenum target, GLuint index, GLint* data);
+GL_APICALL void           (* GL_APIENTRY glBeginTransformFeedback) (GLenum primitiveMode);
+GL_APICALL void           (* GL_APIENTRY glEndTransformFeedback) (void);
+GL_APICALL void           (* GL_APIENTRY glBindBufferRange) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+GL_APICALL void           (* GL_APIENTRY glBindBufferBase) (GLenum target, GLuint index, GLuint buffer);
+GL_APICALL void           (* GL_APIENTRY glTransformFeedbackVaryings) (GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode);
+GL_APICALL void           (* GL_APIENTRY glGetTransformFeedbackVarying) (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name);
+GL_APICALL void           (* GL_APIENTRY glVertexAttribIPointer) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
+GL_APICALL void           (* GL_APIENTRY glGetVertexAttribIiv) (GLuint index, GLenum pname, GLint* params);
+GL_APICALL void           (* GL_APIENTRY glGetVertexAttribIuiv) (GLuint index, GLenum pname, GLuint* params);
+GL_APICALL void           (* GL_APIENTRY glVertexAttribI4i) (GLuint index, GLint x, GLint y, GLint z, GLint w);
+GL_APICALL void           (* GL_APIENTRY glVertexAttribI4ui) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GL_APICALL void           (* GL_APIENTRY glVertexAttribI4iv) (GLuint index, const GLint* v);
+GL_APICALL void           (* GL_APIENTRY glVertexAttribI4uiv) (GLuint index, const GLuint* v);
+GL_APICALL void           (* GL_APIENTRY glGetUniformuiv) (GLuint program, GLint location, GLuint* params);
+GL_APICALL GLint          (* GL_APIENTRY glGetFragDataLocation) (GLuint program, const GLchar *name);
+GL_APICALL void           (* GL_APIENTRY glUniform1ui) (GLint location, GLuint v0);
+GL_APICALL void           (* GL_APIENTRY glUniform2ui) (GLint location, GLuint v0, GLuint v1);
+GL_APICALL void           (* GL_APIENTRY glUniform3ui) (GLint location, GLuint v0, GLuint v1, GLuint v2);
+GL_APICALL void           (* GL_APIENTRY glUniform4ui) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GL_APICALL void           (* GL_APIENTRY glUniform1uiv) (GLint location, GLsizei count, const GLuint* value);
+GL_APICALL void           (* GL_APIENTRY glUniform2uiv) (GLint location, GLsizei count, const GLuint* value);
+GL_APICALL void           (* GL_APIENTRY glUniform3uiv) (GLint location, GLsizei count, const GLuint* value);
+GL_APICALL void           (* GL_APIENTRY glUniform4uiv) (GLint location, GLsizei count, const GLuint* value);
+GL_APICALL void           (* GL_APIENTRY glClearBufferiv) (GLenum buffer, GLint drawbuffer, const GLint* value);
+GL_APICALL void           (* GL_APIENTRY glClearBufferuiv) (GLenum buffer, GLint drawbuffer, const GLuint* value);
+GL_APICALL void           (* GL_APIENTRY glClearBufferfv) (GLenum buffer, GLint drawbuffer, const GLfloat* value);
+GL_APICALL void           (* GL_APIENTRY glClearBufferfi) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+GL_APICALL const GLubyte* (* GL_APIENTRY glGetStringi) (GLenum name, GLuint index);
+GL_APICALL void           (* GL_APIENTRY glCopyBufferSubData) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+GL_APICALL void           (* GL_APIENTRY glGetUniformIndices) (GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices);
+GL_APICALL void           (* GL_APIENTRY glGetActiveUniformsiv) (GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params);
+GL_APICALL GLuint         (* GL_APIENTRY glGetUniformBlockIndex) (GLuint program, const GLchar* uniformBlockName);
+GL_APICALL void           (* GL_APIENTRY glGetActiveUniformBlockiv) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params);
+GL_APICALL void           (* GL_APIENTRY glGetActiveUniformBlockName) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName);
+GL_APICALL void           (* GL_APIENTRY glUniformBlockBinding) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+GL_APICALL void           (* GL_APIENTRY glDrawArraysInstanced) (GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
+GL_APICALL void           (* GL_APIENTRY glDrawElementsInstanced) (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount);
+GL_APICALL GLsync         (* GL_APIENTRY glFenceSync) (GLenum condition, GLbitfield flags);
+GL_APICALL GLboolean      (* GL_APIENTRY glIsSync) (GLsync sync);
+GL_APICALL void           (* GL_APIENTRY glDeleteSync) (GLsync sync);
+GL_APICALL GLenum         (* GL_APIENTRY glClientWaitSync) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GL_APICALL void           (* GL_APIENTRY glWaitSync) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GL_APICALL void           (* GL_APIENTRY glGetInteger64v) (GLenum pname, GLint64* params);
+GL_APICALL void           (* GL_APIENTRY glGetSynciv) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values);
+GL_APICALL void           (* GL_APIENTRY glGetInteger64i_v) (GLenum target, GLuint index, GLint64* data);
+GL_APICALL void           (* GL_APIENTRY glGetBufferParameteri64v) (GLenum target, GLenum pname, GLint64* params);
+GL_APICALL void           (* GL_APIENTRY glGenSamplers) (GLsizei count, GLuint* samplers);
+GL_APICALL void           (* GL_APIENTRY glDeleteSamplers) (GLsizei count, const GLuint* samplers);
+GL_APICALL GLboolean      (* GL_APIENTRY glIsSampler) (GLuint sampler);
+GL_APICALL void           (* GL_APIENTRY glBindSampler) (GLuint unit, GLuint sampler);
+GL_APICALL void           (* GL_APIENTRY glSamplerParameteri) (GLuint sampler, GLenum pname, GLint param);
+GL_APICALL void           (* GL_APIENTRY glSamplerParameteriv) (GLuint sampler, GLenum pname, const GLint* param);
+GL_APICALL void           (* GL_APIENTRY glSamplerParameterf) (GLuint sampler, GLenum pname, GLfloat param);
+GL_APICALL void           (* GL_APIENTRY glSamplerParameterfv) (GLuint sampler, GLenum pname, const GLfloat* param);
+GL_APICALL void           (* GL_APIENTRY glGetSamplerParameteriv) (GLuint sampler, GLenum pname, GLint* params);
+GL_APICALL void           (* GL_APIENTRY glGetSamplerParameterfv) (GLuint sampler, GLenum pname, GLfloat* params);
+GL_APICALL void           (* GL_APIENTRY glVertexAttribDivisor) (GLuint index, GLuint divisor);
+GL_APICALL void           (* GL_APIENTRY glBindTransformFeedback) (GLenum target, GLuint id);
+GL_APICALL void           (* GL_APIENTRY glDeleteTransformFeedbacks) (GLsizei n, const GLuint* ids);
+GL_APICALL void           (* GL_APIENTRY glGenTransformFeedbacks) (GLsizei n, GLuint* ids);
+GL_APICALL GLboolean      (* GL_APIENTRY glIsTransformFeedback) (GLuint id);
+GL_APICALL void           (* GL_APIENTRY glPauseTransformFeedback) (void);
+GL_APICALL void           (* GL_APIENTRY glResumeTransformFeedback) (void);
+GL_APICALL void           (* GL_APIENTRY glGetProgramBinary) (GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary);
+GL_APICALL void           (* GL_APIENTRY glProgramBinary) (GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length);
+GL_APICALL void           (* GL_APIENTRY glProgramParameteri) (GLuint program, GLenum pname, GLint value);
+GL_APICALL void           (* GL_APIENTRY glInvalidateFramebuffer) (GLenum target, GLsizei numAttachments, const GLenum* attachments);
+GL_APICALL void           (* GL_APIENTRY glInvalidateSubFramebuffer) (GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void           (* GL_APIENTRY glTexStorage2D) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void           (* GL_APIENTRY glTexStorage3D) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+GL_APICALL void           (* GL_APIENTRY glGetInternalformativ) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params);
diff --git a/ndk/platforms/android-18/samples/gles3jni/jni/gl3stub.h b/ndk/platforms/android-18/samples/gles3jni/jni/gl3stub.h
new file mode 100644
index 0000000..7a02bf2
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/jni/gl3stub.h
@@ -0,0 +1,491 @@
+#ifndef __gl3_h_
+#define __gl3_h_
+
+/*
+ * stub gl3.h for dynamic loading, based on:
+ * gl3.h last updated on $Date: 2013-02-12 14:37:24 -0800 (Tue, 12 Feb 2013) $
+ *
+ * Changes:
+ * - Added #include <GLES2/gl2.h>
+ * - Removed duplicate OpenGL ES 2.0 declarations
+ * - Converted OpenGL ES 3.0 function prototypes to function pointer
+ *   declarations
+ * - Added gl3stubInit() declaration
+ */
+
+#include <GLES2/gl2.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2007-2013 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/* Call this function before calling any OpenGL ES 3.0 functions. It will
+ * return GL_TRUE if the OpenGL ES 3.0 was successfully initialized, GL_FALSE
+ * otherwise. */
+GLboolean gl3stubInit();
+
+/*-------------------------------------------------------------------------
+ * Data type definitions
+ *-----------------------------------------------------------------------*/
+
+/* OpenGL ES 3.0 */
+
+typedef unsigned short   GLhalf;
+typedef khronos_int64_t  GLint64;
+typedef khronos_uint64_t GLuint64;
+typedef struct __GLsync *GLsync;
+
+/*-------------------------------------------------------------------------
+ * Token definitions
+ *-----------------------------------------------------------------------*/
+
+/* OpenGL ES core versions */
+#define GL_ES_VERSION_3_0                                1
+
+/* OpenGL ES 3.0 */
+
+#define GL_READ_BUFFER                                   0x0C02
+#define GL_UNPACK_ROW_LENGTH                             0x0CF2
+#define GL_UNPACK_SKIP_ROWS                              0x0CF3
+#define GL_UNPACK_SKIP_PIXELS                            0x0CF4
+#define GL_PACK_ROW_LENGTH                               0x0D02
+#define GL_PACK_SKIP_ROWS                                0x0D03
+#define GL_PACK_SKIP_PIXELS                              0x0D04
+#define GL_COLOR                                         0x1800
+#define GL_DEPTH                                         0x1801
+#define GL_STENCIL                                       0x1802
+#define GL_RED                                           0x1903
+#define GL_RGB8                                          0x8051
+#define GL_RGBA8                                         0x8058
+#define GL_RGB10_A2                                      0x8059
+#define GL_TEXTURE_BINDING_3D                            0x806A
+#define GL_UNPACK_SKIP_IMAGES                            0x806D
+#define GL_UNPACK_IMAGE_HEIGHT                           0x806E
+#define GL_TEXTURE_3D                                    0x806F
+#define GL_TEXTURE_WRAP_R                                0x8072
+#define GL_MAX_3D_TEXTURE_SIZE                           0x8073
+#define GL_UNSIGNED_INT_2_10_10_10_REV                   0x8368
+#define GL_MAX_ELEMENTS_VERTICES                         0x80E8
+#define GL_MAX_ELEMENTS_INDICES                          0x80E9
+#define GL_TEXTURE_MIN_LOD                               0x813A
+#define GL_TEXTURE_MAX_LOD                               0x813B
+#define GL_TEXTURE_BASE_LEVEL                            0x813C
+#define GL_TEXTURE_MAX_LEVEL                             0x813D
+#define GL_MIN                                           0x8007
+#define GL_MAX                                           0x8008
+#define GL_DEPTH_COMPONENT24                             0x81A6
+#define GL_MAX_TEXTURE_LOD_BIAS                          0x84FD
+#define GL_TEXTURE_COMPARE_MODE                          0x884C
+#define GL_TEXTURE_COMPARE_FUNC                          0x884D
+#define GL_CURRENT_QUERY                                 0x8865
+#define GL_QUERY_RESULT                                  0x8866
+#define GL_QUERY_RESULT_AVAILABLE                        0x8867
+#define GL_BUFFER_MAPPED                                 0x88BC
+#define GL_BUFFER_MAP_POINTER                            0x88BD
+#define GL_STREAM_READ                                   0x88E1
+#define GL_STREAM_COPY                                   0x88E2
+#define GL_STATIC_READ                                   0x88E5
+#define GL_STATIC_COPY                                   0x88E6
+#define GL_DYNAMIC_READ                                  0x88E9
+#define GL_DYNAMIC_COPY                                  0x88EA
+#define GL_MAX_DRAW_BUFFERS                              0x8824
+#define GL_DRAW_BUFFER0                                  0x8825
+#define GL_DRAW_BUFFER1                                  0x8826
+#define GL_DRAW_BUFFER2                                  0x8827
+#define GL_DRAW_BUFFER3                                  0x8828
+#define GL_DRAW_BUFFER4                                  0x8829
+#define GL_DRAW_BUFFER5                                  0x882A
+#define GL_DRAW_BUFFER6                                  0x882B
+#define GL_DRAW_BUFFER7                                  0x882C
+#define GL_DRAW_BUFFER8                                  0x882D
+#define GL_DRAW_BUFFER9                                  0x882E
+#define GL_DRAW_BUFFER10                                 0x882F
+#define GL_DRAW_BUFFER11                                 0x8830
+#define GL_DRAW_BUFFER12                                 0x8831
+#define GL_DRAW_BUFFER13                                 0x8832
+#define GL_DRAW_BUFFER14                                 0x8833
+#define GL_DRAW_BUFFER15                                 0x8834
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS               0x8B49
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS                 0x8B4A
+#define GL_SAMPLER_3D                                    0x8B5F
+#define GL_SAMPLER_2D_SHADOW                             0x8B62
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT               0x8B8B
+#define GL_PIXEL_PACK_BUFFER                             0x88EB
+#define GL_PIXEL_UNPACK_BUFFER                           0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING                     0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING                   0x88EF
+#define GL_FLOAT_MAT2x3                                  0x8B65
+#define GL_FLOAT_MAT2x4                                  0x8B66
+#define GL_FLOAT_MAT3x2                                  0x8B67
+#define GL_FLOAT_MAT3x4                                  0x8B68
+#define GL_FLOAT_MAT4x2                                  0x8B69
+#define GL_FLOAT_MAT4x3                                  0x8B6A
+#define GL_SRGB                                          0x8C40
+#define GL_SRGB8                                         0x8C41
+#define GL_SRGB8_ALPHA8                                  0x8C43
+#define GL_COMPARE_REF_TO_TEXTURE                        0x884E
+#define GL_MAJOR_VERSION                                 0x821B
+#define GL_MINOR_VERSION                                 0x821C
+#define GL_NUM_EXTENSIONS                                0x821D
+#define GL_RGBA32F                                       0x8814
+#define GL_RGB32F                                        0x8815
+#define GL_RGBA16F                                       0x881A
+#define GL_RGB16F                                        0x881B
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER                   0x88FD
+#define GL_MAX_ARRAY_TEXTURE_LAYERS                      0x88FF
+#define GL_MIN_PROGRAM_TEXEL_OFFSET                      0x8904
+#define GL_MAX_PROGRAM_TEXEL_OFFSET                      0x8905
+#define GL_MAX_VARYING_COMPONENTS                        0x8B4B
+#define GL_TEXTURE_2D_ARRAY                              0x8C1A
+#define GL_TEXTURE_BINDING_2D_ARRAY                      0x8C1D
+#define GL_R11F_G11F_B10F                                0x8C3A
+#define GL_UNSIGNED_INT_10F_11F_11F_REV                  0x8C3B
+#define GL_RGB9_E5                                       0x8C3D
+#define GL_UNSIGNED_INT_5_9_9_9_REV                      0x8C3E
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH         0x8C76
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE                0x8C7F
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS    0x8C80
+#define GL_TRANSFORM_FEEDBACK_VARYINGS                   0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START               0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE                0x8C85
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN         0x8C88
+#define GL_RASTERIZER_DISCARD                            0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS       0x8C8B
+#define GL_INTERLEAVED_ATTRIBS                           0x8C8C
+#define GL_SEPARATE_ATTRIBS                              0x8C8D
+#define GL_TRANSFORM_FEEDBACK_BUFFER                     0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING             0x8C8F
+#define GL_RGBA32UI                                      0x8D70
+#define GL_RGB32UI                                       0x8D71
+#define GL_RGBA16UI                                      0x8D76
+#define GL_RGB16UI                                       0x8D77
+#define GL_RGBA8UI                                       0x8D7C
+#define GL_RGB8UI                                        0x8D7D
+#define GL_RGBA32I                                       0x8D82
+#define GL_RGB32I                                        0x8D83
+#define GL_RGBA16I                                       0x8D88
+#define GL_RGB16I                                        0x8D89
+#define GL_RGBA8I                                        0x8D8E
+#define GL_RGB8I                                         0x8D8F
+#define GL_RED_INTEGER                                   0x8D94
+#define GL_RGB_INTEGER                                   0x8D98
+#define GL_RGBA_INTEGER                                  0x8D99
+#define GL_SAMPLER_2D_ARRAY                              0x8DC1
+#define GL_SAMPLER_2D_ARRAY_SHADOW                       0x8DC4
+#define GL_SAMPLER_CUBE_SHADOW                           0x8DC5
+#define GL_UNSIGNED_INT_VEC2                             0x8DC6
+#define GL_UNSIGNED_INT_VEC3                             0x8DC7
+#define GL_UNSIGNED_INT_VEC4                             0x8DC8
+#define GL_INT_SAMPLER_2D                                0x8DCA
+#define GL_INT_SAMPLER_3D                                0x8DCB
+#define GL_INT_SAMPLER_CUBE                              0x8DCC
+#define GL_INT_SAMPLER_2D_ARRAY                          0x8DCF
+#define GL_UNSIGNED_INT_SAMPLER_2D                       0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_3D                       0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_CUBE                     0x8DD4
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY                 0x8DD7
+#define GL_BUFFER_ACCESS_FLAGS                           0x911F
+#define GL_BUFFER_MAP_LENGTH                             0x9120
+#define GL_BUFFER_MAP_OFFSET                             0x9121
+#define GL_DEPTH_COMPONENT32F                            0x8CAC
+#define GL_DEPTH32F_STENCIL8                             0x8CAD
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV                0x8DAD
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING         0x8210
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE         0x8211
+#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE               0x8212
+#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE             0x8213
+#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE              0x8214
+#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE             0x8215
+#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE             0x8216
+#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE           0x8217
+#define GL_FRAMEBUFFER_DEFAULT                           0x8218
+#define GL_FRAMEBUFFER_UNDEFINED                         0x8219
+#define GL_DEPTH_STENCIL_ATTACHMENT                      0x821A
+#define GL_DEPTH_STENCIL                                 0x84F9
+#define GL_UNSIGNED_INT_24_8                             0x84FA
+#define GL_DEPTH24_STENCIL8                              0x88F0
+#define GL_UNSIGNED_NORMALIZED                           0x8C17
+#define GL_DRAW_FRAMEBUFFER_BINDING                      GL_FRAMEBUFFER_BINDING
+#define GL_READ_FRAMEBUFFER                              0x8CA8
+#define GL_DRAW_FRAMEBUFFER                              0x8CA9
+#define GL_READ_FRAMEBUFFER_BINDING                      0x8CAA
+#define GL_RENDERBUFFER_SAMPLES                          0x8CAB
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER          0x8CD4
+#define GL_MAX_COLOR_ATTACHMENTS                         0x8CDF
+#define GL_COLOR_ATTACHMENT1                             0x8CE1
+#define GL_COLOR_ATTACHMENT2                             0x8CE2
+#define GL_COLOR_ATTACHMENT3                             0x8CE3
+#define GL_COLOR_ATTACHMENT4                             0x8CE4
+#define GL_COLOR_ATTACHMENT5                             0x8CE5
+#define GL_COLOR_ATTACHMENT6                             0x8CE6
+#define GL_COLOR_ATTACHMENT7                             0x8CE7
+#define GL_COLOR_ATTACHMENT8                             0x8CE8
+#define GL_COLOR_ATTACHMENT9                             0x8CE9
+#define GL_COLOR_ATTACHMENT10                            0x8CEA
+#define GL_COLOR_ATTACHMENT11                            0x8CEB
+#define GL_COLOR_ATTACHMENT12                            0x8CEC
+#define GL_COLOR_ATTACHMENT13                            0x8CED
+#define GL_COLOR_ATTACHMENT14                            0x8CEE
+#define GL_COLOR_ATTACHMENT15                            0x8CEF
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE            0x8D56
+#define GL_MAX_SAMPLES                                   0x8D57
+#define GL_HALF_FLOAT                                    0x140B
+#define GL_MAP_READ_BIT                                  0x0001
+#define GL_MAP_WRITE_BIT                                 0x0002
+#define GL_MAP_INVALIDATE_RANGE_BIT                      0x0004
+#define GL_MAP_INVALIDATE_BUFFER_BIT                     0x0008
+#define GL_MAP_FLUSH_EXPLICIT_BIT                        0x0010
+#define GL_MAP_UNSYNCHRONIZED_BIT                        0x0020
+#define GL_RG                                            0x8227
+#define GL_RG_INTEGER                                    0x8228
+#define GL_R8                                            0x8229
+#define GL_RG8                                           0x822B
+#define GL_R16F                                          0x822D
+#define GL_R32F                                          0x822E
+#define GL_RG16F                                         0x822F
+#define GL_RG32F                                         0x8230
+#define GL_R8I                                           0x8231
+#define GL_R8UI                                          0x8232
+#define GL_R16I                                          0x8233
+#define GL_R16UI                                         0x8234
+#define GL_R32I                                          0x8235
+#define GL_R32UI                                         0x8236
+#define GL_RG8I                                          0x8237
+#define GL_RG8UI                                         0x8238
+#define GL_RG16I                                         0x8239
+#define GL_RG16UI                                        0x823A
+#define GL_RG32I                                         0x823B
+#define GL_RG32UI                                        0x823C
+#define GL_VERTEX_ARRAY_BINDING                          0x85B5
+#define GL_R8_SNORM                                      0x8F94
+#define GL_RG8_SNORM                                     0x8F95
+#define GL_RGB8_SNORM                                    0x8F96
+#define GL_RGBA8_SNORM                                   0x8F97
+#define GL_SIGNED_NORMALIZED                             0x8F9C
+#define GL_PRIMITIVE_RESTART_FIXED_INDEX                 0x8D69
+#define GL_COPY_READ_BUFFER                              0x8F36
+#define GL_COPY_WRITE_BUFFER                             0x8F37
+#define GL_COPY_READ_BUFFER_BINDING                      GL_COPY_READ_BUFFER
+#define GL_COPY_WRITE_BUFFER_BINDING                     GL_COPY_WRITE_BUFFER
+#define GL_UNIFORM_BUFFER                                0x8A11
+#define GL_UNIFORM_BUFFER_BINDING                        0x8A28
+#define GL_UNIFORM_BUFFER_START                          0x8A29
+#define GL_UNIFORM_BUFFER_SIZE                           0x8A2A
+#define GL_MAX_VERTEX_UNIFORM_BLOCKS                     0x8A2B
+#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS                   0x8A2D
+#define GL_MAX_COMBINED_UNIFORM_BLOCKS                   0x8A2E
+#define GL_MAX_UNIFORM_BUFFER_BINDINGS                   0x8A2F
+#define GL_MAX_UNIFORM_BLOCK_SIZE                        0x8A30
+#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS        0x8A31
+#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS      0x8A33
+#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT               0x8A34
+#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH          0x8A35
+#define GL_ACTIVE_UNIFORM_BLOCKS                         0x8A36
+#define GL_UNIFORM_TYPE                                  0x8A37
+#define GL_UNIFORM_SIZE                                  0x8A38
+#define GL_UNIFORM_NAME_LENGTH                           0x8A39
+#define GL_UNIFORM_BLOCK_INDEX                           0x8A3A
+#define GL_UNIFORM_OFFSET                                0x8A3B
+#define GL_UNIFORM_ARRAY_STRIDE                          0x8A3C
+#define GL_UNIFORM_MATRIX_STRIDE                         0x8A3D
+#define GL_UNIFORM_IS_ROW_MAJOR                          0x8A3E
+#define GL_UNIFORM_BLOCK_BINDING                         0x8A3F
+#define GL_UNIFORM_BLOCK_DATA_SIZE                       0x8A40
+#define GL_UNIFORM_BLOCK_NAME_LENGTH                     0x8A41
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS                 0x8A42
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES          0x8A43
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER     0x8A44
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER   0x8A46
+#define GL_INVALID_INDEX                                 0xFFFFFFFFu
+#define GL_MAX_VERTEX_OUTPUT_COMPONENTS                  0x9122
+#define GL_MAX_FRAGMENT_INPUT_COMPONENTS                 0x9125
+#define GL_MAX_SERVER_WAIT_TIMEOUT                       0x9111
+#define GL_OBJECT_TYPE                                   0x9112
+#define GL_SYNC_CONDITION                                0x9113
+#define GL_SYNC_STATUS                                   0x9114
+#define GL_SYNC_FLAGS                                    0x9115
+#define GL_SYNC_FENCE                                    0x9116
+#define GL_SYNC_GPU_COMMANDS_COMPLETE                    0x9117
+#define GL_UNSIGNALED                                    0x9118
+#define GL_SIGNALED                                      0x9119
+#define GL_ALREADY_SIGNALED                              0x911A
+#define GL_TIMEOUT_EXPIRED                               0x911B
+#define GL_CONDITION_SATISFIED                           0x911C
+#define GL_WAIT_FAILED                                   0x911D
+#define GL_SYNC_FLUSH_COMMANDS_BIT                       0x00000001
+#define GL_TIMEOUT_IGNORED                               0xFFFFFFFFFFFFFFFFull
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR                   0x88FE
+#define GL_ANY_SAMPLES_PASSED                            0x8C2F
+#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE               0x8D6A
+#define GL_SAMPLER_BINDING                               0x8919
+#define GL_RGB10_A2UI                                    0x906F
+#define GL_TEXTURE_SWIZZLE_R                             0x8E42
+#define GL_TEXTURE_SWIZZLE_G                             0x8E43
+#define GL_TEXTURE_SWIZZLE_B                             0x8E44
+#define GL_TEXTURE_SWIZZLE_A                             0x8E45
+#define GL_GREEN                                         0x1904
+#define GL_BLUE                                          0x1905
+#define GL_INT_2_10_10_10_REV                            0x8D9F
+#define GL_TRANSFORM_FEEDBACK                            0x8E22
+#define GL_TRANSFORM_FEEDBACK_PAUSED                     0x8E23
+#define GL_TRANSFORM_FEEDBACK_ACTIVE                     0x8E24
+#define GL_TRANSFORM_FEEDBACK_BINDING                    0x8E25
+#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT               0x8257
+#define GL_PROGRAM_BINARY_LENGTH                         0x8741
+#define GL_NUM_PROGRAM_BINARY_FORMATS                    0x87FE
+#define GL_PROGRAM_BINARY_FORMATS                        0x87FF
+#define GL_COMPRESSED_R11_EAC                            0x9270
+#define GL_COMPRESSED_SIGNED_R11_EAC                     0x9271
+#define GL_COMPRESSED_RG11_EAC                           0x9272
+#define GL_COMPRESSED_SIGNED_RG11_EAC                    0x9273
+#define GL_COMPRESSED_RGB8_ETC2                          0x9274
+#define GL_COMPRESSED_SRGB8_ETC2                         0x9275
+#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2      0x9276
+#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2     0x9277
+#define GL_COMPRESSED_RGBA8_ETC2_EAC                     0x9278
+#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC              0x9279
+#define GL_TEXTURE_IMMUTABLE_FORMAT                      0x912F
+#define GL_MAX_ELEMENT_INDEX                             0x8D6B
+#define GL_NUM_SAMPLE_COUNTS                             0x9380
+#define GL_TEXTURE_IMMUTABLE_LEVELS                      0x82DF
+
+/*-------------------------------------------------------------------------
+ * Entrypoint definitions
+ *-----------------------------------------------------------------------*/
+
+/* OpenGL ES 3.0 */
+
+extern GL_APICALL void           (* GL_APIENTRY glReadBuffer) (GLenum mode);
+extern GL_APICALL void           (* GL_APIENTRY glDrawRangeElements) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices);
+extern GL_APICALL void           (* GL_APIENTRY glTexImage3D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+extern GL_APICALL void           (* GL_APIENTRY glTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels);
+extern GL_APICALL void           (* GL_APIENTRY glCopyTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+extern GL_APICALL void           (* GL_APIENTRY glCompressedTexImage3D) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data);
+extern GL_APICALL void           (* GL_APIENTRY glCompressedTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data);
+extern GL_APICALL void           (* GL_APIENTRY glGenQueries) (GLsizei n, GLuint* ids);
+extern GL_APICALL void           (* GL_APIENTRY glDeleteQueries) (GLsizei n, const GLuint* ids);
+extern GL_APICALL GLboolean      (* GL_APIENTRY glIsQuery) (GLuint id);
+extern GL_APICALL void           (* GL_APIENTRY glBeginQuery) (GLenum target, GLuint id);
+extern GL_APICALL void           (* GL_APIENTRY glEndQuery) (GLenum target);
+extern GL_APICALL void           (* GL_APIENTRY glGetQueryiv) (GLenum target, GLenum pname, GLint* params);
+extern GL_APICALL void           (* GL_APIENTRY glGetQueryObjectuiv) (GLuint id, GLenum pname, GLuint* params);
+extern GL_APICALL GLboolean      (* GL_APIENTRY glUnmapBuffer) (GLenum target);
+extern GL_APICALL void           (* GL_APIENTRY glGetBufferPointerv) (GLenum target, GLenum pname, GLvoid** params);
+extern GL_APICALL void           (* GL_APIENTRY glDrawBuffers) (GLsizei n, const GLenum* bufs);
+extern GL_APICALL void           (* GL_APIENTRY glUniformMatrix2x3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+extern GL_APICALL void           (* GL_APIENTRY glUniformMatrix3x2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+extern GL_APICALL void           (* GL_APIENTRY glUniformMatrix2x4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+extern GL_APICALL void           (* GL_APIENTRY glUniformMatrix4x2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+extern GL_APICALL void           (* GL_APIENTRY glUniformMatrix3x4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+extern GL_APICALL void           (* GL_APIENTRY glUniformMatrix4x3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+extern GL_APICALL void           (* GL_APIENTRY glBlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+extern GL_APICALL void           (* GL_APIENTRY glRenderbufferStorageMultisample) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+extern GL_APICALL void           (* GL_APIENTRY glFramebufferTextureLayer) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+extern GL_APICALL GLvoid*        (* GL_APIENTRY glMapBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+extern GL_APICALL void           (* GL_APIENTRY glFlushMappedBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length);
+extern GL_APICALL void           (* GL_APIENTRY glBindVertexArray) (GLuint array);
+extern GL_APICALL void           (* GL_APIENTRY glDeleteVertexArrays) (GLsizei n, const GLuint* arrays);
+extern GL_APICALL void           (* GL_APIENTRY glGenVertexArrays) (GLsizei n, GLuint* arrays);
+extern GL_APICALL GLboolean      (* GL_APIENTRY glIsVertexArray) (GLuint array);
+extern GL_APICALL void           (* GL_APIENTRY glGetIntegeri_v) (GLenum target, GLuint index, GLint* data);
+extern GL_APICALL void           (* GL_APIENTRY glBeginTransformFeedback) (GLenum primitiveMode);
+extern GL_APICALL void           (* GL_APIENTRY glEndTransformFeedback) (void);
+extern GL_APICALL void           (* GL_APIENTRY glBindBufferRange) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+extern GL_APICALL void           (* GL_APIENTRY glBindBufferBase) (GLenum target, GLuint index, GLuint buffer);
+extern GL_APICALL void           (* GL_APIENTRY glTransformFeedbackVaryings) (GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode);
+extern GL_APICALL void           (* GL_APIENTRY glGetTransformFeedbackVarying) (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name);
+extern GL_APICALL void           (* GL_APIENTRY glVertexAttribIPointer) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
+extern GL_APICALL void           (* GL_APIENTRY glGetVertexAttribIiv) (GLuint index, GLenum pname, GLint* params);
+extern GL_APICALL void           (* GL_APIENTRY glGetVertexAttribIuiv) (GLuint index, GLenum pname, GLuint* params);
+extern GL_APICALL void           (* GL_APIENTRY glVertexAttribI4i) (GLuint index, GLint x, GLint y, GLint z, GLint w);
+extern GL_APICALL void           (* GL_APIENTRY glVertexAttribI4ui) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+extern GL_APICALL void           (* GL_APIENTRY glVertexAttribI4iv) (GLuint index, const GLint* v);
+extern GL_APICALL void           (* GL_APIENTRY glVertexAttribI4uiv) (GLuint index, const GLuint* v);
+extern GL_APICALL void           (* GL_APIENTRY glGetUniformuiv) (GLuint program, GLint location, GLuint* params);
+extern GL_APICALL GLint          (* GL_APIENTRY glGetFragDataLocation) (GLuint program, const GLchar *name);
+extern GL_APICALL void           (* GL_APIENTRY glUniform1ui) (GLint location, GLuint v0);
+extern GL_APICALL void           (* GL_APIENTRY glUniform2ui) (GLint location, GLuint v0, GLuint v1);
+extern GL_APICALL void           (* GL_APIENTRY glUniform3ui) (GLint location, GLuint v0, GLuint v1, GLuint v2);
+extern GL_APICALL void           (* GL_APIENTRY glUniform4ui) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+extern GL_APICALL void           (* GL_APIENTRY glUniform1uiv) (GLint location, GLsizei count, const GLuint* value);
+extern GL_APICALL void           (* GL_APIENTRY glUniform2uiv) (GLint location, GLsizei count, const GLuint* value);
+extern GL_APICALL void           (* GL_APIENTRY glUniform3uiv) (GLint location, GLsizei count, const GLuint* value);
+extern GL_APICALL void           (* GL_APIENTRY glUniform4uiv) (GLint location, GLsizei count, const GLuint* value);
+extern GL_APICALL void           (* GL_APIENTRY glClearBufferiv) (GLenum buffer, GLint drawbuffer, const GLint* value);
+extern GL_APICALL void           (* GL_APIENTRY glClearBufferuiv) (GLenum buffer, GLint drawbuffer, const GLuint* value);
+extern GL_APICALL void           (* GL_APIENTRY glClearBufferfv) (GLenum buffer, GLint drawbuffer, const GLfloat* value);
+extern GL_APICALL void           (* GL_APIENTRY glClearBufferfi) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+extern GL_APICALL const GLubyte* (* GL_APIENTRY glGetStringi) (GLenum name, GLuint index);
+extern GL_APICALL void           (* GL_APIENTRY glCopyBufferSubData) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+extern GL_APICALL void           (* GL_APIENTRY glGetUniformIndices) (GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices);
+extern GL_APICALL void           (* GL_APIENTRY glGetActiveUniformsiv) (GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params);
+extern GL_APICALL GLuint         (* GL_APIENTRY glGetUniformBlockIndex) (GLuint program, const GLchar* uniformBlockName);
+extern GL_APICALL void           (* GL_APIENTRY glGetActiveUniformBlockiv) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params);
+extern GL_APICALL void           (* GL_APIENTRY glGetActiveUniformBlockName) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName);
+extern GL_APICALL void           (* GL_APIENTRY glUniformBlockBinding) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+extern GL_APICALL void           (* GL_APIENTRY glDrawArraysInstanced) (GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
+extern GL_APICALL void           (* GL_APIENTRY glDrawElementsInstanced) (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount);
+extern GL_APICALL GLsync         (* GL_APIENTRY glFenceSync) (GLenum condition, GLbitfield flags);
+extern GL_APICALL GLboolean      (* GL_APIENTRY glIsSync) (GLsync sync);
+extern GL_APICALL void           (* GL_APIENTRY glDeleteSync) (GLsync sync);
+extern GL_APICALL GLenum         (* GL_APIENTRY glClientWaitSync) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+extern GL_APICALL void           (* GL_APIENTRY glWaitSync) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+extern GL_APICALL void           (* GL_APIENTRY glGetInteger64v) (GLenum pname, GLint64* params);
+extern GL_APICALL void           (* GL_APIENTRY glGetSynciv) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values);
+extern GL_APICALL void           (* GL_APIENTRY glGetInteger64i_v) (GLenum target, GLuint index, GLint64* data);
+extern GL_APICALL void           (* GL_APIENTRY glGetBufferParameteri64v) (GLenum target, GLenum pname, GLint64* params);
+extern GL_APICALL void           (* GL_APIENTRY glGenSamplers) (GLsizei count, GLuint* samplers);
+extern GL_APICALL void           (* GL_APIENTRY glDeleteSamplers) (GLsizei count, const GLuint* samplers);
+extern GL_APICALL GLboolean      (* GL_APIENTRY glIsSampler) (GLuint sampler);
+extern GL_APICALL void           (* GL_APIENTRY glBindSampler) (GLuint unit, GLuint sampler);
+extern GL_APICALL void           (* GL_APIENTRY glSamplerParameteri) (GLuint sampler, GLenum pname, GLint param);
+extern GL_APICALL void           (* GL_APIENTRY glSamplerParameteriv) (GLuint sampler, GLenum pname, const GLint* param);
+extern GL_APICALL void           (* GL_APIENTRY glSamplerParameterf) (GLuint sampler, GLenum pname, GLfloat param);
+extern GL_APICALL void           (* GL_APIENTRY glSamplerParameterfv) (GLuint sampler, GLenum pname, const GLfloat* param);
+extern GL_APICALL void           (* GL_APIENTRY glGetSamplerParameteriv) (GLuint sampler, GLenum pname, GLint* params);
+extern GL_APICALL void           (* GL_APIENTRY glGetSamplerParameterfv) (GLuint sampler, GLenum pname, GLfloat* params);
+extern GL_APICALL void           (* GL_APIENTRY glVertexAttribDivisor) (GLuint index, GLuint divisor);
+extern GL_APICALL void           (* GL_APIENTRY glBindTransformFeedback) (GLenum target, GLuint id);
+extern GL_APICALL void           (* GL_APIENTRY glDeleteTransformFeedbacks) (GLsizei n, const GLuint* ids);
+extern GL_APICALL void           (* GL_APIENTRY glGenTransformFeedbacks) (GLsizei n, GLuint* ids);
+extern GL_APICALL GLboolean      (* GL_APIENTRY glIsTransformFeedback) (GLuint id);
+extern GL_APICALL void           (* GL_APIENTRY glPauseTransformFeedback) (void);
+extern GL_APICALL void           (* GL_APIENTRY glResumeTransformFeedback) (void);
+extern GL_APICALL void           (* GL_APIENTRY glGetProgramBinary) (GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary);
+extern GL_APICALL void           (* GL_APIENTRY glProgramBinary) (GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length);
+extern GL_APICALL void           (* GL_APIENTRY glProgramParameteri) (GLuint program, GLenum pname, GLint value);
+extern GL_APICALL void           (* GL_APIENTRY glInvalidateFramebuffer) (GLenum target, GLsizei numAttachments, const GLenum* attachments);
+extern GL_APICALL void           (* GL_APIENTRY glInvalidateSubFramebuffer) (GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+extern GL_APICALL void           (* GL_APIENTRY glTexStorage2D) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+extern GL_APICALL void           (* GL_APIENTRY glTexStorage3D) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+extern GL_APICALL void           (* GL_APIENTRY glGetInternalformativ) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/ndk/platforms/android-18/samples/gles3jni/jni/gles3jni.cpp b/ndk/platforms/android-18/samples/gles3jni/jni/gles3jni.cpp
new file mode 100644
index 0000000..23f2b05
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/jni/gles3jni.cpp
@@ -0,0 +1,284 @@
+/*
+ * Copyright 2013 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 <jni.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "gles3jni.h"
+
+const Vertex QUAD[4] = {
+    // Square with diagonal < 2 so that it fits in a [-1 .. 1]^2 square
+    // regardless of rotation.
+    {{-0.7f, -0.7f}, {0x00, 0xFF, 0x00}},
+    {{ 0.7f, -0.7f}, {0x00, 0x00, 0xFF}},
+    {{-0.7f,  0.7f}, {0xFF, 0x00, 0x00}},
+    {{ 0.7f,  0.7f}, {0xFF, 0xFF, 0xFF}},
+};
+
+bool checkGlError(const char* funcName) {
+    GLint err = glGetError();
+    if (err != GL_NO_ERROR) {
+        ALOGE("GL error after %s(): 0x%08x\n", funcName, err);
+        return true;
+    }
+    return false;
+}
+
+GLuint createShader(GLenum shaderType, const char* src) {
+    GLuint shader = glCreateShader(shaderType);
+    if (!shader) {
+        checkGlError("glCreateShader");
+        return 0;
+    }
+    glShaderSource(shader, 1, &src, NULL);
+
+    GLint compiled = GL_FALSE;
+    glCompileShader(shader);
+    glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+    if (!compiled) {
+        GLint infoLogLen = 0;
+        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLen);
+        if (infoLogLen > 0) {
+            GLchar* infoLog = (GLchar*)malloc(infoLogLen);
+            if (infoLog) {
+                glGetShaderInfoLog(shader, infoLogLen, NULL, infoLog);
+                ALOGE("Could not compile %s shader:\n%s\n",
+                        shaderType == GL_VERTEX_SHADER ? "vertex" : "fragment",
+                        infoLog);
+                free(infoLog);
+            }
+        }
+        glDeleteShader(shader);
+        return 0;
+    }
+
+    return shader;
+}
+
+GLuint createProgram(const char* vtxSrc, const char* fragSrc) {
+    GLuint vtxShader = 0;
+    GLuint fragShader = 0;
+    GLuint program = 0;
+    GLint linked = GL_FALSE;
+
+    vtxShader = createShader(GL_VERTEX_SHADER, vtxSrc);
+    if (!vtxShader)
+        goto exit;
+
+    fragShader = createShader(GL_FRAGMENT_SHADER, fragSrc);
+    if (!fragShader)
+        goto exit;
+
+    program = glCreateProgram();
+    if (!program) {
+        checkGlError("glCreateProgram");
+        goto exit;
+    }
+    glAttachShader(program, vtxShader);
+    glAttachShader(program, fragShader);
+
+    glLinkProgram(program);
+    glGetProgramiv(program, GL_LINK_STATUS, &linked);
+    if (!linked) {
+        ALOGE("Could not link program");
+        GLint infoLogLen = 0;
+        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLen);
+        if (infoLogLen) {
+            GLchar* infoLog = (GLchar*)malloc(infoLogLen);
+            if (infoLog) {
+                glGetProgramInfoLog(program, infoLogLen, NULL, infoLog);
+                ALOGE("Could not link program:\n%s\n", infoLog);
+                free(infoLog);
+            }
+        }
+        glDeleteProgram(program);
+        program = 0;
+    }
+
+exit:
+    glDeleteShader(vtxShader);
+    glDeleteShader(fragShader);
+    return program;
+}
+
+static void printGlString(const char* name, GLenum s) {
+    const char* v = (const char*)glGetString(s);
+    ALOGV("GL %s: %s\n", name, v);
+}
+
+// ----------------------------------------------------------------------------
+
+Renderer::Renderer()
+:   mNumInstances(0),
+    mLastFrameNs(0)
+{
+    memset(mScale, 0, sizeof(mScale));
+    memset(mAngularVelocity, 0, sizeof(mAngularVelocity));
+    memset(mAngles, 0, sizeof(mAngles));
+}
+
+Renderer::~Renderer() {
+}
+
+void Renderer::resize(int w, int h) {
+    float* offsets = mapOffsetBuf();
+    calcSceneParams(w, h, offsets);
+    unmapOffsetBuf();
+
+    for (unsigned int i = 0; i < mNumInstances; i++) {
+        mAngles[i] = drand48() * TWO_PI;
+        mAngularVelocity[i] = MAX_ROT_SPEED * (2.0*drand48() - 1.0);
+    }
+
+    mLastFrameNs = 0;
+
+    glViewport(0, 0, w, h);
+}
+
+void Renderer::calcSceneParams(unsigned int w, unsigned int h,
+        float* offsets) {
+    // number of cells along the larger screen dimension
+    const float NCELLS_MAJOR = MAX_INSTANCES_PER_SIDE;
+    // cell size in scene space
+    const float CELL_SIZE = 2.0f / NCELLS_MAJOR;
+
+    // Calculations are done in "landscape", i.e. assuming dim[0] >= dim[1].
+    // Only at the end are values put in the opposite order if h > w.
+    const float dim[2] = {fmaxf(w,h), fminf(w,h)};
+    const float aspect[2] = {dim[0] / dim[1], dim[1] / dim[0]};
+    const float scene2clip[2] = {1.0f, aspect[0]};
+    const int ncells[2] = {
+            NCELLS_MAJOR,
+            (int)floorf(NCELLS_MAJOR * aspect[1])
+    };
+
+    float centers[2][MAX_INSTANCES_PER_SIDE];
+    for (int d = 0; d < 2; d++) {
+        float offset = -ncells[d] / NCELLS_MAJOR; // -1.0 for d=0
+        for (int i = 0; i < ncells[d]; i++) {
+            centers[d][i] = scene2clip[d] * (CELL_SIZE*(i + 0.5f) + offset);
+        }
+    }
+
+    int major = w >= h ? 0 : 1;
+    int minor = w >= h ? 1 : 0;
+    // outer product of centers[0] and centers[1]
+    for (int i = 0; i < ncells[0]; i++) {
+        for (int j = 0; j < ncells[1]; j++) {
+            int idx = i*ncells[1] + j;
+            offsets[2*idx + major] = centers[0][i];
+            offsets[2*idx + minor] = centers[1][j];
+        }
+    }
+
+    mNumInstances = ncells[0] * ncells[1];
+    mScale[major] = 0.5f * CELL_SIZE * scene2clip[0];
+    mScale[minor] = 0.5f * CELL_SIZE * scene2clip[1];
+}
+
+void Renderer::step() {
+    timespec now;
+    clock_gettime(CLOCK_MONOTONIC, &now);
+    uint64_t nowNs = now.tv_sec*1000000000ull + now.tv_nsec;
+
+    if (mLastFrameNs > 0) {
+        float dt = float(nowNs - mLastFrameNs) * 0.000000001f;
+
+        for (unsigned int i = 0; i < mNumInstances; i++) {
+            mAngles[i] += mAngularVelocity[i] * dt;
+            if (mAngles[i] >= TWO_PI) {
+                mAngles[i] -= TWO_PI;
+            } else if (mAngles[i] <= -TWO_PI) {
+                mAngles[i] += TWO_PI;
+            }
+        }
+
+        float* transforms = mapTransformBuf();
+        for (unsigned int i = 0; i < mNumInstances; i++) {
+            float s = sinf(mAngles[i]);
+            float c = cosf(mAngles[i]);
+            transforms[4*i + 0] =  c * mScale[0];
+            transforms[4*i + 1] =  s * mScale[1];
+            transforms[4*i + 2] = -s * mScale[0];
+            transforms[4*i + 3] =  c * mScale[1];
+        }
+        unmapTransformBuf();
+    }
+
+    mLastFrameNs = nowNs;
+}
+
+void Renderer::render() {
+    step();
+
+    glClearColor(0.2f, 0.2f, 0.3f, 1.0f);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    draw(mNumInstances);
+    checkGlError("Renderer::render");
+}
+
+// ----------------------------------------------------------------------------
+
+static Renderer* g_renderer = NULL;
+
+extern "C" {
+    JNIEXPORT void JNICALL Java_com_android_gles3jni_GLES3JNILib_init(JNIEnv* env, jobject obj);
+    JNIEXPORT void JNICALL Java_com_android_gles3jni_GLES3JNILib_resize(JNIEnv* env, jobject obj, jint width, jint height);
+    JNIEXPORT void JNICALL Java_com_android_gles3jni_GLES3JNILib_step(JNIEnv* env, jobject obj);
+};
+
+#if !defined(DYNAMIC_ES3)
+static GLboolean gl3stubInit() {
+    return GL_TRUE;
+}
+#endif
+
+JNIEXPORT void JNICALL
+Java_com_android_gles3jni_GLES3JNILib_init(JNIEnv* env, jobject obj) {
+    if (g_renderer) {
+        delete g_renderer;
+        g_renderer = NULL;
+    }
+
+    printGlString("Version", GL_VERSION);
+    printGlString("Vendor", GL_VENDOR);
+    printGlString("Renderer", GL_RENDERER);
+    printGlString("Extensions", GL_EXTENSIONS);
+
+    const char* versionStr = (const char*)glGetString(GL_VERSION);
+    if (strstr(versionStr, "OpenGL ES 3.") && gl3stubInit()) {
+        g_renderer = createES3Renderer();
+    } else if (strstr(versionStr, "OpenGL ES 2.")) {
+        g_renderer = createES2Renderer();
+    } else {
+        ALOGE("Unsupported OpenGL ES version");
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_com_android_gles3jni_GLES3JNILib_resize(JNIEnv* env, jobject obj, jint width, jint height) {
+    if (g_renderer) {
+        g_renderer->resize(width, height);
+    }
+}
+
+JNIEXPORT void JNICALL
+Java_com_android_gles3jni_GLES3JNILib_step(JNIEnv* env, jobject obj) {
+    if (g_renderer) {
+        g_renderer->render();
+    }
+}
diff --git a/ndk/platforms/android-18/samples/gles3jni/jni/gles3jni.h b/ndk/platforms/android-18/samples/gles3jni/jni/gles3jni.h
new file mode 100644
index 0000000..dde779c
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/jni/gles3jni.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2013 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.
+ */
+
+#ifndef GLES3JNI_H
+#define GLES3JNI_H 1
+
+#include <android/log.h>
+#include <math.h>
+
+#if DYNAMIC_ES3
+#include "gl3stub.h"
+#else
+#include <GLES3/gl3.h>
+#endif
+
+#define DEBUG 1
+
+#define LOG_TAG "GLES3JNI"
+#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
+#if DEBUG
+#define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
+#else
+#define ALOGV(...)
+#endif
+
+// ----------------------------------------------------------------------------
+// Types, functions, and data used by both ES2 and ES3 renderers.
+// Defined in gles3jni.cpp.
+
+#define MAX_INSTANCES_PER_SIDE 16
+#define MAX_INSTANCES   (MAX_INSTANCES_PER_SIDE * MAX_INSTANCES_PER_SIDE)
+#define TWO_PI          (2.0 * M_PI)
+#define MAX_ROT_SPEED   (0.3 * TWO_PI)
+
+// This demo uses three coordinate spaces:
+// - The model (a quad) is in a [-1 .. 1]^2 space
+// - Scene space is either
+//    landscape: [-1 .. 1] x [-1/(2*w/h) .. 1/(2*w/h)]
+//    portrait:  [-1/(2*h/w) .. 1/(2*h/w)] x [-1 .. 1]
+// - Clip space in OpenGL is [-1 .. 1]^2
+//
+// Conceptually, the quads are rotated in model space, then scaled (uniformly)
+// and translated to place them in scene space. Scene space is then
+// non-uniformly scaled to clip space. In practice the transforms are combined
+// so vertices go directly from model to clip space.
+
+struct Vertex {
+    GLfloat pos[2];
+    GLubyte rgba[4];
+};
+extern const Vertex QUAD[4];
+
+// returns true if a GL error occurred
+extern bool checkGlError(const char* funcName);
+extern GLuint createShader(GLenum shaderType, const char* src);
+extern GLuint createProgram(const char* vtxSrc, const char* fragSrc);
+
+// ----------------------------------------------------------------------------
+// Interface to the ES2 and ES3 renderers, used by JNI code.
+
+class Renderer {
+public:
+    virtual ~Renderer();
+    void resize(int w, int h);
+    void render();
+
+protected:
+    Renderer();
+
+    // return a pointer to a buffer of MAX_INSTANCES * sizeof(vec2).
+    // the buffer is filled with per-instance offsets, then unmapped.
+    virtual float* mapOffsetBuf() = 0;
+    virtual void unmapOffsetBuf() = 0;
+    // return a pointer to a buffer of MAX_INSTANCES * sizeof(vec4).
+    // the buffer is filled with per-instance scale and rotation transforms.
+    virtual float* mapTransformBuf() = 0;
+    virtual void unmapTransformBuf() = 0;
+
+    virtual void draw(unsigned int numInstances) = 0;
+
+private:
+    void calcSceneParams(unsigned int w, unsigned int h, float* offsets);
+    void step();
+
+    unsigned int mNumInstances;
+    float mScale[2];
+    float mAngularVelocity[MAX_INSTANCES];
+    uint64_t mLastFrameNs;
+    float mAngles[MAX_INSTANCES];
+};
+
+extern Renderer* createES2Renderer();
+extern Renderer* createES3Renderer();
+
+#endif // GLES3JNI_H
diff --git a/ndk/platforms/android-18/samples/gles3jni/res/values/strings.xml b/ndk/platforms/android-18/samples/gles3jni/res/values/strings.xml
new file mode 100644
index 0000000..375efc6
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/res/values/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2013 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.
+-->
+
+<!-- This file contains resource definitions for displayed strings, allowing
+     them to be changed based on the locale and options. -->
+
+<resources>
+    <!-- Simple strings. -->
+    <string name="gles3jni_activity">GLES3JNI</string>
+
+</resources>
diff --git a/ndk/platforms/android-18/samples/gles3jni/src/com/android/gles3jni/GLES3JNIActivity.java b/ndk/platforms/android-18/samples/gles3jni/src/com/android/gles3jni/GLES3JNIActivity.java
new file mode 100644
index 0000000..5427418
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/src/com/android/gles3jni/GLES3JNIActivity.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2013 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.
+ */
+
+package com.android.gles3jni;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.WindowManager;
+
+import java.io.File;
+
+public class GLES3JNIActivity extends Activity {
+
+    GLES3JNIView mView;
+
+    @Override protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        mView = new GLES3JNIView(getApplication());
+        setContentView(mView);
+    }
+
+    @Override protected void onPause() {
+        super.onPause();
+        mView.onPause();
+    }
+
+    @Override protected void onResume() {
+        super.onResume();
+        mView.onResume();
+    }
+}
diff --git a/ndk/platforms/android-18/samples/gles3jni/src/com/android/gles3jni/GLES3JNILib.java b/ndk/platforms/android-18/samples/gles3jni/src/com/android/gles3jni/GLES3JNILib.java
new file mode 100644
index 0000000..811658f
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/src/com/android/gles3jni/GLES3JNILib.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2013 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.
+ */
+
+package com.android.gles3jni;
+
+// Wrapper for native library
+
+public class GLES3JNILib {
+
+     static {
+         System.loadLibrary("gles3jni");
+     }
+
+     public static native void init();
+     public static native void resize(int width, int height);
+     public static native void step();
+}
diff --git a/ndk/platforms/android-18/samples/gles3jni/src/com/android/gles3jni/GLES3JNIView.java b/ndk/platforms/android-18/samples/gles3jni/src/com/android/gles3jni/GLES3JNIView.java
new file mode 100644
index 0000000..12624fd
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/src/com/android/gles3jni/GLES3JNIView.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2013 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.
+ */
+
+package com.android.gles3jni;
+
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.opengl.GLSurfaceView;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.opengles.GL10;
+
+class GLES3JNIView extends GLSurfaceView {
+    private static final String TAG = "GLES3JNI";
+    private static final boolean DEBUG = true;
+
+    public GLES3JNIView(Context context) {
+        super(context);
+        // Pick an EGLConfig with RGB8 color, 16-bit depth, no stencil,
+        // supporting OpenGL ES 2.0 or later backwards-compatible versions.
+        setEGLConfigChooser(8, 8, 8, 0, 16, 0);
+        setEGLContextClientVersion(2);
+        setRenderer(new Renderer());
+    }
+
+    private static class Renderer implements GLSurfaceView.Renderer {
+        public void onDrawFrame(GL10 gl) {
+            GLES3JNILib.step();
+        }
+
+        public void onSurfaceChanged(GL10 gl, int width, int height) {
+            GLES3JNILib.resize(width, height);
+        }
+
+        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+            GLES3JNILib.init();
+        }
+    }
+}