summaryrefslogtreecommitdiff
path: root/gfx/gl
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /gfx/gl
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloaduxp-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
Add m-esr52 at 52.6.0
Diffstat (limited to 'gfx/gl')
-rw-r--r--gfx/gl/AndroidSurfaceTexture.cpp260
-rw-r--r--gfx/gl/AndroidSurfaceTexture.h107
-rw-r--r--gfx/gl/DecomposeIntoNoRepeatTriangles.cpp173
-rw-r--r--gfx/gl/DecomposeIntoNoRepeatTriangles.h77
-rw-r--r--gfx/gl/EGLUtils.cpp114
-rw-r--r--gfx/gl/EGLUtils.h60
-rw-r--r--gfx/gl/ForceDiscreteGPUHelperCGL.h36
-rw-r--r--gfx/gl/GLBlitHelper.cpp1033
-rw-r--r--gfx/gl/GLBlitHelper.h168
-rw-r--r--gfx/gl/GLConsts.h5951
-rw-r--r--gfx/gl/GLContext.cpp3150
-rw-r--r--gfx/gl/GLContext.h3736
-rw-r--r--gfx/gl/GLContextCGL.h66
-rw-r--r--gfx/gl/GLContextEAGL.h79
-rw-r--r--gfx/gl/GLContextEGL.h142
-rw-r--r--gfx/gl/GLContextFeatures.cpp928
-rw-r--r--gfx/gl/GLContextGLX.h99
-rw-r--r--gfx/gl/GLContextProvider.h85
-rw-r--r--gfx/gl/GLContextProviderCGL.mm400
-rw-r--r--gfx/gl/GLContextProviderEAGL.mm281
-rw-r--r--gfx/gl/GLContextProviderEGL.cpp1025
-rw-r--r--gfx/gl/GLContextProviderGLX.cpp1421
-rw-r--r--gfx/gl/GLContextProviderImpl.h130
-rw-r--r--gfx/gl/GLContextProviderNull.cpp60
-rw-r--r--gfx/gl/GLContextProviderWGL.cpp651
-rw-r--r--gfx/gl/GLContextSymbols.h705
-rw-r--r--gfx/gl/GLContextTypes.cpp14
-rw-r--r--gfx/gl/GLContextTypes.h65
-rw-r--r--gfx/gl/GLContextWGL.h78
-rw-r--r--gfx/gl/GLDebugUtils.cpp59
-rw-r--r--gfx/gl/GLDebugUtils.h19
-rw-r--r--gfx/gl/GLDefs.h88
-rw-r--r--gfx/gl/GLLibraryEGL.cpp797
-rw-r--r--gfx/gl/GLLibraryEGL.h704
-rw-r--r--gfx/gl/GLLibraryLoader.cpp117
-rw-r--r--gfx/gl/GLLibraryLoader.h63
-rwxr-xr-xgfx/gl/GLParseRegistryXML.py216
-rw-r--r--gfx/gl/GLReadTexImageHelper.cpp659
-rw-r--r--gfx/gl/GLReadTexImageHelper.h89
-rwxr-xr-xgfx/gl/GLScreenBuffer.cpp1044
-rw-r--r--gfx/gl/GLScreenBuffer.h301
-rw-r--r--gfx/gl/GLTextureImage.cpp521
-rw-r--r--gfx/gl/GLTextureImage.h306
-rw-r--r--gfx/gl/GLTypes.h94
-rw-r--r--gfx/gl/GLUploadHelpers.cpp558
-rw-r--r--gfx/gl/GLUploadHelpers.h84
-rw-r--r--gfx/gl/GLXLibrary.h274
-rw-r--r--gfx/gl/GfxTexturesReporter.cpp82
-rw-r--r--gfx/gl/GfxTexturesReporter.h105
-rw-r--r--gfx/gl/HeapCopyOfStackArray.h47
-rw-r--r--gfx/gl/ScopedGLHelpers.cpp540
-rw-r--r--gfx/gl/ScopedGLHelpers.h368
-rw-r--r--gfx/gl/SharedSurface.cpp621
-rw-r--r--gfx/gl/SharedSurface.h333
-rw-r--r--gfx/gl/SharedSurfaceANGLE.cpp354
-rw-r--r--gfx/gl/SharedSurfaceANGLE.h101
-rw-r--r--gfx/gl/SharedSurfaceD3D11Interop.cpp425
-rw-r--r--gfx/gl/SharedSurfaceD3D11Interop.h100
-rw-r--r--gfx/gl/SharedSurfaceEGL.cpp191
-rw-r--r--gfx/gl/SharedSurfaceEGL.h118
-rw-r--r--gfx/gl/SharedSurfaceGL.cpp190
-rw-r--r--gfx/gl/SharedSurfaceGL.h167
-rw-r--r--gfx/gl/SharedSurfaceGLX.cpp144
-rw-r--r--gfx/gl/SharedSurfaceGLX.h68
-rw-r--r--gfx/gl/SharedSurfaceIO.cpp248
-rw-r--r--gfx/gl/SharedSurfaceIO.h100
-rwxr-xr-xgfx/gl/SkiaGLGlue.cpp327
-rwxr-xr-xgfx/gl/SkiaGLGlue.h64
-rw-r--r--gfx/gl/SurfaceTypes.cpp44
-rw-r--r--gfx/gl/SurfaceTypes.h98
-rw-r--r--gfx/gl/TextureGarbageBin.cpp45
-rw-r--r--gfx/gl/TextureGarbageBin.h47
-rw-r--r--gfx/gl/TextureImageEGL.cpp251
-rw-r--r--gfx/gl/TextureImageEGL.h88
-rw-r--r--gfx/gl/WGLLibrary.h131
-rw-r--r--gfx/gl/moz.build164
76 files changed, 32648 insertions, 0 deletions
diff --git a/gfx/gl/AndroidSurfaceTexture.cpp b/gfx/gl/AndroidSurfaceTexture.cpp
new file mode 100644
index 0000000000..3c8c81974a
--- /dev/null
+++ b/gfx/gl/AndroidSurfaceTexture.cpp
@@ -0,0 +1,260 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+// vim:set ts=2 sts=2 sw=2 et cin:
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifdef MOZ_WIDGET_ANDROID
+
+#include <map>
+#include <android/native_window_jni.h>
+#include <android/log.h>
+#include "AndroidSurfaceTexture.h"
+#include "gfxImageSurface.h"
+#include "gfxPrefs.h"
+#include "AndroidBridge.h"
+#include "nsThreadUtils.h"
+#include "mozilla/gfx/Matrix.h"
+#include "GeneratedJNINatives.h"
+#include "GLContext.h"
+
+using namespace mozilla;
+
+namespace mozilla {
+namespace gl {
+
+class AndroidSurfaceTexture::Listener
+ : public java::SurfaceTextureListener::Natives<Listener>
+{
+ using Base = java::SurfaceTextureListener::Natives<Listener>;
+
+ const nsCOMPtr<nsIRunnable> mCallback;
+
+public:
+ using Base::AttachNative;
+ using Base::DisposeNative;
+
+ Listener(nsIRunnable* aCallback) : mCallback(aCallback) {}
+
+ void OnFrameAvailable()
+ {
+ if (NS_IsMainThread()) {
+ mCallback->Run();
+ return;
+ }
+ NS_DispatchToMainThread(mCallback);
+ }
+};
+
+already_AddRefed<AndroidSurfaceTexture>
+AndroidSurfaceTexture::Create()
+{
+ return Create(nullptr, 0);
+}
+
+already_AddRefed<AndroidSurfaceTexture>
+AndroidSurfaceTexture::Create(GLContext* aContext, GLuint aTexture)
+{
+ RefPtr<AndroidSurfaceTexture> st = new AndroidSurfaceTexture();
+ if (!st->Init(aContext, aTexture)) {
+ printf_stderr("Failed to initialize AndroidSurfaceTexture");
+ st = nullptr;
+ }
+
+ return st.forget();
+}
+
+nsresult
+AndroidSurfaceTexture::Attach(GLContext* aContext, PRIntervalTime aTimeout)
+{
+ MonitorAutoLock lock(mMonitor);
+
+ if (mAttachedContext == aContext) {
+ NS_WARNING("Tried to attach same GLContext to AndroidSurfaceTexture");
+ return NS_OK;
+ }
+
+ if (!CanDetach()) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ while (mAttachedContext) {
+ // Wait until it's detached (or we time out)
+ if (NS_FAILED(lock.Wait(aTimeout))) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+ }
+
+ MOZ_ASSERT(aContext->IsOwningThreadCurrent(), "Trying to attach GLContext from different thread");
+
+ aContext->fGenTextures(1, &mTexture);
+
+ if (NS_FAILED(mSurfaceTexture->AttachToGLContext(mTexture))) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+ mAttachedContext = aContext;
+ mAttachedContext->MakeCurrent();
+
+ return NS_OK;
+}
+
+nsresult
+AndroidSurfaceTexture::Detach()
+{
+ MonitorAutoLock lock(mMonitor);
+
+ if (!CanDetach() ||
+ !mAttachedContext ||
+ !mAttachedContext->IsOwningThreadCurrent())
+ {
+ return NS_ERROR_FAILURE;
+ }
+
+ mAttachedContext->MakeCurrent();
+
+ mSurfaceTexture->DetachFromGLContext();
+
+ mTexture = 0;
+ mAttachedContext = nullptr;
+ lock.NotifyAll();
+ return NS_OK;
+}
+
+bool
+AndroidSurfaceTexture::CanDetach() const
+{
+ // The API for attach/detach only exists on 16+, and PowerVR has some sort of
+ // fencing issue. Additionally, attach/detach seems to be busted on at least
+ // some Mali adapters (400MP2 for sure, bug 1131793)
+ return AndroidBridge::Bridge()->GetAPIVersion() >= 16 &&
+ (!mAttachedContext || mAttachedContext->Vendor() != GLVendor::Imagination) &&
+ (!mAttachedContext || mAttachedContext->Vendor() != GLVendor::ARM /* Mali */) &&
+ gfxPrefs::SurfaceTextureDetachEnabled();
+}
+
+bool
+AndroidSurfaceTexture::Init(GLContext* aContext, GLuint aTexture)
+{
+
+ if (!aTexture && !CanDetach()) {
+ // We have no texture and cannot initialize detached, bail out
+ return false;
+ }
+
+ if (NS_WARN_IF(NS_FAILED(
+ java::sdk::SurfaceTexture::New(aTexture, ReturnTo(&mSurfaceTexture))))) {
+ return false;
+ }
+
+ if (!aTexture) {
+ mSurfaceTexture->DetachFromGLContext();
+ }
+
+ mAttachedContext = aContext;
+
+ if (NS_WARN_IF(NS_FAILED(
+ java::sdk::Surface::New(mSurfaceTexture, ReturnTo(&mSurface))))) {
+ return false;
+ }
+
+ mNativeWindow = ANativeWindow_fromSurface(jni::GetEnvForThread(),
+ mSurface.Get());
+ MOZ_ASSERT(mNativeWindow, "Failed to create native window from surface");
+
+ return true;
+}
+
+AndroidSurfaceTexture::AndroidSurfaceTexture()
+ : mTexture(0)
+ , mSurfaceTexture()
+ , mSurface()
+ , mAttachedContext(nullptr)
+ , mMonitor("AndroidSurfaceTexture")
+{
+}
+
+AndroidSurfaceTexture::~AndroidSurfaceTexture()
+{
+ if (mSurfaceTexture) {
+ SetFrameAvailableCallback(nullptr);
+ mSurfaceTexture = nullptr;
+ }
+
+ if (mNativeWindow) {
+ ANativeWindow_release(mNativeWindow);
+ mNativeWindow = nullptr;
+ }
+}
+
+void
+AndroidSurfaceTexture::UpdateTexImage()
+{
+ mSurfaceTexture->UpdateTexImage();
+}
+
+void
+AndroidSurfaceTexture::GetTransformMatrix(gfx::Matrix4x4& aMatrix) const
+{
+ JNIEnv* const env = jni::GetEnvForThread();
+
+ auto jarray = jni::FloatArray::LocalRef::Adopt(env, env->NewFloatArray(16));
+ mSurfaceTexture->GetTransformMatrix(jarray);
+
+ jfloat* array = env->GetFloatArrayElements(jarray.Get(), nullptr);
+
+ aMatrix._11 = array[0];
+ aMatrix._12 = array[1];
+ aMatrix._13 = array[2];
+ aMatrix._14 = array[3];
+
+ aMatrix._21 = array[4];
+ aMatrix._22 = array[5];
+ aMatrix._23 = array[6];
+ aMatrix._24 = array[7];
+
+ aMatrix._31 = array[8];
+ aMatrix._32 = array[9];
+ aMatrix._33 = array[10];
+ aMatrix._34 = array[11];
+
+ aMatrix._41 = array[12];
+ aMatrix._42 = array[13];
+ aMatrix._43 = array[14];
+ aMatrix._44 = array[15];
+
+ env->ReleaseFloatArrayElements(jarray.Get(), array, 0);
+}
+
+void
+AndroidSurfaceTexture::SetFrameAvailableCallback(nsIRunnable* aRunnable)
+{
+ java::SurfaceTextureListener::LocalRef newListener;
+
+ if (aRunnable) {
+ newListener = java::SurfaceTextureListener::New();
+ Listener::AttachNative(newListener, MakeUnique<Listener>(aRunnable));
+ }
+
+ if (aRunnable || mListener) {
+ MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
+ mSurfaceTexture->SetOnFrameAvailableListener(newListener)));
+ }
+
+ if (mListener) {
+ Listener::DisposeNative(java::SurfaceTextureListener::LocalRef(
+ newListener.Env(), mListener));
+ }
+
+ mListener = newListener;
+}
+
+void
+AndroidSurfaceTexture::SetDefaultSize(mozilla::gfx::IntSize size)
+{
+ mSurfaceTexture->SetDefaultBufferSize(size.width, size.height);
+}
+
+} // gl
+} // mozilla
+
+#endif // MOZ_WIDGET_ANDROID
diff --git a/gfx/gl/AndroidSurfaceTexture.h b/gfx/gl/AndroidSurfaceTexture.h
new file mode 100644
index 0000000000..056fab3263
--- /dev/null
+++ b/gfx/gl/AndroidSurfaceTexture.h
@@ -0,0 +1,107 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+// vim:set ts=2 sts=2 sw=2 et cin:
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef AndroidSurfaceTexture_h__
+#define AndroidSurfaceTexture_h__
+#ifdef MOZ_WIDGET_ANDROID
+
+#include <jni.h>
+#include <android/native_window.h>
+#include "nsIRunnable.h"
+#include "gfxPlatform.h"
+#include "GLDefs.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/gfx/MatrixFwd.h"
+#include "mozilla/Monitor.h"
+
+#include "GeneratedJNIWrappers.h"
+#include "SurfaceTexture.h"
+
+namespace mozilla {
+namespace gl {
+
+class GLContext;
+
+/**
+ * This class is a wrapper around Android's SurfaceTexture class.
+ * Usage is pretty much exactly like the Java class, so see
+ * the Android documentation for details.
+ */
+class AndroidSurfaceTexture {
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AndroidSurfaceTexture)
+
+public:
+
+ // The SurfaceTexture is created in an attached state. This method requires
+ // Android Ice Cream Sandwich.
+ static already_AddRefed<AndroidSurfaceTexture> Create(GLContext* aGLContext, GLuint aTexture);
+
+ // Here the SurfaceTexture will be created in a detached state. You must call
+ // Attach() with the GLContext you wish to composite with. It must be done
+ // on the thread where that GLContext is current. This method requires
+ // Android Jelly Bean.
+ static already_AddRefed<AndroidSurfaceTexture> Create();
+
+ // If we are on Jelly Bean, the SurfaceTexture can be detached and reattached
+ // to allow consumption from different GLContexts. It is recommended to only
+ // attach while you are consuming in order to allow this.
+ //
+ // Only one GLContext may be attached at any given time. If another is already
+ // attached, we try to wait for it to become detached.
+ nsresult Attach(GLContext* aContext, PRIntervalTime aTiemout = PR_INTERVAL_NO_TIMEOUT);
+
+ nsresult Detach();
+
+ // Ability to detach is based on API version (16+), and we also block PowerVR
+ // since it has some type of fencing problem. Bug 1100126.
+ bool CanDetach() const;
+
+ GLContext* AttachedContext() const { return mAttachedContext; }
+
+ ANativeWindow* NativeWindow() const {
+ return mNativeWindow;
+ }
+
+ // This attaches the updated data to the TEXTURE_EXTERNAL target
+ void UpdateTexImage();
+
+ void GetTransformMatrix(mozilla::gfx::Matrix4x4& aMatrix) const;
+
+ void SetDefaultSize(mozilla::gfx::IntSize size);
+
+ // The callback is guaranteed to be called on the main thread even
+ // if the upstream callback is received on a different thread
+ void SetFrameAvailableCallback(nsIRunnable* aRunnable);
+
+ GLuint Texture() const { return mTexture; }
+ const java::sdk::Surface::Ref& JavaSurface() const { return mSurface; }
+
+private:
+ class Listener;
+
+ AndroidSurfaceTexture();
+ ~AndroidSurfaceTexture();
+
+ bool Init(GLContext* aContext, GLuint aTexture);
+
+ GLuint mTexture;
+ java::sdk::SurfaceTexture::GlobalRef mSurfaceTexture;
+ java::sdk::Surface::GlobalRef mSurface;
+ java::SurfaceTextureListener::GlobalRef mListener;
+
+ GLContext* mAttachedContext;
+
+ ANativeWindow* mNativeWindow;
+
+ Monitor mMonitor;
+};
+
+}
+}
+
+
+#endif
+#endif
diff --git a/gfx/gl/DecomposeIntoNoRepeatTriangles.cpp b/gfx/gl/DecomposeIntoNoRepeatTriangles.cpp
new file mode 100644
index 0000000000..829c201870
--- /dev/null
+++ b/gfx/gl/DecomposeIntoNoRepeatTriangles.cpp
@@ -0,0 +1,173 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "DecomposeIntoNoRepeatTriangles.h"
+#include "gfxMatrix.h"
+
+namespace mozilla {
+namespace gl {
+
+void
+RectTriangles::AppendRectToCoordArray(InfallibleTArray<coord>& array,
+ GLfloat x0, GLfloat y0,
+ GLfloat x1, GLfloat y1)
+{
+ coord* v = array.AppendElements(6);
+
+ v[0].x = x0; v[0].y = y0;
+ v[1].x = x1; v[1].y = y0;
+ v[2].x = x0; v[2].y = y1;
+ v[3].x = x0; v[3].y = y1;
+ v[4].x = x1; v[4].y = y0;
+ v[5].x = x1; v[5].y = y1;
+}
+
+void
+RectTriangles::addRect(GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1,
+ GLfloat tx0, GLfloat ty0, GLfloat tx1, GLfloat ty1,
+ bool flip_y /* = false */)
+{
+ if (flip_y) {
+ std::swap(ty0, ty1);
+ }
+ AppendRectToCoordArray(mVertexCoords, x0, y0, x1, y1);
+ AppendRectToCoordArray(mTexCoords, tx0, ty0, tx1, ty1);
+}
+
+static GLfloat
+WrapTexCoord(GLfloat v)
+{
+ // This should return values in range [0, 1.0)
+ return v - floorf(v);
+}
+
+void
+DecomposeIntoNoRepeatTriangles(const gfx::IntRect& aTexCoordRect,
+ const gfx::IntSize& aTexSize,
+ RectTriangles& aRects,
+ bool aFlipY /* = false */)
+{
+ // normalize this
+ gfx::IntRect tcr(aTexCoordRect);
+ while (tcr.x >= aTexSize.width)
+ tcr.x -= aTexSize.width;
+ while (tcr.y >= aTexSize.height)
+ tcr.y -= aTexSize.height;
+
+ // Compute top left and bottom right tex coordinates
+ GLfloat tl[2] =
+ { GLfloat(tcr.x) / GLfloat(aTexSize.width),
+ GLfloat(tcr.y) / GLfloat(aTexSize.height) };
+ GLfloat br[2] =
+ { GLfloat(tcr.XMost()) / GLfloat(aTexSize.width),
+ GLfloat(tcr.YMost()) / GLfloat(aTexSize.height) };
+
+ // then check if we wrap in either the x or y axis; if we do,
+ // then also use fmod to figure out the "true" non-wrapping
+ // texture coordinates.
+
+ bool xwrap = false, ywrap = false;
+ if (tcr.x < 0 || tcr.x > aTexSize.width ||
+ tcr.XMost() < 0 || tcr.XMost() > aTexSize.width)
+ {
+ xwrap = true;
+ tl[0] = WrapTexCoord(tl[0]);
+ br[0] = WrapTexCoord(br[0]);
+ }
+
+ if (tcr.y < 0 || tcr.y > aTexSize.height ||
+ tcr.YMost() < 0 || tcr.YMost() > aTexSize.height)
+ {
+ ywrap = true;
+ tl[1] = WrapTexCoord(tl[1]);
+ br[1] = WrapTexCoord(br[1]);
+ }
+
+ NS_ASSERTION(tl[0] >= 0.0f && tl[0] <= 1.0f &&
+ tl[1] >= 0.0f && tl[1] <= 1.0f &&
+ br[0] >= 0.0f && br[0] <= 1.0f &&
+ br[1] >= 0.0f && br[1] <= 1.0f,
+ "Somehow generated invalid texture coordinates");
+
+ // If xwrap is false, the texture will be sampled from tl[0]
+ // .. br[0]. If xwrap is true, then it will be split into tl[0]
+ // .. 1.0, and 0.0 .. br[0]. Same for the Y axis. The
+ // destination rectangle is also split appropriately, according
+ // to the calculated xmid/ymid values.
+
+ // There isn't a 1:1 mapping between tex coords and destination coords;
+ // when computing midpoints, we have to take that into account. We
+ // need to map the texture coords, which are (in the wrap case):
+ // |tl->1| and |0->br| to the |0->1| range of the vertex coords. So
+ // we have the length (1-tl)+(br) that needs to map into 0->1.
+ // These are only valid if there is wrap involved, they won't be used
+ // otherwise.
+ GLfloat xlen = (1.0f - tl[0]) + br[0];
+ GLfloat ylen = (1.0f - tl[1]) + br[1];
+
+ NS_ASSERTION(!xwrap || xlen > 0.0f, "xlen isn't > 0, what's going on?");
+ NS_ASSERTION(!ywrap || ylen > 0.0f, "ylen isn't > 0, what's going on?");
+ NS_ASSERTION(aTexCoordRect.width <= aTexSize.width &&
+ aTexCoordRect.height <= aTexSize.height, "tex coord rect would cause tiling!");
+
+ if (!xwrap && !ywrap) {
+ aRects.addRect(0.0f, 0.0f,
+ 1.0f, 1.0f,
+ tl[0], tl[1],
+ br[0], br[1],
+ aFlipY);
+ } else if (!xwrap && ywrap) {
+ GLfloat ymid = (1.0f - tl[1]) / ylen;
+ aRects.addRect(0.0f, 0.0f,
+ 1.0f, ymid,
+ tl[0], tl[1],
+ br[0], 1.0f,
+ aFlipY);
+ aRects.addRect(0.0f, ymid,
+ 1.0f, 1.0f,
+ tl[0], 0.0f,
+ br[0], br[1],
+ aFlipY);
+ } else if (xwrap && !ywrap) {
+ GLfloat xmid = (1.0f - tl[0]) / xlen;
+ aRects.addRect(0.0f, 0.0f,
+ xmid, 1.0f,
+ tl[0], tl[1],
+ 1.0f, br[1],
+ aFlipY);
+ aRects.addRect(xmid, 0.0f,
+ 1.0f, 1.0f,
+ 0.0f, tl[1],
+ br[0], br[1],
+ aFlipY);
+ } else {
+ GLfloat xmid = (1.0f - tl[0]) / xlen;
+ GLfloat ymid = (1.0f - tl[1]) / ylen;
+ aRects.addRect(0.0f, 0.0f,
+ xmid, ymid,
+ tl[0], tl[1],
+ 1.0f, 1.0f,
+ aFlipY);
+ aRects.addRect(xmid, 0.0f,
+ 1.0f, ymid,
+ 0.0f, tl[1],
+ br[0], 1.0f,
+ aFlipY);
+ aRects.addRect(0.0f, ymid,
+ xmid, 1.0f,
+ tl[0], 0.0f,
+ 1.0f, br[1],
+ aFlipY);
+ aRects.addRect(xmid, ymid,
+ 1.0f, 1.0f,
+ 0.0f, 0.0f,
+ br[0], br[1],
+ aFlipY);
+ }
+}
+
+} // namespace gl
+} // namespace mozilla
diff --git a/gfx/gl/DecomposeIntoNoRepeatTriangles.h b/gfx/gl/DecomposeIntoNoRepeatTriangles.h
new file mode 100644
index 0000000000..f67d6f93e8
--- /dev/null
+++ b/gfx/gl/DecomposeIntoNoRepeatTriangles.h
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef DecomposeIntoNoRepeatTriangles_h_
+#define DecomposeIntoNoRepeatTriangles_h_
+
+#include "GLTypes.h"
+#include "nsRect.h"
+#include "nsTArray.h"
+
+namespace mozilla {
+namespace gl {
+
+/** Helper for DecomposeIntoNoRepeatTriangles
+ */
+class RectTriangles {
+public:
+ typedef struct { GLfloat x,y; } coord;
+
+ // Always pass texture coordinates upright. If you want to flip the
+ // texture coordinates emitted to the tex_coords array, set flip_y to
+ // true.
+ void addRect(GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1,
+ GLfloat tx0, GLfloat ty0, GLfloat tx1, GLfloat ty1,
+ bool flip_y = false);
+
+ /**
+ * these return a float pointer to the start of each array respectively.
+ * Use it for glVertexAttribPointer calls.
+ * We can return nullptr if we choose to use Vertex Buffer Objects here.
+ */
+ InfallibleTArray<coord>& vertCoords() {
+ return mVertexCoords;
+ }
+
+ InfallibleTArray<coord>& texCoords() {
+ return mTexCoords;
+ }
+
+ unsigned int elements() {
+ return mVertexCoords.Length();
+ }
+private:
+ // Reserve inline storage for one quad (2 triangles, 3 coords).
+ AutoTArray<coord, 6> mVertexCoords;
+ AutoTArray<coord, 6> mTexCoords;
+
+ static void
+ AppendRectToCoordArray(InfallibleTArray<coord>& array, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1);
+};
+
+/**
+ * Decompose drawing the possibly-wrapped aTexCoordRect rectangle
+ * of a texture of aTexSize into one or more rectangles (represented
+ * as 2 triangles) and associated tex coordinates, such that
+ * we don't have to use the REPEAT wrap mode. If aFlipY is true, the
+ * texture coordinates will be specified vertically flipped.
+ *
+ * The resulting triangle vertex coordinates will be in the space of
+ * (0.0, 0.0) to (1.0, 1.0) -- transform the coordinates appropriately
+ * if you need a different space.
+ *
+ * The resulting vertex coordinates should be drawn using GL_TRIANGLES,
+ * and rects.numRects * 3 * 6
+ */
+void DecomposeIntoNoRepeatTriangles(const gfx::IntRect& aTexCoordRect,
+ const gfx::IntSize& aTexSize,
+ RectTriangles& aRects,
+ bool aFlipY = false);
+
+} // namespace gl
+} // namespace mozilla
+
+#endif // DecomposeIntoNoRepeatTriangles_h_
diff --git a/gfx/gl/EGLUtils.cpp b/gfx/gl/EGLUtils.cpp
new file mode 100644
index 0000000000..bc55d7fb03
--- /dev/null
+++ b/gfx/gl/EGLUtils.cpp
@@ -0,0 +1,114 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "EGLUtils.h"
+
+#include "GLContextEGL.h"
+
+namespace mozilla {
+namespace gl {
+
+bool
+DoesEGLContextSupportSharingWithEGLImage(GLContext* gl)
+{
+ return sEGLLibrary.HasKHRImageBase() &&
+ sEGLLibrary.HasKHRImageTexture2D() &&
+ gl->IsExtensionSupported(GLContext::OES_EGL_image);
+}
+
+EGLImage
+CreateEGLImage(GLContext* gl, GLuint tex)
+{
+ MOZ_ASSERT(DoesEGLContextSupportSharingWithEGLImage(gl));
+
+ EGLClientBuffer clientBuffer = (EGLClientBuffer)((uint64_t)tex);
+ EGLContext eglContext = GLContextEGL::Cast(gl)->mContext;
+ EGLImage image = sEGLLibrary.fCreateImage(EGL_DISPLAY(),
+ eglContext,
+ LOCAL_EGL_GL_TEXTURE_2D,
+ clientBuffer,
+ nullptr);
+ return image;
+}
+
+////////////////////////////////////////////////////////////////////////
+// EGLImageWrapper
+
+/*static*/ EGLImageWrapper*
+EGLImageWrapper::Create(GLContext* gl, GLuint tex)
+{
+ MOZ_ASSERT(DoesEGLContextSupportSharingWithEGLImage(gl));
+
+ GLLibraryEGL& library = sEGLLibrary;
+ EGLDisplay display = EGL_DISPLAY();
+ EGLContext eglContext = GLContextEGL::Cast(gl)->mContext;
+ EGLClientBuffer clientBuffer = (EGLClientBuffer)((uint64_t)tex);
+ EGLImage image = library.fCreateImage(display,
+ eglContext,
+ LOCAL_EGL_GL_TEXTURE_2D,
+ clientBuffer,
+ nullptr);
+ if (!image) {
+#ifdef DEBUG
+ printf_stderr("Could not create EGL images: ERROR (0x%04x)\n",
+ sEGLLibrary.fGetError());
+#endif
+ return nullptr;
+ }
+
+ return new EGLImageWrapper(library, display, image);
+}
+
+EGLImageWrapper::~EGLImageWrapper()
+{
+ mLibrary.fDestroyImage(mDisplay, mImage);
+}
+
+bool
+EGLImageWrapper::FenceSync(GLContext* gl)
+{
+ MOZ_ASSERT(!mSync);
+
+ if (mLibrary.IsExtensionSupported(GLLibraryEGL::KHR_fence_sync)) {
+ mSync = mLibrary.fCreateSync(mDisplay,
+ LOCAL_EGL_SYNC_FENCE,
+ nullptr);
+ // We need to flush to make sure the sync object enters the command stream;
+ // we can't use EGL_SYNC_FLUSH_COMMANDS_BIT at wait time, because the wait
+ // happens on a different thread/context.
+ gl->fFlush();
+ }
+
+ if (!mSync) {
+ // we failed to create one, so just do a finish
+ gl->fFinish();
+ }
+
+ return true;
+}
+
+bool
+EGLImageWrapper::ClientWaitSync()
+{
+ if (!mSync) {
+ // if we have no sync object, then we did a Finish() earlier
+ return true;
+ }
+
+ // wait at most 1 second; this should really be never/rarely hit
+ const uint64_t ns_per_ms = 1000 * 1000;
+ EGLTime timeout = 1000 * ns_per_ms;
+
+ EGLint result = mLibrary.fClientWaitSync(mDisplay,
+ mSync,
+ 0,
+ timeout);
+ mLibrary.fDestroySync(mDisplay, mSync);
+ mSync = nullptr;
+
+ return result == LOCAL_EGL_CONDITION_SATISFIED;
+}
+
+} // namespace gl
+} // namespace mozilla
diff --git a/gfx/gl/EGLUtils.h b/gfx/gl/EGLUtils.h
new file mode 100644
index 0000000000..71ca01e9cb
--- /dev/null
+++ b/gfx/gl/EGLUtils.h
@@ -0,0 +1,60 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef EGLUTILS_H_
+#define EGLUTILS_H_
+
+#include "GLContextTypes.h"
+#include "GLTypes.h"
+#include "mozilla/Assertions.h"
+
+namespace mozilla {
+namespace gl {
+
+class GLLibraryEGL;
+
+bool DoesEGLContextSupportSharingWithEGLImage(GLContext* gl);
+EGLImage CreateEGLImage(GLContext* gl, GLuint tex);
+
+////////////////////////////////////////////////////////////////////////
+// EGLImageWrapper
+
+class EGLImageWrapper
+{
+public:
+ static EGLImageWrapper* Create(GLContext* gl, GLuint tex);
+
+private:
+ GLLibraryEGL& mLibrary;
+ const EGLDisplay mDisplay;
+public:
+ const EGLImage mImage;
+private:
+ EGLSync mSync;
+
+ EGLImageWrapper(GLLibraryEGL& library,
+ EGLDisplay display,
+ EGLImage image)
+ : mLibrary(library)
+ , mDisplay(display)
+ , mImage(image)
+ , mSync(0)
+ {
+ MOZ_ASSERT(mImage);
+ }
+
+public:
+ ~EGLImageWrapper();
+
+ // Insert a sync point on the given context, which should be the current active
+ // context.
+ bool FenceSync(GLContext* gl);
+
+ bool ClientWaitSync();
+};
+
+} // namespace gl
+} // namespace mozilla
+
+#endif
diff --git a/gfx/gl/ForceDiscreteGPUHelperCGL.h b/gfx/gl/ForceDiscreteGPUHelperCGL.h
new file mode 100644
index 0000000000..3b4cb07efa
--- /dev/null
+++ b/gfx/gl/ForceDiscreteGPUHelperCGL.h
@@ -0,0 +1,36 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef ForceDiscreteGPUHelperCGL_h_
+#define ForceDiscreteGPUHelperCGL_h_
+
+#include <OpenGL/OpenGL.h>
+
+/** This RAII helper guarantees that we're on the discrete GPU during its lifetime.
+ *
+ * As long as any ForceDiscreteGPUHelperCGL object is alive, we're on the discrete GPU.
+ */
+class ForceDiscreteGPUHelperCGL
+{
+ CGLPixelFormatObj mPixelFormatObj;
+
+public:
+ ForceDiscreteGPUHelperCGL()
+ {
+ // the code in this function is taken from Chromium, src/ui/gfx/gl/gl_context_cgl.cc, r122013
+ // BSD-style license, (c) The Chromium Authors
+ CGLPixelFormatAttribute attribs[1];
+ attribs[0] = static_cast<CGLPixelFormatAttribute>(0);
+ GLint num_pixel_formats = 0;
+ CGLChoosePixelFormat(attribs, &mPixelFormatObj, &num_pixel_formats);
+ }
+
+ ~ForceDiscreteGPUHelperCGL()
+ {
+ CGLReleasePixelFormat(mPixelFormatObj);
+ }
+};
+
+#endif // ForceDiscreteGPUHelperCGL_h_
diff --git a/gfx/gl/GLBlitHelper.cpp b/gfx/gl/GLBlitHelper.cpp
new file mode 100644
index 0000000000..cffa5fbe56
--- /dev/null
+++ b/gfx/gl/GLBlitHelper.cpp
@@ -0,0 +1,1033 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gfxUtils.h"
+#include "GLBlitHelper.h"
+#include "GLContext.h"
+#include "GLScreenBuffer.h"
+#include "ScopedGLHelpers.h"
+#include "mozilla/Preferences.h"
+#include "ImageContainer.h"
+#include "HeapCopyOfStackArray.h"
+#include "mozilla/gfx/Matrix.h"
+#include "mozilla/UniquePtr.h"
+
+#ifdef MOZ_WIDGET_ANDROID
+#include "AndroidSurfaceTexture.h"
+#include "GLImages.h"
+#include "GLLibraryEGL.h"
+#endif
+
+#ifdef XP_MACOSX
+#include "MacIOSurfaceImage.h"
+#include "GLContextCGL.h"
+#endif
+
+using mozilla::layers::PlanarYCbCrImage;
+using mozilla::layers::PlanarYCbCrData;
+
+namespace mozilla {
+namespace gl {
+
+GLBlitHelper::GLBlitHelper(GLContext* gl)
+ : mGL(gl)
+ , mTexBlit_Buffer(0)
+ , mTexBlit_VertShader(0)
+ , mTex2DBlit_FragShader(0)
+ , mTex2DRectBlit_FragShader(0)
+ , mTex2DBlit_Program(0)
+ , mTex2DRectBlit_Program(0)
+ , mYFlipLoc(-1)
+ , mTextureTransformLoc(-1)
+ , mTexExternalBlit_FragShader(0)
+ , mTexYUVPlanarBlit_FragShader(0)
+ , mTexNV12PlanarBlit_FragShader(0)
+ , mTexExternalBlit_Program(0)
+ , mTexYUVPlanarBlit_Program(0)
+ , mTexNV12PlanarBlit_Program(0)
+ , mFBO(0)
+ , mSrcTexY(0)
+ , mSrcTexCb(0)
+ , mSrcTexCr(0)
+ , mSrcTexEGL(0)
+ , mYTexScaleLoc(-1)
+ , mCbCrTexScaleLoc(-1)
+ , mYuvColorMatrixLoc(-1)
+ , mTexWidth(0)
+ , mTexHeight(0)
+ , mCurYScale(1.0f)
+ , mCurCbCrScale(1.0f)
+{
+}
+
+GLBlitHelper::~GLBlitHelper()
+{
+ if (!mGL->MakeCurrent())
+ return;
+
+ DeleteTexBlitProgram();
+
+ GLuint tex[] = {
+ mSrcTexY,
+ mSrcTexCb,
+ mSrcTexCr,
+ mSrcTexEGL,
+ };
+
+ mSrcTexY = mSrcTexCb = mSrcTexCr = mSrcTexEGL = 0;
+ mGL->fDeleteTextures(ArrayLength(tex), tex);
+
+ if (mFBO) {
+ mGL->fDeleteFramebuffers(1, &mFBO);
+ }
+ mFBO = 0;
+}
+
+// Allowed to be destructive of state we restore in functions below.
+bool
+GLBlitHelper::InitTexQuadProgram(BlitType target)
+{
+ const char kTexBlit_VertShaderSource[] = "\
+ #version 100 \n\
+ #ifdef GL_ES \n\
+ precision mediump float; \n\
+ #endif \n\
+ attribute vec2 aPosition; \n\
+ \n\
+ uniform float uYflip; \n\
+ varying vec2 vTexCoord; \n\
+ \n\
+ void main(void) \n\
+ { \n\
+ vTexCoord = aPosition; \n\
+ vTexCoord.y = abs(vTexCoord.y - uYflip); \n\
+ vec2 vertPos = aPosition * 2.0 - 1.0; \n\
+ gl_Position = vec4(vertPos, 0.0, 1.0); \n\
+ } \n\
+ ";
+
+ const char kTex2DBlit_FragShaderSource[] = "\
+ #version 100 \n\
+ #ifdef GL_ES \n\
+ #ifdef GL_FRAGMENT_PRECISION_HIGH \n\
+ precision highp float; \n\
+ #else \n\
+ precision mediump float; \n\
+ #endif \n\
+ #endif \n\
+ uniform sampler2D uTexUnit; \n\
+ \n\
+ varying vec2 vTexCoord; \n\
+ \n\
+ void main(void) \n\
+ { \n\
+ gl_FragColor = texture2D(uTexUnit, vTexCoord); \n\
+ } \n\
+ ";
+
+ const char kTex2DRectBlit_FragShaderSource[] = "\
+ #version 100 \n\
+ #ifdef GL_FRAGMENT_PRECISION_HIGH \n\
+ precision highp float; \n\
+ #else \n\
+ precision mediump float; \n\
+ #endif \n\
+ \n\
+ uniform sampler2D uTexUnit; \n\
+ uniform vec2 uTexCoordMult; \n\
+ \n\
+ varying vec2 vTexCoord; \n\
+ \n\
+ void main(void) \n\
+ { \n\
+ gl_FragColor = texture2DRect(uTexUnit, \n\
+ vTexCoord * uTexCoordMult); \n\
+ } \n\
+ ";
+#ifdef ANDROID /* MOZ_WIDGET_ANDROID */
+ const char kTexExternalBlit_FragShaderSource[] = "\
+ #version 100 \n\
+ #extension GL_OES_EGL_image_external : require \n\
+ #ifdef GL_FRAGMENT_PRECISION_HIGH \n\
+ precision highp float; \n\
+ #else \n\
+ precision mediump float; \n\
+ #endif \n\
+ varying vec2 vTexCoord; \n\
+ uniform mat4 uTextureTransform; \n\
+ uniform samplerExternalOES uTexUnit; \n\
+ \n\
+ void main() \n\
+ { \n\
+ gl_FragColor = texture2D(uTexUnit, \n\
+ (uTextureTransform * vec4(vTexCoord, 0.0, 1.0)).xy); \n\
+ } \n\
+ ";
+#endif
+ /* From Rec601:
+ [R] [1.1643835616438356, 0.0, 1.5960267857142858] [ Y - 16]
+ [G] = [1.1643835616438358, -0.3917622900949137, -0.8129676472377708] x [Cb - 128]
+ [B] [1.1643835616438356, 2.017232142857143, 8.862867620416422e-17] [Cr - 128]
+
+ For [0,1] instead of [0,255], and to 5 places:
+ [R] [1.16438, 0.00000, 1.59603] [ Y - 0.06275]
+ [G] = [1.16438, -0.39176, -0.81297] x [Cb - 0.50196]
+ [B] [1.16438, 2.01723, 0.00000] [Cr - 0.50196]
+
+ From Rec709:
+ [R] [1.1643835616438356, 4.2781193979771426e-17, 1.7927410714285714] [ Y - 16]
+ [G] = [1.1643835616438358, -0.21324861427372963, -0.532909328559444] x [Cb - 128]
+ [B] [1.1643835616438356, 2.1124017857142854, 0.0] [Cr - 128]
+
+ For [0,1] instead of [0,255], and to 5 places:
+ [R] [1.16438, 0.00000, 1.79274] [ Y - 0.06275]
+ [G] = [1.16438, -0.21325, -0.53291] x [Cb - 0.50196]
+ [B] [1.16438, 2.11240, 0.00000] [Cr - 0.50196]
+ */
+ const char kTexYUVPlanarBlit_FragShaderSource[] = "\
+ #version 100 \n\
+ #ifdef GL_ES \n\
+ precision mediump float; \n\
+ #endif \n\
+ varying vec2 vTexCoord; \n\
+ uniform sampler2D uYTexture; \n\
+ uniform sampler2D uCbTexture; \n\
+ uniform sampler2D uCrTexture; \n\
+ uniform vec2 uYTexScale; \n\
+ uniform vec2 uCbCrTexScale; \n\
+ uniform mat3 uYuvColorMatrix; \n\
+ void main() \n\
+ { \n\
+ float y = texture2D(uYTexture, vTexCoord * uYTexScale).r; \n\
+ float cb = texture2D(uCbTexture, vTexCoord * uCbCrTexScale).r; \n\
+ float cr = texture2D(uCrTexture, vTexCoord * uCbCrTexScale).r; \n\
+ y = y - 0.06275; \n\
+ cb = cb - 0.50196; \n\
+ cr = cr - 0.50196; \n\
+ vec3 yuv = vec3(y, cb, cr); \n\
+ gl_FragColor.rgb = uYuvColorMatrix * yuv; \n\
+ gl_FragColor.a = 1.0; \n\
+ } \n\
+ ";
+
+#ifdef XP_MACOSX
+ const char kTexNV12PlanarBlit_FragShaderSource[] = "\
+ #version 100 \n\
+ #extension GL_ARB_texture_rectangle : require \n\
+ #ifdef GL_ES \n\
+ precision mediump float \n\
+ #endif \n\
+ varying vec2 vTexCoord; \n\
+ uniform sampler2DRect uYTexture; \n\
+ uniform sampler2DRect uCbCrTexture; \n\
+ uniform vec2 uYTexScale; \n\
+ uniform vec2 uCbCrTexScale; \n\
+ void main() \n\
+ { \n\
+ float y = texture2DRect(uYTexture, vTexCoord * uYTexScale).r; \n\
+ float cb = texture2DRect(uCbCrTexture, vTexCoord * uCbCrTexScale).r; \n\
+ float cr = texture2DRect(uCbCrTexture, vTexCoord * uCbCrTexScale).a; \n\
+ y = (y - 0.06275) * 1.16438; \n\
+ cb = cb - 0.50196; \n\
+ cr = cr - 0.50196; \n\
+ gl_FragColor.r = y + cr * 1.59603; \n\
+ gl_FragColor.g = y - 0.81297 * cr - 0.39176 * cb; \n\
+ gl_FragColor.b = y + cb * 2.01723; \n\
+ gl_FragColor.a = 1.0; \n\
+ } \n\
+ ";
+#endif
+
+ bool success = false;
+
+ GLuint* programPtr;
+ GLuint* fragShaderPtr;
+ const char* fragShaderSource;
+ switch (target) {
+ case ConvertEGLImage:
+ case BlitTex2D:
+ programPtr = &mTex2DBlit_Program;
+ fragShaderPtr = &mTex2DBlit_FragShader;
+ fragShaderSource = kTex2DBlit_FragShaderSource;
+ break;
+ case BlitTexRect:
+ programPtr = &mTex2DRectBlit_Program;
+ fragShaderPtr = &mTex2DRectBlit_FragShader;
+ fragShaderSource = kTex2DRectBlit_FragShaderSource;
+ break;
+#ifdef ANDROID
+ case ConvertSurfaceTexture:
+ case ConvertGralloc:
+ programPtr = &mTexExternalBlit_Program;
+ fragShaderPtr = &mTexExternalBlit_FragShader;
+ fragShaderSource = kTexExternalBlit_FragShaderSource;
+ break;
+#endif
+ case ConvertPlanarYCbCr:
+ programPtr = &mTexYUVPlanarBlit_Program;
+ fragShaderPtr = &mTexYUVPlanarBlit_FragShader;
+ fragShaderSource = kTexYUVPlanarBlit_FragShaderSource;
+ break;
+#ifdef XP_MACOSX
+ case ConvertMacIOSurfaceImage:
+ programPtr = &mTexNV12PlanarBlit_Program;
+ fragShaderPtr = &mTexNV12PlanarBlit_FragShader;
+ fragShaderSource = kTexNV12PlanarBlit_FragShaderSource;
+ break;
+#endif
+ default:
+ return false;
+ }
+
+ GLuint& program = *programPtr;
+ GLuint& fragShader = *fragShaderPtr;
+
+ // Use do-while(false) to let us break on failure
+ do {
+ if (program) {
+ // Already have it...
+ success = true;
+ break;
+ }
+
+ if (!mTexBlit_Buffer) {
+
+ /* CCW tri-strip:
+ * 2---3
+ * | \ |
+ * 0---1
+ */
+ GLfloat verts[] = {
+ 0.0f, 0.0f,
+ 1.0f, 0.0f,
+ 0.0f, 1.0f,
+ 1.0f, 1.0f
+ };
+ HeapCopyOfStackArray<GLfloat> vertsOnHeap(verts);
+
+ MOZ_ASSERT(!mTexBlit_Buffer);
+ mGL->fGenBuffers(1, &mTexBlit_Buffer);
+ mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mTexBlit_Buffer);
+
+ // Make sure we have a sane size.
+ mGL->fBufferData(LOCAL_GL_ARRAY_BUFFER, vertsOnHeap.ByteLength(), vertsOnHeap.Data(), LOCAL_GL_STATIC_DRAW);
+ }
+
+ if (!mTexBlit_VertShader) {
+
+ const char* vertShaderSource = kTexBlit_VertShaderSource;
+
+ mTexBlit_VertShader = mGL->fCreateShader(LOCAL_GL_VERTEX_SHADER);
+ mGL->fShaderSource(mTexBlit_VertShader, 1, &vertShaderSource, nullptr);
+ mGL->fCompileShader(mTexBlit_VertShader);
+ }
+
+ MOZ_ASSERT(!fragShader);
+ fragShader = mGL->fCreateShader(LOCAL_GL_FRAGMENT_SHADER);
+ mGL->fShaderSource(fragShader, 1, &fragShaderSource, nullptr);
+ mGL->fCompileShader(fragShader);
+
+ program = mGL->fCreateProgram();
+ mGL->fAttachShader(program, mTexBlit_VertShader);
+ mGL->fAttachShader(program, fragShader);
+ mGL->fBindAttribLocation(program, 0, "aPosition");
+ mGL->fLinkProgram(program);
+
+ if (GLContext::ShouldSpew()) {
+ GLint status = 0;
+ mGL->fGetShaderiv(mTexBlit_VertShader, LOCAL_GL_COMPILE_STATUS, &status);
+ if (status != LOCAL_GL_TRUE) {
+ NS_ERROR("Vert shader compilation failed.");
+
+ GLint length = 0;
+ mGL->fGetShaderiv(mTexBlit_VertShader, LOCAL_GL_INFO_LOG_LENGTH, &length);
+ if (!length) {
+ printf_stderr("No shader info log available.\n");
+ break;
+ }
+
+ auto buffer = MakeUnique<char[]>(length);
+ mGL->fGetShaderInfoLog(mTexBlit_VertShader, length, nullptr, buffer.get());
+
+ printf_stderr("Shader info log (%d bytes): %s\n", length, buffer.get());
+ break;
+ }
+
+ status = 0;
+ mGL->fGetShaderiv(fragShader, LOCAL_GL_COMPILE_STATUS, &status);
+ if (status != LOCAL_GL_TRUE) {
+ NS_ERROR("Frag shader compilation failed.");
+
+ GLint length = 0;
+ mGL->fGetShaderiv(fragShader, LOCAL_GL_INFO_LOG_LENGTH, &length);
+ if (!length) {
+ printf_stderr("No shader info log available.\n");
+ break;
+ }
+
+ auto buffer = MakeUnique<char[]>(length);
+ mGL->fGetShaderInfoLog(fragShader, length, nullptr, buffer.get());
+
+ printf_stderr("Shader info log (%d bytes): %s\n", length, buffer.get());
+ break;
+ }
+ }
+
+ GLint status = 0;
+ mGL->fGetProgramiv(program, LOCAL_GL_LINK_STATUS, &status);
+ if (status != LOCAL_GL_TRUE) {
+ if (GLContext::ShouldSpew()) {
+ NS_ERROR("Linking blit program failed.");
+ GLint length = 0;
+ mGL->fGetProgramiv(program, LOCAL_GL_INFO_LOG_LENGTH, &length);
+ if (!length) {
+ printf_stderr("No program info log available.\n");
+ break;
+ }
+
+ auto buffer = MakeUnique<char[]>(length);
+ mGL->fGetProgramInfoLog(program, length, nullptr, buffer.get());
+
+ printf_stderr("Program info log (%d bytes): %s\n", length, buffer.get());
+ }
+ break;
+ }
+
+ // Cache and set attribute and uniform
+ mGL->fUseProgram(program);
+ switch (target) {
+#ifdef ANDROID
+ case ConvertSurfaceTexture:
+ case ConvertGralloc:
+#endif
+ case BlitTex2D:
+ case BlitTexRect:
+ case ConvertEGLImage: {
+ GLint texUnitLoc = mGL->fGetUniformLocation(program, "uTexUnit");
+ MOZ_ASSERT(texUnitLoc != -1, "uniform uTexUnit not found");
+ mGL->fUniform1i(texUnitLoc, 0);
+ break;
+ }
+ case ConvertPlanarYCbCr: {
+ GLint texY = mGL->fGetUniformLocation(program, "uYTexture");
+ GLint texCb = mGL->fGetUniformLocation(program, "uCbTexture");
+ GLint texCr = mGL->fGetUniformLocation(program, "uCrTexture");
+ mYTexScaleLoc = mGL->fGetUniformLocation(program, "uYTexScale");
+ mCbCrTexScaleLoc = mGL->fGetUniformLocation(program, "uCbCrTexScale");
+ mYuvColorMatrixLoc = mGL->fGetUniformLocation(program, "uYuvColorMatrix");
+
+ DebugOnly<bool> hasUniformLocations = texY != -1 &&
+ texCb != -1 &&
+ texCr != -1 &&
+ mYTexScaleLoc != -1 &&
+ mCbCrTexScaleLoc != -1 &&
+ mYuvColorMatrixLoc != -1;
+ MOZ_ASSERT(hasUniformLocations, "uniforms not found");
+
+ mGL->fUniform1i(texY, Channel_Y);
+ mGL->fUniform1i(texCb, Channel_Cb);
+ mGL->fUniform1i(texCr, Channel_Cr);
+ break;
+ }
+ case ConvertMacIOSurfaceImage: {
+#ifdef XP_MACOSX
+ GLint texY = mGL->fGetUniformLocation(program, "uYTexture");
+ GLint texCbCr = mGL->fGetUniformLocation(program, "uCbCrTexture");
+ mYTexScaleLoc = mGL->fGetUniformLocation(program, "uYTexScale");
+ mCbCrTexScaleLoc= mGL->fGetUniformLocation(program, "uCbCrTexScale");
+
+ DebugOnly<bool> hasUniformLocations = texY != -1 &&
+ texCbCr != -1 &&
+ mYTexScaleLoc != -1 &&
+ mCbCrTexScaleLoc != -1;
+ MOZ_ASSERT(hasUniformLocations, "uniforms not found");
+
+ mGL->fUniform1i(texY, Channel_Y);
+ mGL->fUniform1i(texCbCr, Channel_Cb);
+#endif
+ break;
+ }
+ default:
+ return false;
+ }
+ MOZ_ASSERT(mGL->fGetAttribLocation(program, "aPosition") == 0);
+ mYFlipLoc = mGL->fGetUniformLocation(program, "uYflip");
+ MOZ_ASSERT(mYFlipLoc != -1, "uniform: uYflip not found");
+ mTextureTransformLoc = mGL->fGetUniformLocation(program, "uTextureTransform");
+ if (mTextureTransformLoc >= 0) {
+ // Set identity matrix as default
+ gfx::Matrix4x4 identity;
+ mGL->fUniformMatrix4fv(mTextureTransformLoc, 1, false, &identity._11);
+ }
+ success = true;
+ } while (false);
+
+ if (!success) {
+ // Clean up:
+ DeleteTexBlitProgram();
+ return false;
+ }
+
+ mGL->fUseProgram(program);
+ mGL->fEnableVertexAttribArray(0);
+ mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mTexBlit_Buffer);
+ mGL->fVertexAttribPointer(0,
+ 2,
+ LOCAL_GL_FLOAT,
+ false,
+ 0,
+ nullptr);
+ return true;
+}
+
+bool
+GLBlitHelper::UseTexQuadProgram(BlitType target, const gfx::IntSize& srcSize)
+{
+ if (!InitTexQuadProgram(target)) {
+ return false;
+ }
+
+ if (target == BlitTexRect) {
+ GLint texCoordMultLoc = mGL->fGetUniformLocation(mTex2DRectBlit_Program, "uTexCoordMult");
+ MOZ_ASSERT(texCoordMultLoc != -1, "uniform not found");
+ mGL->fUniform2f(texCoordMultLoc, srcSize.width, srcSize.height);
+ }
+
+ return true;
+}
+
+void
+GLBlitHelper::DeleteTexBlitProgram()
+{
+ if (mTexBlit_Buffer) {
+ mGL->fDeleteBuffers(1, &mTexBlit_Buffer);
+ mTexBlit_Buffer = 0;
+ }
+ if (mTexBlit_VertShader) {
+ mGL->fDeleteShader(mTexBlit_VertShader);
+ mTexBlit_VertShader = 0;
+ }
+ if (mTex2DBlit_FragShader) {
+ mGL->fDeleteShader(mTex2DBlit_FragShader);
+ mTex2DBlit_FragShader = 0;
+ }
+ if (mTex2DRectBlit_FragShader) {
+ mGL->fDeleteShader(mTex2DRectBlit_FragShader);
+ mTex2DRectBlit_FragShader = 0;
+ }
+ if (mTex2DBlit_Program) {
+ mGL->fDeleteProgram(mTex2DBlit_Program);
+ mTex2DBlit_Program = 0;
+ }
+ if (mTex2DRectBlit_Program) {
+ mGL->fDeleteProgram(mTex2DRectBlit_Program);
+ mTex2DRectBlit_Program = 0;
+ }
+ if (mTexExternalBlit_FragShader) {
+ mGL->fDeleteShader(mTexExternalBlit_FragShader);
+ mTexExternalBlit_FragShader = 0;
+ }
+ if (mTexYUVPlanarBlit_FragShader) {
+ mGL->fDeleteShader(mTexYUVPlanarBlit_FragShader);
+ mTexYUVPlanarBlit_FragShader = 0;
+ }
+ if (mTexNV12PlanarBlit_FragShader) {
+ mGL->fDeleteShader(mTexNV12PlanarBlit_FragShader);
+ mTexNV12PlanarBlit_FragShader = 0;
+ }
+ if (mTexExternalBlit_Program) {
+ mGL->fDeleteProgram(mTexExternalBlit_Program);
+ mTexExternalBlit_Program = 0;
+ }
+ if (mTexYUVPlanarBlit_Program) {
+ mGL->fDeleteProgram(mTexYUVPlanarBlit_Program);
+ mTexYUVPlanarBlit_Program = 0;
+ }
+ if (mTexNV12PlanarBlit_Program) {
+ mGL->fDeleteProgram(mTexNV12PlanarBlit_Program);
+ mTexNV12PlanarBlit_Program = 0;
+ }
+}
+
+void
+GLBlitHelper::BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
+ const gfx::IntSize& srcSize,
+ const gfx::IntSize& destSize,
+ bool internalFBs)
+{
+ MOZ_ASSERT(!srcFB || mGL->fIsFramebuffer(srcFB));
+ MOZ_ASSERT(!destFB || mGL->fIsFramebuffer(destFB));
+
+ MOZ_ASSERT(mGL->IsSupported(GLFeature::framebuffer_blit));
+
+ ScopedBindFramebuffer boundFB(mGL);
+ ScopedGLState scissor(mGL, LOCAL_GL_SCISSOR_TEST, false);
+
+ if (internalFBs) {
+ mGL->Screen()->BindReadFB_Internal(srcFB);
+ mGL->Screen()->BindDrawFB_Internal(destFB);
+ } else {
+ mGL->BindReadFB(srcFB);
+ mGL->BindDrawFB(destFB);
+ }
+
+ mGL->fBlitFramebuffer(0, 0, srcSize.width, srcSize.height,
+ 0, 0, destSize.width, destSize.height,
+ LOCAL_GL_COLOR_BUFFER_BIT,
+ LOCAL_GL_NEAREST);
+}
+
+void
+GLBlitHelper::BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
+ const gfx::IntSize& srcSize,
+ const gfx::IntSize& destSize,
+ const GLFormats& srcFormats,
+ bool internalFBs)
+{
+ MOZ_ASSERT(!srcFB || mGL->fIsFramebuffer(srcFB));
+ MOZ_ASSERT(!destFB || mGL->fIsFramebuffer(destFB));
+
+ if (mGL->IsSupported(GLFeature::framebuffer_blit)) {
+ BlitFramebufferToFramebuffer(srcFB, destFB,
+ srcSize, destSize,
+ internalFBs);
+ return;
+ }
+
+ GLuint tex = CreateTextureForOffscreen(mGL, srcFormats, srcSize);
+ MOZ_ASSERT(tex);
+
+ BlitFramebufferToTexture(srcFB, tex, srcSize, srcSize, internalFBs);
+ BlitTextureToFramebuffer(tex, destFB, srcSize, destSize, internalFBs);
+
+ mGL->fDeleteTextures(1, &tex);
+}
+
+void
+GLBlitHelper::BindAndUploadYUVTexture(Channel which,
+ uint32_t width,
+ uint32_t height,
+ void* data,
+ bool needsAllocation)
+{
+ MOZ_ASSERT(which < Channel_Max, "Invalid channel!");
+ GLuint* srcTexArr[3] = {&mSrcTexY, &mSrcTexCb, &mSrcTexCr};
+ GLuint& tex = *srcTexArr[which];
+
+ // RED textures aren't valid in GLES2, and ALPHA textures are not valid in desktop GL Core Profiles.
+ // So use R8 textures on GL3.0+ and GLES3.0+, but LUMINANCE/LUMINANCE/UNSIGNED_BYTE otherwise.
+ GLenum format;
+ GLenum internalFormat;
+ if (mGL->IsAtLeast(gl::ContextProfile::OpenGLCore, 300) ||
+ mGL->IsAtLeast(gl::ContextProfile::OpenGLES, 300)) {
+ format = LOCAL_GL_RED;
+ internalFormat = LOCAL_GL_R8;
+ } else {
+ format = LOCAL_GL_LUMINANCE;
+ internalFormat = LOCAL_GL_LUMINANCE;
+ }
+
+ if (!tex) {
+ MOZ_ASSERT(needsAllocation);
+ tex = CreateTexture(mGL, internalFormat, format, LOCAL_GL_UNSIGNED_BYTE,
+ gfx::IntSize(width, height), false);
+ }
+ mGL->fActiveTexture(LOCAL_GL_TEXTURE0 + which);
+
+ mGL->fBindTexture(LOCAL_GL_TEXTURE_2D, tex);
+ if (!needsAllocation) {
+ mGL->fTexSubImage2D(LOCAL_GL_TEXTURE_2D,
+ 0,
+ 0,
+ 0,
+ width,
+ height,
+ format,
+ LOCAL_GL_UNSIGNED_BYTE,
+ data);
+ } else {
+ mGL->fTexImage2D(LOCAL_GL_TEXTURE_2D,
+ 0,
+ internalFormat,
+ width,
+ height,
+ 0,
+ format,
+ LOCAL_GL_UNSIGNED_BYTE,
+ data);
+ }
+}
+
+void
+GLBlitHelper::BindAndUploadEGLImage(EGLImage image, GLuint target)
+{
+ MOZ_ASSERT(image != EGL_NO_IMAGE, "Bad EGLImage");
+
+ if (!mSrcTexEGL) {
+ mGL->fGenTextures(1, &mSrcTexEGL);
+ mGL->fBindTexture(target, mSrcTexEGL);
+ mGL->fTexParameteri(target, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
+ mGL->fTexParameteri(target, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
+ mGL->fTexParameteri(target, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_NEAREST);
+ mGL->fTexParameteri(target, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST);
+ } else {
+ mGL->fBindTexture(target, mSrcTexEGL);
+ }
+ mGL->fEGLImageTargetTexture2D(target, image);
+}
+
+#ifdef MOZ_WIDGET_ANDROID
+
+#define ATTACH_WAIT_MS 50
+
+bool
+GLBlitHelper::BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage)
+{
+ AndroidSurfaceTexture* surfaceTexture = stImage->GetSurfaceTexture();
+
+ ScopedBindTextureUnit boundTU(mGL, LOCAL_GL_TEXTURE0);
+
+ if (NS_FAILED(surfaceTexture->Attach(mGL, PR_MillisecondsToInterval(ATTACH_WAIT_MS))))
+ return false;
+
+ // UpdateTexImage() changes the EXTERNAL binding, so save it here
+ // so we can restore it after.
+ int oldBinding = 0;
+ mGL->fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_EXTERNAL, &oldBinding);
+
+ surfaceTexture->UpdateTexImage();
+
+ gfx::Matrix4x4 transform;
+ surfaceTexture->GetTransformMatrix(transform);
+
+ mGL->fUniformMatrix4fv(mTextureTransformLoc, 1, false, &transform._11);
+ mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
+
+ surfaceTexture->Detach();
+
+ mGL->fBindTexture(LOCAL_GL_TEXTURE_EXTERNAL, oldBinding);
+ return true;
+}
+
+bool
+GLBlitHelper::BlitEGLImageImage(layers::EGLImageImage* image)
+{
+ EGLImage eglImage = image->GetImage();
+ EGLSync eglSync = image->GetSync();
+
+ if (eglSync) {
+ EGLint status = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(), eglSync, 0, LOCAL_EGL_FOREVER);
+ if (status != LOCAL_EGL_CONDITION_SATISFIED) {
+ return false;
+ }
+ }
+
+ ScopedBindTextureUnit boundTU(mGL, LOCAL_GL_TEXTURE0);
+
+ int oldBinding = 0;
+ mGL->fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, &oldBinding);
+
+ BindAndUploadEGLImage(eglImage, LOCAL_GL_TEXTURE_2D);
+
+ mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
+
+ mGL->fBindTexture(LOCAL_GL_TEXTURE_2D, oldBinding);
+ return true;
+}
+
+#endif
+
+bool
+GLBlitHelper::BlitPlanarYCbCrImage(layers::PlanarYCbCrImage* yuvImage)
+{
+ ScopedBindTextureUnit boundTU(mGL, LOCAL_GL_TEXTURE0);
+ const PlanarYCbCrData* yuvData = yuvImage->GetData();
+
+ bool needsAllocation = false;
+ if (mTexWidth != yuvData->mYStride || mTexHeight != yuvData->mYSize.height) {
+ mTexWidth = yuvData->mYStride;
+ mTexHeight = yuvData->mYSize.height;
+ needsAllocation = true;
+ }
+
+ GLint oldTex[3];
+ for (int i = 0; i < 3; i++) {
+ mGL->fActiveTexture(LOCAL_GL_TEXTURE0 + i);
+ mGL->fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, &oldTex[i]);
+ }
+ BindAndUploadYUVTexture(Channel_Y, yuvData->mYStride, yuvData->mYSize.height, yuvData->mYChannel, needsAllocation);
+ BindAndUploadYUVTexture(Channel_Cb, yuvData->mCbCrStride, yuvData->mCbCrSize.height, yuvData->mCbChannel, needsAllocation);
+ BindAndUploadYUVTexture(Channel_Cr, yuvData->mCbCrStride, yuvData->mCbCrSize.height, yuvData->mCrChannel, needsAllocation);
+
+ if (needsAllocation) {
+ mGL->fUniform2f(mYTexScaleLoc, (float)yuvData->mYSize.width/yuvData->mYStride, 1.0f);
+ mGL->fUniform2f(mCbCrTexScaleLoc, (float)yuvData->mCbCrSize.width/yuvData->mCbCrStride, 1.0f);
+ }
+
+ float* yuvToRgb = gfxUtils::Get3x3YuvColorMatrix(yuvData->mYUVColorSpace);
+ mGL->fUniformMatrix3fv(mYuvColorMatrixLoc, 1, 0, yuvToRgb);
+
+ mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
+ for (int i = 0; i < 3; i++) {
+ mGL->fActiveTexture(LOCAL_GL_TEXTURE0 + i);
+ mGL->fBindTexture(LOCAL_GL_TEXTURE_2D, oldTex[i]);
+ }
+ return true;
+}
+
+#ifdef XP_MACOSX
+bool
+GLBlitHelper::BlitMacIOSurfaceImage(layers::MacIOSurfaceImage* ioImage)
+{
+ ScopedBindTextureUnit boundTU(mGL, LOCAL_GL_TEXTURE0);
+ MacIOSurface* surf = ioImage->GetSurface();
+
+ GLint oldTex[2];
+ for (int i = 0; i < 2; i++) {
+ mGL->fActiveTexture(LOCAL_GL_TEXTURE0 + i);
+ mGL->fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, &oldTex[i]);
+ }
+
+ GLuint textures[2];
+ mGL->fGenTextures(2, textures);
+
+ mGL->fActiveTexture(LOCAL_GL_TEXTURE0);
+ mGL->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, textures[0]);
+ mGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
+ mGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
+ surf->CGLTexImageIOSurface2D(gl::GLContextCGL::Cast(mGL)->GetCGLContext(), 0);
+ mGL->fUniform2f(mYTexScaleLoc, surf->GetWidth(0), surf->GetHeight(0));
+
+ mGL->fActiveTexture(LOCAL_GL_TEXTURE1);
+ mGL->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, textures[1]);
+ mGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
+ mGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
+ surf->CGLTexImageIOSurface2D(gl::GLContextCGL::Cast(mGL)->GetCGLContext(), 1);
+ mGL->fUniform2f(mCbCrTexScaleLoc, surf->GetWidth(1), surf->GetHeight(1));
+
+ mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
+ for (int i = 0; i < 2; i++) {
+ mGL->fActiveTexture(LOCAL_GL_TEXTURE0 + i);
+ mGL->fBindTexture(LOCAL_GL_TEXTURE_2D, oldTex[i]);
+ }
+
+ mGL->fDeleteTextures(2, textures);
+ return true;
+}
+#endif
+
+bool
+GLBlitHelper::BlitImageToFramebuffer(layers::Image* srcImage,
+ const gfx::IntSize& destSize,
+ GLuint destFB,
+ OriginPos destOrigin)
+{
+ ScopedGLDrawState autoStates(mGL);
+
+ BlitType type;
+ OriginPos srcOrigin;
+
+ switch (srcImage->GetFormat()) {
+ case ImageFormat::PLANAR_YCBCR:
+ type = ConvertPlanarYCbCr;
+ srcOrigin = OriginPos::BottomLeft;
+ break;
+
+#ifdef MOZ_WIDGET_ANDROID
+ case ImageFormat::SURFACE_TEXTURE:
+ type = ConvertSurfaceTexture;
+ srcOrigin = srcImage->AsSurfaceTextureImage()->GetOriginPos();
+ break;
+ case ImageFormat::EGLIMAGE:
+ type = ConvertEGLImage;
+ srcOrigin = srcImage->AsEGLImageImage()->GetOriginPos();
+ break;
+#endif
+#ifdef XP_MACOSX
+ case ImageFormat::MAC_IOSURFACE:
+ type = ConvertMacIOSurfaceImage;
+ srcOrigin = OriginPos::TopLeft;
+ break;
+#endif
+
+ default:
+ return false;
+ }
+
+ bool init = InitTexQuadProgram(type);
+ if (!init) {
+ return false;
+ }
+
+ const bool needsYFlip = (srcOrigin != destOrigin);
+ mGL->fUniform1f(mYFlipLoc, needsYFlip ? (float)1.0 : (float)0.0);
+
+ ScopedBindFramebuffer boundFB(mGL, destFB);
+ mGL->fColorMask(LOCAL_GL_TRUE, LOCAL_GL_TRUE, LOCAL_GL_TRUE, LOCAL_GL_TRUE);
+ mGL->fViewport(0, 0, destSize.width, destSize.height);
+
+ switch (type) {
+ case ConvertPlanarYCbCr: {
+ const auto saved = mGL->GetIntAs<GLint>(LOCAL_GL_UNPACK_ALIGNMENT);
+ mGL->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 1);
+ const auto ret = BlitPlanarYCbCrImage(static_cast<PlanarYCbCrImage*>(srcImage));
+ mGL->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, saved);
+ return ret;
+ }
+
+#ifdef MOZ_WIDGET_ANDROID
+ case ConvertSurfaceTexture:
+ return BlitSurfaceTextureImage(static_cast<layers::SurfaceTextureImage*>(srcImage));
+
+ case ConvertEGLImage:
+ return BlitEGLImageImage(static_cast<layers::EGLImageImage*>(srcImage));
+#endif
+
+#ifdef XP_MACOSX
+ case ConvertMacIOSurfaceImage:
+ return BlitMacIOSurfaceImage(srcImage->AsMacIOSurfaceImage());
+#endif
+
+ default:
+ return false;
+ }
+}
+
+bool
+GLBlitHelper::BlitImageToTexture(layers::Image* srcImage,
+ const gfx::IntSize& destSize,
+ GLuint destTex,
+ GLenum destTarget,
+ OriginPos destOrigin)
+{
+ ScopedFramebufferForTexture autoFBForTex(mGL, destTex, destTarget);
+ if (!autoFBForTex.IsComplete())
+ return false;
+
+ return BlitImageToFramebuffer(srcImage, destSize, autoFBForTex.FB(), destOrigin);
+}
+
+void
+GLBlitHelper::BlitTextureToFramebuffer(GLuint srcTex, GLuint destFB,
+ const gfx::IntSize& srcSize,
+ const gfx::IntSize& destSize,
+ GLenum srcTarget,
+ bool internalFBs)
+{
+ MOZ_ASSERT(mGL->fIsTexture(srcTex));
+ MOZ_ASSERT(!destFB || mGL->fIsFramebuffer(destFB));
+
+ if (mGL->IsSupported(GLFeature::framebuffer_blit)) {
+ ScopedFramebufferForTexture srcWrapper(mGL, srcTex, srcTarget);
+ MOZ_DIAGNOSTIC_ASSERT(srcWrapper.IsComplete());
+
+ BlitFramebufferToFramebuffer(srcWrapper.FB(), destFB,
+ srcSize, destSize,
+ internalFBs);
+ return;
+ }
+
+ DrawBlitTextureToFramebuffer(srcTex, destFB, srcSize, destSize, srcTarget,
+ internalFBs);
+}
+
+
+void
+GLBlitHelper::DrawBlitTextureToFramebuffer(GLuint srcTex, GLuint destFB,
+ const gfx::IntSize& srcSize,
+ const gfx::IntSize& destSize,
+ GLenum srcTarget,
+ bool internalFBs)
+{
+ BlitType type;
+ switch (srcTarget) {
+ case LOCAL_GL_TEXTURE_2D:
+ type = BlitTex2D;
+ break;
+ case LOCAL_GL_TEXTURE_RECTANGLE_ARB:
+ type = BlitTexRect;
+ break;
+ default:
+ MOZ_CRASH("GFX: Fatal Error: Bad `srcTarget`.");
+ break;
+ }
+
+ ScopedGLDrawState autoStates(mGL);
+ if (internalFBs) {
+ mGL->Screen()->BindFB_Internal(destFB);
+ } else {
+ mGL->BindFB(destFB);
+ }
+
+ // Does destructive things to (only!) what we just saved above.
+ bool good = UseTexQuadProgram(type, srcSize);
+ if (!good) {
+ // We're up against the wall, so bail.
+ MOZ_DIAGNOSTIC_ASSERT(false,
+ "Error: Failed to prepare to blit texture->framebuffer.\n");
+ mGL->fScissor(0, 0, destSize.width, destSize.height);
+ mGL->fColorMask(1, 1, 1, 1);
+ mGL->fClear(LOCAL_GL_COLOR_BUFFER_BIT);
+ return;
+ }
+
+ mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
+}
+
+void
+GLBlitHelper::BlitFramebufferToTexture(GLuint srcFB, GLuint destTex,
+ const gfx::IntSize& srcSize,
+ const gfx::IntSize& destSize,
+ GLenum destTarget,
+ bool internalFBs)
+{
+ // On the Android 4.3 emulator, IsFramebuffer may return false incorrectly.
+ MOZ_ASSERT_IF(mGL->Renderer() != GLRenderer::AndroidEmulator, !srcFB || mGL->fIsFramebuffer(srcFB));
+ MOZ_ASSERT(mGL->fIsTexture(destTex));
+
+ if (mGL->IsSupported(GLFeature::framebuffer_blit)) {
+ ScopedFramebufferForTexture destWrapper(mGL, destTex, destTarget);
+
+ BlitFramebufferToFramebuffer(srcFB, destWrapper.FB(),
+ srcSize, destSize,
+ internalFBs);
+ return;
+ }
+
+ ScopedBindTexture autoTex(mGL, destTex, destTarget);
+
+ ScopedBindFramebuffer boundFB(mGL);
+ if (internalFBs) {
+ mGL->Screen()->BindFB_Internal(srcFB);
+ } else {
+ mGL->BindFB(srcFB);
+ }
+
+ ScopedGLState scissor(mGL, LOCAL_GL_SCISSOR_TEST, false);
+ mGL->fCopyTexSubImage2D(destTarget, 0,
+ 0, 0,
+ 0, 0,
+ srcSize.width, srcSize.height);
+}
+
+void
+GLBlitHelper::BlitTextureToTexture(GLuint srcTex, GLuint destTex,
+ const gfx::IntSize& srcSize,
+ const gfx::IntSize& destSize,
+ GLenum srcTarget, GLenum destTarget)
+{
+ MOZ_ASSERT(mGL->fIsTexture(srcTex));
+ MOZ_ASSERT(mGL->fIsTexture(destTex));
+
+ // Generally, just use the CopyTexSubImage path
+ ScopedFramebufferForTexture srcWrapper(mGL, srcTex, srcTarget);
+
+ BlitFramebufferToTexture(srcWrapper.FB(), destTex,
+ srcSize, destSize, destTarget);
+}
+
+} // namespace gl
+} // namespace mozilla
diff --git a/gfx/gl/GLBlitHelper.h b/gfx/gl/GLBlitHelper.h
new file mode 100644
index 0000000000..31d6a2f5b1
--- /dev/null
+++ b/gfx/gl/GLBlitHelper.h
@@ -0,0 +1,168 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GLBLITHELPER_H_
+#define GLBLITHELPER_H_
+
+#include "GLContextTypes.h"
+#include "GLConsts.h"
+#include "nsSize.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/gfx/Point.h"
+
+namespace mozilla {
+
+namespace layers {
+class Image;
+class PlanarYCbCrImage;
+class GrallocImage;
+class SurfaceTextureImage;
+class MacIOSurfaceImage;
+class EGLImageImage;
+} // namespace layers
+
+namespace gl {
+
+class GLContext;
+
+/** Buffer blitting helper */
+class GLBlitHelper final
+{
+ enum Channel
+ {
+ Channel_Y = 0,
+ Channel_Cb,
+ Channel_Cr,
+ Channel_Max,
+ };
+
+ /**
+ * BlitTex2D is used to copy blit the content of a GL_TEXTURE_2D object,
+ * BlitTexRect is used to copy blit the content of a GL_TEXTURE_RECT object,
+ * The difference between BlitTex2D and BlitTexRect is the texture type, which affect
+ * the fragment shader a bit.
+ *
+ * ConvertGralloc is used to color convert copy blit the GrallocImage into a
+ * normal RGB texture by egl_image_external extension
+ * ConvertPlnarYcbCr is used to color convert copy blit the PlanarYCbCrImage
+ * into a normal RGB texture by create textures of each color channel, and
+ * convert it in GPU.
+ * Convert type is created for canvas.
+ */
+ enum BlitType
+ {
+ BlitTex2D,
+ BlitTexRect,
+ ConvertGralloc,
+ ConvertPlanarYCbCr,
+ ConvertSurfaceTexture,
+ ConvertEGLImage,
+ ConvertMacIOSurfaceImage
+ };
+ // The GLContext is the sole owner of the GLBlitHelper.
+ GLContext* mGL;
+
+ GLuint mTexBlit_Buffer;
+ GLuint mTexBlit_VertShader;
+ GLuint mTex2DBlit_FragShader;
+ GLuint mTex2DRectBlit_FragShader;
+ GLuint mTex2DBlit_Program;
+ GLuint mTex2DRectBlit_Program;
+
+ GLint mYFlipLoc;
+
+ GLint mTextureTransformLoc;
+
+ // Data for image blit path
+ GLuint mTexExternalBlit_FragShader;
+ GLuint mTexYUVPlanarBlit_FragShader;
+ GLuint mTexNV12PlanarBlit_FragShader;
+ GLuint mTexExternalBlit_Program;
+ GLuint mTexYUVPlanarBlit_Program;
+ GLuint mTexNV12PlanarBlit_Program;
+ GLuint mFBO;
+ GLuint mSrcTexY;
+ GLuint mSrcTexCb;
+ GLuint mSrcTexCr;
+ GLuint mSrcTexEGL;
+ GLint mYTexScaleLoc;
+ GLint mCbCrTexScaleLoc;
+ GLint mYuvColorMatrixLoc;
+ int mTexWidth;
+ int mTexHeight;
+
+ // Cache some uniform values
+ float mCurYScale;
+ float mCurCbCrScale;
+
+ void UseBlitProgram();
+ void SetBlitFramebufferForDestTexture(GLuint aTexture);
+
+ bool UseTexQuadProgram(BlitType target, const gfx::IntSize& srcSize);
+ bool InitTexQuadProgram(BlitType target = BlitTex2D);
+ void DeleteTexBlitProgram();
+ void BindAndUploadYUVTexture(Channel which, uint32_t width, uint32_t height, void* data, bool allocation);
+ void BindAndUploadEGLImage(EGLImage image, GLuint target);
+
+ bool BlitPlanarYCbCrImage(layers::PlanarYCbCrImage* yuvImage);
+#ifdef MOZ_WIDGET_ANDROID
+ // Blit onto the current FB.
+ bool BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage);
+ bool BlitEGLImageImage(layers::EGLImageImage* eglImage);
+#endif
+#ifdef XP_MACOSX
+ bool BlitMacIOSurfaceImage(layers::MacIOSurfaceImage* ioImage);
+#endif
+
+ explicit GLBlitHelper(GLContext* gl);
+
+ friend class GLContext;
+
+public:
+ ~GLBlitHelper();
+
+ // If you don't have |srcFormats| for the 2nd definition,
+ // then you'll need the framebuffer_blit extensions to use
+ // the first BlitFramebufferToFramebuffer.
+ void BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
+ const gfx::IntSize& srcSize,
+ const gfx::IntSize& destSize,
+ bool internalFBs = false);
+ void BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
+ const gfx::IntSize& srcSize,
+ const gfx::IntSize& destSize,
+ const GLFormats& srcFormats,
+ bool internalFBs = false);
+ void BlitTextureToFramebuffer(GLuint srcTex, GLuint destFB,
+ const gfx::IntSize& srcSize,
+ const gfx::IntSize& destSize,
+ GLenum srcTarget = LOCAL_GL_TEXTURE_2D,
+ bool internalFBs = false);
+ void DrawBlitTextureToFramebuffer(GLuint srcTex, GLuint destFB,
+ const gfx::IntSize& srcSize,
+ const gfx::IntSize& destSize,
+ GLenum srcTarget = LOCAL_GL_TEXTURE_2D,
+ bool internalFBs = false);
+ void BlitFramebufferToTexture(GLuint srcFB, GLuint destTex,
+ const gfx::IntSize& srcSize,
+ const gfx::IntSize& destSize,
+ GLenum destTarget = LOCAL_GL_TEXTURE_2D,
+ bool internalFBs = false);
+ void BlitTextureToTexture(GLuint srcTex, GLuint destTex,
+ const gfx::IntSize& srcSize,
+ const gfx::IntSize& destSize,
+ GLenum srcTarget = LOCAL_GL_TEXTURE_2D,
+ GLenum destTarget = LOCAL_GL_TEXTURE_2D);
+ bool BlitImageToFramebuffer(layers::Image* srcImage, const gfx::IntSize& destSize,
+ GLuint destFB, OriginPos destOrigin);
+ bool BlitImageToTexture(layers::Image* srcImage, const gfx::IntSize& destSize,
+ GLuint destTex, GLenum destTarget, OriginPos destOrigin);
+};
+
+} // namespace gl
+} // namespace mozilla
+
+#endif // GLBLITHELPER_H_
diff --git a/gfx/gl/GLConsts.h b/gfx/gl/GLConsts.h
new file mode 100644
index 0000000000..ad6175e163
--- /dev/null
+++ b/gfx/gl/GLConsts.h
@@ -0,0 +1,5951 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GLCONSTS_H_
+#define GLCONSTS_H_
+
+/**
+ * GENERATED FILE, DO NOT MODIFY DIRECTLY.
+ * This is a file generated directly from the official OpenGL registry
+ * xml available http://www.opengl.org/registry/#specfiles.
+ *
+ * To generate this file, see tutorial in 'GLParseRegistryXML.py'.
+ */
+
+// GL
+#define LOCAL_GL_1PASS_EXT 0x80A1
+#define LOCAL_GL_1PASS_SGIS 0x80A1
+#define LOCAL_GL_2D 0x0600
+#define LOCAL_GL_2PASS_0_EXT 0x80A2
+#define LOCAL_GL_2PASS_0_SGIS 0x80A2
+#define LOCAL_GL_2PASS_1_EXT 0x80A3
+#define LOCAL_GL_2PASS_1_SGIS 0x80A3
+#define LOCAL_GL_2X_BIT_ATI 0x00000001
+#define LOCAL_GL_2_BYTES 0x1407
+#define LOCAL_GL_3D 0x0601
+#define LOCAL_GL_3DC_XY_AMD 0x87FA
+#define LOCAL_GL_3DC_X_AMD 0x87F9
+#define LOCAL_GL_3D_COLOR 0x0602
+#define LOCAL_GL_3D_COLOR_TEXTURE 0x0603
+#define LOCAL_GL_3_BYTES 0x1408
+#define LOCAL_GL_422_AVERAGE_EXT 0x80CE
+#define LOCAL_GL_422_EXT 0x80CC
+#define LOCAL_GL_422_REV_AVERAGE_EXT 0x80CF
+#define LOCAL_GL_422_REV_EXT 0x80CD
+#define LOCAL_GL_4D_COLOR_TEXTURE 0x0604
+#define LOCAL_GL_4PASS_0_EXT 0x80A4
+#define LOCAL_GL_4PASS_0_SGIS 0x80A4
+#define LOCAL_GL_4PASS_1_EXT 0x80A5
+#define LOCAL_GL_4PASS_1_SGIS 0x80A5
+#define LOCAL_GL_4PASS_2_EXT 0x80A6
+#define LOCAL_GL_4PASS_2_SGIS 0x80A6
+#define LOCAL_GL_4PASS_3_EXT 0x80A7
+#define LOCAL_GL_4PASS_3_SGIS 0x80A7
+#define LOCAL_GL_4X_BIT_ATI 0x00000002
+#define LOCAL_GL_4_BYTES 0x1409
+#define LOCAL_GL_8X_BIT_ATI 0x00000004
+#define LOCAL_GL_ABGR_EXT 0x8000
+#define LOCAL_GL_ACCUM 0x0100
+#define LOCAL_GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD
+#define LOCAL_GL_ACCUM_ALPHA_BITS 0x0D5B
+#define LOCAL_GL_ACCUM_BLUE_BITS 0x0D5A
+#define LOCAL_GL_ACCUM_BUFFER_BIT 0x00000200
+#define LOCAL_GL_ACCUM_CLEAR_VALUE 0x0B80
+#define LOCAL_GL_ACCUM_GREEN_BITS 0x0D59
+#define LOCAL_GL_ACCUM_RED_BITS 0x0D58
+#define LOCAL_GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9
+#define LOCAL_GL_ACTIVE_ATTRIBUTES 0x8B89
+#define LOCAL_GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
+#define LOCAL_GL_ACTIVE_PROGRAM 0x8259
+#define LOCAL_GL_ACTIVE_PROGRAM_EXT 0x8B8D
+#define LOCAL_GL_ACTIVE_RESOURCES 0x92F5
+#define LOCAL_GL_ACTIVE_STENCIL_FACE_EXT 0x8911
+#define LOCAL_GL_ACTIVE_SUBROUTINES 0x8DE5
+#define LOCAL_GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48
+#define LOCAL_GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6
+#define LOCAL_GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47
+#define LOCAL_GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49
+#define LOCAL_GL_ACTIVE_TEXTURE 0x84E0
+#define LOCAL_GL_ACTIVE_TEXTURE_ARB 0x84E0
+#define LOCAL_GL_ACTIVE_UNIFORMS 0x8B86
+#define LOCAL_GL_ACTIVE_UNIFORM_BLOCKS 0x8A36
+#define LOCAL_GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35
+#define LOCAL_GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
+#define LOCAL_GL_ACTIVE_VARIABLES 0x9305
+#define LOCAL_GL_ACTIVE_VARYINGS_NV 0x8C81
+#define LOCAL_GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82
+#define LOCAL_GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5
+#define LOCAL_GL_ADD 0x0104
+#define LOCAL_GL_ADD_ATI 0x8963
+#define LOCAL_GL_ADD_BLEND_IMG 0x8C09
+#define LOCAL_GL_ADD_SIGNED 0x8574
+#define LOCAL_GL_ADD_SIGNED_ARB 0x8574
+#define LOCAL_GL_ADD_SIGNED_EXT 0x8574
+#define LOCAL_GL_ADJACENT_PAIRS_NV 0x90AE
+#define LOCAL_GL_AFFINE_2D_NV 0x9092
+#define LOCAL_GL_AFFINE_3D_NV 0x9094
+#define LOCAL_GL_ALIASED_LINE_WIDTH_RANGE 0x846E
+#define LOCAL_GL_ALIASED_POINT_SIZE_RANGE 0x846D
+#define LOCAL_GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210
+#define LOCAL_GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211
+#define LOCAL_GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E
+#define LOCAL_GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F
+#define LOCAL_GL_ALL_ATTRIB_BITS 0xFFFFFFFF
+#define LOCAL_GL_ALL_BARRIER_BITS 0xFFFFFFFF
+#define LOCAL_GL_ALL_BARRIER_BITS_EXT 0xFFFFFFFF
+#define LOCAL_GL_ALL_COMPLETED_NV 0x84F2
+#define LOCAL_GL_ALL_SHADER_BITS 0xFFFFFFFF
+#define LOCAL_GL_ALL_SHADER_BITS_EXT 0xFFFFFFFF
+#define LOCAL_GL_ALL_STATIC_DATA_IBM 103060
+#define LOCAL_GL_ALPHA 0x1906
+#define LOCAL_GL_ALPHA12 0x803D
+#define LOCAL_GL_ALPHA12_EXT 0x803D
+#define LOCAL_GL_ALPHA16 0x803E
+#define LOCAL_GL_ALPHA16F_ARB 0x881C
+#define LOCAL_GL_ALPHA16F_EXT 0x881C
+#define LOCAL_GL_ALPHA16I_EXT 0x8D8A
+#define LOCAL_GL_ALPHA16UI_EXT 0x8D78
+#define LOCAL_GL_ALPHA16_EXT 0x803E
+#define LOCAL_GL_ALPHA16_SNORM 0x9018
+#define LOCAL_GL_ALPHA32F_ARB 0x8816
+#define LOCAL_GL_ALPHA32F_EXT 0x8816
+#define LOCAL_GL_ALPHA32I_EXT 0x8D84
+#define LOCAL_GL_ALPHA32UI_EXT 0x8D72
+#define LOCAL_GL_ALPHA4 0x803B
+#define LOCAL_GL_ALPHA4_EXT 0x803B
+#define LOCAL_GL_ALPHA8 0x803C
+#define LOCAL_GL_ALPHA8I_EXT 0x8D90
+#define LOCAL_GL_ALPHA8UI_EXT 0x8D7E
+#define LOCAL_GL_ALPHA8_EXT 0x803C
+#define LOCAL_GL_ALPHA8_OES 0x803C
+#define LOCAL_GL_ALPHA8_SNORM 0x9014
+#define LOCAL_GL_ALPHA_BIAS 0x0D1D
+#define LOCAL_GL_ALPHA_BITS 0x0D55
+#define LOCAL_GL_ALPHA_FLOAT16_APPLE 0x881C
+#define LOCAL_GL_ALPHA_FLOAT16_ATI 0x881C
+#define LOCAL_GL_ALPHA_FLOAT32_APPLE 0x8816
+#define LOCAL_GL_ALPHA_FLOAT32_ATI 0x8816
+#define LOCAL_GL_ALPHA_INTEGER 0x8D97
+#define LOCAL_GL_ALPHA_INTEGER_EXT 0x8D97
+#define LOCAL_GL_ALPHA_MAX_CLAMP_INGR 0x8567
+#define LOCAL_GL_ALPHA_MAX_SGIX 0x8321
+#define LOCAL_GL_ALPHA_MIN_CLAMP_INGR 0x8563
+#define LOCAL_GL_ALPHA_MIN_SGIX 0x8320
+#define LOCAL_GL_ALPHA_SCALE 0x0D1C
+#define LOCAL_GL_ALPHA_SNORM 0x9010
+#define LOCAL_GL_ALPHA_TEST 0x0BC0
+#define LOCAL_GL_ALPHA_TEST_FUNC 0x0BC1
+#define LOCAL_GL_ALPHA_TEST_FUNC_QCOM 0x0BC1
+#define LOCAL_GL_ALPHA_TEST_QCOM 0x0BC0
+#define LOCAL_GL_ALPHA_TEST_REF 0x0BC2
+#define LOCAL_GL_ALPHA_TEST_REF_QCOM 0x0BC2
+#define LOCAL_GL_ALREADY_SIGNALED 0x911A
+#define LOCAL_GL_ALREADY_SIGNALED_APPLE 0x911A
+#define LOCAL_GL_ALWAYS 0x0207
+#define LOCAL_GL_ALWAYS_FAST_HINT_PGI 0x1A20C
+#define LOCAL_GL_ALWAYS_SOFT_HINT_PGI 0x1A20D
+#define LOCAL_GL_AMBIENT 0x1200
+#define LOCAL_GL_AMBIENT_AND_DIFFUSE 0x1602
+#define LOCAL_GL_AND 0x1501
+#define LOCAL_GL_AND_INVERTED 0x1504
+#define LOCAL_GL_AND_REVERSE 0x1502
+#define LOCAL_GL_ANY_SAMPLES_PASSED 0x8C2F
+#define LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A
+#define LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT 0x8D6A
+#define LOCAL_GL_ANY_SAMPLES_PASSED_EXT 0x8C2F
+#define LOCAL_GL_ARC_TO_NV 0xFE
+#define LOCAL_GL_ARRAY_BUFFER 0x8892
+#define LOCAL_GL_ARRAY_BUFFER_ARB 0x8892
+#define LOCAL_GL_ARRAY_BUFFER_BINDING 0x8894
+#define LOCAL_GL_ARRAY_BUFFER_BINDING_ARB 0x8894
+#define LOCAL_GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9
+#define LOCAL_GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8
+#define LOCAL_GL_ARRAY_OBJECT_BUFFER_ATI 0x8766
+#define LOCAL_GL_ARRAY_OBJECT_OFFSET_ATI 0x8767
+#define LOCAL_GL_ARRAY_SIZE 0x92FB
+#define LOCAL_GL_ARRAY_STRIDE 0x92FE
+#define LOCAL_GL_ASYNC_DRAW_PIXELS_SGIX 0x835D
+#define LOCAL_GL_ASYNC_HISTOGRAM_SGIX 0x832C
+#define LOCAL_GL_ASYNC_MARKER_SGIX 0x8329
+#define LOCAL_GL_ASYNC_READ_PIXELS_SGIX 0x835E
+#define LOCAL_GL_ASYNC_TEX_IMAGE_SGIX 0x835C
+#define LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93
+#define LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE
+#define LOCAL_GL_ATC_RGB_AMD 0x8C92
+#define LOCAL_GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000
+#define LOCAL_GL_ATOMIC_COUNTER_BARRIER_BIT_EXT 0x00001000
+#define LOCAL_GL_ATOMIC_COUNTER_BUFFER 0x92C0
+#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5
+#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6
+#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1
+#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4
+#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301
+#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED
+#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB
+#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA
+#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8
+#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9
+#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7
+#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3
+#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_START 0x92C2
+#define LOCAL_GL_ATTACHED_SHADERS 0x8B85
+#define LOCAL_GL_ATTENUATION_EXT 0x834D
+#define LOCAL_GL_ATTRIB_ARRAY_POINTER_NV 0x8645
+#define LOCAL_GL_ATTRIB_ARRAY_SIZE_NV 0x8623
+#define LOCAL_GL_ATTRIB_ARRAY_STRIDE_NV 0x8624
+#define LOCAL_GL_ATTRIB_ARRAY_TYPE_NV 0x8625
+#define LOCAL_GL_ATTRIB_STACK_DEPTH 0x0BB0
+#define LOCAL_GL_AUTO_GENERATE_MIPMAP 0x8295
+#define LOCAL_GL_AUTO_NORMAL 0x0D80
+#define LOCAL_GL_AUX0 0x0409
+#define LOCAL_GL_AUX1 0x040A
+#define LOCAL_GL_AUX2 0x040B
+#define LOCAL_GL_AUX3 0x040C
+#define LOCAL_GL_AUX_BUFFERS 0x0C00
+#define LOCAL_GL_AUX_DEPTH_STENCIL_APPLE 0x8A14
+#define LOCAL_GL_AVERAGE_EXT 0x8335
+#define LOCAL_GL_AVERAGE_HP 0x8160
+#define LOCAL_GL_BACK 0x0405
+#define LOCAL_GL_BACK_LEFT 0x0402
+#define LOCAL_GL_BACK_NORMALS_HINT_PGI 0x1A223
+#define LOCAL_GL_BACK_PRIMARY_COLOR_NV 0x8C77
+#define LOCAL_GL_BACK_RIGHT 0x0403
+#define LOCAL_GL_BACK_SECONDARY_COLOR_NV 0x8C78
+#define LOCAL_GL_BEVEL_NV 0x90A6
+#define LOCAL_GL_BGR 0x80E0
+#define LOCAL_GL_BGRA 0x80E1
+#define LOCAL_GL_BGRA8_EXT 0x93A1
+#define LOCAL_GL_BGRA_EXT 0x80E1
+#define LOCAL_GL_BGRA_IMG 0x80E1
+#define LOCAL_GL_BGRA_INTEGER 0x8D9B
+#define LOCAL_GL_BGRA_INTEGER_EXT 0x8D9B
+#define LOCAL_GL_BGR_EXT 0x80E0
+#define LOCAL_GL_BGR_INTEGER 0x8D9A
+#define LOCAL_GL_BGR_INTEGER_EXT 0x8D9A
+#define LOCAL_GL_BIAS_BIT_ATI 0x00000008
+#define LOCAL_GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541
+#define LOCAL_GL_BINNING_CONTROL_HINT_QCOM 0x8FB0
+#define LOCAL_GL_BINORMAL_ARRAY_EXT 0x843A
+#define LOCAL_GL_BINORMAL_ARRAY_POINTER_EXT 0x8443
+#define LOCAL_GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441
+#define LOCAL_GL_BINORMAL_ARRAY_TYPE_EXT 0x8440
+#define LOCAL_GL_BITMAP 0x1A00
+#define LOCAL_GL_BITMAP_TOKEN 0x0704
+#define LOCAL_GL_BLEND 0x0BE2
+#define LOCAL_GL_BLEND_ADVANCED_COHERENT_NV 0x9285
+#define LOCAL_GL_BLEND_COLOR 0x8005
+#define LOCAL_GL_BLEND_COLOR_EXT 0x8005
+#define LOCAL_GL_BLEND_DST 0x0BE0
+#define LOCAL_GL_BLEND_DST_ALPHA 0x80CA
+#define LOCAL_GL_BLEND_DST_ALPHA_EXT 0x80CA
+#define LOCAL_GL_BLEND_DST_ALPHA_OES 0x80CA
+#define LOCAL_GL_BLEND_DST_RGB 0x80C8
+#define LOCAL_GL_BLEND_DST_RGB_EXT 0x80C8
+#define LOCAL_GL_BLEND_DST_RGB_OES 0x80C8
+#define LOCAL_GL_BLEND_EQUATION 0x8009
+#define LOCAL_GL_BLEND_EQUATION_ALPHA 0x883D
+#define LOCAL_GL_BLEND_EQUATION_ALPHA_EXT 0x883D
+#define LOCAL_GL_BLEND_EQUATION_ALPHA_OES 0x883D
+#define LOCAL_GL_BLEND_EQUATION_EXT 0x8009
+#define LOCAL_GL_BLEND_EQUATION_OES 0x8009
+#define LOCAL_GL_BLEND_EQUATION_RGB 0x8009
+#define LOCAL_GL_BLEND_EQUATION_RGB_EXT 0x8009
+#define LOCAL_GL_BLEND_EQUATION_RGB_OES 0x8009
+#define LOCAL_GL_BLEND_OVERLAP_NV 0x9281
+#define LOCAL_GL_BLEND_PREMULTIPLIED_SRC_NV 0x9280
+#define LOCAL_GL_BLEND_SRC 0x0BE1
+#define LOCAL_GL_BLEND_SRC_ALPHA 0x80CB
+#define LOCAL_GL_BLEND_SRC_ALPHA_EXT 0x80CB
+#define LOCAL_GL_BLEND_SRC_ALPHA_OES 0x80CB
+#define LOCAL_GL_BLEND_SRC_RGB 0x80C9
+#define LOCAL_GL_BLEND_SRC_RGB_EXT 0x80C9
+#define LOCAL_GL_BLEND_SRC_RGB_OES 0x80C9
+#define LOCAL_GL_BLOCK_INDEX 0x92FD
+#define LOCAL_GL_BLUE 0x1905
+#define LOCAL_GL_BLUE_BIAS 0x0D1B
+#define LOCAL_GL_BLUE_BITS 0x0D54
+#define LOCAL_GL_BLUE_BIT_ATI 0x00000004
+#define LOCAL_GL_BLUE_INTEGER 0x8D96
+#define LOCAL_GL_BLUE_INTEGER_EXT 0x8D96
+#define LOCAL_GL_BLUE_MAX_CLAMP_INGR 0x8566
+#define LOCAL_GL_BLUE_MIN_CLAMP_INGR 0x8562
+#define LOCAL_GL_BLUE_NV 0x1905
+#define LOCAL_GL_BLUE_SCALE 0x0D1A
+#define LOCAL_GL_BOLD_BIT_NV 0x01
+#define LOCAL_GL_BOOL 0x8B56
+#define LOCAL_GL_BOOL_ARB 0x8B56
+#define LOCAL_GL_BOOL_VEC2 0x8B57
+#define LOCAL_GL_BOOL_VEC2_ARB 0x8B57
+#define LOCAL_GL_BOOL_VEC3 0x8B58
+#define LOCAL_GL_BOOL_VEC3_ARB 0x8B58
+#define LOCAL_GL_BOOL_VEC4 0x8B59
+#define LOCAL_GL_BOOL_VEC4_ARB 0x8B59
+#define LOCAL_GL_BOUNDING_BOX_NV 0x908D
+#define LOCAL_GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C
+#define LOCAL_GL_BUFFER 0x82E0
+#define LOCAL_GL_BUFFER_ACCESS 0x88BB
+#define LOCAL_GL_BUFFER_ACCESS_ARB 0x88BB
+#define LOCAL_GL_BUFFER_ACCESS_FLAGS 0x911F
+#define LOCAL_GL_BUFFER_ACCESS_OES 0x88BB
+#define LOCAL_GL_BUFFER_BINDING 0x9302
+#define LOCAL_GL_BUFFER_DATA_SIZE 0x9303
+#define LOCAL_GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13
+#define LOCAL_GL_BUFFER_GPU_ADDRESS_NV 0x8F1D
+#define LOCAL_GL_BUFFER_IMMUTABLE_STORAGE 0x821F
+#define LOCAL_GL_BUFFER_KHR 0x82E0
+#define LOCAL_GL_BUFFER_MAPPED 0x88BC
+#define LOCAL_GL_BUFFER_MAPPED_ARB 0x88BC
+#define LOCAL_GL_BUFFER_MAPPED_OES 0x88BC
+#define LOCAL_GL_BUFFER_MAP_LENGTH 0x9120
+#define LOCAL_GL_BUFFER_MAP_OFFSET 0x9121
+#define LOCAL_GL_BUFFER_MAP_POINTER 0x88BD
+#define LOCAL_GL_BUFFER_MAP_POINTER_ARB 0x88BD
+#define LOCAL_GL_BUFFER_MAP_POINTER_OES 0x88BD
+#define LOCAL_GL_BUFFER_OBJECT_APPLE 0x85B3
+#define LOCAL_GL_BUFFER_OBJECT_EXT 0x9151
+#define LOCAL_GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12
+#define LOCAL_GL_BUFFER_SIZE 0x8764
+#define LOCAL_GL_BUFFER_SIZE_ARB 0x8764
+#define LOCAL_GL_BUFFER_STORAGE_FLAGS 0x8220
+#define LOCAL_GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200
+#define LOCAL_GL_BUFFER_UPDATE_BARRIER_BIT_EXT 0x00000200
+#define LOCAL_GL_BUFFER_USAGE 0x8765
+#define LOCAL_GL_BUFFER_USAGE_ARB 0x8765
+#define LOCAL_GL_BUFFER_VARIABLE 0x92E5
+#define LOCAL_GL_BUMP_ENVMAP_ATI 0x877B
+#define LOCAL_GL_BUMP_NUM_TEX_UNITS_ATI 0x8777
+#define LOCAL_GL_BUMP_ROT_MATRIX_ATI 0x8775
+#define LOCAL_GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776
+#define LOCAL_GL_BUMP_TARGET_ATI 0x877C
+#define LOCAL_GL_BUMP_TEX_UNITS_ATI 0x8778
+#define LOCAL_GL_BYTE 0x1400
+#define LOCAL_GL_C3F_V3F 0x2A24
+#define LOCAL_GL_C4F_N3F_V3F 0x2A26
+#define LOCAL_GL_C4UB_V2F 0x2A22
+#define LOCAL_GL_C4UB_V3F 0x2A23
+#define LOCAL_GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183
+#define LOCAL_GL_CAVEAT_SUPPORT 0x82B8
+#define LOCAL_GL_CCW 0x0901
+#define LOCAL_GL_CIRCULAR_CCW_ARC_TO_NV 0xF8
+#define LOCAL_GL_CIRCULAR_CW_ARC_TO_NV 0xFA
+#define LOCAL_GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC
+#define LOCAL_GL_CLAMP 0x2900
+#define LOCAL_GL_CLAMP_FRAGMENT_COLOR 0x891B
+#define LOCAL_GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B
+#define LOCAL_GL_CLAMP_READ_COLOR 0x891C
+#define LOCAL_GL_CLAMP_READ_COLOR_ARB 0x891C
+#define LOCAL_GL_CLAMP_TO_BORDER 0x812D
+#define LOCAL_GL_CLAMP_TO_BORDER_ARB 0x812D
+#define LOCAL_GL_CLAMP_TO_BORDER_NV 0x812D
+#define LOCAL_GL_CLAMP_TO_BORDER_SGIS 0x812D
+#define LOCAL_GL_CLAMP_TO_EDGE 0x812F
+#define LOCAL_GL_CLAMP_TO_EDGE_SGIS 0x812F
+#define LOCAL_GL_CLAMP_VERTEX_COLOR 0x891A
+#define LOCAL_GL_CLAMP_VERTEX_COLOR_ARB 0x891A
+#define LOCAL_GL_CLEAR 0x1500
+#define LOCAL_GL_CLEAR_BUFFER 0x82B4
+#define LOCAL_GL_CLEAR_TEXTURE 0x9365
+#define LOCAL_GL_CLIENT_ACTIVE_TEXTURE 0x84E1
+#define LOCAL_GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1
+#define LOCAL_GL_CLIENT_ALL_ATTRIB_BITS 0xFFFFFFFF
+#define LOCAL_GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1
+#define LOCAL_GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000
+#define LOCAL_GL_CLIENT_PIXEL_STORE_BIT 0x00000001
+#define LOCAL_GL_CLIENT_STORAGE_BIT 0x0200
+#define LOCAL_GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002
+#define LOCAL_GL_CLIP_DISTANCE0 0x3000
+#define LOCAL_GL_CLIP_DISTANCE1 0x3001
+#define LOCAL_GL_CLIP_DISTANCE2 0x3002
+#define LOCAL_GL_CLIP_DISTANCE3 0x3003
+#define LOCAL_GL_CLIP_DISTANCE4 0x3004
+#define LOCAL_GL_CLIP_DISTANCE5 0x3005
+#define LOCAL_GL_CLIP_DISTANCE6 0x3006
+#define LOCAL_GL_CLIP_DISTANCE7 0x3007
+#define LOCAL_GL_CLIP_DISTANCE_NV 0x8C7A
+#define LOCAL_GL_CLIP_FAR_HINT_PGI 0x1A221
+#define LOCAL_GL_CLIP_NEAR_HINT_PGI 0x1A220
+#define LOCAL_GL_CLIP_PLANE0 0x3000
+#define LOCAL_GL_CLIP_PLANE0_IMG 0x3000
+#define LOCAL_GL_CLIP_PLANE1 0x3001
+#define LOCAL_GL_CLIP_PLANE1_IMG 0x3001
+#define LOCAL_GL_CLIP_PLANE2 0x3002
+#define LOCAL_GL_CLIP_PLANE2_IMG 0x3002
+#define LOCAL_GL_CLIP_PLANE3 0x3003
+#define LOCAL_GL_CLIP_PLANE3_IMG 0x3003
+#define LOCAL_GL_CLIP_PLANE4 0x3004
+#define LOCAL_GL_CLIP_PLANE4_IMG 0x3004
+#define LOCAL_GL_CLIP_PLANE5 0x3005
+#define LOCAL_GL_CLIP_PLANE5_IMG 0x3005
+#define LOCAL_GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0
+#define LOCAL_GL_CLOSE_PATH_NV 0x00
+#define LOCAL_GL_CMYKA_EXT 0x800D
+#define LOCAL_GL_CMYK_EXT 0x800C
+#define LOCAL_GL_CND0_ATI 0x896B
+#define LOCAL_GL_CND_ATI 0x896A
+#define LOCAL_GL_COEFF 0x0A00
+#define LOCAL_GL_COLOR 0x1800
+#define LOCAL_GL_COLOR3_BIT_PGI 0x00010000
+#define LOCAL_GL_COLOR4_BIT_PGI 0x00020000
+#define LOCAL_GL_COLORBURN_NV 0x929A
+#define LOCAL_GL_COLORDODGE_NV 0x9299
+#define LOCAL_GL_COLOR_ALPHA_PAIRING_ATI 0x8975
+#define LOCAL_GL_COLOR_ARRAY 0x8076
+#define LOCAL_GL_COLOR_ARRAY_ADDRESS_NV 0x8F23
+#define LOCAL_GL_COLOR_ARRAY_BUFFER_BINDING 0x8898
+#define LOCAL_GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898
+#define LOCAL_GL_COLOR_ARRAY_COUNT_EXT 0x8084
+#define LOCAL_GL_COLOR_ARRAY_EXT 0x8076
+#define LOCAL_GL_COLOR_ARRAY_LENGTH_NV 0x8F2D
+#define LOCAL_GL_COLOR_ARRAY_LIST_IBM 103072
+#define LOCAL_GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082
+#define LOCAL_GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7
+#define LOCAL_GL_COLOR_ARRAY_POINTER 0x8090
+#define LOCAL_GL_COLOR_ARRAY_POINTER_EXT 0x8090
+#define LOCAL_GL_COLOR_ARRAY_SIZE 0x8081
+#define LOCAL_GL_COLOR_ARRAY_SIZE_EXT 0x8081
+#define LOCAL_GL_COLOR_ARRAY_STRIDE 0x8083
+#define LOCAL_GL_COLOR_ARRAY_STRIDE_EXT 0x8083
+#define LOCAL_GL_COLOR_ARRAY_TYPE 0x8082
+#define LOCAL_GL_COLOR_ARRAY_TYPE_EXT 0x8082
+#define LOCAL_GL_COLOR_ATTACHMENT0 0x8CE0
+#define LOCAL_GL_COLOR_ATTACHMENT0_EXT 0x8CE0
+#define LOCAL_GL_COLOR_ATTACHMENT0_NV 0x8CE0
+#define LOCAL_GL_COLOR_ATTACHMENT0_OES 0x8CE0
+#define LOCAL_GL_COLOR_ATTACHMENT1 0x8CE1
+#define LOCAL_GL_COLOR_ATTACHMENT10 0x8CEA
+#define LOCAL_GL_COLOR_ATTACHMENT10_EXT 0x8CEA
+#define LOCAL_GL_COLOR_ATTACHMENT10_NV 0x8CEA
+#define LOCAL_GL_COLOR_ATTACHMENT11 0x8CEB
+#define LOCAL_GL_COLOR_ATTACHMENT11_EXT 0x8CEB
+#define LOCAL_GL_COLOR_ATTACHMENT11_NV 0x8CEB
+#define LOCAL_GL_COLOR_ATTACHMENT12 0x8CEC
+#define LOCAL_GL_COLOR_ATTACHMENT12_EXT 0x8CEC
+#define LOCAL_GL_COLOR_ATTACHMENT12_NV 0x8CEC
+#define LOCAL_GL_COLOR_ATTACHMENT13 0x8CED
+#define LOCAL_GL_COLOR_ATTACHMENT13_EXT 0x8CED
+#define LOCAL_GL_COLOR_ATTACHMENT13_NV 0x8CED
+#define LOCAL_GL_COLOR_ATTACHMENT14 0x8CEE
+#define LOCAL_GL_COLOR_ATTACHMENT14_EXT 0x8CEE
+#define LOCAL_GL_COLOR_ATTACHMENT14_NV 0x8CEE
+#define LOCAL_GL_COLOR_ATTACHMENT15 0x8CEF
+#define LOCAL_GL_COLOR_ATTACHMENT15_EXT 0x8CEF
+#define LOCAL_GL_COLOR_ATTACHMENT15_NV 0x8CEF
+#define LOCAL_GL_COLOR_ATTACHMENT1_EXT 0x8CE1
+#define LOCAL_GL_COLOR_ATTACHMENT1_NV 0x8CE1
+#define LOCAL_GL_COLOR_ATTACHMENT2 0x8CE2
+#define LOCAL_GL_COLOR_ATTACHMENT2_EXT 0x8CE2
+#define LOCAL_GL_COLOR_ATTACHMENT2_NV 0x8CE2
+#define LOCAL_GL_COLOR_ATTACHMENT3 0x8CE3
+#define LOCAL_GL_COLOR_ATTACHMENT3_EXT 0x8CE3
+#define LOCAL_GL_COLOR_ATTACHMENT3_NV 0x8CE3
+#define LOCAL_GL_COLOR_ATTACHMENT4 0x8CE4
+#define LOCAL_GL_COLOR_ATTACHMENT4_EXT 0x8CE4
+#define LOCAL_GL_COLOR_ATTACHMENT4_NV 0x8CE4
+#define LOCAL_GL_COLOR_ATTACHMENT5 0x8CE5
+#define LOCAL_GL_COLOR_ATTACHMENT5_EXT 0x8CE5
+#define LOCAL_GL_COLOR_ATTACHMENT5_NV 0x8CE5
+#define LOCAL_GL_COLOR_ATTACHMENT6 0x8CE6
+#define LOCAL_GL_COLOR_ATTACHMENT6_EXT 0x8CE6
+#define LOCAL_GL_COLOR_ATTACHMENT6_NV 0x8CE6
+#define LOCAL_GL_COLOR_ATTACHMENT7 0x8CE7
+#define LOCAL_GL_COLOR_ATTACHMENT7_EXT 0x8CE7
+#define LOCAL_GL_COLOR_ATTACHMENT7_NV 0x8CE7
+#define LOCAL_GL_COLOR_ATTACHMENT8 0x8CE8
+#define LOCAL_GL_COLOR_ATTACHMENT8_EXT 0x8CE8
+#define LOCAL_GL_COLOR_ATTACHMENT8_NV 0x8CE8
+#define LOCAL_GL_COLOR_ATTACHMENT9 0x8CE9
+#define LOCAL_GL_COLOR_ATTACHMENT9_EXT 0x8CE9
+#define LOCAL_GL_COLOR_ATTACHMENT9_NV 0x8CE9
+#define LOCAL_GL_COLOR_ATTACHMENT_EXT 0x90F0
+#define LOCAL_GL_COLOR_BUFFER_BIT 0x00004000
+#define LOCAL_GL_COLOR_BUFFER_BIT0_QCOM 0x00000001
+#define LOCAL_GL_COLOR_BUFFER_BIT1_QCOM 0x00000002
+#define LOCAL_GL_COLOR_BUFFER_BIT2_QCOM 0x00000004
+#define LOCAL_GL_COLOR_BUFFER_BIT3_QCOM 0x00000008
+#define LOCAL_GL_COLOR_BUFFER_BIT4_QCOM 0x00000010
+#define LOCAL_GL_COLOR_BUFFER_BIT5_QCOM 0x00000020
+#define LOCAL_GL_COLOR_BUFFER_BIT6_QCOM 0x00000040
+#define LOCAL_GL_COLOR_BUFFER_BIT7_QCOM 0x00000080
+#define LOCAL_GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835
+#define LOCAL_GL_COLOR_CLEAR_VALUE 0x0C22
+#define LOCAL_GL_COLOR_COMPONENTS 0x8283
+#define LOCAL_GL_COLOR_ENCODING 0x8296
+#define LOCAL_GL_COLOR_EXT 0x1800
+#define LOCAL_GL_COLOR_FLOAT_APPLE 0x8A0F
+#define LOCAL_GL_COLOR_INDEX 0x1900
+#define LOCAL_GL_COLOR_INDEX12_EXT 0x80E6
+#define LOCAL_GL_COLOR_INDEX16_EXT 0x80E7
+#define LOCAL_GL_COLOR_INDEX1_EXT 0x80E2
+#define LOCAL_GL_COLOR_INDEX2_EXT 0x80E3
+#define LOCAL_GL_COLOR_INDEX4_EXT 0x80E4
+#define LOCAL_GL_COLOR_INDEX8_EXT 0x80E5
+#define LOCAL_GL_COLOR_INDEXES 0x1603
+#define LOCAL_GL_COLOR_LOGIC_OP 0x0BF2
+#define LOCAL_GL_COLOR_MATERIAL 0x0B57
+#define LOCAL_GL_COLOR_MATERIAL_FACE 0x0B55
+#define LOCAL_GL_COLOR_MATERIAL_PARAMETER 0x0B56
+#define LOCAL_GL_COLOR_MATRIX 0x80B1
+#define LOCAL_GL_COLOR_MATRIX_SGI 0x80B1
+#define LOCAL_GL_COLOR_MATRIX_STACK_DEPTH 0x80B2
+#define LOCAL_GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2
+#define LOCAL_GL_COLOR_RENDERABLE 0x8286
+#define LOCAL_GL_COLOR_SAMPLES_NV 0x8E20
+#define LOCAL_GL_COLOR_SUM 0x8458
+#define LOCAL_GL_COLOR_SUM_ARB 0x8458
+#define LOCAL_GL_COLOR_SUM_CLAMP_NV 0x854F
+#define LOCAL_GL_COLOR_SUM_EXT 0x8458
+#define LOCAL_GL_COLOR_TABLE 0x80D0
+#define LOCAL_GL_COLOR_TABLE_ALPHA_SIZE 0x80DD
+#define LOCAL_GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD
+#define LOCAL_GL_COLOR_TABLE_BIAS 0x80D7
+#define LOCAL_GL_COLOR_TABLE_BIAS_SGI 0x80D7
+#define LOCAL_GL_COLOR_TABLE_BLUE_SIZE 0x80DC
+#define LOCAL_GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC
+#define LOCAL_GL_COLOR_TABLE_FORMAT 0x80D8
+#define LOCAL_GL_COLOR_TABLE_FORMAT_SGI 0x80D8
+#define LOCAL_GL_COLOR_TABLE_GREEN_SIZE 0x80DB
+#define LOCAL_GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB
+#define LOCAL_GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF
+#define LOCAL_GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF
+#define LOCAL_GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE
+#define LOCAL_GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE
+#define LOCAL_GL_COLOR_TABLE_RED_SIZE 0x80DA
+#define LOCAL_GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA
+#define LOCAL_GL_COLOR_TABLE_SCALE 0x80D6
+#define LOCAL_GL_COLOR_TABLE_SCALE_SGI 0x80D6
+#define LOCAL_GL_COLOR_TABLE_SGI 0x80D0
+#define LOCAL_GL_COLOR_TABLE_WIDTH 0x80D9
+#define LOCAL_GL_COLOR_TABLE_WIDTH_SGI 0x80D9
+#define LOCAL_GL_COLOR_WRITEMASK 0x0C23
+#define LOCAL_GL_COMBINE 0x8570
+#define LOCAL_GL_COMBINE4_NV 0x8503
+#define LOCAL_GL_COMBINER0_NV 0x8550
+#define LOCAL_GL_COMBINER1_NV 0x8551
+#define LOCAL_GL_COMBINER2_NV 0x8552
+#define LOCAL_GL_COMBINER3_NV 0x8553
+#define LOCAL_GL_COMBINER4_NV 0x8554
+#define LOCAL_GL_COMBINER5_NV 0x8555
+#define LOCAL_GL_COMBINER6_NV 0x8556
+#define LOCAL_GL_COMBINER7_NV 0x8557
+#define LOCAL_GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545
+#define LOCAL_GL_COMBINER_AB_OUTPUT_NV 0x854A
+#define LOCAL_GL_COMBINER_BIAS_NV 0x8549
+#define LOCAL_GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546
+#define LOCAL_GL_COMBINER_CD_OUTPUT_NV 0x854B
+#define LOCAL_GL_COMBINER_COMPONENT_USAGE_NV 0x8544
+#define LOCAL_GL_COMBINER_INPUT_NV 0x8542
+#define LOCAL_GL_COMBINER_MAPPING_NV 0x8543
+#define LOCAL_GL_COMBINER_MUX_SUM_NV 0x8547
+#define LOCAL_GL_COMBINER_SCALE_NV 0x8548
+#define LOCAL_GL_COMBINER_SUM_OUTPUT_NV 0x854C
+#define LOCAL_GL_COMBINE_ALPHA 0x8572
+#define LOCAL_GL_COMBINE_ALPHA_ARB 0x8572
+#define LOCAL_GL_COMBINE_ALPHA_EXT 0x8572
+#define LOCAL_GL_COMBINE_ARB 0x8570
+#define LOCAL_GL_COMBINE_EXT 0x8570
+#define LOCAL_GL_COMBINE_RGB 0x8571
+#define LOCAL_GL_COMBINE_RGB_ARB 0x8571
+#define LOCAL_GL_COMBINE_RGB_EXT 0x8571
+#define LOCAL_GL_COMMAND_BARRIER_BIT 0x00000040
+#define LOCAL_GL_COMMAND_BARRIER_BIT_EXT 0x00000040
+#define LOCAL_GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E
+#define LOCAL_GL_COMPARE_REF_TO_TEXTURE 0x884E
+#define LOCAL_GL_COMPARE_REF_TO_TEXTURE_EXT 0x884E
+#define LOCAL_GL_COMPARE_R_TO_TEXTURE 0x884E
+#define LOCAL_GL_COMPARE_R_TO_TEXTURE_ARB 0x884E
+#define LOCAL_GL_COMPATIBLE_SUBROUTINES 0x8E4B
+#define LOCAL_GL_COMPILE 0x1300
+#define LOCAL_GL_COMPILE_AND_EXECUTE 0x1301
+#define LOCAL_GL_COMPILE_STATUS 0x8B81
+#define LOCAL_GL_COMPRESSED_ALPHA 0x84E9
+#define LOCAL_GL_COMPRESSED_ALPHA_ARB 0x84E9
+#define LOCAL_GL_COMPRESSED_INTENSITY 0x84EC
+#define LOCAL_GL_COMPRESSED_INTENSITY_ARB 0x84EC
+#define LOCAL_GL_COMPRESSED_LUMINANCE 0x84EA
+#define LOCAL_GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB
+#define LOCAL_GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI 0x8837
+#define LOCAL_GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB
+#define LOCAL_GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72
+#define LOCAL_GL_COMPRESSED_LUMINANCE_ARB 0x84EA
+#define LOCAL_GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70
+#define LOCAL_GL_COMPRESSED_R11_EAC 0x9270
+#define LOCAL_GL_COMPRESSED_R11_EAC_OES 0x9270
+#define LOCAL_GL_COMPRESSED_RED 0x8225
+#define LOCAL_GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD
+#define LOCAL_GL_COMPRESSED_RED_RGTC1 0x8DBB
+#define LOCAL_GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB
+#define LOCAL_GL_COMPRESSED_RG 0x8226
+#define LOCAL_GL_COMPRESSED_RG11_EAC 0x9272
+#define LOCAL_GL_COMPRESSED_RG11_EAC_OES 0x9272
+#define LOCAL_GL_COMPRESSED_RGB 0x84ED
+#define LOCAL_GL_COMPRESSED_RGB8_ETC2 0x9274
+#define LOCAL_GL_COMPRESSED_RGB8_ETC2_OES 0x9274
+#define LOCAL_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
+#define LOCAL_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_OES 0x9276
+#define LOCAL_GL_COMPRESSED_RGBA 0x84EE
+#define LOCAL_GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
+#define LOCAL_GL_COMPRESSED_RGBA8_ETC2_EAC_OES 0x9278
+#define LOCAL_GL_COMPRESSED_RGBA_ARB 0x84EE
+#define LOCAL_GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB
+#define LOCAL_GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8
+#define LOCAL_GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9
+#define LOCAL_GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA
+#define LOCAL_GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC
+#define LOCAL_GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD
+#define LOCAL_GL_COMPRESSED_RGBA_ASTC_3x3x3_OES 0x93C0
+#define LOCAL_GL_COMPRESSED_RGBA_ASTC_4x3x3_OES 0x93C1
+#define LOCAL_GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0
+#define LOCAL_GL_COMPRESSED_RGBA_ASTC_4x4x3_OES 0x93C2
+#define LOCAL_GL_COMPRESSED_RGBA_ASTC_4x4x4_OES 0x93C3
+#define LOCAL_GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1
+#define LOCAL_GL_COMPRESSED_RGBA_ASTC_5x4x4_OES 0x93C4
+#define LOCAL_GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2
+#define LOCAL_GL_COMPRESSED_RGBA_ASTC_5x5x4_OES 0x93C5
+#define LOCAL_GL_COMPRESSED_RGBA_ASTC_5x5x5_OES 0x93C6
+#define LOCAL_GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3
+#define LOCAL_GL_COMPRESSED_RGBA_ASTC_6x5x5_OES 0x93C7
+#define LOCAL_GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4
+#define LOCAL_GL_COMPRESSED_RGBA_ASTC_6x6x5_OES 0x93C8
+#define LOCAL_GL_COMPRESSED_RGBA_ASTC_6x6x6_OES 0x93C9
+#define LOCAL_GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5
+#define LOCAL_GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6
+#define LOCAL_GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7
+#define LOCAL_GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C
+#define LOCAL_GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C
+#define LOCAL_GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1
+#define LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03
+#define LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG 0x9137
+#define LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02
+#define LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138
+#define LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
+#define LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2
+#define LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
+#define LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3
+#define LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
+#define LOCAL_GL_COMPRESSED_RGB_ARB 0x84ED
+#define LOCAL_GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E
+#define LOCAL_GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E
+#define LOCAL_GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F
+#define LOCAL_GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F
+#define LOCAL_GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0
+#define LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01
+#define LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00
+#define LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
+#define LOCAL_GL_COMPRESSED_RG_RGTC2 0x8DBD
+#define LOCAL_GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73
+#define LOCAL_GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71
+#define LOCAL_GL_COMPRESSED_SIGNED_R11_EAC 0x9271
+#define LOCAL_GL_COMPRESSED_SIGNED_R11_EAC_OES 0x9271
+#define LOCAL_GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE
+#define LOCAL_GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC
+#define LOCAL_GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC
+#define LOCAL_GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
+#define LOCAL_GL_COMPRESSED_SIGNED_RG11_EAC_OES 0x9273
+#define LOCAL_GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE
+#define LOCAL_GL_COMPRESSED_SLUMINANCE 0x8C4A
+#define LOCAL_GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B
+#define LOCAL_GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B
+#define LOCAL_GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A
+#define LOCAL_GL_COMPRESSED_SRGB 0x8C48
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES 0x93E0
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES 0x93E1
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES 0x93E2
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES 0x93E3
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES 0x93E4
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES 0x93E5
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES 0x93E6
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES 0x93E7
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES 0x93E8
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES 0x93E9
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
+#define LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_OES 0x9279
+#define LOCAL_GL_COMPRESSED_SRGB8_ETC2 0x9275
+#define LOCAL_GL_COMPRESSED_SRGB8_ETC2_OES 0x9275
+#define LOCAL_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
+#define LOCAL_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_OES 0x9277
+#define LOCAL_GL_COMPRESSED_SRGB_ALPHA 0x8C49
+#define LOCAL_GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D
+#define LOCAL_GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D
+#define LOCAL_GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49
+#define LOCAL_GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT 0x8A56
+#define LOCAL_GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT 0x8A57
+#define LOCAL_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
+#define LOCAL_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV 0x8C4D
+#define LOCAL_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
+#define LOCAL_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV 0x8C4E
+#define LOCAL_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
+#define LOCAL_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV 0x8C4F
+#define LOCAL_GL_COMPRESSED_SRGB_EXT 0x8C48
+#define LOCAL_GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT 0x8A54
+#define LOCAL_GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT 0x8A55
+#define LOCAL_GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C
+#define LOCAL_GL_COMPRESSED_SRGB_S3TC_DXT1_NV 0x8C4C
+#define LOCAL_GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
+#define LOCAL_GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3
+#define LOCAL_GL_COMPUTE_PROGRAM_NV 0x90FB
+#define LOCAL_GL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV 0x90FC
+#define LOCAL_GL_COMPUTE_SHADER 0x91B9
+#define LOCAL_GL_COMPUTE_SHADER_BIT 0x00000020
+#define LOCAL_GL_COMPUTE_SUBROUTINE 0x92ED
+#define LOCAL_GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3
+#define LOCAL_GL_COMPUTE_TEXTURE 0x82A0
+#define LOCAL_GL_COMPUTE_WORK_GROUP_SIZE 0x8267
+#define LOCAL_GL_COMP_BIT_ATI 0x00000002
+#define LOCAL_GL_CONDITION_SATISFIED 0x911C
+#define LOCAL_GL_CONDITION_SATISFIED_APPLE 0x911C
+#define LOCAL_GL_CONJOINT_NV 0x9284
+#define LOCAL_GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD
+#define LOCAL_GL_CONSTANT 0x8576
+#define LOCAL_GL_CONSTANT_ALPHA 0x8003
+#define LOCAL_GL_CONSTANT_ALPHA_EXT 0x8003
+#define LOCAL_GL_CONSTANT_ARB 0x8576
+#define LOCAL_GL_CONSTANT_ATTENUATION 0x1207
+#define LOCAL_GL_CONSTANT_BORDER 0x8151
+#define LOCAL_GL_CONSTANT_BORDER_HP 0x8151
+#define LOCAL_GL_CONSTANT_COLOR 0x8001
+#define LOCAL_GL_CONSTANT_COLOR0_NV 0x852A
+#define LOCAL_GL_CONSTANT_COLOR1_NV 0x852B
+#define LOCAL_GL_CONSTANT_COLOR_EXT 0x8001
+#define LOCAL_GL_CONSTANT_EXT 0x8576
+#define LOCAL_GL_CONST_EYE_NV 0x86E5
+#define LOCAL_GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define LOCAL_GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
+#define LOCAL_GL_CONTEXT_FLAGS 0x821E
+#define LOCAL_GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
+#define LOCAL_GL_CONTEXT_FLAG_DEBUG_BIT_KHR 0x00000002
+#define LOCAL_GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001
+#define LOCAL_GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004
+#define LOCAL_GL_CONTEXT_PROFILE_MASK 0x9126
+#define LOCAL_GL_CONTEXT_ROBUST_ACCESS_EXT 0x90F3
+#define LOCAL_GL_CONTINUOUS_AMD 0x9007
+#define LOCAL_GL_CONTRAST_NV 0x92A1
+#define LOCAL_GL_CONVEX_HULL_NV 0x908B
+#define LOCAL_GL_CONVOLUTION_1D 0x8010
+#define LOCAL_GL_CONVOLUTION_1D_EXT 0x8010
+#define LOCAL_GL_CONVOLUTION_2D 0x8011
+#define LOCAL_GL_CONVOLUTION_2D_EXT 0x8011
+#define LOCAL_GL_CONVOLUTION_BORDER_COLOR 0x8154
+#define LOCAL_GL_CONVOLUTION_BORDER_COLOR_HP 0x8154
+#define LOCAL_GL_CONVOLUTION_BORDER_MODE 0x8013
+#define LOCAL_GL_CONVOLUTION_BORDER_MODE_EXT 0x8013
+#define LOCAL_GL_CONVOLUTION_FILTER_BIAS 0x8015
+#define LOCAL_GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015
+#define LOCAL_GL_CONVOLUTION_FILTER_SCALE 0x8014
+#define LOCAL_GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014
+#define LOCAL_GL_CONVOLUTION_FORMAT 0x8017
+#define LOCAL_GL_CONVOLUTION_FORMAT_EXT 0x8017
+#define LOCAL_GL_CONVOLUTION_HEIGHT 0x8019
+#define LOCAL_GL_CONVOLUTION_HEIGHT_EXT 0x8019
+#define LOCAL_GL_CONVOLUTION_HINT_SGIX 0x8316
+#define LOCAL_GL_CONVOLUTION_WIDTH 0x8018
+#define LOCAL_GL_CONVOLUTION_WIDTH_EXT 0x8018
+#define LOCAL_GL_CON_0_ATI 0x8941
+#define LOCAL_GL_CON_10_ATI 0x894B
+#define LOCAL_GL_CON_11_ATI 0x894C
+#define LOCAL_GL_CON_12_ATI 0x894D
+#define LOCAL_GL_CON_13_ATI 0x894E
+#define LOCAL_GL_CON_14_ATI 0x894F
+#define LOCAL_GL_CON_15_ATI 0x8950
+#define LOCAL_GL_CON_16_ATI 0x8951
+#define LOCAL_GL_CON_17_ATI 0x8952
+#define LOCAL_GL_CON_18_ATI 0x8953
+#define LOCAL_GL_CON_19_ATI 0x8954
+#define LOCAL_GL_CON_1_ATI 0x8942
+#define LOCAL_GL_CON_20_ATI 0x8955
+#define LOCAL_GL_CON_21_ATI 0x8956
+#define LOCAL_GL_CON_22_ATI 0x8957
+#define LOCAL_GL_CON_23_ATI 0x8958
+#define LOCAL_GL_CON_24_ATI 0x8959
+#define LOCAL_GL_CON_25_ATI 0x895A
+#define LOCAL_GL_CON_26_ATI 0x895B
+#define LOCAL_GL_CON_27_ATI 0x895C
+#define LOCAL_GL_CON_28_ATI 0x895D
+#define LOCAL_GL_CON_29_ATI 0x895E
+#define LOCAL_GL_CON_2_ATI 0x8943
+#define LOCAL_GL_CON_30_ATI 0x895F
+#define LOCAL_GL_CON_31_ATI 0x8960
+#define LOCAL_GL_CON_3_ATI 0x8944
+#define LOCAL_GL_CON_4_ATI 0x8945
+#define LOCAL_GL_CON_5_ATI 0x8946
+#define LOCAL_GL_CON_6_ATI 0x8947
+#define LOCAL_GL_CON_7_ATI 0x8948
+#define LOCAL_GL_CON_8_ATI 0x8949
+#define LOCAL_GL_CON_9_ATI 0x894A
+#define LOCAL_GL_COORD_REPLACE 0x8862
+#define LOCAL_GL_COORD_REPLACE_ARB 0x8862
+#define LOCAL_GL_COORD_REPLACE_NV 0x8862
+#define LOCAL_GL_COORD_REPLACE_OES 0x8862
+#define LOCAL_GL_COPY 0x1503
+#define LOCAL_GL_COPY_INVERTED 0x150C
+#define LOCAL_GL_COPY_PIXEL_TOKEN 0x0706
+#define LOCAL_GL_COPY_READ_BUFFER 0x8F36
+#define LOCAL_GL_COPY_READ_BUFFER_BINDING 0x8F36
+#define LOCAL_GL_COPY_READ_BUFFER_NV 0x8F36
+#define LOCAL_GL_COPY_WRITE_BUFFER 0x8F37
+#define LOCAL_GL_COPY_WRITE_BUFFER_BINDING 0x8F37
+#define LOCAL_GL_COPY_WRITE_BUFFER_NV 0x8F37
+#define LOCAL_GL_COUNTER_RANGE_AMD 0x8BC1
+#define LOCAL_GL_COUNTER_TYPE_AMD 0x8BC0
+#define LOCAL_GL_COUNT_DOWN_NV 0x9089
+#define LOCAL_GL_COUNT_UP_NV 0x9088
+#define LOCAL_GL_COVERAGE_ALL_FRAGMENTS_NV 0x8ED5
+#define LOCAL_GL_COVERAGE_ATTACHMENT_NV 0x8ED2
+#define LOCAL_GL_COVERAGE_AUTOMATIC_NV 0x8ED7
+#define LOCAL_GL_COVERAGE_BUFFERS_NV 0x8ED3
+#define LOCAL_GL_COVERAGE_BUFFER_BIT_NV 0x00008000
+#define LOCAL_GL_COVERAGE_COMPONENT4_NV 0x8ED1
+#define LOCAL_GL_COVERAGE_COMPONENT_NV 0x8ED0
+#define LOCAL_GL_COVERAGE_EDGE_FRAGMENTS_NV 0x8ED6
+#define LOCAL_GL_COVERAGE_SAMPLES_NV 0x8ED4
+#define LOCAL_GL_CPU_OPTIMIZED_QCOM 0x8FB1
+#define LOCAL_GL_CUBIC_CURVE_TO_NV 0x0C
+#define LOCAL_GL_CUBIC_EXT 0x8334
+#define LOCAL_GL_CUBIC_HP 0x815F
+#define LOCAL_GL_CULL_FACE 0x0B44
+#define LOCAL_GL_CULL_FACE_MODE 0x0B45
+#define LOCAL_GL_CULL_FRAGMENT_NV 0x86E7
+#define LOCAL_GL_CULL_MODES_NV 0x86E0
+#define LOCAL_GL_CULL_VERTEX_EXT 0x81AA
+#define LOCAL_GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB
+#define LOCAL_GL_CULL_VERTEX_IBM 103050
+#define LOCAL_GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC
+#define LOCAL_GL_CURRENT_ATTRIB_NV 0x8626
+#define LOCAL_GL_CURRENT_BINORMAL_EXT 0x843C
+#define LOCAL_GL_CURRENT_BIT 0x00000001
+#define LOCAL_GL_CURRENT_COLOR 0x0B00
+#define LOCAL_GL_CURRENT_FOG_COORD 0x8453
+#define LOCAL_GL_CURRENT_FOG_COORDINATE 0x8453
+#define LOCAL_GL_CURRENT_FOG_COORDINATE_EXT 0x8453
+#define LOCAL_GL_CURRENT_INDEX 0x0B01
+#define LOCAL_GL_CURRENT_MATRIX_ARB 0x8641
+#define LOCAL_GL_CURRENT_MATRIX_INDEX_ARB 0x8845
+#define LOCAL_GL_CURRENT_MATRIX_NV 0x8641
+#define LOCAL_GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640
+#define LOCAL_GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640
+#define LOCAL_GL_CURRENT_NORMAL 0x0B02
+#define LOCAL_GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865
+#define LOCAL_GL_CURRENT_PALETTE_MATRIX_ARB 0x8843
+#define LOCAL_GL_CURRENT_PALETTE_MATRIX_OES 0x8843
+#define LOCAL_GL_CURRENT_PROGRAM 0x8B8D
+#define LOCAL_GL_CURRENT_QUERY 0x8865
+#define LOCAL_GL_CURRENT_QUERY_ARB 0x8865
+#define LOCAL_GL_CURRENT_QUERY_EXT 0x8865
+#define LOCAL_GL_CURRENT_RASTER_COLOR 0x0B04
+#define LOCAL_GL_CURRENT_RASTER_DISTANCE 0x0B09
+#define LOCAL_GL_CURRENT_RASTER_INDEX 0x0B05
+#define LOCAL_GL_CURRENT_RASTER_NORMAL_SGIX 0x8406
+#define LOCAL_GL_CURRENT_RASTER_POSITION 0x0B07
+#define LOCAL_GL_CURRENT_RASTER_POSITION_VALID 0x0B08
+#define LOCAL_GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F
+#define LOCAL_GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06
+#define LOCAL_GL_CURRENT_SECONDARY_COLOR 0x8459
+#define LOCAL_GL_CURRENT_SECONDARY_COLOR_EXT 0x8459
+#define LOCAL_GL_CURRENT_TANGENT_EXT 0x843B
+#define LOCAL_GL_CURRENT_TEXTURE_COORDS 0x0B03
+#define LOCAL_GL_CURRENT_TIME_NV 0x8E28
+#define LOCAL_GL_CURRENT_VERTEX_ATTRIB 0x8626
+#define LOCAL_GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626
+#define LOCAL_GL_CURRENT_VERTEX_EXT 0x87E2
+#define LOCAL_GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B
+#define LOCAL_GL_CURRENT_WEIGHT_ARB 0x86A8
+#define LOCAL_GL_CW 0x0900
+#define LOCAL_GL_DARKEN_NV 0x9297
+#define LOCAL_GL_DATA_BUFFER_AMD 0x9151
+#define LOCAL_GL_DEBUG_ASSERT_MESA 0x875B
+#define LOCAL_GL_DEBUG_CALLBACK_FUNCTION 0x8244
+#define LOCAL_GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244
+#define LOCAL_GL_DEBUG_CALLBACK_FUNCTION_KHR 0x8244
+#define LOCAL_GL_DEBUG_CALLBACK_USER_PARAM 0x8245
+#define LOCAL_GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245
+#define LOCAL_GL_DEBUG_CALLBACK_USER_PARAM_KHR 0x8245
+#define LOCAL_GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149
+#define LOCAL_GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F
+#define LOCAL_GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B
+#define LOCAL_GL_DEBUG_CATEGORY_OTHER_AMD 0x9150
+#define LOCAL_GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D
+#define LOCAL_GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E
+#define LOCAL_GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C
+#define LOCAL_GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A
+#define LOCAL_GL_DEBUG_GROUP_STACK_DEPTH 0x826D
+#define LOCAL_GL_DEBUG_GROUP_STACK_DEPTH_KHR 0x826D
+#define LOCAL_GL_DEBUG_LOGGED_MESSAGES 0x9145
+#define LOCAL_GL_DEBUG_LOGGED_MESSAGES_AMD 0x9145
+#define LOCAL_GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145
+#define LOCAL_GL_DEBUG_LOGGED_MESSAGES_KHR 0x9145
+#define LOCAL_GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243
+#define LOCAL_GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243
+#define LOCAL_GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_KHR 0x8243
+#define LOCAL_GL_DEBUG_OBJECT_MESA 0x8759
+#define LOCAL_GL_DEBUG_OUTPUT 0x92E0
+#define LOCAL_GL_DEBUG_OUTPUT_KHR 0x92E0
+#define LOCAL_GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
+#define LOCAL_GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242
+#define LOCAL_GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR 0x8242
+#define LOCAL_GL_DEBUG_PRINT_MESA 0x875A
+#define LOCAL_GL_DEBUG_SEVERITY_HIGH 0x9146
+#define LOCAL_GL_DEBUG_SEVERITY_HIGH_AMD 0x9146
+#define LOCAL_GL_DEBUG_SEVERITY_HIGH_ARB 0x9146
+#define LOCAL_GL_DEBUG_SEVERITY_HIGH_KHR 0x9146
+#define LOCAL_GL_DEBUG_SEVERITY_LOW 0x9148
+#define LOCAL_GL_DEBUG_SEVERITY_LOW_AMD 0x9148
+#define LOCAL_GL_DEBUG_SEVERITY_LOW_ARB 0x9148
+#define LOCAL_GL_DEBUG_SEVERITY_LOW_KHR 0x9148
+#define LOCAL_GL_DEBUG_SEVERITY_MEDIUM 0x9147
+#define LOCAL_GL_DEBUG_SEVERITY_MEDIUM_AMD 0x9147
+#define LOCAL_GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147
+#define LOCAL_GL_DEBUG_SEVERITY_MEDIUM_KHR 0x9147
+#define LOCAL_GL_DEBUG_SEVERITY_NOTIFICATION 0x826B
+#define LOCAL_GL_DEBUG_SEVERITY_NOTIFICATION_KHR 0x826B
+#define LOCAL_GL_DEBUG_SOURCE_API 0x8246
+#define LOCAL_GL_DEBUG_SOURCE_API_ARB 0x8246
+#define LOCAL_GL_DEBUG_SOURCE_API_KHR 0x8246
+#define LOCAL_GL_DEBUG_SOURCE_APPLICATION 0x824A
+#define LOCAL_GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A
+#define LOCAL_GL_DEBUG_SOURCE_APPLICATION_KHR 0x824A
+#define LOCAL_GL_DEBUG_SOURCE_OTHER 0x824B
+#define LOCAL_GL_DEBUG_SOURCE_OTHER_ARB 0x824B
+#define LOCAL_GL_DEBUG_SOURCE_OTHER_KHR 0x824B
+#define LOCAL_GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248
+#define LOCAL_GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248
+#define LOCAL_GL_DEBUG_SOURCE_SHADER_COMPILER_KHR 0x8248
+#define LOCAL_GL_DEBUG_SOURCE_THIRD_PARTY 0x8249
+#define LOCAL_GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249
+#define LOCAL_GL_DEBUG_SOURCE_THIRD_PARTY_KHR 0x8249
+#define LOCAL_GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247
+#define LOCAL_GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247
+#define LOCAL_GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR 0x8247
+#define LOCAL_GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D
+#define LOCAL_GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D
+#define LOCAL_GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR 0x824D
+#define LOCAL_GL_DEBUG_TYPE_ERROR 0x824C
+#define LOCAL_GL_DEBUG_TYPE_ERROR_ARB 0x824C
+#define LOCAL_GL_DEBUG_TYPE_ERROR_KHR 0x824C
+#define LOCAL_GL_DEBUG_TYPE_MARKER 0x8268
+#define LOCAL_GL_DEBUG_TYPE_MARKER_KHR 0x8268
+#define LOCAL_GL_DEBUG_TYPE_OTHER 0x8251
+#define LOCAL_GL_DEBUG_TYPE_OTHER_ARB 0x8251
+#define LOCAL_GL_DEBUG_TYPE_OTHER_KHR 0x8251
+#define LOCAL_GL_DEBUG_TYPE_PERFORMANCE 0x8250
+#define LOCAL_GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250
+#define LOCAL_GL_DEBUG_TYPE_PERFORMANCE_KHR 0x8250
+#define LOCAL_GL_DEBUG_TYPE_POP_GROUP 0x826A
+#define LOCAL_GL_DEBUG_TYPE_POP_GROUP_KHR 0x826A
+#define LOCAL_GL_DEBUG_TYPE_PORTABILITY 0x824F
+#define LOCAL_GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F
+#define LOCAL_GL_DEBUG_TYPE_PORTABILITY_KHR 0x824F
+#define LOCAL_GL_DEBUG_TYPE_PUSH_GROUP 0x8269
+#define LOCAL_GL_DEBUG_TYPE_PUSH_GROUP_KHR 0x8269
+#define LOCAL_GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E
+#define LOCAL_GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E
+#define LOCAL_GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR 0x824E
+#define LOCAL_GL_DECAL 0x2101
+#define LOCAL_GL_DECODE_EXT 0x8A49
+#define LOCAL_GL_DECR 0x1E03
+#define LOCAL_GL_DECR_WRAP 0x8508
+#define LOCAL_GL_DECR_WRAP_EXT 0x8508
+#define LOCAL_GL_DECR_WRAP_OES 0x8508
+#define LOCAL_GL_DEFORMATIONS_MASK_SGIX 0x8196
+#define LOCAL_GL_DELETE_STATUS 0x8B80
+#define LOCAL_GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9
+#define LOCAL_GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA
+#define LOCAL_GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858
+#define LOCAL_GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859
+#define LOCAL_GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A
+#define LOCAL_GL_DEPTH 0x1801
+#define LOCAL_GL_DEPTH24_STENCIL8 0x88F0
+#define LOCAL_GL_DEPTH24_STENCIL8_EXT 0x88F0
+#define LOCAL_GL_DEPTH24_STENCIL8_OES 0x88F0
+#define LOCAL_GL_DEPTH32F_STENCIL8 0x8CAD
+#define LOCAL_GL_DEPTH32F_STENCIL8_NV 0x8DAC
+#define LOCAL_GL_DEPTH_ATTACHMENT 0x8D00
+#define LOCAL_GL_DEPTH_ATTACHMENT_EXT 0x8D00
+#define LOCAL_GL_DEPTH_ATTACHMENT_OES 0x8D00
+#define LOCAL_GL_DEPTH_BIAS 0x0D1F
+#define LOCAL_GL_DEPTH_BITS 0x0D56
+#define LOCAL_GL_DEPTH_BOUNDS_EXT 0x8891
+#define LOCAL_GL_DEPTH_BOUNDS_TEST_EXT 0x8890
+#define LOCAL_GL_DEPTH_BUFFER_BIT 0x00000100
+#define LOCAL_GL_DEPTH_BUFFER_BIT0_QCOM 0x00000100
+#define LOCAL_GL_DEPTH_BUFFER_BIT1_QCOM 0x00000200
+#define LOCAL_GL_DEPTH_BUFFER_BIT2_QCOM 0x00000400
+#define LOCAL_GL_DEPTH_BUFFER_BIT3_QCOM 0x00000800
+#define LOCAL_GL_DEPTH_BUFFER_BIT4_QCOM 0x00001000
+#define LOCAL_GL_DEPTH_BUFFER_BIT5_QCOM 0x00002000
+#define LOCAL_GL_DEPTH_BUFFER_BIT6_QCOM 0x00004000
+#define LOCAL_GL_DEPTH_BUFFER_BIT7_QCOM 0x00008000
+#define LOCAL_GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF
+#define LOCAL_GL_DEPTH_CLAMP 0x864F
+#define LOCAL_GL_DEPTH_CLAMP_FAR_AMD 0x901F
+#define LOCAL_GL_DEPTH_CLAMP_NEAR_AMD 0x901E
+#define LOCAL_GL_DEPTH_CLAMP_NV 0x864F
+#define LOCAL_GL_DEPTH_CLEAR_VALUE 0x0B73
+#define LOCAL_GL_DEPTH_COMPONENT 0x1902
+#define LOCAL_GL_DEPTH_COMPONENT16 0x81A5
+#define LOCAL_GL_DEPTH_COMPONENT16_ARB 0x81A5
+#define LOCAL_GL_DEPTH_COMPONENT16_NONLINEAR_NV 0x8E2C
+#define LOCAL_GL_DEPTH_COMPONENT16_OES 0x81A5
+#define LOCAL_GL_DEPTH_COMPONENT16_SGIX 0x81A5
+#define LOCAL_GL_DEPTH_COMPONENT24 0x81A6
+#define LOCAL_GL_DEPTH_COMPONENT24_ARB 0x81A6
+#define LOCAL_GL_DEPTH_COMPONENT24_OES 0x81A6
+#define LOCAL_GL_DEPTH_COMPONENT24_SGIX 0x81A6
+#define LOCAL_GL_DEPTH_COMPONENT32 0x81A7
+#define LOCAL_GL_DEPTH_COMPONENT32F 0x8CAC
+#define LOCAL_GL_DEPTH_COMPONENT32F_NV 0x8DAB
+#define LOCAL_GL_DEPTH_COMPONENT32_ARB 0x81A7
+#define LOCAL_GL_DEPTH_COMPONENT32_OES 0x81A7
+#define LOCAL_GL_DEPTH_COMPONENT32_SGIX 0x81A7
+#define LOCAL_GL_DEPTH_COMPONENTS 0x8284
+#define LOCAL_GL_DEPTH_EXT 0x1801
+#define LOCAL_GL_DEPTH_FUNC 0x0B74
+#define LOCAL_GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311
+#define LOCAL_GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312
+#define LOCAL_GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310
+#define LOCAL_GL_DEPTH_RANGE 0x0B70
+#define LOCAL_GL_DEPTH_RENDERABLE 0x8287
+#define LOCAL_GL_DEPTH_SCALE 0x0D1E
+#define LOCAL_GL_DEPTH_STENCIL 0x84F9
+#define LOCAL_GL_DEPTH_STENCIL_ATTACHMENT 0x821A
+#define LOCAL_GL_DEPTH_STENCIL_EXT 0x84F9
+#define LOCAL_GL_DEPTH_STENCIL_MESA 0x8750
+#define LOCAL_GL_DEPTH_STENCIL_NV 0x84F9
+#define LOCAL_GL_DEPTH_STENCIL_OES 0x84F9
+#define LOCAL_GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA
+#define LOCAL_GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F
+#define LOCAL_GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E
+#define LOCAL_GL_DEPTH_TEST 0x0B71
+#define LOCAL_GL_DEPTH_TEXTURE_MODE 0x884B
+#define LOCAL_GL_DEPTH_TEXTURE_MODE_ARB 0x884B
+#define LOCAL_GL_DEPTH_WRITEMASK 0x0B72
+#define LOCAL_GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096
+#define LOCAL_GL_DETAIL_TEXTURE_2D_SGIS 0x8095
+#define LOCAL_GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C
+#define LOCAL_GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A
+#define LOCAL_GL_DETAIL_TEXTURE_MODE_SGIS 0x809B
+#define LOCAL_GL_DIFFERENCE_NV 0x929E
+#define LOCAL_GL_DIFFUSE 0x1201
+#define LOCAL_GL_DISCARD_ATI 0x8763
+#define LOCAL_GL_DISCARD_NV 0x8530
+#define LOCAL_GL_DISCRETE_AMD 0x9006
+#define LOCAL_GL_DISJOINT_NV 0x9283
+#define LOCAL_GL_DISPATCH_INDIRECT_BUFFER 0x90EE
+#define LOCAL_GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF
+#define LOCAL_GL_DISPLAY_LIST 0x82E7
+#define LOCAL_GL_DISTANCE_ATTENUATION_EXT 0x8129
+#define LOCAL_GL_DISTANCE_ATTENUATION_SGIS 0x8129
+#define LOCAL_GL_DITHER 0x0BD0
+#define LOCAL_GL_DOMAIN 0x0A02
+#define LOCAL_GL_DONT_CARE 0x1100
+#define LOCAL_GL_DOT2_ADD_ATI 0x896C
+#define LOCAL_GL_DOT3_ATI 0x8966
+#define LOCAL_GL_DOT3_RGB 0x86AE
+#define LOCAL_GL_DOT3_RGBA 0x86AF
+#define LOCAL_GL_DOT3_RGBA_ARB 0x86AF
+#define LOCAL_GL_DOT3_RGBA_EXT 0x8741
+#define LOCAL_GL_DOT3_RGBA_IMG 0x86AF
+#define LOCAL_GL_DOT3_RGB_ARB 0x86AE
+#define LOCAL_GL_DOT3_RGB_EXT 0x8740
+#define LOCAL_GL_DOT4_ATI 0x8967
+#define LOCAL_GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D
+#define LOCAL_GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3
+#define LOCAL_GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED
+#define LOCAL_GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1
+#define LOCAL_GL_DOT_PRODUCT_NV 0x86EC
+#define LOCAL_GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B
+#define LOCAL_GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2
+#define LOCAL_GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C
+#define LOCAL_GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE
+#define LOCAL_GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF
+#define LOCAL_GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0
+#define LOCAL_GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E
+#define LOCAL_GL_DOUBLE 0x140A
+#define LOCAL_GL_DOUBLEBUFFER 0x0C32
+#define LOCAL_GL_DOUBLE_EXT 0x140A
+#define LOCAL_GL_DOUBLE_MAT2 0x8F46
+#define LOCAL_GL_DOUBLE_MAT2_EXT 0x8F46
+#define LOCAL_GL_DOUBLE_MAT2x3 0x8F49
+#define LOCAL_GL_DOUBLE_MAT2x3_EXT 0x8F49
+#define LOCAL_GL_DOUBLE_MAT2x4 0x8F4A
+#define LOCAL_GL_DOUBLE_MAT2x4_EXT 0x8F4A
+#define LOCAL_GL_DOUBLE_MAT3 0x8F47
+#define LOCAL_GL_DOUBLE_MAT3_EXT 0x8F47
+#define LOCAL_GL_DOUBLE_MAT3x2 0x8F4B
+#define LOCAL_GL_DOUBLE_MAT3x2_EXT 0x8F4B
+#define LOCAL_GL_DOUBLE_MAT3x4 0x8F4C
+#define LOCAL_GL_DOUBLE_MAT3x4_EXT 0x8F4C
+#define LOCAL_GL_DOUBLE_MAT4 0x8F48
+#define LOCAL_GL_DOUBLE_MAT4_EXT 0x8F48
+#define LOCAL_GL_DOUBLE_MAT4x2 0x8F4D
+#define LOCAL_GL_DOUBLE_MAT4x2_EXT 0x8F4D
+#define LOCAL_GL_DOUBLE_MAT4x3 0x8F4E
+#define LOCAL_GL_DOUBLE_MAT4x3_EXT 0x8F4E
+#define LOCAL_GL_DOUBLE_VEC2 0x8FFC
+#define LOCAL_GL_DOUBLE_VEC2_EXT 0x8FFC
+#define LOCAL_GL_DOUBLE_VEC3 0x8FFD
+#define LOCAL_GL_DOUBLE_VEC3_EXT 0x8FFD
+#define LOCAL_GL_DOUBLE_VEC4 0x8FFE
+#define LOCAL_GL_DOUBLE_VEC4_EXT 0x8FFE
+#define LOCAL_GL_DRAW_BUFFER 0x0C01
+#define LOCAL_GL_DRAW_BUFFER0 0x8825
+#define LOCAL_GL_DRAW_BUFFER0_ARB 0x8825
+#define LOCAL_GL_DRAW_BUFFER0_ATI 0x8825
+#define LOCAL_GL_DRAW_BUFFER0_EXT 0x8825
+#define LOCAL_GL_DRAW_BUFFER0_NV 0x8825
+#define LOCAL_GL_DRAW_BUFFER1 0x8826
+#define LOCAL_GL_DRAW_BUFFER10 0x882F
+#define LOCAL_GL_DRAW_BUFFER10_ARB 0x882F
+#define LOCAL_GL_DRAW_BUFFER10_ATI 0x882F
+#define LOCAL_GL_DRAW_BUFFER10_EXT 0x882F
+#define LOCAL_GL_DRAW_BUFFER10_NV 0x882F
+#define LOCAL_GL_DRAW_BUFFER11 0x8830
+#define LOCAL_GL_DRAW_BUFFER11_ARB 0x8830
+#define LOCAL_GL_DRAW_BUFFER11_ATI 0x8830
+#define LOCAL_GL_DRAW_BUFFER11_EXT 0x8830
+#define LOCAL_GL_DRAW_BUFFER11_NV 0x8830
+#define LOCAL_GL_DRAW_BUFFER12 0x8831
+#define LOCAL_GL_DRAW_BUFFER12_ARB 0x8831
+#define LOCAL_GL_DRAW_BUFFER12_ATI 0x8831
+#define LOCAL_GL_DRAW_BUFFER12_EXT 0x8831
+#define LOCAL_GL_DRAW_BUFFER12_NV 0x8831
+#define LOCAL_GL_DRAW_BUFFER13 0x8832
+#define LOCAL_GL_DRAW_BUFFER13_ARB 0x8832
+#define LOCAL_GL_DRAW_BUFFER13_ATI 0x8832
+#define LOCAL_GL_DRAW_BUFFER13_EXT 0x8832
+#define LOCAL_GL_DRAW_BUFFER13_NV 0x8832
+#define LOCAL_GL_DRAW_BUFFER14 0x8833
+#define LOCAL_GL_DRAW_BUFFER14_ARB 0x8833
+#define LOCAL_GL_DRAW_BUFFER14_ATI 0x8833
+#define LOCAL_GL_DRAW_BUFFER14_EXT 0x8833
+#define LOCAL_GL_DRAW_BUFFER14_NV 0x8833
+#define LOCAL_GL_DRAW_BUFFER15 0x8834
+#define LOCAL_GL_DRAW_BUFFER15_ARB 0x8834
+#define LOCAL_GL_DRAW_BUFFER15_ATI 0x8834
+#define LOCAL_GL_DRAW_BUFFER15_EXT 0x8834
+#define LOCAL_GL_DRAW_BUFFER15_NV 0x8834
+#define LOCAL_GL_DRAW_BUFFER1_ARB 0x8826
+#define LOCAL_GL_DRAW_BUFFER1_ATI 0x8826
+#define LOCAL_GL_DRAW_BUFFER1_EXT 0x8826
+#define LOCAL_GL_DRAW_BUFFER1_NV 0x8826
+#define LOCAL_GL_DRAW_BUFFER2 0x8827
+#define LOCAL_GL_DRAW_BUFFER2_ARB 0x8827
+#define LOCAL_GL_DRAW_BUFFER2_ATI 0x8827
+#define LOCAL_GL_DRAW_BUFFER2_EXT 0x8827
+#define LOCAL_GL_DRAW_BUFFER2_NV 0x8827
+#define LOCAL_GL_DRAW_BUFFER3 0x8828
+#define LOCAL_GL_DRAW_BUFFER3_ARB 0x8828
+#define LOCAL_GL_DRAW_BUFFER3_ATI 0x8828
+#define LOCAL_GL_DRAW_BUFFER3_EXT 0x8828
+#define LOCAL_GL_DRAW_BUFFER3_NV 0x8828
+#define LOCAL_GL_DRAW_BUFFER4 0x8829
+#define LOCAL_GL_DRAW_BUFFER4_ARB 0x8829
+#define LOCAL_GL_DRAW_BUFFER4_ATI 0x8829
+#define LOCAL_GL_DRAW_BUFFER4_EXT 0x8829
+#define LOCAL_GL_DRAW_BUFFER4_NV 0x8829
+#define LOCAL_GL_DRAW_BUFFER5 0x882A
+#define LOCAL_GL_DRAW_BUFFER5_ARB 0x882A
+#define LOCAL_GL_DRAW_BUFFER5_ATI 0x882A
+#define LOCAL_GL_DRAW_BUFFER5_EXT 0x882A
+#define LOCAL_GL_DRAW_BUFFER5_NV 0x882A
+#define LOCAL_GL_DRAW_BUFFER6 0x882B
+#define LOCAL_GL_DRAW_BUFFER6_ARB 0x882B
+#define LOCAL_GL_DRAW_BUFFER6_ATI 0x882B
+#define LOCAL_GL_DRAW_BUFFER6_EXT 0x882B
+#define LOCAL_GL_DRAW_BUFFER6_NV 0x882B
+#define LOCAL_GL_DRAW_BUFFER7 0x882C
+#define LOCAL_GL_DRAW_BUFFER7_ARB 0x882C
+#define LOCAL_GL_DRAW_BUFFER7_ATI 0x882C
+#define LOCAL_GL_DRAW_BUFFER7_EXT 0x882C
+#define LOCAL_GL_DRAW_BUFFER7_NV 0x882C
+#define LOCAL_GL_DRAW_BUFFER8 0x882D
+#define LOCAL_GL_DRAW_BUFFER8_ARB 0x882D
+#define LOCAL_GL_DRAW_BUFFER8_ATI 0x882D
+#define LOCAL_GL_DRAW_BUFFER8_EXT 0x882D
+#define LOCAL_GL_DRAW_BUFFER8_NV 0x882D
+#define LOCAL_GL_DRAW_BUFFER9 0x882E
+#define LOCAL_GL_DRAW_BUFFER9_ARB 0x882E
+#define LOCAL_GL_DRAW_BUFFER9_ATI 0x882E
+#define LOCAL_GL_DRAW_BUFFER9_EXT 0x882E
+#define LOCAL_GL_DRAW_BUFFER9_NV 0x882E
+#define LOCAL_GL_DRAW_BUFFER_EXT 0x0C01
+#define LOCAL_GL_DRAW_FRAMEBUFFER 0x8CA9
+#define LOCAL_GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9
+#define LOCAL_GL_DRAW_FRAMEBUFFER_APPLE 0x8CA9
+#define LOCAL_GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6
+#define LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6
+#define LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6
+#define LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6
+#define LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_NV 0x8CA6
+#define LOCAL_GL_DRAW_FRAMEBUFFER_EXT 0x8CA9
+#define LOCAL_GL_DRAW_FRAMEBUFFER_NV 0x8CA9
+#define LOCAL_GL_DRAW_INDIRECT_ADDRESS_NV 0x8F41
+#define LOCAL_GL_DRAW_INDIRECT_BUFFER 0x8F3F
+#define LOCAL_GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43
+#define LOCAL_GL_DRAW_INDIRECT_LENGTH_NV 0x8F42
+#define LOCAL_GL_DRAW_INDIRECT_UNIFIED_NV 0x8F40
+#define LOCAL_GL_DRAW_PIXELS_APPLE 0x8A0A
+#define LOCAL_GL_DRAW_PIXEL_TOKEN 0x0705
+#define LOCAL_GL_DSDT8_MAG8_INTENSITY8_NV 0x870B
+#define LOCAL_GL_DSDT8_MAG8_NV 0x870A
+#define LOCAL_GL_DSDT8_NV 0x8709
+#define LOCAL_GL_DSDT_MAG_INTENSITY_NV 0x86DC
+#define LOCAL_GL_DSDT_MAG_NV 0x86F6
+#define LOCAL_GL_DSDT_MAG_VIB_NV 0x86F7
+#define LOCAL_GL_DSDT_NV 0x86F5
+#define LOCAL_GL_DST_ALPHA 0x0304
+#define LOCAL_GL_DST_ATOP_NV 0x928F
+#define LOCAL_GL_DST_COLOR 0x0306
+#define LOCAL_GL_DST_IN_NV 0x928B
+#define LOCAL_GL_DST_NV 0x9287
+#define LOCAL_GL_DST_OUT_NV 0x928D
+#define LOCAL_GL_DST_OVER_NV 0x9289
+#define LOCAL_GL_DS_BIAS_NV 0x8716
+#define LOCAL_GL_DS_SCALE_NV 0x8710
+#define LOCAL_GL_DT_BIAS_NV 0x8717
+#define LOCAL_GL_DT_SCALE_NV 0x8711
+#define LOCAL_GL_DU8DV8_ATI 0x877A
+#define LOCAL_GL_DUAL_ALPHA12_SGIS 0x8112
+#define LOCAL_GL_DUAL_ALPHA16_SGIS 0x8113
+#define LOCAL_GL_DUAL_ALPHA4_SGIS 0x8110
+#define LOCAL_GL_DUAL_ALPHA8_SGIS 0x8111
+#define LOCAL_GL_DUAL_INTENSITY12_SGIS 0x811A
+#define LOCAL_GL_DUAL_INTENSITY16_SGIS 0x811B
+#define LOCAL_GL_DUAL_INTENSITY4_SGIS 0x8118
+#define LOCAL_GL_DUAL_INTENSITY8_SGIS 0x8119
+#define LOCAL_GL_DUAL_LUMINANCE12_SGIS 0x8116
+#define LOCAL_GL_DUAL_LUMINANCE16_SGIS 0x8117
+#define LOCAL_GL_DUAL_LUMINANCE4_SGIS 0x8114
+#define LOCAL_GL_DUAL_LUMINANCE8_SGIS 0x8115
+#define LOCAL_GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C
+#define LOCAL_GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D
+#define LOCAL_GL_DUAL_TEXTURE_SELECT_SGIS 0x8124
+#define LOCAL_GL_DUDV_ATI 0x8779
+#define LOCAL_GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2
+#define LOCAL_GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4
+#define LOCAL_GL_DYNAMIC_ATI 0x8761
+#define LOCAL_GL_DYNAMIC_COPY 0x88EA
+#define LOCAL_GL_DYNAMIC_COPY_ARB 0x88EA
+#define LOCAL_GL_DYNAMIC_DRAW 0x88E8
+#define LOCAL_GL_DYNAMIC_DRAW_ARB 0x88E8
+#define LOCAL_GL_DYNAMIC_READ 0x88E9
+#define LOCAL_GL_DYNAMIC_READ_ARB 0x88E9
+#define LOCAL_GL_DYNAMIC_STORAGE_BIT 0x0100
+#define LOCAL_GL_EDGEFLAG_BIT_PGI 0x00040000
+#define LOCAL_GL_EDGE_FLAG 0x0B43
+#define LOCAL_GL_EDGE_FLAG_ARRAY 0x8079
+#define LOCAL_GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26
+#define LOCAL_GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B
+#define LOCAL_GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B
+#define LOCAL_GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D
+#define LOCAL_GL_EDGE_FLAG_ARRAY_EXT 0x8079
+#define LOCAL_GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30
+#define LOCAL_GL_EDGE_FLAG_ARRAY_LIST_IBM 103075
+#define LOCAL_GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085
+#define LOCAL_GL_EDGE_FLAG_ARRAY_POINTER 0x8093
+#define LOCAL_GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093
+#define LOCAL_GL_EDGE_FLAG_ARRAY_STRIDE 0x808C
+#define LOCAL_GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C
+#define LOCAL_GL_EIGHTH_BIT_ATI 0x00000020
+#define LOCAL_GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29
+#define LOCAL_GL_ELEMENT_ARRAY_APPLE 0x8A0C
+#define LOCAL_GL_ELEMENT_ARRAY_ATI 0x8768
+#define LOCAL_GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002
+#define LOCAL_GL_ELEMENT_ARRAY_BARRIER_BIT_EXT 0x00000002
+#define LOCAL_GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define LOCAL_GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
+#define LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+#define LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895
+#define LOCAL_GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33
+#define LOCAL_GL_ELEMENT_ARRAY_POINTER_APPLE 0x8A0E
+#define LOCAL_GL_ELEMENT_ARRAY_POINTER_ATI 0x876A
+#define LOCAL_GL_ELEMENT_ARRAY_TYPE_APPLE 0x8A0D
+#define LOCAL_GL_ELEMENT_ARRAY_TYPE_ATI 0x8769
+#define LOCAL_GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F
+#define LOCAL_GL_EMBOSS_CONSTANT_NV 0x855E
+#define LOCAL_GL_EMBOSS_LIGHT_NV 0x855D
+#define LOCAL_GL_EMBOSS_MAP_NV 0x855F
+#define LOCAL_GL_EMISSION 0x1600
+#define LOCAL_GL_ENABLE_BIT 0x00002000
+#define LOCAL_GL_EQUAL 0x0202
+#define LOCAL_GL_EQUIV 0x1509
+#define LOCAL_GL_ETC1_RGB8_OES 0x8D64
+#define LOCAL_GL_ETC1_SRGB8_NV 0x88EE
+#define LOCAL_GL_EVAL_2D_NV 0x86C0
+#define LOCAL_GL_EVAL_BIT 0x00010000
+#define LOCAL_GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5
+#define LOCAL_GL_EVAL_TRIANGULAR_2D_NV 0x86C1
+#define LOCAL_GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6
+#define LOCAL_GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0
+#define LOCAL_GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1
+#define LOCAL_GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2
+#define LOCAL_GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3
+#define LOCAL_GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4
+#define LOCAL_GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5
+#define LOCAL_GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7
+#define LOCAL_GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8
+#define LOCAL_GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9
+#define LOCAL_GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA
+#define LOCAL_GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB
+#define LOCAL_GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC
+#define LOCAL_GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD
+#define LOCAL_GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE
+#define LOCAL_GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF
+#define LOCAL_GL_EXCLUSION_NV 0x92A0
+#define LOCAL_GL_EXP 0x0800
+#define LOCAL_GL_EXP2 0x0801
+#define LOCAL_GL_EXPAND_NEGATE_NV 0x8539
+#define LOCAL_GL_EXPAND_NORMAL_NV 0x8538
+#define LOCAL_GL_EXTENSIONS 0x1F03
+#define LOCAL_GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD 0x9160
+#define LOCAL_GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2
+#define LOCAL_GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0
+#define LOCAL_GL_EYE_LINEAR 0x2400
+#define LOCAL_GL_EYE_LINE_SGIS 0x81F6
+#define LOCAL_GL_EYE_PLANE 0x2502
+#define LOCAL_GL_EYE_PLANE_ABSOLUTE_NV 0x855C
+#define LOCAL_GL_EYE_POINT_SGIS 0x81F4
+#define LOCAL_GL_EYE_RADIAL_NV 0x855B
+#define LOCAL_GL_E_TIMES_F_NV 0x8531
+#define LOCAL_GL_FACTOR_ALPHA_MODULATE_IMG 0x8C07
+#define LOCAL_GL_FACTOR_MAX_AMD 0x901D
+#define LOCAL_GL_FACTOR_MIN_AMD 0x901C
+#define LOCAL_GL_FAILURE_NV 0x9030
+#define LOCAL_GL_FALSE 0
+#define LOCAL_GL_FASTEST 0x1101
+#define LOCAL_GL_FEEDBACK 0x1C01
+#define LOCAL_GL_FEEDBACK_BUFFER_POINTER 0x0DF0
+#define LOCAL_GL_FEEDBACK_BUFFER_SIZE 0x0DF1
+#define LOCAL_GL_FEEDBACK_BUFFER_TYPE 0x0DF2
+#define LOCAL_GL_FENCE_APPLE 0x8A0B
+#define LOCAL_GL_FENCE_CONDITION_NV 0x84F4
+#define LOCAL_GL_FENCE_STATUS_NV 0x84F3
+#define LOCAL_GL_FIELDS_NV 0x8E27
+#define LOCAL_GL_FIELD_LOWER_NV 0x9023
+#define LOCAL_GL_FIELD_UPPER_NV 0x9022
+#define LOCAL_GL_FILE_NAME_NV 0x9074
+#define LOCAL_GL_FILL 0x1B02
+#define LOCAL_GL_FILTER 0x829A
+#define LOCAL_GL_FILTER4_SGIS 0x8146
+#define LOCAL_GL_FIRST_TO_REST_NV 0x90AF
+#define LOCAL_GL_FIRST_VERTEX_CONVENTION 0x8E4D
+#define LOCAL_GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D
+#define LOCAL_GL_FIXED 0x140C
+#define LOCAL_GL_FIXED_OES 0x140C
+#define LOCAL_GL_FIXED_ONLY 0x891D
+#define LOCAL_GL_FIXED_ONLY_ARB 0x891D
+#define LOCAL_GL_FLAT 0x1D00
+#define LOCAL_GL_FLOAT 0x1406
+#define LOCAL_GL_FLOAT16_NV 0x8FF8
+#define LOCAL_GL_FLOAT16_VEC2_NV 0x8FF9
+#define LOCAL_GL_FLOAT16_VEC3_NV 0x8FFA
+#define LOCAL_GL_FLOAT16_VEC4_NV 0x8FFB
+#define LOCAL_GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD
+#define LOCAL_GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD
+#define LOCAL_GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D
+#define LOCAL_GL_FLOAT_MAT2 0x8B5A
+#define LOCAL_GL_FLOAT_MAT2_ARB 0x8B5A
+#define LOCAL_GL_FLOAT_MAT2x3 0x8B65
+#define LOCAL_GL_FLOAT_MAT2x3_NV 0x8B65
+#define LOCAL_GL_FLOAT_MAT2x4 0x8B66
+#define LOCAL_GL_FLOAT_MAT2x4_NV 0x8B66
+#define LOCAL_GL_FLOAT_MAT3 0x8B5B
+#define LOCAL_GL_FLOAT_MAT3_ARB 0x8B5B
+#define LOCAL_GL_FLOAT_MAT3x2 0x8B67
+#define LOCAL_GL_FLOAT_MAT3x2_NV 0x8B67
+#define LOCAL_GL_FLOAT_MAT3x4 0x8B68
+#define LOCAL_GL_FLOAT_MAT3x4_NV 0x8B68
+#define LOCAL_GL_FLOAT_MAT4 0x8B5C
+#define LOCAL_GL_FLOAT_MAT4_ARB 0x8B5C
+#define LOCAL_GL_FLOAT_MAT4x2 0x8B69
+#define LOCAL_GL_FLOAT_MAT4x2_NV 0x8B69
+#define LOCAL_GL_FLOAT_MAT4x3 0x8B6A
+#define LOCAL_GL_FLOAT_MAT4x3_NV 0x8B6A
+#define LOCAL_GL_FLOAT_R16_NV 0x8884
+#define LOCAL_GL_FLOAT_R32_NV 0x8885
+#define LOCAL_GL_FLOAT_RG16_NV 0x8886
+#define LOCAL_GL_FLOAT_RG32_NV 0x8887
+#define LOCAL_GL_FLOAT_RGB16_NV 0x8888
+#define LOCAL_GL_FLOAT_RGB32_NV 0x8889
+#define LOCAL_GL_FLOAT_RGBA16_NV 0x888A
+#define LOCAL_GL_FLOAT_RGBA32_NV 0x888B
+#define LOCAL_GL_FLOAT_RGBA_MODE_NV 0x888E
+#define LOCAL_GL_FLOAT_RGBA_NV 0x8883
+#define LOCAL_GL_FLOAT_RGB_NV 0x8882
+#define LOCAL_GL_FLOAT_RG_NV 0x8881
+#define LOCAL_GL_FLOAT_R_NV 0x8880
+#define LOCAL_GL_FLOAT_VEC2 0x8B50
+#define LOCAL_GL_FLOAT_VEC2_ARB 0x8B50
+#define LOCAL_GL_FLOAT_VEC3 0x8B51
+#define LOCAL_GL_FLOAT_VEC3_ARB 0x8B51
+#define LOCAL_GL_FLOAT_VEC4 0x8B52
+#define LOCAL_GL_FLOAT_VEC4_ARB 0x8B52
+#define LOCAL_GL_FOG 0x0B60
+#define LOCAL_GL_FOG_BIT 0x00000080
+#define LOCAL_GL_FOG_COLOR 0x0B66
+#define LOCAL_GL_FOG_COORD 0x8451
+#define LOCAL_GL_FOG_COORDINATE 0x8451
+#define LOCAL_GL_FOG_COORDINATE_ARRAY 0x8457
+#define LOCAL_GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D
+#define LOCAL_GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D
+#define LOCAL_GL_FOG_COORDINATE_ARRAY_EXT 0x8457
+#define LOCAL_GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076
+#define LOCAL_GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086
+#define LOCAL_GL_FOG_COORDINATE_ARRAY_POINTER 0x8456
+#define LOCAL_GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456
+#define LOCAL_GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455
+#define LOCAL_GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455
+#define LOCAL_GL_FOG_COORDINATE_ARRAY_TYPE 0x8454
+#define LOCAL_GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454
+#define LOCAL_GL_FOG_COORDINATE_EXT 0x8451
+#define LOCAL_GL_FOG_COORDINATE_SOURCE 0x8450
+#define LOCAL_GL_FOG_COORDINATE_SOURCE_EXT 0x8450
+#define LOCAL_GL_FOG_COORD_ARRAY 0x8457
+#define LOCAL_GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28
+#define LOCAL_GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D
+#define LOCAL_GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32
+#define LOCAL_GL_FOG_COORD_ARRAY_POINTER 0x8456
+#define LOCAL_GL_FOG_COORD_ARRAY_STRIDE 0x8455
+#define LOCAL_GL_FOG_COORD_ARRAY_TYPE 0x8454
+#define LOCAL_GL_FOG_COORD_SRC 0x8450
+#define LOCAL_GL_FOG_DENSITY 0x0B62
+#define LOCAL_GL_FOG_DISTANCE_MODE_NV 0x855A
+#define LOCAL_GL_FOG_END 0x0B64
+#define LOCAL_GL_FOG_FUNC_POINTS_SGIS 0x812B
+#define LOCAL_GL_FOG_FUNC_SGIS 0x812A
+#define LOCAL_GL_FOG_HINT 0x0C54
+#define LOCAL_GL_FOG_INDEX 0x0B61
+#define LOCAL_GL_FOG_MODE 0x0B65
+#define LOCAL_GL_FOG_OFFSET_SGIX 0x8198
+#define LOCAL_GL_FOG_OFFSET_VALUE_SGIX 0x8199
+#define LOCAL_GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC
+#define LOCAL_GL_FOG_START 0x0B63
+#define LOCAL_GL_FONT_ASCENDER_BIT_NV 0x00200000
+#define LOCAL_GL_FONT_DESCENDER_BIT_NV 0x00400000
+#define LOCAL_GL_FONT_HAS_KERNING_BIT_NV 0x10000000
+#define LOCAL_GL_FONT_HEIGHT_BIT_NV 0x00800000
+#define LOCAL_GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000
+#define LOCAL_GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000
+#define LOCAL_GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000
+#define LOCAL_GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000
+#define LOCAL_GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000
+#define LOCAL_GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000
+#define LOCAL_GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000
+#define LOCAL_GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000
+#define LOCAL_GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000
+#define LOCAL_GL_FORCE_BLUE_TO_ONE_NV 0x8860
+#define LOCAL_GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983
+#define LOCAL_GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982
+#define LOCAL_GL_FRACTIONAL_EVEN 0x8E7C
+#define LOCAL_GL_FRACTIONAL_ODD 0x8E7B
+#define LOCAL_GL_FRAGMENTS_INSTRUMENT_COUNTERS_SGIX 0x8314
+#define LOCAL_GL_FRAGMENTS_INSTRUMENT_MAX_SGIX 0x8315
+#define LOCAL_GL_FRAGMENTS_INSTRUMENT_SGIX 0x8313
+#define LOCAL_GL_FRAGMENT_ALPHA_MODULATE_IMG 0x8C08
+#define LOCAL_GL_FRAGMENT_COLOR_EXT 0x834C
+#define LOCAL_GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402
+#define LOCAL_GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403
+#define LOCAL_GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401
+#define LOCAL_GL_FRAGMENT_DEPTH 0x8452
+#define LOCAL_GL_FRAGMENT_DEPTH_EXT 0x8452
+#define LOCAL_GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D
+#define LOCAL_GL_FRAGMENT_LIGHT0_SGIX 0x840C
+#define LOCAL_GL_FRAGMENT_LIGHT1_SGIX 0x840D
+#define LOCAL_GL_FRAGMENT_LIGHT2_SGIX 0x840E
+#define LOCAL_GL_FRAGMENT_LIGHT3_SGIX 0x840F
+#define LOCAL_GL_FRAGMENT_LIGHT4_SGIX 0x8410
+#define LOCAL_GL_FRAGMENT_LIGHT5_SGIX 0x8411
+#define LOCAL_GL_FRAGMENT_LIGHT6_SGIX 0x8412
+#define LOCAL_GL_FRAGMENT_LIGHT7_SGIX 0x8413
+#define LOCAL_GL_FRAGMENT_LIGHTING_SGIX 0x8400
+#define LOCAL_GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A
+#define LOCAL_GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408
+#define LOCAL_GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B
+#define LOCAL_GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409
+#define LOCAL_GL_FRAGMENT_MATERIAL_EXT 0x8349
+#define LOCAL_GL_FRAGMENT_NORMAL_EXT 0x834A
+#define LOCAL_GL_FRAGMENT_PROGRAM_ARB 0x8804
+#define LOCAL_GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873
+#define LOCAL_GL_FRAGMENT_PROGRAM_CALLBACK_DATA_MESA 0x8BB3
+#define LOCAL_GL_FRAGMENT_PROGRAM_CALLBACK_FUNC_MESA 0x8BB2
+#define LOCAL_GL_FRAGMENT_PROGRAM_CALLBACK_MESA 0x8BB1
+#define LOCAL_GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV 0x8E5D
+#define LOCAL_GL_FRAGMENT_PROGRAM_NV 0x8870
+#define LOCAL_GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4
+#define LOCAL_GL_FRAGMENT_PROGRAM_POSITION_MESA 0x8BB0
+#define LOCAL_GL_FRAGMENT_SHADER 0x8B30
+#define LOCAL_GL_FRAGMENT_SHADER_ARB 0x8B30
+#define LOCAL_GL_FRAGMENT_SHADER_ATI 0x8920
+#define LOCAL_GL_FRAGMENT_SHADER_BIT 0x00000002
+#define LOCAL_GL_FRAGMENT_SHADER_BIT_EXT 0x00000002
+#define LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B
+#define LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B
+#define LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES 0x8B8B
+#define LOCAL_GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52
+#define LOCAL_GL_FRAGMENT_SUBROUTINE 0x92EC
+#define LOCAL_GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2
+#define LOCAL_GL_FRAGMENT_TEXTURE 0x829F
+#define LOCAL_GL_FRAMEBUFFER 0x8D40
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES 0x8CD1
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES 0x8CD0
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES 0x8CD3
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES 0x8CD2
+#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C
+#define LOCAL_GL_FRAMEBUFFER_BARRIER_BIT 0x00000400
+#define LOCAL_GL_FRAMEBUFFER_BARRIER_BIT_EXT 0x00000400
+#define LOCAL_GL_FRAMEBUFFER_BINDING 0x8CA6
+#define LOCAL_GL_FRAMEBUFFER_BINDING_ANGLE 0x8CA6
+#define LOCAL_GL_FRAMEBUFFER_BINDING_EXT 0x8CA6
+#define LOCAL_GL_FRAMEBUFFER_BINDING_OES 0x8CA6
+#define LOCAL_GL_FRAMEBUFFER_BLEND 0x828B
+#define LOCAL_GL_FRAMEBUFFER_COMPLETE 0x8CD5
+#define LOCAL_GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5
+#define LOCAL_GL_FRAMEBUFFER_COMPLETE_OES 0x8CD5
+#define LOCAL_GL_FRAMEBUFFER_DEFAULT 0x8218
+#define LOCAL_GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314
+#define LOCAL_GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311
+#define LOCAL_GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312
+#define LOCAL_GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313
+#define LOCAL_GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310
+#define LOCAL_GL_FRAMEBUFFER_EXT 0x8D40
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES 0x8CD6
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES 0x8CD9
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES 0x8CDB
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES 0x8CDA
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES 0x8CD7
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG 0x9134
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_NV 0x8D56
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC
+#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES 0x8CDC
+#define LOCAL_GL_FRAMEBUFFER_OES 0x8D40
+#define LOCAL_GL_FRAMEBUFFER_RENDERABLE 0x8289
+#define LOCAL_GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A
+#define LOCAL_GL_FRAMEBUFFER_SRGB 0x8DB9
+#define LOCAL_GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA
+#define LOCAL_GL_FRAMEBUFFER_SRGB_EXT 0x8DB9
+#define LOCAL_GL_FRAMEBUFFER_UNDEFINED 0x8219
+#define LOCAL_GL_FRAMEBUFFER_UNDEFINED_OES 0x8219
+#define LOCAL_GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
+#define LOCAL_GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD
+#define LOCAL_GL_FRAMEBUFFER_UNSUPPORTED_OES 0x8CDD
+#define LOCAL_GL_FRAMEZOOM_FACTOR_SGIX 0x818C
+#define LOCAL_GL_FRAMEZOOM_SGIX 0x818B
+#define LOCAL_GL_FRAME_NV 0x8E26
+#define LOCAL_GL_FRONT 0x0404
+#define LOCAL_GL_FRONT_AND_BACK 0x0408
+#define LOCAL_GL_FRONT_FACE 0x0B46
+#define LOCAL_GL_FRONT_LEFT 0x0400
+#define LOCAL_GL_FRONT_RIGHT 0x0401
+#define LOCAL_GL_FULL_RANGE_EXT 0x87E1
+#define LOCAL_GL_FULL_STIPPLE_HINT_PGI 0x1A219
+#define LOCAL_GL_FULL_SUPPORT 0x82B7
+#define LOCAL_GL_FUNC_ADD 0x8006
+#define LOCAL_GL_FUNC_ADD_EXT 0x8006
+#define LOCAL_GL_FUNC_ADD_OES 0x8006
+#define LOCAL_GL_FUNC_REVERSE_SUBTRACT 0x800B
+#define LOCAL_GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B
+#define LOCAL_GL_FUNC_REVERSE_SUBTRACT_OES 0x800B
+#define LOCAL_GL_FUNC_SUBTRACT 0x800A
+#define LOCAL_GL_FUNC_SUBTRACT_EXT 0x800A
+#define LOCAL_GL_FUNC_SUBTRACT_OES 0x800A
+#define LOCAL_GL_GCCSO_SHADER_BINARY_FJ 0x9260
+#define LOCAL_GL_GENERATE_MIPMAP 0x8191
+#define LOCAL_GL_GENERATE_MIPMAP_HINT 0x8192
+#define LOCAL_GL_GENERATE_MIPMAP_HINT_SGIS 0x8192
+#define LOCAL_GL_GENERATE_MIPMAP_SGIS 0x8191
+#define LOCAL_GL_GENERIC_ATTRIB_NV 0x8C7D
+#define LOCAL_GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002
+#define LOCAL_GL_GEOMETRY_DEFORMATION_SGIX 0x8194
+#define LOCAL_GL_GEOMETRY_INPUT_TYPE 0x8917
+#define LOCAL_GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB
+#define LOCAL_GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB
+#define LOCAL_GL_GEOMETRY_OUTPUT_TYPE 0x8918
+#define LOCAL_GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC
+#define LOCAL_GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC
+#define LOCAL_GL_GEOMETRY_PROGRAM_NV 0x8C26
+#define LOCAL_GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3
+#define LOCAL_GL_GEOMETRY_SHADER 0x8DD9
+#define LOCAL_GL_GEOMETRY_SHADER_ARB 0x8DD9
+#define LOCAL_GL_GEOMETRY_SHADER_BIT 0x00000004
+#define LOCAL_GL_GEOMETRY_SHADER_EXT 0x8DD9
+#define LOCAL_GL_GEOMETRY_SHADER_INVOCATIONS 0x887F
+#define LOCAL_GL_GEOMETRY_SUBROUTINE 0x92EB
+#define LOCAL_GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1
+#define LOCAL_GL_GEOMETRY_TEXTURE 0x829E
+#define LOCAL_GL_GEOMETRY_VERTICES_OUT 0x8916
+#define LOCAL_GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA
+#define LOCAL_GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA
+#define LOCAL_GL_GEQUAL 0x0206
+#define LOCAL_GL_GET_TEXTURE_IMAGE_FORMAT 0x8291
+#define LOCAL_GL_GET_TEXTURE_IMAGE_TYPE 0x8292
+#define LOCAL_GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA
+#define LOCAL_GL_GLOBAL_ALPHA_SUN 0x81D9
+#define LOCAL_GL_GLYPH_HAS_KERNING_BIT_NV 0x100
+#define LOCAL_GL_GLYPH_HEIGHT_BIT_NV 0x02
+#define LOCAL_GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10
+#define LOCAL_GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04
+#define LOCAL_GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08
+#define LOCAL_GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80
+#define LOCAL_GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20
+#define LOCAL_GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40
+#define LOCAL_GL_GLYPH_WIDTH_BIT_NV 0x01
+#define LOCAL_GL_GPU_ADDRESS_NV 0x8F34
+#define LOCAL_GL_GPU_DISJOINT_EXT 0x8FBB
+#define LOCAL_GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049
+#define LOCAL_GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047
+#define LOCAL_GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B
+#define LOCAL_GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A
+#define LOCAL_GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048
+#define LOCAL_GL_GPU_OPTIMIZED_QCOM 0x8FB2
+#define LOCAL_GL_GREATER 0x0204
+#define LOCAL_GL_GREEN 0x1904
+#define LOCAL_GL_GREEN_BIAS 0x0D19
+#define LOCAL_GL_GREEN_BITS 0x0D53
+#define LOCAL_GL_GREEN_BIT_ATI 0x00000002
+#define LOCAL_GL_GREEN_INTEGER 0x8D95
+#define LOCAL_GL_GREEN_INTEGER_EXT 0x8D95
+#define LOCAL_GL_GREEN_MAX_CLAMP_INGR 0x8565
+#define LOCAL_GL_GREEN_MIN_CLAMP_INGR 0x8561
+#define LOCAL_GL_GREEN_NV 0x1904
+#define LOCAL_GL_GREEN_SCALE 0x0D18
+#define LOCAL_GL_GUILTY_CONTEXT_RESET_ARB 0x8253
+#define LOCAL_GL_GUILTY_CONTEXT_RESET_EXT 0x8253
+#define LOCAL_GL_HALF_APPLE 0x140B
+#define LOCAL_GL_HALF_BIAS_NEGATE_NV 0x853B
+#define LOCAL_GL_HALF_BIAS_NORMAL_NV 0x853A
+#define LOCAL_GL_HALF_BIT_ATI 0x00000008
+#define LOCAL_GL_HALF_FLOAT 0x140B
+#define LOCAL_GL_HALF_FLOAT_ARB 0x140B
+#define LOCAL_GL_HALF_FLOAT_NV 0x140B
+#define LOCAL_GL_HALF_FLOAT_OES 0x8D61
+#define LOCAL_GL_HARDLIGHT_NV 0x929B
+#define LOCAL_GL_HARDMIX_NV 0x92A9
+#define LOCAL_GL_HIGH_FLOAT 0x8DF2
+#define LOCAL_GL_HIGH_INT 0x8DF5
+#define LOCAL_GL_HILO16_NV 0x86F8
+#define LOCAL_GL_HILO8_NV 0x885E
+#define LOCAL_GL_HILO_NV 0x86F4
+#define LOCAL_GL_HINT_BIT 0x00008000
+#define LOCAL_GL_HISTOGRAM 0x8024
+#define LOCAL_GL_HISTOGRAM_ALPHA_SIZE 0x802B
+#define LOCAL_GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B
+#define LOCAL_GL_HISTOGRAM_BLUE_SIZE 0x802A
+#define LOCAL_GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A
+#define LOCAL_GL_HISTOGRAM_EXT 0x8024
+#define LOCAL_GL_HISTOGRAM_FORMAT 0x8027
+#define LOCAL_GL_HISTOGRAM_FORMAT_EXT 0x8027
+#define LOCAL_GL_HISTOGRAM_GREEN_SIZE 0x8029
+#define LOCAL_GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029
+#define LOCAL_GL_HISTOGRAM_LUMINANCE_SIZE 0x802C
+#define LOCAL_GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C
+#define LOCAL_GL_HISTOGRAM_RED_SIZE 0x8028
+#define LOCAL_GL_HISTOGRAM_RED_SIZE_EXT 0x8028
+#define LOCAL_GL_HISTOGRAM_SINK 0x802D
+#define LOCAL_GL_HISTOGRAM_SINK_EXT 0x802D
+#define LOCAL_GL_HISTOGRAM_WIDTH 0x8026
+#define LOCAL_GL_HISTOGRAM_WIDTH_EXT 0x8026
+#define LOCAL_GL_HI_BIAS_NV 0x8714
+#define LOCAL_GL_HI_SCALE_NV 0x870E
+#define LOCAL_GL_HORIZONTAL_LINE_TO_NV 0x06
+#define LOCAL_GL_HSL_COLOR_NV 0x92AF
+#define LOCAL_GL_HSL_HUE_NV 0x92AD
+#define LOCAL_GL_HSL_LUMINOSITY_NV 0x92B0
+#define LOCAL_GL_HSL_SATURATION_NV 0x92AE
+#define LOCAL_GL_IDENTITY_NV 0x862A
+#define LOCAL_GL_IGNORE_BORDER_HP 0x8150
+#define LOCAL_GL_IMAGE_1D 0x904C
+#define LOCAL_GL_IMAGE_1D_ARRAY 0x9052
+#define LOCAL_GL_IMAGE_1D_ARRAY_EXT 0x9052
+#define LOCAL_GL_IMAGE_1D_EXT 0x904C
+#define LOCAL_GL_IMAGE_2D 0x904D
+#define LOCAL_GL_IMAGE_2D_ARRAY 0x9053
+#define LOCAL_GL_IMAGE_2D_ARRAY_EXT 0x9053
+#define LOCAL_GL_IMAGE_2D_EXT 0x904D
+#define LOCAL_GL_IMAGE_2D_MULTISAMPLE 0x9055
+#define LOCAL_GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056
+#define LOCAL_GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9056
+#define LOCAL_GL_IMAGE_2D_MULTISAMPLE_EXT 0x9055
+#define LOCAL_GL_IMAGE_2D_RECT 0x904F
+#define LOCAL_GL_IMAGE_2D_RECT_EXT 0x904F
+#define LOCAL_GL_IMAGE_3D 0x904E
+#define LOCAL_GL_IMAGE_3D_EXT 0x904E
+#define LOCAL_GL_IMAGE_BINDING_ACCESS 0x8F3E
+#define LOCAL_GL_IMAGE_BINDING_ACCESS_EXT 0x8F3E
+#define LOCAL_GL_IMAGE_BINDING_FORMAT 0x906E
+#define LOCAL_GL_IMAGE_BINDING_FORMAT_EXT 0x906E
+#define LOCAL_GL_IMAGE_BINDING_LAYER 0x8F3D
+#define LOCAL_GL_IMAGE_BINDING_LAYERED 0x8F3C
+#define LOCAL_GL_IMAGE_BINDING_LAYERED_EXT 0x8F3C
+#define LOCAL_GL_IMAGE_BINDING_LAYER_EXT 0x8F3D
+#define LOCAL_GL_IMAGE_BINDING_LEVEL 0x8F3B
+#define LOCAL_GL_IMAGE_BINDING_LEVEL_EXT 0x8F3B
+#define LOCAL_GL_IMAGE_BINDING_NAME 0x8F3A
+#define LOCAL_GL_IMAGE_BINDING_NAME_EXT 0x8F3A
+#define LOCAL_GL_IMAGE_BUFFER 0x9051
+#define LOCAL_GL_IMAGE_BUFFER_EXT 0x9051
+#define LOCAL_GL_IMAGE_CLASS_10_10_10_2 0x82C3
+#define LOCAL_GL_IMAGE_CLASS_11_11_10 0x82C2
+#define LOCAL_GL_IMAGE_CLASS_1_X_16 0x82BE
+#define LOCAL_GL_IMAGE_CLASS_1_X_32 0x82BB
+#define LOCAL_GL_IMAGE_CLASS_1_X_8 0x82C1
+#define LOCAL_GL_IMAGE_CLASS_2_X_16 0x82BD
+#define LOCAL_GL_IMAGE_CLASS_2_X_32 0x82BA
+#define LOCAL_GL_IMAGE_CLASS_2_X_8 0x82C0
+#define LOCAL_GL_IMAGE_CLASS_4_X_16 0x82BC
+#define LOCAL_GL_IMAGE_CLASS_4_X_32 0x82B9
+#define LOCAL_GL_IMAGE_CLASS_4_X_8 0x82BF
+#define LOCAL_GL_IMAGE_COMPATIBILITY_CLASS 0x82A8
+#define LOCAL_GL_IMAGE_CUBE 0x9050
+#define LOCAL_GL_IMAGE_CUBE_EXT 0x9050
+#define LOCAL_GL_IMAGE_CUBE_MAP_ARRAY 0x9054
+#define LOCAL_GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054
+#define LOCAL_GL_IMAGE_CUBIC_WEIGHT_HP 0x815E
+#define LOCAL_GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9
+#define LOCAL_GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8
+#define LOCAL_GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7
+#define LOCAL_GL_IMAGE_MAG_FILTER_HP 0x815C
+#define LOCAL_GL_IMAGE_MIN_FILTER_HP 0x815D
+#define LOCAL_GL_IMAGE_PIXEL_FORMAT 0x82A9
+#define LOCAL_GL_IMAGE_PIXEL_TYPE 0x82AA
+#define LOCAL_GL_IMAGE_ROTATE_ANGLE_HP 0x8159
+#define LOCAL_GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A
+#define LOCAL_GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B
+#define LOCAL_GL_IMAGE_SCALE_X_HP 0x8155
+#define LOCAL_GL_IMAGE_SCALE_Y_HP 0x8156
+#define LOCAL_GL_IMAGE_TEXEL_SIZE 0x82A7
+#define LOCAL_GL_IMAGE_TRANSFORM_2D_HP 0x8161
+#define LOCAL_GL_IMAGE_TRANSLATE_X_HP 0x8157
+#define LOCAL_GL_IMAGE_TRANSLATE_Y_HP 0x8158
+#define LOCAL_GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
+#define LOCAL_GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B
+#define LOCAL_GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
+#define LOCAL_GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A
+#define LOCAL_GL_INCR 0x1E02
+#define LOCAL_GL_INCR_WRAP 0x8507
+#define LOCAL_GL_INCR_WRAP_EXT 0x8507
+#define LOCAL_GL_INCR_WRAP_OES 0x8507
+#define LOCAL_GL_INDEX 0x8222
+#define LOCAL_GL_INDEX_ARRAY 0x8077
+#define LOCAL_GL_INDEX_ARRAY_ADDRESS_NV 0x8F24
+#define LOCAL_GL_INDEX_ARRAY_BUFFER_BINDING 0x8899
+#define LOCAL_GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899
+#define LOCAL_GL_INDEX_ARRAY_COUNT_EXT 0x8087
+#define LOCAL_GL_INDEX_ARRAY_EXT 0x8077
+#define LOCAL_GL_INDEX_ARRAY_LENGTH_NV 0x8F2E
+#define LOCAL_GL_INDEX_ARRAY_LIST_IBM 103073
+#define LOCAL_GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083
+#define LOCAL_GL_INDEX_ARRAY_POINTER 0x8091
+#define LOCAL_GL_INDEX_ARRAY_POINTER_EXT 0x8091
+#define LOCAL_GL_INDEX_ARRAY_STRIDE 0x8086
+#define LOCAL_GL_INDEX_ARRAY_STRIDE_EXT 0x8086
+#define LOCAL_GL_INDEX_ARRAY_TYPE 0x8085
+#define LOCAL_GL_INDEX_ARRAY_TYPE_EXT 0x8085
+#define LOCAL_GL_INDEX_BITS 0x0D51
+#define LOCAL_GL_INDEX_BIT_PGI 0x00080000
+#define LOCAL_GL_INDEX_CLEAR_VALUE 0x0C20
+#define LOCAL_GL_INDEX_LOGIC_OP 0x0BF1
+#define LOCAL_GL_INDEX_MATERIAL_EXT 0x81B8
+#define LOCAL_GL_INDEX_MATERIAL_FACE_EXT 0x81BA
+#define LOCAL_GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9
+#define LOCAL_GL_INDEX_MODE 0x0C30
+#define LOCAL_GL_INDEX_OFFSET 0x0D13
+#define LOCAL_GL_INDEX_SHIFT 0x0D12
+#define LOCAL_GL_INDEX_TEST_EXT 0x81B5
+#define LOCAL_GL_INDEX_TEST_FUNC_EXT 0x81B6
+#define LOCAL_GL_INDEX_TEST_REF_EXT 0x81B7
+#define LOCAL_GL_INDEX_WRITEMASK 0x0C21
+#define LOCAL_GL_INFO_LOG_LENGTH 0x8B84
+#define LOCAL_GL_INNOCENT_CONTEXT_RESET_ARB 0x8254
+#define LOCAL_GL_INNOCENT_CONTEXT_RESET_EXT 0x8254
+#define LOCAL_GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180
+#define LOCAL_GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181
+#define LOCAL_GL_INT 0x1404
+#define LOCAL_GL_INT16_NV 0x8FE4
+#define LOCAL_GL_INT16_VEC2_NV 0x8FE5
+#define LOCAL_GL_INT16_VEC3_NV 0x8FE6
+#define LOCAL_GL_INT16_VEC4_NV 0x8FE7
+#define LOCAL_GL_INT64_NV 0x140E
+#define LOCAL_GL_INT64_VEC2_NV 0x8FE9
+#define LOCAL_GL_INT64_VEC3_NV 0x8FEA
+#define LOCAL_GL_INT64_VEC4_NV 0x8FEB
+#define LOCAL_GL_INT8_NV 0x8FE0
+#define LOCAL_GL_INT8_VEC2_NV 0x8FE1
+#define LOCAL_GL_INT8_VEC3_NV 0x8FE2
+#define LOCAL_GL_INT8_VEC4_NV 0x8FE3
+#define LOCAL_GL_INTENSITY 0x8049
+#define LOCAL_GL_INTENSITY12 0x804C
+#define LOCAL_GL_INTENSITY12_EXT 0x804C
+#define LOCAL_GL_INTENSITY16 0x804D
+#define LOCAL_GL_INTENSITY16F_ARB 0x881D
+#define LOCAL_GL_INTENSITY16I_EXT 0x8D8B
+#define LOCAL_GL_INTENSITY16UI_EXT 0x8D79
+#define LOCAL_GL_INTENSITY16_EXT 0x804D
+#define LOCAL_GL_INTENSITY16_SNORM 0x901B
+#define LOCAL_GL_INTENSITY32F_ARB 0x8817
+#define LOCAL_GL_INTENSITY32I_EXT 0x8D85
+#define LOCAL_GL_INTENSITY32UI_EXT 0x8D73
+#define LOCAL_GL_INTENSITY4 0x804A
+#define LOCAL_GL_INTENSITY4_EXT 0x804A
+#define LOCAL_GL_INTENSITY8 0x804B
+#define LOCAL_GL_INTENSITY8I_EXT 0x8D91
+#define LOCAL_GL_INTENSITY8UI_EXT 0x8D7F
+#define LOCAL_GL_INTENSITY8_EXT 0x804B
+#define LOCAL_GL_INTENSITY8_SNORM 0x9017
+#define LOCAL_GL_INTENSITY_EXT 0x8049
+#define LOCAL_GL_INTENSITY_FLOAT16_APPLE 0x881D
+#define LOCAL_GL_INTENSITY_FLOAT16_ATI 0x881D
+#define LOCAL_GL_INTENSITY_FLOAT32_APPLE 0x8817
+#define LOCAL_GL_INTENSITY_FLOAT32_ATI 0x8817
+#define LOCAL_GL_INTENSITY_SNORM 0x9013
+#define LOCAL_GL_INTERLACE_OML 0x8980
+#define LOCAL_GL_INTERLACE_READ_INGR 0x8568
+#define LOCAL_GL_INTERLACE_READ_OML 0x8981
+#define LOCAL_GL_INTERLACE_SGIX 0x8094
+#define LOCAL_GL_INTERLEAVED_ATTRIBS 0x8C8C
+#define LOCAL_GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C
+#define LOCAL_GL_INTERLEAVED_ATTRIBS_NV 0x8C8C
+#define LOCAL_GL_INTERNALFORMAT_ALPHA_SIZE 0x8274
+#define LOCAL_GL_INTERNALFORMAT_ALPHA_TYPE 0x827B
+#define LOCAL_GL_INTERNALFORMAT_BLUE_SIZE 0x8273
+#define LOCAL_GL_INTERNALFORMAT_BLUE_TYPE 0x827A
+#define LOCAL_GL_INTERNALFORMAT_DEPTH_SIZE 0x8275
+#define LOCAL_GL_INTERNALFORMAT_DEPTH_TYPE 0x827C
+#define LOCAL_GL_INTERNALFORMAT_GREEN_SIZE 0x8272
+#define LOCAL_GL_INTERNALFORMAT_GREEN_TYPE 0x8279
+#define LOCAL_GL_INTERNALFORMAT_PREFERRED 0x8270
+#define LOCAL_GL_INTERNALFORMAT_RED_SIZE 0x8271
+#define LOCAL_GL_INTERNALFORMAT_RED_TYPE 0x8278
+#define LOCAL_GL_INTERNALFORMAT_SHARED_SIZE 0x8277
+#define LOCAL_GL_INTERNALFORMAT_STENCIL_SIZE 0x8276
+#define LOCAL_GL_INTERNALFORMAT_STENCIL_TYPE 0x827D
+#define LOCAL_GL_INTERNALFORMAT_SUPPORTED 0x826F
+#define LOCAL_GL_INTERPOLATE 0x8575
+#define LOCAL_GL_INTERPOLATE_ARB 0x8575
+#define LOCAL_GL_INTERPOLATE_EXT 0x8575
+#define LOCAL_GL_INT_10_10_10_2_OES 0x8DF7
+#define LOCAL_GL_INT_2_10_10_10_REV 0x8D9F
+#define LOCAL_GL_INT_IMAGE_1D 0x9057
+#define LOCAL_GL_INT_IMAGE_1D_ARRAY 0x905D
+#define LOCAL_GL_INT_IMAGE_1D_ARRAY_EXT 0x905D
+#define LOCAL_GL_INT_IMAGE_1D_EXT 0x9057
+#define LOCAL_GL_INT_IMAGE_2D 0x9058
+#define LOCAL_GL_INT_IMAGE_2D_ARRAY 0x905E
+#define LOCAL_GL_INT_IMAGE_2D_ARRAY_EXT 0x905E
+#define LOCAL_GL_INT_IMAGE_2D_EXT 0x9058
+#define LOCAL_GL_INT_IMAGE_2D_MULTISAMPLE 0x9060
+#define LOCAL_GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061
+#define LOCAL_GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9061
+#define LOCAL_GL_INT_IMAGE_2D_MULTISAMPLE_EXT 0x9060
+#define LOCAL_GL_INT_IMAGE_2D_RECT 0x905A
+#define LOCAL_GL_INT_IMAGE_2D_RECT_EXT 0x905A
+#define LOCAL_GL_INT_IMAGE_3D 0x9059
+#define LOCAL_GL_INT_IMAGE_3D_EXT 0x9059
+#define LOCAL_GL_INT_IMAGE_BUFFER 0x905C
+#define LOCAL_GL_INT_IMAGE_BUFFER_EXT 0x905C
+#define LOCAL_GL_INT_IMAGE_CUBE 0x905B
+#define LOCAL_GL_INT_IMAGE_CUBE_EXT 0x905B
+#define LOCAL_GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F
+#define LOCAL_GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F
+#define LOCAL_GL_INT_SAMPLER_1D 0x8DC9
+#define LOCAL_GL_INT_SAMPLER_1D_ARRAY 0x8DCE
+#define LOCAL_GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE
+#define LOCAL_GL_INT_SAMPLER_1D_EXT 0x8DC9
+#define LOCAL_GL_INT_SAMPLER_2D 0x8DCA
+#define LOCAL_GL_INT_SAMPLER_2D_ARRAY 0x8DCF
+#define LOCAL_GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF
+#define LOCAL_GL_INT_SAMPLER_2D_EXT 0x8DCA
+#define LOCAL_GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109
+#define LOCAL_GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C
+#define LOCAL_GL_INT_SAMPLER_2D_RECT 0x8DCD
+#define LOCAL_GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD
+#define LOCAL_GL_INT_SAMPLER_3D 0x8DCB
+#define LOCAL_GL_INT_SAMPLER_3D_EXT 0x8DCB
+#define LOCAL_GL_INT_SAMPLER_BUFFER 0x8DD0
+#define LOCAL_GL_INT_SAMPLER_BUFFER_AMD 0x9002
+#define LOCAL_GL_INT_SAMPLER_BUFFER_EXT 0x8DD0
+#define LOCAL_GL_INT_SAMPLER_CUBE 0x8DCC
+#define LOCAL_GL_INT_SAMPLER_CUBE_EXT 0x8DCC
+#define LOCAL_GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E
+#define LOCAL_GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E
+#define LOCAL_GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57
+#define LOCAL_GL_INT_VEC2 0x8B53
+#define LOCAL_GL_INT_VEC2_ARB 0x8B53
+#define LOCAL_GL_INT_VEC3 0x8B54
+#define LOCAL_GL_INT_VEC3_ARB 0x8B54
+#define LOCAL_GL_INT_VEC4 0x8B55
+#define LOCAL_GL_INT_VEC4_ARB 0x8B55
+#define LOCAL_GL_INVALID_ENUM 0x0500
+#define LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
+#define LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506
+#define LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION_OES 0x0506
+#define LOCAL_GL_INVALID_INDEX 0xFFFFFFFF
+#define LOCAL_GL_INVALID_OPERATION 0x0502
+#define LOCAL_GL_INVALID_VALUE 0x0501
+#define LOCAL_GL_INVARIANT_DATATYPE_EXT 0x87EB
+#define LOCAL_GL_INVARIANT_EXT 0x87C2
+#define LOCAL_GL_INVARIANT_VALUE_EXT 0x87EA
+#define LOCAL_GL_INVERSE_NV 0x862B
+#define LOCAL_GL_INVERSE_TRANSPOSE_NV 0x862D
+#define LOCAL_GL_INVERT 0x150A
+#define LOCAL_GL_INVERTED_SCREEN_W_REND 0x8491
+#define LOCAL_GL_INVERT_OVG_NV 0x92B4
+#define LOCAL_GL_INVERT_RGB_NV 0x92A3
+#define LOCAL_GL_IR_INSTRUMENT1_SGIX 0x817F
+#define LOCAL_GL_ISOLINES 0x8E7A
+#define LOCAL_GL_IS_PER_PATCH 0x92E7
+#define LOCAL_GL_IS_ROW_MAJOR 0x9300
+#define LOCAL_GL_ITALIC_BIT_NV 0x02
+#define LOCAL_GL_IUI_N3F_V2F_EXT 0x81AF
+#define LOCAL_GL_IUI_N3F_V3F_EXT 0x81B0
+#define LOCAL_GL_IUI_V2F_EXT 0x81AD
+#define LOCAL_GL_IUI_V3F_EXT 0x81AE
+#define LOCAL_GL_KEEP 0x1E00
+#define LOCAL_GL_LARGE_CCW_ARC_TO_NV 0x16
+#define LOCAL_GL_LARGE_CW_ARC_TO_NV 0x18
+#define LOCAL_GL_LAST_VERTEX_CONVENTION 0x8E4E
+#define LOCAL_GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E
+#define LOCAL_GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027
+#define LOCAL_GL_LAYER_NV 0x8DAA
+#define LOCAL_GL_LAYER_PROVOKING_VERTEX 0x825E
+#define LOCAL_GL_LAYOUT_DEFAULT_INTEL 0
+#define LOCAL_GL_LAYOUT_LINEAR_CPU_CACHED_INTEL 2
+#define LOCAL_GL_LAYOUT_LINEAR_INTEL 1
+#define LOCAL_GL_LEFT 0x0406
+#define LOCAL_GL_LEQUAL 0x0203
+#define LOCAL_GL_LERP_ATI 0x8969
+#define LOCAL_GL_LESS 0x0201
+#define LOCAL_GL_LIGHT0 0x4000
+#define LOCAL_GL_LIGHT1 0x4001
+#define LOCAL_GL_LIGHT2 0x4002
+#define LOCAL_GL_LIGHT3 0x4003
+#define LOCAL_GL_LIGHT4 0x4004
+#define LOCAL_GL_LIGHT5 0x4005
+#define LOCAL_GL_LIGHT6 0x4006
+#define LOCAL_GL_LIGHT7 0x4007
+#define LOCAL_GL_LIGHTEN_NV 0x9298
+#define LOCAL_GL_LIGHTING 0x0B50
+#define LOCAL_GL_LIGHTING_BIT 0x00000040
+#define LOCAL_GL_LIGHT_ENV_MODE_SGIX 0x8407
+#define LOCAL_GL_LIGHT_MODEL_AMBIENT 0x0B53
+#define LOCAL_GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
+#define LOCAL_GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8
+#define LOCAL_GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
+#define LOCAL_GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0
+#define LOCAL_GL_LIGHT_MODEL_TWO_SIDE 0x0B52
+#define LOCAL_GL_LINE 0x1B01
+#define LOCAL_GL_LINEAR 0x2601
+#define LOCAL_GL_LINEARBURN_NV 0x92A5
+#define LOCAL_GL_LINEARDODGE_NV 0x92A4
+#define LOCAL_GL_LINEARLIGHT_NV 0x92A7
+#define LOCAL_GL_LINEAR_ATTENUATION 0x1208
+#define LOCAL_GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170
+#define LOCAL_GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F
+#define LOCAL_GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098
+#define LOCAL_GL_LINEAR_DETAIL_COLOR_SGIS 0x8099
+#define LOCAL_GL_LINEAR_DETAIL_SGIS 0x8097
+#define LOCAL_GL_LINEAR_MIPMAP_LINEAR 0x2703
+#define LOCAL_GL_LINEAR_MIPMAP_NEAREST 0x2701
+#define LOCAL_GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE
+#define LOCAL_GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF
+#define LOCAL_GL_LINEAR_SHARPEN_SGIS 0x80AD
+#define LOCAL_GL_LINES 0x0001
+#define LOCAL_GL_LINES_ADJACENCY 0x000A
+#define LOCAL_GL_LINES_ADJACENCY_ARB 0x000A
+#define LOCAL_GL_LINES_ADJACENCY_EXT 0x000A
+#define LOCAL_GL_LINE_BIT 0x00000004
+#define LOCAL_GL_LINE_LOOP 0x0002
+#define LOCAL_GL_LINE_QUALITY_HINT_SGIX 0x835B
+#define LOCAL_GL_LINE_RESET_TOKEN 0x0707
+#define LOCAL_GL_LINE_SMOOTH 0x0B20
+#define LOCAL_GL_LINE_SMOOTH_HINT 0x0C52
+#define LOCAL_GL_LINE_STIPPLE 0x0B24
+#define LOCAL_GL_LINE_STIPPLE_PATTERN 0x0B25
+#define LOCAL_GL_LINE_STIPPLE_REPEAT 0x0B26
+#define LOCAL_GL_LINE_STRIP 0x0003
+#define LOCAL_GL_LINE_STRIP_ADJACENCY 0x000B
+#define LOCAL_GL_LINE_STRIP_ADJACENCY_ARB 0x000B
+#define LOCAL_GL_LINE_STRIP_ADJACENCY_EXT 0x000B
+#define LOCAL_GL_LINE_TOKEN 0x0702
+#define LOCAL_GL_LINE_TO_NV 0x04
+#define LOCAL_GL_LINE_WIDTH 0x0B21
+#define LOCAL_GL_LINE_WIDTH_GRANULARITY 0x0B23
+#define LOCAL_GL_LINE_WIDTH_RANGE 0x0B22
+#define LOCAL_GL_LINK_STATUS 0x8B82
+#define LOCAL_GL_LIST_BASE 0x0B32
+#define LOCAL_GL_LIST_BIT 0x00020000
+#define LOCAL_GL_LIST_INDEX 0x0B33
+#define LOCAL_GL_LIST_MODE 0x0B30
+#define LOCAL_GL_LIST_PRIORITY_SGIX 0x8182
+#define LOCAL_GL_LOAD 0x0101
+#define LOCAL_GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED
+#define LOCAL_GL_LOCAL_CONSTANT_EXT 0x87C3
+#define LOCAL_GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC
+#define LOCAL_GL_LOCAL_EXT 0x87C4
+#define LOCAL_GL_LOCATION 0x930E
+#define LOCAL_GL_LOCATION_COMPONENT 0x934A
+#define LOCAL_GL_LOCATION_INDEX 0x930F
+#define LOCAL_GL_LOGIC_OP 0x0BF1
+#define LOCAL_GL_LOGIC_OP_MODE 0x0BF0
+#define LOCAL_GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
+#define LOCAL_GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252
+#define LOCAL_GL_LOWER_LEFT 0x8CA1
+#define LOCAL_GL_LOW_FLOAT 0x8DF0
+#define LOCAL_GL_LOW_INT 0x8DF3
+#define LOCAL_GL_LO_BIAS_NV 0x8715
+#define LOCAL_GL_LO_SCALE_NV 0x870F
+#define LOCAL_GL_LUMINANCE 0x1909
+#define LOCAL_GL_LUMINANCE12 0x8041
+#define LOCAL_GL_LUMINANCE12_ALPHA12 0x8047
+#define LOCAL_GL_LUMINANCE12_ALPHA12_EXT 0x8047
+#define LOCAL_GL_LUMINANCE12_ALPHA4 0x8046
+#define LOCAL_GL_LUMINANCE12_ALPHA4_EXT 0x8046
+#define LOCAL_GL_LUMINANCE12_EXT 0x8041
+#define LOCAL_GL_LUMINANCE16 0x8042
+#define LOCAL_GL_LUMINANCE16F_ARB 0x881E
+#define LOCAL_GL_LUMINANCE16F_EXT 0x881E
+#define LOCAL_GL_LUMINANCE16I_EXT 0x8D8C
+#define LOCAL_GL_LUMINANCE16UI_EXT 0x8D7A
+#define LOCAL_GL_LUMINANCE16_ALPHA16 0x8048
+#define LOCAL_GL_LUMINANCE16_ALPHA16_EXT 0x8048
+#define LOCAL_GL_LUMINANCE16_ALPHA16_SNORM 0x901A
+#define LOCAL_GL_LUMINANCE16_EXT 0x8042
+#define LOCAL_GL_LUMINANCE16_SNORM 0x9019
+#define LOCAL_GL_LUMINANCE32F_ARB 0x8818
+#define LOCAL_GL_LUMINANCE32F_EXT 0x8818
+#define LOCAL_GL_LUMINANCE32I_EXT 0x8D86
+#define LOCAL_GL_LUMINANCE32UI_EXT 0x8D74
+#define LOCAL_GL_LUMINANCE4 0x803F
+#define LOCAL_GL_LUMINANCE4_ALPHA4 0x8043
+#define LOCAL_GL_LUMINANCE4_ALPHA4_EXT 0x8043
+#define LOCAL_GL_LUMINANCE4_ALPHA4_OES 0x8043
+#define LOCAL_GL_LUMINANCE4_EXT 0x803F
+#define LOCAL_GL_LUMINANCE6_ALPHA2 0x8044
+#define LOCAL_GL_LUMINANCE6_ALPHA2_EXT 0x8044
+#define LOCAL_GL_LUMINANCE8 0x8040
+#define LOCAL_GL_LUMINANCE8I_EXT 0x8D92
+#define LOCAL_GL_LUMINANCE8UI_EXT 0x8D80
+#define LOCAL_GL_LUMINANCE8_ALPHA8 0x8045
+#define LOCAL_GL_LUMINANCE8_ALPHA8_EXT 0x8045
+#define LOCAL_GL_LUMINANCE8_ALPHA8_OES 0x8045
+#define LOCAL_GL_LUMINANCE8_ALPHA8_SNORM 0x9016
+#define LOCAL_GL_LUMINANCE8_EXT 0x8040
+#define LOCAL_GL_LUMINANCE8_OES 0x8040
+#define LOCAL_GL_LUMINANCE8_SNORM 0x9015
+#define LOCAL_GL_LUMINANCE_ALPHA 0x190A
+#define LOCAL_GL_LUMINANCE_ALPHA16F_ARB 0x881F
+#define LOCAL_GL_LUMINANCE_ALPHA16F_EXT 0x881F
+#define LOCAL_GL_LUMINANCE_ALPHA16I_EXT 0x8D8D
+#define LOCAL_GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B
+#define LOCAL_GL_LUMINANCE_ALPHA32F_ARB 0x8819
+#define LOCAL_GL_LUMINANCE_ALPHA32F_EXT 0x8819
+#define LOCAL_GL_LUMINANCE_ALPHA32I_EXT 0x8D87
+#define LOCAL_GL_LUMINANCE_ALPHA32UI_EXT 0x8D75
+#define LOCAL_GL_LUMINANCE_ALPHA8I_EXT 0x8D93
+#define LOCAL_GL_LUMINANCE_ALPHA8UI_EXT 0x8D81
+#define LOCAL_GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F
+#define LOCAL_GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F
+#define LOCAL_GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819
+#define LOCAL_GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819
+#define LOCAL_GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D
+#define LOCAL_GL_LUMINANCE_ALPHA_SNORM 0x9012
+#define LOCAL_GL_LUMINANCE_FLOAT16_APPLE 0x881E
+#define LOCAL_GL_LUMINANCE_FLOAT16_ATI 0x881E
+#define LOCAL_GL_LUMINANCE_FLOAT32_APPLE 0x8818
+#define LOCAL_GL_LUMINANCE_FLOAT32_ATI 0x8818
+#define LOCAL_GL_LUMINANCE_INTEGER_EXT 0x8D9C
+#define LOCAL_GL_LUMINANCE_SNORM 0x9011
+#define LOCAL_GL_MAD_ATI 0x8968
+#define LOCAL_GL_MAGNITUDE_BIAS_NV 0x8718
+#define LOCAL_GL_MAGNITUDE_SCALE_NV 0x8712
+#define LOCAL_GL_MAJOR_VERSION 0x821B
+#define LOCAL_GL_MALI_PROGRAM_BINARY_ARM 0x8F61
+#define LOCAL_GL_MALI_SHADER_BINARY_ARM 0x8F60
+#define LOCAL_GL_MANUAL_GENERATE_MIPMAP 0x8294
+#define LOCAL_GL_MAP1_BINORMAL_EXT 0x8446
+#define LOCAL_GL_MAP1_COLOR_4 0x0D90
+#define LOCAL_GL_MAP1_GRID_DOMAIN 0x0DD0
+#define LOCAL_GL_MAP1_GRID_SEGMENTS 0x0DD1
+#define LOCAL_GL_MAP1_INDEX 0x0D91
+#define LOCAL_GL_MAP1_NORMAL 0x0D92
+#define LOCAL_GL_MAP1_TANGENT_EXT 0x8444
+#define LOCAL_GL_MAP1_TEXTURE_COORD_1 0x0D93
+#define LOCAL_GL_MAP1_TEXTURE_COORD_2 0x0D94
+#define LOCAL_GL_MAP1_TEXTURE_COORD_3 0x0D95
+#define LOCAL_GL_MAP1_TEXTURE_COORD_4 0x0D96
+#define LOCAL_GL_MAP1_VERTEX_3 0x0D97
+#define LOCAL_GL_MAP1_VERTEX_4 0x0D98
+#define LOCAL_GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660
+#define LOCAL_GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A
+#define LOCAL_GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B
+#define LOCAL_GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C
+#define LOCAL_GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D
+#define LOCAL_GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E
+#define LOCAL_GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F
+#define LOCAL_GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661
+#define LOCAL_GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662
+#define LOCAL_GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663
+#define LOCAL_GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664
+#define LOCAL_GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665
+#define LOCAL_GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666
+#define LOCAL_GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667
+#define LOCAL_GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668
+#define LOCAL_GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669
+#define LOCAL_GL_MAP2_BINORMAL_EXT 0x8447
+#define LOCAL_GL_MAP2_COLOR_4 0x0DB0
+#define LOCAL_GL_MAP2_GRID_DOMAIN 0x0DD2
+#define LOCAL_GL_MAP2_GRID_SEGMENTS 0x0DD3
+#define LOCAL_GL_MAP2_INDEX 0x0DB1
+#define LOCAL_GL_MAP2_NORMAL 0x0DB2
+#define LOCAL_GL_MAP2_TANGENT_EXT 0x8445
+#define LOCAL_GL_MAP2_TEXTURE_COORD_1 0x0DB3
+#define LOCAL_GL_MAP2_TEXTURE_COORD_2 0x0DB4
+#define LOCAL_GL_MAP2_TEXTURE_COORD_3 0x0DB5
+#define LOCAL_GL_MAP2_TEXTURE_COORD_4 0x0DB6
+#define LOCAL_GL_MAP2_VERTEX_3 0x0DB7
+#define LOCAL_GL_MAP2_VERTEX_4 0x0DB8
+#define LOCAL_GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670
+#define LOCAL_GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A
+#define LOCAL_GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B
+#define LOCAL_GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C
+#define LOCAL_GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D
+#define LOCAL_GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E
+#define LOCAL_GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F
+#define LOCAL_GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671
+#define LOCAL_GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672
+#define LOCAL_GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673
+#define LOCAL_GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674
+#define LOCAL_GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675
+#define LOCAL_GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676
+#define LOCAL_GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677
+#define LOCAL_GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678
+#define LOCAL_GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679
+#define LOCAL_GL_MAP_ATTRIB_U_ORDER_NV 0x86C3
+#define LOCAL_GL_MAP_ATTRIB_V_ORDER_NV 0x86C4
+#define LOCAL_GL_MAP_COHERENT_BIT 0x0080
+#define LOCAL_GL_MAP_COLOR 0x0D10
+#define LOCAL_GL_MAP_FLUSH_EXPLICIT_BIT 0x0010
+#define LOCAL_GL_MAP_FLUSH_EXPLICIT_BIT_EXT 0x0010
+#define LOCAL_GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
+#define LOCAL_GL_MAP_INVALIDATE_BUFFER_BIT_EXT 0x0008
+#define LOCAL_GL_MAP_INVALIDATE_RANGE_BIT 0x0004
+#define LOCAL_GL_MAP_INVALIDATE_RANGE_BIT_EXT 0x0004
+#define LOCAL_GL_MAP_PERSISTENT_BIT 0x0040
+#define LOCAL_GL_MAP_READ_BIT 0x0001
+#define LOCAL_GL_MAP_READ_BIT_EXT 0x0001
+#define LOCAL_GL_MAP_STENCIL 0x0D11
+#define LOCAL_GL_MAP_TESSELLATION_NV 0x86C2
+#define LOCAL_GL_MAP_UNSYNCHRONIZED_BIT 0x0020
+#define LOCAL_GL_MAP_UNSYNCHRONIZED_BIT_EXT 0x0020
+#define LOCAL_GL_MAP_WRITE_BIT 0x0002
+#define LOCAL_GL_MAP_WRITE_BIT_EXT 0x0002
+#define LOCAL_GL_MATERIAL_SIDE_HINT_PGI 0x1A22C
+#define LOCAL_GL_MATRIX0_ARB 0x88C0
+#define LOCAL_GL_MATRIX0_NV 0x8630
+#define LOCAL_GL_MATRIX10_ARB 0x88CA
+#define LOCAL_GL_MATRIX11_ARB 0x88CB
+#define LOCAL_GL_MATRIX12_ARB 0x88CC
+#define LOCAL_GL_MATRIX13_ARB 0x88CD
+#define LOCAL_GL_MATRIX14_ARB 0x88CE
+#define LOCAL_GL_MATRIX15_ARB 0x88CF
+#define LOCAL_GL_MATRIX16_ARB 0x88D0
+#define LOCAL_GL_MATRIX17_ARB 0x88D1
+#define LOCAL_GL_MATRIX18_ARB 0x88D2
+#define LOCAL_GL_MATRIX19_ARB 0x88D3
+#define LOCAL_GL_MATRIX1_ARB 0x88C1
+#define LOCAL_GL_MATRIX1_NV 0x8631
+#define LOCAL_GL_MATRIX20_ARB 0x88D4
+#define LOCAL_GL_MATRIX21_ARB 0x88D5
+#define LOCAL_GL_MATRIX22_ARB 0x88D6
+#define LOCAL_GL_MATRIX23_ARB 0x88D7
+#define LOCAL_GL_MATRIX24_ARB 0x88D8
+#define LOCAL_GL_MATRIX25_ARB 0x88D9
+#define LOCAL_GL_MATRIX26_ARB 0x88DA
+#define LOCAL_GL_MATRIX27_ARB 0x88DB
+#define LOCAL_GL_MATRIX28_ARB 0x88DC
+#define LOCAL_GL_MATRIX29_ARB 0x88DD
+#define LOCAL_GL_MATRIX2_ARB 0x88C2
+#define LOCAL_GL_MATRIX2_NV 0x8632
+#define LOCAL_GL_MATRIX30_ARB 0x88DE
+#define LOCAL_GL_MATRIX31_ARB 0x88DF
+#define LOCAL_GL_MATRIX3_ARB 0x88C3
+#define LOCAL_GL_MATRIX3_NV 0x8633
+#define LOCAL_GL_MATRIX4_ARB 0x88C4
+#define LOCAL_GL_MATRIX4_NV 0x8634
+#define LOCAL_GL_MATRIX5_ARB 0x88C5
+#define LOCAL_GL_MATRIX5_NV 0x8635
+#define LOCAL_GL_MATRIX6_ARB 0x88C6
+#define LOCAL_GL_MATRIX6_NV 0x8636
+#define LOCAL_GL_MATRIX7_ARB 0x88C7
+#define LOCAL_GL_MATRIX7_NV 0x8637
+#define LOCAL_GL_MATRIX8_ARB 0x88C8
+#define LOCAL_GL_MATRIX9_ARB 0x88C9
+#define LOCAL_GL_MATRIX_EXT 0x87C0
+#define LOCAL_GL_MATRIX_INDEX_ARRAY_ARB 0x8844
+#define LOCAL_GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES 0x8B9E
+#define LOCAL_GL_MATRIX_INDEX_ARRAY_OES 0x8844
+#define LOCAL_GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849
+#define LOCAL_GL_MATRIX_INDEX_ARRAY_POINTER_OES 0x8849
+#define LOCAL_GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846
+#define LOCAL_GL_MATRIX_INDEX_ARRAY_SIZE_OES 0x8846
+#define LOCAL_GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848
+#define LOCAL_GL_MATRIX_INDEX_ARRAY_STRIDE_OES 0x8848
+#define LOCAL_GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847
+#define LOCAL_GL_MATRIX_INDEX_ARRAY_TYPE_OES 0x8847
+#define LOCAL_GL_MATRIX_MODE 0x0BA0
+#define LOCAL_GL_MATRIX_PALETTE_ARB 0x8840
+#define LOCAL_GL_MATRIX_PALETTE_OES 0x8840
+#define LOCAL_GL_MATRIX_STRIDE 0x92FF
+#define LOCAL_GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000
+#define LOCAL_GL_MAT_AMBIENT_BIT_PGI 0x00100000
+#define LOCAL_GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000
+#define LOCAL_GL_MAT_DIFFUSE_BIT_PGI 0x00400000
+#define LOCAL_GL_MAT_EMISSION_BIT_PGI 0x00800000
+#define LOCAL_GL_MAT_SHININESS_BIT_PGI 0x02000000
+#define LOCAL_GL_MAT_SPECULAR_BIT_PGI 0x04000000
+#define LOCAL_GL_MAX 0x8008
+#define LOCAL_GL_MAX_3D_TEXTURE_SIZE 0x8073
+#define LOCAL_GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073
+#define LOCAL_GL_MAX_3D_TEXTURE_SIZE_OES 0x8073
+#define LOCAL_GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138
+#define LOCAL_GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405
+#define LOCAL_GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF
+#define LOCAL_GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF
+#define LOCAL_GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360
+#define LOCAL_GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D
+#define LOCAL_GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361
+#define LOCAL_GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F
+#define LOCAL_GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC
+#define LOCAL_GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8
+#define LOCAL_GL_MAX_ATTRIB_STACK_DEPTH 0x0D35
+#define LOCAL_GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED
+#define LOCAL_GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B
+#define LOCAL_GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177
+#define LOCAL_GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178
+#define LOCAL_GL_MAX_CLIP_DISTANCES 0x0D32
+#define LOCAL_GL_MAX_CLIP_PLANES 0x0D32
+#define LOCAL_GL_MAX_CLIP_PLANES_IMG 0x0D32
+#define LOCAL_GL_MAX_COLOR_ATTACHMENTS 0x8CDF
+#define LOCAL_GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF
+#define LOCAL_GL_MAX_COLOR_ATTACHMENTS_NV 0x8CDF
+#define LOCAL_GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3
+#define LOCAL_GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3
+#define LOCAL_GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E
+#define LOCAL_GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7
+#define LOCAL_GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1
+#define LOCAL_GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266
+#define LOCAL_GL_MAX_COMBINED_DIMENSIONS 0x8282
+#define LOCAL_GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33
+#define LOCAL_GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32
+#define LOCAL_GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF
+#define LOCAL_GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39
+#define LOCAL_GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39
+#define LOCAL_GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39
+#define LOCAL_GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC
+#define LOCAL_GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E
+#define LOCAL_GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F
+#define LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#define LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D
+#define LOCAL_GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E
+#define LOCAL_GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31
+#define LOCAL_GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265
+#define LOCAL_GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264
+#define LOCAL_GL_MAX_COMPUTE_FIXED_GROUP_INVOCATIONS_ARB 0x90EB
+#define LOCAL_GL_MAX_COMPUTE_FIXED_GROUP_SIZE_ARB 0x91BF
+#define LOCAL_GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD
+#define LOCAL_GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB
+#define LOCAL_GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262
+#define LOCAL_GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC
+#define LOCAL_GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB
+#define LOCAL_GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263
+#define LOCAL_GL_MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB 0x9344
+#define LOCAL_GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB 0x9345
+#define LOCAL_GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE
+#define LOCAL_GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB
+#define LOCAL_GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF
+#define LOCAL_GL_MAX_CONVOLUTION_HEIGHT 0x801B
+#define LOCAL_GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B
+#define LOCAL_GL_MAX_CONVOLUTION_WIDTH 0x801A
+#define LOCAL_GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A
+#define LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
+#define LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C
+#define LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C
+#define LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES 0x851C
+#define LOCAL_GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C
+#define LOCAL_GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR 0x826C
+#define LOCAL_GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144
+#define LOCAL_GL_MAX_DEBUG_LOGGED_MESSAGES_AMD 0x9144
+#define LOCAL_GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144
+#define LOCAL_GL_MAX_DEBUG_LOGGED_MESSAGES_KHR 0x9144
+#define LOCAL_GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143
+#define LOCAL_GL_MAX_DEBUG_MESSAGE_LENGTH_AMD 0x9143
+#define LOCAL_GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143
+#define LOCAL_GL_MAX_DEBUG_MESSAGE_LENGTH_KHR 0x9143
+#define LOCAL_GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV 0x90D1
+#define LOCAL_GL_MAX_DEEP_3D_TEXTURE_WIDTH_HEIGHT_NV 0x90D0
+#define LOCAL_GL_MAX_DEFORMATION_ORDER_SGIX 0x8197
+#define LOCAL_GL_MAX_DEPTH 0x8280
+#define LOCAL_GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F
+#define LOCAL_GL_MAX_DRAW_BUFFERS 0x8824
+#define LOCAL_GL_MAX_DRAW_BUFFERS_ARB 0x8824
+#define LOCAL_GL_MAX_DRAW_BUFFERS_ATI 0x8824
+#define LOCAL_GL_MAX_DRAW_BUFFERS_EXT 0x8824
+#define LOCAL_GL_MAX_DRAW_BUFFERS_NV 0x8824
+#define LOCAL_GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC
+#define LOCAL_GL_MAX_ELEMENTS_INDICES 0x80E9
+#define LOCAL_GL_MAX_ELEMENTS_INDICES_EXT 0x80E9
+#define LOCAL_GL_MAX_ELEMENTS_VERTICES 0x80E8
+#define LOCAL_GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8
+#define LOCAL_GL_MAX_ELEMENT_INDEX 0x8D6B
+#define LOCAL_GL_MAX_EVAL_ORDER 0x0D30
+#define LOCAL_GL_MAX_EXT 0x8008
+#define LOCAL_GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C
+#define LOCAL_GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6
+#define LOCAL_GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0
+#define LOCAL_GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3
+#define LOCAL_GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE
+#define LOCAL_GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125
+#define LOCAL_GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C
+#define LOCAL_GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5C
+#define LOCAL_GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404
+#define LOCAL_GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868
+#define LOCAL_GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA
+#define LOCAL_GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D
+#define LOCAL_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
+#define LOCAL_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49
+#define LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
+#define LOCAL_GL_MAX_FRAMEBUFFER_HEIGHT 0x9316
+#define LOCAL_GL_MAX_FRAMEBUFFER_LAYERS 0x9317
+#define LOCAL_GL_MAX_FRAMEBUFFER_SAMPLES 0x9318
+#define LOCAL_GL_MAX_FRAMEBUFFER_WIDTH 0x9315
+#define LOCAL_GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D
+#define LOCAL_GL_MAX_GENERAL_COMBINERS_NV 0x854D
+#define LOCAL_GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5
+#define LOCAL_GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF
+#define LOCAL_GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4
+#define LOCAL_GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD
+#define LOCAL_GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123
+#define LOCAL_GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124
+#define LOCAL_GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0
+#define LOCAL_GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0
+#define LOCAL_GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0
+#define LOCAL_GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV 0x8E5A
+#define LOCAL_GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A
+#define LOCAL_GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7
+#define LOCAL_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29
+#define LOCAL_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29
+#define LOCAL_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29
+#define LOCAL_GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1
+#define LOCAL_GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1
+#define LOCAL_GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1
+#define LOCAL_GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C
+#define LOCAL_GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF
+#define LOCAL_GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF
+#define LOCAL_GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF
+#define LOCAL_GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD
+#define LOCAL_GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD
+#define LOCAL_GL_MAX_HEIGHT 0x827F
+#define LOCAL_GL_MAX_IMAGE_SAMPLES 0x906D
+#define LOCAL_GL_MAX_IMAGE_SAMPLES_EXT 0x906D
+#define LOCAL_GL_MAX_IMAGE_UNITS 0x8F38
+#define LOCAL_GL_MAX_IMAGE_UNITS_EXT 0x8F38
+#define LOCAL_GL_MAX_INTEGER_SAMPLES 0x9110
+#define LOCAL_GL_MAX_LABEL_LENGTH 0x82E8
+#define LOCAL_GL_MAX_LABEL_LENGTH_KHR 0x82E8
+#define LOCAL_GL_MAX_LAYERS 0x8281
+#define LOCAL_GL_MAX_LIGHTS 0x0D31
+#define LOCAL_GL_MAX_LIST_NESTING 0x0B31
+#define LOCAL_GL_MAX_MAP_TESSELLATION_NV 0x86D6
+#define LOCAL_GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841
+#define LOCAL_GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36
+#define LOCAL_GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11
+#define LOCAL_GL_MAX_MULTIVIEW_BUFFERS_EXT 0x90F2
+#define LOCAL_GL_MAX_NAME_LENGTH 0x92F6
+#define LOCAL_GL_MAX_NAME_STACK_DEPTH 0x0D37
+#define LOCAL_GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7
+#define LOCAL_GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8
+#define LOCAL_GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA
+#define LOCAL_GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD
+#define LOCAL_GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE
+#define LOCAL_GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC
+#define LOCAL_GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB
+#define LOCAL_GL_MAX_PALETTE_MATRICES_ARB 0x8842
+#define LOCAL_GL_MAX_PALETTE_MATRICES_OES 0x8842
+#define LOCAL_GL_MAX_PATCH_VERTICES 0x8E7D
+#define LOCAL_GL_MAX_PIXEL_MAP_TABLE 0x0D34
+#define LOCAL_GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337
+#define LOCAL_GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1
+#define LOCAL_GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1
+#define LOCAL_GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B
+#define LOCAL_GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD
+#define LOCAL_GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908
+#define LOCAL_GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5
+#define LOCAL_GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5
+#define LOCAL_GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4
+#define LOCAL_GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5
+#define LOCAL_GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6
+#define LOCAL_GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6
+#define LOCAL_GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1
+#define LOCAL_GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4
+#define LOCAL_GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8
+#define LOCAL_GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7
+#define LOCAL_GL_MAX_PROGRAM_MATRICES_ARB 0x862F
+#define LOCAL_GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E
+#define LOCAL_GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3
+#define LOCAL_GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E
+#define LOCAL_GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF
+#define LOCAL_GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3
+#define LOCAL_GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB
+#define LOCAL_GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7
+#define LOCAL_GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810
+#define LOCAL_GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F
+#define LOCAL_GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27
+#define LOCAL_GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9
+#define LOCAL_GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0
+#define LOCAL_GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1
+#define LOCAL_GL_MAX_PROGRAM_PATCH_ATTRIBS_NV 0x86D8
+#define LOCAL_GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909
+#define LOCAL_GL_MAX_PROGRAM_SUBROUTINE_NUM_NV 0x8F45
+#define LOCAL_GL_MAX_PROGRAM_SUBROUTINE_PARAMETERS_NV 0x8F44
+#define LOCAL_GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5
+#define LOCAL_GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905
+#define LOCAL_GL_MAX_PROGRAM_TEXEL_OFFSET_EXT 0x8905
+#define LOCAL_GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905
+#define LOCAL_GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB 0x8F9F
+#define LOCAL_GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F
+#define LOCAL_GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F
+#define LOCAL_GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5F
+#define LOCAL_GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D
+#define LOCAL_GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C
+#define LOCAL_GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28
+#define LOCAL_GL_MAX_PROJECTION_STACK_DEPTH 0x0D38
+#define LOCAL_GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7
+#define LOCAL_GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8
+#define LOCAL_GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8
+#define LOCAL_GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8
+#define LOCAL_GL_MAX_RENDERBUFFER_SIZE 0x84E8
+#define LOCAL_GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8
+#define LOCAL_GL_MAX_RENDERBUFFER_SIZE_OES 0x84E8
+#define LOCAL_GL_MAX_SAMPLES 0x8D57
+#define LOCAL_GL_MAX_SAMPLES_ANGLE 0x8D57
+#define LOCAL_GL_MAX_SAMPLES_APPLE 0x8D57
+#define LOCAL_GL_MAX_SAMPLES_EXT 0x8D57
+#define LOCAL_GL_MAX_SAMPLES_IMG 0x9135
+#define LOCAL_GL_MAX_SAMPLES_NV 0x8D57
+#define LOCAL_GL_MAX_SAMPLE_MASK_WORDS 0x8E59
+#define LOCAL_GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59
+#define LOCAL_GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
+#define LOCAL_GL_MAX_SERVER_WAIT_TIMEOUT_APPLE 0x9111
+#define LOCAL_GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35
+#define LOCAL_GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE
+#define LOCAL_GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD
+#define LOCAL_GL_MAX_SHININESS_NV 0x8504
+#define LOCAL_GL_MAX_SPARSE_3D_TEXTURE_SIZE_AMD 0x9199
+#define LOCAL_GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB 0x9199
+#define LOCAL_GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS 0x919A
+#define LOCAL_GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB 0x919A
+#define LOCAL_GL_MAX_SPARSE_TEXTURE_SIZE_AMD 0x9198
+#define LOCAL_GL_MAX_SPARSE_TEXTURE_SIZE_ARB 0x9198
+#define LOCAL_GL_MAX_SPOT_EXPONENT_NV 0x8505
+#define LOCAL_GL_MAX_SUBROUTINES 0x8DE7
+#define LOCAL_GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8
+#define LOCAL_GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3
+#define LOCAL_GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD
+#define LOCAL_GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB
+#define LOCAL_GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C
+#define LOCAL_GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83
+#define LOCAL_GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8
+#define LOCAL_GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81
+#define LOCAL_GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85
+#define LOCAL_GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89
+#define LOCAL_GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F
+#define LOCAL_GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4
+#define LOCAL_GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE
+#define LOCAL_GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC
+#define LOCAL_GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D
+#define LOCAL_GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86
+#define LOCAL_GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9
+#define LOCAL_GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82
+#define LOCAL_GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A
+#define LOCAL_GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80
+#define LOCAL_GL_MAX_TESS_GEN_LEVEL 0x8E7E
+#define LOCAL_GL_MAX_TESS_PATCH_COMPONENTS 0x8E84
+#define LOCAL_GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B
+#define LOCAL_GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B
+#define LOCAL_GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B
+#define LOCAL_GL_MAX_TEXTURE_COORDS 0x8871
+#define LOCAL_GL_MAX_TEXTURE_COORDS_ARB 0x8871
+#define LOCAL_GL_MAX_TEXTURE_COORDS_NV 0x8871
+#define LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
+#define LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872
+#define LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872
+#define LOCAL_GL_MAX_TEXTURE_LOD_BIAS 0x84FD
+#define LOCAL_GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD
+#define LOCAL_GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
+#define LOCAL_GL_MAX_TEXTURE_SIZE 0x0D33
+#define LOCAL_GL_MAX_TEXTURE_STACK_DEPTH 0x0D39
+#define LOCAL_GL_MAX_TEXTURE_UNITS 0x84E2
+#define LOCAL_GL_MAX_TEXTURE_UNITS_ARB 0x84E2
+#define LOCAL_GL_MAX_TRACK_MATRICES_NV 0x862F
+#define LOCAL_GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E
+#define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70
+#define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A
+#define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A
+#define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV 0x8C8A
+#define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B
+#define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B
+#define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B
+#define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80
+#define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80
+#define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80
+#define LOCAL_GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
+#define LOCAL_GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F
+#define LOCAL_GL_MAX_UNIFORM_LOCATIONS 0x826E
+#define LOCAL_GL_MAX_VARYING_COMPONENTS 0x8B4B
+#define LOCAL_GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B
+#define LOCAL_GL_MAX_VARYING_FLOATS 0x8B4B
+#define LOCAL_GL_MAX_VARYING_FLOATS_ARB 0x8B4B
+#define LOCAL_GL_MAX_VARYING_VECTORS 0x8DFC
+#define LOCAL_GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520
+#define LOCAL_GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2
+#define LOCAL_GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC
+#define LOCAL_GL_MAX_VERTEX_ATTRIBS 0x8869
+#define LOCAL_GL_MAX_VERTEX_ATTRIBS_ARB 0x8869
+#define LOCAL_GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA
+#define LOCAL_GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9
+#define LOCAL_GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5
+#define LOCAL_GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2
+#define LOCAL_GL_MAX_VERTEX_HINT_PGI 0x1A22D
+#define LOCAL_GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA
+#define LOCAL_GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
+#define LOCAL_GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5
+#define LOCAL_GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7
+#define LOCAL_GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9
+#define LOCAL_GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8
+#define LOCAL_GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6
+#define LOCAL_GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6
+#define LOCAL_GL_MAX_VERTEX_STREAMS 0x8E71
+#define LOCAL_GL_MAX_VERTEX_STREAMS_ATI 0x876B
+#define LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
+#define LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C
+#define LOCAL_GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B
+#define LOCAL_GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A
+#define LOCAL_GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A
+#define LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
+#define LOCAL_GL_MAX_VERTEX_UNITS_ARB 0x86A4
+#define LOCAL_GL_MAX_VERTEX_UNITS_OES 0x86A4
+#define LOCAL_GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE
+#define LOCAL_GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE
+#define LOCAL_GL_MAX_VIEWPORTS 0x825B
+#define LOCAL_GL_MAX_VIEWPORT_DIMS 0x0D3A
+#define LOCAL_GL_MAX_WIDTH 0x827E
+#define LOCAL_GL_MEDIUM_FLOAT 0x8DF1
+#define LOCAL_GL_MEDIUM_INT 0x8DF4
+#define LOCAL_GL_MIN 0x8007
+#define LOCAL_GL_MINMAX 0x802E
+#define LOCAL_GL_MINMAX_EXT 0x802E
+#define LOCAL_GL_MINMAX_FORMAT 0x802F
+#define LOCAL_GL_MINMAX_FORMAT_EXT 0x802F
+#define LOCAL_GL_MINMAX_SINK 0x8030
+#define LOCAL_GL_MINMAX_SINK_EXT 0x8030
+#define LOCAL_GL_MINOR_VERSION 0x821C
+#define LOCAL_GL_MINUS_CLAMPED_NV 0x92B3
+#define LOCAL_GL_MINUS_NV 0x929F
+#define LOCAL_GL_MIN_EXT 0x8007
+#define LOCAL_GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B
+#define LOCAL_GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5B
+#define LOCAL_GL_MIN_LOD_WARNING_AMD 0x919C
+#define LOCAL_GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC
+#define LOCAL_GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904
+#define LOCAL_GL_MIN_PROGRAM_TEXEL_OFFSET_EXT 0x8904
+#define LOCAL_GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904
+#define LOCAL_GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E
+#define LOCAL_GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E
+#define LOCAL_GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5E
+#define LOCAL_GL_MIN_SAMPLE_SHADING_VALUE 0x8C37
+#define LOCAL_GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37
+#define LOCAL_GL_MIN_SPARSE_LEVEL_AMD 0x919B
+#define LOCAL_GL_MIN_SPARSE_LEVEL_ARB 0x919B
+#define LOCAL_GL_MIPMAP 0x8293
+#define LOCAL_GL_MIRRORED_REPEAT 0x8370
+#define LOCAL_GL_MIRRORED_REPEAT_ARB 0x8370
+#define LOCAL_GL_MIRRORED_REPEAT_IBM 0x8370
+#define LOCAL_GL_MIRRORED_REPEAT_OES 0x8370
+#define LOCAL_GL_MIRROR_CLAMP_ATI 0x8742
+#define LOCAL_GL_MIRROR_CLAMP_EXT 0x8742
+#define LOCAL_GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912
+#define LOCAL_GL_MIRROR_CLAMP_TO_EDGE 0x8743
+#define LOCAL_GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743
+#define LOCAL_GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743
+#define LOCAL_GL_MITER_REVERT_NV 0x90A7
+#define LOCAL_GL_MITER_TRUNCATE_NV 0x90A8
+#define LOCAL_GL_MODELVIEW 0x1700
+#define LOCAL_GL_MODELVIEW0_ARB 0x1700
+#define LOCAL_GL_MODELVIEW0_EXT 0x1700
+#define LOCAL_GL_MODELVIEW0_MATRIX_EXT 0x0BA6
+#define LOCAL_GL_MODELVIEW0_STACK_DEPTH_EXT 0x0BA3
+#define LOCAL_GL_MODELVIEW10_ARB 0x872A
+#define LOCAL_GL_MODELVIEW11_ARB 0x872B
+#define LOCAL_GL_MODELVIEW12_ARB 0x872C
+#define LOCAL_GL_MODELVIEW13_ARB 0x872D
+#define LOCAL_GL_MODELVIEW14_ARB 0x872E
+#define LOCAL_GL_MODELVIEW15_ARB 0x872F
+#define LOCAL_GL_MODELVIEW16_ARB 0x8730
+#define LOCAL_GL_MODELVIEW17_ARB 0x8731
+#define LOCAL_GL_MODELVIEW18_ARB 0x8732
+#define LOCAL_GL_MODELVIEW19_ARB 0x8733
+#define LOCAL_GL_MODELVIEW1_ARB 0x850A
+#define LOCAL_GL_MODELVIEW1_EXT 0x850A
+#define LOCAL_GL_MODELVIEW1_MATRIX_EXT 0x8506
+#define LOCAL_GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502
+#define LOCAL_GL_MODELVIEW20_ARB 0x8734
+#define LOCAL_GL_MODELVIEW21_ARB 0x8735
+#define LOCAL_GL_MODELVIEW22_ARB 0x8736
+#define LOCAL_GL_MODELVIEW23_ARB 0x8737
+#define LOCAL_GL_MODELVIEW24_ARB 0x8738
+#define LOCAL_GL_MODELVIEW25_ARB 0x8739
+#define LOCAL_GL_MODELVIEW26_ARB 0x873A
+#define LOCAL_GL_MODELVIEW27_ARB 0x873B
+#define LOCAL_GL_MODELVIEW28_ARB 0x873C
+#define LOCAL_GL_MODELVIEW29_ARB 0x873D
+#define LOCAL_GL_MODELVIEW2_ARB 0x8722
+#define LOCAL_GL_MODELVIEW30_ARB 0x873E
+#define LOCAL_GL_MODELVIEW31_ARB 0x873F
+#define LOCAL_GL_MODELVIEW3_ARB 0x8723
+#define LOCAL_GL_MODELVIEW4_ARB 0x8724
+#define LOCAL_GL_MODELVIEW5_ARB 0x8725
+#define LOCAL_GL_MODELVIEW6_ARB 0x8726
+#define LOCAL_GL_MODELVIEW7_ARB 0x8727
+#define LOCAL_GL_MODELVIEW8_ARB 0x8728
+#define LOCAL_GL_MODELVIEW9_ARB 0x8729
+#define LOCAL_GL_MODELVIEW_MATRIX 0x0BA6
+#define LOCAL_GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES 0x898D
+#define LOCAL_GL_MODELVIEW_PROJECTION_NV 0x8629
+#define LOCAL_GL_MODELVIEW_STACK_DEPTH 0x0BA3
+#define LOCAL_GL_MODULATE 0x2100
+#define LOCAL_GL_MODULATE_ADD_ATI 0x8744
+#define LOCAL_GL_MODULATE_COLOR_IMG 0x8C04
+#define LOCAL_GL_MODULATE_SIGNED_ADD_ATI 0x8745
+#define LOCAL_GL_MODULATE_SUBTRACT_ATI 0x8746
+#define LOCAL_GL_MOVE_TO_CONTINUES_NV 0x90B6
+#define LOCAL_GL_MOVE_TO_NV 0x02
+#define LOCAL_GL_MOVE_TO_RESETS_NV 0x90B5
+#define LOCAL_GL_MOV_ATI 0x8961
+#define LOCAL_GL_MULT 0x0103
+#define LOCAL_GL_MULTIPLY_NV 0x9294
+#define LOCAL_GL_MULTISAMPLE 0x809D
+#define LOCAL_GL_MULTISAMPLE_3DFX 0x86B2
+#define LOCAL_GL_MULTISAMPLE_ARB 0x809D
+#define LOCAL_GL_MULTISAMPLE_BIT 0x20000000
+#define LOCAL_GL_MULTISAMPLE_BIT_3DFX 0x20000000
+#define LOCAL_GL_MULTISAMPLE_BIT_ARB 0x20000000
+#define LOCAL_GL_MULTISAMPLE_BIT_EXT 0x20000000
+#define LOCAL_GL_MULTISAMPLE_BUFFER_BIT0_QCOM 0x01000000
+#define LOCAL_GL_MULTISAMPLE_BUFFER_BIT1_QCOM 0x02000000
+#define LOCAL_GL_MULTISAMPLE_BUFFER_BIT2_QCOM 0x04000000
+#define LOCAL_GL_MULTISAMPLE_BUFFER_BIT3_QCOM 0x08000000
+#define LOCAL_GL_MULTISAMPLE_BUFFER_BIT4_QCOM 0x10000000
+#define LOCAL_GL_MULTISAMPLE_BUFFER_BIT5_QCOM 0x20000000
+#define LOCAL_GL_MULTISAMPLE_BUFFER_BIT6_QCOM 0x40000000
+#define LOCAL_GL_MULTISAMPLE_BUFFER_BIT7_QCOM 0x80000000
+#define LOCAL_GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12
+#define LOCAL_GL_MULTISAMPLE_EXT 0x809D
+#define LOCAL_GL_MULTISAMPLE_FILTER_HINT_NV 0x8534
+#define LOCAL_GL_MULTISAMPLE_SGIS 0x809D
+#define LOCAL_GL_MULTIVIEW_EXT 0x90F1
+#define LOCAL_GL_MUL_ATI 0x8964
+#define LOCAL_GL_MVP_MATRIX_EXT 0x87E3
+#define LOCAL_GL_N3F_V3F 0x2A25
+#define LOCAL_GL_NAMED_STRING_LENGTH_ARB 0x8DE9
+#define LOCAL_GL_NAMED_STRING_TYPE_ARB 0x8DEA
+#define LOCAL_GL_NAME_LENGTH 0x92F9
+#define LOCAL_GL_NAME_STACK_DEPTH 0x0D70
+#define LOCAL_GL_NAND 0x150E
+#define LOCAL_GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203
+#define LOCAL_GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204
+#define LOCAL_GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202
+#define LOCAL_GL_NEAREST 0x2600
+#define LOCAL_GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E
+#define LOCAL_GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D
+#define LOCAL_GL_NEAREST_MIPMAP_LINEAR 0x2702
+#define LOCAL_GL_NEAREST_MIPMAP_NEAREST 0x2700
+#define LOCAL_GL_NEGATE_BIT_ATI 0x00000004
+#define LOCAL_GL_NEGATIVE_ONE_EXT 0x87DF
+#define LOCAL_GL_NEGATIVE_W_EXT 0x87DC
+#define LOCAL_GL_NEGATIVE_X_EXT 0x87D9
+#define LOCAL_GL_NEGATIVE_Y_EXT 0x87DA
+#define LOCAL_GL_NEGATIVE_Z_EXT 0x87DB
+#define LOCAL_GL_NEVER 0x0200
+#define LOCAL_GL_NEXT_BUFFER_NV -2
+#define LOCAL_GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025
+#define LOCAL_GL_NICEST 0x1102
+#define LOCAL_GL_NONE 0
+#define LOCAL_GL_NONE_OES 0
+#define LOCAL_GL_NOOP 0x1505
+#define LOCAL_GL_NOR 0x1508
+#define LOCAL_GL_NORMALIZE 0x0BA1
+#define LOCAL_GL_NORMALIZED_RANGE_EXT 0x87E0
+#define LOCAL_GL_NORMAL_ARRAY 0x8075
+#define LOCAL_GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22
+#define LOCAL_GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897
+#define LOCAL_GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897
+#define LOCAL_GL_NORMAL_ARRAY_COUNT_EXT 0x8080
+#define LOCAL_GL_NORMAL_ARRAY_EXT 0x8075
+#define LOCAL_GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C
+#define LOCAL_GL_NORMAL_ARRAY_LIST_IBM 103071
+#define LOCAL_GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081
+#define LOCAL_GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6
+#define LOCAL_GL_NORMAL_ARRAY_POINTER 0x808F
+#define LOCAL_GL_NORMAL_ARRAY_POINTER_EXT 0x808F
+#define LOCAL_GL_NORMAL_ARRAY_STRIDE 0x807F
+#define LOCAL_GL_NORMAL_ARRAY_STRIDE_EXT 0x807F
+#define LOCAL_GL_NORMAL_ARRAY_TYPE 0x807E
+#define LOCAL_GL_NORMAL_ARRAY_TYPE_EXT 0x807E
+#define LOCAL_GL_NORMAL_BIT_PGI 0x08000000
+#define LOCAL_GL_NORMAL_MAP 0x8511
+#define LOCAL_GL_NORMAL_MAP_ARB 0x8511
+#define LOCAL_GL_NORMAL_MAP_EXT 0x8511
+#define LOCAL_GL_NORMAL_MAP_NV 0x8511
+#define LOCAL_GL_NORMAL_MAP_OES 0x8511
+#define LOCAL_GL_NOTEQUAL 0x0205
+#define LOCAL_GL_NO_ERROR 0
+#define LOCAL_GL_NO_RESET_NOTIFICATION_ARB 0x8261
+#define LOCAL_GL_NO_RESET_NOTIFICATION_EXT 0x8261
+#define LOCAL_GL_NUM_ACTIVE_VARIABLES 0x9304
+#define LOCAL_GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A
+#define LOCAL_GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define LOCAL_GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2
+#define LOCAL_GL_NUM_EXTENSIONS 0x821D
+#define LOCAL_GL_NUM_FILL_STREAMS_NV 0x8E29
+#define LOCAL_GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F
+#define LOCAL_GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E
+#define LOCAL_GL_NUM_GENERAL_COMBINERS_NV 0x854E
+#define LOCAL_GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973
+#define LOCAL_GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971
+#define LOCAL_GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972
+#define LOCAL_GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974
+#define LOCAL_GL_NUM_PASSES_ATI 0x8970
+#define LOCAL_GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
+#define LOCAL_GL_NUM_PROGRAM_BINARY_FORMATS_OES 0x87FE
+#define LOCAL_GL_NUM_SAMPLE_COUNTS 0x9380
+#define LOCAL_GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
+#define LOCAL_GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9
+#define LOCAL_GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024
+#define LOCAL_GL_NUM_VIRTUAL_PAGE_SIZES_ARB 0x91A8
+#define LOCAL_GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89
+#define LOCAL_GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A
+#define LOCAL_GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86
+#define LOCAL_GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87
+#define LOCAL_GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85
+#define LOCAL_GL_OBJECT_BUFFER_SIZE_ATI 0x8764
+#define LOCAL_GL_OBJECT_BUFFER_USAGE_ATI 0x8765
+#define LOCAL_GL_OBJECT_COMPILE_STATUS_ARB 0x8B81
+#define LOCAL_GL_OBJECT_DELETE_STATUS_ARB 0x8B80
+#define LOCAL_GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3
+#define LOCAL_GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1
+#define LOCAL_GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84
+#define LOCAL_GL_OBJECT_LINEAR 0x2401
+#define LOCAL_GL_OBJECT_LINE_SGIS 0x81F7
+#define LOCAL_GL_OBJECT_LINK_STATUS_ARB 0x8B82
+#define LOCAL_GL_OBJECT_PLANE 0x2501
+#define LOCAL_GL_OBJECT_POINT_SGIS 0x81F5
+#define LOCAL_GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88
+#define LOCAL_GL_OBJECT_SUBTYPE_ARB 0x8B4F
+#define LOCAL_GL_OBJECT_TYPE 0x9112
+#define LOCAL_GL_OBJECT_TYPE_APPLE 0x9112
+#define LOCAL_GL_OBJECT_TYPE_ARB 0x8B4E
+#define LOCAL_GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83
+#define LOCAL_GL_OCCLUSION_QUERY_EVENT_MASK_AMD 0x874F
+#define LOCAL_GL_OCCLUSION_TEST_HP 0x8165
+#define LOCAL_GL_OCCLUSION_TEST_RESULT_HP 0x8166
+#define LOCAL_GL_OFFSET 0x92FC
+#define LOCAL_GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856
+#define LOCAL_GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857
+#define LOCAL_GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854
+#define LOCAL_GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855
+#define LOCAL_GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850
+#define LOCAL_GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851
+#define LOCAL_GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852
+#define LOCAL_GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853
+#define LOCAL_GL_OFFSET_TEXTURE_2D_BIAS_NV 0x86E3
+#define LOCAL_GL_OFFSET_TEXTURE_2D_MATRIX_NV 0x86E1
+#define LOCAL_GL_OFFSET_TEXTURE_2D_NV 0x86E8
+#define LOCAL_GL_OFFSET_TEXTURE_2D_SCALE_NV 0x86E2
+#define LOCAL_GL_OFFSET_TEXTURE_BIAS_NV 0x86E3
+#define LOCAL_GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1
+#define LOCAL_GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C
+#define LOCAL_GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D
+#define LOCAL_GL_OFFSET_TEXTURE_SCALE_NV 0x86E2
+#define LOCAL_GL_ONE 1
+#define LOCAL_GL_ONE_EXT 0x87DE
+#define LOCAL_GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#define LOCAL_GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004
+#define LOCAL_GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#define LOCAL_GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002
+#define LOCAL_GL_ONE_MINUS_DST_ALPHA 0x0305
+#define LOCAL_GL_ONE_MINUS_DST_COLOR 0x0307
+#define LOCAL_GL_ONE_MINUS_SRC1_ALPHA 0x88FB
+#define LOCAL_GL_ONE_MINUS_SRC1_COLOR 0x88FA
+#define LOCAL_GL_ONE_MINUS_SRC_ALPHA 0x0303
+#define LOCAL_GL_ONE_MINUS_SRC_COLOR 0x0301
+#define LOCAL_GL_OPERAND0_ALPHA 0x8598
+#define LOCAL_GL_OPERAND0_ALPHA_ARB 0x8598
+#define LOCAL_GL_OPERAND0_ALPHA_EXT 0x8598
+#define LOCAL_GL_OPERAND0_RGB 0x8590
+#define LOCAL_GL_OPERAND0_RGB_ARB 0x8590
+#define LOCAL_GL_OPERAND0_RGB_EXT 0x8590
+#define LOCAL_GL_OPERAND1_ALPHA 0x8599
+#define LOCAL_GL_OPERAND1_ALPHA_ARB 0x8599
+#define LOCAL_GL_OPERAND1_ALPHA_EXT 0x8599
+#define LOCAL_GL_OPERAND1_RGB 0x8591
+#define LOCAL_GL_OPERAND1_RGB_ARB 0x8591
+#define LOCAL_GL_OPERAND1_RGB_EXT 0x8591
+#define LOCAL_GL_OPERAND2_ALPHA 0x859A
+#define LOCAL_GL_OPERAND2_ALPHA_ARB 0x859A
+#define LOCAL_GL_OPERAND2_ALPHA_EXT 0x859A
+#define LOCAL_GL_OPERAND2_RGB 0x8592
+#define LOCAL_GL_OPERAND2_RGB_ARB 0x8592
+#define LOCAL_GL_OPERAND2_RGB_EXT 0x8592
+#define LOCAL_GL_OPERAND3_ALPHA_NV 0x859B
+#define LOCAL_GL_OPERAND3_RGB_NV 0x8593
+#define LOCAL_GL_OP_ADD_EXT 0x8787
+#define LOCAL_GL_OP_CLAMP_EXT 0x878E
+#define LOCAL_GL_OP_CROSS_PRODUCT_EXT 0x8797
+#define LOCAL_GL_OP_DOT3_EXT 0x8784
+#define LOCAL_GL_OP_DOT4_EXT 0x8785
+#define LOCAL_GL_OP_EXP_BASE_2_EXT 0x8791
+#define LOCAL_GL_OP_FLOOR_EXT 0x878F
+#define LOCAL_GL_OP_FRAC_EXT 0x8789
+#define LOCAL_GL_OP_INDEX_EXT 0x8782
+#define LOCAL_GL_OP_LOG_BASE_2_EXT 0x8792
+#define LOCAL_GL_OP_MADD_EXT 0x8788
+#define LOCAL_GL_OP_MAX_EXT 0x878A
+#define LOCAL_GL_OP_MIN_EXT 0x878B
+#define LOCAL_GL_OP_MOV_EXT 0x8799
+#define LOCAL_GL_OP_MULTIPLY_MATRIX_EXT 0x8798
+#define LOCAL_GL_OP_MUL_EXT 0x8786
+#define LOCAL_GL_OP_NEGATE_EXT 0x8783
+#define LOCAL_GL_OP_POWER_EXT 0x8793
+#define LOCAL_GL_OP_RECIP_EXT 0x8794
+#define LOCAL_GL_OP_RECIP_SQRT_EXT 0x8795
+#define LOCAL_GL_OP_ROUND_EXT 0x8790
+#define LOCAL_GL_OP_SET_GE_EXT 0x878C
+#define LOCAL_GL_OP_SET_LT_EXT 0x878D
+#define LOCAL_GL_OP_SUB_EXT 0x8796
+#define LOCAL_GL_OR 0x1507
+#define LOCAL_GL_ORDER 0x0A01
+#define LOCAL_GL_OR_INVERTED 0x150D
+#define LOCAL_GL_OR_REVERSE 0x150B
+#define LOCAL_GL_OUTPUT_COLOR0_EXT 0x879B
+#define LOCAL_GL_OUTPUT_COLOR1_EXT 0x879C
+#define LOCAL_GL_OUTPUT_FOG_EXT 0x87BD
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5
+#define LOCAL_GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6
+#define LOCAL_GL_OUTPUT_VERTEX_EXT 0x879A
+#define LOCAL_GL_OUT_OF_MEMORY 0x0505
+#define LOCAL_GL_OVERLAY_NV 0x9296
+#define LOCAL_GL_PACK_ALIGNMENT 0x0D05
+#define LOCAL_GL_PACK_CMYK_HINT_EXT 0x800E
+#define LOCAL_GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D
+#define LOCAL_GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C
+#define LOCAL_GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E
+#define LOCAL_GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B
+#define LOCAL_GL_PACK_COMPRESSED_SIZE_SGIX 0x831C
+#define LOCAL_GL_PACK_IMAGE_DEPTH_SGIS 0x8131
+#define LOCAL_GL_PACK_IMAGE_HEIGHT 0x806C
+#define LOCAL_GL_PACK_IMAGE_HEIGHT_EXT 0x806C
+#define LOCAL_GL_PACK_INVERT_MESA 0x8758
+#define LOCAL_GL_PACK_LSB_FIRST 0x0D01
+#define LOCAL_GL_PACK_MAX_COMPRESSED_SIZE_SGIX 0x831B
+#define LOCAL_GL_PACK_RESAMPLE_OML 0x8984
+#define LOCAL_GL_PACK_RESAMPLE_SGIX 0x842C
+#define LOCAL_GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4
+#define LOCAL_GL_PACK_ROW_BYTES_APPLE 0x8A15
+#define LOCAL_GL_PACK_ROW_LENGTH 0x0D02
+#define LOCAL_GL_PACK_SKIP_IMAGES 0x806B
+#define LOCAL_GL_PACK_SKIP_IMAGES_EXT 0x806B
+#define LOCAL_GL_PACK_SKIP_PIXELS 0x0D04
+#define LOCAL_GL_PACK_SKIP_ROWS 0x0D03
+#define LOCAL_GL_PACK_SKIP_VOLUMES_SGIS 0x8130
+#define LOCAL_GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0
+#define LOCAL_GL_PACK_SWAP_BYTES 0x0D00
+#define LOCAL_GL_PALETTE4_R5_G6_B5_OES 0x8B92
+#define LOCAL_GL_PALETTE4_RGB5_A1_OES 0x8B94
+#define LOCAL_GL_PALETTE4_RGB8_OES 0x8B90
+#define LOCAL_GL_PALETTE4_RGBA4_OES 0x8B93
+#define LOCAL_GL_PALETTE4_RGBA8_OES 0x8B91
+#define LOCAL_GL_PALETTE8_R5_G6_B5_OES 0x8B97
+#define LOCAL_GL_PALETTE8_RGB5_A1_OES 0x8B99
+#define LOCAL_GL_PALETTE8_RGB8_OES 0x8B95
+#define LOCAL_GL_PALETTE8_RGBA4_OES 0x8B98
+#define LOCAL_GL_PALETTE8_RGBA8_OES 0x8B96
+#define LOCAL_GL_PARALLEL_ARRAYS_INTEL 0x83F4
+#define LOCAL_GL_PARAMETER_BUFFER_ARB 0x80EE
+#define LOCAL_GL_PARAMETER_BUFFER_BINDING_ARB 0x80EF
+#define LOCAL_GL_PARTIAL_SUCCESS_NV 0x902E
+#define LOCAL_GL_PASS_THROUGH_NV 0x86E6
+#define LOCAL_GL_PASS_THROUGH_TOKEN 0x0700
+#define LOCAL_GL_PATCHES 0x000E
+#define LOCAL_GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73
+#define LOCAL_GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74
+#define LOCAL_GL_PATCH_VERTICES 0x8E72
+#define LOCAL_GL_PATH_CLIENT_LENGTH_NV 0x907F
+#define LOCAL_GL_PATH_COMMAND_COUNT_NV 0x909D
+#define LOCAL_GL_PATH_COMPUTED_LENGTH_NV 0x90A0
+#define LOCAL_GL_PATH_COORD_COUNT_NV 0x909E
+#define LOCAL_GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF
+#define LOCAL_GL_PATH_DASH_ARRAY_COUNT_NV 0x909F
+#define LOCAL_GL_PATH_DASH_CAPS_NV 0x907B
+#define LOCAL_GL_PATH_DASH_OFFSET_NV 0x907E
+#define LOCAL_GL_PATH_DASH_OFFSET_RESET_NV 0x90B4
+#define LOCAL_GL_PATH_END_CAPS_NV 0x9076
+#define LOCAL_GL_PATH_ERROR_POSITION_NV 0x90AB
+#define LOCAL_GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1
+#define LOCAL_GL_PATH_FILL_COVER_MODE_NV 0x9082
+#define LOCAL_GL_PATH_FILL_MASK_NV 0x9081
+#define LOCAL_GL_PATH_FILL_MODE_NV 0x9080
+#define LOCAL_GL_PATH_FOG_GEN_MODE_NV 0x90AC
+#define LOCAL_GL_PATH_FORMAT_PS_NV 0x9071
+#define LOCAL_GL_PATH_FORMAT_SVG_NV 0x9070
+#define LOCAL_GL_PATH_GEN_COEFF_NV 0x90B1
+#define LOCAL_GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2
+#define LOCAL_GL_PATH_GEN_COMPONENTS_NV 0x90B3
+#define LOCAL_GL_PATH_GEN_MODE_NV 0x90B0
+#define LOCAL_GL_PATH_INITIAL_DASH_CAP_NV 0x907C
+#define LOCAL_GL_PATH_INITIAL_END_CAP_NV 0x9077
+#define LOCAL_GL_PATH_JOIN_STYLE_NV 0x9079
+#define LOCAL_GL_PATH_MITER_LIMIT_NV 0x907A
+#define LOCAL_GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A
+#define LOCAL_GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD
+#define LOCAL_GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE
+#define LOCAL_GL_PATH_STENCIL_FUNC_NV 0x90B7
+#define LOCAL_GL_PATH_STENCIL_REF_NV 0x90B8
+#define LOCAL_GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9
+#define LOCAL_GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2
+#define LOCAL_GL_PATH_STROKE_COVER_MODE_NV 0x9083
+#define LOCAL_GL_PATH_STROKE_MASK_NV 0x9084
+#define LOCAL_GL_PATH_STROKE_WIDTH_NV 0x9075
+#define LOCAL_GL_PATH_TERMINAL_DASH_CAP_NV 0x907D
+#define LOCAL_GL_PATH_TERMINAL_END_CAP_NV 0x9078
+#define LOCAL_GL_PERCENTAGE_AMD 0x8BC3
+#define LOCAL_GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0
+#define LOCAL_GL_PERFMON_RESULT_AMD 0x8BC6
+#define LOCAL_GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4
+#define LOCAL_GL_PERFMON_RESULT_SIZE_AMD 0x8BC5
+#define LOCAL_GL_PERFORMANCE_MONITOR_AMD 0x9152
+#define LOCAL_GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL 0x94FC
+#define LOCAL_GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL 0x94FB
+#define LOCAL_GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL 0x94FA
+#define LOCAL_GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL 0x94F8
+#define LOCAL_GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL 0x94F9
+#define LOCAL_GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL 0x94FF
+#define LOCAL_GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL 0x94F1
+#define LOCAL_GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL 0x94F2
+#define LOCAL_GL_PERFQUERY_COUNTER_EVENT_INTEL 0x94F0
+#define LOCAL_GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL 0x94FE
+#define LOCAL_GL_PERFQUERY_COUNTER_RAW_INTEL 0x94F4
+#define LOCAL_GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL 0x94F3
+#define LOCAL_GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL 0x94F5
+#define LOCAL_GL_PERFQUERY_DONOT_FLUSH_INTEL 0x83F9
+#define LOCAL_GL_PERFQUERY_FLUSH_INTEL 0x83FA
+#define LOCAL_GL_PERFQUERY_GLOBAL_CONTEXT_INTEL 0x00000001
+#define LOCAL_GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL 0x9500
+#define LOCAL_GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL 0x94FD
+#define LOCAL_GL_PERFQUERY_SINGLE_CONTEXT_INTEL 0x00000000
+#define LOCAL_GL_PERFQUERY_WAIT_INTEL 0x83FB
+#define LOCAL_GL_PERSPECTIVE_CORRECTION_HINT 0x0C50
+#define LOCAL_GL_PERTURB_EXT 0x85AE
+#define LOCAL_GL_PER_STAGE_CONSTANTS_NV 0x8535
+#define LOCAL_GL_PHONG_HINT_WIN 0x80EB
+#define LOCAL_GL_PHONG_WIN 0x80EA
+#define LOCAL_GL_PINLIGHT_NV 0x92A8
+#define LOCAL_GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080
+#define LOCAL_GL_PIXEL_BUFFER_BARRIER_BIT_EXT 0x00000080
+#define LOCAL_GL_PIXEL_COUNTER_BITS_NV 0x8864
+#define LOCAL_GL_PIXEL_COUNT_AVAILABLE_NV 0x8867
+#define LOCAL_GL_PIXEL_COUNT_NV 0x8866
+#define LOCAL_GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333
+#define LOCAL_GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355
+#define LOCAL_GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354
+#define LOCAL_GL_PIXEL_GROUP_COLOR_SGIS 0x8356
+#define LOCAL_GL_PIXEL_MAG_FILTER_EXT 0x8331
+#define LOCAL_GL_PIXEL_MAP_A_TO_A 0x0C79
+#define LOCAL_GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9
+#define LOCAL_GL_PIXEL_MAP_B_TO_B 0x0C78
+#define LOCAL_GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8
+#define LOCAL_GL_PIXEL_MAP_G_TO_G 0x0C77
+#define LOCAL_GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7
+#define LOCAL_GL_PIXEL_MAP_I_TO_A 0x0C75
+#define LOCAL_GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5
+#define LOCAL_GL_PIXEL_MAP_I_TO_B 0x0C74
+#define LOCAL_GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4
+#define LOCAL_GL_PIXEL_MAP_I_TO_G 0x0C73
+#define LOCAL_GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3
+#define LOCAL_GL_PIXEL_MAP_I_TO_I 0x0C70
+#define LOCAL_GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0
+#define LOCAL_GL_PIXEL_MAP_I_TO_R 0x0C72
+#define LOCAL_GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2
+#define LOCAL_GL_PIXEL_MAP_R_TO_R 0x0C76
+#define LOCAL_GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6
+#define LOCAL_GL_PIXEL_MAP_S_TO_S 0x0C71
+#define LOCAL_GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1
+#define LOCAL_GL_PIXEL_MIN_FILTER_EXT 0x8332
+#define LOCAL_GL_PIXEL_MODE_BIT 0x00000020
+#define LOCAL_GL_PIXEL_PACK_BUFFER 0x88EB
+#define LOCAL_GL_PIXEL_PACK_BUFFER_ARB 0x88EB
+#define LOCAL_GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
+#define LOCAL_GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED
+#define LOCAL_GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED
+#define LOCAL_GL_PIXEL_PACK_BUFFER_EXT 0x88EB
+#define LOCAL_GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3
+#define LOCAL_GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4
+#define LOCAL_GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2
+#define LOCAL_GL_PIXEL_TEXTURE_SGIS 0x8353
+#define LOCAL_GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX 0x8189
+#define LOCAL_GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX 0x818A
+#define LOCAL_GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX 0x8188
+#define LOCAL_GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX 0x8187
+#define LOCAL_GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B
+#define LOCAL_GL_PIXEL_TEX_GEN_Q_CEILING_SGIX 0x8184
+#define LOCAL_GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX 0x8186
+#define LOCAL_GL_PIXEL_TEX_GEN_Q_ROUND_SGIX 0x8185
+#define LOCAL_GL_PIXEL_TEX_GEN_SGIX 0x8139
+#define LOCAL_GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E
+#define LOCAL_GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F
+#define LOCAL_GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145
+#define LOCAL_GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144
+#define LOCAL_GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143
+#define LOCAL_GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142
+#define LOCAL_GL_PIXEL_TILE_HEIGHT_SGIX 0x8141
+#define LOCAL_GL_PIXEL_TILE_WIDTH_SGIX 0x8140
+#define LOCAL_GL_PIXEL_TRANSFORM_2D_EXT 0x8330
+#define LOCAL_GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338
+#define LOCAL_GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336
+#define LOCAL_GL_PIXEL_UNPACK_BUFFER 0x88EC
+#define LOCAL_GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC
+#define LOCAL_GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
+#define LOCAL_GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF
+#define LOCAL_GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF
+#define LOCAL_GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC
+#define LOCAL_GL_PLUS_CLAMPED_ALPHA_NV 0x92B2
+#define LOCAL_GL_PLUS_CLAMPED_NV 0x92B1
+#define LOCAL_GL_PLUS_DARKER_NV 0x9292
+#define LOCAL_GL_PLUS_NV 0x9291
+#define LOCAL_GL_PN_TRIANGLES_ATI 0x87F0
+#define LOCAL_GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3
+#define LOCAL_GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7
+#define LOCAL_GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8
+#define LOCAL_GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2
+#define LOCAL_GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6
+#define LOCAL_GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5
+#define LOCAL_GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4
+#define LOCAL_GL_POINT 0x1B00
+#define LOCAL_GL_POINTS 0x0000
+#define LOCAL_GL_POINT_BIT 0x00000002
+#define LOCAL_GL_POINT_DISTANCE_ATTENUATION 0x8129
+#define LOCAL_GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129
+#define LOCAL_GL_POINT_FADE_THRESHOLD_SIZE 0x8128
+#define LOCAL_GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128
+#define LOCAL_GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128
+#define LOCAL_GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128
+#define LOCAL_GL_POINT_SIZE 0x0B11
+#define LOCAL_GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES 0x8B9F
+#define LOCAL_GL_POINT_SIZE_ARRAY_OES 0x8B9C
+#define LOCAL_GL_POINT_SIZE_ARRAY_POINTER_OES 0x898C
+#define LOCAL_GL_POINT_SIZE_ARRAY_STRIDE_OES 0x898B
+#define LOCAL_GL_POINT_SIZE_ARRAY_TYPE_OES 0x898A
+#define LOCAL_GL_POINT_SIZE_GRANULARITY 0x0B13
+#define LOCAL_GL_POINT_SIZE_MAX 0x8127
+#define LOCAL_GL_POINT_SIZE_MAX_ARB 0x8127
+#define LOCAL_GL_POINT_SIZE_MAX_EXT 0x8127
+#define LOCAL_GL_POINT_SIZE_MAX_SGIS 0x8127
+#define LOCAL_GL_POINT_SIZE_MIN 0x8126
+#define LOCAL_GL_POINT_SIZE_MIN_ARB 0x8126
+#define LOCAL_GL_POINT_SIZE_MIN_EXT 0x8126
+#define LOCAL_GL_POINT_SIZE_MIN_SGIS 0x8126
+#define LOCAL_GL_POINT_SIZE_RANGE 0x0B12
+#define LOCAL_GL_POINT_SMOOTH 0x0B10
+#define LOCAL_GL_POINT_SMOOTH_HINT 0x0C51
+#define LOCAL_GL_POINT_SPRITE 0x8861
+#define LOCAL_GL_POINT_SPRITE_ARB 0x8861
+#define LOCAL_GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0
+#define LOCAL_GL_POINT_SPRITE_NV 0x8861
+#define LOCAL_GL_POINT_SPRITE_OES 0x8861
+#define LOCAL_GL_POINT_SPRITE_R_MODE_NV 0x8863
+#define LOCAL_GL_POINT_TOKEN 0x0701
+#define LOCAL_GL_POLYGON 0x0009
+#define LOCAL_GL_POLYGON_BIT 0x00000008
+#define LOCAL_GL_POLYGON_MODE 0x0B40
+#define LOCAL_GL_POLYGON_OFFSET_BIAS_EXT 0x8039
+#define LOCAL_GL_POLYGON_OFFSET_EXT 0x8037
+#define LOCAL_GL_POLYGON_OFFSET_FACTOR 0x8038
+#define LOCAL_GL_POLYGON_OFFSET_FACTOR_EXT 0x8038
+#define LOCAL_GL_POLYGON_OFFSET_FILL 0x8037
+#define LOCAL_GL_POLYGON_OFFSET_LINE 0x2A02
+#define LOCAL_GL_POLYGON_OFFSET_POINT 0x2A01
+#define LOCAL_GL_POLYGON_OFFSET_UNITS 0x2A00
+#define LOCAL_GL_POLYGON_SMOOTH 0x0B41
+#define LOCAL_GL_POLYGON_SMOOTH_HINT 0x0C53
+#define LOCAL_GL_POLYGON_STIPPLE 0x0B42
+#define LOCAL_GL_POLYGON_STIPPLE_BIT 0x00000010
+#define LOCAL_GL_POLYGON_TOKEN 0x0703
+#define LOCAL_GL_POSITION 0x1203
+#define LOCAL_GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB
+#define LOCAL_GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB
+#define LOCAL_GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7
+#define LOCAL_GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7
+#define LOCAL_GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA
+#define LOCAL_GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA
+#define LOCAL_GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6
+#define LOCAL_GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6
+#define LOCAL_GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2
+#define LOCAL_GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2
+#define LOCAL_GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9
+#define LOCAL_GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9
+#define LOCAL_GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5
+#define LOCAL_GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5
+#define LOCAL_GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8
+#define LOCAL_GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8
+#define LOCAL_GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4
+#define LOCAL_GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4
+#define LOCAL_GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023
+#define LOCAL_GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023
+#define LOCAL_GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F
+#define LOCAL_GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F
+#define LOCAL_GL_POST_CONVOLUTION_BLUE_BIAS 0x8022
+#define LOCAL_GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022
+#define LOCAL_GL_POST_CONVOLUTION_BLUE_SCALE 0x801E
+#define LOCAL_GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E
+#define LOCAL_GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1
+#define LOCAL_GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1
+#define LOCAL_GL_POST_CONVOLUTION_GREEN_BIAS 0x8021
+#define LOCAL_GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021
+#define LOCAL_GL_POST_CONVOLUTION_GREEN_SCALE 0x801D
+#define LOCAL_GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D
+#define LOCAL_GL_POST_CONVOLUTION_RED_BIAS 0x8020
+#define LOCAL_GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020
+#define LOCAL_GL_POST_CONVOLUTION_RED_SCALE 0x801C
+#define LOCAL_GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C
+#define LOCAL_GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162
+#define LOCAL_GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B
+#define LOCAL_GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179
+#define LOCAL_GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C
+#define LOCAL_GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A
+#define LOCAL_GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8
+#define LOCAL_GL_PRESENT_DURATION_NV 0x8E2B
+#define LOCAL_GL_PRESENT_TIME_NV 0x8E2A
+#define LOCAL_GL_PRESERVE_ATI 0x8762
+#define LOCAL_GL_PREVIOUS 0x8578
+#define LOCAL_GL_PREVIOUS_ARB 0x8578
+#define LOCAL_GL_PREVIOUS_EXT 0x8578
+#define LOCAL_GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4
+#define LOCAL_GL_PRIMARY_COLOR 0x8577
+#define LOCAL_GL_PRIMARY_COLOR_ARB 0x8577
+#define LOCAL_GL_PRIMARY_COLOR_EXT 0x8577
+#define LOCAL_GL_PRIMARY_COLOR_NV 0x852C
+#define LOCAL_GL_PRIMITIVES_GENERATED 0x8C87
+#define LOCAL_GL_PRIMITIVES_GENERATED_EXT 0x8C87
+#define LOCAL_GL_PRIMITIVES_GENERATED_NV 0x8C87
+#define LOCAL_GL_PRIMITIVE_ID_NV 0x8C7C
+#define LOCAL_GL_PRIMITIVE_RESTART 0x8F9D
+#define LOCAL_GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69
+#define LOCAL_GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221
+#define LOCAL_GL_PRIMITIVE_RESTART_INDEX 0x8F9E
+#define LOCAL_GL_PRIMITIVE_RESTART_INDEX_NV 0x8559
+#define LOCAL_GL_PRIMITIVE_RESTART_NV 0x8558
+#define LOCAL_GL_PROGRAM 0x82E2
+#define LOCAL_GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0
+#define LOCAL_GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805
+#define LOCAL_GL_PROGRAM_ATTRIBS_ARB 0x88AC
+#define LOCAL_GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906
+#define LOCAL_GL_PROGRAM_BINARY_ANGLE 0x93A6
+#define LOCAL_GL_PROGRAM_BINARY_FORMATS 0x87FF
+#define LOCAL_GL_PROGRAM_BINARY_FORMATS_OES 0x87FF
+#define LOCAL_GL_PROGRAM_BINARY_LENGTH 0x8741
+#define LOCAL_GL_PROGRAM_BINARY_LENGTH_OES 0x8741
+#define LOCAL_GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257
+#define LOCAL_GL_PROGRAM_BINDING_ARB 0x8677
+#define LOCAL_GL_PROGRAM_ERROR_POSITION_ARB 0x864B
+#define LOCAL_GL_PROGRAM_ERROR_POSITION_NV 0x864B
+#define LOCAL_GL_PROGRAM_ERROR_STRING_ARB 0x8874
+#define LOCAL_GL_PROGRAM_ERROR_STRING_NV 0x8874
+#define LOCAL_GL_PROGRAM_FORMAT_ARB 0x8876
+#define LOCAL_GL_PROGRAM_FORMAT_ASCII_ARB 0x8875
+#define LOCAL_GL_PROGRAM_INPUT 0x92E3
+#define LOCAL_GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0
+#define LOCAL_GL_PROGRAM_KHR 0x82E2
+#define LOCAL_GL_PROGRAM_LENGTH_ARB 0x8627
+#define LOCAL_GL_PROGRAM_LENGTH_NV 0x8627
+#define LOCAL_GL_PROGRAM_MATRIX_EXT 0x8E2D
+#define LOCAL_GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F
+#define LOCAL_GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2
+#define LOCAL_GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808
+#define LOCAL_GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE
+#define LOCAL_GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2
+#define LOCAL_GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA
+#define LOCAL_GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6
+#define LOCAL_GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A
+#define LOCAL_GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809
+#define LOCAL_GL_PROGRAM_OBJECT_ARB 0x8B40
+#define LOCAL_GL_PROGRAM_OBJECT_EXT 0x8B40
+#define LOCAL_GL_PROGRAM_OUTPUT 0x92E4
+#define LOCAL_GL_PROGRAM_PARAMETERS_ARB 0x88A8
+#define LOCAL_GL_PROGRAM_PARAMETER_NV 0x8644
+#define LOCAL_GL_PROGRAM_PIPELINE 0x82E4
+#define LOCAL_GL_PROGRAM_PIPELINE_BINDING 0x825A
+#define LOCAL_GL_PROGRAM_PIPELINE_BINDING_EXT 0x825A
+#define LOCAL_GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F
+#define LOCAL_GL_PROGRAM_POINT_SIZE 0x8642
+#define LOCAL_GL_PROGRAM_POINT_SIZE_ARB 0x8642
+#define LOCAL_GL_PROGRAM_POINT_SIZE_EXT 0x8642
+#define LOCAL_GL_PROGRAM_RESIDENT_NV 0x8647
+#define LOCAL_GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907
+#define LOCAL_GL_PROGRAM_SEPARABLE 0x8258
+#define LOCAL_GL_PROGRAM_SEPARABLE_EXT 0x8258
+#define LOCAL_GL_PROGRAM_STRING_ARB 0x8628
+#define LOCAL_GL_PROGRAM_STRING_NV 0x8628
+#define LOCAL_GL_PROGRAM_TARGET_NV 0x8646
+#define LOCAL_GL_PROGRAM_TEMPORARIES_ARB 0x88A4
+#define LOCAL_GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807
+#define LOCAL_GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806
+#define LOCAL_GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6
+#define LOCAL_GL_PROJECTION 0x1701
+#define LOCAL_GL_PROJECTION_MATRIX 0x0BA7
+#define LOCAL_GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES 0x898E
+#define LOCAL_GL_PROJECTION_STACK_DEPTH 0x0BA4
+#define LOCAL_GL_PROVOKING_VERTEX 0x8E4F
+#define LOCAL_GL_PROVOKING_VERTEX_EXT 0x8E4F
+#define LOCAL_GL_PROXY_COLOR_TABLE 0x80D3
+#define LOCAL_GL_PROXY_COLOR_TABLE_SGI 0x80D3
+#define LOCAL_GL_PROXY_HISTOGRAM 0x8025
+#define LOCAL_GL_PROXY_HISTOGRAM_EXT 0x8025
+#define LOCAL_GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5
+#define LOCAL_GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5
+#define LOCAL_GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4
+#define LOCAL_GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4
+#define LOCAL_GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163
+#define LOCAL_GL_PROXY_TEXTURE_1D 0x8063
+#define LOCAL_GL_PROXY_TEXTURE_1D_ARRAY 0x8C19
+#define LOCAL_GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19
+#define LOCAL_GL_PROXY_TEXTURE_1D_EXT 0x8063
+#define LOCAL_GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B
+#define LOCAL_GL_PROXY_TEXTURE_2D 0x8064
+#define LOCAL_GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B
+#define LOCAL_GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B
+#define LOCAL_GL_PROXY_TEXTURE_2D_EXT 0x8064
+#define LOCAL_GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101
+#define LOCAL_GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103
+#define LOCAL_GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C
+#define LOCAL_GL_PROXY_TEXTURE_3D 0x8070
+#define LOCAL_GL_PROXY_TEXTURE_3D_EXT 0x8070
+#define LOCAL_GL_PROXY_TEXTURE_4D_SGIS 0x8135
+#define LOCAL_GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD
+#define LOCAL_GL_PROXY_TEXTURE_CUBE_MAP 0x851B
+#define LOCAL_GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B
+#define LOCAL_GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B
+#define LOCAL_GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B
+#define LOCAL_GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B
+#define LOCAL_GL_PROXY_TEXTURE_RECTANGLE 0x84F7
+#define LOCAL_GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7
+#define LOCAL_GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7
+#define LOCAL_GL_PURGEABLE_APPLE 0x8A1D
+#define LOCAL_GL_Q 0x2003
+#define LOCAL_GL_QUADRATIC_ATTENUATION 0x1209
+#define LOCAL_GL_QUADRATIC_CURVE_TO_NV 0x0A
+#define LOCAL_GL_QUADS 0x0007
+#define LOCAL_GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C
+#define LOCAL_GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C
+#define LOCAL_GL_QUAD_ALPHA4_SGIS 0x811E
+#define LOCAL_GL_QUAD_ALPHA8_SGIS 0x811F
+#define LOCAL_GL_QUAD_INTENSITY4_SGIS 0x8122
+#define LOCAL_GL_QUAD_INTENSITY8_SGIS 0x8123
+#define LOCAL_GL_QUAD_LUMINANCE4_SGIS 0x8120
+#define LOCAL_GL_QUAD_LUMINANCE8_SGIS 0x8121
+#define LOCAL_GL_QUAD_MESH_SUN 0x8614
+#define LOCAL_GL_QUAD_STRIP 0x0008
+#define LOCAL_GL_QUAD_TEXTURE_SELECT_SGIS 0x8125
+#define LOCAL_GL_QUARTER_BIT_ATI 0x00000010
+#define LOCAL_GL_QUERY 0x82E3
+#define LOCAL_GL_QUERY_ALL_EVENT_BITS_AMD 0xFFFFFFFF
+#define LOCAL_GL_QUERY_BUFFER 0x9192
+#define LOCAL_GL_QUERY_BUFFER_AMD 0x9192
+#define LOCAL_GL_QUERY_BUFFER_BARRIER_BIT 0x00008000
+#define LOCAL_GL_QUERY_BUFFER_BINDING 0x9193
+#define LOCAL_GL_QUERY_BUFFER_BINDING_AMD 0x9193
+#define LOCAL_GL_QUERY_BY_REGION_NO_WAIT 0x8E16
+#define LOCAL_GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16
+#define LOCAL_GL_QUERY_BY_REGION_WAIT 0x8E15
+#define LOCAL_GL_QUERY_BY_REGION_WAIT_NV 0x8E15
+#define LOCAL_GL_QUERY_COUNTER_BITS 0x8864
+#define LOCAL_GL_QUERY_COUNTER_BITS_ARB 0x8864
+#define LOCAL_GL_QUERY_COUNTER_BITS_EXT 0x8864
+#define LOCAL_GL_QUERY_DEPTH_BOUNDS_FAIL_EVENT_BIT_AMD 0x00000008
+#define LOCAL_GL_QUERY_DEPTH_FAIL_EVENT_BIT_AMD 0x00000002
+#define LOCAL_GL_QUERY_DEPTH_PASS_EVENT_BIT_AMD 0x00000001
+#define LOCAL_GL_QUERY_KHR 0x82E3
+#define LOCAL_GL_QUERY_NO_WAIT 0x8E14
+#define LOCAL_GL_QUERY_NO_WAIT_NV 0x8E14
+#define LOCAL_GL_QUERY_OBJECT_AMD 0x9153
+#define LOCAL_GL_QUERY_OBJECT_EXT 0x9153
+#define LOCAL_GL_QUERY_RESULT 0x8866
+#define LOCAL_GL_QUERY_RESULT_ARB 0x8866
+#define LOCAL_GL_QUERY_RESULT_AVAILABLE 0x8867
+#define LOCAL_GL_QUERY_RESULT_AVAILABLE_ARB 0x8867
+#define LOCAL_GL_QUERY_RESULT_AVAILABLE_EXT 0x8867
+#define LOCAL_GL_QUERY_RESULT_EXT 0x8866
+#define LOCAL_GL_QUERY_RESULT_NO_WAIT 0x9194
+#define LOCAL_GL_QUERY_RESULT_NO_WAIT_AMD 0x9194
+#define LOCAL_GL_QUERY_STENCIL_FAIL_EVENT_BIT_AMD 0x00000004
+#define LOCAL_GL_QUERY_WAIT 0x8E13
+#define LOCAL_GL_QUERY_WAIT_NV 0x8E13
+#define LOCAL_GL_R 0x2002
+#define LOCAL_GL_R11F_G11F_B10F 0x8C3A
+#define LOCAL_GL_R11F_G11F_B10F_EXT 0x8C3A
+#define LOCAL_GL_R16 0x822A
+#define LOCAL_GL_R16F 0x822D
+#define LOCAL_GL_R16F_EXT 0x822D
+#define LOCAL_GL_R16I 0x8233
+#define LOCAL_GL_R16UI 0x8234
+#define LOCAL_GL_R16_SNORM 0x8F98
+#define LOCAL_GL_R1UI_C3F_V3F_SUN 0x85C6
+#define LOCAL_GL_R1UI_C4F_N3F_V3F_SUN 0x85C8
+#define LOCAL_GL_R1UI_C4UB_V3F_SUN 0x85C5
+#define LOCAL_GL_R1UI_N3F_V3F_SUN 0x85C7
+#define LOCAL_GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB
+#define LOCAL_GL_R1UI_T2F_N3F_V3F_SUN 0x85CA
+#define LOCAL_GL_R1UI_T2F_V3F_SUN 0x85C9
+#define LOCAL_GL_R1UI_V3F_SUN 0x85C4
+#define LOCAL_GL_R32F 0x822E
+#define LOCAL_GL_R32F_EXT 0x822E
+#define LOCAL_GL_R32I 0x8235
+#define LOCAL_GL_R32UI 0x8236
+#define LOCAL_GL_R3_G3_B2 0x2A10
+#define LOCAL_GL_R8 0x8229
+#define LOCAL_GL_R8I 0x8231
+#define LOCAL_GL_R8UI 0x8232
+#define LOCAL_GL_R8_EXT 0x8229
+#define LOCAL_GL_R8_SNORM 0x8F94
+#define LOCAL_GL_RASTERIZER_DISCARD 0x8C89
+#define LOCAL_GL_RASTERIZER_DISCARD_EXT 0x8C89
+#define LOCAL_GL_RASTERIZER_DISCARD_NV 0x8C89
+#define LOCAL_GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262
+#define LOCAL_GL_READ_BUFFER 0x0C02
+#define LOCAL_GL_READ_BUFFER_EXT 0x0C02
+#define LOCAL_GL_READ_BUFFER_NV 0x0C02
+#define LOCAL_GL_READ_FRAMEBUFFER 0x8CA8
+#define LOCAL_GL_READ_FRAMEBUFFER_ANGLE 0x8CA8
+#define LOCAL_GL_READ_FRAMEBUFFER_APPLE 0x8CA8
+#define LOCAL_GL_READ_FRAMEBUFFER_BINDING 0x8CAA
+#define LOCAL_GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA
+#define LOCAL_GL_READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA
+#define LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA
+#define LOCAL_GL_READ_FRAMEBUFFER_BINDING_NV 0x8CAA
+#define LOCAL_GL_READ_FRAMEBUFFER_EXT 0x8CA8
+#define LOCAL_GL_READ_FRAMEBUFFER_NV 0x8CA8
+#define LOCAL_GL_READ_ONLY 0x88B8
+#define LOCAL_GL_READ_ONLY_ARB 0x88B8
+#define LOCAL_GL_READ_PIXELS 0x828C
+#define LOCAL_GL_READ_PIXELS_FORMAT 0x828D
+#define LOCAL_GL_READ_PIXELS_TYPE 0x828E
+#define LOCAL_GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B
+#define LOCAL_GL_READ_PIXEL_DATA_RANGE_NV 0x8879
+#define LOCAL_GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D
+#define LOCAL_GL_READ_WRITE 0x88BA
+#define LOCAL_GL_READ_WRITE_ARB 0x88BA
+#define LOCAL_GL_RECIP_ADD_SIGNED_ALPHA_IMG 0x8C05
+#define LOCAL_GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE
+#define LOCAL_GL_RECT_NV 0xF6
+#define LOCAL_GL_RED 0x1903
+#define LOCAL_GL_REDUCE 0x8016
+#define LOCAL_GL_REDUCE_EXT 0x8016
+#define LOCAL_GL_RED_BIAS 0x0D15
+#define LOCAL_GL_RED_BITS 0x0D52
+#define LOCAL_GL_RED_BIT_ATI 0x00000001
+#define LOCAL_GL_RED_EXT 0x1903
+#define LOCAL_GL_RED_INTEGER 0x8D94
+#define LOCAL_GL_RED_INTEGER_EXT 0x8D94
+#define LOCAL_GL_RED_MAX_CLAMP_INGR 0x8564
+#define LOCAL_GL_RED_MIN_CLAMP_INGR 0x8560
+#define LOCAL_GL_RED_NV 0x1903
+#define LOCAL_GL_RED_SCALE 0x0D14
+#define LOCAL_GL_RED_SNORM 0x8F90
+#define LOCAL_GL_REFERENCED_BY_COMPUTE_SHADER 0x930B
+#define LOCAL_GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A
+#define LOCAL_GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309
+#define LOCAL_GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307
+#define LOCAL_GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308
+#define LOCAL_GL_REFERENCED_BY_VERTEX_SHADER 0x9306
+#define LOCAL_GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E
+#define LOCAL_GL_REFERENCE_PLANE_SGIX 0x817D
+#define LOCAL_GL_REFLECTION_MAP 0x8512
+#define LOCAL_GL_REFLECTION_MAP_ARB 0x8512
+#define LOCAL_GL_REFLECTION_MAP_EXT 0x8512
+#define LOCAL_GL_REFLECTION_MAP_NV 0x8512
+#define LOCAL_GL_REFLECTION_MAP_OES 0x8512
+#define LOCAL_GL_REGISTER_COMBINERS_NV 0x8522
+#define LOCAL_GL_REG_0_ATI 0x8921
+#define LOCAL_GL_REG_10_ATI 0x892B
+#define LOCAL_GL_REG_11_ATI 0x892C
+#define LOCAL_GL_REG_12_ATI 0x892D
+#define LOCAL_GL_REG_13_ATI 0x892E
+#define LOCAL_GL_REG_14_ATI 0x892F
+#define LOCAL_GL_REG_15_ATI 0x8930
+#define LOCAL_GL_REG_16_ATI 0x8931
+#define LOCAL_GL_REG_17_ATI 0x8932
+#define LOCAL_GL_REG_18_ATI 0x8933
+#define LOCAL_GL_REG_19_ATI 0x8934
+#define LOCAL_GL_REG_1_ATI 0x8922
+#define LOCAL_GL_REG_20_ATI 0x8935
+#define LOCAL_GL_REG_21_ATI 0x8936
+#define LOCAL_GL_REG_22_ATI 0x8937
+#define LOCAL_GL_REG_23_ATI 0x8938
+#define LOCAL_GL_REG_24_ATI 0x8939
+#define LOCAL_GL_REG_25_ATI 0x893A
+#define LOCAL_GL_REG_26_ATI 0x893B
+#define LOCAL_GL_REG_27_ATI 0x893C
+#define LOCAL_GL_REG_28_ATI 0x893D
+#define LOCAL_GL_REG_29_ATI 0x893E
+#define LOCAL_GL_REG_2_ATI 0x8923
+#define LOCAL_GL_REG_30_ATI 0x893F
+#define LOCAL_GL_REG_31_ATI 0x8940
+#define LOCAL_GL_REG_3_ATI 0x8924
+#define LOCAL_GL_REG_4_ATI 0x8925
+#define LOCAL_GL_REG_5_ATI 0x8926
+#define LOCAL_GL_REG_6_ATI 0x8927
+#define LOCAL_GL_REG_7_ATI 0x8928
+#define LOCAL_GL_REG_8_ATI 0x8929
+#define LOCAL_GL_REG_9_ATI 0x892A
+#define LOCAL_GL_RELATIVE_ARC_TO_NV 0xFF
+#define LOCAL_GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D
+#define LOCAL_GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07
+#define LOCAL_GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17
+#define LOCAL_GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19
+#define LOCAL_GL_RELATIVE_LINE_TO_NV 0x05
+#define LOCAL_GL_RELATIVE_MOVE_TO_NV 0x03
+#define LOCAL_GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B
+#define LOCAL_GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13
+#define LOCAL_GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15
+#define LOCAL_GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11
+#define LOCAL_GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F
+#define LOCAL_GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09
+#define LOCAL_GL_RELEASED_APPLE 0x8A19
+#define LOCAL_GL_RENDER 0x1C00
+#define LOCAL_GL_RENDERBUFFER 0x8D41
+#define LOCAL_GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
+#define LOCAL_GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53
+#define LOCAL_GL_RENDERBUFFER_ALPHA_SIZE_OES 0x8D53
+#define LOCAL_GL_RENDERBUFFER_BINDING 0x8CA7
+#define LOCAL_GL_RENDERBUFFER_BINDING_ANGLE 0x8CA7
+#define LOCAL_GL_RENDERBUFFER_BINDING_EXT 0x8CA7
+#define LOCAL_GL_RENDERBUFFER_BINDING_OES 0x8CA7
+#define LOCAL_GL_RENDERBUFFER_BLUE_SIZE 0x8D52
+#define LOCAL_GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52
+#define LOCAL_GL_RENDERBUFFER_BLUE_SIZE_OES 0x8D52
+#define LOCAL_GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10
+#define LOCAL_GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB
+#define LOCAL_GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
+#define LOCAL_GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54
+#define LOCAL_GL_RENDERBUFFER_DEPTH_SIZE_OES 0x8D54
+#define LOCAL_GL_RENDERBUFFER_EXT 0x8D41
+#define LOCAL_GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD
+#define LOCAL_GL_RENDERBUFFER_GREEN_SIZE 0x8D51
+#define LOCAL_GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51
+#define LOCAL_GL_RENDERBUFFER_GREEN_SIZE_OES 0x8D51
+#define LOCAL_GL_RENDERBUFFER_HEIGHT 0x8D43
+#define LOCAL_GL_RENDERBUFFER_HEIGHT_EXT 0x8D43
+#define LOCAL_GL_RENDERBUFFER_HEIGHT_OES 0x8D43
+#define LOCAL_GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
+#define LOCAL_GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44
+#define LOCAL_GL_RENDERBUFFER_INTERNAL_FORMAT_OES 0x8D44
+#define LOCAL_GL_RENDERBUFFER_OES 0x8D41
+#define LOCAL_GL_RENDERBUFFER_RED_SIZE 0x8D50
+#define LOCAL_GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50
+#define LOCAL_GL_RENDERBUFFER_RED_SIZE_OES 0x8D50
+#define LOCAL_GL_RENDERBUFFER_SAMPLES 0x8CAB
+#define LOCAL_GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB
+#define LOCAL_GL_RENDERBUFFER_SAMPLES_APPLE 0x8CAB
+#define LOCAL_GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
+#define LOCAL_GL_RENDERBUFFER_SAMPLES_IMG 0x9133
+#define LOCAL_GL_RENDERBUFFER_SAMPLES_NV 0x8CAB
+#define LOCAL_GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
+#define LOCAL_GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55
+#define LOCAL_GL_RENDERBUFFER_STENCIL_SIZE_OES 0x8D55
+#define LOCAL_GL_RENDERBUFFER_WIDTH 0x8D42
+#define LOCAL_GL_RENDERBUFFER_WIDTH_EXT 0x8D42
+#define LOCAL_GL_RENDERBUFFER_WIDTH_OES 0x8D42
+#define LOCAL_GL_RENDERER 0x1F01
+#define LOCAL_GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM 0x8FB3
+#define LOCAL_GL_RENDER_MODE 0x0C40
+#define LOCAL_GL_REPEAT 0x2901
+#define LOCAL_GL_REPLACE 0x1E01
+#define LOCAL_GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3
+#define LOCAL_GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2
+#define LOCAL_GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0
+#define LOCAL_GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1
+#define LOCAL_GL_REPLACEMENT_CODE_SUN 0x81D8
+#define LOCAL_GL_REPLACE_EXT 0x8062
+#define LOCAL_GL_REPLACE_MIDDLE_SUN 0x0002
+#define LOCAL_GL_REPLACE_OLDEST_SUN 0x0003
+#define LOCAL_GL_REPLACE_VALUE_AMD 0x874B
+#define LOCAL_GL_REPLICATE_BORDER 0x8153
+#define LOCAL_GL_REPLICATE_BORDER_HP 0x8153
+#define LOCAL_GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68
+#define LOCAL_GL_RESAMPLE_AVERAGE_OML 0x8988
+#define LOCAL_GL_RESAMPLE_DECIMATE_OML 0x8989
+#define LOCAL_GL_RESAMPLE_DECIMATE_SGIX 0x8430
+#define LOCAL_GL_RESAMPLE_REPLICATE_OML 0x8986
+#define LOCAL_GL_RESAMPLE_REPLICATE_SGIX 0x842E
+#define LOCAL_GL_RESAMPLE_ZERO_FILL_OML 0x8987
+#define LOCAL_GL_RESAMPLE_ZERO_FILL_SGIX 0x842F
+#define LOCAL_GL_RESCALE_NORMAL 0x803A
+#define LOCAL_GL_RESCALE_NORMAL_EXT 0x803A
+#define LOCAL_GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define LOCAL_GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256
+#define LOCAL_GL_RESTART_PATH_NV 0xF0
+#define LOCAL_GL_RESTART_SUN 0x0001
+#define LOCAL_GL_RETAINED_APPLE 0x8A1B
+#define LOCAL_GL_RETURN 0x0102
+#define LOCAL_GL_RG 0x8227
+#define LOCAL_GL_RG16 0x822C
+#define LOCAL_GL_RG16F 0x822F
+#define LOCAL_GL_RG16F_EXT 0x822F
+#define LOCAL_GL_RG16I 0x8239
+#define LOCAL_GL_RG16UI 0x823A
+#define LOCAL_GL_RG16_SNORM 0x8F99
+#define LOCAL_GL_RG32F 0x8230
+#define LOCAL_GL_RG32F_EXT 0x8230
+#define LOCAL_GL_RG32I 0x823B
+#define LOCAL_GL_RG32UI 0x823C
+#define LOCAL_GL_RG8 0x822B
+#define LOCAL_GL_RG8I 0x8237
+#define LOCAL_GL_RG8UI 0x8238
+#define LOCAL_GL_RG8_EXT 0x822B
+#define LOCAL_GL_RG8_SNORM 0x8F95
+#define LOCAL_GL_RGB 0x1907
+#define LOCAL_GL_RGB10 0x8052
+#define LOCAL_GL_RGB10_A2 0x8059
+#define LOCAL_GL_RGB10_A2UI 0x906F
+#define LOCAL_GL_RGB10_A2_EXT 0x8059
+#define LOCAL_GL_RGB10_EXT 0x8052
+#define LOCAL_GL_RGB12 0x8053
+#define LOCAL_GL_RGB12_EXT 0x8053
+#define LOCAL_GL_RGB16 0x8054
+#define LOCAL_GL_RGB16F 0x881B
+#define LOCAL_GL_RGB16F_ARB 0x881B
+#define LOCAL_GL_RGB16F_EXT 0x881B
+#define LOCAL_GL_RGB16I 0x8D89
+#define LOCAL_GL_RGB16I_EXT 0x8D89
+#define LOCAL_GL_RGB16UI 0x8D77
+#define LOCAL_GL_RGB16UI_EXT 0x8D77
+#define LOCAL_GL_RGB16_EXT 0x8054
+#define LOCAL_GL_RGB16_SNORM 0x8F9A
+#define LOCAL_GL_RGB2_EXT 0x804E
+#define LOCAL_GL_RGB32F 0x8815
+#define LOCAL_GL_RGB32F_ARB 0x8815
+#define LOCAL_GL_RGB32F_EXT 0x8815
+#define LOCAL_GL_RGB32I 0x8D83
+#define LOCAL_GL_RGB32I_EXT 0x8D83
+#define LOCAL_GL_RGB32UI 0x8D71
+#define LOCAL_GL_RGB32UI_EXT 0x8D71
+#define LOCAL_GL_RGB4 0x804F
+#define LOCAL_GL_RGB4_EXT 0x804F
+#define LOCAL_GL_RGB4_S3TC 0x83A1
+#define LOCAL_GL_RGB5 0x8050
+#define LOCAL_GL_RGB565 0x8D62
+#define LOCAL_GL_RGB565_OES 0x8D62
+#define LOCAL_GL_RGB5_A1 0x8057
+#define LOCAL_GL_RGB5_A1_EXT 0x8057
+#define LOCAL_GL_RGB5_A1_OES 0x8057
+#define LOCAL_GL_RGB5_EXT 0x8050
+#define LOCAL_GL_RGB8 0x8051
+#define LOCAL_GL_RGB8I 0x8D8F
+#define LOCAL_GL_RGB8I_EXT 0x8D8F
+#define LOCAL_GL_RGB8UI 0x8D7D
+#define LOCAL_GL_RGB8UI_EXT 0x8D7D
+#define LOCAL_GL_RGB8_EXT 0x8051
+#define LOCAL_GL_RGB8_OES 0x8051
+#define LOCAL_GL_RGB8_SNORM 0x8F96
+#define LOCAL_GL_RGB9_E5 0x8C3D
+#define LOCAL_GL_RGB9_E5_EXT 0x8C3D
+#define LOCAL_GL_RGBA 0x1908
+#define LOCAL_GL_RGBA12 0x805A
+#define LOCAL_GL_RGBA12_EXT 0x805A
+#define LOCAL_GL_RGBA16 0x805B
+#define LOCAL_GL_RGBA16F 0x881A
+#define LOCAL_GL_RGBA16F_ARB 0x881A
+#define LOCAL_GL_RGBA16F_EXT 0x881A
+#define LOCAL_GL_RGBA16I 0x8D88
+#define LOCAL_GL_RGBA16I_EXT 0x8D88
+#define LOCAL_GL_RGBA16UI 0x8D76
+#define LOCAL_GL_RGBA16UI_EXT 0x8D76
+#define LOCAL_GL_RGBA16_EXT 0x805B
+#define LOCAL_GL_RGBA16_SNORM 0x8F9B
+#define LOCAL_GL_RGBA2 0x8055
+#define LOCAL_GL_RGBA2_EXT 0x8055
+#define LOCAL_GL_RGBA32F 0x8814
+#define LOCAL_GL_RGBA32F_ARB 0x8814
+#define LOCAL_GL_RGBA32F_EXT 0x8814
+#define LOCAL_GL_RGBA32I 0x8D82
+#define LOCAL_GL_RGBA32I_EXT 0x8D82
+#define LOCAL_GL_RGBA32UI 0x8D70
+#define LOCAL_GL_RGBA32UI_EXT 0x8D70
+#define LOCAL_GL_RGBA4 0x8056
+#define LOCAL_GL_RGBA4_DXT5_S3TC 0x83A5
+#define LOCAL_GL_RGBA4_EXT 0x8056
+#define LOCAL_GL_RGBA4_OES 0x8056
+#define LOCAL_GL_RGBA4_S3TC 0x83A3
+#define LOCAL_GL_RGBA8 0x8058
+#define LOCAL_GL_RGBA8I 0x8D8E
+#define LOCAL_GL_RGBA8I_EXT 0x8D8E
+#define LOCAL_GL_RGBA8UI 0x8D7C
+#define LOCAL_GL_RGBA8UI_EXT 0x8D7C
+#define LOCAL_GL_RGBA8_EXT 0x8058
+#define LOCAL_GL_RGBA8_OES 0x8058
+#define LOCAL_GL_RGBA8_SNORM 0x8F97
+#define LOCAL_GL_RGBA_DXT5_S3TC 0x83A4
+#define LOCAL_GL_RGBA_FLOAT16_APPLE 0x881A
+#define LOCAL_GL_RGBA_FLOAT16_ATI 0x881A
+#define LOCAL_GL_RGBA_FLOAT32_APPLE 0x8814
+#define LOCAL_GL_RGBA_FLOAT32_ATI 0x8814
+#define LOCAL_GL_RGBA_FLOAT_MODE_ARB 0x8820
+#define LOCAL_GL_RGBA_FLOAT_MODE_ATI 0x8820
+#define LOCAL_GL_RGBA_INTEGER 0x8D99
+#define LOCAL_GL_RGBA_INTEGER_EXT 0x8D99
+#define LOCAL_GL_RGBA_INTEGER_MODE_EXT 0x8D9E
+#define LOCAL_GL_RGBA_MODE 0x0C31
+#define LOCAL_GL_RGBA_S3TC 0x83A2
+#define LOCAL_GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C
+#define LOCAL_GL_RGBA_SNORM 0x8F93
+#define LOCAL_GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9
+#define LOCAL_GL_RGB_422_APPLE 0x8A1F
+#define LOCAL_GL_RGB_FLOAT16_APPLE 0x881B
+#define LOCAL_GL_RGB_FLOAT16_ATI 0x881B
+#define LOCAL_GL_RGB_FLOAT32_APPLE 0x8815
+#define LOCAL_GL_RGB_FLOAT32_ATI 0x8815
+#define LOCAL_GL_RGB_INTEGER 0x8D98
+#define LOCAL_GL_RGB_INTEGER_EXT 0x8D98
+#define LOCAL_GL_RGB_RAW_422_APPLE 0x8A51
+#define LOCAL_GL_RGB_S3TC 0x83A0
+#define LOCAL_GL_RGB_SCALE 0x8573
+#define LOCAL_GL_RGB_SCALE_ARB 0x8573
+#define LOCAL_GL_RGB_SCALE_EXT 0x8573
+#define LOCAL_GL_RGB_SNORM 0x8F92
+#define LOCAL_GL_RG_EXT 0x8227
+#define LOCAL_GL_RG_INTEGER 0x8228
+#define LOCAL_GL_RG_SNORM 0x8F91
+#define LOCAL_GL_RIGHT 0x0407
+#define LOCAL_GL_ROUND_NV 0x90A4
+#define LOCAL_GL_S 0x2000
+#define LOCAL_GL_SAMPLER 0x82E6
+#define LOCAL_GL_SAMPLER_1D 0x8B5D
+#define LOCAL_GL_SAMPLER_1D_ARB 0x8B5D
+#define LOCAL_GL_SAMPLER_1D_ARRAY 0x8DC0
+#define LOCAL_GL_SAMPLER_1D_ARRAY_EXT 0x8DC0
+#define LOCAL_GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3
+#define LOCAL_GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3
+#define LOCAL_GL_SAMPLER_1D_SHADOW 0x8B61
+#define LOCAL_GL_SAMPLER_1D_SHADOW_ARB 0x8B61
+#define LOCAL_GL_SAMPLER_2D 0x8B5E
+#define LOCAL_GL_SAMPLER_2D_ARB 0x8B5E
+#define LOCAL_GL_SAMPLER_2D_ARRAY 0x8DC1
+#define LOCAL_GL_SAMPLER_2D_ARRAY_EXT 0x8DC1
+#define LOCAL_GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
+#define LOCAL_GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4
+#define LOCAL_GL_SAMPLER_2D_ARRAY_SHADOW_NV 0x8DC4
+#define LOCAL_GL_SAMPLER_2D_MULTISAMPLE 0x9108
+#define LOCAL_GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B
+#define LOCAL_GL_SAMPLER_2D_RECT 0x8B63
+#define LOCAL_GL_SAMPLER_2D_RECT_ARB 0x8B63
+#define LOCAL_GL_SAMPLER_2D_RECT_SHADOW 0x8B64
+#define LOCAL_GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64
+#define LOCAL_GL_SAMPLER_2D_SHADOW 0x8B62
+#define LOCAL_GL_SAMPLER_2D_SHADOW_ARB 0x8B62
+#define LOCAL_GL_SAMPLER_2D_SHADOW_EXT 0x8B62
+#define LOCAL_GL_SAMPLER_3D 0x8B5F
+#define LOCAL_GL_SAMPLER_3D_ARB 0x8B5F
+#define LOCAL_GL_SAMPLER_3D_OES 0x8B5F
+#define LOCAL_GL_SAMPLER_BINDING 0x8919
+#define LOCAL_GL_SAMPLER_BUFFER 0x8DC2
+#define LOCAL_GL_SAMPLER_BUFFER_AMD 0x9001
+#define LOCAL_GL_SAMPLER_BUFFER_EXT 0x8DC2
+#define LOCAL_GL_SAMPLER_CUBE 0x8B60
+#define LOCAL_GL_SAMPLER_CUBE_ARB 0x8B60
+#define LOCAL_GL_SAMPLER_CUBE_MAP_ARRAY 0x900C
+#define LOCAL_GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C
+#define LOCAL_GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D
+#define LOCAL_GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D
+#define LOCAL_GL_SAMPLER_CUBE_SHADOW 0x8DC5
+#define LOCAL_GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5
+#define LOCAL_GL_SAMPLER_CUBE_SHADOW_NV 0x8DC5
+#define LOCAL_GL_SAMPLER_EXTERNAL_OES 0x8D66
+#define LOCAL_GL_SAMPLER_KHR 0x82E6
+#define LOCAL_GL_SAMPLER_OBJECT_AMD 0x9155
+#define LOCAL_GL_SAMPLER_RENDERBUFFER_NV 0x8E56
+#define LOCAL_GL_SAMPLES 0x80A9
+#define LOCAL_GL_SAMPLES_3DFX 0x86B4
+#define LOCAL_GL_SAMPLES_ARB 0x80A9
+#define LOCAL_GL_SAMPLES_EXT 0x80A9
+#define LOCAL_GL_SAMPLES_PASSED 0x8914
+#define LOCAL_GL_SAMPLES_PASSED_ARB 0x8914
+#define LOCAL_GL_SAMPLES_SGIS 0x80A9
+#define LOCAL_GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
+#define LOCAL_GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E
+#define LOCAL_GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E
+#define LOCAL_GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E
+#define LOCAL_GL_SAMPLE_ALPHA_TO_ONE 0x809F
+#define LOCAL_GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F
+#define LOCAL_GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F
+#define LOCAL_GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F
+#define LOCAL_GL_SAMPLE_BUFFERS 0x80A8
+#define LOCAL_GL_SAMPLE_BUFFERS_3DFX 0x86B3
+#define LOCAL_GL_SAMPLE_BUFFERS_ARB 0x80A8
+#define LOCAL_GL_SAMPLE_BUFFERS_EXT 0x80A8
+#define LOCAL_GL_SAMPLE_BUFFERS_SGIS 0x80A8
+#define LOCAL_GL_SAMPLE_COVERAGE 0x80A0
+#define LOCAL_GL_SAMPLE_COVERAGE_ARB 0x80A0
+#define LOCAL_GL_SAMPLE_COVERAGE_INVERT 0x80AB
+#define LOCAL_GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB
+#define LOCAL_GL_SAMPLE_COVERAGE_VALUE 0x80AA
+#define LOCAL_GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA
+#define LOCAL_GL_SAMPLE_MASK 0x8E51
+#define LOCAL_GL_SAMPLE_MASK_EXT 0x80A0
+#define LOCAL_GL_SAMPLE_MASK_INVERT_EXT 0x80AB
+#define LOCAL_GL_SAMPLE_MASK_INVERT_SGIS 0x80AB
+#define LOCAL_GL_SAMPLE_MASK_NV 0x8E51
+#define LOCAL_GL_SAMPLE_MASK_SGIS 0x80A0
+#define LOCAL_GL_SAMPLE_MASK_VALUE 0x8E52
+#define LOCAL_GL_SAMPLE_MASK_VALUE_EXT 0x80AA
+#define LOCAL_GL_SAMPLE_MASK_VALUE_NV 0x8E52
+#define LOCAL_GL_SAMPLE_MASK_VALUE_SGIS 0x80AA
+#define LOCAL_GL_SAMPLE_PATTERN_EXT 0x80AC
+#define LOCAL_GL_SAMPLE_PATTERN_SGIS 0x80AC
+#define LOCAL_GL_SAMPLE_POSITION 0x8E50
+#define LOCAL_GL_SAMPLE_POSITION_NV 0x8E50
+#define LOCAL_GL_SAMPLE_SHADING 0x8C36
+#define LOCAL_GL_SAMPLE_SHADING_ARB 0x8C36
+#define LOCAL_GL_SATURATE_BIT_ATI 0x00000040
+#define LOCAL_GL_SCALAR_EXT 0x87BE
+#define LOCAL_GL_SCALEBIAS_HINT_SGIX 0x8322
+#define LOCAL_GL_SCALED_RESOLVE_FASTEST_EXT 0x90BA
+#define LOCAL_GL_SCALED_RESOLVE_NICEST_EXT 0x90BB
+#define LOCAL_GL_SCALE_BY_FOUR_NV 0x853F
+#define LOCAL_GL_SCALE_BY_ONE_HALF_NV 0x8540
+#define LOCAL_GL_SCALE_BY_TWO_NV 0x853E
+#define LOCAL_GL_SCISSOR_BIT 0x00080000
+#define LOCAL_GL_SCISSOR_BOX 0x0C10
+#define LOCAL_GL_SCISSOR_TEST 0x0C11
+#define LOCAL_GL_SCREEN_COORDINATES_REND 0x8490
+#define LOCAL_GL_SCREEN_NV 0x9295
+#define LOCAL_GL_SECONDARY_COLOR_ARRAY 0x845E
+#define LOCAL_GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27
+#define LOCAL_GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C
+#define LOCAL_GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C
+#define LOCAL_GL_SECONDARY_COLOR_ARRAY_EXT 0x845E
+#define LOCAL_GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31
+#define LOCAL_GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077
+#define LOCAL_GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087
+#define LOCAL_GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D
+#define LOCAL_GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D
+#define LOCAL_GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A
+#define LOCAL_GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A
+#define LOCAL_GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C
+#define LOCAL_GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C
+#define LOCAL_GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B
+#define LOCAL_GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B
+#define LOCAL_GL_SECONDARY_COLOR_NV 0x852D
+#define LOCAL_GL_SECONDARY_INTERPOLATOR_ATI 0x896D
+#define LOCAL_GL_SELECT 0x1C02
+#define LOCAL_GL_SELECTION_BUFFER_POINTER 0x0DF3
+#define LOCAL_GL_SELECTION_BUFFER_SIZE 0x0DF4
+#define LOCAL_GL_SEPARABLE_2D 0x8012
+#define LOCAL_GL_SEPARABLE_2D_EXT 0x8012
+#define LOCAL_GL_SEPARATE_ATTRIBS 0x8C8D
+#define LOCAL_GL_SEPARATE_ATTRIBS_EXT 0x8C8D
+#define LOCAL_GL_SEPARATE_ATTRIBS_NV 0x8C8D
+#define LOCAL_GL_SEPARATE_SPECULAR_COLOR 0x81FA
+#define LOCAL_GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA
+#define LOCAL_GL_SET 0x150F
+#define LOCAL_GL_SET_AMD 0x874A
+#define LOCAL_GL_SGX_BINARY_IMG 0x8C0A
+#define LOCAL_GL_SGX_PROGRAM_BINARY_IMG 0x9130
+#define LOCAL_GL_SHADER 0x82E1
+#define LOCAL_GL_SHADER_BINARY_DMP 0x9250
+#define LOCAL_GL_SHADER_BINARY_FORMATS 0x8DF8
+#define LOCAL_GL_SHADER_BINARY_VIV 0x8FC4
+#define LOCAL_GL_SHADER_COMPILER 0x8DFA
+#define LOCAL_GL_SHADER_CONSISTENT_NV 0x86DD
+#define LOCAL_GL_SHADER_GLOBAL_ACCESS_BARRIER_BIT_NV 0x00000010
+#define LOCAL_GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020
+#define LOCAL_GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT 0x00000020
+#define LOCAL_GL_SHADER_IMAGE_ATOMIC 0x82A6
+#define LOCAL_GL_SHADER_IMAGE_LOAD 0x82A4
+#define LOCAL_GL_SHADER_IMAGE_STORE 0x82A5
+#define LOCAL_GL_SHADER_INCLUDE_ARB 0x8DAE
+#define LOCAL_GL_SHADER_KHR 0x82E1
+#define LOCAL_GL_SHADER_OBJECT_ARB 0x8B48
+#define LOCAL_GL_SHADER_OBJECT_EXT 0x8B48
+#define LOCAL_GL_SHADER_OPERATION_NV 0x86DF
+#define LOCAL_GL_SHADER_SOURCE_LENGTH 0x8B88
+#define LOCAL_GL_SHADER_STORAGE_BARRIER_BIT 0x00002000
+#define LOCAL_GL_SHADER_STORAGE_BLOCK 0x92E6
+#define LOCAL_GL_SHADER_STORAGE_BUFFER 0x90D2
+#define LOCAL_GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3
+#define LOCAL_GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF
+#define LOCAL_GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5
+#define LOCAL_GL_SHADER_STORAGE_BUFFER_START 0x90D4
+#define LOCAL_GL_SHADER_TYPE 0x8B4F
+#define LOCAL_GL_SHADE_MODEL 0x0B54
+#define LOCAL_GL_SHADING_LANGUAGE_VERSION 0x8B8C
+#define LOCAL_GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C
+#define LOCAL_GL_SHADOW_AMBIENT_SGIX 0x80BF
+#define LOCAL_GL_SHADOW_ATTENUATION_EXT 0x834E
+#define LOCAL_GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB
+#define LOCAL_GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0
+#define LOCAL_GL_SHININESS 0x1601
+#define LOCAL_GL_SHORT 0x1402
+#define LOCAL_GL_SIGNALED 0x9119
+#define LOCAL_GL_SIGNALED_APPLE 0x9119
+#define LOCAL_GL_SIGNED_ALPHA8_NV 0x8706
+#define LOCAL_GL_SIGNED_ALPHA_NV 0x8705
+#define LOCAL_GL_SIGNED_HILO16_NV 0x86FA
+#define LOCAL_GL_SIGNED_HILO8_NV 0x885F
+#define LOCAL_GL_SIGNED_HILO_NV 0x86F9
+#define LOCAL_GL_SIGNED_IDENTITY_NV 0x853C
+#define LOCAL_GL_SIGNED_INTENSITY8_NV 0x8708
+#define LOCAL_GL_SIGNED_INTENSITY_NV 0x8707
+#define LOCAL_GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704
+#define LOCAL_GL_SIGNED_LUMINANCE8_NV 0x8702
+#define LOCAL_GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703
+#define LOCAL_GL_SIGNED_LUMINANCE_NV 0x8701
+#define LOCAL_GL_SIGNED_NEGATE_NV 0x853D
+#define LOCAL_GL_SIGNED_NORMALIZED 0x8F9C
+#define LOCAL_GL_SIGNED_RGB8_NV 0x86FF
+#define LOCAL_GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D
+#define LOCAL_GL_SIGNED_RGBA8_NV 0x86FC
+#define LOCAL_GL_SIGNED_RGBA_NV 0x86FB
+#define LOCAL_GL_SIGNED_RGB_NV 0x86FE
+#define LOCAL_GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C
+#define LOCAL_GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC
+#define LOCAL_GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE
+#define LOCAL_GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD
+#define LOCAL_GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF
+#define LOCAL_GL_SINGLE_COLOR 0x81F9
+#define LOCAL_GL_SINGLE_COLOR_EXT 0x81F9
+#define LOCAL_GL_SKIP_COMPONENTS1_NV -6
+#define LOCAL_GL_SKIP_COMPONENTS2_NV -5
+#define LOCAL_GL_SKIP_COMPONENTS3_NV -4
+#define LOCAL_GL_SKIP_COMPONENTS4_NV -3
+#define LOCAL_GL_SKIP_DECODE_EXT 0x8A4A
+#define LOCAL_GL_SKIP_MISSING_GLYPH_NV 0x90A9
+#define LOCAL_GL_SLICE_ACCUM_SUN 0x85CC
+#define LOCAL_GL_SLIM10U_SGIX 0x831E
+#define LOCAL_GL_SLIM12S_SGIX 0x831F
+#define LOCAL_GL_SLIM8U_SGIX 0x831D
+#define LOCAL_GL_SLUMINANCE 0x8C46
+#define LOCAL_GL_SLUMINANCE8 0x8C47
+#define LOCAL_GL_SLUMINANCE8_ALPHA8 0x8C45
+#define LOCAL_GL_SLUMINANCE8_ALPHA8_EXT 0x8C45
+#define LOCAL_GL_SLUMINANCE8_ALPHA8_NV 0x8C45
+#define LOCAL_GL_SLUMINANCE8_EXT 0x8C47
+#define LOCAL_GL_SLUMINANCE8_NV 0x8C47
+#define LOCAL_GL_SLUMINANCE_ALPHA 0x8C44
+#define LOCAL_GL_SLUMINANCE_ALPHA_EXT 0x8C44
+#define LOCAL_GL_SLUMINANCE_ALPHA_NV 0x8C44
+#define LOCAL_GL_SLUMINANCE_EXT 0x8C46
+#define LOCAL_GL_SLUMINANCE_NV 0x8C46
+#define LOCAL_GL_SMALL_CCW_ARC_TO_NV 0x12
+#define LOCAL_GL_SMALL_CW_ARC_TO_NV 0x14
+#define LOCAL_GL_SMOOTH 0x1D01
+#define LOCAL_GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10
+#define LOCAL_GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23
+#define LOCAL_GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22
+#define LOCAL_GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13
+#define LOCAL_GL_SMOOTH_POINT_SIZE_RANGE 0x0B12
+#define LOCAL_GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E
+#define LOCAL_GL_SOFTLIGHT_NV 0x929C
+#define LOCAL_GL_SOURCE0_ALPHA 0x8588
+#define LOCAL_GL_SOURCE0_ALPHA_ARB 0x8588
+#define LOCAL_GL_SOURCE0_ALPHA_EXT 0x8588
+#define LOCAL_GL_SOURCE0_RGB 0x8580
+#define LOCAL_GL_SOURCE0_RGB_ARB 0x8580
+#define LOCAL_GL_SOURCE0_RGB_EXT 0x8580
+#define LOCAL_GL_SOURCE1_ALPHA 0x8589
+#define LOCAL_GL_SOURCE1_ALPHA_ARB 0x8589
+#define LOCAL_GL_SOURCE1_ALPHA_EXT 0x8589
+#define LOCAL_GL_SOURCE1_RGB 0x8581
+#define LOCAL_GL_SOURCE1_RGB_ARB 0x8581
+#define LOCAL_GL_SOURCE1_RGB_EXT 0x8581
+#define LOCAL_GL_SOURCE2_ALPHA 0x858A
+#define LOCAL_GL_SOURCE2_ALPHA_ARB 0x858A
+#define LOCAL_GL_SOURCE2_ALPHA_EXT 0x858A
+#define LOCAL_GL_SOURCE2_RGB 0x8582
+#define LOCAL_GL_SOURCE2_RGB_ARB 0x8582
+#define LOCAL_GL_SOURCE2_RGB_EXT 0x8582
+#define LOCAL_GL_SOURCE3_ALPHA_NV 0x858B
+#define LOCAL_GL_SOURCE3_RGB_NV 0x8583
+#define LOCAL_GL_SPARE0_NV 0x852E
+#define LOCAL_GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532
+#define LOCAL_GL_SPARE1_NV 0x852F
+#define LOCAL_GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB 0x91A9
+#define LOCAL_GL_SPECULAR 0x1202
+#define LOCAL_GL_SPHERE_MAP 0x2402
+#define LOCAL_GL_SPOT_CUTOFF 0x1206
+#define LOCAL_GL_SPOT_DIRECTION 0x1204
+#define LOCAL_GL_SPOT_EXPONENT 0x1205
+#define LOCAL_GL_SPRITE_AXIAL_SGIX 0x814C
+#define LOCAL_GL_SPRITE_AXIS_SGIX 0x814A
+#define LOCAL_GL_SPRITE_EYE_ALIGNED_SGIX 0x814E
+#define LOCAL_GL_SPRITE_MODE_SGIX 0x8149
+#define LOCAL_GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D
+#define LOCAL_GL_SPRITE_SGIX 0x8148
+#define LOCAL_GL_SPRITE_TRANSLATION_SGIX 0x814B
+#define LOCAL_GL_SQUARE_NV 0x90A3
+#define LOCAL_GL_SRC0_ALPHA 0x8588
+#define LOCAL_GL_SRC0_RGB 0x8580
+#define LOCAL_GL_SRC1_ALPHA 0x8589
+#define LOCAL_GL_SRC1_COLOR 0x88F9
+#define LOCAL_GL_SRC1_RGB 0x8581
+#define LOCAL_GL_SRC2_ALPHA 0x858A
+#define LOCAL_GL_SRC2_RGB 0x8582
+#define LOCAL_GL_SRC_ALPHA 0x0302
+#define LOCAL_GL_SRC_ALPHA_SATURATE 0x0308
+#define LOCAL_GL_SRC_ATOP_NV 0x928E
+#define LOCAL_GL_SRC_COLOR 0x0300
+#define LOCAL_GL_SRC_IN_NV 0x928A
+#define LOCAL_GL_SRC_NV 0x9286
+#define LOCAL_GL_SRC_OUT_NV 0x928C
+#define LOCAL_GL_SRC_OVER_NV 0x9288
+#define LOCAL_GL_SRGB 0x8C40
+#define LOCAL_GL_SRGB8 0x8C41
+#define LOCAL_GL_SRGB8_ALPHA8 0x8C43
+#define LOCAL_GL_SRGB8_ALPHA8_EXT 0x8C43
+#define LOCAL_GL_SRGB8_EXT 0x8C41
+#define LOCAL_GL_SRGB8_NV 0x8C41
+#define LOCAL_GL_SRGB_ALPHA 0x8C42
+#define LOCAL_GL_SRGB_ALPHA_EXT 0x8C42
+#define LOCAL_GL_SRGB_DECODE_ARB 0x8299
+#define LOCAL_GL_SRGB_EXT 0x8C40
+#define LOCAL_GL_SRGB_READ 0x8297
+#define LOCAL_GL_SRGB_WRITE 0x8298
+#define LOCAL_GL_STACK_OVERFLOW 0x0503
+#define LOCAL_GL_STACK_OVERFLOW_KHR 0x0503
+#define LOCAL_GL_STACK_UNDERFLOW 0x0504
+#define LOCAL_GL_STACK_UNDERFLOW_KHR 0x0504
+#define LOCAL_GL_STANDARD_FONT_NAME_NV 0x9072
+#define LOCAL_GL_STATE_RESTORE 0x8BDC
+#define LOCAL_GL_STATIC_ATI 0x8760
+#define LOCAL_GL_STATIC_COPY 0x88E6
+#define LOCAL_GL_STATIC_COPY_ARB 0x88E6
+#define LOCAL_GL_STATIC_DRAW 0x88E4
+#define LOCAL_GL_STATIC_DRAW_ARB 0x88E4
+#define LOCAL_GL_STATIC_READ 0x88E5
+#define LOCAL_GL_STATIC_READ_ARB 0x88E5
+#define LOCAL_GL_STATIC_VERTEX_ARRAY_IBM 103061
+#define LOCAL_GL_STENCIL 0x1802
+#define LOCAL_GL_STENCIL_ATTACHMENT 0x8D20
+#define LOCAL_GL_STENCIL_ATTACHMENT_EXT 0x8D20
+#define LOCAL_GL_STENCIL_ATTACHMENT_OES 0x8D20
+#define LOCAL_GL_STENCIL_BACK_FAIL 0x8801
+#define LOCAL_GL_STENCIL_BACK_FAIL_ATI 0x8801
+#define LOCAL_GL_STENCIL_BACK_FUNC 0x8800
+#define LOCAL_GL_STENCIL_BACK_FUNC_ATI 0x8800
+#define LOCAL_GL_STENCIL_BACK_OP_VALUE_AMD 0x874D
+#define LOCAL_GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
+#define LOCAL_GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802
+#define LOCAL_GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
+#define LOCAL_GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803
+#define LOCAL_GL_STENCIL_BACK_REF 0x8CA3
+#define LOCAL_GL_STENCIL_BACK_VALUE_MASK 0x8CA4
+#define LOCAL_GL_STENCIL_BACK_WRITEMASK 0x8CA5
+#define LOCAL_GL_STENCIL_BITS 0x0D57
+#define LOCAL_GL_STENCIL_BUFFER_BIT 0x00000400
+#define LOCAL_GL_STENCIL_BUFFER_BIT0_QCOM 0x00010000
+#define LOCAL_GL_STENCIL_BUFFER_BIT1_QCOM 0x00020000
+#define LOCAL_GL_STENCIL_BUFFER_BIT2_QCOM 0x00040000
+#define LOCAL_GL_STENCIL_BUFFER_BIT3_QCOM 0x00080000
+#define LOCAL_GL_STENCIL_BUFFER_BIT4_QCOM 0x00100000
+#define LOCAL_GL_STENCIL_BUFFER_BIT5_QCOM 0x00200000
+#define LOCAL_GL_STENCIL_BUFFER_BIT6_QCOM 0x00400000
+#define LOCAL_GL_STENCIL_BUFFER_BIT7_QCOM 0x00800000
+#define LOCAL_GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3
+#define LOCAL_GL_STENCIL_CLEAR_VALUE 0x0B91
+#define LOCAL_GL_STENCIL_COMPONENTS 0x8285
+#define LOCAL_GL_STENCIL_EXT 0x1802
+#define LOCAL_GL_STENCIL_FAIL 0x0B94
+#define LOCAL_GL_STENCIL_FUNC 0x0B92
+#define LOCAL_GL_STENCIL_INDEX 0x1901
+#define LOCAL_GL_STENCIL_INDEX1 0x8D46
+#define LOCAL_GL_STENCIL_INDEX16 0x8D49
+#define LOCAL_GL_STENCIL_INDEX16_EXT 0x8D49
+#define LOCAL_GL_STENCIL_INDEX1_EXT 0x8D46
+#define LOCAL_GL_STENCIL_INDEX1_OES 0x8D46
+#define LOCAL_GL_STENCIL_INDEX4 0x8D47
+#define LOCAL_GL_STENCIL_INDEX4_EXT 0x8D47
+#define LOCAL_GL_STENCIL_INDEX4_OES 0x8D47
+#define LOCAL_GL_STENCIL_INDEX8 0x8D48
+#define LOCAL_GL_STENCIL_INDEX8_EXT 0x8D48
+#define LOCAL_GL_STENCIL_INDEX8_OES 0x8D48
+#define LOCAL_GL_STENCIL_OP_VALUE_AMD 0x874C
+#define LOCAL_GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
+#define LOCAL_GL_STENCIL_PASS_DEPTH_PASS 0x0B96
+#define LOCAL_GL_STENCIL_REF 0x0B97
+#define LOCAL_GL_STENCIL_RENDERABLE 0x8288
+#define LOCAL_GL_STENCIL_TAG_BITS_EXT 0x88F2
+#define LOCAL_GL_STENCIL_TEST 0x0B90
+#define LOCAL_GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910
+#define LOCAL_GL_STENCIL_VALUE_MASK 0x0B93
+#define LOCAL_GL_STENCIL_WRITEMASK 0x0B98
+#define LOCAL_GL_STEREO 0x0C33
+#define LOCAL_GL_STORAGE_CACHED_APPLE 0x85BE
+#define LOCAL_GL_STORAGE_CLIENT_APPLE 0x85B4
+#define LOCAL_GL_STORAGE_PRIVATE_APPLE 0x85BD
+#define LOCAL_GL_STORAGE_SHARED_APPLE 0x85BF
+#define LOCAL_GL_STREAM_COPY 0x88E2
+#define LOCAL_GL_STREAM_COPY_ARB 0x88E2
+#define LOCAL_GL_STREAM_DRAW 0x88E0
+#define LOCAL_GL_STREAM_DRAW_ARB 0x88E0
+#define LOCAL_GL_STREAM_READ 0x88E1
+#define LOCAL_GL_STREAM_READ_ARB 0x88E1
+#define LOCAL_GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216
+#define LOCAL_GL_STRICT_LIGHTING_HINT_PGI 0x1A217
+#define LOCAL_GL_STRICT_SCISSOR_HINT_PGI 0x1A218
+#define LOCAL_GL_SUBPIXEL_BITS 0x0D50
+#define LOCAL_GL_SUBSAMPLE_DISTANCE_AMD 0x883F
+#define LOCAL_GL_SUBTRACT 0x84E7
+#define LOCAL_GL_SUBTRACT_ARB 0x84E7
+#define LOCAL_GL_SUB_ATI 0x8965
+#define LOCAL_GL_SUCCESS_NV 0x902F
+#define LOCAL_GL_SURFACE_MAPPED_NV 0x8700
+#define LOCAL_GL_SURFACE_REGISTERED_NV 0x86FD
+#define LOCAL_GL_SURFACE_STATE_NV 0x86EB
+#define LOCAL_GL_SWIZZLE_STQ_ATI 0x8977
+#define LOCAL_GL_SWIZZLE_STQ_DQ_ATI 0x8979
+#define LOCAL_GL_SWIZZLE_STRQ_ATI 0x897A
+#define LOCAL_GL_SWIZZLE_STRQ_DQ_ATI 0x897B
+#define LOCAL_GL_SWIZZLE_STR_ATI 0x8976
+#define LOCAL_GL_SWIZZLE_STR_DR_ATI 0x8978
+#define LOCAL_GL_SYNC_CL_EVENT_ARB 0x8240
+#define LOCAL_GL_SYNC_CL_EVENT_COMPLETE_ARB 0x8241
+#define LOCAL_GL_SYNC_CONDITION 0x9113
+#define LOCAL_GL_SYNC_CONDITION_APPLE 0x9113
+#define LOCAL_GL_SYNC_FENCE 0x9116
+#define LOCAL_GL_SYNC_FENCE_APPLE 0x9116
+#define LOCAL_GL_SYNC_FLAGS 0x9115
+#define LOCAL_GL_SYNC_FLAGS_APPLE 0x9115
+#define LOCAL_GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
+#define LOCAL_GL_SYNC_FLUSH_COMMANDS_BIT_APPLE 0x00000001
+#define LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
+#define LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE 0x9117
+#define LOCAL_GL_SYNC_OBJECT_APPLE 0x8A53
+#define LOCAL_GL_SYNC_STATUS 0x9114
+#define LOCAL_GL_SYNC_STATUS_APPLE 0x9114
+#define LOCAL_GL_SYNC_X11_FENCE_EXT 0x90E1
+#define LOCAL_GL_SYSTEM_FONT_NAME_NV 0x9073
+#define LOCAL_GL_T 0x2001
+#define LOCAL_GL_T2F_C3F_V3F 0x2A2A
+#define LOCAL_GL_T2F_C4F_N3F_V3F 0x2A2C
+#define LOCAL_GL_T2F_C4UB_V3F 0x2A29
+#define LOCAL_GL_T2F_IUI_N3F_V2F_EXT 0x81B3
+#define LOCAL_GL_T2F_IUI_N3F_V3F_EXT 0x81B4
+#define LOCAL_GL_T2F_IUI_V2F_EXT 0x81B1
+#define LOCAL_GL_T2F_IUI_V3F_EXT 0x81B2
+#define LOCAL_GL_T2F_N3F_V3F 0x2A2B
+#define LOCAL_GL_T2F_V3F 0x2A27
+#define LOCAL_GL_T4F_C4F_N3F_V4F 0x2A2D
+#define LOCAL_GL_T4F_V4F 0x2A28
+#define LOCAL_GL_TABLE_TOO_LARGE 0x8031
+#define LOCAL_GL_TABLE_TOO_LARGE_EXT 0x8031
+#define LOCAL_GL_TANGENT_ARRAY_EXT 0x8439
+#define LOCAL_GL_TANGENT_ARRAY_POINTER_EXT 0x8442
+#define LOCAL_GL_TANGENT_ARRAY_STRIDE_EXT 0x843F
+#define LOCAL_GL_TANGENT_ARRAY_TYPE_EXT 0x843E
+#define LOCAL_GL_TESSELLATION_FACTOR_AMD 0x9005
+#define LOCAL_GL_TESSELLATION_MODE_AMD 0x9004
+#define LOCAL_GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75
+#define LOCAL_GL_TESS_CONTROL_PROGRAM_NV 0x891E
+#define LOCAL_GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV 0x8C74
+#define LOCAL_GL_TESS_CONTROL_SHADER 0x8E88
+#define LOCAL_GL_TESS_CONTROL_SHADER_BIT 0x00000008
+#define LOCAL_GL_TESS_CONTROL_SUBROUTINE 0x92E9
+#define LOCAL_GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF
+#define LOCAL_GL_TESS_CONTROL_TEXTURE 0x829C
+#define LOCAL_GL_TESS_EVALUATION_PROGRAM_NV 0x891F
+#define LOCAL_GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV 0x8C75
+#define LOCAL_GL_TESS_EVALUATION_SHADER 0x8E87
+#define LOCAL_GL_TESS_EVALUATION_SHADER_BIT 0x00000010
+#define LOCAL_GL_TESS_EVALUATION_SUBROUTINE 0x92EA
+#define LOCAL_GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0
+#define LOCAL_GL_TESS_EVALUATION_TEXTURE 0x829D
+#define LOCAL_GL_TESS_GEN_MODE 0x8E76
+#define LOCAL_GL_TESS_GEN_POINT_MODE 0x8E79
+#define LOCAL_GL_TESS_GEN_SPACING 0x8E77
+#define LOCAL_GL_TESS_GEN_VERTEX_ORDER 0x8E78
+#define LOCAL_GL_TEXCOORD1_BIT_PGI 0x10000000
+#define LOCAL_GL_TEXCOORD2_BIT_PGI 0x20000000
+#define LOCAL_GL_TEXCOORD3_BIT_PGI 0x40000000
+#define LOCAL_GL_TEXCOORD4_BIT_PGI 0x80000000
+#define LOCAL_GL_TEXTURE 0x1702
+#define LOCAL_GL_TEXTURE0 0x84C0
+#define LOCAL_GL_TEXTURE0_ARB 0x84C0
+#define LOCAL_GL_TEXTURE1 0x84C1
+#define LOCAL_GL_TEXTURE10 0x84CA
+#define LOCAL_GL_TEXTURE10_ARB 0x84CA
+#define LOCAL_GL_TEXTURE11 0x84CB
+#define LOCAL_GL_TEXTURE11_ARB 0x84CB
+#define LOCAL_GL_TEXTURE12 0x84CC
+#define LOCAL_GL_TEXTURE12_ARB 0x84CC
+#define LOCAL_GL_TEXTURE13 0x84CD
+#define LOCAL_GL_TEXTURE13_ARB 0x84CD
+#define LOCAL_GL_TEXTURE14 0x84CE
+#define LOCAL_GL_TEXTURE14_ARB 0x84CE
+#define LOCAL_GL_TEXTURE15 0x84CF
+#define LOCAL_GL_TEXTURE15_ARB 0x84CF
+#define LOCAL_GL_TEXTURE16 0x84D0
+#define LOCAL_GL_TEXTURE16_ARB 0x84D0
+#define LOCAL_GL_TEXTURE17 0x84D1
+#define LOCAL_GL_TEXTURE17_ARB 0x84D1
+#define LOCAL_GL_TEXTURE18 0x84D2
+#define LOCAL_GL_TEXTURE18_ARB 0x84D2
+#define LOCAL_GL_TEXTURE19 0x84D3
+#define LOCAL_GL_TEXTURE19_ARB 0x84D3
+#define LOCAL_GL_TEXTURE1_ARB 0x84C1
+#define LOCAL_GL_TEXTURE2 0x84C2
+#define LOCAL_GL_TEXTURE20 0x84D4
+#define LOCAL_GL_TEXTURE20_ARB 0x84D4
+#define LOCAL_GL_TEXTURE21 0x84D5
+#define LOCAL_GL_TEXTURE21_ARB 0x84D5
+#define LOCAL_GL_TEXTURE22 0x84D6
+#define LOCAL_GL_TEXTURE22_ARB 0x84D6
+#define LOCAL_GL_TEXTURE23 0x84D7
+#define LOCAL_GL_TEXTURE23_ARB 0x84D7
+#define LOCAL_GL_TEXTURE24 0x84D8
+#define LOCAL_GL_TEXTURE24_ARB 0x84D8
+#define LOCAL_GL_TEXTURE25 0x84D9
+#define LOCAL_GL_TEXTURE25_ARB 0x84D9
+#define LOCAL_GL_TEXTURE26 0x84DA
+#define LOCAL_GL_TEXTURE26_ARB 0x84DA
+#define LOCAL_GL_TEXTURE27 0x84DB
+#define LOCAL_GL_TEXTURE27_ARB 0x84DB
+#define LOCAL_GL_TEXTURE28 0x84DC
+#define LOCAL_GL_TEXTURE28_ARB 0x84DC
+#define LOCAL_GL_TEXTURE29 0x84DD
+#define LOCAL_GL_TEXTURE29_ARB 0x84DD
+#define LOCAL_GL_TEXTURE2_ARB 0x84C2
+#define LOCAL_GL_TEXTURE3 0x84C3
+#define LOCAL_GL_TEXTURE30 0x84DE
+#define LOCAL_GL_TEXTURE30_ARB 0x84DE
+#define LOCAL_GL_TEXTURE31 0x84DF
+#define LOCAL_GL_TEXTURE31_ARB 0x84DF
+#define LOCAL_GL_TEXTURE3_ARB 0x84C3
+#define LOCAL_GL_TEXTURE4 0x84C4
+#define LOCAL_GL_TEXTURE4_ARB 0x84C4
+#define LOCAL_GL_TEXTURE5 0x84C5
+#define LOCAL_GL_TEXTURE5_ARB 0x84C5
+#define LOCAL_GL_TEXTURE6 0x84C6
+#define LOCAL_GL_TEXTURE6_ARB 0x84C6
+#define LOCAL_GL_TEXTURE7 0x84C7
+#define LOCAL_GL_TEXTURE7_ARB 0x84C7
+#define LOCAL_GL_TEXTURE8 0x84C8
+#define LOCAL_GL_TEXTURE8_ARB 0x84C8
+#define LOCAL_GL_TEXTURE9 0x84C9
+#define LOCAL_GL_TEXTURE9_ARB 0x84C9
+#define LOCAL_GL_TEXTURE_1D 0x0DE0
+#define LOCAL_GL_TEXTURE_1D_ARRAY 0x8C18
+#define LOCAL_GL_TEXTURE_1D_ARRAY_EXT 0x8C18
+#define LOCAL_GL_TEXTURE_1D_BINDING_EXT 0x8068
+#define LOCAL_GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D
+#define LOCAL_GL_TEXTURE_1D_STACK_MESAX 0x8759
+#define LOCAL_GL_TEXTURE_2D 0x0DE1
+#define LOCAL_GL_TEXTURE_2D_ARRAY 0x8C1A
+#define LOCAL_GL_TEXTURE_2D_ARRAY_EXT 0x8C1A
+#define LOCAL_GL_TEXTURE_2D_BINDING_EXT 0x8069
+#define LOCAL_GL_TEXTURE_2D_MULTISAMPLE 0x9100
+#define LOCAL_GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
+#define LOCAL_GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E
+#define LOCAL_GL_TEXTURE_2D_STACK_MESAX 0x875A
+#define LOCAL_GL_TEXTURE_3D 0x806F
+#define LOCAL_GL_TEXTURE_3D_BINDING_EXT 0x806A
+#define LOCAL_GL_TEXTURE_3D_BINDING_OES 0x806A
+#define LOCAL_GL_TEXTURE_3D_EXT 0x806F
+#define LOCAL_GL_TEXTURE_3D_OES 0x806F
+#define LOCAL_GL_TEXTURE_4DSIZE_SGIS 0x8136
+#define LOCAL_GL_TEXTURE_4D_BINDING_SGIS 0x814F
+#define LOCAL_GL_TEXTURE_4D_SGIS 0x8134
+#define LOCAL_GL_TEXTURE_ALPHA_MODULATE_IMG 0x8C06
+#define LOCAL_GL_TEXTURE_ALPHA_SIZE 0x805F
+#define LOCAL_GL_TEXTURE_ALPHA_SIZE_EXT 0x805F
+#define LOCAL_GL_TEXTURE_ALPHA_TYPE 0x8C13
+#define LOCAL_GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13
+#define LOCAL_GL_TEXTURE_APPLICATION_MODE_EXT 0x834F
+#define LOCAL_GL_TEXTURE_BASE_LEVEL 0x813C
+#define LOCAL_GL_TEXTURE_BASE_LEVEL_SGIS 0x813C
+#define LOCAL_GL_TEXTURE_BINDING_1D 0x8068
+#define LOCAL_GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C
+#define LOCAL_GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C
+#define LOCAL_GL_TEXTURE_BINDING_2D 0x8069
+#define LOCAL_GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D
+#define LOCAL_GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D
+#define LOCAL_GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104
+#define LOCAL_GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105
+#define LOCAL_GL_TEXTURE_BINDING_3D 0x806A
+#define LOCAL_GL_TEXTURE_BINDING_3D_OES 0x806A
+#define LOCAL_GL_TEXTURE_BINDING_BUFFER 0x8C2C
+#define LOCAL_GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C
+#define LOCAL_GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C
+#define LOCAL_GL_TEXTURE_BINDING_CUBE_MAP 0x8514
+#define LOCAL_GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514
+#define LOCAL_GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A
+#define LOCAL_GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A
+#define LOCAL_GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514
+#define LOCAL_GL_TEXTURE_BINDING_CUBE_MAP_OES 0x8514
+#define LOCAL_GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67
+#define LOCAL_GL_TEXTURE_BINDING_RECTANGLE 0x84F6
+#define LOCAL_GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6
+#define LOCAL_GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6
+#define LOCAL_GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53
+#define LOCAL_GL_TEXTURE_BIT 0x00040000
+#define LOCAL_GL_TEXTURE_BLUE_SIZE 0x805E
+#define LOCAL_GL_TEXTURE_BLUE_SIZE_EXT 0x805E
+#define LOCAL_GL_TEXTURE_BLUE_TYPE 0x8C12
+#define LOCAL_GL_TEXTURE_BLUE_TYPE_ARB 0x8C12
+#define LOCAL_GL_TEXTURE_BORDER 0x1005
+#define LOCAL_GL_TEXTURE_BORDER_COLOR 0x1004
+#define LOCAL_GL_TEXTURE_BORDER_COLOR_NV 0x1004
+#define LOCAL_GL_TEXTURE_BORDER_VALUES_NV 0x871A
+#define LOCAL_GL_TEXTURE_BUFFER 0x8C2A
+#define LOCAL_GL_TEXTURE_BUFFER_ARB 0x8C2A
+#define LOCAL_GL_TEXTURE_BUFFER_BINDING 0x8C2A
+#define LOCAL_GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D
+#define LOCAL_GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D
+#define LOCAL_GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D
+#define LOCAL_GL_TEXTURE_BUFFER_EXT 0x8C2A
+#define LOCAL_GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E
+#define LOCAL_GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E
+#define LOCAL_GL_TEXTURE_BUFFER_OFFSET 0x919D
+#define LOCAL_GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F
+#define LOCAL_GL_TEXTURE_BUFFER_SIZE 0x919E
+#define LOCAL_GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171
+#define LOCAL_GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176
+#define LOCAL_GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172
+#define LOCAL_GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175
+#define LOCAL_GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173
+#define LOCAL_GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174
+#define LOCAL_GL_TEXTURE_COLOR_SAMPLES_NV 0x9046
+#define LOCAL_GL_TEXTURE_COLOR_TABLE_SGI 0x80BC
+#define LOCAL_GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF
+#define LOCAL_GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF
+#define LOCAL_GL_TEXTURE_COMPARE_FUNC 0x884D
+#define LOCAL_GL_TEXTURE_COMPARE_FUNC_ARB 0x884D
+#define LOCAL_GL_TEXTURE_COMPARE_FUNC_EXT 0x884D
+#define LOCAL_GL_TEXTURE_COMPARE_MODE 0x884C
+#define LOCAL_GL_TEXTURE_COMPARE_MODE_ARB 0x884C
+#define LOCAL_GL_TEXTURE_COMPARE_MODE_EXT 0x884C
+#define LOCAL_GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B
+#define LOCAL_GL_TEXTURE_COMPARE_SGIX 0x819A
+#define LOCAL_GL_TEXTURE_COMPONENTS 0x1003
+#define LOCAL_GL_TEXTURE_COMPRESSED 0x86A1
+#define LOCAL_GL_TEXTURE_COMPRESSED_ARB 0x86A1
+#define LOCAL_GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2
+#define LOCAL_GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3
+#define LOCAL_GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1
+#define LOCAL_GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0
+#define LOCAL_GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0
+#define LOCAL_GL_TEXTURE_COMPRESSION_HINT 0x84EF
+#define LOCAL_GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF
+#define LOCAL_GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6
+#define LOCAL_GL_TEXTURE_COORD_ARRAY 0x8078
+#define LOCAL_GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25
+#define LOCAL_GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A
+#define LOCAL_GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A
+#define LOCAL_GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B
+#define LOCAL_GL_TEXTURE_COORD_ARRAY_EXT 0x8078
+#define LOCAL_GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F
+#define LOCAL_GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074
+#define LOCAL_GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084
+#define LOCAL_GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8
+#define LOCAL_GL_TEXTURE_COORD_ARRAY_POINTER 0x8092
+#define LOCAL_GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092
+#define LOCAL_GL_TEXTURE_COORD_ARRAY_SIZE 0x8088
+#define LOCAL_GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088
+#define LOCAL_GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A
+#define LOCAL_GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A
+#define LOCAL_GL_TEXTURE_COORD_ARRAY_TYPE 0x8089
+#define LOCAL_GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089
+#define LOCAL_GL_TEXTURE_COORD_NV 0x8C79
+#define LOCAL_GL_TEXTURE_COVERAGE_SAMPLES_NV 0x9045
+#define LOCAL_GL_TEXTURE_CROP_RECT_OES 0x8B9D
+#define LOCAL_GL_TEXTURE_CUBE_MAP 0x8513
+#define LOCAL_GL_TEXTURE_CUBE_MAP_ARB 0x8513
+#define LOCAL_GL_TEXTURE_CUBE_MAP_ARRAY 0x9009
+#define LOCAL_GL_TEXTURE_CUBE_MAP_ARRAY_ARB 0x9009
+#define LOCAL_GL_TEXTURE_CUBE_MAP_EXT 0x8513
+#define LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+#define LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516
+#define LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516
+#define LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES 0x8516
+#define LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+#define LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518
+#define LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518
+#define LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES 0x8518
+#define LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#define LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A
+#define LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A
+#define LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES 0x851A
+#define LOCAL_GL_TEXTURE_CUBE_MAP_OES 0x8513
+#define LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+#define LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515
+#define LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515
+#define LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES 0x8515
+#define LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+#define LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517
+#define LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517
+#define LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES 0x8517
+#define LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+#define LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519
+#define LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519
+#define LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES 0x8519
+#define LOCAL_GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F
+#define LOCAL_GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001
+#define LOCAL_GL_TEXTURE_DEFORMATION_SGIX 0x8195
+#define LOCAL_GL_TEXTURE_DEPTH 0x8071
+#define LOCAL_GL_TEXTURE_DEPTH_EXT 0x8071
+#define LOCAL_GL_TEXTURE_DEPTH_QCOM 0x8BD4
+#define LOCAL_GL_TEXTURE_DEPTH_SIZE 0x884A
+#define LOCAL_GL_TEXTURE_DEPTH_SIZE_ARB 0x884A
+#define LOCAL_GL_TEXTURE_DEPTH_TYPE 0x8C16
+#define LOCAL_GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16
+#define LOCAL_GL_TEXTURE_DS_SIZE_NV 0x871D
+#define LOCAL_GL_TEXTURE_DT_SIZE_NV 0x871E
+#define LOCAL_GL_TEXTURE_ENV 0x2300
+#define LOCAL_GL_TEXTURE_ENV_BIAS_SGIX 0x80BE
+#define LOCAL_GL_TEXTURE_ENV_COLOR 0x2201
+#define LOCAL_GL_TEXTURE_ENV_MODE 0x2200
+#define LOCAL_GL_TEXTURE_EXTERNAL_OES 0x8D65
+#define LOCAL_GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008
+#define LOCAL_GL_TEXTURE_FETCH_BARRIER_BIT_EXT 0x00000008
+#define LOCAL_GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147
+#define LOCAL_GL_TEXTURE_FILTER_CONTROL 0x8500
+#define LOCAL_GL_TEXTURE_FILTER_CONTROL_EXT 0x8500
+#define LOCAL_GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107
+#define LOCAL_GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C
+#define LOCAL_GL_TEXTURE_FORMAT_QCOM 0x8BD6
+#define LOCAL_GL_TEXTURE_FREE_MEMORY_ATI 0x87FC
+#define LOCAL_GL_TEXTURE_GATHER 0x82A2
+#define LOCAL_GL_TEXTURE_GATHER_SHADOW 0x82A3
+#define LOCAL_GL_TEXTURE_GEN_MODE 0x2500
+#define LOCAL_GL_TEXTURE_GEN_MODE_OES 0x2500
+#define LOCAL_GL_TEXTURE_GEN_Q 0x0C63
+#define LOCAL_GL_TEXTURE_GEN_R 0x0C62
+#define LOCAL_GL_TEXTURE_GEN_S 0x0C60
+#define LOCAL_GL_TEXTURE_GEN_STR_OES 0x8D60
+#define LOCAL_GL_TEXTURE_GEN_T 0x0C61
+#define LOCAL_GL_TEXTURE_GEQUAL_R_SGIX 0x819D
+#define LOCAL_GL_TEXTURE_GREEN_SIZE 0x805D
+#define LOCAL_GL_TEXTURE_GREEN_SIZE_EXT 0x805D
+#define LOCAL_GL_TEXTURE_GREEN_TYPE 0x8C11
+#define LOCAL_GL_TEXTURE_GREEN_TYPE_ARB 0x8C11
+#define LOCAL_GL_TEXTURE_HEIGHT 0x1001
+#define LOCAL_GL_TEXTURE_HEIGHT_QCOM 0x8BD3
+#define LOCAL_GL_TEXTURE_HI_SIZE_NV 0x871B
+#define LOCAL_GL_TEXTURE_IMAGE_FORMAT 0x828F
+#define LOCAL_GL_TEXTURE_IMAGE_TYPE 0x8290
+#define LOCAL_GL_TEXTURE_IMAGE_VALID_QCOM 0x8BD8
+#define LOCAL_GL_TEXTURE_IMMUTABLE_FORMAT 0x912F
+#define LOCAL_GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F
+#define LOCAL_GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
+#define LOCAL_GL_TEXTURE_INDEX_SIZE_EXT 0x80ED
+#define LOCAL_GL_TEXTURE_INTENSITY_SIZE 0x8061
+#define LOCAL_GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061
+#define LOCAL_GL_TEXTURE_INTENSITY_TYPE 0x8C15
+#define LOCAL_GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15
+#define LOCAL_GL_TEXTURE_INTERNAL_FORMAT 0x1003
+#define LOCAL_GL_TEXTURE_INTERNAL_FORMAT_QCOM 0x8BD5
+#define LOCAL_GL_TEXTURE_LEQUAL_R_SGIX 0x819C
+#define LOCAL_GL_TEXTURE_LIGHTING_MODE_HP 0x8167
+#define LOCAL_GL_TEXTURE_LIGHT_EXT 0x8350
+#define LOCAL_GL_TEXTURE_LOD_BIAS 0x8501
+#define LOCAL_GL_TEXTURE_LOD_BIAS_EXT 0x8501
+#define LOCAL_GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190
+#define LOCAL_GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E
+#define LOCAL_GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F
+#define LOCAL_GL_TEXTURE_LO_SIZE_NV 0x871C
+#define LOCAL_GL_TEXTURE_LUMINANCE_SIZE 0x8060
+#define LOCAL_GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060
+#define LOCAL_GL_TEXTURE_LUMINANCE_TYPE 0x8C14
+#define LOCAL_GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14
+#define LOCAL_GL_TEXTURE_MAG_FILTER 0x2800
+#define LOCAL_GL_TEXTURE_MAG_SIZE_NV 0x871F
+#define LOCAL_GL_TEXTURE_MATERIAL_FACE_EXT 0x8351
+#define LOCAL_GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352
+#define LOCAL_GL_TEXTURE_MATRIX 0x0BA8
+#define LOCAL_GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES 0x898F
+#define LOCAL_GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
+#define LOCAL_GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B
+#define LOCAL_GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369
+#define LOCAL_GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A
+#define LOCAL_GL_TEXTURE_MAX_LEVEL 0x813D
+#define LOCAL_GL_TEXTURE_MAX_LEVEL_APPLE 0x813D
+#define LOCAL_GL_TEXTURE_MAX_LEVEL_SGIS 0x813D
+#define LOCAL_GL_TEXTURE_MAX_LOD 0x813B
+#define LOCAL_GL_TEXTURE_MAX_LOD_SGIS 0x813B
+#define LOCAL_GL_TEXTURE_MEMORY_LAYOUT_INTEL 0x83FF
+#define LOCAL_GL_TEXTURE_MIN_FILTER 0x2801
+#define LOCAL_GL_TEXTURE_MIN_LOD 0x813A
+#define LOCAL_GL_TEXTURE_MIN_LOD_SGIS 0x813A
+#define LOCAL_GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E
+#define LOCAL_GL_TEXTURE_NORMAL_EXT 0x85AF
+#define LOCAL_GL_TEXTURE_NUM_LEVELS_QCOM 0x8BD9
+#define LOCAL_GL_TEXTURE_OBJECT_VALID_QCOM 0x8BDB
+#define LOCAL_GL_TEXTURE_POST_SPECULAR_HP 0x8168
+#define LOCAL_GL_TEXTURE_PRE_SPECULAR_HP 0x8169
+#define LOCAL_GL_TEXTURE_PRIORITY 0x8066
+#define LOCAL_GL_TEXTURE_PRIORITY_EXT 0x8066
+#define LOCAL_GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7
+#define LOCAL_GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8
+#define LOCAL_GL_TEXTURE_RECTANGLE 0x84F5
+#define LOCAL_GL_TEXTURE_RECTANGLE_ARB 0x84F5
+#define LOCAL_GL_TEXTURE_RECTANGLE_NV 0x84F5
+#define LOCAL_GL_TEXTURE_RED_SIZE 0x805C
+#define LOCAL_GL_TEXTURE_RED_SIZE_EXT 0x805C
+#define LOCAL_GL_TEXTURE_RED_TYPE 0x8C10
+#define LOCAL_GL_TEXTURE_RED_TYPE_ARB 0x8C10
+#define LOCAL_GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54
+#define LOCAL_GL_TEXTURE_RENDERBUFFER_NV 0x8E55
+#define LOCAL_GL_TEXTURE_RESIDENT 0x8067
+#define LOCAL_GL_TEXTURE_RESIDENT_EXT 0x8067
+#define LOCAL_GL_TEXTURE_SAMPLES 0x9106
+#define LOCAL_GL_TEXTURE_SAMPLES_IMG 0x9136
+#define LOCAL_GL_TEXTURE_SHADER_NV 0x86DE
+#define LOCAL_GL_TEXTURE_SHADOW 0x82A1
+#define LOCAL_GL_TEXTURE_SHARED_SIZE 0x8C3F
+#define LOCAL_GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F
+#define LOCAL_GL_TEXTURE_SPARSE_ARB 0x91A6
+#define LOCAL_GL_TEXTURE_SRGB_DECODE_EXT 0x8A48
+#define LOCAL_GL_TEXTURE_STACK_DEPTH 0x0BA5
+#define LOCAL_GL_TEXTURE_STENCIL_SIZE 0x88F1
+#define LOCAL_GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1
+#define LOCAL_GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC
+#define LOCAL_GL_TEXTURE_STORAGE_SPARSE_BIT_AMD 0x00000001
+#define LOCAL_GL_TEXTURE_SWIZZLE_A 0x8E45
+#define LOCAL_GL_TEXTURE_SWIZZLE_A_EXT 0x8E45
+#define LOCAL_GL_TEXTURE_SWIZZLE_B 0x8E44
+#define LOCAL_GL_TEXTURE_SWIZZLE_B_EXT 0x8E44
+#define LOCAL_GL_TEXTURE_SWIZZLE_G 0x8E43
+#define LOCAL_GL_TEXTURE_SWIZZLE_G_EXT 0x8E43
+#define LOCAL_GL_TEXTURE_SWIZZLE_R 0x8E42
+#define LOCAL_GL_TEXTURE_SWIZZLE_RGBA 0x8E46
+#define LOCAL_GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46
+#define LOCAL_GL_TEXTURE_SWIZZLE_R_EXT 0x8E42
+#define LOCAL_GL_TEXTURE_TARGET_QCOM 0x8BDA
+#define LOCAL_GL_TEXTURE_TOO_LARGE_EXT 0x8065
+#define LOCAL_GL_TEXTURE_TYPE_QCOM 0x8BD7
+#define LOCAL_GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F
+#define LOCAL_GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100
+#define LOCAL_GL_TEXTURE_UPDATE_BARRIER_BIT_EXT 0x00000100
+#define LOCAL_GL_TEXTURE_USAGE_ANGLE 0x93A2
+#define LOCAL_GL_TEXTURE_VIEW 0x82B5
+#define LOCAL_GL_TEXTURE_VIEW_MIN_LAYER 0x82DD
+#define LOCAL_GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB
+#define LOCAL_GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE
+#define LOCAL_GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC
+#define LOCAL_GL_TEXTURE_WIDTH 0x1000
+#define LOCAL_GL_TEXTURE_WIDTH_QCOM 0x8BD2
+#define LOCAL_GL_TEXTURE_WRAP_Q_SGIS 0x8137
+#define LOCAL_GL_TEXTURE_WRAP_R 0x8072
+#define LOCAL_GL_TEXTURE_WRAP_R_EXT 0x8072
+#define LOCAL_GL_TEXTURE_WRAP_R_OES 0x8072
+#define LOCAL_GL_TEXTURE_WRAP_S 0x2802
+#define LOCAL_GL_TEXTURE_WRAP_T 0x2803
+#define LOCAL_GL_TEXT_FRAGMENT_SHADER_ATI 0x8200
+#define LOCAL_GL_TIMEOUT_EXPIRED 0x911B
+#define LOCAL_GL_TIMEOUT_EXPIRED_APPLE 0x911B
+#define LOCAL_GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF
+#define LOCAL_GL_TIMEOUT_IGNORED_APPLE 0xFFFFFFFFFFFFFFFF
+#define LOCAL_GL_TIMESTAMP 0x8E28
+#define LOCAL_GL_TIMESTAMP_EXT 0x8E28
+#define LOCAL_GL_TIME_ELAPSED 0x88BF
+#define LOCAL_GL_TIME_ELAPSED_EXT 0x88BF
+#define LOCAL_GL_TOP_LEVEL_ARRAY_SIZE 0x930C
+#define LOCAL_GL_TOP_LEVEL_ARRAY_STRIDE 0x930D
+#define LOCAL_GL_TRACE_ALL_BITS_MESA 0xFFFF
+#define LOCAL_GL_TRACE_ARRAYS_BIT_MESA 0x0004
+#define LOCAL_GL_TRACE_ERRORS_BIT_MESA 0x0020
+#define LOCAL_GL_TRACE_MASK_MESA 0x8755
+#define LOCAL_GL_TRACE_NAME_MESA 0x8756
+#define LOCAL_GL_TRACE_OPERATIONS_BIT_MESA 0x0001
+#define LOCAL_GL_TRACE_PIXELS_BIT_MESA 0x0010
+#define LOCAL_GL_TRACE_PRIMITIVES_BIT_MESA 0x0002
+#define LOCAL_GL_TRACE_TEXTURES_BIT_MESA 0x0008
+#define LOCAL_GL_TRACK_MATRIX_NV 0x8648
+#define LOCAL_GL_TRACK_MATRIX_TRANSFORM_NV 0x8649
+#define LOCAL_GL_TRANSFORM_BIT 0x00001000
+#define LOCAL_GL_TRANSFORM_FEEDBACK 0x8E22
+#define LOCAL_GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24
+#define LOCAL_GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E
+#define LOCAL_GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800
+#define LOCAL_GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT 0x00000800
+#define LOCAL_GL_TRANSFORM_FEEDBACK_BINDING 0x8E25
+#define LOCAL_GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25
+#define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E
+#define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24
+#define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24
+#define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F
+#define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F
+#define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F
+#define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E
+#define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B
+#define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F
+#define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F
+#define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F
+#define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E
+#define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23
+#define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23
+#define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85
+#define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85
+#define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85
+#define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84
+#define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84
+#define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84
+#define LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C
+#define LOCAL_GL_TRANSFORM_FEEDBACK_NV 0x8E22
+#define LOCAL_GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23
+#define LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88
+#define LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88
+#define LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88
+#define LOCAL_GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86
+#define LOCAL_GL_TRANSFORM_FEEDBACK_VARYING 0x92F4
+#define LOCAL_GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83
+#define LOCAL_GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83
+#define LOCAL_GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83
+#define LOCAL_GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76
+#define LOCAL_GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76
+#define LOCAL_GL_TRANSFORM_HINT_APPLE 0x85B1
+#define LOCAL_GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0
+#define LOCAL_GL_TRANSLATE_2D_NV 0x9090
+#define LOCAL_GL_TRANSLATE_3D_NV 0x9091
+#define LOCAL_GL_TRANSLATE_X_NV 0x908E
+#define LOCAL_GL_TRANSLATE_Y_NV 0x908F
+#define LOCAL_GL_TRANSPOSE_AFFINE_2D_NV 0x9096
+#define LOCAL_GL_TRANSPOSE_AFFINE_3D_NV 0x9098
+#define LOCAL_GL_TRANSPOSE_COLOR_MATRIX 0x84E6
+#define LOCAL_GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6
+#define LOCAL_GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7
+#define LOCAL_GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3
+#define LOCAL_GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3
+#define LOCAL_GL_TRANSPOSE_NV 0x862C
+#define LOCAL_GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E
+#define LOCAL_GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4
+#define LOCAL_GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4
+#define LOCAL_GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5
+#define LOCAL_GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5
+#define LOCAL_GL_TRIANGLES 0x0004
+#define LOCAL_GL_TRIANGLES_ADJACENCY 0x000C
+#define LOCAL_GL_TRIANGLES_ADJACENCY_ARB 0x000C
+#define LOCAL_GL_TRIANGLES_ADJACENCY_EXT 0x000C
+#define LOCAL_GL_TRIANGLE_FAN 0x0006
+#define LOCAL_GL_TRIANGLE_LIST_SUN 0x81D7
+#define LOCAL_GL_TRIANGLE_MESH_SUN 0x8615
+#define LOCAL_GL_TRIANGLE_STRIP 0x0005
+#define LOCAL_GL_TRIANGLE_STRIP_ADJACENCY 0x000D
+#define LOCAL_GL_TRIANGLE_STRIP_ADJACENCY_ARB 0x000D
+#define LOCAL_GL_TRIANGLE_STRIP_ADJACENCY_EXT 0x000D
+#define LOCAL_GL_TRIANGULAR_NV 0x90A5
+#define LOCAL_GL_TRUE 1
+#define LOCAL_GL_TYPE 0x92FA
+#define LOCAL_GL_UNCORRELATED_NV 0x9282
+#define LOCAL_GL_UNDEFINED_APPLE 0x8A1C
+#define LOCAL_GL_UNDEFINED_VERTEX 0x8260
+#define LOCAL_GL_UNIFORM 0x92E1
+#define LOCAL_GL_UNIFORM_ARRAY_STRIDE 0x8A3C
+#define LOCAL_GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA
+#define LOCAL_GL_UNIFORM_BARRIER_BIT 0x00000004
+#define LOCAL_GL_UNIFORM_BARRIER_BIT_EXT 0x00000004
+#define LOCAL_GL_UNIFORM_BLOCK 0x92E2
+#define LOCAL_GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42
+#define LOCAL_GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43
+#define LOCAL_GL_UNIFORM_BLOCK_BINDING 0x8A3F
+#define LOCAL_GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40
+#define LOCAL_GL_UNIFORM_BLOCK_INDEX 0x8A3A
+#define LOCAL_GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41
+#define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC
+#define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
+#define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45
+#define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0
+#define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1
+#define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44
+#define LOCAL_GL_UNIFORM_BUFFER 0x8A11
+#define LOCAL_GL_UNIFORM_BUFFER_BINDING 0x8A28
+#define LOCAL_GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF
+#define LOCAL_GL_UNIFORM_BUFFER_EXT 0x8DEE
+#define LOCAL_GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34
+#define LOCAL_GL_UNIFORM_BUFFER_SIZE 0x8A2A
+#define LOCAL_GL_UNIFORM_BUFFER_START 0x8A29
+#define LOCAL_GL_UNIFORM_IS_ROW_MAJOR 0x8A3E
+#define LOCAL_GL_UNIFORM_MATRIX_STRIDE 0x8A3D
+#define LOCAL_GL_UNIFORM_NAME_LENGTH 0x8A39
+#define LOCAL_GL_UNIFORM_OFFSET 0x8A3B
+#define LOCAL_GL_UNIFORM_SIZE 0x8A38
+#define LOCAL_GL_UNIFORM_TYPE 0x8A37
+#define LOCAL_GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255
+#define LOCAL_GL_UNKNOWN_CONTEXT_RESET_EXT 0x8255
+#define LOCAL_GL_UNPACK_ALIGNMENT 0x0CF5
+#define LOCAL_GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2
+#define LOCAL_GL_UNPACK_CMYK_HINT_EXT 0x800F
+#define LOCAL_GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129
+#define LOCAL_GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128
+#define LOCAL_GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A
+#define LOCAL_GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127
+#define LOCAL_GL_UNPACK_COMPRESSED_SIZE_SGIX 0x831A
+#define LOCAL_GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5
+#define LOCAL_GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133
+#define LOCAL_GL_UNPACK_IMAGE_HEIGHT 0x806E
+#define LOCAL_GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E
+#define LOCAL_GL_UNPACK_LSB_FIRST 0x0CF1
+#define LOCAL_GL_UNPACK_RESAMPLE_OML 0x8985
+#define LOCAL_GL_UNPACK_RESAMPLE_SGIX 0x842D
+#define LOCAL_GL_UNPACK_ROW_BYTES_APPLE 0x8A16
+#define LOCAL_GL_UNPACK_ROW_LENGTH 0x0CF2
+#define LOCAL_GL_UNPACK_ROW_LENGTH_EXT 0x0CF2
+#define LOCAL_GL_UNPACK_SKIP_IMAGES 0x806D
+#define LOCAL_GL_UNPACK_SKIP_IMAGES_EXT 0x806D
+#define LOCAL_GL_UNPACK_SKIP_PIXELS 0x0CF4
+#define LOCAL_GL_UNPACK_SKIP_PIXELS_EXT 0x0CF4
+#define LOCAL_GL_UNPACK_SKIP_ROWS 0x0CF3
+#define LOCAL_GL_UNPACK_SKIP_ROWS_EXT 0x0CF3
+#define LOCAL_GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132
+#define LOCAL_GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1
+#define LOCAL_GL_UNPACK_SWAP_BYTES 0x0CF0
+#define LOCAL_GL_UNSIGNALED 0x9118
+#define LOCAL_GL_UNSIGNALED_APPLE 0x9118
+#define LOCAL_GL_UNSIGNED_BYTE 0x1401
+#define LOCAL_GL_UNSIGNED_BYTE_2_3_3_REV 0x8362
+#define LOCAL_GL_UNSIGNED_BYTE_2_3_3_REV_EXT 0x8362
+#define LOCAL_GL_UNSIGNED_BYTE_3_3_2 0x8032
+#define LOCAL_GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032
+#define LOCAL_GL_UNSIGNED_IDENTITY_NV 0x8536
+#define LOCAL_GL_UNSIGNED_INT 0x1405
+#define LOCAL_GL_UNSIGNED_INT16_NV 0x8FF0
+#define LOCAL_GL_UNSIGNED_INT16_VEC2_NV 0x8FF1
+#define LOCAL_GL_UNSIGNED_INT16_VEC3_NV 0x8FF2
+#define LOCAL_GL_UNSIGNED_INT16_VEC4_NV 0x8FF3
+#define LOCAL_GL_UNSIGNED_INT64_AMD 0x8BC2
+#define LOCAL_GL_UNSIGNED_INT64_ARB 0x140F
+#define LOCAL_GL_UNSIGNED_INT64_NV 0x140F
+#define LOCAL_GL_UNSIGNED_INT64_VEC2_NV 0x8FF5
+#define LOCAL_GL_UNSIGNED_INT64_VEC3_NV 0x8FF6
+#define LOCAL_GL_UNSIGNED_INT64_VEC4_NV 0x8FF7
+#define LOCAL_GL_UNSIGNED_INT8_NV 0x8FEC
+#define LOCAL_GL_UNSIGNED_INT8_VEC2_NV 0x8FED
+#define LOCAL_GL_UNSIGNED_INT8_VEC3_NV 0x8FEE
+#define LOCAL_GL_UNSIGNED_INT8_VEC4_NV 0x8FEF
+#define LOCAL_GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
+#define LOCAL_GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B
+#define LOCAL_GL_UNSIGNED_INT_10_10_10_2 0x8036
+#define LOCAL_GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036
+#define LOCAL_GL_UNSIGNED_INT_10_10_10_2_OES 0x8DF6
+#define LOCAL_GL_UNSIGNED_INT_24_8 0x84FA
+#define LOCAL_GL_UNSIGNED_INT_24_8_EXT 0x84FA
+#define LOCAL_GL_UNSIGNED_INT_24_8_MESA 0x8751
+#define LOCAL_GL_UNSIGNED_INT_24_8_NV 0x84FA
+#define LOCAL_GL_UNSIGNED_INT_24_8_OES 0x84FA
+#define LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#define LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368
+#define LOCAL_GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E
+#define LOCAL_GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E
+#define LOCAL_GL_UNSIGNED_INT_8_24_REV_MESA 0x8752
+#define LOCAL_GL_UNSIGNED_INT_8_8_8_8 0x8035
+#define LOCAL_GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035
+#define LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
+#define LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV_EXT 0x8367
+#define LOCAL_GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB
+#define LOCAL_GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB
+#define LOCAL_GL_UNSIGNED_INT_IMAGE_1D 0x9062
+#define LOCAL_GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068
+#define LOCAL_GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT 0x9068
+#define LOCAL_GL_UNSIGNED_INT_IMAGE_1D_EXT 0x9062
+#define LOCAL_GL_UNSIGNED_INT_IMAGE_2D 0x9063
+#define LOCAL_GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069
+#define LOCAL_GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT 0x9069
+#define LOCAL_GL_UNSIGNED_INT_IMAGE_2D_EXT 0x9063
+#define LOCAL_GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B
+#define LOCAL_GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C
+#define LOCAL_GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x906C
+#define LOCAL_GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT 0x906B
+#define LOCAL_GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065
+#define LOCAL_GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT 0x9065
+#define LOCAL_GL_UNSIGNED_INT_IMAGE_3D 0x9064
+#define LOCAL_GL_UNSIGNED_INT_IMAGE_3D_EXT 0x9064
+#define LOCAL_GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067
+#define LOCAL_GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067
+#define LOCAL_GL_UNSIGNED_INT_IMAGE_CUBE 0x9066
+#define LOCAL_GL_UNSIGNED_INT_IMAGE_CUBE_EXT 0x9066
+#define LOCAL_GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A
+#define LOCAL_GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A
+#define LOCAL_GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA
+#define LOCAL_GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1
+#define LOCAL_GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6
+#define LOCAL_GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6
+#define LOCAL_GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1
+#define LOCAL_GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2
+#define LOCAL_GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7
+#define LOCAL_GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7
+#define LOCAL_GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2
+#define LOCAL_GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A
+#define LOCAL_GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D
+#define LOCAL_GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5
+#define LOCAL_GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5
+#define LOCAL_GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3
+#define LOCAL_GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3
+#define LOCAL_GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8
+#define LOCAL_GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003
+#define LOCAL_GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8
+#define LOCAL_GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4
+#define LOCAL_GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4
+#define LOCAL_GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F
+#define LOCAL_GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F
+#define LOCAL_GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58
+#define LOCAL_GL_UNSIGNED_INT_VEC2 0x8DC6
+#define LOCAL_GL_UNSIGNED_INT_VEC2_EXT 0x8DC6
+#define LOCAL_GL_UNSIGNED_INT_VEC3 0x8DC7
+#define LOCAL_GL_UNSIGNED_INT_VEC3_EXT 0x8DC7
+#define LOCAL_GL_UNSIGNED_INT_VEC4 0x8DC8
+#define LOCAL_GL_UNSIGNED_INT_VEC4_EXT 0x8DC8
+#define LOCAL_GL_UNSIGNED_INVERT_NV 0x8537
+#define LOCAL_GL_UNSIGNED_NORMALIZED 0x8C17
+#define LOCAL_GL_UNSIGNED_NORMALIZED_ARB 0x8C17
+#define LOCAL_GL_UNSIGNED_NORMALIZED_EXT 0x8C17
+#define LOCAL_GL_UNSIGNED_SHORT 0x1403
+#define LOCAL_GL_UNSIGNED_SHORT_15_1_MESA 0x8753
+#define LOCAL_GL_UNSIGNED_SHORT_1_15_REV_MESA 0x8754
+#define LOCAL_GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
+#define LOCAL_GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366
+#define LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#define LOCAL_GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033
+#define LOCAL_GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
+#define LOCAL_GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365
+#define LOCAL_GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG 0x8365
+#define LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#define LOCAL_GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034
+#define LOCAL_GL_UNSIGNED_SHORT_5_6_5 0x8363
+#define LOCAL_GL_UNSIGNED_SHORT_5_6_5_EXT 0x8363
+#define LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
+#define LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV_EXT 0x8364
+#define LOCAL_GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA
+#define LOCAL_GL_UNSIGNED_SHORT_8_8_MESA 0x85BA
+#define LOCAL_GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB
+#define LOCAL_GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB
+#define LOCAL_GL_UPPER_LEFT 0x8CA2
+#define LOCAL_GL_USE_MISSING_GLYPH_NV 0x90AA
+#define LOCAL_GL_UTF16_NV 0x909B
+#define LOCAL_GL_UTF8_NV 0x909A
+#define LOCAL_GL_V2F 0x2A20
+#define LOCAL_GL_V3F 0x2A21
+#define LOCAL_GL_VALIDATE_STATUS 0x8B83
+#define LOCAL_GL_VARIABLE_A_NV 0x8523
+#define LOCAL_GL_VARIABLE_B_NV 0x8524
+#define LOCAL_GL_VARIABLE_C_NV 0x8525
+#define LOCAL_GL_VARIABLE_D_NV 0x8526
+#define LOCAL_GL_VARIABLE_E_NV 0x8527
+#define LOCAL_GL_VARIABLE_F_NV 0x8528
+#define LOCAL_GL_VARIABLE_G_NV 0x8529
+#define LOCAL_GL_VARIANT_ARRAY_EXT 0x87E8
+#define LOCAL_GL_VARIANT_ARRAY_POINTER_EXT 0x87E9
+#define LOCAL_GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6
+#define LOCAL_GL_VARIANT_ARRAY_TYPE_EXT 0x87E7
+#define LOCAL_GL_VARIANT_DATATYPE_EXT 0x87E5
+#define LOCAL_GL_VARIANT_EXT 0x87C1
+#define LOCAL_GL_VARIANT_VALUE_EXT 0x87E4
+#define LOCAL_GL_VBO_FREE_MEMORY_ATI 0x87FB
+#define LOCAL_GL_VECTOR_EXT 0x87BF
+#define LOCAL_GL_VENDOR 0x1F00
+#define LOCAL_GL_VERSION 0x1F02
+#define LOCAL_GL_VERSION_ES_CL_1_0 1
+#define LOCAL_GL_VERSION_ES_CL_1_1 1
+#define LOCAL_GL_VERSION_ES_CM_1_1 1
+#define LOCAL_GL_VERTEX23_BIT_PGI 0x00000004
+#define LOCAL_GL_VERTEX4_BIT_PGI 0x00000008
+#define LOCAL_GL_VERTEX_ARRAY 0x8074
+#define LOCAL_GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21
+#define LOCAL_GL_VERTEX_ARRAY_BINDING 0x85B5
+#define LOCAL_GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5
+#define LOCAL_GL_VERTEX_ARRAY_BINDING_OES 0x85B5
+#define LOCAL_GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896
+#define LOCAL_GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896
+#define LOCAL_GL_VERTEX_ARRAY_COUNT_EXT 0x807D
+#define LOCAL_GL_VERTEX_ARRAY_EXT 0x8074
+#define LOCAL_GL_VERTEX_ARRAY_KHR 0x8074
+#define LOCAL_GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B
+#define LOCAL_GL_VERTEX_ARRAY_LIST_IBM 103070
+#define LOCAL_GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080
+#define LOCAL_GL_VERTEX_ARRAY_OBJECT_AMD 0x9154
+#define LOCAL_GL_VERTEX_ARRAY_OBJECT_EXT 0x9154
+#define LOCAL_GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5
+#define LOCAL_GL_VERTEX_ARRAY_POINTER 0x808E
+#define LOCAL_GL_VERTEX_ARRAY_POINTER_EXT 0x808E
+#define LOCAL_GL_VERTEX_ARRAY_RANGE_APPLE 0x851D
+#define LOCAL_GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E
+#define LOCAL_GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E
+#define LOCAL_GL_VERTEX_ARRAY_RANGE_NV 0x851D
+#define LOCAL_GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521
+#define LOCAL_GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521
+#define LOCAL_GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F
+#define LOCAL_GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533
+#define LOCAL_GL_VERTEX_ARRAY_SIZE 0x807A
+#define LOCAL_GL_VERTEX_ARRAY_SIZE_EXT 0x807A
+#define LOCAL_GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F
+#define LOCAL_GL_VERTEX_ARRAY_STRIDE 0x807C
+#define LOCAL_GL_VERTEX_ARRAY_STRIDE_EXT 0x807C
+#define LOCAL_GL_VERTEX_ARRAY_TYPE 0x807B
+#define LOCAL_GL_VERTEX_ARRAY_TYPE_EXT 0x807B
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT 0x00000001
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_DIVISOR_EXT 0x88FE
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_DIVISOR_NV 0x88FE
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625
+#define LOCAL_GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E
+#define LOCAL_GL_VERTEX_ATTRIB_BINDING 0x82D4
+#define LOCAL_GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00
+#define LOCAL_GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03
+#define LOCAL_GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05
+#define LOCAL_GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04
+#define LOCAL_GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02
+#define LOCAL_GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01
+#define LOCAL_GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07
+#define LOCAL_GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09
+#define LOCAL_GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08
+#define LOCAL_GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06
+#define LOCAL_GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5
+#define LOCAL_GL_VERTEX_BINDING_DIVISOR 0x82D6
+#define LOCAL_GL_VERTEX_BINDING_OFFSET 0x82D7
+#define LOCAL_GL_VERTEX_BINDING_STRIDE 0x82D8
+#define LOCAL_GL_VERTEX_BLEND_ARB 0x86A7
+#define LOCAL_GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B
+#define LOCAL_GL_VERTEX_DATA_HINT_PGI 0x1A22A
+#define LOCAL_GL_VERTEX_ELEMENT_SWIZZLE_AMD 0x91A4
+#define LOCAL_GL_VERTEX_ID_NV 0x8C7B
+#define LOCAL_GL_VERTEX_ID_SWIZZLE_AMD 0x91A5
+#define LOCAL_GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF
+#define LOCAL_GL_VERTEX_PRECLIP_SGIX 0x83EE
+#define LOCAL_GL_VERTEX_PROGRAM_ARB 0x8620
+#define LOCAL_GL_VERTEX_PROGRAM_BINDING_NV 0x864A
+#define LOCAL_GL_VERTEX_PROGRAM_CALLBACK_DATA_MESA 0x8BB7
+#define LOCAL_GL_VERTEX_PROGRAM_CALLBACK_FUNC_MESA 0x8BB6
+#define LOCAL_GL_VERTEX_PROGRAM_CALLBACK_MESA 0x8BB5
+#define LOCAL_GL_VERTEX_PROGRAM_NV 0x8620
+#define LOCAL_GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2
+#define LOCAL_GL_VERTEX_PROGRAM_POINT_SIZE 0x8642
+#define LOCAL_GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642
+#define LOCAL_GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642
+#define LOCAL_GL_VERTEX_PROGRAM_POSITION_MESA 0x8BB4
+#define LOCAL_GL_VERTEX_PROGRAM_TWO_SIDE 0x8643
+#define LOCAL_GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643
+#define LOCAL_GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643
+#define LOCAL_GL_VERTEX_SHADER 0x8B31
+#define LOCAL_GL_VERTEX_SHADER_ARB 0x8B31
+#define LOCAL_GL_VERTEX_SHADER_BINDING_EXT 0x8781
+#define LOCAL_GL_VERTEX_SHADER_BIT 0x00000001
+#define LOCAL_GL_VERTEX_SHADER_BIT_EXT 0x00000001
+#define LOCAL_GL_VERTEX_SHADER_EXT 0x8780
+#define LOCAL_GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF
+#define LOCAL_GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1
+#define LOCAL_GL_VERTEX_SHADER_LOCALS_EXT 0x87D3
+#define LOCAL_GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2
+#define LOCAL_GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4
+#define LOCAL_GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0
+#define LOCAL_GL_VERTEX_SOURCE_ATI 0x8774
+#define LOCAL_GL_VERTEX_STATE_PROGRAM_NV 0x8621
+#define LOCAL_GL_VERTEX_STREAM0_ATI 0x876C
+#define LOCAL_GL_VERTEX_STREAM1_ATI 0x876D
+#define LOCAL_GL_VERTEX_STREAM2_ATI 0x876E
+#define LOCAL_GL_VERTEX_STREAM3_ATI 0x876F
+#define LOCAL_GL_VERTEX_STREAM4_ATI 0x8770
+#define LOCAL_GL_VERTEX_STREAM5_ATI 0x8771
+#define LOCAL_GL_VERTEX_STREAM6_ATI 0x8772
+#define LOCAL_GL_VERTEX_STREAM7_ATI 0x8773
+#define LOCAL_GL_VERTEX_SUBROUTINE 0x92E8
+#define LOCAL_GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE
+#define LOCAL_GL_VERTEX_TEXTURE 0x829B
+#define LOCAL_GL_VERTEX_WEIGHTING_EXT 0x8509
+#define LOCAL_GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C
+#define LOCAL_GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510
+#define LOCAL_GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D
+#define LOCAL_GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F
+#define LOCAL_GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E
+#define LOCAL_GL_VERTICAL_LINE_TO_NV 0x08
+#define LOCAL_GL_VIBRANCE_BIAS_NV 0x8719
+#define LOCAL_GL_VIBRANCE_SCALE_NV 0x8713
+#define LOCAL_GL_VIDEO_BUFFER_BINDING_NV 0x9021
+#define LOCAL_GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D
+#define LOCAL_GL_VIDEO_BUFFER_NV 0x9020
+#define LOCAL_GL_VIDEO_BUFFER_PITCH_NV 0x9028
+#define LOCAL_GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B
+#define LOCAL_GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A
+#define LOCAL_GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV 0x9039
+#define LOCAL_GL_VIDEO_CAPTURE_FRAME_WIDTH_NV 0x9038
+#define LOCAL_GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C
+#define LOCAL_GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026
+#define LOCAL_GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029
+#define LOCAL_GL_VIDEO_COLOR_CONVERSION_MAX_NV 0x902A
+#define LOCAL_GL_VIDEO_COLOR_CONVERSION_MIN_NV 0x902B
+#define LOCAL_GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C
+#define LOCAL_GL_VIEWPORT 0x0BA2
+#define LOCAL_GL_VIEWPORT_BIT 0x00000800
+#define LOCAL_GL_VIEWPORT_BOUNDS_RANGE 0x825D
+#define LOCAL_GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F
+#define LOCAL_GL_VIEWPORT_SUBPIXEL_BITS 0x825C
+#define LOCAL_GL_VIEW_CLASS_128_BITS 0x82C4
+#define LOCAL_GL_VIEW_CLASS_16_BITS 0x82CA
+#define LOCAL_GL_VIEW_CLASS_24_BITS 0x82C9
+#define LOCAL_GL_VIEW_CLASS_32_BITS 0x82C8
+#define LOCAL_GL_VIEW_CLASS_48_BITS 0x82C7
+#define LOCAL_GL_VIEW_CLASS_64_BITS 0x82C6
+#define LOCAL_GL_VIEW_CLASS_8_BITS 0x82CB
+#define LOCAL_GL_VIEW_CLASS_96_BITS 0x82C5
+#define LOCAL_GL_VIEW_CLASS_BPTC_FLOAT 0x82D3
+#define LOCAL_GL_VIEW_CLASS_BPTC_UNORM 0x82D2
+#define LOCAL_GL_VIEW_CLASS_RGTC1_RED 0x82D0
+#define LOCAL_GL_VIEW_CLASS_RGTC2_RG 0x82D1
+#define LOCAL_GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC
+#define LOCAL_GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD
+#define LOCAL_GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE
+#define LOCAL_GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF
+#define LOCAL_GL_VIEW_COMPATIBILITY_CLASS 0x82B6
+#define LOCAL_GL_VIRTUAL_PAGE_SIZE_INDEX_ARB 0x91A7
+#define LOCAL_GL_VIRTUAL_PAGE_SIZE_X_AMD 0x9195
+#define LOCAL_GL_VIRTUAL_PAGE_SIZE_X_ARB 0x9195
+#define LOCAL_GL_VIRTUAL_PAGE_SIZE_Y_AMD 0x9196
+#define LOCAL_GL_VIRTUAL_PAGE_SIZE_Y_ARB 0x9196
+#define LOCAL_GL_VIRTUAL_PAGE_SIZE_Z_AMD 0x9197
+#define LOCAL_GL_VIRTUAL_PAGE_SIZE_Z_ARB 0x9197
+#define LOCAL_GL_VIVIDLIGHT_NV 0x92A6
+#define LOCAL_GL_VOLATILE_APPLE 0x8A1A
+#define LOCAL_GL_WAIT_FAILED 0x911D
+#define LOCAL_GL_WAIT_FAILED_APPLE 0x911D
+#define LOCAL_GL_WEIGHT_ARRAY_ARB 0x86AD
+#define LOCAL_GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E
+#define LOCAL_GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E
+#define LOCAL_GL_WEIGHT_ARRAY_BUFFER_BINDING_OES 0x889E
+#define LOCAL_GL_WEIGHT_ARRAY_OES 0x86AD
+#define LOCAL_GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC
+#define LOCAL_GL_WEIGHT_ARRAY_POINTER_OES 0x86AC
+#define LOCAL_GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB
+#define LOCAL_GL_WEIGHT_ARRAY_SIZE_OES 0x86AB
+#define LOCAL_GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA
+#define LOCAL_GL_WEIGHT_ARRAY_STRIDE_OES 0x86AA
+#define LOCAL_GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9
+#define LOCAL_GL_WEIGHT_ARRAY_TYPE_OES 0x86A9
+#define LOCAL_GL_WEIGHT_SUM_UNITY_ARB 0x86A6
+#define LOCAL_GL_WIDE_LINE_HINT_PGI 0x1A222
+#define LOCAL_GL_WRAP_BORDER_SUN 0x81D4
+#define LOCAL_GL_WRITEONLY_RENDERING_QCOM 0x8823
+#define LOCAL_GL_WRITE_DISCARD_NV 0x88BE
+#define LOCAL_GL_WRITE_ONLY 0x88B9
+#define LOCAL_GL_WRITE_ONLY_ARB 0x88B9
+#define LOCAL_GL_WRITE_ONLY_OES 0x88B9
+#define LOCAL_GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A
+#define LOCAL_GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878
+#define LOCAL_GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C
+#define LOCAL_GL_W_EXT 0x87D8
+#define LOCAL_GL_XOR 0x1506
+#define LOCAL_GL_XOR_NV 0x1506
+#define LOCAL_GL_X_EXT 0x87D5
+#define LOCAL_GL_YCBAYCR8A_4224_NV 0x9032
+#define LOCAL_GL_YCBCR_422_APPLE 0x85B9
+#define LOCAL_GL_YCBCR_MESA 0x8757
+#define LOCAL_GL_YCBYCR8_422_NV 0x9031
+#define LOCAL_GL_YCRCBA_SGIX 0x8319
+#define LOCAL_GL_YCRCB_422_SGIX 0x81BB
+#define LOCAL_GL_YCRCB_444_SGIX 0x81BC
+#define LOCAL_GL_YCRCB_SGIX 0x8318
+#define LOCAL_GL_Y_EXT 0x87D6
+#define LOCAL_GL_Z400_BINARY_AMD 0x8740
+#define LOCAL_GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036
+#define LOCAL_GL_Z4Y12Z4CB12Z4CR12_444_NV 0x9037
+#define LOCAL_GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV 0x9035
+#define LOCAL_GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034
+#define LOCAL_GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV 0x9033
+#define LOCAL_GL_ZERO 0
+#define LOCAL_GL_ZERO_EXT 0x87DD
+#define LOCAL_GL_ZOOM_X 0x0D16
+#define LOCAL_GL_ZOOM_Y 0x0D17
+#define LOCAL_GL_Z_EXT 0x87D7
+
+
+// EGL
+#define LOCAL_EGL_ALPHA_FORMAT 0x3088
+#define LOCAL_EGL_ALPHA_FORMAT_NONPRE 0x308B
+#define LOCAL_EGL_ALPHA_FORMAT_PRE 0x308C
+#define LOCAL_EGL_ALPHA_MASK_SIZE 0x303E
+#define LOCAL_EGL_ALPHA_SIZE 0x3021
+#define LOCAL_EGL_ALREADY_SIGNALED_NV 0x30EA
+#define LOCAL_EGL_AUTO_STEREO_NV 0x3136
+#define LOCAL_EGL_BACK_BUFFER 0x3084
+#define LOCAL_EGL_BAD_ACCESS 0x3002
+#define LOCAL_EGL_BAD_ALLOC 0x3003
+#define LOCAL_EGL_BAD_ATTRIBUTE 0x3004
+#define LOCAL_EGL_BAD_CONFIG 0x3005
+#define LOCAL_EGL_BAD_CONTEXT 0x3006
+#define LOCAL_EGL_BAD_CURRENT_SURFACE 0x3007
+#define LOCAL_EGL_BAD_DISPLAY 0x3008
+#define LOCAL_EGL_BAD_MATCH 0x3009
+#define LOCAL_EGL_BAD_NATIVE_PIXMAP 0x300A
+#define LOCAL_EGL_BAD_NATIVE_WINDOW 0x300B
+#define LOCAL_EGL_BAD_PARAMETER 0x300C
+#define LOCAL_EGL_BAD_STATE_KHR 0x321C
+#define LOCAL_EGL_BAD_STREAM_KHR 0x321B
+#define LOCAL_EGL_BAD_SURFACE 0x300D
+#define LOCAL_EGL_BIND_TO_TEXTURE_RGB 0x3039
+#define LOCAL_EGL_BIND_TO_TEXTURE_RGBA 0x303A
+#define LOCAL_EGL_BITMAP_ORIGIN_KHR 0x30C8
+#define LOCAL_EGL_BITMAP_PITCH_KHR 0x30C7
+#define LOCAL_EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC
+#define LOCAL_EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB
+#define LOCAL_EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA
+#define LOCAL_EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD
+#define LOCAL_EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9
+#define LOCAL_EGL_BITMAP_PIXEL_SIZE_KHR 0x3110
+#define LOCAL_EGL_BITMAP_POINTER_KHR 0x30C6
+#define LOCAL_EGL_BLUE_SIZE 0x3022
+#define LOCAL_EGL_BUFFER_AGE_EXT 0x313D
+#define LOCAL_EGL_BUFFER_COUNT_NV 0x321D
+#define LOCAL_EGL_BUFFER_DESTROYED 0x3095
+#define LOCAL_EGL_BUFFER_PRESERVED 0x3094
+#define LOCAL_EGL_BUFFER_SIZE 0x3020
+#define LOCAL_EGL_CLIENT_APIS 0x308D
+#define LOCAL_EGL_CLIENT_PIXMAP_POINTER_HI 0x8F74
+#define LOCAL_EGL_CL_EVENT_HANDLE_KHR 0x309C
+#define LOCAL_EGL_COLORSPACE 0x3087
+#define LOCAL_EGL_COLORSPACE_LINEAR 0x308A
+#define LOCAL_EGL_COLORSPACE_sRGB 0x3089
+#define LOCAL_EGL_COLOR_ARGB_HI 0x8F73
+#define LOCAL_EGL_COLOR_BUFFER_TYPE 0x303F
+#define LOCAL_EGL_COLOR_FORMAT_HI 0x8F70
+#define LOCAL_EGL_COLOR_RGBA_HI 0x8F72
+#define LOCAL_EGL_COLOR_RGB_HI 0x8F71
+#define LOCAL_EGL_CONDITION_SATISFIED_KHR 0x30F6
+#define LOCAL_EGL_CONDITION_SATISFIED_NV 0x30EC
+#define LOCAL_EGL_CONFIG_CAVEAT 0x3027
+#define LOCAL_EGL_CONFIG_ID 0x3028
+#define LOCAL_EGL_CONFORMANT 0x3042
+#define LOCAL_EGL_CONFORMANT_KHR 0x3042
+#define LOCAL_EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR 0x321E
+#define LOCAL_EGL_CONSUMER_FRAME_KHR 0x3213
+#define LOCAL_EGL_CONSUMER_LATENCY_USEC_KHR 0x3210
+#define LOCAL_EGL_CONTEXT_CLIENT_TYPE 0x3097
+#define LOCAL_EGL_CONTEXT_CLIENT_VERSION 0x3098
+#define LOCAL_EGL_CONTEXT_FLAGS_KHR 0x30FC
+#define LOCAL_EGL_CONTEXT_LOST 0x300E
+#define LOCAL_EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098
+#define LOCAL_EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB
+#define LOCAL_EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002
+#define LOCAL_EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
+#define LOCAL_EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001
+#define LOCAL_EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
+#define LOCAL_EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD
+#define LOCAL_EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138
+#define LOCAL_EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD
+#define LOCAL_EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004
+#define LOCAL_EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF
+#define LOCAL_EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101
+#define LOCAL_EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100
+#define LOCAL_EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103
+#define LOCAL_EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102
+#define LOCAL_EGL_CORE_NATIVE_ENGINE 0x305B
+#define LOCAL_EGL_COVERAGE_BUFFERS_NV 0x30E0
+#define LOCAL_EGL_COVERAGE_SAMPLES_NV 0x30E1
+#define LOCAL_EGL_COVERAGE_SAMPLE_RESOLVE_DEFAULT_NV 0x3132
+#define LOCAL_EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133
+#define LOCAL_EGL_COVERAGE_SAMPLE_RESOLVE_NV 0x3131
+#define LOCAL_EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
+#define LOCAL_EGL_DXGI_KEYED_MUTEX_ANGLE 0x33A2
+#define LOCAL_EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0)
+#define LOCAL_EGL_DEPTH_ENCODING_NONE_NV 0
+#define LOCAL_EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3
+#define LOCAL_EGL_DEPTH_ENCODING_NV 0x30E2
+#define LOCAL_EGL_DEPTH_SIZE 0x3025
+#define LOCAL_EGL_DISCARD_SAMPLES_ARM 0x3286
+#define LOCAL_EGL_DISPLAY_SCALING 10000
+#define LOCAL_EGL_DMA_BUF_PLANE0_FD_EXT 0x3272
+#define LOCAL_EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273
+#define LOCAL_EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274
+#define LOCAL_EGL_DMA_BUF_PLANE1_FD_EXT 0x3275
+#define LOCAL_EGL_DMA_BUF_PLANE1_OFFSET_EXT 0x3276
+#define LOCAL_EGL_DMA_BUF_PLANE1_PITCH_EXT 0x3277
+#define LOCAL_EGL_DMA_BUF_PLANE2_FD_EXT 0x3278
+#define LOCAL_EGL_DMA_BUF_PLANE2_OFFSET_EXT 0x3279
+#define LOCAL_EGL_DMA_BUF_PLANE2_PITCH_EXT 0x327A
+#define LOCAL_EGL_DONT_CARE ((EGLint)-1)
+#define LOCAL_EGL_DRAW 0x3059
+#define LOCAL_EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2
+#define LOCAL_EGL_DRM_BUFFER_FORMAT_MESA 0x31D0
+#define LOCAL_EGL_DRM_BUFFER_MESA 0x31D3
+#define LOCAL_EGL_DRM_BUFFER_STRIDE_MESA 0x31D4
+#define LOCAL_EGL_DRM_BUFFER_USE_MESA 0x31D1
+#define LOCAL_EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001
+#define LOCAL_EGL_DRM_BUFFER_USE_SHARE_MESA 0x00000002
+#define LOCAL_EGL_EXTENSIONS 0x3055
+#define LOCAL_EGL_FALSE 0
+#define LOCAL_EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFF
+#define LOCAL_EGL_FOREVER_NV 0xFFFFFFFFFFFFFFFF
+#define LOCAL_EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2
+#define LOCAL_EGL_FORMAT_RGBA_8888_KHR 0x30C3
+#define LOCAL_EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0
+#define LOCAL_EGL_FORMAT_RGB_565_KHR 0x30C1
+#define LOCAL_EGL_FRAMEBUFFER_TARGET_ANDROID 0x3147
+#define LOCAL_EGL_GL_COLORSPACE_KHR 0x309D
+#define LOCAL_EGL_GL_COLORSPACE_LINEAR_KHR 0x308A
+#define LOCAL_EGL_GL_COLORSPACE_SRGB_KHR 0x3089
+#define LOCAL_EGL_GL_RENDERBUFFER_KHR 0x30B9
+#define LOCAL_EGL_GL_TEXTURE_2D_KHR 0x30B1
+#define LOCAL_EGL_GL_TEXTURE_3D_KHR 0x30B2
+#define LOCAL_EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR 0x30B4
+#define LOCAL_EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR 0x30B6
+#define LOCAL_EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR 0x30B8
+#define LOCAL_EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR 0x30B3
+#define LOCAL_EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR 0x30B5
+#define LOCAL_EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR 0x30B7
+#define LOCAL_EGL_GL_TEXTURE_LEVEL_KHR 0x30BC
+#define LOCAL_EGL_GL_TEXTURE_ZOFFSET_KHR 0x30BD
+#define LOCAL_EGL_GREEN_SIZE 0x3023
+#define LOCAL_EGL_HEIGHT 0x3056
+#define LOCAL_EGL_HORIZONTAL_RESOLUTION 0x3090
+#define LOCAL_EGL_IMAGE_PRESERVED_KHR 0x30D2
+#define LOCAL_EGL_INTEROP_BIT_KHR 0x0010
+#define LOCAL_EGL_ITU_REC2020_EXT 0x3281
+#define LOCAL_EGL_ITU_REC601_EXT 0x327F
+#define LOCAL_EGL_ITU_REC709_EXT 0x3280
+#define LOCAL_EGL_LARGEST_PBUFFER 0x3058
+#define LOCAL_EGL_LEVEL 0x3029
+#define LOCAL_EGL_LINUX_DMA_BUF_EXT 0x3270
+#define LOCAL_EGL_LINUX_DRM_FOURCC_EXT 0x3271
+#define LOCAL_EGL_LOCK_SURFACE_BIT_KHR 0x0080
+#define LOCAL_EGL_LOCK_USAGE_HINT_KHR 0x30C5
+#define LOCAL_EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF
+#define LOCAL_EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF
+#define LOCAL_EGL_LOWER_LEFT_KHR 0x30CE
+#define LOCAL_EGL_LUMINANCE_BUFFER 0x308F
+#define LOCAL_EGL_LUMINANCE_SIZE 0x303D
+#define LOCAL_EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4
+#define LOCAL_EGL_MATCH_FORMAT_KHR 0x3043
+#define LOCAL_EGL_MATCH_NATIVE_PIXMAP 0x3041
+#define LOCAL_EGL_MAX_PBUFFER_HEIGHT 0x302A
+#define LOCAL_EGL_MAX_PBUFFER_PIXELS 0x302B
+#define LOCAL_EGL_MAX_PBUFFER_WIDTH 0x302C
+#define LOCAL_EGL_MAX_SWAP_INTERVAL 0x303C
+#define LOCAL_EGL_MIN_SWAP_INTERVAL 0x303B
+#define LOCAL_EGL_MIPMAP_LEVEL 0x3083
+#define LOCAL_EGL_MIPMAP_TEXTURE 0x3082
+#define LOCAL_EGL_MULTISAMPLE_RESOLVE 0x3099
+#define LOCAL_EGL_MULTISAMPLE_RESOLVE_BOX 0x309B
+#define LOCAL_EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200
+#define LOCAL_EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A
+#define LOCAL_EGL_MULTIVIEW_VIEW_COUNT_EXT 0x3134
+#define LOCAL_EGL_NATIVE_BUFFER_ANDROID 0x3140
+#define LOCAL_EGL_NATIVE_PIXMAP_KHR 0x30B0
+#define LOCAL_EGL_NATIVE_RENDERABLE 0x302D
+#define LOCAL_EGL_NATIVE_VISUAL_ID 0x302E
+#define LOCAL_EGL_NATIVE_VISUAL_TYPE 0x302F
+#define LOCAL_EGL_NONE 0x3038
+#define LOCAL_EGL_NON_CONFORMANT_CONFIG 0x3051
+#define LOCAL_EGL_NOT_INITIALIZED 0x3001
+#define LOCAL_EGL_NO_CONTEXT ((EGLContext)0)
+#define LOCAL_EGL_NO_DISPLAY ((EGLDisplay)0)
+#define LOCAL_EGL_NO_FILE_DESCRIPTOR_KHR ((EGLNativeFileDescriptorKHR)(-1))
+#define LOCAL_EGL_NO_IMAGE_KHR ((EGLImageKHR)0)
+#define LOCAL_EGL_NO_NATIVE_FENCE_FD_ANDROID -1
+#define LOCAL_EGL_NO_RESET_NOTIFICATION_EXT 0x31BE
+#define LOCAL_EGL_NO_RESET_NOTIFICATION_KHR 0x31BE
+#define LOCAL_EGL_NO_STREAM_KHR ((EGLStreamKHR)0)
+#define LOCAL_EGL_NO_SURFACE ((EGLSurface)0)
+#define LOCAL_EGL_NO_SYNC_KHR ((EGLSyncKHR)0)
+#define LOCAL_EGL_NO_SYNC_NV ((EGLSyncNV)0)
+#define LOCAL_EGL_NO_TEXTURE 0x305C
+#define LOCAL_EGL_OPENGL_API 0x30A2
+#define LOCAL_EGL_OPENGL_BIT 0x0008
+#define LOCAL_EGL_OPENGL_ES2_BIT 0x0004
+#define LOCAL_EGL_OPENGL_ES3_BIT_KHR 0x00000040
+#define LOCAL_EGL_OPENGL_ES_API 0x30A0
+#define LOCAL_EGL_OPENGL_ES_BIT 0x0001
+#define LOCAL_EGL_OPENMAX_IL_BIT_KHR 0x0020
+#define LOCAL_EGL_OPENVG_API 0x30A1
+#define LOCAL_EGL_OPENVG_BIT 0x0002
+#define LOCAL_EGL_OPENVG_IMAGE 0x3096
+#define LOCAL_EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100
+#define LOCAL_EGL_PBUFFER_BIT 0x0001
+#define LOCAL_EGL_PBUFFER_IMAGE_BIT_TAO 0x0008
+#define LOCAL_EGL_PBUFFER_PALETTE_IMAGE_BIT_TAO 0x0010
+#define LOCAL_EGL_PIXEL_ASPECT_RATIO 0x3092
+#define LOCAL_EGL_PIXMAP_BIT 0x0002
+#define LOCAL_EGL_PLATFORM_GBM_MESA 0x31D7
+#define LOCAL_EGL_PLATFORM_WAYLAND_EXT 0x31D8
+#define LOCAL_EGL_PLATFORM_X11_EXT 0x31D5
+#define LOCAL_EGL_PLATFORM_X11_SCREEN_EXT 0x31D6
+#define LOCAL_EGL_POST_SUB_BUFFER_SUPPORTED_NV 0x30BE
+#define LOCAL_EGL_PRODUCER_FRAME_KHR 0x3212
+#define LOCAL_EGL_PROTECTED_CONTENT_EXT 0x32C0
+#define LOCAL_EGL_READ 0x305A
+#define LOCAL_EGL_READ_SURFACE_BIT_KHR 0x0001
+#define LOCAL_EGL_RECORDABLE_ANDROID 0x3142
+#define LOCAL_EGL_RED_SIZE 0x3024
+#define LOCAL_EGL_RENDERABLE_TYPE 0x3040
+#define LOCAL_EGL_RENDER_BUFFER 0x3086
+#define LOCAL_EGL_RGB_BUFFER 0x308E
+#define LOCAL_EGL_SAMPLES 0x3031
+#define LOCAL_EGL_SAMPLE_BUFFERS 0x3032
+#define LOCAL_EGL_SAMPLE_RANGE_HINT_EXT 0x327C
+#define LOCAL_EGL_SHARED_IMAGE_NOK 0x30DA
+#define LOCAL_EGL_SIGNALED_KHR 0x30F2
+#define LOCAL_EGL_SIGNALED_NV 0x30E8
+#define LOCAL_EGL_SINGLE_BUFFER 0x3085
+#define LOCAL_EGL_SLOW_CONFIG 0x3050
+#define LOCAL_EGL_STENCIL_SIZE 0x3026
+#define LOCAL_EGL_STREAM_BIT_KHR 0x0800
+#define LOCAL_EGL_STREAM_FIFO_LENGTH_KHR 0x31FC
+#define LOCAL_EGL_STREAM_STATE_CONNECTING_KHR 0x3216
+#define LOCAL_EGL_STREAM_STATE_CREATED_KHR 0x3215
+#define LOCAL_EGL_STREAM_STATE_DISCONNECTED_KHR 0x321A
+#define LOCAL_EGL_STREAM_STATE_EMPTY_KHR 0x3217
+#define LOCAL_EGL_STREAM_STATE_KHR 0x3214
+#define LOCAL_EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR 0x3218
+#define LOCAL_EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR 0x3219
+#define LOCAL_EGL_STREAM_TIME_CONSUMER_KHR 0x31FE
+#define LOCAL_EGL_STREAM_TIME_NOW_KHR 0x31FD
+#define LOCAL_EGL_STREAM_TIME_PRODUCER_KHR 0x31FF
+#define LOCAL_EGL_SUCCESS 0x3000
+#define LOCAL_EGL_SURFACE_TYPE 0x3033
+#define LOCAL_EGL_SWAP_BEHAVIOR 0x3093
+#define LOCAL_EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400
+#define LOCAL_EGL_SYNC_CL_EVENT_COMPLETE_KHR 0x30FF
+#define LOCAL_EGL_SYNC_CL_EVENT_KHR 0x30FE
+#define LOCAL_EGL_SYNC_CONDITION_KHR 0x30F8
+#define LOCAL_EGL_SYNC_CONDITION_NV 0x30EE
+#define LOCAL_EGL_SYNC_FENCE_KHR 0x30F9
+#define LOCAL_EGL_SYNC_FENCE_NV 0x30EF
+#define LOCAL_EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001
+#define LOCAL_EGL_SYNC_FLUSH_COMMANDS_BIT_NV 0x0001
+#define LOCAL_EGL_SYNC_NATIVE_FENCE_ANDROID 0x3144
+#define LOCAL_EGL_SYNC_NATIVE_FENCE_FD_ANDROID 0x3145
+#define LOCAL_EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID 0x3146
+#define LOCAL_EGL_SYNC_NEW_FRAME_NV 0x321F
+#define LOCAL_EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0
+#define LOCAL_EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV 0x30E6
+#define LOCAL_EGL_SYNC_REUSABLE_KHR 0x30FA
+#define LOCAL_EGL_SYNC_STATUS_KHR 0x30F1
+#define LOCAL_EGL_SYNC_STATUS_NV 0x30E7
+#define LOCAL_EGL_SYNC_TYPE_KHR 0x30F7
+#define LOCAL_EGL_SYNC_TYPE_NV 0x30ED
+#define LOCAL_EGL_TEXTURE_2D 0x305F
+#define LOCAL_EGL_TEXTURE_FORMAT 0x3080
+#define LOCAL_EGL_TEXTURE_RGB 0x305D
+#define LOCAL_EGL_TEXTURE_RGBA 0x305E
+#define LOCAL_EGL_TEXTURE_TARGET 0x3081
+#define LOCAL_EGL_TIMEOUT_EXPIRED_KHR 0x30F5
+#define LOCAL_EGL_TIMEOUT_EXPIRED_NV 0x30EB
+#define LOCAL_EGL_TRANSPARENT_BLUE_VALUE 0x3035
+#define LOCAL_EGL_TRANSPARENT_GREEN_VALUE 0x3036
+#define LOCAL_EGL_TRANSPARENT_RED_VALUE 0x3037
+#define LOCAL_EGL_TRANSPARENT_RGB 0x3052
+#define LOCAL_EGL_TRANSPARENT_TYPE 0x3034
+#define LOCAL_EGL_TRUE 1
+#define LOCAL_EGL_UNKNOWN ((EGLint)-1)
+#define LOCAL_EGL_UNSIGNALED_KHR 0x30F3
+#define LOCAL_EGL_UNSIGNALED_NV 0x30E9
+#define LOCAL_EGL_UPPER_LEFT_KHR 0x30CF
+#define LOCAL_EGL_VENDOR 0x3053
+#define LOCAL_EGL_VERSION 0x3054
+#define LOCAL_EGL_VERTICAL_RESOLUTION 0x3091
+#define LOCAL_EGL_VG_ALPHA_FORMAT 0x3088
+#define LOCAL_EGL_VG_ALPHA_FORMAT_NONPRE 0x308B
+#define LOCAL_EGL_VG_ALPHA_FORMAT_PRE 0x308C
+#define LOCAL_EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040
+#define LOCAL_EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040
+#define LOCAL_EGL_VG_COLORSPACE 0x3087
+#define LOCAL_EGL_VG_COLORSPACE_LINEAR 0x308A
+#define LOCAL_EGL_VG_COLORSPACE_LINEAR_BIT 0x0020
+#define LOCAL_EGL_VG_COLORSPACE_LINEAR_BIT_KHR 0x0020
+#define LOCAL_EGL_VG_COLORSPACE_sRGB 0x3089
+#define LOCAL_EGL_VG_PARENT_IMAGE_KHR 0x30BA
+#define LOCAL_EGL_WIDTH 0x3057
+#define LOCAL_EGL_WINDOW_BIT 0x0004
+#define LOCAL_EGL_WRITE_SURFACE_BIT_KHR 0x0002
+#define LOCAL_EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT 0x327D
+#define LOCAL_EGL_YUV_CHROMA_SITING_0_5_EXT 0x3285
+#define LOCAL_EGL_YUV_CHROMA_SITING_0_EXT 0x3284
+#define LOCAL_EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT 0x327E
+#define LOCAL_EGL_YUV_COLOR_SPACE_HINT_EXT 0x327B
+#define LOCAL_EGL_YUV_FULL_RANGE_EXT 0x3282
+#define LOCAL_EGL_YUV_NARROW_RANGE_EXT 0x3283
+
+
+// GLX
+#define LOCAL_GLX_3DFX_FULLSCREEN_MODE_MESA 0x2
+#define LOCAL_GLX_3DFX_WINDOW_MODE_MESA 0x1
+#define LOCAL_GLX_ACCUM_ALPHA_SIZE 17
+#define LOCAL_GLX_ACCUM_BLUE_SIZE 16
+#define LOCAL_GLX_ACCUM_BUFFER_BIT 0x00000080
+#define LOCAL_GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080
+#define LOCAL_GLX_ACCUM_GREEN_SIZE 15
+#define LOCAL_GLX_ACCUM_RED_SIZE 14
+#define LOCAL_GLX_ALPHA_SIZE 11
+#define LOCAL_GLX_AUX0_EXT 0x20E2
+#define LOCAL_GLX_AUX1_EXT 0x20E3
+#define LOCAL_GLX_AUX2_EXT 0x20E4
+#define LOCAL_GLX_AUX3_EXT 0x20E5
+#define LOCAL_GLX_AUX4_EXT 0x20E6
+#define LOCAL_GLX_AUX5_EXT 0x20E7
+#define LOCAL_GLX_AUX6_EXT 0x20E8
+#define LOCAL_GLX_AUX7_EXT 0x20E9
+#define LOCAL_GLX_AUX8_EXT 0x20EA
+#define LOCAL_GLX_AUX9_EXT 0x20EB
+#define LOCAL_GLX_AUX_BUFFERS 7
+#define LOCAL_GLX_AUX_BUFFERS_BIT 0x00000010
+#define LOCAL_GLX_AUX_BUFFERS_BIT_SGIX 0x00000010
+#define LOCAL_GLX_BACK_BUFFER_AGE_EXT 0x20F4
+#define LOCAL_GLX_BACK_EXT 0x20E0
+#define LOCAL_GLX_BACK_LEFT_BUFFER_BIT 0x00000004
+#define LOCAL_GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004
+#define LOCAL_GLX_BACK_LEFT_EXT 0x20E0
+#define LOCAL_GLX_BACK_RIGHT_BUFFER_BIT 0x00000008
+#define LOCAL_GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008
+#define LOCAL_GLX_BACK_RIGHT_EXT 0x20E1
+#define LOCAL_GLX_BAD_ATTRIBUTE 2
+#define LOCAL_GLX_BAD_CONTEXT 5
+#define LOCAL_GLX_BAD_ENUM 7
+#define LOCAL_GLX_BAD_HYPERPIPE_CONFIG_SGIX 91
+#define LOCAL_GLX_BAD_HYPERPIPE_SGIX 92
+#define LOCAL_GLX_BAD_SCREEN 1
+#define LOCAL_GLX_BAD_VALUE 6
+#define LOCAL_GLX_BAD_VISUAL 4
+#define LOCAL_GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2
+#define LOCAL_GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1
+#define LOCAL_GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0
+#define LOCAL_GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3
+#define LOCAL_GLX_BLENDED_RGBA_SGIS 0x8025
+#define LOCAL_GLX_BLUE_SIZE 10
+#define LOCAL_GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000
+#define LOCAL_GLX_BUFFER_SIZE 2
+#define LOCAL_GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK 0x04000000
+#define LOCAL_GLX_BufferSwapComplete 1
+#define LOCAL_GLX_COLOR_INDEX_BIT 0x00000002
+#define LOCAL_GLX_COLOR_INDEX_BIT_SGIX 0x00000002
+#define LOCAL_GLX_COLOR_INDEX_TYPE 0x8015
+#define LOCAL_GLX_COLOR_INDEX_TYPE_SGIX 0x8015
+#define LOCAL_GLX_COLOR_SAMPLES_NV 0x20B3
+#define LOCAL_GLX_CONFIG_CAVEAT 0x20
+#define LOCAL_GLX_CONTEXT_ALLOW_BUFFER_BYTE_ORDER_MISMATCH_ARB 0x2095
+#define LOCAL_GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#define LOCAL_GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define LOCAL_GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001
+#define LOCAL_GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
+#define LOCAL_GLX_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004
+#define LOCAL_GLX_CONTEXT_FLAGS_ARB 0x2094
+#define LOCAL_GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
+#define LOCAL_GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define LOCAL_GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
+#define LOCAL_GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
+#define LOCAL_GLX_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008
+#define LOCAL_GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define LOCAL_GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
+#define LOCAL_GLX_COPY_COMPLETE_INTEL 0x8181
+#define LOCAL_GLX_COVERAGE_SAMPLES_NV 100001
+#define LOCAL_GLX_DAMAGED 0x8020
+#define LOCAL_GLX_DAMAGED_SGIX 0x8020
+#define LOCAL_GLX_DEPTH_BUFFER_BIT 0x00000020
+#define LOCAL_GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020
+#define LOCAL_GLX_DEPTH_SIZE 12
+#define LOCAL_GLX_DEVICE_ID_NV 0x20CD
+#define LOCAL_GLX_DIGITAL_MEDIA_PBUFFER_SGIX 0x8024
+#define LOCAL_GLX_DIRECT_COLOR 0x8003
+#define LOCAL_GLX_DIRECT_COLOR_EXT 0x8003
+#define LOCAL_GLX_DONT_CARE 0xFFFFFFFF
+#define LOCAL_GLX_DOUBLEBUFFER 5
+#define LOCAL_GLX_DRAWABLE_TYPE 0x8010
+#define LOCAL_GLX_DRAWABLE_TYPE_SGIX 0x8010
+#define LOCAL_GLX_EVENT_MASK 0x801F
+#define LOCAL_GLX_EVENT_MASK_SGIX 0x801F
+#define LOCAL_GLX_EXCHANGE_COMPLETE_INTEL 0x8180
+#define LOCAL_GLX_EXTENSIONS 0x3
+#define LOCAL_GLX_EXTENSION_NAME "GLX"
+#define LOCAL_GLX_FBCONFIG_ID 0x8013
+#define LOCAL_GLX_FBCONFIG_ID_SGIX 0x8013
+#define LOCAL_GLX_FLIP_COMPLETE_INTEL 0x8182
+#define LOCAL_GLX_FLOAT_COMPONENTS_NV 0x20B0
+#define LOCAL_GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2
+#define LOCAL_GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2
+#define LOCAL_GLX_FRONT_EXT 0x20DE
+#define LOCAL_GLX_FRONT_LEFT_BUFFER_BIT 0x00000001
+#define LOCAL_GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001
+#define LOCAL_GLX_FRONT_LEFT_EXT 0x20DE
+#define LOCAL_GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002
+#define LOCAL_GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002
+#define LOCAL_GLX_FRONT_RIGHT_EXT 0x20DF
+#define LOCAL_GLX_GPU_CLOCK_AMD 0x21A4
+#define LOCAL_GLX_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2
+#define LOCAL_GLX_GPU_NUM_PIPES_AMD 0x21A5
+#define LOCAL_GLX_GPU_NUM_RB_AMD 0x21A7
+#define LOCAL_GLX_GPU_NUM_SIMD_AMD 0x21A6
+#define LOCAL_GLX_GPU_NUM_SPI_AMD 0x21A8
+#define LOCAL_GLX_GPU_OPENGL_VERSION_STRING_AMD 0x1F02
+#define LOCAL_GLX_GPU_RAM_AMD 0x21A3
+#define LOCAL_GLX_GPU_RENDERER_STRING_AMD 0x1F01
+#define LOCAL_GLX_GPU_VENDOR_AMD 0x1F00
+#define LOCAL_GLX_GRAY_SCALE 0x8006
+#define LOCAL_GLX_GRAY_SCALE_EXT 0x8006
+#define LOCAL_GLX_GREEN_SIZE 9
+#define LOCAL_GLX_HEIGHT 0x801E
+#define LOCAL_GLX_HEIGHT_SGIX 0x801E
+#define LOCAL_GLX_HYPERPIPE_DISPLAY_PIPE_SGIX 0x00000001
+#define LOCAL_GLX_HYPERPIPE_ID_SGIX 0x8030
+#define LOCAL_GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX 80
+#define LOCAL_GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX 0x00000004
+#define LOCAL_GLX_HYPERPIPE_RENDER_PIPE_SGIX 0x00000002
+#define LOCAL_GLX_HYPERPIPE_STEREO_SGIX 0x00000003
+#define LOCAL_GLX_LARGEST_PBUFFER 0x801C
+#define LOCAL_GLX_LARGEST_PBUFFER_SGIX 0x801C
+#define LOCAL_GLX_LATE_SWAPS_TEAR_EXT 0x20F3
+#define LOCAL_GLX_LEVEL 3
+#define LOCAL_GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252
+#define LOCAL_GLX_MAX_PBUFFER_HEIGHT 0x8017
+#define LOCAL_GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017
+#define LOCAL_GLX_MAX_PBUFFER_PIXELS 0x8018
+#define LOCAL_GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018
+#define LOCAL_GLX_MAX_PBUFFER_WIDTH 0x8016
+#define LOCAL_GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016
+#define LOCAL_GLX_MAX_SWAP_INTERVAL_EXT 0x20F2
+#define LOCAL_GLX_MIPMAP_TEXTURE_EXT 0x20D7
+#define LOCAL_GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027
+#define LOCAL_GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026
+#define LOCAL_GLX_NONE 0x8000
+#define LOCAL_GLX_NONE_EXT 0x8000
+#define LOCAL_GLX_NON_CONFORMANT_CONFIG 0x800D
+#define LOCAL_GLX_NON_CONFORMANT_VISUAL_EXT 0x800D
+#define LOCAL_GLX_NO_EXTENSION 3
+#define LOCAL_GLX_NO_RESET_NOTIFICATION_ARB 0x8261
+#define LOCAL_GLX_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF
+#define LOCAL_GLX_NUM_VIDEO_SLOTS_NV 0x20F0
+#define LOCAL_GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A
+#define LOCAL_GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019
+#define LOCAL_GLX_PBUFFER 0x8023
+#define LOCAL_GLX_PBUFFER_BIT 0x00000004
+#define LOCAL_GLX_PBUFFER_BIT_SGIX 0x00000004
+#define LOCAL_GLX_PBUFFER_CLOBBER_MASK 0x08000000
+#define LOCAL_GLX_PBUFFER_HEIGHT 0x8040
+#define LOCAL_GLX_PBUFFER_SGIX 0x8023
+#define LOCAL_GLX_PBUFFER_WIDTH 0x8041
+#define LOCAL_GLX_PIPE_RECT_LIMITS_SGIX 0x00000002
+#define LOCAL_GLX_PIPE_RECT_SGIX 0x00000001
+#define LOCAL_GLX_PIXMAP_BIT 0x00000002
+#define LOCAL_GLX_PIXMAP_BIT_SGIX 0x00000002
+#define LOCAL_GLX_PRESERVED_CONTENTS 0x801B
+#define LOCAL_GLX_PRESERVED_CONTENTS_SGIX 0x801B
+#define LOCAL_GLX_PSEUDO_COLOR 0x8004
+#define LOCAL_GLX_PSEUDO_COLOR_EXT 0x8004
+#define LOCAL_GLX_PbufferClobber 0
+#define LOCAL_GLX_RED_SIZE 8
+#define LOCAL_GLX_RENDER_TYPE 0x8011
+#define LOCAL_GLX_RENDER_TYPE_SGIX 0x8011
+#define LOCAL_GLX_RGBA 4
+#define LOCAL_GLX_RGBA_BIT 0x00000001
+#define LOCAL_GLX_RGBA_BIT_SGIX 0x00000001
+#define LOCAL_GLX_RGBA_FLOAT_BIT_ARB 0x00000004
+#define LOCAL_GLX_RGBA_FLOAT_TYPE_ARB 0x20B9
+#define LOCAL_GLX_RGBA_TYPE 0x8014
+#define LOCAL_GLX_RGBA_TYPE_SGIX 0x8014
+#define LOCAL_GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT 0x00000008
+#define LOCAL_GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1
+#define LOCAL_GLX_SAMPLES 100001
+#define LOCAL_GLX_SAMPLES_3DFX 0x8051
+#define LOCAL_GLX_SAMPLES_ARB 100001
+#define LOCAL_GLX_SAMPLES_SGIS 100001
+#define LOCAL_GLX_SAMPLE_BUFFERS 100000
+#define LOCAL_GLX_SAMPLE_BUFFERS_3DFX 0x8050
+#define LOCAL_GLX_SAMPLE_BUFFERS_ARB 100000
+#define LOCAL_GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100
+#define LOCAL_GLX_SAMPLE_BUFFERS_SGIS 100000
+#define LOCAL_GLX_SAVED 0x8021
+#define LOCAL_GLX_SAVED_SGIX 0x8021
+#define LOCAL_GLX_SCREEN 0x800C
+#define LOCAL_GLX_SCREEN_EXT 0x800C
+#define LOCAL_GLX_SHARE_CONTEXT_EXT 0x800A
+#define LOCAL_GLX_SLOW_CONFIG 0x8001
+#define LOCAL_GLX_SLOW_VISUAL_EXT 0x8001
+#define LOCAL_GLX_STATIC_COLOR 0x8005
+#define LOCAL_GLX_STATIC_COLOR_EXT 0x8005
+#define LOCAL_GLX_STATIC_GRAY 0x8007
+#define LOCAL_GLX_STATIC_GRAY_EXT 0x8007
+#define LOCAL_GLX_STENCIL_BUFFER_BIT 0x00000040
+#define LOCAL_GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040
+#define LOCAL_GLX_STENCIL_SIZE 13
+#define LOCAL_GLX_STEREO 6
+#define LOCAL_GLX_SWAP_COPY_OML 0x8062
+#define LOCAL_GLX_SWAP_EXCHANGE_OML 0x8061
+#define LOCAL_GLX_SWAP_INTERVAL_EXT 0x20F1
+#define LOCAL_GLX_SWAP_METHOD_OML 0x8060
+#define LOCAL_GLX_SWAP_UNDEFINED_OML 0x8063
+#define LOCAL_GLX_SYNC_FRAME_SGIX 0x00000000
+#define LOCAL_GLX_SYNC_SWAP_SGIX 0x00000001
+#define LOCAL_GLX_TEXTURE_1D_BIT_EXT 0x00000001
+#define LOCAL_GLX_TEXTURE_1D_EXT 0x20DB
+#define LOCAL_GLX_TEXTURE_2D_BIT_EXT 0x00000002
+#define LOCAL_GLX_TEXTURE_2D_EXT 0x20DC
+#define LOCAL_GLX_TEXTURE_FORMAT_EXT 0x20D5
+#define LOCAL_GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8
+#define LOCAL_GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA
+#define LOCAL_GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9
+#define LOCAL_GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004
+#define LOCAL_GLX_TEXTURE_RECTANGLE_EXT 0x20DD
+#define LOCAL_GLX_TEXTURE_TARGET_EXT 0x20D6
+#define LOCAL_GLX_TRANSPARENT_ALPHA_VALUE 0x28
+#define LOCAL_GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28
+#define LOCAL_GLX_TRANSPARENT_BLUE_VALUE 0x27
+#define LOCAL_GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27
+#define LOCAL_GLX_TRANSPARENT_GREEN_VALUE 0x26
+#define LOCAL_GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26
+#define LOCAL_GLX_TRANSPARENT_INDEX 0x8009
+#define LOCAL_GLX_TRANSPARENT_INDEX_EXT 0x8009
+#define LOCAL_GLX_TRANSPARENT_INDEX_VALUE 0x24
+#define LOCAL_GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24
+#define LOCAL_GLX_TRANSPARENT_RED_VALUE 0x25
+#define LOCAL_GLX_TRANSPARENT_RED_VALUE_EXT 0x25
+#define LOCAL_GLX_TRANSPARENT_RGB 0x8008
+#define LOCAL_GLX_TRANSPARENT_RGB_EXT 0x8008
+#define LOCAL_GLX_TRANSPARENT_TYPE 0x23
+#define LOCAL_GLX_TRANSPARENT_TYPE_EXT 0x23
+#define LOCAL_GLX_TRUE_COLOR 0x8002
+#define LOCAL_GLX_TRUE_COLOR_EXT 0x8002
+#define LOCAL_GLX_UNIQUE_ID_NV 0x20CE
+#define LOCAL_GLX_USE_GL 1
+#define LOCAL_GLX_VENDOR 0x1
+#define LOCAL_GLX_VERSION 0x2
+#define LOCAL_GLX_VIDEO_OUT_ALPHA_NV 0x20C4
+#define LOCAL_GLX_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6
+#define LOCAL_GLX_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7
+#define LOCAL_GLX_VIDEO_OUT_COLOR_NV 0x20C3
+#define LOCAL_GLX_VIDEO_OUT_DEPTH_NV 0x20C5
+#define LOCAL_GLX_VIDEO_OUT_FIELD_1_NV 0x20C9
+#define LOCAL_GLX_VIDEO_OUT_FIELD_2_NV 0x20CA
+#define LOCAL_GLX_VIDEO_OUT_FRAME_NV 0x20C8
+#define LOCAL_GLX_VIDEO_OUT_STACKED_FIELDS_1_2_NV 0x20CB
+#define LOCAL_GLX_VIDEO_OUT_STACKED_FIELDS_2_1_NV 0x20CC
+#define LOCAL_GLX_VISUAL_CAVEAT_EXT 0x20
+#define LOCAL_GLX_VISUAL_ID 0x800B
+#define LOCAL_GLX_VISUAL_ID_EXT 0x800B
+#define LOCAL_GLX_VISUAL_SELECT_GROUP_SGIX 0x8028
+#define LOCAL_GLX_WIDTH 0x801D
+#define LOCAL_GLX_WIDTH_SGIX 0x801D
+#define LOCAL_GLX_WINDOW 0x8022
+#define LOCAL_GLX_WINDOW_BIT 0x00000001
+#define LOCAL_GLX_WINDOW_BIT_SGIX 0x00000001
+#define LOCAL_GLX_WINDOW_SGIX 0x8022
+#define LOCAL_GLX_X_RENDERABLE 0x8012
+#define LOCAL_GLX_X_RENDERABLE_SGIX 0x8012
+#define LOCAL_GLX_X_VISUAL_TYPE 0x22
+#define LOCAL_GLX_X_VISUAL_TYPE_EXT 0x22
+#define LOCAL_GLX_Y_INVERTED_EXT 0x20D4
+
+// WGL
+#define LOCAL_WGL_ACCELERATION_ARB 0x2003
+#define LOCAL_WGL_ACCELERATION_EXT 0x2003
+#define LOCAL_WGL_ACCESS_READ_ONLY_NV 0x00000000
+#define LOCAL_WGL_ACCESS_READ_WRITE_NV 0x00000001
+#define LOCAL_WGL_ACCESS_WRITE_DISCARD_NV 0x00000002
+#define LOCAL_WGL_ACCUM_ALPHA_BITS_ARB 0x2021
+#define LOCAL_WGL_ACCUM_ALPHA_BITS_EXT 0x2021
+#define LOCAL_WGL_ACCUM_BITS_ARB 0x201D
+#define LOCAL_WGL_ACCUM_BITS_EXT 0x201D
+#define LOCAL_WGL_ACCUM_BLUE_BITS_ARB 0x2020
+#define LOCAL_WGL_ACCUM_BLUE_BITS_EXT 0x2020
+#define LOCAL_WGL_ACCUM_GREEN_BITS_ARB 0x201F
+#define LOCAL_WGL_ACCUM_GREEN_BITS_EXT 0x201F
+#define LOCAL_WGL_ACCUM_RED_BITS_ARB 0x201E
+#define LOCAL_WGL_ACCUM_RED_BITS_EXT 0x201E
+#define LOCAL_WGL_ALPHA_BITS_ARB 0x201B
+#define LOCAL_WGL_ALPHA_BITS_EXT 0x201B
+#define LOCAL_WGL_ALPHA_SHIFT_ARB 0x201C
+#define LOCAL_WGL_ALPHA_SHIFT_EXT 0x201C
+#define LOCAL_WGL_AUX0_ARB 0x2087
+#define LOCAL_WGL_AUX1_ARB 0x2088
+#define LOCAL_WGL_AUX2_ARB 0x2089
+#define LOCAL_WGL_AUX3_ARB 0x208A
+#define LOCAL_WGL_AUX4_ARB 0x208B
+#define LOCAL_WGL_AUX5_ARB 0x208C
+#define LOCAL_WGL_AUX6_ARB 0x208D
+#define LOCAL_WGL_AUX7_ARB 0x208E
+#define LOCAL_WGL_AUX8_ARB 0x208F
+#define LOCAL_WGL_AUX9_ARB 0x2090
+#define LOCAL_WGL_AUX_BUFFERS_ARB 0x2024
+#define LOCAL_WGL_AUX_BUFFERS_EXT 0x2024
+#define LOCAL_WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002
+#define LOCAL_WGL_BACK_LEFT_ARB 0x2085
+#define LOCAL_WGL_BACK_RIGHT_ARB 0x2086
+#define LOCAL_WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3
+#define LOCAL_WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4
+#define LOCAL_WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4
+#define LOCAL_WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3
+#define LOCAL_WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2
+#define LOCAL_WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1
+#define LOCAL_WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1
+#define LOCAL_WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0
+#define LOCAL_WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071
+#define LOCAL_WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070
+#define LOCAL_WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1
+#define LOCAL_WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2
+#define LOCAL_WGL_BIND_TO_VIDEO_RGB_NV 0x20C0
+#define LOCAL_WGL_BLUE_BITS_ARB 0x2019
+#define LOCAL_WGL_BLUE_BITS_EXT 0x2019
+#define LOCAL_WGL_BLUE_SHIFT_ARB 0x201A
+#define LOCAL_WGL_BLUE_SHIFT_EXT 0x201A
+#define LOCAL_WGL_COLOR_BITS_ARB 0x2014
+#define LOCAL_WGL_COLOR_BITS_EXT 0x2014
+#define LOCAL_WGL_COLOR_SAMPLES_NV 0x20B9
+#define LOCAL_WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#define LOCAL_WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define LOCAL_WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
+#define LOCAL_WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
+#define LOCAL_WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004
+#define LOCAL_WGL_CONTEXT_FLAGS_ARB 0x2094
+#define LOCAL_WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
+#define LOCAL_WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
+#define LOCAL_WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define LOCAL_WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
+#define LOCAL_WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
+#define LOCAL_WGL_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008
+#define LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
+#define LOCAL_WGL_COVERAGE_SAMPLES_NV 0x2042
+#define LOCAL_WGL_CUBE_MAP_FACE_ARB 0x207C
+#define LOCAL_WGL_DEPTH_BITS_ARB 0x2022
+#define LOCAL_WGL_DEPTH_BITS_EXT 0x2022
+#define LOCAL_WGL_DEPTH_BUFFER_BIT_ARB 0x00000004
+#define LOCAL_WGL_DEPTH_COMPONENT_NV 0x20A7
+#define LOCAL_WGL_DEPTH_FLOAT_EXT 0x2040
+#define LOCAL_WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5
+#define LOCAL_WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050
+#define LOCAL_WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051
+#define LOCAL_WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052
+#define LOCAL_WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053
+#define LOCAL_WGL_DOUBLE_BUFFER_ARB 0x2011
+#define LOCAL_WGL_DOUBLE_BUFFER_EXT 0x2011
+#define LOCAL_WGL_DRAW_TO_BITMAP_ARB 0x2002
+#define LOCAL_WGL_DRAW_TO_BITMAP_EXT 0x2002
+#define LOCAL_WGL_DRAW_TO_PBUFFER_ARB 0x202D
+#define LOCAL_WGL_DRAW_TO_PBUFFER_EXT 0x202D
+#define LOCAL_WGL_DRAW_TO_WINDOW_ARB 0x2001
+#define LOCAL_WGL_DRAW_TO_WINDOW_EXT 0x2001
+#define LOCAL_WGL_FLOAT_COMPONENTS_NV 0x20B0
+#define LOCAL_WGL_FONT_LINES 0
+#define LOCAL_WGL_FONT_POLYGONS 1
+#define LOCAL_WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
+#define LOCAL_WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9
+#define LOCAL_WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001
+#define LOCAL_WGL_FRONT_LEFT_ARB 0x2083
+#define LOCAL_WGL_FRONT_RIGHT_ARB 0x2084
+#define LOCAL_WGL_FULL_ACCELERATION_ARB 0x2027
+#define LOCAL_WGL_FULL_ACCELERATION_EXT 0x2027
+#define LOCAL_WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F
+#define LOCAL_WGL_GAMMA_TABLE_SIZE_I3D 0x204E
+#define LOCAL_WGL_GENERIC_ACCELERATION_ARB 0x2026
+#define LOCAL_WGL_GENERIC_ACCELERATION_EXT 0x2026
+#define LOCAL_WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049
+#define LOCAL_WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048
+#define LOCAL_WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C
+#define LOCAL_WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A
+#define LOCAL_WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B
+#define LOCAL_WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D 0x2046
+#define LOCAL_WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D 0x2045
+#define LOCAL_WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D 0x2047
+#define LOCAL_WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044
+#define LOCAL_WGL_GPU_CLOCK_AMD 0x21A4
+#define LOCAL_WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2
+#define LOCAL_WGL_GPU_NUM_PIPES_AMD 0x21A5
+#define LOCAL_WGL_GPU_NUM_RB_AMD 0x21A7
+#define LOCAL_WGL_GPU_NUM_SIMD_AMD 0x21A6
+#define LOCAL_WGL_GPU_NUM_SPI_AMD 0x21A8
+#define LOCAL_WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02
+#define LOCAL_WGL_GPU_RAM_AMD 0x21A3
+#define LOCAL_WGL_GPU_RENDERER_STRING_AMD 0x1F01
+#define LOCAL_WGL_GPU_VENDOR_AMD 0x1F00
+#define LOCAL_WGL_GREEN_BITS_ARB 0x2017
+#define LOCAL_WGL_GREEN_BITS_EXT 0x2017
+#define LOCAL_WGL_GREEN_SHIFT_ARB 0x2018
+#define LOCAL_WGL_GREEN_SHIFT_EXT 0x2018
+#define LOCAL_WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002
+#define LOCAL_WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001
+#define LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
+#define LOCAL_WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
+#define LOCAL_WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030
+#define LOCAL_WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
+#define LOCAL_WGL_MAX_PBUFFER_PIXELS_EXT 0x202E
+#define LOCAL_WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
+#define LOCAL_WGL_MAX_PBUFFER_WIDTH_EXT 0x202F
+#define LOCAL_WGL_MIPMAP_LEVEL_ARB 0x207B
+#define LOCAL_WGL_MIPMAP_TEXTURE_ARB 0x2074
+#define LOCAL_WGL_NEED_PALETTE_ARB 0x2004
+#define LOCAL_WGL_NEED_PALETTE_EXT 0x2004
+#define LOCAL_WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
+#define LOCAL_WGL_NEED_SYSTEM_PALETTE_EXT 0x2005
+#define LOCAL_WGL_NO_ACCELERATION_ARB 0x2025
+#define LOCAL_WGL_NO_ACCELERATION_EXT 0x2025
+#define LOCAL_WGL_NO_RESET_NOTIFICATION_ARB 0x8261
+#define LOCAL_WGL_NO_TEXTURE_ARB 0x2077
+#define LOCAL_WGL_NUMBER_OVERLAYS_ARB 0x2008
+#define LOCAL_WGL_NUMBER_OVERLAYS_EXT 0x2008
+#define LOCAL_WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
+#define LOCAL_WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000
+#define LOCAL_WGL_NUMBER_UNDERLAYS_ARB 0x2009
+#define LOCAL_WGL_NUMBER_UNDERLAYS_EXT 0x2009
+#define LOCAL_WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF
+#define LOCAL_WGL_NUM_VIDEO_SLOTS_NV 0x20F0
+#define LOCAL_WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032
+#define LOCAL_WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031
+#define LOCAL_WGL_PBUFFER_HEIGHT_ARB 0x2035
+#define LOCAL_WGL_PBUFFER_HEIGHT_EXT 0x2035
+#define LOCAL_WGL_PBUFFER_LARGEST_ARB 0x2033
+#define LOCAL_WGL_PBUFFER_LARGEST_EXT 0x2033
+#define LOCAL_WGL_PBUFFER_LOST_ARB 0x2036
+#define LOCAL_WGL_PBUFFER_WIDTH_ARB 0x2034
+#define LOCAL_WGL_PBUFFER_WIDTH_EXT 0x2034
+#define LOCAL_WGL_PIXEL_TYPE_ARB 0x2013
+#define LOCAL_WGL_PIXEL_TYPE_EXT 0x2013
+#define LOCAL_WGL_RED_BITS_ARB 0x2015
+#define LOCAL_WGL_RED_BITS_EXT 0x2015
+#define LOCAL_WGL_RED_SHIFT_ARB 0x2016
+#define LOCAL_WGL_RED_SHIFT_EXT 0x2016
+#define LOCAL_WGL_SAMPLES_3DFX 0x2061
+#define LOCAL_WGL_SAMPLES_ARB 0x2042
+#define LOCAL_WGL_SAMPLES_EXT 0x2042
+#define LOCAL_WGL_SAMPLE_BUFFERS_3DFX 0x2060
+#define LOCAL_WGL_SAMPLE_BUFFERS_ARB 0x2041
+#define LOCAL_WGL_SAMPLE_BUFFERS_EXT 0x2041
+#define LOCAL_WGL_SHARE_ACCUM_ARB 0x200E
+#define LOCAL_WGL_SHARE_ACCUM_EXT 0x200E
+#define LOCAL_WGL_SHARE_DEPTH_ARB 0x200C
+#define LOCAL_WGL_SHARE_DEPTH_EXT 0x200C
+#define LOCAL_WGL_SHARE_STENCIL_ARB 0x200D
+#define LOCAL_WGL_SHARE_STENCIL_EXT 0x200D
+#define LOCAL_WGL_STENCIL_BITS_ARB 0x2023
+#define LOCAL_WGL_STENCIL_BITS_EXT 0x2023
+#define LOCAL_WGL_STENCIL_BUFFER_BIT_ARB 0x00000008
+#define LOCAL_WGL_STEREO_ARB 0x2012
+#define LOCAL_WGL_STEREO_EMITTER_DISABLE_3DL 0x2056
+#define LOCAL_WGL_STEREO_EMITTER_ENABLE_3DL 0x2055
+#define LOCAL_WGL_STEREO_EXT 0x2012
+#define LOCAL_WGL_STEREO_POLARITY_INVERT_3DL 0x2058
+#define LOCAL_WGL_STEREO_POLARITY_NORMAL_3DL 0x2057
+#define LOCAL_WGL_SUPPORT_GDI_ARB 0x200F
+#define LOCAL_WGL_SUPPORT_GDI_EXT 0x200F
+#define LOCAL_WGL_SUPPORT_OPENGL_ARB 0x2010
+#define LOCAL_WGL_SUPPORT_OPENGL_EXT 0x2010
+#define LOCAL_WGL_SWAP_COPY_ARB 0x2029
+#define LOCAL_WGL_SWAP_COPY_EXT 0x2029
+#define LOCAL_WGL_SWAP_EXCHANGE_ARB 0x2028
+#define LOCAL_WGL_SWAP_EXCHANGE_EXT 0x2028
+#define LOCAL_WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
+#define LOCAL_WGL_SWAP_LAYER_BUFFERS_EXT 0x2006
+#define LOCAL_WGL_SWAP_MAIN_PLANE 0x00000001
+#define LOCAL_WGL_SWAP_METHOD_ARB 0x2007
+#define LOCAL_WGL_SWAP_METHOD_EXT 0x2007
+#define LOCAL_WGL_SWAP_OVERLAY1 0x00000002
+#define LOCAL_WGL_SWAP_OVERLAY10 0x00000400
+#define LOCAL_WGL_SWAP_OVERLAY11 0x00000800
+#define LOCAL_WGL_SWAP_OVERLAY12 0x00001000
+#define LOCAL_WGL_SWAP_OVERLAY13 0x00002000
+#define LOCAL_WGL_SWAP_OVERLAY14 0x00004000
+#define LOCAL_WGL_SWAP_OVERLAY15 0x00008000
+#define LOCAL_WGL_SWAP_OVERLAY2 0x00000004
+#define LOCAL_WGL_SWAP_OVERLAY3 0x00000008
+#define LOCAL_WGL_SWAP_OVERLAY4 0x00000010
+#define LOCAL_WGL_SWAP_OVERLAY5 0x00000020
+#define LOCAL_WGL_SWAP_OVERLAY6 0x00000040
+#define LOCAL_WGL_SWAP_OVERLAY7 0x00000080
+#define LOCAL_WGL_SWAP_OVERLAY8 0x00000100
+#define LOCAL_WGL_SWAP_OVERLAY9 0x00000200
+#define LOCAL_WGL_SWAP_UNDEFINED_ARB 0x202A
+#define LOCAL_WGL_SWAP_UNDEFINED_EXT 0x202A
+#define LOCAL_WGL_SWAP_UNDERLAY1 0x00010000
+#define LOCAL_WGL_SWAP_UNDERLAY10 0x02000000
+#define LOCAL_WGL_SWAP_UNDERLAY11 0x04000000
+#define LOCAL_WGL_SWAP_UNDERLAY12 0x08000000
+#define LOCAL_WGL_SWAP_UNDERLAY13 0x10000000
+#define LOCAL_WGL_SWAP_UNDERLAY14 0x20000000
+#define LOCAL_WGL_SWAP_UNDERLAY15 0x40000000
+#define LOCAL_WGL_SWAP_UNDERLAY2 0x00020000
+#define LOCAL_WGL_SWAP_UNDERLAY3 0x00040000
+#define LOCAL_WGL_SWAP_UNDERLAY4 0x00080000
+#define LOCAL_WGL_SWAP_UNDERLAY5 0x00100000
+#define LOCAL_WGL_SWAP_UNDERLAY6 0x00200000
+#define LOCAL_WGL_SWAP_UNDERLAY7 0x00400000
+#define LOCAL_WGL_SWAP_UNDERLAY8 0x00800000
+#define LOCAL_WGL_SWAP_UNDERLAY9 0x01000000
+#define LOCAL_WGL_TEXTURE_1D_ARB 0x2079
+#define LOCAL_WGL_TEXTURE_2D_ARB 0x207A
+#define LOCAL_WGL_TEXTURE_CUBE_MAP_ARB 0x2078
+#define LOCAL_WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E
+#define LOCAL_WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080
+#define LOCAL_WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082
+#define LOCAL_WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D
+#define LOCAL_WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F
+#define LOCAL_WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081
+#define LOCAL_WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6
+#define LOCAL_WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8
+#define LOCAL_WGL_TEXTURE_FLOAT_RGB_NV 0x20B7
+#define LOCAL_WGL_TEXTURE_FLOAT_RG_NV 0x20B6
+#define LOCAL_WGL_TEXTURE_FLOAT_R_NV 0x20B5
+#define LOCAL_WGL_TEXTURE_FORMAT_ARB 0x2072
+#define LOCAL_WGL_TEXTURE_RECTANGLE_NV 0x20A2
+#define LOCAL_WGL_TEXTURE_RGBA_ARB 0x2076
+#define LOCAL_WGL_TEXTURE_RGB_ARB 0x2075
+#define LOCAL_WGL_TEXTURE_TARGET_ARB 0x2073
+#define LOCAL_WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
+#define LOCAL_WGL_TRANSPARENT_ARB 0x200A
+#define LOCAL_WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
+#define LOCAL_WGL_TRANSPARENT_EXT 0x200A
+#define LOCAL_WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
+#define LOCAL_WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
+#define LOCAL_WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
+#define LOCAL_WGL_TRANSPARENT_VALUE_EXT 0x200B
+#define LOCAL_WGL_TYPE_COLORINDEX_ARB 0x202C
+#define LOCAL_WGL_TYPE_COLORINDEX_EXT 0x202C
+#define LOCAL_WGL_TYPE_RGBA_ARB 0x202B
+#define LOCAL_WGL_TYPE_RGBA_EXT 0x202B
+#define LOCAL_WGL_TYPE_RGBA_FLOAT_ARB 0x21A0
+#define LOCAL_WGL_TYPE_RGBA_FLOAT_ATI 0x21A0
+#define LOCAL_WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8
+#define LOCAL_WGL_UNIQUE_ID_NV 0x20CE
+#define LOCAL_WGL_VIDEO_OUT_ALPHA_NV 0x20C4
+#define LOCAL_WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6
+#define LOCAL_WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7
+#define LOCAL_WGL_VIDEO_OUT_COLOR_NV 0x20C3
+#define LOCAL_WGL_VIDEO_OUT_DEPTH_NV 0x20C5
+#define LOCAL_WGL_VIDEO_OUT_FIELD_1 0x20C9
+#define LOCAL_WGL_VIDEO_OUT_FIELD_2 0x20CA
+#define LOCAL_WGL_VIDEO_OUT_FRAME 0x20C8
+#define LOCAL_WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB
+#define LOCAL_WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC
+
+#endif // GLCONSTS_H_
diff --git a/gfx/gl/GLContext.cpp b/gfx/gl/GLContext.cpp
new file mode 100644
index 0000000000..23090ef989
--- /dev/null
+++ b/gfx/gl/GLContext.cpp
@@ -0,0 +1,3150 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "GLContext.h"
+
+#include <algorithm>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <vector>
+#ifdef MOZ_WIDGET_ANDROID
+#include <sys/mman.h>
+#endif
+
+#include "GLBlitHelper.h"
+#include "GLReadTexImageHelper.h"
+#include "GLScreenBuffer.h"
+
+#include "gfxCrashReporterUtils.h"
+#include "gfxEnv.h"
+#include "gfxUtils.h"
+#include "GLContextProvider.h"
+#include "GLTextureImage.h"
+#include "nsPrintfCString.h"
+#include "nsThreadUtils.h"
+#include "prenv.h"
+#include "prlink.h"
+#include "ScopedGLHelpers.h"
+#include "SharedSurfaceGL.h"
+#include "GfxTexturesReporter.h"
+#include "TextureGarbageBin.h"
+#include "gfx2DGlue.h"
+#include "gfxPrefs.h"
+#include "mozilla/IntegerPrintfMacros.h"
+#include "mozilla/gfx/Logging.h"
+
+#include "OGLShaderProgram.h" // for ShaderProgramType
+
+#include "mozilla/DebugOnly.h"
+
+#ifdef XP_MACOSX
+#include <CoreServices/CoreServices.h>
+#endif
+
+#if defined(MOZ_WIDGET_COCOA)
+#include "nsCocoaFeatures.h"
+#endif
+
+#ifdef MOZ_WIDGET_ANDROID
+#include "AndroidBridge.h"
+#endif
+
+namespace mozilla {
+namespace gl {
+
+using namespace mozilla::gfx;
+using namespace mozilla::layers;
+
+#ifdef MOZ_GL_DEBUG
+unsigned GLContext::sCurrentGLContextTLS = -1;
+#endif
+
+// If adding defines, don't forget to undefine symbols. See #undef block below.
+#define CORE_SYMBOL(x) { (PRFuncPtr*) &mSymbols.f##x, { #x, nullptr } }
+#define CORE_EXT_SYMBOL2(x,y,z) { (PRFuncPtr*) &mSymbols.f##x, { #x, #x #y, #x #z, nullptr } }
+#define EXT_SYMBOL2(x,y,z) { (PRFuncPtr*) &mSymbols.f##x, { #x #y, #x #z, nullptr } }
+#define EXT_SYMBOL3(x,y,z,w) { (PRFuncPtr*) &mSymbols.f##x, { #x #y, #x #z, #x #w, nullptr } }
+#define END_SYMBOLS { nullptr, { nullptr } }
+
+// should match the order of GLExtensions, and be null-terminated.
+static const char* const sExtensionNames[] = {
+ "NO_EXTENSION",
+ "GL_AMD_compressed_ATC_texture",
+ "GL_ANGLE_depth_texture",
+ "GL_ANGLE_framebuffer_blit",
+ "GL_ANGLE_framebuffer_multisample",
+ "GL_ANGLE_instanced_arrays",
+ "GL_ANGLE_texture_compression_dxt3",
+ "GL_ANGLE_texture_compression_dxt5",
+ "GL_ANGLE_timer_query",
+ "GL_APPLE_client_storage",
+ "GL_APPLE_framebuffer_multisample",
+ "GL_APPLE_sync",
+ "GL_APPLE_texture_range",
+ "GL_APPLE_vertex_array_object",
+ "GL_ARB_ES2_compatibility",
+ "GL_ARB_ES3_compatibility",
+ "GL_ARB_color_buffer_float",
+ "GL_ARB_copy_buffer",
+ "GL_ARB_depth_texture",
+ "GL_ARB_draw_buffers",
+ "GL_ARB_draw_instanced",
+ "GL_ARB_framebuffer_object",
+ "GL_ARB_framebuffer_sRGB",
+ "GL_ARB_geometry_shader4",
+ "GL_ARB_half_float_pixel",
+ "GL_ARB_instanced_arrays",
+ "GL_ARB_internalformat_query",
+ "GL_ARB_invalidate_subdata",
+ "GL_ARB_map_buffer_range",
+ "GL_ARB_occlusion_query2",
+ "GL_ARB_pixel_buffer_object",
+ "GL_ARB_robustness",
+ "GL_ARB_sampler_objects",
+ "GL_ARB_seamless_cube_map",
+ "GL_ARB_shader_texture_lod",
+ "GL_ARB_sync",
+ "GL_ARB_texture_compression",
+ "GL_ARB_texture_float",
+ "GL_ARB_texture_non_power_of_two",
+ "GL_ARB_texture_rectangle",
+ "GL_ARB_texture_rg",
+ "GL_ARB_texture_storage",
+ "GL_ARB_texture_swizzle",
+ "GL_ARB_timer_query",
+ "GL_ARB_transform_feedback2",
+ "GL_ARB_uniform_buffer_object",
+ "GL_ARB_vertex_array_object",
+ "GL_EXT_bgra",
+ "GL_EXT_blend_minmax",
+ "GL_EXT_color_buffer_float",
+ "GL_EXT_color_buffer_half_float",
+ "GL_EXT_copy_texture",
+ "GL_EXT_disjoint_timer_query",
+ "GL_EXT_draw_buffers",
+ "GL_EXT_draw_buffers2",
+ "GL_EXT_draw_instanced",
+ "GL_EXT_draw_range_elements",
+ "GL_EXT_frag_depth",
+ "GL_EXT_framebuffer_blit",
+ "GL_EXT_framebuffer_multisample",
+ "GL_EXT_framebuffer_object",
+ "GL_EXT_framebuffer_sRGB",
+ "GL_EXT_gpu_shader4",
+ "GL_EXT_multisampled_render_to_texture",
+ "GL_EXT_occlusion_query_boolean",
+ "GL_EXT_packed_depth_stencil",
+ "GL_EXT_read_format_bgra",
+ "GL_EXT_robustness",
+ "GL_EXT_sRGB",
+ "GL_EXT_sRGB_write_control",
+ "GL_EXT_shader_texture_lod",
+ "GL_EXT_texture3D",
+ "GL_EXT_texture_compression_dxt1",
+ "GL_EXT_texture_compression_s3tc",
+ "GL_EXT_texture_filter_anisotropic",
+ "GL_EXT_texture_format_BGRA8888",
+ "GL_EXT_texture_sRGB",
+ "GL_EXT_texture_storage",
+ "GL_EXT_timer_query",
+ "GL_EXT_transform_feedback",
+ "GL_EXT_unpack_subimage",
+ "GL_IMG_read_format",
+ "GL_IMG_texture_compression_pvrtc",
+ "GL_IMG_texture_npot",
+ "GL_KHR_debug",
+ "GL_NV_draw_instanced",
+ "GL_NV_fence",
+ "GL_NV_framebuffer_blit",
+ "GL_NV_geometry_program4",
+ "GL_NV_half_float",
+ "GL_NV_instanced_arrays",
+ "GL_NV_primitive_restart",
+ "GL_NV_texture_barrier",
+ "GL_NV_transform_feedback",
+ "GL_NV_transform_feedback2",
+ "GL_OES_EGL_image",
+ "GL_OES_EGL_image_external",
+ "GL_OES_EGL_sync",
+ "GL_OES_compressed_ETC1_RGB8_texture",
+ "GL_OES_depth24",
+ "GL_OES_depth32",
+ "GL_OES_depth_texture",
+ "GL_OES_element_index_uint",
+ "GL_OES_framebuffer_object",
+ "GL_OES_packed_depth_stencil",
+ "GL_OES_rgb8_rgba8",
+ "GL_OES_standard_derivatives",
+ "GL_OES_stencil8",
+ "GL_OES_texture_3D",
+ "GL_OES_texture_float",
+ "GL_OES_texture_float_linear",
+ "GL_OES_texture_half_float",
+ "GL_OES_texture_half_float_linear",
+ "GL_OES_texture_npot",
+ "GL_OES_vertex_array_object"
+};
+
+static bool
+ParseGLSLVersion(GLContext* gl, uint32_t* out_version)
+{
+ if (gl->fGetError() != LOCAL_GL_NO_ERROR) {
+ MOZ_ASSERT(false, "An OpenGL error has been triggered before.");
+ return false;
+ }
+
+ /**
+ * OpenGL 2.x, 3.x, 4.x specifications:
+ * The VERSION and SHADING_LANGUAGE_VERSION strings are laid out as follows:
+ *
+ * <version number><space><vendor-specific information>
+ *
+ * The version number is either of the form major_number.minor_number or
+ * major_number.minor_number.release_number, where the numbers all have
+ * one or more digits.
+ *
+ * SHADING_LANGUAGE_VERSION is *almost* identical to VERSION. The
+ * difference is that the minor version always has two digits and the
+ * prefix has an additional 'GLSL ES'
+ *
+ *
+ * OpenGL ES 2.0, 3.0 specifications:
+ * The VERSION string is laid out as follows:
+ *
+ * "OpenGL ES N.M vendor-specific information"
+ *
+ * The version number is either of the form major_number.minor_number or
+ * major_number.minor_number.release_number, where the numbers all have
+ * one or more digits.
+ *
+ *
+ * Note:
+ * We don't care about release_number.
+ */
+ const char* versionString = (const char*) gl->fGetString(LOCAL_GL_SHADING_LANGUAGE_VERSION);
+
+ if (gl->fGetError() != LOCAL_GL_NO_ERROR) {
+ MOZ_ASSERT(false, "glGetString(GL_SHADING_LANGUAGE_VERSION) has generated an error");
+ return false;
+ }
+
+ if (!versionString) {
+ // This happens on the Android emulators. We'll just return 100
+ *out_version = 100;
+ return true;
+ }
+
+ const auto fnSkipPrefix = [&versionString](const char* prefix) {
+ const auto len = strlen(prefix);
+ if (strncmp(versionString, prefix, len) == 0)
+ versionString += len;
+ };
+
+ const char kGLESVersionPrefix[] = "OpenGL ES GLSL ES";
+ fnSkipPrefix(kGLESVersionPrefix);
+
+ if (gl->WorkAroundDriverBugs()) {
+ // Nexus 7 2013 (bug 1234441)
+ const char kBadGLESVersionPrefix[] = "OpenGL ES GLSL";
+ fnSkipPrefix(kBadGLESVersionPrefix);
+ }
+
+ const char* itr = versionString;
+ char* end = nullptr;
+ auto majorVersion = strtol(itr, &end, 10);
+
+ if (!end) {
+ MOZ_ASSERT(false, "Failed to parse the GL major version number.");
+ return false;
+ }
+
+ if (*end != '.') {
+ MOZ_ASSERT(false, "Failed to parse GL's major-minor version number separator.");
+ return false;
+ }
+
+ // we skip the '.' between the major and the minor version
+ itr = end + 1;
+ end = nullptr;
+
+ auto minorVersion = strtol(itr, &end, 10);
+ if (!end) {
+ MOZ_ASSERT(false, "Failed to parse GL's minor version number.");
+ return false;
+ }
+
+ if (majorVersion <= 0 || majorVersion >= 100) {
+ MOZ_ASSERT(false, "Invalid major version.");
+ return false;
+ }
+
+ if (minorVersion < 0 || minorVersion >= 100) {
+ MOZ_ASSERT(false, "Invalid minor version.");
+ return false;
+ }
+
+ *out_version = (uint32_t) majorVersion * 100 + (uint32_t) minorVersion;
+ return true;
+}
+
+static bool
+ParseGLVersion(GLContext* gl, uint32_t* out_version)
+{
+ if (gl->fGetError() != LOCAL_GL_NO_ERROR) {
+ MOZ_ASSERT(false, "An OpenGL error has been triggered before.");
+ return false;
+ }
+
+ /**
+ * B2G emulator bug work around: The emulator implements OpenGL ES 2.0 on
+ * OpenGL 3.2. The bug is that GetIntegerv(LOCAL_GL_{MAJOR,MINOR}_VERSION)
+ * returns OpenGL 3.2 instead of generating an error.
+ */
+ if (!gl->IsGLES()) {
+ /**
+ * OpenGL 3.1 and OpenGL ES 3.0 both introduce GL_{MAJOR,MINOR}_VERSION
+ * with GetIntegerv. So we first try those constants even though we
+ * might not have an OpenGL context supporting them, as this is a
+ * better way than parsing GL_VERSION.
+ */
+ GLint majorVersion = 0;
+ GLint minorVersion = 0;
+
+ const bool ok = (gl->GetPotentialInteger(LOCAL_GL_MAJOR_VERSION,
+ &majorVersion) &&
+ gl->GetPotentialInteger(LOCAL_GL_MINOR_VERSION,
+ &minorVersion));
+
+ // If it's not an OpenGL (ES) 3.0 context, we will have an error
+ if (ok &&
+ majorVersion > 0 &&
+ minorVersion >= 0)
+ {
+ *out_version = majorVersion * 100 + minorVersion * 10;
+ return true;
+ }
+ }
+
+ /**
+ * We were not able to use GL_{MAJOR,MINOR}_VERSION, so we parse
+ * GL_VERSION.
+ *
+ *
+ * OpenGL 2.x, 3.x, 4.x specifications:
+ * The VERSION and SHADING_LANGUAGE_VERSION strings are laid out as follows:
+ *
+ * <version number><space><vendor-specific information>
+ *
+ * The version number is either of the form major_number.minor_number or
+ * major_number.minor_number.release_number, where the numbers all have
+ * one or more digits.
+ *
+ *
+ * OpenGL ES 2.0, 3.0 specifications:
+ * The VERSION string is laid out as follows:
+ *
+ * "OpenGL ES N.M vendor-specific information"
+ *
+ * The version number is either of the form major_number.minor_number or
+ * major_number.minor_number.release_number, where the numbers all have
+ * one or more digits.
+ *
+ *
+ * Note:
+ * We don't care about release_number.
+ */
+ const char* versionString = (const char*)gl->fGetString(LOCAL_GL_VERSION);
+
+ if (gl->fGetError() != LOCAL_GL_NO_ERROR) {
+ MOZ_ASSERT(false, "glGetString(GL_VERSION) has generated an error");
+ return false;
+ } else if (!versionString) {
+ MOZ_ASSERT(false, "glGetString(GL_VERSION) has returned 0");
+ return false;
+ }
+
+ const char kGLESVersionPrefix[] = "OpenGL ES ";
+ if (strncmp(versionString, kGLESVersionPrefix, strlen(kGLESVersionPrefix)) == 0) {
+ versionString += strlen(kGLESVersionPrefix);
+ }
+
+ const char* itr = versionString;
+ char* end = nullptr;
+ auto majorVersion = strtol(itr, &end, 10);
+
+ if (!end) {
+ MOZ_ASSERT(false, "Failed to parse the GL major version number.");
+ return false;
+ } else if (*end != '.') {
+ MOZ_ASSERT(false, "Failed to parse GL's major-minor version number separator.");
+ return false;
+ }
+
+ // we skip the '.' between the major and the minor version
+ itr = end + 1;
+
+ end = nullptr;
+
+ auto minorVersion = strtol(itr, &end, 10);
+ if (!end) {
+ MOZ_ASSERT(false, "Failed to parse GL's minor version number.");
+ return false;
+ }
+
+ if (majorVersion <= 0 || majorVersion >= 100) {
+ MOZ_ASSERT(false, "Invalid major version.");
+ return false;
+ } else if (minorVersion < 0 || minorVersion >= 10) {
+ MOZ_ASSERT(false, "Invalid minor version.");
+ return false;
+ }
+
+ *out_version = (uint32_t)majorVersion * 100 + (uint32_t)minorVersion * 10;
+ return true;
+}
+
+static uint8_t
+ChooseDebugFlags(CreateContextFlags createFlags)
+{
+ uint8_t debugFlags = 0;
+
+#ifdef MOZ_GL_DEBUG
+ if (gfxEnv::GlDebug()) {
+ debugFlags |= GLContext::DebugFlagEnabled;
+ }
+
+ // Enables extra verbose output, informing of the start and finish of every GL call.
+ // Useful e.g. to record information to investigate graphics system crashes/lockups
+ if (gfxEnv::GlDebugVerbose()) {
+ debugFlags |= GLContext::DebugFlagTrace;
+ }
+
+ // Aborts on GL error. Can be useful to debug quicker code that is known not to
+ // generate any GL error in principle.
+ bool abortOnError = false;
+
+ if (createFlags & CreateContextFlags::NO_VALIDATION) {
+ abortOnError = true;
+
+ const auto fnStringsMatch = [](const char* a, const char* b) {
+ return strcmp(a, b) == 0;
+ };
+
+ const char* envAbortOnError = PR_GetEnv("MOZ_GL_DEBUG_ABORT_ON_ERROR");
+ if (envAbortOnError && fnStringsMatch(envAbortOnError, "0")) {
+ abortOnError = false;
+ }
+ }
+
+ if (abortOnError) {
+ debugFlags |= GLContext::DebugFlagAbortOnError;
+ }
+#endif
+
+ return debugFlags;
+}
+
+GLContext::GLContext(CreateContextFlags flags, const SurfaceCaps& caps,
+ GLContext* sharedContext, bool isOffscreen)
+ : mIsOffscreen(isOffscreen),
+ mContextLost(false),
+ mVersion(0),
+ mProfile(ContextProfile::Unknown),
+ mShadingLanguageVersion(0),
+ mVendor(GLVendor::Other),
+ mRenderer(GLRenderer::Other),
+ mTopError(LOCAL_GL_NO_ERROR),
+ mDebugFlags(ChooseDebugFlags(flags)),
+ mSharedContext(sharedContext),
+ mCaps(caps),
+ mScreen(nullptr),
+ mLockedSurface(nullptr),
+ mMaxTextureSize(0),
+ mMaxCubeMapTextureSize(0),
+ mMaxTextureImageSize(0),
+ mMaxRenderbufferSize(0),
+ mMaxSamples(0),
+ mNeedsTextureSizeChecks(false),
+ mNeedsFlushBeforeDeleteFB(false),
+ mTextureAllocCrashesOnMapFailure(false),
+ mNeedsCheckAfterAttachTextureToFb(false),
+ mWorkAroundDriverBugs(true),
+ mHeavyGLCallsSinceLastFlush(false)
+{
+ mMaxViewportDims[0] = 0;
+ mMaxViewportDims[1] = 0;
+ mOwningThreadId = PlatformThread::CurrentId();
+}
+
+GLContext::~GLContext() {
+ NS_ASSERTION(IsDestroyed(), "GLContext implementation must call MarkDestroyed in destructor!");
+#ifdef MOZ_GL_DEBUG
+ if (mSharedContext) {
+ GLContext* tip = mSharedContext;
+ while (tip->mSharedContext)
+ tip = tip->mSharedContext;
+ tip->SharedContextDestroyed(this);
+ tip->ReportOutstandingNames();
+ } else {
+ ReportOutstandingNames();
+ }
+#endif
+}
+
+/*static*/ void
+GLContext::StaticDebugCallback(GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar* message,
+ const GLvoid* userParam)
+{
+ GLContext* gl = (GLContext*)userParam;
+ gl->DebugCallback(source, type, id, severity, length, message);
+}
+
+static void
+ClearSymbols(const GLLibraryLoader::SymLoadStruct* symbols)
+{
+ while (symbols->symPointer) {
+ *symbols->symPointer = nullptr;
+ symbols++;
+ }
+}
+
+bool
+GLContext::InitWithPrefix(const char* prefix, bool trygl)
+{
+ MOZ_RELEASE_ASSERT(!mSymbols.fBindFramebuffer,
+ "GFX: InitWithPrefix should only be called once.");
+
+ ScopedGfxFeatureReporter reporter("GL Context");
+
+ if (!InitWithPrefixImpl(prefix, trygl)) {
+ // If initialization fails, zero the symbols to avoid hard-to-understand bugs.
+ mSymbols.Zero();
+ NS_WARNING("GLContext::InitWithPrefix failed!");
+ return false;
+ }
+
+ reporter.SetSuccessful();
+ return true;
+}
+
+static bool
+LoadGLSymbols(GLContext* gl, const char* prefix, bool trygl,
+ const GLLibraryLoader::SymLoadStruct* list, const char* desc)
+{
+ if (gl->LoadSymbols(list, trygl, prefix))
+ return true;
+
+ ClearSymbols(list);
+
+ if (desc) {
+ const nsPrintfCString err("Failed to load symbols for %s.", desc);
+ NS_ERROR(err.BeginReading());
+ }
+ return false;
+}
+
+bool
+GLContext::LoadExtSymbols(const char* prefix, bool trygl, const SymLoadStruct* list,
+ GLExtensions ext)
+{
+ const char* extName = sExtensionNames[size_t(ext)];
+ if (!LoadGLSymbols(this, prefix, trygl, list, extName)) {
+ MarkExtensionUnsupported(ext);
+ return false;
+ }
+ return true;
+};
+
+bool
+GLContext::LoadFeatureSymbols(const char* prefix, bool trygl, const SymLoadStruct* list,
+ GLFeature feature)
+{
+ const char* featureName = GetFeatureName(feature);
+ if (!LoadGLSymbols(this, prefix, trygl, list, featureName)) {
+ MarkUnsupported(feature);
+ return false;
+ }
+ return true;
+};
+
+bool
+GLContext::InitWithPrefixImpl(const char* prefix, bool trygl)
+{
+ mWorkAroundDriverBugs = gfxPrefs::WorkAroundDriverBugs();
+
+ const SymLoadStruct coreSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fActiveTexture, { "ActiveTexture", "ActiveTextureARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fAttachShader, { "AttachShader", "AttachShaderARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fBindAttribLocation, { "BindAttribLocation", "BindAttribLocationARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fBindBuffer, { "BindBuffer", "BindBufferARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fBindTexture, { "BindTexture", "BindTextureARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fBlendColor, { "BlendColor", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fBlendEquation, { "BlendEquation", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fBlendEquationSeparate, { "BlendEquationSeparate", "BlendEquationSeparateEXT", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fBlendFunc, { "BlendFunc", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fBlendFuncSeparate, { "BlendFuncSeparate", "BlendFuncSeparateEXT", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fBufferData, { "BufferData", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fBufferSubData, { "BufferSubData", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fClear, { "Clear", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fClearColor, { "ClearColor", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fClearStencil, { "ClearStencil", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fColorMask, { "ColorMask", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fCompressedTexImage2D, {"CompressedTexImage2D", nullptr} },
+ { (PRFuncPtr*) &mSymbols.fCompressedTexSubImage2D, {"CompressedTexSubImage2D", nullptr} },
+ { (PRFuncPtr*) &mSymbols.fCullFace, { "CullFace", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDetachShader, { "DetachShader", "DetachShaderARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDepthFunc, { "DepthFunc", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDepthMask, { "DepthMask", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDisable, { "Disable", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDisableVertexAttribArray, { "DisableVertexAttribArray", "DisableVertexAttribArrayARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDrawArrays, { "DrawArrays", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDrawElements, { "DrawElements", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fEnable, { "Enable", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fEnableVertexAttribArray, { "EnableVertexAttribArray", "EnableVertexAttribArrayARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fFinish, { "Finish", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fFlush, { "Flush", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fFrontFace, { "FrontFace", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetActiveAttrib, { "GetActiveAttrib", "GetActiveAttribARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetActiveUniform, { "GetActiveUniform", "GetActiveUniformARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetAttachedShaders, { "GetAttachedShaders", "GetAttachedShadersARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetAttribLocation, { "GetAttribLocation", "GetAttribLocationARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetIntegerv, { "GetIntegerv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetFloatv, { "GetFloatv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetBooleanv, { "GetBooleanv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetBufferParameteriv, { "GetBufferParameteriv", "GetBufferParameterivARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetError, { "GetError", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetProgramiv, { "GetProgramiv", "GetProgramivARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetProgramInfoLog, { "GetProgramInfoLog", "GetProgramInfoLogARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fTexParameteri, { "TexParameteri", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fTexParameteriv, { "TexParameteriv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fTexParameterf, { "TexParameterf", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetString, { "GetString", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetTexParameterfv, { "GetTexParameterfv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetTexParameteriv, { "GetTexParameteriv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetUniformfv, { "GetUniformfv", "GetUniformfvARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetUniformiv, { "GetUniformiv", "GetUniformivARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetUniformLocation, { "GetUniformLocation", "GetUniformLocationARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetVertexAttribfv, { "GetVertexAttribfv", "GetVertexAttribfvARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetVertexAttribiv, { "GetVertexAttribiv", "GetVertexAttribivARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetVertexAttribPointerv, { "GetVertexAttribPointerv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fHint, { "Hint", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fIsBuffer, { "IsBuffer", "IsBufferARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fIsEnabled, { "IsEnabled", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fIsProgram, { "IsProgram", "IsProgramARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fIsShader, { "IsShader", "IsShaderARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fIsTexture, { "IsTexture", "IsTextureARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fLineWidth, { "LineWidth", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fLinkProgram, { "LinkProgram", "LinkProgramARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fPixelStorei, { "PixelStorei", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fPolygonOffset, { "PolygonOffset", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fReadPixels, { "ReadPixels", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fSampleCoverage, { "SampleCoverage", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fScissor, { "Scissor", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fStencilFunc, { "StencilFunc", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fStencilFuncSeparate, { "StencilFuncSeparate", "StencilFuncSeparateEXT", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fStencilMask, { "StencilMask", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fStencilMaskSeparate, { "StencilMaskSeparate", "StencilMaskSeparateEXT", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fStencilOp, { "StencilOp", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fStencilOpSeparate, { "StencilOpSeparate", "StencilOpSeparateEXT", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fTexImage2D, { "TexImage2D", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fTexSubImage2D, { "TexSubImage2D", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniform1f, { "Uniform1f", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniform1fv, { "Uniform1fv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniform1i, { "Uniform1i", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniform1iv, { "Uniform1iv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniform2f, { "Uniform2f", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniform2fv, { "Uniform2fv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniform2i, { "Uniform2i", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniform2iv, { "Uniform2iv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniform3f, { "Uniform3f", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniform3fv, { "Uniform3fv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniform3i, { "Uniform3i", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniform3iv, { "Uniform3iv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniform4f, { "Uniform4f", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniform4fv, { "Uniform4fv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniform4i, { "Uniform4i", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniform4iv, { "Uniform4iv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniformMatrix2fv, { "UniformMatrix2fv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniformMatrix3fv, { "UniformMatrix3fv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniformMatrix4fv, { "UniformMatrix4fv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUseProgram, { "UseProgram", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fValidateProgram, { "ValidateProgram", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fVertexAttribPointer, { "VertexAttribPointer", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fVertexAttrib1f, { "VertexAttrib1f", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fVertexAttrib2f, { "VertexAttrib2f", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fVertexAttrib3f, { "VertexAttrib3f", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fVertexAttrib4f, { "VertexAttrib4f", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fVertexAttrib1fv, { "VertexAttrib1fv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fVertexAttrib2fv, { "VertexAttrib2fv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fVertexAttrib3fv, { "VertexAttrib3fv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fVertexAttrib4fv, { "VertexAttrib4fv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fViewport, { "Viewport", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fCompileShader, { "CompileShader", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fCopyTexImage2D, { "CopyTexImage2D", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fCopyTexSubImage2D, { "CopyTexSubImage2D", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetShaderiv, { "GetShaderiv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetShaderInfoLog, { "GetShaderInfoLog", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetShaderSource, { "GetShaderSource", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fShaderSource, { "ShaderSource", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fVertexAttribPointer, { "VertexAttribPointer", nullptr } },
+
+ { (PRFuncPtr*) &mSymbols.fGenBuffers, { "GenBuffers", "GenBuffersARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGenTextures, { "GenTextures", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fCreateProgram, { "CreateProgram", "CreateProgramARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fCreateShader, { "CreateShader", "CreateShaderARB", nullptr } },
+
+ { (PRFuncPtr*) &mSymbols.fDeleteBuffers, { "DeleteBuffers", "DeleteBuffersARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDeleteTextures, { "DeleteTextures", "DeleteTexturesARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDeleteProgram, { "DeleteProgram", "DeleteProgramARB", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDeleteShader, { "DeleteShader", "DeleteShaderARB", nullptr } },
+
+ END_SYMBOLS
+ };
+
+ if (!LoadGLSymbols(this, prefix, trygl, coreSymbols, "GL"))
+ return false;
+
+ ////////////////
+
+ MakeCurrent();
+ MOZ_ASSERT(mProfile != ContextProfile::Unknown);
+
+ uint32_t version = 0;
+ ParseGLVersion(this, &version);
+
+ mShadingLanguageVersion = 100;
+ ParseGLSLVersion(this, &mShadingLanguageVersion);
+
+ if (ShouldSpew()) {
+ printf_stderr("OpenGL version detected: %u\n", version);
+ printf_stderr("OpenGL shading language version detected: %u\n", mShadingLanguageVersion);
+ printf_stderr("OpenGL vendor: %s\n", fGetString(LOCAL_GL_VENDOR));
+ printf_stderr("OpenGL renderer: %s\n", fGetString(LOCAL_GL_RENDERER));
+ }
+
+ if (version >= mVersion) {
+ mVersion = version;
+ }
+ // Don't fail if version < mVersion, see bug 999445,
+ // Mac OSX 10.6/10.7 machines with Intel GPUs claim only OpenGL 1.4 but
+ // have all the GL2+ extensions that we need.
+
+ ////////////////
+
+ // Load OpenGL ES 2.0 symbols, or desktop if we aren't using ES 2.
+ if (IsGLES()) {
+ const SymLoadStruct symbols[] = {
+ { (PRFuncPtr*) &mSymbols.fGetShaderPrecisionFormat, { "GetShaderPrecisionFormat", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fClearDepthf, { "ClearDepthf", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDepthRangef, { "DepthRangef", nullptr } },
+ END_SYMBOLS
+ };
+
+ if (!LoadGLSymbols(this, prefix, trygl, symbols, "OpenGL ES"))
+ return false;
+ } else {
+ const SymLoadStruct symbols[] = {
+ { (PRFuncPtr*) &mSymbols.fClearDepth, { "ClearDepth", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDepthRange, { "DepthRange", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fReadBuffer, { "ReadBuffer", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fMapBuffer, { "MapBuffer", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUnmapBuffer, { "UnmapBuffer", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fPointParameterf, { "PointParameterf", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDrawBuffer, { "DrawBuffer", nullptr } },
+ // The following functions are only used by Skia/GL in desktop mode.
+ // Other parts of Gecko should avoid using these
+ { (PRFuncPtr*) &mSymbols.fDrawBuffers, { "DrawBuffers", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fClientActiveTexture, { "ClientActiveTexture", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDisableClientState, { "DisableClientState", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fEnableClientState, { "EnableClientState", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fLoadIdentity, { "LoadIdentity", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fLoadMatrixf, { "LoadMatrixf", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fMatrixMode, { "MatrixMode", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fTexGeni, { "TexGeni", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fTexGenf, { "TexGenf", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fTexGenfv, { "TexGenfv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fVertexPointer, { "VertexPointer", nullptr } },
+ END_SYMBOLS
+ };
+
+ if (!LoadGLSymbols(this, prefix, trygl, symbols, "Desktop OpenGL"))
+ return false;
+ }
+
+ ////////////////
+
+ const char* glVendorString = (const char*)fGetString(LOCAL_GL_VENDOR);
+ const char* glRendererString = (const char*)fGetString(LOCAL_GL_RENDERER);
+ if (!glVendorString || !glRendererString)
+ return false;
+
+ // The order of these strings must match up with the order of the enum
+ // defined in GLContext.h for vendor IDs.
+ const char* vendorMatchStrings[size_t(GLVendor::Other) + 1] = {
+ "Intel",
+ "NVIDIA",
+ "ATI",
+ "Qualcomm",
+ "Imagination",
+ "nouveau",
+ "Vivante",
+ "VMware, Inc.",
+ "ARM",
+ "Unknown"
+ };
+
+ mVendor = GLVendor::Other;
+ for (size_t i = 0; i < size_t(GLVendor::Other); ++i) {
+ if (DoesStringMatch(glVendorString, vendorMatchStrings[i])) {
+ mVendor = GLVendor(i);
+ break;
+ }
+ }
+
+ // The order of these strings must match up with the order of the enum
+ // defined in GLContext.h for renderer IDs.
+ const char* rendererMatchStrings[size_t(GLRenderer::Other) + 1] = {
+ "Adreno 200",
+ "Adreno 205",
+ "Adreno (TM) 200",
+ "Adreno (TM) 205",
+ "Adreno (TM) 305",
+ "Adreno (TM) 320",
+ "Adreno (TM) 330",
+ "Adreno (TM) 420",
+ "Mali-400 MP",
+ "Mali-450 MP",
+ "PowerVR SGX 530",
+ "PowerVR SGX 540",
+ "PowerVR SGX 544MP",
+ "NVIDIA Tegra",
+ "Android Emulator",
+ "Gallium 0.4 on llvmpipe",
+ "Intel HD Graphics 3000 OpenGL Engine",
+ "Microsoft Basic Render Driver",
+ "Unknown"
+ };
+
+ mRenderer = GLRenderer::Other;
+ for (size_t i = 0; i < size_t(GLRenderer::Other); ++i) {
+ if (DoesStringMatch(glRendererString, rendererMatchStrings[i])) {
+ mRenderer = GLRenderer(i);
+ break;
+ }
+ }
+
+ if (ShouldSpew()) {
+ printf_stderr("GL_VENDOR: %s\n", glVendorString);
+ printf_stderr("mVendor: %s\n", vendorMatchStrings[size_t(mVendor)]);
+ printf_stderr("GL_RENDERER: %s\n", glRendererString);
+ printf_stderr("mRenderer: %s\n", rendererMatchStrings[size_t(mRenderer)]);
+ }
+
+ ////////////////
+
+ // We need this for retrieving the list of extensions on Core profiles.
+ if (IsFeatureProvidedByCoreSymbols(GLFeature::get_string_indexed)) {
+ const SymLoadStruct symbols[] = {
+ { (PRFuncPtr*) &mSymbols.fGetStringi, { "GetStringi", nullptr } },
+ END_SYMBOLS
+ };
+
+ if (!LoadGLSymbols(this, prefix, trygl, symbols, "get_string_indexed")) {
+ MOZ_RELEASE_ASSERT(false, "GFX: get_string_indexed is required!");
+ return false;
+ }
+ }
+
+ InitExtensions();
+ InitFeatures();
+
+ // Disable extensions with partial or incorrect support.
+ if (WorkAroundDriverBugs()) {
+ if (Renderer() == GLRenderer::AdrenoTM320) {
+ MarkUnsupported(GLFeature::standard_derivatives);
+ }
+
+ if (Vendor() == GLVendor::Vivante) {
+ // bug 958256
+ MarkUnsupported(GLFeature::standard_derivatives);
+ }
+
+ if (Renderer() == GLRenderer::MicrosoftBasicRenderDriver) {
+ // Bug 978966: on Microsoft's "Basic Render Driver" (software renderer)
+ // multisampling hardcodes blending with the default blendfunc, which breaks WebGL.
+ MarkUnsupported(GLFeature::framebuffer_multisample);
+ }
+
+#ifdef XP_MACOSX
+ // The Mac Nvidia driver, for versions up to and including 10.8,
+ // don't seem to properly support this. See 814839
+ // this has been fixed in Mac OS X 10.9. See 907946
+ // and it also works in 10.8.3 and higher. See 1094338.
+ if (Vendor() == gl::GLVendor::NVIDIA &&
+ !nsCocoaFeatures::IsAtLeastVersion(10,8,3))
+ {
+ MarkUnsupported(GLFeature::depth_texture);
+ }
+#endif
+ }
+
+ if (IsExtensionSupported(GLContext::ARB_pixel_buffer_object)) {
+ MOZ_ASSERT((mSymbols.fMapBuffer && mSymbols.fUnmapBuffer),
+ "ARB_pixel_buffer_object supported without glMapBuffer/UnmapBuffer"
+ " being available!");
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+
+ const auto fnLoadForFeature = [this, prefix, trygl](const SymLoadStruct* list,
+ GLFeature feature)
+ {
+ return this->LoadFeatureSymbols(prefix, trygl, list, feature);
+ };
+
+ // Check for ARB_framebuffer_objects
+ if (IsSupported(GLFeature::framebuffer_object)) {
+ // https://www.opengl.org/registry/specs/ARB/framebuffer_object.txt
+ const SymLoadStruct symbols[] = {
+ CORE_SYMBOL(IsRenderbuffer),
+ CORE_SYMBOL(BindRenderbuffer),
+ CORE_SYMBOL(DeleteRenderbuffers),
+ CORE_SYMBOL(GenRenderbuffers),
+ CORE_SYMBOL(RenderbufferStorage),
+ CORE_SYMBOL(RenderbufferStorageMultisample),
+ CORE_SYMBOL(GetRenderbufferParameteriv),
+ CORE_SYMBOL(IsFramebuffer),
+ CORE_SYMBOL(BindFramebuffer),
+ CORE_SYMBOL(DeleteFramebuffers),
+ CORE_SYMBOL(GenFramebuffers),
+ CORE_SYMBOL(CheckFramebufferStatus),
+ CORE_SYMBOL(FramebufferTexture2D),
+ CORE_SYMBOL(FramebufferTextureLayer),
+ CORE_SYMBOL(FramebufferRenderbuffer),
+ CORE_SYMBOL(GetFramebufferAttachmentParameteriv),
+ CORE_SYMBOL(BlitFramebuffer),
+ CORE_SYMBOL(GenerateMipmap),
+ END_SYMBOLS
+ };
+ fnLoadForFeature(symbols, GLFeature::framebuffer_object);
+ }
+
+ if (!IsSupported(GLFeature::framebuffer_object)) {
+ // Check for aux symbols based on extensions
+ if (IsSupported(GLFeature::framebuffer_object_EXT_OES)) {
+ const SymLoadStruct symbols[] = {
+ CORE_EXT_SYMBOL2(IsRenderbuffer, EXT, OES),
+ CORE_EXT_SYMBOL2(BindRenderbuffer, EXT, OES),
+ CORE_EXT_SYMBOL2(DeleteRenderbuffers, EXT, OES),
+ CORE_EXT_SYMBOL2(GenRenderbuffers, EXT, OES),
+ CORE_EXT_SYMBOL2(RenderbufferStorage, EXT, OES),
+ CORE_EXT_SYMBOL2(GetRenderbufferParameteriv, EXT, OES),
+ CORE_EXT_SYMBOL2(IsFramebuffer, EXT, OES),
+ CORE_EXT_SYMBOL2(BindFramebuffer, EXT, OES),
+ CORE_EXT_SYMBOL2(DeleteFramebuffers, EXT, OES),
+ CORE_EXT_SYMBOL2(GenFramebuffers, EXT, OES),
+ CORE_EXT_SYMBOL2(CheckFramebufferStatus, EXT, OES),
+ CORE_EXT_SYMBOL2(FramebufferTexture2D, EXT, OES),
+ CORE_EXT_SYMBOL2(FramebufferRenderbuffer, EXT, OES),
+ CORE_EXT_SYMBOL2(GetFramebufferAttachmentParameteriv, EXT, OES),
+ CORE_EXT_SYMBOL2(GenerateMipmap, EXT, OES),
+ END_SYMBOLS
+ };
+ fnLoadForFeature(symbols, GLFeature::framebuffer_object_EXT_OES);
+ }
+
+ if (IsSupported(GLFeature::framebuffer_blit)) {
+ const SymLoadStruct symbols[] = {
+ EXT_SYMBOL3(BlitFramebuffer, ANGLE, EXT, NV),
+ END_SYMBOLS
+ };
+ fnLoadForFeature(symbols, GLFeature::framebuffer_blit);
+ }
+
+ if (IsSupported(GLFeature::framebuffer_multisample)) {
+ const SymLoadStruct symbols[] = {
+ EXT_SYMBOL3(RenderbufferStorageMultisample, ANGLE, APPLE, EXT),
+ END_SYMBOLS
+ };
+ fnLoadForFeature(symbols, GLFeature::framebuffer_multisample);
+ }
+
+ if (IsExtensionSupported(GLContext::ARB_geometry_shader4) ||
+ IsExtensionSupported(GLContext::NV_geometry_program4))
+ {
+ const SymLoadStruct symbols[] = {
+ EXT_SYMBOL2(FramebufferTextureLayer, ARB, EXT),
+ END_SYMBOLS
+ };
+ if (!LoadGLSymbols(this, prefix, trygl, symbols,
+ "ARB_geometry_shader4/NV_geometry_program4"))
+ {
+ MarkExtensionUnsupported(GLContext::ARB_geometry_shader4);
+ MarkExtensionUnsupported(GLContext::NV_geometry_program4);
+ }
+ }
+ }
+
+ if (!IsSupported(GLFeature::framebuffer_object) &&
+ !IsSupported(GLFeature::framebuffer_object_EXT_OES))
+ {
+ NS_ERROR("GLContext requires support for framebuffer objects.");
+ return false;
+ }
+ MOZ_RELEASE_ASSERT(mSymbols.fBindFramebuffer, "GFX: mSymbols.fBindFramebuffer zero or not set.");
+
+ ////////////////
+
+ LoadMoreSymbols(prefix, trygl);
+
+ ////////////////////////////////////////////////////////////////////////////
+
+ raw_fGetIntegerv(LOCAL_GL_VIEWPORT, mViewportRect);
+ raw_fGetIntegerv(LOCAL_GL_SCISSOR_BOX, mScissorRect);
+ raw_fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
+ raw_fGetIntegerv(LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE, &mMaxCubeMapTextureSize);
+ raw_fGetIntegerv(LOCAL_GL_MAX_RENDERBUFFER_SIZE, &mMaxRenderbufferSize);
+ raw_fGetIntegerv(LOCAL_GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
+
+#ifdef XP_MACOSX
+ if (mWorkAroundDriverBugs) {
+ if (mVendor == GLVendor::Intel) {
+ // see bug 737182 for 2D textures, bug 684882 for cube map textures.
+ mMaxTextureSize = std::min(mMaxTextureSize, 4096);
+ mMaxCubeMapTextureSize = std::min(mMaxCubeMapTextureSize, 512);
+ // for good measure, we align renderbuffers on what we do for 2D textures
+ mMaxRenderbufferSize = std::min(mMaxRenderbufferSize, 4096);
+ mNeedsTextureSizeChecks = true;
+ } else if (mVendor == GLVendor::NVIDIA) {
+ // See bug 879656. 8192 fails, 8191 works.
+ mMaxTextureSize = std::min(mMaxTextureSize, 8191);
+ mMaxRenderbufferSize = std::min(mMaxRenderbufferSize, 8191);
+
+ // Part of the bug 879656, but it also doesn't hurt the 877949
+ mNeedsTextureSizeChecks = true;
+ }
+ }
+#endif
+#ifdef MOZ_X11
+ if (mWorkAroundDriverBugs) {
+ if (mVendor == GLVendor::Nouveau) {
+ // see bug 814716. Clamp MaxCubeMapTextureSize at 2K for Nouveau.
+ mMaxCubeMapTextureSize = std::min(mMaxCubeMapTextureSize, 2048);
+ mNeedsTextureSizeChecks = true;
+ } else if (mVendor == GLVendor::Intel) {
+ // Bug 1199923. Driver seems to report a larger max size than
+ // actually supported.
+ mMaxTextureSize /= 2;
+ mMaxRenderbufferSize /= 2;
+ mNeedsTextureSizeChecks = true;
+ }
+ }
+#endif
+ if (mWorkAroundDriverBugs &&
+ Renderer() == GLRenderer::AdrenoTM420) {
+ // see bug 1194923. Calling glFlush before glDeleteFramebuffers
+ // prevents occasional driver crash.
+ mNeedsFlushBeforeDeleteFB = true;
+ }
+#ifdef MOZ_WIDGET_ANDROID
+ if (mWorkAroundDriverBugs &&
+ (Renderer() == GLRenderer::AdrenoTM305 ||
+ Renderer() == GLRenderer::AdrenoTM320 ||
+ Renderer() == GLRenderer::AdrenoTM330) &&
+ AndroidBridge::Bridge()->GetAPIVersion() < 21) {
+ // Bug 1164027. Driver crashes when functions such as
+ // glTexImage2D fail due to virtual memory exhaustion.
+ mTextureAllocCrashesOnMapFailure = true;
+ }
+#endif
+#if MOZ_WIDGET_ANDROID
+ if (mWorkAroundDriverBugs &&
+ Renderer() == GLRenderer::SGX540 &&
+ AndroidBridge::Bridge()->GetAPIVersion() <= 15) {
+ // Bug 1288446. Driver sometimes crashes when uploading data to a
+ // texture if the render target has changed since the texture was
+ // rendered from. Calling glCheckFramebufferStatus after
+ // glFramebufferTexture2D prevents the crash.
+ mNeedsCheckAfterAttachTextureToFb = true;
+ }
+#endif
+
+ mMaxTextureImageSize = mMaxTextureSize;
+
+ if (IsSupported(GLFeature::framebuffer_multisample)) {
+ fGetIntegerv(LOCAL_GL_MAX_SAMPLES, (GLint*)&mMaxSamples);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+
+ // We're ready for final setup.
+ fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
+
+ // TODO: Remove SurfaceCaps::any.
+ if (mCaps.any) {
+ mCaps.any = false;
+ mCaps.color = true;
+ mCaps.alpha = false;
+ }
+
+ mTexGarbageBin = new TextureGarbageBin(this);
+
+ MOZ_ASSERT(IsCurrent());
+
+ if (ShouldSpew() && IsExtensionSupported(KHR_debug)) {
+ fEnable(LOCAL_GL_DEBUG_OUTPUT);
+ fDisable(LOCAL_GL_DEBUG_OUTPUT_SYNCHRONOUS);
+ fDebugMessageCallback(&StaticDebugCallback, (void*)this);
+ fDebugMessageControl(LOCAL_GL_DONT_CARE,
+ LOCAL_GL_DONT_CARE,
+ LOCAL_GL_DONT_CARE,
+ 0, nullptr,
+ true);
+ }
+
+ mVersionString = nsPrintfCString("%u.%u.%u", mVersion / 100, (mVersion / 10) % 10,
+ mVersion % 10);
+ return true;
+}
+
+void
+GLContext::LoadMoreSymbols(const char* prefix, bool trygl)
+{
+ const auto fnLoadForExt = [this, prefix, trygl](const SymLoadStruct* list,
+ GLExtensions ext)
+ {
+ return this->LoadExtSymbols(prefix, trygl, list, ext);
+ };
+
+ const auto fnLoadForFeature = [this, prefix, trygl](const SymLoadStruct* list,
+ GLFeature feature)
+ {
+ return this->LoadFeatureSymbols(prefix, trygl, list, feature);
+ };
+
+ const auto fnLoadFeatureByCore = [this, fnLoadForFeature](const SymLoadStruct* coreList,
+ const SymLoadStruct* extList,
+ GLFeature feature)
+ {
+ const bool useCore = this->IsFeatureProvidedByCoreSymbols(feature);
+ const auto list = useCore ? coreList : extList;
+ return fnLoadForFeature(list, feature);
+ };
+
+ if (IsSupported(GLFeature::robustness)) {
+ bool hasRobustness = false;
+
+ if (!hasRobustness && IsExtensionSupported(ARB_robustness)) {
+ const SymLoadStruct symbols[] = {
+ { (PRFuncPtr*) &mSymbols.fGetGraphicsResetStatus, { "GetGraphicsResetStatusARB", nullptr } },
+ END_SYMBOLS
+ };
+ if (fnLoadForExt(symbols, ARB_robustness)) {
+ hasRobustness = true;
+ }
+ }
+
+ if (!hasRobustness && IsExtensionSupported(EXT_robustness)) {
+ const SymLoadStruct symbols[] = {
+ { (PRFuncPtr*) &mSymbols.fGetGraphicsResetStatus, { "GetGraphicsResetStatusEXT", nullptr } },
+ END_SYMBOLS
+ };
+ if (fnLoadForExt(symbols, EXT_robustness)) {
+ hasRobustness = true;
+ }
+ }
+
+ if (!hasRobustness) {
+ MarkUnsupported(GLFeature::robustness);
+ }
+ }
+
+ if (IsSupported(GLFeature::sync)) {
+ const SymLoadStruct symbols[] = {
+ { (PRFuncPtr*) &mSymbols.fFenceSync, { "FenceSync", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fIsSync, { "IsSync", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDeleteSync, { "DeleteSync", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fClientWaitSync, { "ClientWaitSync", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fWaitSync, { "WaitSync", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetInteger64v, { "GetInteger64v", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetSynciv, { "GetSynciv", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadForFeature(symbols, GLFeature::sync);
+ }
+
+ if (IsExtensionSupported(OES_EGL_image)) {
+ const SymLoadStruct symbols[] = {
+ { (PRFuncPtr*) &mSymbols.fEGLImageTargetTexture2D, { "EGLImageTargetTexture2DOES", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fEGLImageTargetRenderbufferStorage, { "EGLImageTargetRenderbufferStorageOES", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadForExt(symbols, OES_EGL_image);
+ }
+
+ if (IsExtensionSupported(APPLE_texture_range)) {
+ const SymLoadStruct symbols[] = {
+ { (PRFuncPtr*) &mSymbols.fTextureRangeAPPLE, { "TextureRangeAPPLE", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadForExt(symbols, APPLE_texture_range);
+ }
+
+ if (IsSupported(GLFeature::vertex_array_object)) {
+ const SymLoadStruct coreSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fIsVertexArray, { "IsVertexArray", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGenVertexArrays, { "GenVertexArrays", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fBindVertexArray, { "BindVertexArray", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDeleteVertexArrays, { "DeleteVertexArrays", nullptr } },
+ END_SYMBOLS
+ };
+ const SymLoadStruct extSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fIsVertexArray, { "IsVertexArrayARB", "IsVertexArrayOES", "IsVertexArrayAPPLE", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGenVertexArrays, { "GenVertexArraysARB", "GenVertexArraysOES", "GenVertexArraysAPPLE", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fBindVertexArray, { "BindVertexArrayARB", "BindVertexArrayOES", "BindVertexArrayAPPLE", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDeleteVertexArrays, { "DeleteVertexArraysARB", "DeleteVertexArraysOES", "DeleteVertexArraysAPPLE", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::vertex_array_object);
+ }
+
+ if (IsSupported(GLFeature::draw_instanced)) {
+ const SymLoadStruct coreSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fDrawArraysInstanced, { "DrawArraysInstanced", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDrawElementsInstanced, { "DrawElementsInstanced", nullptr } },
+ END_SYMBOLS
+ };
+ const SymLoadStruct extSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fDrawArraysInstanced, { "DrawArraysInstancedARB", "DrawArraysInstancedEXT", "DrawArraysInstancedNV", "DrawArraysInstancedANGLE", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDrawElementsInstanced, { "DrawElementsInstancedARB", "DrawElementsInstancedEXT", "DrawElementsInstancedNV", "DrawElementsInstancedANGLE", nullptr }
+ },
+ END_SYMBOLS
+ };
+ fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::draw_instanced);
+ }
+
+ if (IsSupported(GLFeature::instanced_arrays)) {
+ const SymLoadStruct coreSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fVertexAttribDivisor, { "VertexAttribDivisor", nullptr } },
+ END_SYMBOLS
+ };
+ const SymLoadStruct extSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fVertexAttribDivisor, { "VertexAttribDivisorARB", "VertexAttribDivisorNV", "VertexAttribDivisorANGLE", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::instanced_arrays);
+ }
+
+ if (IsSupported(GLFeature::texture_storage)) {
+ const SymLoadStruct coreSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fTexStorage2D, { "TexStorage2D", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fTexStorage3D, { "TexStorage3D", nullptr } },
+ END_SYMBOLS
+ };
+ const SymLoadStruct extSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fTexStorage2D, { "TexStorage2DEXT", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fTexStorage3D, { "TexStorage3DEXT", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::texture_storage);
+ }
+
+ if (IsSupported(GLFeature::sampler_objects)) {
+ const SymLoadStruct symbols[] = {
+ { (PRFuncPtr*) &mSymbols.fGenSamplers, { "GenSamplers", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDeleteSamplers, { "DeleteSamplers", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fIsSampler, { "IsSampler", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fBindSampler, { "BindSampler", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fSamplerParameteri, { "SamplerParameteri", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fSamplerParameteriv, { "SamplerParameteriv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fSamplerParameterf, { "SamplerParameterf", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fSamplerParameterfv, { "SamplerParameterfv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetSamplerParameteriv, { "GetSamplerParameteriv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetSamplerParameterfv, { "GetSamplerParameterfv", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadForFeature(symbols, GLFeature::sampler_objects);
+ }
+
+ // ARB_transform_feedback2/NV_transform_feedback2 is a
+ // superset of EXT_transform_feedback/NV_transform_feedback
+ // and adds glPauseTransformFeedback &
+ // glResumeTransformFeedback, which are required for WebGL2.
+ if (IsSupported(GLFeature::transform_feedback2)) {
+ const SymLoadStruct coreSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fBindBufferBase, { "BindBufferBase", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fBindBufferRange, { "BindBufferRange", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGenTransformFeedbacks, { "GenTransformFeedbacks", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fBindTransformFeedback, { "BindTransformFeedback", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDeleteTransformFeedbacks, { "DeleteTransformFeedbacks", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fIsTransformFeedback, { "IsTransformFeedback", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fBeginTransformFeedback, { "BeginTransformFeedback", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fEndTransformFeedback, { "EndTransformFeedback", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fTransformFeedbackVaryings, { "TransformFeedbackVaryings", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetTransformFeedbackVarying, { "GetTransformFeedbackVarying", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fPauseTransformFeedback, { "PauseTransformFeedback", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fResumeTransformFeedback, { "ResumeTransformFeedback", nullptr } },
+ END_SYMBOLS
+ };
+ const SymLoadStruct extSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fBindBufferBase, { "BindBufferBaseEXT", "BindBufferBaseNV", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fBindBufferRange, { "BindBufferRangeEXT", "BindBufferRangeNV", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGenTransformFeedbacks, { "GenTransformFeedbacksNV", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fBindTransformFeedback, { "BindTransformFeedbackNV", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDeleteTransformFeedbacks, { "DeleteTransformFeedbacksNV", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fIsTransformFeedback, { "IsTransformFeedbackNV", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fBeginTransformFeedback, { "BeginTransformFeedbackEXT", "BeginTransformFeedbackNV", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fEndTransformFeedback, { "EndTransformFeedbackEXT", "EndTransformFeedbackNV", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fTransformFeedbackVaryings, { "TransformFeedbackVaryingsEXT", "TransformFeedbackVaryingsNV", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetTransformFeedbackVarying, { "GetTransformFeedbackVaryingEXT", "GetTransformFeedbackVaryingNV", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fPauseTransformFeedback, { "PauseTransformFeedbackNV", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fResumeTransformFeedback, { "ResumeTransformFeedbackNV", nullptr } },
+ END_SYMBOLS
+ };
+ if (!fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::texture_storage)) {
+ // Also mark bind_buffer_offset as unsupported.
+ MarkUnsupported(GLFeature::bind_buffer_offset);
+ }
+ }
+
+ if (IsSupported(GLFeature::bind_buffer_offset)) {
+ const SymLoadStruct coreSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fBindBufferOffset, { "BindBufferOffset", nullptr } },
+ END_SYMBOLS
+ };
+ const SymLoadStruct extSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fBindBufferOffset,
+ { "BindBufferOffsetEXT", "BindBufferOffsetNV", nullptr }
+ },
+ END_SYMBOLS
+ };
+ fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::bind_buffer_offset);
+ }
+
+ if (IsSupported(GLFeature::query_counter)) {
+ const SymLoadStruct coreSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fQueryCounter, { "QueryCounter", nullptr } },
+ END_SYMBOLS
+ };
+ const SymLoadStruct extSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fQueryCounter, { "QueryCounterEXT", "QueryCounterANGLE", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::query_counter);
+ }
+
+ if (IsSupported(GLFeature::query_objects)) {
+ const SymLoadStruct coreSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fBeginQuery, { "BeginQuery", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGenQueries, { "GenQueries", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDeleteQueries, { "DeleteQueries", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fEndQuery, { "EndQuery", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetQueryiv, { "GetQueryiv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetQueryObjectuiv, { "GetQueryObjectuiv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fIsQuery, { "IsQuery", nullptr } },
+ END_SYMBOLS
+ };
+ const SymLoadStruct extSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fBeginQuery, { "BeginQueryEXT", "BeginQueryANGLE", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGenQueries, { "GenQueriesEXT", "GenQueriesANGLE", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDeleteQueries, { "DeleteQueriesEXT", "DeleteQueriesANGLE", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fEndQuery, { "EndQueryEXT", "EndQueryANGLE", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetQueryiv, { "GetQueryivEXT", "GetQueryivANGLE", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetQueryObjectuiv, { "GetQueryObjectuivEXT", "GetQueryObjectuivANGLE", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fIsQuery, { "IsQueryEXT", "IsQueryANGLE", nullptr } },
+ END_SYMBOLS
+ };
+ if (!fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::query_objects)) {
+ MarkUnsupported(GLFeature::get_query_object_i64v);
+ MarkUnsupported(GLFeature::get_query_object_iv);
+ MarkUnsupported(GLFeature::occlusion_query);
+ MarkUnsupported(GLFeature::occlusion_query_boolean);
+ MarkUnsupported(GLFeature::occlusion_query2);
+ }
+ }
+
+ if (IsSupported(GLFeature::get_query_object_i64v)) {
+ const SymLoadStruct coreSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fGetQueryObjecti64v, { "GetQueryObjecti64v", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetQueryObjectui64v, { "GetQueryObjectui64v", nullptr } },
+ END_SYMBOLS
+ };
+ const SymLoadStruct extSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fGetQueryObjecti64v, { "GetQueryObjecti64vEXT", "GetQueryObjecti64vANGLE", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetQueryObjectui64v, { "GetQueryObjectui64vEXT", "GetQueryObjectui64vANGLE", nullptr } },
+ END_SYMBOLS
+ };
+ if (!fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::get_query_object_i64v)) {
+ MarkUnsupported(GLFeature::query_counter);
+ }
+ }
+
+ if (IsSupported(GLFeature::get_query_object_iv)) {
+ const SymLoadStruct coreSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fGetQueryObjectiv, { "GetQueryObjectiv", nullptr } },
+ END_SYMBOLS
+ };
+ const SymLoadStruct extSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fGetQueryObjectiv, { "GetQueryObjectivEXT", "GetQueryObjectivANGLE", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::get_query_object_iv);
+ }
+
+ if (IsSupported(GLFeature::clear_buffers)) {
+ const SymLoadStruct symbols[] = {
+ { (PRFuncPtr*) &mSymbols.fClearBufferfi, { "ClearBufferfi", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fClearBufferfv, { "ClearBufferfv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fClearBufferiv, { "ClearBufferiv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fClearBufferuiv, { "ClearBufferuiv", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadForFeature(symbols, GLFeature::clear_buffers);
+ }
+
+ if (IsSupported(GLFeature::copy_buffer)) {
+ const SymLoadStruct symbols[] = {
+ { (PRFuncPtr*) &mSymbols.fCopyBufferSubData, { "CopyBufferSubData", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadForFeature(symbols, GLFeature::copy_buffer);
+ }
+
+ if (IsSupported(GLFeature::draw_buffers)) {
+ const SymLoadStruct coreSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fDrawBuffers, { "DrawBuffers", nullptr } },
+ END_SYMBOLS
+ };
+ const SymLoadStruct extSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fDrawBuffers, { "DrawBuffersARB", "DrawBuffersEXT", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::draw_buffers);
+ }
+
+ if (IsSupported(GLFeature::draw_range_elements)) {
+ const SymLoadStruct coreSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fDrawRangeElements, { "DrawRangeElements", nullptr } },
+ END_SYMBOLS
+ };
+ const SymLoadStruct extSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fDrawRangeElements, { "DrawRangeElementsEXT", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::draw_range_elements);
+ }
+
+ if (IsSupported(GLFeature::get_integer_indexed)) {
+ const SymLoadStruct coreSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fGetIntegeri_v, { "GetIntegeri_v", nullptr } },
+ END_SYMBOLS
+ };
+ const SymLoadStruct extSymbols[] ={
+ { (PRFuncPtr*) &mSymbols.fGetIntegeri_v, { "GetIntegerIndexedvEXT", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::get_integer_indexed);
+ }
+
+ if (IsSupported(GLFeature::get_integer64_indexed)) {
+ const SymLoadStruct symbols[] = {
+ { (PRFuncPtr*) &mSymbols.fGetInteger64i_v, { "GetInteger64i_v", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadForFeature(symbols, GLFeature::get_integer64_indexed);
+ }
+
+ if (IsSupported(GLFeature::gpu_shader4)) {
+ const SymLoadStruct symbols[] = {
+ { (PRFuncPtr*) &mSymbols.fGetVertexAttribIiv, { "GetVertexAttribIiv", "GetVertexAttribIivEXT", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetVertexAttribIuiv, { "GetVertexAttribIuiv", "GetVertexAttribIuivEXT", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fVertexAttribI4i, { "VertexAttribI4i", "VertexAttribI4iEXT", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fVertexAttribI4iv, { "VertexAttribI4iv","VertexAttribI4ivEXT", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fVertexAttribI4ui, { "VertexAttribI4ui", "VertexAttribI4uiEXT", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fVertexAttribI4uiv, { "VertexAttribI4uiv", "VertexAttribI4uivEXT", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fVertexAttribIPointer, { "VertexAttribIPointer", "VertexAttribIPointerEXT", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniform1ui, { "Uniform1ui", "Uniform1uiEXT", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniform2ui, { "Uniform2ui", "Uniform2uiEXT", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniform3ui, { "Uniform3ui", "Uniform3uiEXT", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniform4ui, { "Uniform4ui", "Uniform4uiEXT", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniform1uiv, { "Uniform1uiv", "Uniform1uivEXT", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniform2uiv, { "Uniform2uiv", "Uniform2uivEXT", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniform3uiv, { "Uniform3uiv", "Uniform3uivEXT", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniform4uiv, { "Uniform4uiv", "Uniform4uivEXT", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetFragDataLocation, { "GetFragDataLocation", "GetFragDataLocationEXT", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetUniformuiv, { "GetUniformuiv", "GetUniformuivEXT", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadForFeature(symbols, GLFeature::gpu_shader4);
+ }
+
+ if (IsSupported(GLFeature::map_buffer_range)) {
+ const SymLoadStruct symbols[] = {
+ { (PRFuncPtr*) &mSymbols.fMapBufferRange, { "MapBufferRange", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fFlushMappedBufferRange, { "FlushMappedBufferRange", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUnmapBuffer, { "UnmapBuffer", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadForFeature(symbols, GLFeature::map_buffer_range);
+ }
+
+ if (IsSupported(GLFeature::texture_3D)) {
+ const SymLoadStruct coreSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fTexImage3D, { "TexImage3D", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fTexSubImage3D, { "TexSubImage3D", nullptr } },
+ END_SYMBOLS
+ };
+ const SymLoadStruct extSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fTexSubImage3D, { "TexSubImage3DEXT", "TexSubImage3DOES", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::texture_3D);
+ }
+
+ if (IsSupported(GLFeature::texture_3D_compressed)) {
+ const SymLoadStruct coreSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fCompressedTexImage3D, { "CompressedTexImage3D", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fCompressedTexSubImage3D, { "CompressedTexSubImage3D", nullptr } },
+ END_SYMBOLS
+ };
+ const SymLoadStruct extSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fCompressedTexImage3D, { "CompressedTexImage3DARB", "CompressedTexImage3DOES", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fCompressedTexSubImage3D, { "CompressedTexSubImage3DARB", "CompressedTexSubImage3DOES", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::texture_3D_compressed);
+ }
+
+ if (IsSupported(GLFeature::texture_3D_copy)) {
+ const SymLoadStruct coreSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fCopyTexSubImage3D, { "CopyTexSubImage3D", nullptr } },
+ END_SYMBOLS
+ };
+ const SymLoadStruct extSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fCopyTexSubImage3D, { "CopyTexSubImage3DEXT", "CopyTexSubImage3DOES", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadFeatureByCore(coreSymbols, extSymbols, GLFeature::texture_3D_copy);
+ }
+
+ if (IsSupported(GLFeature::uniform_buffer_object)) {
+ // Note: Don't query for glGetActiveUniformName because it is not
+ // supported by GL ES 3.
+ const SymLoadStruct symbols[] = {
+ { (PRFuncPtr*) &mSymbols.fGetUniformIndices, { "GetUniformIndices", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetActiveUniformsiv, { "GetActiveUniformsiv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetUniformBlockIndex, { "GetUniformBlockIndex", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetActiveUniformBlockiv, { "GetActiveUniformBlockiv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetActiveUniformBlockName, { "GetActiveUniformBlockName", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniformBlockBinding, { "UniformBlockBinding", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadForFeature(symbols, GLFeature::uniform_buffer_object);
+ }
+
+ if (IsSupported(GLFeature::uniform_matrix_nonsquare)) {
+ const SymLoadStruct symbols[] = {
+ { (PRFuncPtr*) &mSymbols.fUniformMatrix2x3fv, { "UniformMatrix2x3fv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniformMatrix2x4fv, { "UniformMatrix2x4fv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniformMatrix3x2fv, { "UniformMatrix3x2fv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniformMatrix3x4fv, { "UniformMatrix3x4fv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniformMatrix4x2fv, { "UniformMatrix4x2fv", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUniformMatrix4x3fv, { "UniformMatrix4x3fv", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadForFeature(symbols, GLFeature::uniform_matrix_nonsquare);
+ }
+
+ if (IsSupported(GLFeature::internalformat_query)) {
+ const SymLoadStruct symbols[] = {
+ CORE_SYMBOL(GetInternalformativ),
+ END_SYMBOLS
+ };
+ fnLoadForFeature(symbols, GLFeature::internalformat_query);
+ }
+
+ if (IsSupported(GLFeature::invalidate_framebuffer)) {
+ const SymLoadStruct symbols[] = {
+ { (PRFuncPtr*) &mSymbols.fInvalidateFramebuffer, { "InvalidateFramebuffer", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fInvalidateSubFramebuffer, { "InvalidateSubFramebuffer", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadForFeature(symbols, GLFeature::invalidate_framebuffer);
+ }
+
+ if (IsSupported(GLFeature::prim_restart)) {
+ const SymLoadStruct symbols[] = {
+ { (PRFuncPtr*) &mSymbols.fPrimitiveRestartIndex, { "PrimitiveRestartIndex", "PrimitiveRestartIndexNV", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadForFeature(symbols, GLFeature::prim_restart);
+ }
+
+ if (IsExtensionSupported(KHR_debug)) {
+ const SymLoadStruct symbols[] = {
+ { (PRFuncPtr*) &mSymbols.fDebugMessageControl, { "DebugMessageControl", "DebugMessageControlKHR", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDebugMessageInsert, { "DebugMessageInsert", "DebugMessageInsertKHR", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDebugMessageCallback, { "DebugMessageCallback", "DebugMessageCallbackKHR", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetDebugMessageLog, { "GetDebugMessageLog", "GetDebugMessageLogKHR", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetPointerv, { "GetPointerv", "GetPointervKHR", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fPushDebugGroup, { "PushDebugGroup", "PushDebugGroupKHR", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fPopDebugGroup, { "PopDebugGroup", "PopDebugGroupKHR", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fObjectLabel, { "ObjectLabel", "ObjectLabelKHR", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetObjectLabel, { "GetObjectLabel", "GetObjectLabelKHR", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fObjectPtrLabel, { "ObjectPtrLabel", "ObjectPtrLabelKHR", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetObjectPtrLabel, { "GetObjectPtrLabel", "GetObjectPtrLabelKHR", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadForExt(symbols, KHR_debug);
+ }
+
+ if (IsExtensionSupported(NV_fence)) {
+ const SymLoadStruct symbols[] = {
+ { (PRFuncPtr*) &mSymbols.fGenFences, { "GenFencesNV", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDeleteFences, { "DeleteFencesNV", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fSetFence, { "SetFenceNV", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fTestFence, { "TestFenceNV", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fFinishFence, { "FinishFenceNV", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fIsFence, { "IsFenceNV", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetFenceiv, { "GetFenceivNV", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadForExt(symbols, NV_fence);
+ }
+
+ if (IsExtensionSupported(NV_texture_barrier)) {
+ const SymLoadStruct symbols[] = {
+ { (PRFuncPtr*) &mSymbols.fTextureBarrier, { "TextureBarrierNV", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadForExt(symbols, NV_texture_barrier);
+ }
+
+ if (IsSupported(GLFeature::read_buffer)) {
+ const SymLoadStruct symbols[] = {
+ { (PRFuncPtr*) &mSymbols.fReadBuffer, { "ReadBuffer", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadForFeature(symbols, GLFeature::read_buffer);
+ }
+
+ if (IsExtensionSupported(APPLE_framebuffer_multisample)) {
+ const SymLoadStruct symbols[] = {
+ { (PRFuncPtr*) &mSymbols.fResolveMultisampleFramebufferAPPLE, { "ResolveMultisampleFramebufferAPPLE", nullptr } },
+ END_SYMBOLS
+ };
+ fnLoadForExt(symbols, APPLE_framebuffer_multisample);
+ }
+
+ // Load developer symbols, don't fail if we can't find them.
+ const SymLoadStruct devSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fGetTexImage, { "GetTexImage", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetTexLevelParameteriv, { "GetTexLevelParameteriv", nullptr } },
+ END_SYMBOLS
+ };
+ const bool warnOnFailures = ShouldSpew();
+ LoadSymbols(devSymbols, trygl, prefix, warnOnFailures);
+}
+
+#undef CORE_SYMBOL
+#undef CORE_EXT_SYMBOL2
+#undef EXT_SYMBOL2
+#undef EXT_SYMBOL3
+#undef END_SYMBOLS
+
+void
+GLContext::DebugCallback(GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar* message)
+{
+ nsAutoCString sourceStr;
+ switch (source) {
+ case LOCAL_GL_DEBUG_SOURCE_API:
+ sourceStr = NS_LITERAL_CSTRING("SOURCE_API");
+ break;
+ case LOCAL_GL_DEBUG_SOURCE_WINDOW_SYSTEM:
+ sourceStr = NS_LITERAL_CSTRING("SOURCE_WINDOW_SYSTEM");
+ break;
+ case LOCAL_GL_DEBUG_SOURCE_SHADER_COMPILER:
+ sourceStr = NS_LITERAL_CSTRING("SOURCE_SHADER_COMPILER");
+ break;
+ case LOCAL_GL_DEBUG_SOURCE_THIRD_PARTY:
+ sourceStr = NS_LITERAL_CSTRING("SOURCE_THIRD_PARTY");
+ break;
+ case LOCAL_GL_DEBUG_SOURCE_APPLICATION:
+ sourceStr = NS_LITERAL_CSTRING("SOURCE_APPLICATION");
+ break;
+ case LOCAL_GL_DEBUG_SOURCE_OTHER:
+ sourceStr = NS_LITERAL_CSTRING("SOURCE_OTHER");
+ break;
+ default:
+ sourceStr = nsPrintfCString("<source 0x%04x>", source);
+ break;
+ }
+
+ nsAutoCString typeStr;
+ switch (type) {
+ case LOCAL_GL_DEBUG_TYPE_ERROR:
+ typeStr = NS_LITERAL_CSTRING("TYPE_ERROR");
+ break;
+ case LOCAL_GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
+ typeStr = NS_LITERAL_CSTRING("TYPE_DEPRECATED_BEHAVIOR");
+ break;
+ case LOCAL_GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
+ typeStr = NS_LITERAL_CSTRING("TYPE_UNDEFINED_BEHAVIOR");
+ break;
+ case LOCAL_GL_DEBUG_TYPE_PORTABILITY:
+ typeStr = NS_LITERAL_CSTRING("TYPE_PORTABILITY");
+ break;
+ case LOCAL_GL_DEBUG_TYPE_PERFORMANCE:
+ typeStr = NS_LITERAL_CSTRING("TYPE_PERFORMANCE");
+ break;
+ case LOCAL_GL_DEBUG_TYPE_OTHER:
+ typeStr = NS_LITERAL_CSTRING("TYPE_OTHER");
+ break;
+ case LOCAL_GL_DEBUG_TYPE_MARKER:
+ typeStr = NS_LITERAL_CSTRING("TYPE_MARKER");
+ break;
+ default:
+ typeStr = nsPrintfCString("<type 0x%04x>", type);
+ break;
+ }
+
+ nsAutoCString sevStr;
+ switch (severity) {
+ case LOCAL_GL_DEBUG_SEVERITY_HIGH:
+ sevStr = NS_LITERAL_CSTRING("SEVERITY_HIGH");
+ break;
+ case LOCAL_GL_DEBUG_SEVERITY_MEDIUM:
+ sevStr = NS_LITERAL_CSTRING("SEVERITY_MEDIUM");
+ break;
+ case LOCAL_GL_DEBUG_SEVERITY_LOW:
+ sevStr = NS_LITERAL_CSTRING("SEVERITY_LOW");
+ break;
+ case LOCAL_GL_DEBUG_SEVERITY_NOTIFICATION:
+ sevStr = NS_LITERAL_CSTRING("SEVERITY_NOTIFICATION");
+ break;
+ default:
+ sevStr = nsPrintfCString("<severity 0x%04x>", severity);
+ break;
+ }
+
+ printf_stderr("[KHR_debug: 0x%" PRIxPTR "] ID %u: %s, %s, %s:\n %s\n",
+ (uintptr_t)this,
+ id,
+ sourceStr.BeginReading(),
+ typeStr.BeginReading(),
+ sevStr.BeginReading(),
+ message);
+}
+
+void
+GLContext::InitExtensions()
+{
+ MOZ_ASSERT(IsCurrent());
+
+ std::vector<nsCString> driverExtensionList;
+
+ if (IsFeatureProvidedByCoreSymbols(GLFeature::get_string_indexed)) {
+ GLuint count = 0;
+ GetUIntegerv(LOCAL_GL_NUM_EXTENSIONS, &count);
+ for (GLuint i = 0; i < count; i++) {
+ // This is UTF-8.
+ const char* rawExt = (const char*)fGetStringi(LOCAL_GL_EXTENSIONS, i);
+
+ // We CANNOT use nsDependentCString here, because the spec doesn't guarantee
+ // that the pointers returned are different, only that their contents are.
+ // On Flame, each of these index string queries returns the same address.
+ driverExtensionList.push_back(nsCString(rawExt));
+ }
+ } else {
+ MOZ_ALWAYS_TRUE(!fGetError());
+ const char* rawExts = (const char*)fGetString(LOCAL_GL_EXTENSIONS);
+ MOZ_ALWAYS_TRUE(!fGetError());
+
+ if (rawExts) {
+ nsDependentCString exts(rawExts);
+ SplitByChar(exts, ' ', &driverExtensionList);
+ }
+ }
+
+ const bool shouldDumpExts = ShouldDumpExts();
+ if (shouldDumpExts) {
+ printf_stderr("%i GL driver extensions: (*: recognized)\n",
+ (uint32_t)driverExtensionList.size());
+ }
+
+ MarkBitfieldByStrings(driverExtensionList, shouldDumpExts, sExtensionNames,
+ &mAvailableExtensions);
+
+ if (WorkAroundDriverBugs()) {
+ if (Vendor() == GLVendor::Qualcomm) {
+ // Some Adreno drivers do not report GL_OES_EGL_sync, but they really do support it.
+ MarkExtensionSupported(OES_EGL_sync);
+ }
+
+ if (Vendor() == GLVendor::ATI) {
+ // ATI drivers say this extension exists, but we can't
+ // actually find the EGLImageTargetRenderbufferStorageOES
+ // extension function pointer in the drivers.
+ MarkExtensionUnsupported(OES_EGL_image);
+ }
+
+ if (Vendor() == GLVendor::Imagination &&
+ Renderer() == GLRenderer::SGX540)
+ {
+ // Bug 980048
+ MarkExtensionUnsupported(OES_EGL_sync);
+ }
+
+#ifdef MOZ_WIDGET_ANDROID
+ if (Vendor() == GLVendor::Imagination &&
+ Renderer() == GLRenderer::SGX544MP &&
+ AndroidBridge::Bridge()->GetAPIVersion() < 21)
+ {
+ // Bug 1026404
+ MarkExtensionUnsupported(OES_EGL_image);
+ MarkExtensionUnsupported(OES_EGL_image_external);
+ }
+#endif
+
+ if (Vendor() == GLVendor::ARM &&
+ (Renderer() == GLRenderer::Mali400MP ||
+ Renderer() == GLRenderer::Mali450MP))
+ {
+ // Bug 1264505
+ MarkExtensionUnsupported(OES_EGL_image_external);
+ }
+
+ if (Renderer() == GLRenderer::AndroidEmulator) {
+ // the Android emulator, which we use to run B2G reftests on,
+ // doesn't expose the OES_rgb8_rgba8 extension, but it seems to
+ // support it (tautologically, as it only runs on desktop GL).
+ MarkExtensionSupported(OES_rgb8_rgba8);
+ // there seems to be a similar issue for EXT_texture_format_BGRA8888
+ // on the Android 4.3 emulator
+ MarkExtensionSupported(EXT_texture_format_BGRA8888);
+ }
+
+ if (Vendor() == GLVendor::VMware &&
+ Renderer() == GLRenderer::GalliumLlvmpipe)
+ {
+ // The llvmpipe driver that is used on linux try servers appears to have
+ // buggy support for s3tc/dxt1 compressed textures.
+ // See Bug 975824.
+ MarkExtensionUnsupported(EXT_texture_compression_s3tc);
+ MarkExtensionUnsupported(EXT_texture_compression_dxt1);
+ MarkExtensionUnsupported(ANGLE_texture_compression_dxt3);
+ MarkExtensionUnsupported(ANGLE_texture_compression_dxt5);
+ }
+
+#ifdef XP_MACOSX
+ // Bug 1009642: On OSX Mavericks (10.9), the driver for Intel HD
+ // 3000 appears to be buggy WRT updating sub-images of S3TC
+ // textures with glCompressedTexSubImage2D. Works on Intel HD 4000
+ // and Intel HD 5000/Iris that I tested.
+ // Bug 1124996: Appears to be the same on OSX Yosemite (10.10)
+ if (nsCocoaFeatures::OSXVersionMajor() == 10 &&
+ nsCocoaFeatures::OSXVersionMinor() >= 9 &&
+ Renderer() == GLRenderer::IntelHD3000)
+ {
+ MarkExtensionUnsupported(EXT_texture_compression_s3tc);
+ }
+#endif
+ }
+
+ if (shouldDumpExts) {
+ printf_stderr("\nActivated extensions:\n");
+
+ for (size_t i = 0; i < mAvailableExtensions.size(); i++) {
+ if (!mAvailableExtensions[i])
+ continue;
+
+ const char* ext = sExtensionNames[i];
+ printf_stderr("[%i] %s\n", (uint32_t)i, ext);
+ }
+ }
+}
+
+void
+GLContext::PlatformStartup()
+{
+ RegisterStrongMemoryReporter(new GfxTexturesReporter());
+}
+
+// Common code for checking for both GL extensions and GLX extensions.
+bool
+GLContext::ListHasExtension(const GLubyte* extensions, const char* extension)
+{
+ // fix bug 612572 - we were crashing as we were calling this function with extensions==null
+ if (extensions == nullptr || extension == nullptr)
+ return false;
+
+ const GLubyte* start;
+ GLubyte* where;
+ GLubyte* terminator;
+
+ /* Extension names should not have spaces. */
+ where = (GLubyte*) strchr(extension, ' ');
+ if (where || *extension == '\0')
+ return false;
+
+ /*
+ * It takes a bit of care to be fool-proof about parsing the
+ * OpenGL extensions string. Don't be fooled by sub-strings,
+ * etc.
+ */
+ start = extensions;
+ for (;;) {
+ where = (GLubyte*) strstr((const char*) start, extension);
+ if (!where) {
+ break;
+ }
+ terminator = where + strlen(extension);
+ if (where == start || *(where - 1) == ' ') {
+ if (*terminator == ' ' || *terminator == '\0') {
+ return true;
+ }
+ }
+ start = terminator;
+ }
+ return false;
+}
+
+GLFormats
+GLContext::ChooseGLFormats(const SurfaceCaps& caps) const
+{
+ GLFormats formats;
+
+ // If we're on ES2 hardware and we have an explicit request for 16 bits of color or less
+ // OR we don't support full 8-bit color, return a 4444 or 565 format.
+ bool bpp16 = caps.bpp16;
+ if (IsGLES()) {
+ if (!IsExtensionSupported(OES_rgb8_rgba8))
+ bpp16 = true;
+ } else {
+ // RGB565 is uncommon on desktop, requiring ARB_ES2_compatibility.
+ // Since it's also vanishingly useless there, let's not support it.
+ bpp16 = false;
+ }
+
+ if (bpp16) {
+ MOZ_ASSERT(IsGLES());
+ if (caps.alpha) {
+ formats.color_texInternalFormat = LOCAL_GL_RGBA;
+ formats.color_texFormat = LOCAL_GL_RGBA;
+ formats.color_texType = LOCAL_GL_UNSIGNED_SHORT_4_4_4_4;
+ formats.color_rbFormat = LOCAL_GL_RGBA4;
+ } else {
+ formats.color_texInternalFormat = LOCAL_GL_RGB;
+ formats.color_texFormat = LOCAL_GL_RGB;
+ formats.color_texType = LOCAL_GL_UNSIGNED_SHORT_5_6_5;
+ formats.color_rbFormat = LOCAL_GL_RGB565;
+ }
+ } else {
+ formats.color_texType = LOCAL_GL_UNSIGNED_BYTE;
+
+ if (caps.alpha) {
+ formats.color_texInternalFormat = IsGLES() ? LOCAL_GL_RGBA : LOCAL_GL_RGBA8;
+ formats.color_texFormat = LOCAL_GL_RGBA;
+ formats.color_rbFormat = LOCAL_GL_RGBA8;
+ } else {
+ formats.color_texInternalFormat = IsGLES() ? LOCAL_GL_RGB : LOCAL_GL_RGB8;
+ formats.color_texFormat = LOCAL_GL_RGB;
+ formats.color_rbFormat = LOCAL_GL_RGB8;
+ }
+ }
+
+ uint32_t msaaLevel = gfxPrefs::MSAALevel();
+ GLsizei samples = msaaLevel * msaaLevel;
+ samples = std::min(samples, mMaxSamples);
+
+ // Bug 778765.
+ if (WorkAroundDriverBugs() && samples == 1) {
+ samples = 0;
+ }
+ formats.samples = samples;
+
+
+ // Be clear that these are 0 if unavailable.
+ formats.depthStencil = 0;
+ if (IsSupported(GLFeature::packed_depth_stencil)) {
+ formats.depthStencil = LOCAL_GL_DEPTH24_STENCIL8;
+ }
+
+ formats.depth = 0;
+ if (IsGLES()) {
+ if (IsExtensionSupported(OES_depth24)) {
+ formats.depth = LOCAL_GL_DEPTH_COMPONENT24;
+ } else {
+ formats.depth = LOCAL_GL_DEPTH_COMPONENT16;
+ }
+ } else {
+ formats.depth = LOCAL_GL_DEPTH_COMPONENT24;
+ }
+
+ formats.stencil = LOCAL_GL_STENCIL_INDEX8;
+
+ return formats;
+}
+
+bool
+GLContext::IsFramebufferComplete(GLuint fb, GLenum* pStatus)
+{
+ MOZ_ASSERT(fb);
+
+ ScopedBindFramebuffer autoFB(this, fb);
+ MOZ_ASSERT(fIsFramebuffer(fb));
+
+ GLenum status = fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
+ if (pStatus)
+ *pStatus = status;
+
+ return status == LOCAL_GL_FRAMEBUFFER_COMPLETE;
+}
+
+void
+GLContext::AttachBuffersToFB(GLuint colorTex, GLuint colorRB,
+ GLuint depthRB, GLuint stencilRB,
+ GLuint fb, GLenum target)
+{
+ MOZ_ASSERT(fb);
+ MOZ_ASSERT( !(colorTex && colorRB) );
+
+ ScopedBindFramebuffer autoFB(this, fb);
+ MOZ_ASSERT(fIsFramebuffer(fb)); // It only counts after being bound.
+
+ if (colorTex) {
+ MOZ_ASSERT(fIsTexture(colorTex));
+ MOZ_ASSERT(target == LOCAL_GL_TEXTURE_2D ||
+ target == LOCAL_GL_TEXTURE_RECTANGLE_ARB);
+ fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
+ LOCAL_GL_COLOR_ATTACHMENT0,
+ target,
+ colorTex,
+ 0);
+ } else if (colorRB) {
+ // On the Android 4.3 emulator, IsRenderbuffer may return false incorrectly.
+ MOZ_ASSERT_IF(Renderer() != GLRenderer::AndroidEmulator, fIsRenderbuffer(colorRB));
+ fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
+ LOCAL_GL_COLOR_ATTACHMENT0,
+ LOCAL_GL_RENDERBUFFER,
+ colorRB);
+ }
+
+ if (depthRB) {
+ MOZ_ASSERT_IF(Renderer() != GLRenderer::AndroidEmulator, fIsRenderbuffer(depthRB));
+ fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
+ LOCAL_GL_DEPTH_ATTACHMENT,
+ LOCAL_GL_RENDERBUFFER,
+ depthRB);
+ }
+
+ if (stencilRB) {
+ MOZ_ASSERT_IF(Renderer() != GLRenderer::AndroidEmulator, fIsRenderbuffer(stencilRB));
+ fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
+ LOCAL_GL_STENCIL_ATTACHMENT,
+ LOCAL_GL_RENDERBUFFER,
+ stencilRB);
+ }
+}
+
+bool
+GLContext::AssembleOffscreenFBs(const GLuint colorMSRB,
+ const GLuint depthRB,
+ const GLuint stencilRB,
+ const GLuint texture,
+ GLuint* drawFB_out,
+ GLuint* readFB_out)
+{
+ if (!colorMSRB && !texture) {
+ MOZ_ASSERT(!depthRB && !stencilRB);
+
+ if (drawFB_out)
+ *drawFB_out = 0;
+ if (readFB_out)
+ *readFB_out = 0;
+
+ return true;
+ }
+
+ ScopedBindFramebuffer autoFB(this);
+
+ GLuint drawFB = 0;
+ GLuint readFB = 0;
+
+ if (texture) {
+ readFB = 0;
+ fGenFramebuffers(1, &readFB);
+ BindFB(readFB);
+ fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
+ LOCAL_GL_COLOR_ATTACHMENT0,
+ LOCAL_GL_TEXTURE_2D,
+ texture,
+ 0);
+ }
+
+ if (colorMSRB) {
+ drawFB = 0;
+ fGenFramebuffers(1, &drawFB);
+ BindFB(drawFB);
+ fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
+ LOCAL_GL_COLOR_ATTACHMENT0,
+ LOCAL_GL_RENDERBUFFER,
+ colorMSRB);
+ } else {
+ drawFB = readFB;
+ }
+ MOZ_ASSERT(GetFB() == drawFB);
+
+ if (depthRB) {
+ fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
+ LOCAL_GL_DEPTH_ATTACHMENT,
+ LOCAL_GL_RENDERBUFFER,
+ depthRB);
+ }
+
+ if (stencilRB) {
+ fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
+ LOCAL_GL_STENCIL_ATTACHMENT,
+ LOCAL_GL_RENDERBUFFER,
+ stencilRB);
+ }
+
+ // We should be all resized. Check for framebuffer completeness.
+ GLenum status;
+ bool isComplete = true;
+
+ if (!IsFramebufferComplete(drawFB, &status)) {
+ NS_WARNING("DrawFBO: Incomplete");
+ #ifdef MOZ_GL_DEBUG
+ if (ShouldSpew()) {
+ printf_stderr("Framebuffer status: %X\n", status);
+ }
+ #endif
+ isComplete = false;
+ }
+
+ if (!IsFramebufferComplete(readFB, &status)) {
+ NS_WARNING("ReadFBO: Incomplete");
+ #ifdef MOZ_GL_DEBUG
+ if (ShouldSpew()) {
+ printf_stderr("Framebuffer status: %X\n", status);
+ }
+ #endif
+ isComplete = false;
+ }
+
+ if (drawFB_out) {
+ *drawFB_out = drawFB;
+ } else if (drawFB) {
+ NS_RUNTIMEABORT("drawFB created when not requested!");
+ }
+
+ if (readFB_out) {
+ *readFB_out = readFB;
+ } else if (readFB) {
+ NS_RUNTIMEABORT("readFB created when not requested!");
+ }
+
+ return isComplete;
+}
+
+
+void
+GLContext::ClearSafely()
+{
+ // bug 659349 --- we must be very careful here: clearing a GL framebuffer is nontrivial, relies on a lot of state,
+ // and in the case of the backbuffer of a WebGL context, state is exposed to scripts.
+ //
+ // The code here is taken from WebGLContext::ForceClearFramebufferWithDefaultValues, but I didn't find a good way of
+ // sharing code with it. WebGL's code is somewhat performance-critical as it is typically called on every frame, so
+ // WebGL keeps track of GL state to avoid having to query it everytime, and also tries to only do work for actually
+ // present buffers (e.g. stencil buffer). Doing that here seems like premature optimization,
+ // as ClearSafely() is called only when e.g. a canvas is resized, not on every animation frame.
+
+ realGLboolean scissorTestEnabled;
+ realGLboolean ditherEnabled;
+ realGLboolean colorWriteMask[4];
+ realGLboolean depthWriteMask;
+ GLint stencilWriteMaskFront, stencilWriteMaskBack;
+ GLfloat colorClearValue[4];
+ GLfloat depthClearValue;
+ GLint stencilClearValue;
+
+ // save current GL state
+ fGetBooleanv(LOCAL_GL_SCISSOR_TEST, &scissorTestEnabled);
+ fGetBooleanv(LOCAL_GL_DITHER, &ditherEnabled);
+ fGetBooleanv(LOCAL_GL_COLOR_WRITEMASK, colorWriteMask);
+ fGetBooleanv(LOCAL_GL_DEPTH_WRITEMASK, &depthWriteMask);
+ fGetIntegerv(LOCAL_GL_STENCIL_WRITEMASK, &stencilWriteMaskFront);
+ fGetIntegerv(LOCAL_GL_STENCIL_BACK_WRITEMASK, &stencilWriteMaskBack);
+ fGetFloatv(LOCAL_GL_COLOR_CLEAR_VALUE, colorClearValue);
+ fGetFloatv(LOCAL_GL_DEPTH_CLEAR_VALUE, &depthClearValue);
+ fGetIntegerv(LOCAL_GL_STENCIL_CLEAR_VALUE, &stencilClearValue);
+
+ // prepare GL state for clearing
+ fDisable(LOCAL_GL_SCISSOR_TEST);
+ fDisable(LOCAL_GL_DITHER);
+
+ fColorMask(1, 1, 1, 1);
+ fClearColor(0.f, 0.f, 0.f, 0.f);
+
+ fDepthMask(1);
+ fClearDepth(1.0f);
+
+ fStencilMask(0xffffffff);
+ fClearStencil(0);
+
+ // do clear
+ fClear(LOCAL_GL_COLOR_BUFFER_BIT |
+ LOCAL_GL_DEPTH_BUFFER_BIT |
+ LOCAL_GL_STENCIL_BUFFER_BIT);
+
+ // restore GL state after clearing
+ fColorMask(colorWriteMask[0],
+ colorWriteMask[1],
+ colorWriteMask[2],
+ colorWriteMask[3]);
+ fClearColor(colorClearValue[0],
+ colorClearValue[1],
+ colorClearValue[2],
+ colorClearValue[3]);
+
+ fDepthMask(depthWriteMask);
+ fClearDepth(depthClearValue);
+
+ fStencilMaskSeparate(LOCAL_GL_FRONT, stencilWriteMaskFront);
+ fStencilMaskSeparate(LOCAL_GL_BACK, stencilWriteMaskBack);
+ fClearStencil(stencilClearValue);
+
+ if (ditherEnabled)
+ fEnable(LOCAL_GL_DITHER);
+ else
+ fDisable(LOCAL_GL_DITHER);
+
+ if (scissorTestEnabled)
+ fEnable(LOCAL_GL_SCISSOR_TEST);
+ else
+ fDisable(LOCAL_GL_SCISSOR_TEST);
+
+}
+
+void
+GLContext::MarkDestroyed()
+{
+ if (IsDestroyed())
+ return;
+
+ // Null these before they're naturally nulled after dtor, as we want GLContext to
+ // still be alive in *their* dtors.
+ mScreen = nullptr;
+ mBlitHelper = nullptr;
+ mReadTexImageHelper = nullptr;
+
+ if (MakeCurrent()) {
+ mTexGarbageBin->GLContextTeardown();
+ } else {
+ NS_WARNING("MakeCurrent() failed during MarkDestroyed! Skipping GL object teardown.");
+ }
+
+ mSymbols.Zero();
+}
+
+#ifdef MOZ_GL_DEBUG
+/* static */ void
+GLContext::AssertNotPassingStackBufferToTheGL(const void* ptr)
+{
+ int somethingOnTheStack;
+ const void* someStackPtr = &somethingOnTheStack;
+ const int page_bits = 12;
+ intptr_t page = reinterpret_cast<uintptr_t>(ptr) >> page_bits;
+ intptr_t someStackPage = reinterpret_cast<uintptr_t>(someStackPtr) >> page_bits;
+ uintptr_t pageDistance = std::abs(page - someStackPage);
+
+ // Explanation for the "distance <= 1" check here as opposed to just
+ // an equality check.
+ //
+ // Here we assume that pages immediately adjacent to the someStackAddress page,
+ // are also stack pages. That allows to catch the case where the calling frame put
+ // a buffer on the stack, and we just crossed the page boundary. That is likely
+ // to happen, precisely, when using stack arrays. I hit that specifically
+ // with CompositorOGL::Initialize.
+ //
+ // In theory we could be unlucky and wrongly assert here. If that happens,
+ // it will only affect debug builds, and looking at stacks we'll be able to
+ // see that this assert is wrong and revert to the conservative and safe
+ // approach of only asserting when address and someStackAddress are
+ // on the same page.
+ bool isStackAddress = pageDistance <= 1;
+ MOZ_ASSERT(!isStackAddress,
+ "Please don't pass stack arrays to the GL. "
+ "Consider using HeapCopyOfStackArray. "
+ "See bug 1005658.");
+}
+
+void
+GLContext::CreatedProgram(GLContext* aOrigin, GLuint aName)
+{
+ mTrackedPrograms.AppendElement(NamedResource(aOrigin, aName));
+}
+
+void
+GLContext::CreatedShader(GLContext* aOrigin, GLuint aName)
+{
+ mTrackedShaders.AppendElement(NamedResource(aOrigin, aName));
+}
+
+void
+GLContext::CreatedBuffers(GLContext* aOrigin, GLsizei aCount, GLuint* aNames)
+{
+ for (GLsizei i = 0; i < aCount; ++i) {
+ mTrackedBuffers.AppendElement(NamedResource(aOrigin, aNames[i]));
+ }
+}
+
+void
+GLContext::CreatedQueries(GLContext* aOrigin, GLsizei aCount, GLuint* aNames)
+{
+ for (GLsizei i = 0; i < aCount; ++i) {
+ mTrackedQueries.AppendElement(NamedResource(aOrigin, aNames[i]));
+ }
+}
+
+void
+GLContext::CreatedTextures(GLContext* aOrigin, GLsizei aCount, GLuint* aNames)
+{
+ for (GLsizei i = 0; i < aCount; ++i) {
+ mTrackedTextures.AppendElement(NamedResource(aOrigin, aNames[i]));
+ }
+}
+
+void
+GLContext::CreatedFramebuffers(GLContext* aOrigin, GLsizei aCount, GLuint* aNames)
+{
+ for (GLsizei i = 0; i < aCount; ++i) {
+ mTrackedFramebuffers.AppendElement(NamedResource(aOrigin, aNames[i]));
+ }
+}
+
+void
+GLContext::CreatedRenderbuffers(GLContext* aOrigin, GLsizei aCount, GLuint* aNames)
+{
+ for (GLsizei i = 0; i < aCount; ++i) {
+ mTrackedRenderbuffers.AppendElement(NamedResource(aOrigin, aNames[i]));
+ }
+}
+
+static void
+RemoveNamesFromArray(GLContext* aOrigin, GLsizei aCount, const GLuint* aNames, nsTArray<GLContext::NamedResource>& aArray)
+{
+ for (GLsizei j = 0; j < aCount; ++j) {
+ GLuint name = aNames[j];
+ // name 0 can be ignored
+ if (name == 0)
+ continue;
+
+ for (uint32_t i = 0; i < aArray.Length(); ++i) {
+ if (aArray[i].name == name) {
+ aArray.RemoveElementAt(i);
+ break;
+ }
+ }
+ }
+}
+
+void
+GLContext::DeletedProgram(GLContext* aOrigin, GLuint aName)
+{
+ RemoveNamesFromArray(aOrigin, 1, &aName, mTrackedPrograms);
+}
+
+void
+GLContext::DeletedShader(GLContext* aOrigin, GLuint aName)
+{
+ RemoveNamesFromArray(aOrigin, 1, &aName, mTrackedShaders);
+}
+
+void
+GLContext::DeletedBuffers(GLContext* aOrigin, GLsizei aCount, const GLuint* aNames)
+{
+ RemoveNamesFromArray(aOrigin, aCount, aNames, mTrackedBuffers);
+}
+
+void
+GLContext::DeletedQueries(GLContext* aOrigin, GLsizei aCount, const GLuint* aNames)
+{
+ RemoveNamesFromArray(aOrigin, aCount, aNames, mTrackedQueries);
+}
+
+void
+GLContext::DeletedTextures(GLContext* aOrigin, GLsizei aCount, const GLuint* aNames)
+{
+ RemoveNamesFromArray(aOrigin, aCount, aNames, mTrackedTextures);
+}
+
+void
+GLContext::DeletedFramebuffers(GLContext* aOrigin, GLsizei aCount, const GLuint* aNames)
+{
+ RemoveNamesFromArray(aOrigin, aCount, aNames, mTrackedFramebuffers);
+}
+
+void
+GLContext::DeletedRenderbuffers(GLContext* aOrigin, GLsizei aCount, const GLuint* aNames)
+{
+ RemoveNamesFromArray(aOrigin, aCount, aNames, mTrackedRenderbuffers);
+}
+
+static void
+MarkContextDestroyedInArray(GLContext* aContext, nsTArray<GLContext::NamedResource>& aArray)
+{
+ for (uint32_t i = 0; i < aArray.Length(); ++i) {
+ if (aArray[i].origin == aContext)
+ aArray[i].originDeleted = true;
+ }
+}
+
+void
+GLContext::SharedContextDestroyed(GLContext* aChild)
+{
+ MarkContextDestroyedInArray(aChild, mTrackedPrograms);
+ MarkContextDestroyedInArray(aChild, mTrackedShaders);
+ MarkContextDestroyedInArray(aChild, mTrackedTextures);
+ MarkContextDestroyedInArray(aChild, mTrackedFramebuffers);
+ MarkContextDestroyedInArray(aChild, mTrackedRenderbuffers);
+ MarkContextDestroyedInArray(aChild, mTrackedBuffers);
+ MarkContextDestroyedInArray(aChild, mTrackedQueries);
+}
+
+static void
+ReportArrayContents(const char* title, const nsTArray<GLContext::NamedResource>& aArray)
+{
+ if (aArray.Length() == 0)
+ return;
+
+ printf_stderr("%s:\n", title);
+
+ nsTArray<GLContext::NamedResource> copy(aArray);
+ copy.Sort();
+
+ GLContext* lastContext = nullptr;
+ for (uint32_t i = 0; i < copy.Length(); ++i) {
+ if (lastContext != copy[i].origin) {
+ if (lastContext)
+ printf_stderr("\n");
+ printf_stderr(" [%p - %s] ", copy[i].origin, copy[i].originDeleted ? "deleted" : "live");
+ lastContext = copy[i].origin;
+ }
+ printf_stderr("%d ", copy[i].name);
+ }
+ printf_stderr("\n");
+}
+
+void
+GLContext::ReportOutstandingNames()
+{
+ if (!ShouldSpew())
+ return;
+
+ printf_stderr("== GLContext %p Outstanding ==\n", this);
+
+ ReportArrayContents("Outstanding Textures", mTrackedTextures);
+ ReportArrayContents("Outstanding Buffers", mTrackedBuffers);
+ ReportArrayContents("Outstanding Queries", mTrackedQueries);
+ ReportArrayContents("Outstanding Programs", mTrackedPrograms);
+ ReportArrayContents("Outstanding Shaders", mTrackedShaders);
+ ReportArrayContents("Outstanding Framebuffers", mTrackedFramebuffers);
+ ReportArrayContents("Outstanding Renderbuffers", mTrackedRenderbuffers);
+}
+
+#endif /* DEBUG */
+
+void
+GLContext::GuaranteeResolve()
+{
+ if (mScreen) {
+ mScreen->AssureBlitted();
+ }
+ fFinish();
+}
+
+const gfx::IntSize&
+GLContext::OffscreenSize() const
+{
+ MOZ_ASSERT(IsOffscreen());
+ return mScreen->Size();
+}
+
+bool
+GLContext::CreateScreenBufferImpl(const IntSize& size, const SurfaceCaps& caps)
+{
+ UniquePtr<GLScreenBuffer> newScreen = GLScreenBuffer::Create(this, size, caps);
+ if (!newScreen)
+ return false;
+
+ if (!newScreen->Resize(size)) {
+ return false;
+ }
+
+ // This will rebind to 0 (Screen) if needed when
+ // it falls out of scope.
+ ScopedBindFramebuffer autoFB(this);
+
+ mScreen = Move(newScreen);
+
+ return true;
+}
+
+bool
+GLContext::ResizeScreenBuffer(const IntSize& size)
+{
+ if (!IsOffscreenSizeAllowed(size))
+ return false;
+
+ return mScreen->Resize(size);
+}
+
+void
+GLContext::ForceDirtyScreen()
+{
+ ScopedBindFramebuffer autoFB(0);
+
+ BeforeGLDrawCall();
+ // no-op; just pretend we did something
+ AfterGLDrawCall();
+}
+
+void
+GLContext::CleanDirtyScreen()
+{
+ ScopedBindFramebuffer autoFB(0);
+
+ BeforeGLReadCall();
+ // no-op; we just want to make sure the Read FBO is updated if it needs to be
+ AfterGLReadCall();
+}
+
+void
+GLContext::EmptyTexGarbageBin()
+{
+ TexGarbageBin()->EmptyGarbage();
+}
+
+bool
+GLContext::IsOffscreenSizeAllowed(const IntSize& aSize) const
+{
+ int32_t biggerDimension = std::max(aSize.width, aSize.height);
+ int32_t maxAllowed = std::min(mMaxRenderbufferSize, mMaxTextureSize);
+ return biggerDimension <= maxAllowed;
+}
+
+bool
+GLContext::IsOwningThreadCurrent()
+{
+ return PlatformThread::CurrentId() == mOwningThreadId;
+}
+
+GLBlitHelper*
+GLContext::BlitHelper()
+{
+ if (!mBlitHelper) {
+ mBlitHelper.reset(new GLBlitHelper(this));
+ }
+
+ return mBlitHelper.get();
+}
+
+GLReadTexImageHelper*
+GLContext::ReadTexImageHelper()
+{
+ if (!mReadTexImageHelper) {
+ mReadTexImageHelper = MakeUnique<GLReadTexImageHelper>(this);
+ }
+
+ return mReadTexImageHelper.get();
+}
+
+void
+GLContext::FlushIfHeavyGLCallsSinceLastFlush()
+{
+ if (!mHeavyGLCallsSinceLastFlush) {
+ return;
+ }
+ MakeCurrent();
+ fFlush();
+}
+
+/*static*/ bool
+GLContext::ShouldDumpExts()
+{
+ return gfxEnv::GlDumpExtensions();
+}
+
+bool
+DoesStringMatch(const char* aString, const char* aWantedString)
+{
+ if (!aString || !aWantedString)
+ return false;
+
+ const char* occurrence = strstr(aString, aWantedString);
+
+ // aWanted not found
+ if (!occurrence)
+ return false;
+
+ // aWantedString preceded by alpha character
+ if (occurrence != aString && isalpha(*(occurrence-1)))
+ return false;
+
+ // aWantedVendor followed by alpha character
+ const char* afterOccurrence = occurrence + strlen(aWantedString);
+ if (isalpha(*afterOccurrence))
+ return false;
+
+ return true;
+}
+
+/*static*/ bool
+GLContext::ShouldSpew()
+{
+ return gfxEnv::GlSpew();
+}
+
+void
+SplitByChar(const nsACString& str, const char delim, std::vector<nsCString>* const out)
+{
+ uint32_t start = 0;
+ while (true) {
+ int32_t end = str.FindChar(' ', start);
+ if (end == -1)
+ break;
+
+ uint32_t len = (uint32_t)end - start;
+ nsDependentCSubstring substr(str, start, len);
+ out->push_back(nsCString(substr));
+
+ start = end + 1;
+ continue;
+ }
+
+ nsDependentCSubstring substr(str, start);
+ out->push_back(nsCString(substr));
+}
+
+void
+GLContext::Readback(SharedSurface* src, gfx::DataSourceSurface* dest)
+{
+ MOZ_ASSERT(src && dest);
+ MOZ_ASSERT(dest->GetSize() == src->mSize);
+ MOZ_ASSERT(dest->GetFormat() == (src->mHasAlpha ? SurfaceFormat::B8G8R8A8
+ : SurfaceFormat::B8G8R8X8));
+
+ MakeCurrent();
+
+ SharedSurface* prev = GetLockedSurface();
+
+ const bool needsSwap = src != prev;
+ if (needsSwap) {
+ if (prev)
+ prev->UnlockProd();
+ src->LockProd();
+ }
+
+ GLuint tempFB = 0;
+ GLuint tempTex = 0;
+
+ {
+ ScopedBindFramebuffer autoFB(this);
+
+ // We're consuming from the producer side, so which do we use?
+ // Really, we just want a read-only lock, so ConsumerAcquire is the best match.
+ src->ProducerReadAcquire();
+
+ if (src->mAttachType == AttachmentType::Screen) {
+ fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
+ } else {
+ fGenFramebuffers(1, &tempFB);
+ fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, tempFB);
+
+ switch (src->mAttachType) {
+ case AttachmentType::GLTexture:
+ fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0,
+ src->ProdTextureTarget(), src->ProdTexture(), 0);
+ break;
+ case AttachmentType::GLRenderbuffer:
+ fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0,
+ LOCAL_GL_RENDERBUFFER, src->ProdRenderbuffer());
+ break;
+ default:
+ MOZ_CRASH("GFX: bad `src->mAttachType`.");
+ }
+
+ DebugOnly<GLenum> status = fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
+ MOZ_ASSERT(status == LOCAL_GL_FRAMEBUFFER_COMPLETE);
+ }
+
+ if (src->NeedsIndirectReads()) {
+ fGenTextures(1, &tempTex);
+ {
+ ScopedBindTexture autoTex(this, tempTex);
+
+ GLenum format = src->mHasAlpha ? LOCAL_GL_RGBA
+ : LOCAL_GL_RGB;
+ auto width = src->mSize.width;
+ auto height = src->mSize.height;
+ fCopyTexImage2D(LOCAL_GL_TEXTURE_2D, 0, format, 0, 0, width,
+ height, 0);
+ }
+
+ fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
+ LOCAL_GL_COLOR_ATTACHMENT0,
+ LOCAL_GL_TEXTURE_2D, tempTex, 0);
+ }
+
+ ReadPixelsIntoDataSurface(this, dest);
+
+ src->ProducerReadRelease();
+ }
+
+ if (tempFB)
+ fDeleteFramebuffers(1, &tempFB);
+
+ if (tempTex) {
+ fDeleteTextures(1, &tempTex);
+ }
+
+ if (needsSwap) {
+ src->UnlockProd();
+ if (prev)
+ prev->LockProd();
+ }
+}
+
+// Do whatever tear-down is necessary after drawing to our offscreen FBO,
+// if it's bound.
+void
+GLContext::AfterGLDrawCall()
+{
+ if (mScreen) {
+ mScreen->AfterDrawCall();
+ }
+ mHeavyGLCallsSinceLastFlush = true;
+}
+
+// Do whatever setup is necessary to read from our offscreen FBO, if it's
+// bound.
+void
+GLContext::BeforeGLReadCall()
+{
+ if (mScreen)
+ mScreen->BeforeReadCall();
+}
+
+void
+GLContext::fBindFramebuffer(GLenum target, GLuint framebuffer)
+{
+ if (!mScreen) {
+ raw_fBindFramebuffer(target, framebuffer);
+ return;
+ }
+
+ switch (target) {
+ case LOCAL_GL_DRAW_FRAMEBUFFER_EXT:
+ mScreen->BindDrawFB(framebuffer);
+ return;
+
+ case LOCAL_GL_READ_FRAMEBUFFER_EXT:
+ mScreen->BindReadFB(framebuffer);
+ return;
+
+ case LOCAL_GL_FRAMEBUFFER:
+ mScreen->BindFB(framebuffer);
+ return;
+
+ default:
+ // Nothing we care about, likely an error.
+ break;
+ }
+
+ raw_fBindFramebuffer(target, framebuffer);
+}
+
+void
+GLContext::fCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x,
+ GLint y, GLsizei width, GLsizei height, GLint border)
+{
+ if (!IsTextureSizeSafeToPassToDriver(target, width, height)) {
+ // pass wrong values to cause the GL to generate GL_INVALID_VALUE.
+ // See bug 737182 and the comment in IsTextureSizeSafeToPassToDriver.
+ level = -1;
+ width = -1;
+ height = -1;
+ border = -1;
+ }
+
+ BeforeGLReadCall();
+ bool didCopyTexImage2D = false;
+ if (mScreen) {
+ didCopyTexImage2D = mScreen->CopyTexImage2D(target, level, internalformat, x,
+ y, width, height, border);
+ }
+
+ if (!didCopyTexImage2D) {
+ raw_fCopyTexImage2D(target, level, internalformat, x, y, width, height,
+ border);
+ }
+ AfterGLReadCall();
+}
+
+void
+GLContext::fGetIntegerv(GLenum pname, GLint* params)
+{
+ switch (pname) {
+ // LOCAL_GL_FRAMEBUFFER_BINDING is equal to
+ // LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT,
+ // so we don't need two cases.
+ case LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT:
+ if (mScreen) {
+ *params = mScreen->GetDrawFB();
+ } else {
+ raw_fGetIntegerv(pname, params);
+ }
+ break;
+
+ case LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT:
+ if (mScreen) {
+ *params = mScreen->GetReadFB();
+ } else {
+ raw_fGetIntegerv(pname, params);
+ }
+ break;
+
+ case LOCAL_GL_MAX_TEXTURE_SIZE:
+ MOZ_ASSERT(mMaxTextureSize>0);
+ *params = mMaxTextureSize;
+ break;
+
+ case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE:
+ MOZ_ASSERT(mMaxCubeMapTextureSize>0);
+ *params = mMaxCubeMapTextureSize;
+ break;
+
+ case LOCAL_GL_MAX_RENDERBUFFER_SIZE:
+ MOZ_ASSERT(mMaxRenderbufferSize>0);
+ *params = mMaxRenderbufferSize;
+ break;
+
+ case LOCAL_GL_VIEWPORT:
+ for (size_t i = 0; i < 4; i++) {
+ params[i] = mViewportRect[i];
+ }
+ break;
+
+ case LOCAL_GL_SCISSOR_BOX:
+ for (size_t i = 0; i < 4; i++) {
+ params[i] = mScissorRect[i];
+ }
+ break;
+
+ default:
+ raw_fGetIntegerv(pname, params);
+ break;
+ }
+}
+
+void
+GLContext::fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
+ GLenum type, GLvoid* pixels)
+{
+ BeforeGLReadCall();
+
+ bool didReadPixels = false;
+ if (mScreen) {
+ didReadPixels = mScreen->ReadPixels(x, y, width, height, format, type, pixels);
+ }
+
+ if (!didReadPixels) {
+ raw_fReadPixels(x, y, width, height, format, type, pixels);
+ }
+
+ AfterGLReadCall();
+
+ // Check if GL is giving back 1.0 alpha for
+ // RGBA reads to RGBA images from no-alpha buffers.
+#ifdef XP_MACOSX
+ if (WorkAroundDriverBugs() &&
+ Vendor() == gl::GLVendor::NVIDIA &&
+ format == LOCAL_GL_RGBA &&
+ type == LOCAL_GL_UNSIGNED_BYTE &&
+ !IsCoreProfile() &&
+ width && height)
+ {
+ GLint alphaBits = 0;
+ fGetIntegerv(LOCAL_GL_ALPHA_BITS, &alphaBits);
+ if (!alphaBits) {
+ const uint32_t alphaMask = 0xff000000;
+
+ uint32_t* itr = (uint32_t*)pixels;
+ uint32_t testPixel = *itr;
+ if ((testPixel & alphaMask) != alphaMask) {
+ // We need to set the alpha channel to 1.0 manually.
+ uint32_t* itrEnd = itr + width*height; // Stride is guaranteed to be width*4.
+
+ for (; itr != itrEnd; itr++) {
+ *itr |= alphaMask;
+ }
+ }
+ }
+ }
+#endif
+}
+
+void
+GLContext::fDeleteFramebuffers(GLsizei n, const GLuint* names)
+{
+ if (mScreen) {
+ // Notify mScreen which framebuffers we're deleting.
+ // Otherwise, we will get framebuffer binding mispredictions.
+ for (int i = 0; i < n; i++) {
+ mScreen->DeletingFB(names[i]);
+ }
+ }
+
+ // Avoid crash by flushing before glDeleteFramebuffers. See bug 1194923.
+ if (mNeedsFlushBeforeDeleteFB) {
+ fFlush();
+ }
+
+ if (n == 1 && *names == 0) {
+ // Deleting framebuffer 0 causes hangs on the DROID. See bug 623228.
+ } else {
+ raw_fDeleteFramebuffers(n, names);
+ }
+ TRACKING_CONTEXT(DeletedFramebuffers(this, n, names));
+}
+
+#ifdef MOZ_WIDGET_ANDROID
+/**
+ * Conservatively estimate whether there is enough available
+ * contiguous virtual address space to map a newly allocated texture.
+ */
+static bool
+WillTextureMapSucceed(GLsizei width, GLsizei height, GLenum format, GLenum type)
+{
+ bool willSucceed = false;
+ // Some drivers leave large gaps between textures, so require
+ // there to be double the actual size of the texture available.
+ size_t size = width * height * GetBytesPerTexel(format, type) * 2;
+
+ void *p = mmap(nullptr, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (p != MAP_FAILED) {
+ willSucceed = true;
+ munmap(p, size);
+ }
+
+ return willSucceed;
+}
+#endif // MOZ_WIDGET_ANDROID
+
+void
+GLContext::fTexImage2D(GLenum target, GLint level, GLint internalformat,
+ GLsizei width, GLsizei height, GLint border,
+ GLenum format, GLenum type, const GLvoid* pixels) {
+ if (!IsTextureSizeSafeToPassToDriver(target, width, height)) {
+ // pass wrong values to cause the GL to generate GL_INVALID_VALUE.
+ // See bug 737182 and the comment in IsTextureSizeSafeToPassToDriver.
+ level = -1;
+ width = -1;
+ height = -1;
+ border = -1;
+ }
+#if MOZ_WIDGET_ANDROID
+ if (mTextureAllocCrashesOnMapFailure) {
+ // We have no way of knowing whether this texture already has
+ // storage allocated for it, and therefore whether this check
+ // is necessary. We must therefore assume it does not and
+ // always perform the check.
+ if (!WillTextureMapSucceed(width, height, internalformat, type)) {
+ return;
+ }
+ }
+#endif
+ raw_fTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
+}
+
+GLuint
+GLContext::GetDrawFB()
+{
+ if (mScreen)
+ return mScreen->GetDrawFB();
+
+ GLuint ret = 0;
+ GetUIntegerv(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT, &ret);
+ return ret;
+}
+
+GLuint
+GLContext::GetReadFB()
+{
+ if (mScreen)
+ return mScreen->GetReadFB();
+
+ GLenum bindEnum = IsSupported(GLFeature::split_framebuffer)
+ ? LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT
+ : LOCAL_GL_FRAMEBUFFER_BINDING;
+
+ GLuint ret = 0;
+ GetUIntegerv(bindEnum, &ret);
+ return ret;
+}
+
+GLuint
+GLContext::GetFB()
+{
+ if (mScreen) {
+ // This has a very important extra assert that checks that we're
+ // not accidentally ignoring a situation where the draw and read
+ // FBs differ.
+ return mScreen->GetFB();
+ }
+
+ GLuint ret = 0;
+ GetUIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, &ret);
+ return ret;
+}
+
+bool
+GLContext::InitOffscreen(const gfx::IntSize& size, const SurfaceCaps& caps)
+{
+ if (!CreateScreenBuffer(size, caps))
+ return false;
+
+ MakeCurrent();
+ fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
+ fScissor(0, 0, size.width, size.height);
+ fViewport(0, 0, size.width, size.height);
+
+ mCaps = mScreen->mCaps;
+ MOZ_ASSERT(!mCaps.any);
+
+ return true;
+}
+
+bool
+GLContext::IsDrawingToDefaultFramebuffer()
+{
+ return Screen()->IsDrawFramebufferDefault();
+}
+
+GLuint
+CreateTexture(GLContext* aGL, GLenum aInternalFormat, GLenum aFormat,
+ GLenum aType, const gfx::IntSize& aSize, bool linear)
+{
+ GLuint tex = 0;
+ aGL->fGenTextures(1, &tex);
+ ScopedBindTexture autoTex(aGL, tex);
+
+ aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D,
+ LOCAL_GL_TEXTURE_MIN_FILTER, linear ? LOCAL_GL_LINEAR
+ : LOCAL_GL_NEAREST);
+ aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D,
+ LOCAL_GL_TEXTURE_MAG_FILTER, linear ? LOCAL_GL_LINEAR
+ : LOCAL_GL_NEAREST);
+ aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S,
+ LOCAL_GL_CLAMP_TO_EDGE);
+ aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T,
+ LOCAL_GL_CLAMP_TO_EDGE);
+
+ aGL->fTexImage2D(LOCAL_GL_TEXTURE_2D,
+ 0,
+ aInternalFormat,
+ aSize.width, aSize.height,
+ 0,
+ aFormat,
+ aType,
+ nullptr);
+
+ return tex;
+}
+
+GLuint
+CreateTextureForOffscreen(GLContext* aGL, const GLFormats& aFormats,
+ const gfx::IntSize& aSize)
+{
+ MOZ_ASSERT(aFormats.color_texInternalFormat);
+ MOZ_ASSERT(aFormats.color_texFormat);
+ MOZ_ASSERT(aFormats.color_texType);
+
+ GLenum internalFormat = aFormats.color_texInternalFormat;
+ GLenum unpackFormat = aFormats.color_texFormat;
+ GLenum unpackType = aFormats.color_texType;
+ if (aGL->IsANGLE()) {
+ MOZ_ASSERT(internalFormat == LOCAL_GL_RGBA);
+ MOZ_ASSERT(unpackFormat == LOCAL_GL_RGBA);
+ MOZ_ASSERT(unpackType == LOCAL_GL_UNSIGNED_BYTE);
+ internalFormat = LOCAL_GL_BGRA_EXT;
+ unpackFormat = LOCAL_GL_BGRA_EXT;
+ }
+
+ return CreateTexture(aGL, internalFormat, unpackFormat, unpackType, aSize);
+}
+
+uint32_t
+GetBytesPerTexel(GLenum format, GLenum type)
+{
+ // If there is no defined format or type, we're not taking up any memory
+ if (!format || !type) {
+ return 0;
+ }
+
+ if (format == LOCAL_GL_DEPTH_COMPONENT) {
+ if (type == LOCAL_GL_UNSIGNED_SHORT)
+ return 2;
+ else if (type == LOCAL_GL_UNSIGNED_INT)
+ return 4;
+ } else if (format == LOCAL_GL_DEPTH_STENCIL) {
+ if (type == LOCAL_GL_UNSIGNED_INT_24_8_EXT)
+ return 4;
+ }
+
+ if (type == LOCAL_GL_UNSIGNED_BYTE || type == LOCAL_GL_FLOAT || type == LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV) {
+ uint32_t multiplier = type == LOCAL_GL_UNSIGNED_BYTE ? 1 : 4;
+ switch (format) {
+ case LOCAL_GL_ALPHA:
+ case LOCAL_GL_LUMINANCE:
+ return 1 * multiplier;
+ case LOCAL_GL_LUMINANCE_ALPHA:
+ return 2 * multiplier;
+ case LOCAL_GL_RGB:
+ return 3 * multiplier;
+ case LOCAL_GL_RGBA:
+ case LOCAL_GL_BGRA_EXT:
+ return 4 * multiplier;
+ default:
+ break;
+ }
+ } else if (type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 ||
+ type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 ||
+ type == LOCAL_GL_UNSIGNED_SHORT_5_6_5)
+ {
+ return 2;
+ }
+
+ gfxCriticalError() << "Unknown texture type " << type << " or format " << format;
+ return 0;
+}
+
+} /* namespace gl */
+} /* namespace mozilla */
diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h
new file mode 100644
index 0000000000..f205630705
--- /dev/null
+++ b/gfx/gl/GLContext.h
@@ -0,0 +1,3736 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GLCONTEXT_H_
+#define GLCONTEXT_H_
+
+#include <bitset>
+#include <ctype.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <map>
+#include <queue>
+#include <stack>
+
+#ifdef DEBUG
+#include <string.h>
+#endif
+
+#ifdef GetClassName
+#undef GetClassName
+#endif
+
+// Define MOZ_GL_DEBUG unconditionally to enable GL debugging in opt
+// builds.
+#ifdef DEBUG
+#define MOZ_GL_DEBUG 1
+#endif
+
+#include "../../mfbt/RefPtr.h"
+#include "../../mfbt/UniquePtr.h"
+
+#include "GLDefs.h"
+#include "GLLibraryLoader.h"
+#include "nsISupportsImpl.h"
+#include "plstr.h"
+#include "GLContextTypes.h"
+#include "SurfaceTypes.h"
+#include "GLContextSymbols.h"
+#include "base/platform_thread.h" // for PlatformThreadId
+#include "mozilla/GenericRefCounted.h"
+#include "mozilla/WeakPtr.h"
+#include "gfx2DGlue.h"
+#include "GeckoProfiler.h"
+
+class nsIWidget;
+
+namespace android {
+ class GraphicBuffer;
+} // namespace android
+
+namespace mozilla {
+ namespace gfx {
+ class DataSourceSurface;
+ class SourceSurface;
+ } // namespace gfx
+
+ namespace gl {
+ class GLBlitHelper;
+ class GLBlitTextureImageHelper;
+ class GLContext;
+ class GLLibraryEGL;
+ class GLReadTexImageHelper;
+ class GLScreenBuffer;
+ class SharedSurface;
+ class TextureGarbageBin;
+ struct SurfaceCaps;
+ } // namespace gl
+
+ namespace layers {
+ class ColorTextureLayerProgram;
+ } // namespace layers
+} // namespace mozilla
+
+namespace mozilla {
+namespace gl {
+
+enum class GLFeature {
+ bind_buffer_offset,
+ blend_minmax,
+ clear_buffers,
+ copy_buffer,
+ depth_texture,
+ draw_buffers,
+ draw_instanced,
+ draw_range_elements,
+ element_index_uint,
+ ES2_compatibility,
+ ES3_compatibility,
+ EXT_color_buffer_float,
+ frag_color_float,
+ frag_depth,
+ framebuffer_blit,
+ framebuffer_multisample,
+ framebuffer_object,
+ framebuffer_object_EXT_OES,
+ get_integer_indexed,
+ get_integer64_indexed,
+ get_query_object_i64v,
+ get_query_object_iv,
+ get_string_indexed,
+ gpu_shader4,
+ instanced_arrays,
+ instanced_non_arrays,
+ internalformat_query,
+ invalidate_framebuffer,
+ map_buffer_range,
+ occlusion_query,
+ occlusion_query_boolean,
+ occlusion_query2,
+ packed_depth_stencil,
+ prim_restart,
+ prim_restart_fixed,
+ query_counter,
+ query_objects,
+ query_time_elapsed,
+ read_buffer,
+ renderbuffer_color_float,
+ renderbuffer_color_half_float,
+ robustness,
+ sRGB_framebuffer,
+ sRGB_texture,
+ sampler_objects,
+ seamless_cube_map_opt_in,
+ shader_texture_lod,
+ split_framebuffer,
+ standard_derivatives,
+ sync,
+ texture_3D,
+ texture_3D_compressed,
+ texture_3D_copy,
+ texture_float,
+ texture_float_linear,
+ texture_half_float,
+ texture_half_float_linear,
+ texture_non_power_of_two,
+ texture_rg,
+ texture_storage,
+ texture_swizzle,
+ transform_feedback2,
+ uniform_buffer_object,
+ uniform_matrix_nonsquare,
+ vertex_array_object,
+ EnumMax
+};
+
+enum class ContextProfile : uint8_t {
+ Unknown = 0,
+ OpenGL, // only for IsAtLeast's <profile> parameter
+ OpenGLCore,
+ OpenGLCompatibility,
+ OpenGLES
+};
+
+enum class GLVendor {
+ Intel,
+ NVIDIA,
+ ATI,
+ Qualcomm,
+ Imagination,
+ Nouveau,
+ Vivante,
+ VMware,
+ ARM,
+ Other
+};
+
+enum class GLRenderer {
+ Adreno200,
+ Adreno205,
+ AdrenoTM200,
+ AdrenoTM205,
+ AdrenoTM305,
+ AdrenoTM320,
+ AdrenoTM330,
+ AdrenoTM420,
+ Mali400MP,
+ Mali450MP,
+ SGX530,
+ SGX540,
+ SGX544MP,
+ Tegra,
+ AndroidEmulator,
+ GalliumLlvmpipe,
+ IntelHD3000,
+ MicrosoftBasicRenderDriver,
+ Other
+};
+
+class GLContext
+ : public GLLibraryLoader
+ , public GenericAtomicRefCounted
+ , public SupportsWeakPtr<GLContext>
+{
+public:
+ MOZ_DECLARE_WEAKREFERENCE_TYPENAME(GLContext)
+
+// -----------------------------------------------------------------------------
+// basic enums
+public:
+
+// -----------------------------------------------------------------------------
+// basic getters
+public:
+
+ /**
+ * Returns true if the context is using ANGLE. This should only be overridden
+ * for an ANGLE implementation.
+ */
+ virtual bool IsANGLE() const {
+ return false;
+ }
+
+ /**
+ * Returns true if the context is using WARP. This should only be overridden
+ * for an ANGLE implementation.
+ */
+ virtual bool IsWARP() const {
+ return false;
+ }
+
+ /**
+ * Return true if we are running on a OpenGL core profile context
+ */
+ inline bool IsCoreProfile() const {
+ MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
+
+ return mProfile == ContextProfile::OpenGLCore;
+ }
+
+ /**
+ * Return true if we are running on a OpenGL compatibility profile context
+ * (legacy profile 2.1 on Max OS X)
+ */
+ inline bool IsCompatibilityProfile() const {
+ MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
+
+ return mProfile == ContextProfile::OpenGLCompatibility;
+ }
+
+ /**
+ * Return true if the context is a true OpenGL ES context or an ANGLE context
+ */
+ inline bool IsGLES() const {
+ MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
+
+ return mProfile == ContextProfile::OpenGLES;
+ }
+
+ static const char* GetProfileName(ContextProfile profile)
+ {
+ switch (profile)
+ {
+ case ContextProfile::OpenGL:
+ return "OpenGL";
+ case ContextProfile::OpenGLCore:
+ return "OpenGL Core";
+ case ContextProfile::OpenGLCompatibility:
+ return "OpenGL Compatibility";
+ case ContextProfile::OpenGLES:
+ return "OpenGL ES";
+ default:
+ break;
+ }
+
+ MOZ_ASSERT(profile != ContextProfile::Unknown, "unknown context profile");
+ return "OpenGL unknown profile";
+ }
+
+ /**
+ * Return true if we are running on a OpenGL core profile context
+ */
+ const char* ProfileString() const {
+ return GetProfileName(mProfile);
+ }
+
+ /**
+ * Return true if the context is compatible with given parameters
+ *
+ * IsAtLeast(ContextProfile::OpenGL, N) is exactly same as
+ * IsAtLeast(ContextProfile::OpenGLCore, N) || IsAtLeast(ContextProfile::OpenGLCompatibility, N)
+ */
+ inline bool IsAtLeast(ContextProfile profile, unsigned int version) const
+ {
+ MOZ_ASSERT(profile != ContextProfile::Unknown, "IsAtLeast: bad <profile> parameter");
+ MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
+ MOZ_ASSERT(mVersion != 0, "unknown context version");
+
+ if (version > mVersion) {
+ return false;
+ }
+
+ if (profile == ContextProfile::OpenGL) {
+ return mProfile == ContextProfile::OpenGLCore ||
+ mProfile == ContextProfile::OpenGLCompatibility;
+ }
+
+ return profile == mProfile;
+ }
+
+ /**
+ * Return the version of the context.
+ * Example :
+ * If this a OpenGL 2.1, that will return 210
+ */
+ inline uint32_t Version() const {
+ return mVersion;
+ }
+
+ const char* VersionString() const {
+ return mVersionString.get();
+ }
+
+ inline uint32_t ShadingLanguageVersion() const {
+ return mShadingLanguageVersion;
+ }
+
+ GLVendor Vendor() const {
+ return mVendor;
+ }
+
+ GLRenderer Renderer() const {
+ return mRenderer;
+ }
+
+ bool IsContextLost() const {
+ return mContextLost;
+ }
+
+ /**
+ * If this context is double-buffered, returns TRUE.
+ */
+ virtual bool IsDoubleBuffered() const {
+ return false;
+ }
+
+ virtual GLContextType GetContextType() const = 0;
+
+ virtual bool IsCurrent() = 0;
+
+ /**
+ * Get the default framebuffer for this context.
+ */
+ virtual GLuint GetDefaultFramebuffer() {
+ return 0;
+ }
+
+protected:
+ bool mIsOffscreen;
+ bool mContextLost;
+
+ /**
+ * mVersion store the OpenGL's version, multiplied by 100. For example, if
+ * the context is an OpenGL 2.1 context, mVersion value will be 210.
+ */
+ uint32_t mVersion;
+ nsCString mVersionString;
+ ContextProfile mProfile;
+
+ uint32_t mShadingLanguageVersion;
+
+ GLVendor mVendor;
+ GLRenderer mRenderer;
+
+ void SetProfileVersion(ContextProfile profile, uint32_t version) {
+ MOZ_ASSERT(!mSymbols.fBindFramebuffer,
+ "SetProfileVersion can only be called before initialization!");
+ MOZ_ASSERT(profile != ContextProfile::Unknown &&
+ profile != ContextProfile::OpenGL,
+ "Invalid `profile` for SetProfileVersion");
+ MOZ_ASSERT(version >= 100, "Invalid `version` for SetProfileVersion");
+
+ mVersion = version;
+ mProfile = profile;
+ }
+
+
+// -----------------------------------------------------------------------------
+// Extensions management
+/**
+ * This mechanism is designed to know if an extension is supported. In the long
+ * term, we would like to only use the extension group queries XXX_* to have
+ * full compatibility with context version and profiles (especialy the core that
+ * officialy don't bring any extensions).
+ */
+public:
+
+ /**
+ * Known GL extensions that can be queried by
+ * IsExtensionSupported. The results of this are cached, and as
+ * such it's safe to use this even in performance critical code.
+ * If you add to this array, remember to add to the string names
+ * in GLContext.cpp.
+ */
+ enum GLExtensions {
+ Extension_None = 0,
+ AMD_compressed_ATC_texture,
+ ANGLE_depth_texture,
+ ANGLE_framebuffer_blit,
+ ANGLE_framebuffer_multisample,
+ ANGLE_instanced_arrays,
+ ANGLE_texture_compression_dxt3,
+ ANGLE_texture_compression_dxt5,
+ ANGLE_timer_query,
+ APPLE_client_storage,
+ APPLE_framebuffer_multisample,
+ APPLE_sync,
+ APPLE_texture_range,
+ APPLE_vertex_array_object,
+ ARB_ES2_compatibility,
+ ARB_ES3_compatibility,
+ ARB_color_buffer_float,
+ ARB_copy_buffer,
+ ARB_depth_texture,
+ ARB_draw_buffers,
+ ARB_draw_instanced,
+ ARB_framebuffer_object,
+ ARB_framebuffer_sRGB,
+ ARB_geometry_shader4,
+ ARB_half_float_pixel,
+ ARB_instanced_arrays,
+ ARB_internalformat_query,
+ ARB_invalidate_subdata,
+ ARB_map_buffer_range,
+ ARB_occlusion_query2,
+ ARB_pixel_buffer_object,
+ ARB_robustness,
+ ARB_sampler_objects,
+ ARB_seamless_cube_map,
+ ARB_shader_texture_lod,
+ ARB_sync,
+ ARB_texture_compression,
+ ARB_texture_float,
+ ARB_texture_non_power_of_two,
+ ARB_texture_rectangle,
+ ARB_texture_rg,
+ ARB_texture_storage,
+ ARB_texture_swizzle,
+ ARB_timer_query,
+ ARB_transform_feedback2,
+ ARB_uniform_buffer_object,
+ ARB_vertex_array_object,
+ EXT_bgra,
+ EXT_blend_minmax,
+ EXT_color_buffer_float,
+ EXT_color_buffer_half_float,
+ EXT_copy_texture,
+ EXT_disjoint_timer_query,
+ EXT_draw_buffers,
+ EXT_draw_buffers2,
+ EXT_draw_instanced,
+ EXT_draw_range_elements,
+ EXT_frag_depth,
+ EXT_framebuffer_blit,
+ EXT_framebuffer_multisample,
+ EXT_framebuffer_object,
+ EXT_framebuffer_sRGB,
+ EXT_gpu_shader4,
+ EXT_multisampled_render_to_texture,
+ EXT_occlusion_query_boolean,
+ EXT_packed_depth_stencil,
+ EXT_read_format_bgra,
+ EXT_robustness,
+ EXT_sRGB,
+ EXT_sRGB_write_control,
+ EXT_shader_texture_lod,
+ EXT_texture3D,
+ EXT_texture_compression_dxt1,
+ EXT_texture_compression_s3tc,
+ EXT_texture_filter_anisotropic,
+ EXT_texture_format_BGRA8888,
+ EXT_texture_sRGB,
+ EXT_texture_storage,
+ EXT_timer_query,
+ EXT_transform_feedback,
+ EXT_unpack_subimage,
+ IMG_read_format,
+ IMG_texture_compression_pvrtc,
+ IMG_texture_npot,
+ KHR_debug,
+ NV_draw_instanced,
+ NV_fence,
+ NV_framebuffer_blit,
+ NV_geometry_program4,
+ NV_half_float,
+ NV_instanced_arrays,
+ NV_primitive_restart,
+ NV_texture_barrier,
+ NV_transform_feedback,
+ NV_transform_feedback2,
+ OES_EGL_image,
+ OES_EGL_image_external,
+ OES_EGL_sync,
+ OES_compressed_ETC1_RGB8_texture,
+ OES_depth24,
+ OES_depth32,
+ OES_depth_texture,
+ OES_element_index_uint,
+ OES_framebuffer_object,
+ OES_packed_depth_stencil,
+ OES_rgb8_rgba8,
+ OES_standard_derivatives,
+ OES_stencil8,
+ OES_texture_3D,
+ OES_texture_float,
+ OES_texture_float_linear,
+ OES_texture_half_float,
+ OES_texture_half_float_linear,
+ OES_texture_npot,
+ OES_vertex_array_object,
+ Extensions_Max,
+ Extensions_End
+ };
+
+ bool IsExtensionSupported(GLExtensions aKnownExtension) const {
+ return mAvailableExtensions[aKnownExtension];
+ }
+
+protected:
+ void MarkExtensionUnsupported(GLExtensions aKnownExtension) {
+ mAvailableExtensions[aKnownExtension] = 0;
+ }
+
+ void MarkExtensionSupported(GLExtensions aKnownExtension) {
+ mAvailableExtensions[aKnownExtension] = 1;
+ }
+
+ std::bitset<Extensions_Max> mAvailableExtensions;
+
+// -----------------------------------------------------------------------------
+// Feature queries
+/*
+ * This mecahnism introduces a new way to check if a OpenGL feature is
+ * supported, regardless of whether it is supported by an extension or natively
+ * by the context version/profile
+ */
+public:
+ bool IsSupported(GLFeature feature) const {
+ return mAvailableFeatures[size_t(feature)];
+ }
+
+ static const char* GetFeatureName(GLFeature feature);
+
+private:
+ std::bitset<size_t(GLFeature::EnumMax)> mAvailableFeatures;
+
+ /**
+ * Init features regarding OpenGL extension and context version and profile
+ */
+ void InitFeatures();
+
+ /**
+ * Mark the feature and associated extensions as unsupported
+ */
+ void MarkUnsupported(GLFeature feature);
+
+ /**
+ * Is this feature supported using the core (unsuffixed) symbols?
+ */
+ bool IsFeatureProvidedByCoreSymbols(GLFeature feature);
+
+// -----------------------------------------------------------------------------
+// Robustness handling
+private:
+ /**
+ * The derived class is expected to provide information on whether or not it
+ * supports robustness.
+ */
+ virtual bool SupportsRobustness() const = 0;
+
+public:
+// -----------------------------------------------------------------------------
+// Error handling
+ static const char* GLErrorToString(GLenum aError) {
+ switch (aError) {
+ case LOCAL_GL_INVALID_ENUM:
+ return "GL_INVALID_ENUM";
+ case LOCAL_GL_INVALID_VALUE:
+ return "GL_INVALID_VALUE";
+ case LOCAL_GL_INVALID_OPERATION:
+ return "GL_INVALID_OPERATION";
+ case LOCAL_GL_STACK_OVERFLOW:
+ return "GL_STACK_OVERFLOW";
+ case LOCAL_GL_STACK_UNDERFLOW:
+ return "GL_STACK_UNDERFLOW";
+ case LOCAL_GL_OUT_OF_MEMORY:
+ return "GL_OUT_OF_MEMORY";
+ case LOCAL_GL_TABLE_TOO_LARGE:
+ return "GL_TABLE_TOO_LARGE";
+ case LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION:
+ return "GL_INVALID_FRAMEBUFFER_OPERATION";
+ default:
+ return "";
+ }
+ }
+
+private:
+ GLenum mTopError;
+
+ GLenum RawGetError() {
+ return mSymbols.fGetError();
+ }
+
+ GLenum RawGetErrorAndClear() {
+ GLenum err = RawGetError();
+
+ if (err)
+ while (RawGetError()) {}
+
+ return err;
+ }
+
+public:
+ GLenum FlushErrors() {
+ GLenum err = RawGetErrorAndClear();
+ if (!mTopError)
+ mTopError = err;
+ return err;
+ }
+
+ // We smash all errors together, so you never have to loop on this. We
+ // guarantee that immediately after this call, there are no errors left.
+ GLenum fGetError() {
+ FlushErrors();
+
+ GLenum err = mTopError;
+ mTopError = LOCAL_GL_NO_ERROR;
+ return err;
+ }
+
+ ////////////////////////////////////
+ // Use this safer option.
+ class LocalErrorScope;
+
+private:
+ std::stack<const LocalErrorScope*> mLocalErrorScopeStack;
+
+public:
+ class LocalErrorScope {
+ GLContext& mGL;
+ GLenum mOldTop;
+ bool mHasBeenChecked;
+
+ public:
+ explicit LocalErrorScope(GLContext& gl)
+ : mGL(gl)
+ , mHasBeenChecked(false)
+ {
+ mGL.mLocalErrorScopeStack.push(this);
+
+ mGL.FlushErrors();
+
+ mOldTop = mGL.mTopError;
+ mGL.mTopError = LOCAL_GL_NO_ERROR;
+ }
+
+ GLenum GetError() {
+ MOZ_ASSERT(!mHasBeenChecked);
+ mHasBeenChecked = true;
+
+ const GLenum ret = mGL.fGetError();
+
+ while (mGL.fGetError()) {}
+
+ return ret;
+ }
+
+ ~LocalErrorScope() {
+ MOZ_ASSERT(mHasBeenChecked);
+
+ MOZ_ASSERT(mGL.fGetError() == LOCAL_GL_NO_ERROR);
+
+ MOZ_ASSERT(mGL.mLocalErrorScopeStack.top() == this);
+ mGL.mLocalErrorScopeStack.pop();
+
+ mGL.mTopError = mOldTop;
+ }
+ };
+
+ bool GetPotentialInteger(GLenum pname, GLint* param) {
+ LocalErrorScope localError(*this);
+
+ fGetIntegerv(pname, param);
+
+ GLenum err = localError.GetError();
+ MOZ_ASSERT_IF(err != LOCAL_GL_NO_ERROR, err == LOCAL_GL_INVALID_ENUM);
+ return err == LOCAL_GL_NO_ERROR;
+ }
+
+private:
+ static void GLAPIENTRY StaticDebugCallback(GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar* message,
+ const GLvoid* userParam);
+ void DebugCallback(GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar* message);
+
+
+// -----------------------------------------------------------------------------
+// MOZ_GL_DEBUG implementation
+private:
+
+#undef BEFORE_GL_CALL
+#undef AFTER_GL_CALL
+
+#ifdef MOZ_GL_DEBUG
+
+#ifndef MOZ_FUNCTION_NAME
+# ifdef __GNUC__
+# define MOZ_FUNCTION_NAME __PRETTY_FUNCTION__
+# elif defined(_MSC_VER)
+# define MOZ_FUNCTION_NAME __FUNCTION__
+# else
+# define MOZ_FUNCTION_NAME __func__ // defined in C99, supported in various C++ compilers. Just raw function name.
+# endif
+#endif
+
+ void BeforeGLCall(const char* funcName) {
+ MOZ_ASSERT(IsCurrent());
+
+ if (mDebugFlags) {
+ FlushErrors();
+
+ if (mDebugFlags & DebugFlagTrace) {
+ printf_stderr("[gl:%p] > %s\n", this, funcName);
+ }
+
+ GLContext* tlsContext = (GLContext*)PR_GetThreadPrivate(sCurrentGLContextTLS);
+ if (this != tlsContext) {
+ printf_stderr("Fatal: %s called on non-current context %p. The"
+ " current context for this thread is %p.\n",
+ funcName, this, tlsContext);
+ MOZ_CRASH("GFX: GLContext is not current.");
+ }
+ }
+ }
+
+ void AfterGLCall(const char* funcName) {
+ if (mDebugFlags) {
+ // calling fFinish() immediately after every GL call makes sure that if this GL command crashes,
+ // the stack trace will actually point to it. Otherwise, OpenGL being an asynchronous API, stack traces
+ // tend to be meaningless
+ mSymbols.fFinish();
+ GLenum err = FlushErrors();
+
+ if (mDebugFlags & DebugFlagTrace) {
+ printf_stderr("[gl:%p] < %s [%s (0x%04x)]\n", this, funcName,
+ GLErrorToString(err), err);
+ }
+
+ if (err != LOCAL_GL_NO_ERROR &&
+ !mLocalErrorScopeStack.size())
+ {
+ printf_stderr("[gl:%p] %s: Generated unexpected %s error."
+ " (0x%04x)\n", this, funcName,
+ GLErrorToString(err), err);
+
+ if (mDebugFlags & DebugFlagAbortOnError) {
+ MOZ_CRASH("Unexpected error with MOZ_GL_DEBUG_ABORT_ON_ERROR. (Run"
+ " with MOZ_GL_DEBUG_ABORT_ON_ERROR=0 to disable)");
+ }
+ }
+ }
+ }
+
+ GLContext* TrackingContext()
+ {
+ GLContext* tip = this;
+ while (tip->mSharedContext)
+ tip = tip->mSharedContext;
+ return tip;
+ }
+
+ static void AssertNotPassingStackBufferToTheGL(const void* ptr);
+
+#ifdef MOZ_WIDGET_ANDROID
+// Record the name of the GL call for better hang stacks on Android.
+#define BEFORE_GL_CALL \
+ PROFILER_LABEL_FUNC( \
+ js::ProfileEntry::Category::GRAPHICS);\
+ BeforeGLCall(MOZ_FUNCTION_NAME)
+#else
+#define BEFORE_GL_CALL \
+ do { \
+ BeforeGLCall(MOZ_FUNCTION_NAME); \
+ } while (0)
+#endif
+
+#define AFTER_GL_CALL \
+ do { \
+ AfterGLCall(MOZ_FUNCTION_NAME); \
+ } while (0)
+
+#define TRACKING_CONTEXT(a) \
+ do { \
+ TrackingContext()->a; \
+ } while (0)
+
+#define ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(ptr) AssertNotPassingStackBufferToTheGL(ptr)
+
+#else // ifdef MOZ_GL_DEBUG
+
+#ifdef MOZ_WIDGET_ANDROID
+// Record the name of the GL call for better hang stacks on Android.
+#define BEFORE_GL_CALL PROFILER_LABEL_FUNC(js::ProfileEntry::Category::GRAPHICS)
+#else
+#define BEFORE_GL_CALL do { } while (0)
+#endif
+#define AFTER_GL_CALL do { } while (0)
+#define TRACKING_CONTEXT(a) do {} while (0)
+#define ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(ptr) do {} while (0)
+
+#endif // ifdef MOZ_GL_DEBUG
+
+#define ASSERT_SYMBOL_PRESENT(func) \
+ do {\
+ MOZ_ASSERT(strstr(MOZ_FUNCTION_NAME, #func) != nullptr, "Mismatched symbol check.");\
+ if (MOZ_UNLIKELY(!mSymbols.func)) {\
+ printf_stderr("RUNTIME ASSERT: Uninitialized GL function: %s\n", #func);\
+ MOZ_CRASH("GFX: Uninitialized GL function");\
+ }\
+ } while (0)
+
+ // Do whatever setup is necessary to draw to our offscreen FBO, if it's
+ // bound.
+ void BeforeGLDrawCall() { }
+
+ // Do whatever tear-down is necessary after drawing to our offscreen FBO,
+ // if it's bound.
+ void AfterGLDrawCall();
+
+ // Do whatever setup is necessary to read from our offscreen FBO, if it's
+ // bound.
+ void BeforeGLReadCall();
+
+ // Do whatever tear-down is necessary after reading from our offscreen FBO,
+ // if it's bound.
+ void AfterGLReadCall() { }
+
+
+// -----------------------------------------------------------------------------
+// GL official entry points
+public:
+
+ void fActiveTexture(GLenum texture) {
+ BEFORE_GL_CALL;
+ mSymbols.fActiveTexture(texture);
+ AFTER_GL_CALL;
+ }
+
+ void fAttachShader(GLuint program, GLuint shader) {
+ BEFORE_GL_CALL;
+ mSymbols.fAttachShader(program, shader);
+ AFTER_GL_CALL;
+ }
+
+ void fBeginQuery(GLenum target, GLuint id) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fBeginQuery);
+ mSymbols.fBeginQuery(target, id);
+ AFTER_GL_CALL;
+ }
+
+ void fBindAttribLocation(GLuint program, GLuint index, const GLchar* name) {
+ BEFORE_GL_CALL;
+ mSymbols.fBindAttribLocation(program, index, name);
+ AFTER_GL_CALL;
+ }
+
+ void fBindBuffer(GLenum target, GLuint buffer) {
+ BEFORE_GL_CALL;
+ mSymbols.fBindBuffer(target, buffer);
+ AFTER_GL_CALL;
+ }
+
+ void fBindFramebuffer(GLenum target, GLuint framebuffer);
+
+ void fInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments) {
+ BeforeGLDrawCall();
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fInvalidateFramebuffer);
+ mSymbols.fInvalidateFramebuffer(target, numAttachments, attachments);
+ AFTER_GL_CALL;
+ AfterGLDrawCall();
+ }
+
+ void fInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height) {
+ BeforeGLDrawCall();
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fInvalidateSubFramebuffer);
+ mSymbols.fInvalidateSubFramebuffer(target, numAttachments, attachments, x, y, width, height);
+ AFTER_GL_CALL;
+ AfterGLDrawCall();
+ }
+
+ void fBindTexture(GLenum target, GLuint texture) {
+ BEFORE_GL_CALL;
+ mSymbols.fBindTexture(target, texture);
+ AFTER_GL_CALL;
+ }
+
+ void fBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
+ BEFORE_GL_CALL;
+ mSymbols.fBlendColor(red, green, blue, alpha);
+ AFTER_GL_CALL;
+ }
+
+ void fBlendEquation(GLenum mode) {
+ BEFORE_GL_CALL;
+ mSymbols.fBlendEquation(mode);
+ AFTER_GL_CALL;
+ }
+
+ void fBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) {
+ BEFORE_GL_CALL;
+ mSymbols.fBlendEquationSeparate(modeRGB, modeAlpha);
+ AFTER_GL_CALL;
+ }
+
+ void fBlendFunc(GLenum sfactor, GLenum dfactor) {
+ BEFORE_GL_CALL;
+ mSymbols.fBlendFunc(sfactor, dfactor);
+ AFTER_GL_CALL;
+ }
+
+ void fBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) {
+ BEFORE_GL_CALL;
+ mSymbols.fBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
+ AFTER_GL_CALL;
+ }
+
+private:
+ void raw_fBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) {
+ ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(data);
+ BEFORE_GL_CALL;
+ mSymbols.fBufferData(target, size, data, usage);
+ AFTER_GL_CALL;
+ mHeavyGLCallsSinceLastFlush = true;
+ }
+
+public:
+ void fBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) {
+ raw_fBufferData(target, size, data, usage);
+
+ // bug 744888
+ if (WorkAroundDriverBugs() &&
+ !data &&
+ Vendor() == GLVendor::NVIDIA)
+ {
+ UniquePtr<char[]> buf = MakeUnique<char[]>(1);
+ buf[0] = 0;
+ fBufferSubData(target, size-1, 1, buf.get());
+ }
+ }
+
+ void fBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) {
+ ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(data);
+ BEFORE_GL_CALL;
+ mSymbols.fBufferSubData(target, offset, size, data);
+ AFTER_GL_CALL;
+ mHeavyGLCallsSinceLastFlush = true;
+ }
+
+private:
+ void raw_fClear(GLbitfield mask) {
+ BEFORE_GL_CALL;
+ mSymbols.fClear(mask);
+ AFTER_GL_CALL;
+ }
+
+public:
+ void fClear(GLbitfield mask) {
+ BeforeGLDrawCall();
+ raw_fClear(mask);
+ AfterGLDrawCall();
+ }
+
+ void fClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) {
+ BeforeGLDrawCall();
+ BEFORE_GL_CALL;
+ mSymbols.fClearBufferfi(buffer, drawbuffer, depth, stencil);
+ AFTER_GL_CALL;
+ AfterGLDrawCall();
+ }
+
+ void fClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) {
+ BeforeGLDrawCall();
+ BEFORE_GL_CALL;
+ mSymbols.fClearBufferfv(buffer, drawbuffer, value);
+ AFTER_GL_CALL;
+ AfterGLDrawCall();
+ }
+
+ void fClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) {
+ BeforeGLDrawCall();
+ BEFORE_GL_CALL;
+ mSymbols.fClearBufferiv(buffer, drawbuffer, value);
+ AFTER_GL_CALL;
+ AfterGLDrawCall();
+ }
+
+ void fClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) {
+ BeforeGLDrawCall();
+ BEFORE_GL_CALL;
+ mSymbols.fClearBufferuiv(buffer, drawbuffer, value);
+ AFTER_GL_CALL;
+ AfterGLDrawCall();
+ }
+
+ void fClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
+ BEFORE_GL_CALL;
+ mSymbols.fClearColor(r, g, b, a);
+ AFTER_GL_CALL;
+ }
+
+ void fClearStencil(GLint s) {
+ BEFORE_GL_CALL;
+ mSymbols.fClearStencil(s);
+ AFTER_GL_CALL;
+ }
+
+ void fClientActiveTexture(GLenum texture) {
+ BEFORE_GL_CALL;
+ mSymbols.fClientActiveTexture(texture);
+ AFTER_GL_CALL;
+ }
+
+ void fColorMask(realGLboolean red, realGLboolean green, realGLboolean blue, realGLboolean alpha) {
+ BEFORE_GL_CALL;
+ mSymbols.fColorMask(red, green, blue, alpha);
+ AFTER_GL_CALL;
+ }
+
+ void fCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* pixels) {
+ ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels);
+ BEFORE_GL_CALL;
+ mSymbols.fCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, pixels);
+ AFTER_GL_CALL;
+ mHeavyGLCallsSinceLastFlush = true;
+ }
+
+ void fCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* pixels) {
+ ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels);
+ BEFORE_GL_CALL;
+ mSymbols.fCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, pixels);
+ AFTER_GL_CALL;
+ mHeavyGLCallsSinceLastFlush = true;
+ }
+
+ void fCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x,
+ GLint y, GLsizei width, GLsizei height, GLint border);
+
+ void fCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
+ BeforeGLReadCall();
+ raw_fCopyTexSubImage2D(target, level, xoffset, yoffset,
+ x, y, width, height);
+ AfterGLReadCall();
+ }
+
+ void fCullFace(GLenum mode) {
+ BEFORE_GL_CALL;
+ mSymbols.fCullFace(mode);
+ AFTER_GL_CALL;
+ }
+
+ void fDebugMessageCallback(GLDEBUGPROC callback, const GLvoid* userParam) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fDebugMessageCallback);
+ mSymbols.fDebugMessageCallback(callback, userParam);
+ AFTER_GL_CALL;
+ }
+
+ void fDebugMessageControl(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, realGLboolean enabled) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fDebugMessageControl);
+ mSymbols.fDebugMessageControl(source, type, severity, count, ids, enabled);
+ AFTER_GL_CALL;
+ }
+
+ void fDebugMessageInsert(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fDebugMessageInsert);
+ mSymbols.fDebugMessageInsert(source, type, id, severity, length, buf);
+ AFTER_GL_CALL;
+ }
+
+ void fDetachShader(GLuint program, GLuint shader) {
+ BEFORE_GL_CALL;
+ mSymbols.fDetachShader(program, shader);
+ AFTER_GL_CALL;
+ }
+
+ void fDepthFunc(GLenum func) {
+ BEFORE_GL_CALL;
+ mSymbols.fDepthFunc(func);
+ AFTER_GL_CALL;
+ }
+
+ void fDepthMask(realGLboolean flag) {
+ BEFORE_GL_CALL;
+ mSymbols.fDepthMask(flag);
+ AFTER_GL_CALL;
+ }
+
+ void fDisable(GLenum capability) {
+ BEFORE_GL_CALL;
+ mSymbols.fDisable(capability);
+ AFTER_GL_CALL;
+ }
+
+ void fDisableClientState(GLenum capability) {
+ BEFORE_GL_CALL;
+ mSymbols.fDisableClientState(capability);
+ AFTER_GL_CALL;
+ }
+
+ void fDisableVertexAttribArray(GLuint index) {
+ BEFORE_GL_CALL;
+ mSymbols.fDisableVertexAttribArray(index);
+ AFTER_GL_CALL;
+ }
+
+ void fDrawBuffer(GLenum mode) {
+ BEFORE_GL_CALL;
+ mSymbols.fDrawBuffer(mode);
+ AFTER_GL_CALL;
+ }
+
+private:
+ void raw_fDrawArrays(GLenum mode, GLint first, GLsizei count) {
+ BEFORE_GL_CALL;
+ mSymbols.fDrawArrays(mode, first, count);
+ AFTER_GL_CALL;
+ }
+
+ void raw_fDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) {
+ BEFORE_GL_CALL;
+ mSymbols.fDrawElements(mode, count, type, indices);
+ AFTER_GL_CALL;
+ }
+
+public:
+ void fDrawArrays(GLenum mode, GLint first, GLsizei count) {
+ BeforeGLDrawCall();
+ raw_fDrawArrays(mode, first, count);
+ AfterGLDrawCall();
+ }
+
+ void fDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) {
+ BeforeGLDrawCall();
+ raw_fDrawElements(mode, count, type, indices);
+ AfterGLDrawCall();
+ }
+
+ void fEnable(GLenum capability) {
+ BEFORE_GL_CALL;
+ mSymbols.fEnable(capability);
+ AFTER_GL_CALL;
+ }
+
+ void fEnableClientState(GLenum capability) {
+ BEFORE_GL_CALL;
+ mSymbols.fEnableClientState(capability);
+ AFTER_GL_CALL;
+ }
+
+ void fEnableVertexAttribArray(GLuint index) {
+ BEFORE_GL_CALL;
+ mSymbols.fEnableVertexAttribArray(index);
+ AFTER_GL_CALL;
+ }
+
+ void fEndQuery(GLenum target) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fEndQuery);
+ mSymbols.fEndQuery(target);
+ AFTER_GL_CALL;
+ }
+
+ void fFinish() {
+ BEFORE_GL_CALL;
+ mSymbols.fFinish();
+ AFTER_GL_CALL;
+ mHeavyGLCallsSinceLastFlush = false;
+ }
+
+ void fFlush() {
+ BEFORE_GL_CALL;
+ mSymbols.fFlush();
+ AFTER_GL_CALL;
+ mHeavyGLCallsSinceLastFlush = false;
+ }
+
+ void fFrontFace(GLenum face) {
+ BEFORE_GL_CALL;
+ mSymbols.fFrontFace(face);
+ AFTER_GL_CALL;
+ }
+
+ void fGetActiveAttrib(GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name) {
+ BEFORE_GL_CALL;
+ mSymbols.fGetActiveAttrib(program, index, maxLength, length, size, type, name);
+ AFTER_GL_CALL;
+ }
+
+ void fGetActiveUniform(GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name) {
+ BEFORE_GL_CALL;
+ mSymbols.fGetActiveUniform(program, index, maxLength, length, size, type, name);
+ AFTER_GL_CALL;
+ }
+
+ void fGetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders) {
+ BEFORE_GL_CALL;
+ mSymbols.fGetAttachedShaders(program, maxCount, count, shaders);
+ AFTER_GL_CALL;
+ }
+
+ GLint fGetAttribLocation(GLuint program, const GLchar* name) {
+ BEFORE_GL_CALL;
+ GLint retval = mSymbols.fGetAttribLocation(program, name);
+ AFTER_GL_CALL;
+ return retval;
+ }
+
+private:
+ void raw_fGetIntegerv(GLenum pname, GLint* params) {
+ BEFORE_GL_CALL;
+ mSymbols.fGetIntegerv(pname, params);
+ AFTER_GL_CALL;
+ }
+
+public:
+
+ void fGetIntegerv(GLenum pname, GLint* params);
+
+ void GetUIntegerv(GLenum pname, GLuint* params) {
+ fGetIntegerv(pname, reinterpret_cast<GLint*>(params));
+ }
+
+ template<typename T>
+ T GetIntAs(GLenum pname) {
+ static_assert(sizeof(T) == sizeof(GLint), "Invalid T.");
+ T ret = 0;
+ fGetIntegerv(pname, (GLint*)&ret);
+ return ret;
+ }
+
+ void fGetFloatv(GLenum pname, GLfloat* params) {
+ BEFORE_GL_CALL;
+ mSymbols.fGetFloatv(pname, params);
+ AFTER_GL_CALL;
+ }
+
+ void fGetBooleanv(GLenum pname, realGLboolean* params) {
+ BEFORE_GL_CALL;
+ mSymbols.fGetBooleanv(pname, params);
+ AFTER_GL_CALL;
+ }
+
+ void fGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) {
+ BEFORE_GL_CALL;
+ mSymbols.fGetBufferParameteriv(target, pname, params);
+ AFTER_GL_CALL;
+ }
+
+ GLuint fGetDebugMessageLog(GLuint count, GLsizei bufsize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGetDebugMessageLog);
+ GLuint ret = mSymbols.fGetDebugMessageLog(count, bufsize, sources, types, ids, severities, lengths, messageLog);
+ AFTER_GL_CALL;
+ return ret;
+ }
+
+ void fGetPointerv(GLenum pname, GLvoid** params) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGetPointerv);
+ mSymbols.fGetPointerv(pname, params);
+ AFTER_GL_CALL;
+ }
+
+ void fGetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei* length, GLchar* label) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGetObjectLabel);
+ mSymbols.fGetObjectLabel(identifier, name, bufSize, length, label);
+ AFTER_GL_CALL;
+ }
+
+ void fGetObjectPtrLabel(const GLvoid* ptr, GLsizei bufSize, GLsizei* length, GLchar* label) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGetObjectPtrLabel);
+ mSymbols.fGetObjectPtrLabel(ptr, bufSize, length, label);
+ AFTER_GL_CALL;
+ }
+
+ void fGenerateMipmap(GLenum target) {
+ BEFORE_GL_CALL;
+ mSymbols.fGenerateMipmap(target);
+ AFTER_GL_CALL;
+ }
+
+ void fGetProgramiv(GLuint program, GLenum pname, GLint* param) {
+ BEFORE_GL_CALL;
+ mSymbols.fGetProgramiv(program, pname, param);
+ AFTER_GL_CALL;
+ }
+
+ void fGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
+ BEFORE_GL_CALL;
+ mSymbols.fGetProgramInfoLog(program, bufSize, length, infoLog);
+ AFTER_GL_CALL;
+ }
+
+ void fTexParameteri(GLenum target, GLenum pname, GLint param) {
+ BEFORE_GL_CALL;
+ mSymbols.fTexParameteri(target, pname, param);
+ AFTER_GL_CALL;
+ }
+
+ void fTexParameteriv(GLenum target, GLenum pname, const GLint* params) {
+ BEFORE_GL_CALL;
+ mSymbols.fTexParameteriv(target, pname, params);
+ AFTER_GL_CALL;
+ }
+
+ void fTexParameterf(GLenum target, GLenum pname, GLfloat param) {
+ BEFORE_GL_CALL;
+ mSymbols.fTexParameterf(target, pname, param);
+ AFTER_GL_CALL;
+ }
+
+ const GLubyte* fGetString(GLenum name) {
+ BEFORE_GL_CALL;
+ const GLubyte* result = mSymbols.fGetString(name);
+ AFTER_GL_CALL;
+ return result;
+ }
+
+ void fGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* img) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGetTexImage);
+ mSymbols.fGetTexImage(target, level, format, type, img);
+ AFTER_GL_CALL;
+ }
+
+ void fGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGetTexLevelParameteriv);
+ mSymbols.fGetTexLevelParameteriv(target, level, pname, params);
+ AFTER_GL_CALL;
+ }
+
+ void fGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) {
+ BEFORE_GL_CALL;
+ mSymbols.fGetTexParameterfv(target, pname, params);
+ AFTER_GL_CALL;
+ }
+
+ void fGetTexParameteriv(GLenum target, GLenum pname, GLint* params) {
+ BEFORE_GL_CALL;
+ mSymbols.fGetTexParameteriv(target, pname, params);
+ AFTER_GL_CALL;
+ }
+
+ void fGetUniformfv(GLuint program, GLint location, GLfloat* params) {
+ BEFORE_GL_CALL;
+ mSymbols.fGetUniformfv(program, location, params);
+ AFTER_GL_CALL;
+ }
+
+ void fGetUniformiv(GLuint program, GLint location, GLint* params) {
+ BEFORE_GL_CALL;
+ mSymbols.fGetUniformiv(program, location, params);
+ AFTER_GL_CALL;
+ }
+
+ void fGetUniformuiv(GLuint program, GLint location, GLuint* params) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGetUniformuiv);
+ mSymbols.fGetUniformuiv(program, location, params);
+ AFTER_GL_CALL;
+ }
+
+ GLint fGetUniformLocation (GLint programObj, const GLchar* name) {
+ BEFORE_GL_CALL;
+ GLint retval = mSymbols.fGetUniformLocation(programObj, name);
+ AFTER_GL_CALL;
+ return retval;
+ }
+
+ void fGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* retval) {
+ BEFORE_GL_CALL;
+ mSymbols.fGetVertexAttribfv(index, pname, retval);
+ AFTER_GL_CALL;
+ }
+
+ void fGetVertexAttribiv(GLuint index, GLenum pname, GLint* retval) {
+ BEFORE_GL_CALL;
+ mSymbols.fGetVertexAttribiv(index, pname, retval);
+ AFTER_GL_CALL;
+ }
+
+ void fGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** retval) {
+ BEFORE_GL_CALL;
+ mSymbols.fGetVertexAttribPointerv(index, pname, retval);
+ AFTER_GL_CALL;
+ }
+
+ void fHint(GLenum target, GLenum mode) {
+ BEFORE_GL_CALL;
+ mSymbols.fHint(target, mode);
+ AFTER_GL_CALL;
+ }
+
+ realGLboolean fIsBuffer(GLuint buffer) {
+ BEFORE_GL_CALL;
+ realGLboolean retval = mSymbols.fIsBuffer(buffer);
+ AFTER_GL_CALL;
+ return retval;
+ }
+
+ realGLboolean fIsEnabled(GLenum capability) {
+ BEFORE_GL_CALL;
+ realGLboolean retval = mSymbols.fIsEnabled(capability);
+ AFTER_GL_CALL;
+ return retval;
+ }
+
+ realGLboolean fIsProgram(GLuint program) {
+ BEFORE_GL_CALL;
+ realGLboolean retval = mSymbols.fIsProgram(program);
+ AFTER_GL_CALL;
+ return retval;
+ }
+
+ realGLboolean fIsShader(GLuint shader) {
+ BEFORE_GL_CALL;
+ realGLboolean retval = mSymbols.fIsShader(shader);
+ AFTER_GL_CALL;
+ return retval;
+ }
+
+ realGLboolean fIsTexture(GLuint texture) {
+ BEFORE_GL_CALL;
+ realGLboolean retval = mSymbols.fIsTexture(texture);
+ AFTER_GL_CALL;
+ return retval;
+ }
+
+ void fLineWidth(GLfloat width) {
+ BEFORE_GL_CALL;
+ mSymbols.fLineWidth(width);
+ AFTER_GL_CALL;
+ }
+
+ void fLinkProgram(GLuint program) {
+ BEFORE_GL_CALL;
+ mSymbols.fLinkProgram(program);
+ AFTER_GL_CALL;
+ }
+
+ void fObjectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar* label) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fObjectLabel);
+ mSymbols.fObjectLabel(identifier, name, length, label);
+ AFTER_GL_CALL;
+ }
+
+ void fObjectPtrLabel(const GLvoid* ptr, GLsizei length, const GLchar* label) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fObjectPtrLabel);
+ mSymbols.fObjectPtrLabel(ptr, length, label);
+ AFTER_GL_CALL;
+ }
+
+ void fLoadIdentity() {
+ BEFORE_GL_CALL;
+ mSymbols.fLoadIdentity();
+ AFTER_GL_CALL;
+ }
+
+ void fLoadMatrixf(const GLfloat* matrix) {
+ BEFORE_GL_CALL;
+ mSymbols.fLoadMatrixf(matrix);
+ AFTER_GL_CALL;
+ }
+
+ void fMatrixMode(GLenum mode) {
+ BEFORE_GL_CALL;
+ mSymbols.fMatrixMode(mode);
+ AFTER_GL_CALL;
+ }
+
+ void fPixelStorei(GLenum pname, GLint param) {
+ BEFORE_GL_CALL;
+ mSymbols.fPixelStorei(pname, param);
+ AFTER_GL_CALL;
+ }
+
+ void fTextureRangeAPPLE(GLenum target, GLsizei length, GLvoid* pointer) {
+ ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pointer);
+ BEFORE_GL_CALL;
+ mSymbols.fTextureRangeAPPLE(target, length, pointer);
+ AFTER_GL_CALL;
+ }
+
+ void fPointParameterf(GLenum pname, GLfloat param) {
+ BEFORE_GL_CALL;
+ mSymbols.fPointParameterf(pname, param);
+ AFTER_GL_CALL;
+ }
+
+ void fPolygonOffset(GLfloat factor, GLfloat bias) {
+ BEFORE_GL_CALL;
+ mSymbols.fPolygonOffset(factor, bias);
+ AFTER_GL_CALL;
+ }
+
+ void fPopDebugGroup() {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fPopDebugGroup);
+ mSymbols.fPopDebugGroup();
+ AFTER_GL_CALL;
+ }
+
+ void fPushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar* message) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fPushDebugGroup);
+ mSymbols.fPushDebugGroup(source, id, length, message);
+ AFTER_GL_CALL;
+ }
+
+ void fReadBuffer(GLenum mode) {
+ BEFORE_GL_CALL;
+ mSymbols.fReadBuffer(mode);
+ AFTER_GL_CALL;
+ }
+
+ void raw_fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) {
+ ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels);
+ BEFORE_GL_CALL;
+ mSymbols.fReadPixels(x, y, width, height, format, type, pixels);
+ AFTER_GL_CALL;
+ mHeavyGLCallsSinceLastFlush = true;
+ }
+
+ void fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
+ GLenum type, GLvoid* pixels);
+
+public:
+ void fSampleCoverage(GLclampf value, realGLboolean invert) {
+ BEFORE_GL_CALL;
+ mSymbols.fSampleCoverage(value, invert);
+ AFTER_GL_CALL;
+ }
+
+ void fScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
+ if (mScissorRect[0] == x &&
+ mScissorRect[1] == y &&
+ mScissorRect[2] == width &&
+ mScissorRect[3] == height)
+ {
+ return;
+ }
+ mScissorRect[0] = x;
+ mScissorRect[1] = y;
+ mScissorRect[2] = width;
+ mScissorRect[3] = height;
+ BEFORE_GL_CALL;
+ mSymbols.fScissor(x, y, width, height);
+ AFTER_GL_CALL;
+ }
+
+ void fStencilFunc(GLenum func, GLint reference, GLuint mask) {
+ BEFORE_GL_CALL;
+ mSymbols.fStencilFunc(func, reference, mask);
+ AFTER_GL_CALL;
+ }
+
+ void fStencilFuncSeparate(GLenum frontfunc, GLenum backfunc, GLint reference, GLuint mask) {
+ BEFORE_GL_CALL;
+ mSymbols.fStencilFuncSeparate(frontfunc, backfunc, reference, mask);
+ AFTER_GL_CALL;
+ }
+
+ void fStencilMask(GLuint mask) {
+ BEFORE_GL_CALL;
+ mSymbols.fStencilMask(mask);
+ AFTER_GL_CALL;
+ }
+
+ void fStencilMaskSeparate(GLenum face, GLuint mask) {
+ BEFORE_GL_CALL;
+ mSymbols.fStencilMaskSeparate(face, mask);
+ AFTER_GL_CALL;
+ }
+
+ void fStencilOp(GLenum fail, GLenum zfail, GLenum zpass) {
+ BEFORE_GL_CALL;
+ mSymbols.fStencilOp(fail, zfail, zpass);
+ AFTER_GL_CALL;
+ }
+
+ void fStencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) {
+ BEFORE_GL_CALL;
+ mSymbols.fStencilOpSeparate(face, sfail, dpfail, dppass);
+ AFTER_GL_CALL;
+ }
+
+ void fTexGeni(GLenum coord, GLenum pname, GLint param) {
+ BEFORE_GL_CALL;
+ mSymbols.fTexGeni(coord, pname, param);
+ AFTER_GL_CALL;
+ }
+
+ void fTexGenf(GLenum coord, GLenum pname, GLfloat param) {
+ BEFORE_GL_CALL;
+ mSymbols.fTexGenf(coord, pname, param);
+ AFTER_GL_CALL;
+ }
+
+ void fTexGenfv(GLenum coord, GLenum pname, const GLfloat* params) {
+ BEFORE_GL_CALL;
+ mSymbols.fTexGenfv(coord, pname, params);
+ AFTER_GL_CALL;
+ }
+
+private:
+ void raw_fTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels) {
+ ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels);
+ BEFORE_GL_CALL;
+ mSymbols.fTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
+ AFTER_GL_CALL;
+ mHeavyGLCallsSinceLastFlush = true;
+ }
+
+public:
+ void fTexImage2D(GLenum target, GLint level, GLint internalformat,
+ GLsizei width, GLsizei height, GLint border,
+ GLenum format, GLenum type, const GLvoid* pixels);
+
+ void fTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels) {
+ ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels);
+ BEFORE_GL_CALL;
+ mSymbols.fTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+ AFTER_GL_CALL;
+ mHeavyGLCallsSinceLastFlush = true;
+ }
+
+ void fUniform1f(GLint location, GLfloat v0) {
+ BEFORE_GL_CALL;
+ mSymbols.fUniform1f(location, v0);
+ AFTER_GL_CALL;
+ }
+
+ void fUniform1fv(GLint location, GLsizei count, const GLfloat* value) {
+ BEFORE_GL_CALL;
+ mSymbols.fUniform1fv(location, count, value);
+ AFTER_GL_CALL;
+ }
+
+ void fUniform1i(GLint location, GLint v0) {
+ BEFORE_GL_CALL;
+ mSymbols.fUniform1i(location, v0);
+ AFTER_GL_CALL;
+ }
+
+ void fUniform1iv(GLint location, GLsizei count, const GLint* value) {
+ BEFORE_GL_CALL;
+ mSymbols.fUniform1iv(location, count, value);
+ AFTER_GL_CALL;
+ }
+
+ void fUniform2f(GLint location, GLfloat v0, GLfloat v1) {
+ BEFORE_GL_CALL;
+ mSymbols.fUniform2f(location, v0, v1);
+ AFTER_GL_CALL;
+ }
+
+ void fUniform2fv(GLint location, GLsizei count, const GLfloat* value) {
+ BEFORE_GL_CALL;
+ mSymbols.fUniform2fv(location, count, value);
+ AFTER_GL_CALL;
+ }
+
+ void fUniform2i(GLint location, GLint v0, GLint v1) {
+ BEFORE_GL_CALL;
+ mSymbols.fUniform2i(location, v0, v1);
+ AFTER_GL_CALL;
+ }
+
+ void fUniform2iv(GLint location, GLsizei count, const GLint* value) {
+ BEFORE_GL_CALL;
+ mSymbols.fUniform2iv(location, count, value);
+ AFTER_GL_CALL;
+ }
+
+ void fUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {
+ BEFORE_GL_CALL;
+ mSymbols.fUniform3f(location, v0, v1, v2);
+ AFTER_GL_CALL;
+ }
+
+ void fUniform3fv(GLint location, GLsizei count, const GLfloat* value) {
+ BEFORE_GL_CALL;
+ mSymbols.fUniform3fv(location, count, value);
+ AFTER_GL_CALL;
+ }
+
+ void fUniform3i(GLint location, GLint v0, GLint v1, GLint v2) {
+ BEFORE_GL_CALL;
+ mSymbols.fUniform3i(location, v0, v1, v2);
+ AFTER_GL_CALL;
+ }
+
+ void fUniform3iv(GLint location, GLsizei count, const GLint* value) {
+ BEFORE_GL_CALL;
+ mSymbols.fUniform3iv(location, count, value);
+ AFTER_GL_CALL;
+ }
+
+ void fUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
+ BEFORE_GL_CALL;
+ mSymbols.fUniform4f(location, v0, v1, v2, v3);
+ AFTER_GL_CALL;
+ }
+
+ void fUniform4fv(GLint location, GLsizei count, const GLfloat* value) {
+ BEFORE_GL_CALL;
+ mSymbols.fUniform4fv(location, count, value);
+ AFTER_GL_CALL;
+ }
+
+ void fUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) {
+ BEFORE_GL_CALL;
+ mSymbols.fUniform4i(location, v0, v1, v2, v3);
+ AFTER_GL_CALL;
+ }
+
+ void fUniform4iv(GLint location, GLsizei count, const GLint* value) {
+ BEFORE_GL_CALL;
+ mSymbols.fUniform4iv(location, count, value);
+ AFTER_GL_CALL;
+ }
+
+ void fUniformMatrix2fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
+ BEFORE_GL_CALL;
+ mSymbols.fUniformMatrix2fv(location, count, transpose, value);
+ AFTER_GL_CALL;
+ }
+
+ void fUniformMatrix2x3fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fUniformMatrix2x3fv);
+ mSymbols.fUniformMatrix2x3fv(location, count, transpose, value);
+ AFTER_GL_CALL;
+ }
+
+ void fUniformMatrix2x4fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fUniformMatrix2x4fv);
+ mSymbols.fUniformMatrix2x4fv(location, count, transpose, value);
+ AFTER_GL_CALL;
+ }
+
+ void fUniformMatrix3fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
+ BEFORE_GL_CALL;
+ mSymbols.fUniformMatrix3fv(location, count, transpose, value);
+ AFTER_GL_CALL;
+ }
+
+ void fUniformMatrix3x2fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fUniformMatrix3x2fv);
+ mSymbols.fUniformMatrix3x2fv(location, count, transpose, value);
+ AFTER_GL_CALL;
+ }
+
+ void fUniformMatrix3x4fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fUniformMatrix3x4fv);
+ mSymbols.fUniformMatrix3x4fv(location, count, transpose, value);
+ AFTER_GL_CALL;
+ }
+
+ void fUniformMatrix4fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
+ BEFORE_GL_CALL;
+ mSymbols.fUniformMatrix4fv(location, count, transpose, value);
+ AFTER_GL_CALL;
+ }
+
+ void fUniformMatrix4x2fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fUniformMatrix4x2fv);
+ mSymbols.fUniformMatrix4x2fv(location, count, transpose, value);
+ AFTER_GL_CALL;
+ }
+
+ void fUniformMatrix4x3fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fUniformMatrix4x3fv);
+ mSymbols.fUniformMatrix4x3fv(location, count, transpose, value);
+ AFTER_GL_CALL;
+ }
+
+ void fUseProgram(GLuint program) {
+ BEFORE_GL_CALL;
+ mSymbols.fUseProgram(program);
+ AFTER_GL_CALL;
+ }
+
+ void fValidateProgram(GLuint program) {
+ BEFORE_GL_CALL;
+ mSymbols.fValidateProgram(program);
+ AFTER_GL_CALL;
+ }
+
+ void fVertexAttribPointer(GLuint index, GLint size, GLenum type, realGLboolean normalized, GLsizei stride, const GLvoid* pointer) {
+ BEFORE_GL_CALL;
+ mSymbols.fVertexAttribPointer(index, size, type, normalized, stride, pointer);
+ AFTER_GL_CALL;
+ }
+
+ void fVertexAttrib1f(GLuint index, GLfloat x) {
+ BEFORE_GL_CALL;
+ mSymbols.fVertexAttrib1f(index, x);
+ AFTER_GL_CALL;
+ }
+
+ void fVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) {
+ BEFORE_GL_CALL;
+ mSymbols.fVertexAttrib2f(index, x, y);
+ AFTER_GL_CALL;
+ }
+
+ void fVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) {
+ BEFORE_GL_CALL;
+ mSymbols.fVertexAttrib3f(index, x, y, z);
+ AFTER_GL_CALL;
+ }
+
+ void fVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
+ BEFORE_GL_CALL;
+ mSymbols.fVertexAttrib4f(index, x, y, z, w);
+ AFTER_GL_CALL;
+ }
+
+ void fVertexAttrib1fv(GLuint index, const GLfloat* v) {
+ BEFORE_GL_CALL;
+ mSymbols.fVertexAttrib1fv(index, v);
+ AFTER_GL_CALL;
+ }
+
+ void fVertexAttrib2fv(GLuint index, const GLfloat* v) {
+ BEFORE_GL_CALL;
+ mSymbols.fVertexAttrib2fv(index, v);
+ AFTER_GL_CALL;
+ }
+
+ void fVertexAttrib3fv(GLuint index, const GLfloat* v) {
+ BEFORE_GL_CALL;
+ mSymbols.fVertexAttrib3fv(index, v);
+ AFTER_GL_CALL;
+ }
+
+ void fVertexAttrib4fv(GLuint index, const GLfloat* v) {
+ BEFORE_GL_CALL;
+ mSymbols.fVertexAttrib4fv(index, v);
+ AFTER_GL_CALL;
+ }
+
+ void fVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) {
+ BEFORE_GL_CALL;
+ mSymbols.fVertexPointer(size, type, stride, pointer);
+ AFTER_GL_CALL;
+ }
+
+ void fCompileShader(GLuint shader) {
+ BEFORE_GL_CALL;
+ mSymbols.fCompileShader(shader);
+ AFTER_GL_CALL;
+ }
+
+private:
+
+ friend class SharedSurface_IOSurface;
+
+ void raw_fCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+ {
+ BEFORE_GL_CALL;
+ mSymbols.fCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
+ AFTER_GL_CALL;
+ }
+
+ void raw_fCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+ {
+ BEFORE_GL_CALL;
+ mSymbols.fCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+ AFTER_GL_CALL;
+ }
+
+public:
+ void fGetShaderiv(GLuint shader, GLenum pname, GLint* param) {
+ BEFORE_GL_CALL;
+ mSymbols.fGetShaderiv(shader, pname, param);
+ AFTER_GL_CALL;
+ }
+
+ void fGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
+ BEFORE_GL_CALL;
+ mSymbols.fGetShaderInfoLog(shader, bufSize, length, infoLog);
+ AFTER_GL_CALL;
+ }
+
+private:
+ void raw_fGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
+ MOZ_ASSERT(IsGLES());
+
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGetShaderPrecisionFormat);
+ mSymbols.fGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
+ AFTER_GL_CALL;
+ }
+
+public:
+ void fGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
+ if (IsGLES()) {
+ raw_fGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
+ } else {
+ // Fall back to automatic values because almost all desktop hardware supports the OpenGL standard precisions.
+ GetShaderPrecisionFormatNonES2(shadertype, precisiontype, range, precision);
+ }
+ }
+
+ void fGetShaderSource(GLint obj, GLsizei maxLength, GLsizei* length, GLchar* source) {
+ BEFORE_GL_CALL;
+ mSymbols.fGetShaderSource(obj, maxLength, length, source);
+ AFTER_GL_CALL;
+ }
+
+ void fShaderSource(GLuint shader, GLsizei count, const GLchar* const* strings, const GLint* lengths) {
+ BEFORE_GL_CALL;
+ mSymbols.fShaderSource(shader, count, strings, lengths);
+ AFTER_GL_CALL;
+ }
+
+private:
+ friend class SharedSurface;
+
+ void raw_fBindFramebuffer(GLenum target, GLuint framebuffer) {
+ BEFORE_GL_CALL;
+ mSymbols.fBindFramebuffer(target, framebuffer);
+ AFTER_GL_CALL;
+ }
+
+public:
+ void fBindRenderbuffer(GLenum target, GLuint renderbuffer) {
+ BEFORE_GL_CALL;
+ mSymbols.fBindRenderbuffer(target, renderbuffer);
+ AFTER_GL_CALL;
+ }
+
+ GLenum fCheckFramebufferStatus(GLenum target) {
+ BEFORE_GL_CALL;
+ GLenum retval = mSymbols.fCheckFramebufferStatus(target);
+ AFTER_GL_CALL;
+ return retval;
+ }
+
+ void fFramebufferRenderbuffer(GLenum target, GLenum attachmentPoint, GLenum renderbufferTarget, GLuint renderbuffer) {
+ BEFORE_GL_CALL;
+ mSymbols.fFramebufferRenderbuffer(target, attachmentPoint, renderbufferTarget, renderbuffer);
+ AFTER_GL_CALL;
+ }
+
+ void fFramebufferTexture2D(GLenum target, GLenum attachmentPoint, GLenum textureTarget, GLuint texture, GLint level) {
+ BEFORE_GL_CALL;
+ mSymbols.fFramebufferTexture2D(target, attachmentPoint, textureTarget, texture, level);
+ AFTER_GL_CALL;
+ if (mNeedsCheckAfterAttachTextureToFb) {
+ fCheckFramebufferStatus(target);
+ }
+ }
+
+ void fFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fFramebufferTextureLayer);
+ mSymbols.fFramebufferTextureLayer(target, attachment, texture, level, layer);
+ AFTER_GL_CALL;
+ }
+
+ void fGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* value) {
+ BEFORE_GL_CALL;
+ mSymbols.fGetFramebufferAttachmentParameteriv(target, attachment, pname, value);
+ AFTER_GL_CALL;
+ }
+
+ void fGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* value) {
+ BEFORE_GL_CALL;
+ mSymbols.fGetRenderbufferParameteriv(target, pname, value);
+ AFTER_GL_CALL;
+ }
+
+ realGLboolean fIsFramebuffer (GLuint framebuffer) {
+ BEFORE_GL_CALL;
+ realGLboolean retval = mSymbols.fIsFramebuffer(framebuffer);
+ AFTER_GL_CALL;
+ return retval;
+ }
+
+public:
+ realGLboolean fIsRenderbuffer (GLuint renderbuffer) {
+ BEFORE_GL_CALL;
+ realGLboolean retval = mSymbols.fIsRenderbuffer(renderbuffer);
+ AFTER_GL_CALL;
+ return retval;
+ }
+
+ void fRenderbufferStorage(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height) {
+ BEFORE_GL_CALL;
+ mSymbols.fRenderbufferStorage(target, internalFormat, width, height);
+ AFTER_GL_CALL;
+ }
+
+private:
+ void raw_fDepthRange(GLclampf a, GLclampf b) {
+ MOZ_ASSERT(!IsGLES());
+
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fDepthRange);
+ mSymbols.fDepthRange(a, b);
+ AFTER_GL_CALL;
+ }
+
+ void raw_fDepthRangef(GLclampf a, GLclampf b) {
+ MOZ_ASSERT(IsGLES());
+
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fDepthRangef);
+ mSymbols.fDepthRangef(a, b);
+ AFTER_GL_CALL;
+ }
+
+ void raw_fClearDepth(GLclampf v) {
+ MOZ_ASSERT(!IsGLES());
+
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fClearDepth);
+ mSymbols.fClearDepth(v);
+ AFTER_GL_CALL;
+ }
+
+ void raw_fClearDepthf(GLclampf v) {
+ MOZ_ASSERT(IsGLES());
+
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fClearDepthf);
+ mSymbols.fClearDepthf(v);
+ AFTER_GL_CALL;
+ }
+
+public:
+ void fDepthRange(GLclampf a, GLclampf b) {
+ if (IsGLES()) {
+ raw_fDepthRangef(a, b);
+ } else {
+ raw_fDepthRange(a, b);
+ }
+ }
+
+ void fClearDepth(GLclampf v) {
+ if (IsGLES()) {
+ raw_fClearDepthf(v);
+ } else {
+ raw_fClearDepth(v);
+ }
+ }
+
+ void* fMapBuffer(GLenum target, GLenum access) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fMapBuffer);
+ void* ret = mSymbols.fMapBuffer(target, access);
+ AFTER_GL_CALL;
+ return ret;
+ }
+
+ realGLboolean fUnmapBuffer(GLenum target) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fUnmapBuffer);
+ realGLboolean ret = mSymbols.fUnmapBuffer(target);
+ AFTER_GL_CALL;
+ return ret;
+ }
+
+
+private:
+ GLuint raw_fCreateProgram() {
+ BEFORE_GL_CALL;
+ GLuint ret = mSymbols.fCreateProgram();
+ AFTER_GL_CALL;
+ return ret;
+ }
+
+ GLuint raw_fCreateShader(GLenum t) {
+ BEFORE_GL_CALL;
+ GLuint ret = mSymbols.fCreateShader(t);
+ AFTER_GL_CALL;
+ return ret;
+ }
+
+ void raw_fGenBuffers(GLsizei n, GLuint* names) {
+ BEFORE_GL_CALL;
+ mSymbols.fGenBuffers(n, names);
+ AFTER_GL_CALL;
+ }
+
+ void raw_fGenFramebuffers(GLsizei n, GLuint* names) {
+ BEFORE_GL_CALL;
+ mSymbols.fGenFramebuffers(n, names);
+ AFTER_GL_CALL;
+ }
+
+ void raw_fGenRenderbuffers(GLsizei n, GLuint* names) {
+ BEFORE_GL_CALL;
+ mSymbols.fGenRenderbuffers(n, names);
+ AFTER_GL_CALL;
+ }
+
+ void raw_fGenTextures(GLsizei n, GLuint* names) {
+ BEFORE_GL_CALL;
+ mSymbols.fGenTextures(n, names);
+ AFTER_GL_CALL;
+ }
+
+public:
+ GLuint fCreateProgram() {
+ GLuint ret = raw_fCreateProgram();
+ TRACKING_CONTEXT(CreatedProgram(this, ret));
+ return ret;
+ }
+
+ GLuint fCreateShader(GLenum t) {
+ GLuint ret = raw_fCreateShader(t);
+ TRACKING_CONTEXT(CreatedShader(this, ret));
+ return ret;
+ }
+
+ void fGenBuffers(GLsizei n, GLuint* names) {
+ raw_fGenBuffers(n, names);
+ TRACKING_CONTEXT(CreatedBuffers(this, n, names));
+ }
+
+ void fGenFramebuffers(GLsizei n, GLuint* names) {
+ raw_fGenFramebuffers(n, names);
+ TRACKING_CONTEXT(CreatedFramebuffers(this, n, names));
+ }
+
+ void fGenRenderbuffers(GLsizei n, GLuint* names) {
+ raw_fGenRenderbuffers(n, names);
+ TRACKING_CONTEXT(CreatedRenderbuffers(this, n, names));
+ }
+
+ void fGenTextures(GLsizei n, GLuint* names) {
+ raw_fGenTextures(n, names);
+ TRACKING_CONTEXT(CreatedTextures(this, n, names));
+ }
+
+private:
+ void raw_fDeleteProgram(GLuint program) {
+ BEFORE_GL_CALL;
+ mSymbols.fDeleteProgram(program);
+ AFTER_GL_CALL;
+ }
+
+ void raw_fDeleteShader(GLuint shader) {
+ BEFORE_GL_CALL;
+ mSymbols.fDeleteShader(shader);
+ AFTER_GL_CALL;
+ }
+
+ void raw_fDeleteBuffers(GLsizei n, const GLuint* names) {
+ BEFORE_GL_CALL;
+ mSymbols.fDeleteBuffers(n, names);
+ AFTER_GL_CALL;
+ }
+
+ void raw_fDeleteFramebuffers(GLsizei n, const GLuint* names) {
+ BEFORE_GL_CALL;
+ mSymbols.fDeleteFramebuffers(n, names);
+ AFTER_GL_CALL;
+ }
+
+ void raw_fDeleteRenderbuffers(GLsizei n, const GLuint* names) {
+ BEFORE_GL_CALL;
+ mSymbols.fDeleteRenderbuffers(n, names);
+ AFTER_GL_CALL;
+ }
+
+ void raw_fDeleteTextures(GLsizei n, const GLuint* names) {
+ BEFORE_GL_CALL;
+ mSymbols.fDeleteTextures(n, names);
+ AFTER_GL_CALL;
+ }
+
+public:
+
+ void fDeleteProgram(GLuint program) {
+ raw_fDeleteProgram(program);
+ TRACKING_CONTEXT(DeletedProgram(this, program));
+ }
+
+ void fDeleteShader(GLuint shader) {
+ raw_fDeleteShader(shader);
+ TRACKING_CONTEXT(DeletedShader(this, shader));
+ }
+
+ void fDeleteBuffers(GLsizei n, const GLuint* names) {
+ raw_fDeleteBuffers(n, names);
+ TRACKING_CONTEXT(DeletedBuffers(this, n, names));
+ }
+
+ void fDeleteFramebuffers(GLsizei n, const GLuint* names);
+
+ void fDeleteRenderbuffers(GLsizei n, const GLuint* names) {
+ raw_fDeleteRenderbuffers(n, names);
+ TRACKING_CONTEXT(DeletedRenderbuffers(this, n, names));
+ }
+
+ void fDeleteTextures(GLsizei n, const GLuint* names) {
+ raw_fDeleteTextures(n, names);
+ TRACKING_CONTEXT(DeletedTextures(this, n, names));
+ }
+
+ GLenum fGetGraphicsResetStatus() {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGetGraphicsResetStatus);
+ GLenum ret = mSymbols.fGetGraphicsResetStatus();
+ AFTER_GL_CALL;
+ return ret;
+ }
+
+
+// -----------------------------------------------------------------------------
+// Extension ARB_sync (GL)
+public:
+ GLsync fFenceSync(GLenum condition, GLbitfield flags) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fFenceSync);
+ GLsync ret = mSymbols.fFenceSync(condition, flags);
+ AFTER_GL_CALL;
+ return ret;
+ }
+
+ realGLboolean fIsSync(GLsync sync) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fIsSync);
+ realGLboolean ret = mSymbols.fIsSync(sync);
+ AFTER_GL_CALL;
+ return ret;
+ }
+
+ void fDeleteSync(GLsync sync) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fDeleteSync);
+ mSymbols.fDeleteSync(sync);
+ AFTER_GL_CALL;
+ }
+
+ GLenum fClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fClientWaitSync);
+ GLenum ret = mSymbols.fClientWaitSync(sync, flags, timeout);
+ AFTER_GL_CALL;
+ return ret;
+ }
+
+ void fWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fWaitSync);
+ mSymbols.fWaitSync(sync, flags, timeout);
+ AFTER_GL_CALL;
+ }
+
+ void fGetInteger64v(GLenum pname, GLint64* params) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGetInteger64v);
+ mSymbols.fGetInteger64v(pname, params);
+ AFTER_GL_CALL;
+ }
+
+ void fGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGetSynciv);
+ mSymbols.fGetSynciv(sync, pname, bufSize, length, values);
+ AFTER_GL_CALL;
+ }
+
+
+// -----------------------------------------------------------------------------
+// Extension OES_EGL_image (GLES)
+public:
+ void fEGLImageTargetTexture2D(GLenum target, GLeglImage image) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fEGLImageTargetTexture2D);
+ mSymbols.fEGLImageTargetTexture2D(target, image);
+ AFTER_GL_CALL;
+ mHeavyGLCallsSinceLastFlush = true;
+ }
+
+ void fEGLImageTargetRenderbufferStorage(GLenum target, GLeglImage image)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fEGLImageTargetRenderbufferStorage);
+ mSymbols.fEGLImageTargetRenderbufferStorage(target, image);
+ AFTER_GL_CALL;
+ }
+
+
+// -----------------------------------------------------------------------------
+// Package XXX_bind_buffer_offset
+public:
+ void fBindBufferOffset(GLenum target, GLuint index, GLuint buffer, GLintptr offset)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fBindBufferOffset);
+ mSymbols.fBindBufferOffset(target, index, buffer, offset);
+ AFTER_GL_CALL;
+ }
+
+
+// -----------------------------------------------------------------------------
+// Package XXX_draw_buffers
+public:
+ void fDrawBuffers(GLsizei n, const GLenum* bufs) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fDrawBuffers);
+ mSymbols.fDrawBuffers(n, bufs);
+ AFTER_GL_CALL;
+ }
+
+
+// -----------------------------------------------------------------------------
+// Package XXX_draw_instanced
+public:
+ void fDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
+ {
+ BeforeGLDrawCall();
+ raw_fDrawArraysInstanced(mode, first, count, primcount);
+ AfterGLDrawCall();
+ }
+
+ void fDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei primcount)
+ {
+ BeforeGLDrawCall();
+ raw_fDrawElementsInstanced(mode, count, type, indices, primcount);
+ AfterGLDrawCall();
+ }
+
+private:
+ void raw_fDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fDrawArraysInstanced);
+ mSymbols.fDrawArraysInstanced(mode, first, count, primcount);
+ AFTER_GL_CALL;
+ }
+
+ void raw_fDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei primcount)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fDrawElementsInstanced);
+ mSymbols.fDrawElementsInstanced(mode, count, type, indices, primcount);
+ AFTER_GL_CALL;
+ }
+
+// -----------------------------------------------------------------------------
+// Feature draw_range_elements
+public:
+ void fDrawRangeElements(GLenum mode, GLuint start, GLuint end,
+ GLsizei count, GLenum type, const GLvoid* indices)
+ {
+ BeforeGLDrawCall();
+ raw_fDrawRangeElements(mode, start, end, count, type, indices);
+ AfterGLDrawCall();
+ }
+
+private:
+ void raw_fDrawRangeElements(GLenum mode, GLuint start, GLuint end,
+ GLsizei count, GLenum type, const GLvoid* indices)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fDrawRangeElements);
+ mSymbols.fDrawRangeElements(mode, start, end, count, type, indices);
+ AFTER_GL_CALL;
+ }
+
+// -----------------------------------------------------------------------------
+// Package XXX_framebuffer_blit
+public:
+ // Draw/Read
+ void fBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
+ BeforeGLDrawCall();
+ BeforeGLReadCall();
+ raw_fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+ AfterGLReadCall();
+ AfterGLDrawCall();
+ }
+
+
+private:
+ void raw_fBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fBlitFramebuffer);
+ mSymbols.fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+ AFTER_GL_CALL;
+ }
+
+
+// -----------------------------------------------------------------------------
+// Package XXX_framebuffer_multisample
+public:
+ void fRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fRenderbufferStorageMultisample);
+ mSymbols.fRenderbufferStorageMultisample(target, samples, internalFormat, width, height);
+ AFTER_GL_CALL;
+ }
+
+// -----------------------------------------------------------------------------
+// GL 3.0, GL ES 3.0 & EXT_gpu_shader4
+public:
+ void fGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params)
+ {
+ ASSERT_SYMBOL_PRESENT(fGetVertexAttribIiv);
+ BEFORE_GL_CALL;
+ mSymbols.fGetVertexAttribIiv(index, pname, params);
+ AFTER_GL_CALL;
+ }
+
+ void fGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params)
+ {
+ ASSERT_SYMBOL_PRESENT(fGetVertexAttribIuiv);
+ BEFORE_GL_CALL;
+ mSymbols.fGetVertexAttribIuiv(index, pname, params);
+ AFTER_GL_CALL;
+ }
+
+ void fVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fVertexAttribI4i);
+ mSymbols.fVertexAttribI4i(index, x, y, z, w);
+ AFTER_GL_CALL;
+ }
+
+ void fVertexAttribI4iv(GLuint index, const GLint* v)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fVertexAttribI4iv);
+ mSymbols.fVertexAttribI4iv(index, v);
+ AFTER_GL_CALL;
+ }
+
+ void fVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fVertexAttribI4ui);
+ mSymbols.fVertexAttribI4ui(index, x, y, z, w);
+ AFTER_GL_CALL;
+ }
+
+ void fVertexAttribI4uiv(GLuint index, const GLuint* v)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fVertexAttribI4uiv);
+ mSymbols.fVertexAttribI4uiv(index, v);
+ AFTER_GL_CALL;
+ }
+
+ void fVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* offset)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fVertexAttribIPointer);
+ mSymbols.fVertexAttribIPointer(index, size, type, stride, offset);
+ AFTER_GL_CALL;
+ }
+
+ void fUniform1ui(GLint location, GLuint v0) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fUniform1ui);
+ mSymbols.fUniform1ui(location, v0);
+ AFTER_GL_CALL;
+ }
+
+ void fUniform2ui(GLint location, GLuint v0, GLuint v1) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fUniform2ui);
+ mSymbols.fUniform2ui(location, v0, v1);
+ AFTER_GL_CALL;
+ }
+
+ void fUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fUniform3ui);
+ mSymbols.fUniform3ui(location, v0, v1, v2);
+ AFTER_GL_CALL;
+ }
+
+ void fUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fUniform4ui);
+ mSymbols.fUniform4ui(location, v0, v1, v2, v3);
+ AFTER_GL_CALL;
+ }
+
+ void fUniform1uiv(GLint location, GLsizei count, const GLuint* value) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fUniform1uiv);
+ mSymbols.fUniform1uiv(location, count, value);
+ AFTER_GL_CALL;
+ }
+
+ void fUniform2uiv(GLint location, GLsizei count, const GLuint* value) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fUniform2uiv);
+ mSymbols.fUniform2uiv(location, count, value);
+ AFTER_GL_CALL;
+ }
+
+ void fUniform3uiv(GLint location, GLsizei count, const GLuint* value) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fUniform3uiv);
+ mSymbols.fUniform3uiv(location, count, value);
+ AFTER_GL_CALL;
+ }
+
+ void fUniform4uiv(GLint location, GLsizei count, const GLuint* value) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fUniform4uiv);
+ mSymbols.fUniform4uiv(location, count, value);
+ AFTER_GL_CALL;
+ }
+
+ GLint fGetFragDataLocation(GLuint program, const GLchar* name)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGetFragDataLocation);
+ GLint result = mSymbols.fGetFragDataLocation(program, name);
+ AFTER_GL_CALL;
+ return result;
+ }
+
+
+// -----------------------------------------------------------------------------
+// Package XXX_instanced_arrays
+public:
+ void fVertexAttribDivisor(GLuint index, GLuint divisor)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fVertexAttribDivisor);
+ mSymbols.fVertexAttribDivisor(index, divisor);
+ AFTER_GL_CALL;
+ }
+
+// -----------------------------------------------------------------------------
+// Feature internalformat_query
+public:
+ void fGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGetInternalformativ);
+ mSymbols.fGetInternalformativ(target, internalformat, pname, bufSize, params);
+ AFTER_GL_CALL;
+ }
+
+
+// -----------------------------------------------------------------------------
+// Package XXX_query_counter
+/**
+ * XXX_query_counter:
+ * - depends on XXX_query_objects
+ * - provide all followed entry points
+ * - provide GL_TIMESTAMP
+ */
+public:
+ void fQueryCounter(GLuint id, GLenum target) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fQueryCounter);
+ mSymbols.fQueryCounter(id, target);
+ AFTER_GL_CALL;
+ }
+
+
+// -----------------------------------------------------------------------------
+// Package XXX_query_objects
+/**
+ * XXX_query_objects:
+ * - provide all followed entry points
+ *
+ * XXX_occlusion_query2:
+ * - depends on XXX_query_objects
+ * - provide ANY_SAMPLES_PASSED
+ *
+ * XXX_occlusion_query_boolean:
+ * - depends on XXX_occlusion_query2
+ * - provide ANY_SAMPLES_PASSED_CONSERVATIVE
+ */
+public:
+ void fDeleteQueries(GLsizei n, const GLuint* names) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fDeleteQueries);
+ mSymbols.fDeleteQueries(n, names);
+ AFTER_GL_CALL;
+ TRACKING_CONTEXT(DeletedQueries(this, n, names));
+ }
+
+ void fGenQueries(GLsizei n, GLuint* names) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGenQueries);
+ mSymbols.fGenQueries(n, names);
+ AFTER_GL_CALL;
+ TRACKING_CONTEXT(CreatedQueries(this, n, names));
+ }
+
+ void fGetQueryiv(GLenum target, GLenum pname, GLint* params) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGetQueryiv);
+ mSymbols.fGetQueryiv(target, pname, params);
+ AFTER_GL_CALL;
+ }
+
+ void fGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGetQueryObjectuiv);
+ mSymbols.fGetQueryObjectuiv(id, pname, params);
+ AFTER_GL_CALL;
+ }
+
+ realGLboolean fIsQuery(GLuint query) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fIsQuery);
+ realGLboolean retval = mSymbols.fIsQuery(query);
+ AFTER_GL_CALL;
+ return retval;
+ }
+
+// -----------------------------------------------------------------------------
+// Package XXX_get_query_object_i64v
+/**
+ * XXX_get_query_object_i64v:
+ * - depends on XXX_query_objects
+ * - provide the followed entry point
+ */
+public:
+ void fGetQueryObjecti64v(GLuint id, GLenum pname, GLint64* params) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGetQueryObjecti64v);
+ mSymbols.fGetQueryObjecti64v(id, pname, params);
+ AFTER_GL_CALL;
+ }
+
+ void fGetQueryObjectui64v(GLuint id, GLenum pname, GLuint64* params) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGetQueryObjectui64v);
+ mSymbols.fGetQueryObjectui64v(id, pname, params);
+ AFTER_GL_CALL;
+ }
+
+
+// -----------------------------------------------------------------------------
+// Package XXX_get_query_object_iv
+/**
+ * XXX_get_query_object_iv:
+ * - depends on XXX_query_objects
+ * - provide the followed entry point
+ *
+ * XXX_occlusion_query:
+ * - depends on XXX_get_query_object_iv
+ * - provide LOCAL_GL_SAMPLES_PASSED
+ */
+public:
+ void fGetQueryObjectiv(GLuint id, GLenum pname, GLint* params) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGetQueryObjectiv);
+ mSymbols.fGetQueryObjectiv(id, pname, params);
+ AFTER_GL_CALL;
+ }
+
+
+// -----------------------------------------------------------------------------
+// GL 4.0, GL ES 3.0, ARB_transform_feedback2, NV_transform_feedback2
+public:
+ void fBindBufferBase(GLenum target, GLuint index, GLuint buffer)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fBindBufferBase);
+ mSymbols.fBindBufferBase(target, index, buffer);
+ AFTER_GL_CALL;
+ }
+
+ void fBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fBindBufferRange);
+ mSymbols.fBindBufferRange(target, index, buffer, offset, size);
+ AFTER_GL_CALL;
+ }
+
+ void fGenTransformFeedbacks(GLsizei n, GLuint* ids)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGenTransformFeedbacks);
+ mSymbols.fGenTransformFeedbacks(n, ids);
+ AFTER_GL_CALL;
+ }
+
+ void fDeleteTransformFeedbacks(GLsizei n, const GLuint* ids)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fDeleteTransformFeedbacks);
+ mSymbols.fDeleteTransformFeedbacks(n, ids);
+ AFTER_GL_CALL;
+ }
+
+ realGLboolean fIsTransformFeedback(GLuint id)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fIsTransformFeedback);
+ realGLboolean result = mSymbols.fIsTransformFeedback(id);
+ AFTER_GL_CALL;
+ return result;
+ }
+
+ void fBindTransformFeedback(GLenum target, GLuint id)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fBindTransformFeedback);
+ mSymbols.fBindTransformFeedback(target, id);
+ AFTER_GL_CALL;
+ }
+
+ void fBeginTransformFeedback(GLenum primitiveMode)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fBeginTransformFeedback);
+ mSymbols.fBeginTransformFeedback(primitiveMode);
+ AFTER_GL_CALL;
+ }
+
+ void fEndTransformFeedback()
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fEndTransformFeedback);
+ mSymbols.fEndTransformFeedback();
+ AFTER_GL_CALL;
+ }
+
+ void fTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fTransformFeedbackVaryings);
+ mSymbols.fTransformFeedbackVaryings(program, count, varyings, bufferMode);
+ AFTER_GL_CALL;
+ }
+
+ void fGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGetTransformFeedbackVarying);
+ mSymbols.fGetTransformFeedbackVarying(program, index, bufSize, length, size, type, name);
+ AFTER_GL_CALL;
+ }
+
+ void fPauseTransformFeedback()
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fPauseTransformFeedback);
+ mSymbols.fPauseTransformFeedback();
+ AFTER_GL_CALL;
+ }
+
+ void fResumeTransformFeedback()
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fResumeTransformFeedback);
+ mSymbols.fResumeTransformFeedback();
+ AFTER_GL_CALL;
+ }
+
+ void fGetIntegeri_v(GLenum param, GLuint index, GLint* values)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGetIntegeri_v);
+ mSymbols.fGetIntegeri_v(param, index, values);
+ AFTER_GL_CALL;
+ }
+
+ void fGetInteger64i_v(GLenum target, GLuint index, GLint64* data) {
+ ASSERT_SYMBOL_PRESENT(fGetInteger64i_v);
+ BEFORE_GL_CALL;
+ mSymbols.fGetInteger64i_v(target, index, data);
+ AFTER_GL_CALL;
+ }
+
+// -----------------------------------------------------------------------------
+// Package XXX_vertex_array_object
+public:
+ void fBindVertexArray(GLuint array)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fBindVertexArray);
+ mSymbols.fBindVertexArray(array);
+ AFTER_GL_CALL;
+ }
+
+ void fDeleteVertexArrays(GLsizei n, const GLuint* arrays)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fDeleteVertexArrays);
+ mSymbols.fDeleteVertexArrays(n, arrays);
+ AFTER_GL_CALL;
+ }
+
+ void fGenVertexArrays(GLsizei n, GLuint* arrays)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGenVertexArrays);
+ mSymbols.fGenVertexArrays(n, arrays);
+ AFTER_GL_CALL;
+ }
+
+ realGLboolean fIsVertexArray(GLuint array)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fIsVertexArray);
+ realGLboolean ret = mSymbols.fIsVertexArray(array);
+ AFTER_GL_CALL;
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// Extension NV_fence
+public:
+ void fGenFences(GLsizei n, GLuint* fences)
+ {
+ ASSERT_SYMBOL_PRESENT(fGenFences);
+ BEFORE_GL_CALL;
+ mSymbols.fGenFences(n, fences);
+ AFTER_GL_CALL;
+ }
+
+ void fDeleteFences(GLsizei n, const GLuint* fences)
+ {
+ ASSERT_SYMBOL_PRESENT(fDeleteFences);
+ BEFORE_GL_CALL;
+ mSymbols.fDeleteFences(n, fences);
+ AFTER_GL_CALL;
+ }
+
+ void fSetFence(GLuint fence, GLenum condition)
+ {
+ ASSERT_SYMBOL_PRESENT(fSetFence);
+ BEFORE_GL_CALL;
+ mSymbols.fSetFence(fence, condition);
+ AFTER_GL_CALL;
+ }
+
+ realGLboolean fTestFence(GLuint fence)
+ {
+ ASSERT_SYMBOL_PRESENT(fTestFence);
+ BEFORE_GL_CALL;
+ realGLboolean ret = mSymbols.fTestFence(fence);
+ AFTER_GL_CALL;
+ return ret;
+ }
+
+ void fFinishFence(GLuint fence)
+ {
+ ASSERT_SYMBOL_PRESENT(fFinishFence);
+ BEFORE_GL_CALL;
+ mSymbols.fFinishFence(fence);
+ AFTER_GL_CALL;
+ }
+
+ realGLboolean fIsFence(GLuint fence)
+ {
+ ASSERT_SYMBOL_PRESENT(fIsFence);
+ BEFORE_GL_CALL;
+ realGLboolean ret = mSymbols.fIsFence(fence);
+ AFTER_GL_CALL;
+ return ret;
+ }
+
+ void fGetFenceiv(GLuint fence, GLenum pname, GLint* params)
+ {
+ ASSERT_SYMBOL_PRESENT(fGetFenceiv);
+ BEFORE_GL_CALL;
+ mSymbols.fGetFenceiv(fence, pname, params);
+ AFTER_GL_CALL;
+ }
+
+// -----------------------------------------------------------------------------
+// Extension NV_texture_barrier
+public:
+ void fTextureBarrier()
+ {
+ ASSERT_SYMBOL_PRESENT(fTextureBarrier);
+ BEFORE_GL_CALL;
+ mSymbols.fTextureBarrier();
+ AFTER_GL_CALL;
+ }
+
+// Core GL & Extension ARB_copy_buffer
+public:
+ void fCopyBufferSubData(GLenum readtarget, GLenum writetarget,
+ GLintptr readoffset, GLintptr writeoffset,
+ GLsizeiptr size)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fCopyBufferSubData);
+ mSymbols.fCopyBufferSubData(readtarget, writetarget, readoffset, writeoffset, size);
+ AFTER_GL_CALL;
+ }
+
+
+// -----------------------------------------------------------------------------
+// Core GL & Extension ARB_map_buffer_range
+public:
+ void* fMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
+ GLbitfield access)
+ {
+ ASSERT_SYMBOL_PRESENT(fMapBufferRange);
+ BEFORE_GL_CALL;
+ void* data = mSymbols.fMapBufferRange(target, offset, length, access);
+ AFTER_GL_CALL;
+ return data;
+ }
+
+ void fFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) {
+ ASSERT_SYMBOL_PRESENT(fFlushMappedBufferRange);
+ BEFORE_GL_CALL;
+ mSymbols.fFlushMappedBufferRange(target, offset, length);
+ AFTER_GL_CALL;
+ }
+
+
+// -----------------------------------------------------------------------------
+// Core GL & Extension ARB_sampler_objects
+public:
+ void fGenSamplers(GLsizei count, GLuint* samplers)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGenSamplers);
+ mSymbols.fGenSamplers(count, samplers);
+ AFTER_GL_CALL;
+ }
+
+ void fDeleteSamplers(GLsizei count, const GLuint* samplers)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fDeleteSamplers);
+ mSymbols.fDeleteSamplers(count, samplers);
+ AFTER_GL_CALL;
+ }
+
+ realGLboolean fIsSampler(GLuint sampler)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fIsSampler);
+ realGLboolean result = mSymbols.fIsSampler(sampler);
+ AFTER_GL_CALL;
+ return result;
+ }
+
+ void fBindSampler(GLuint unit, GLuint sampler)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fBindSampler);
+ mSymbols.fBindSampler(unit, sampler);
+ AFTER_GL_CALL;
+ }
+
+ void fSamplerParameteri(GLuint sampler, GLenum pname, GLint param)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fSamplerParameteri);
+ mSymbols.fSamplerParameteri(sampler, pname, param);
+ AFTER_GL_CALL;
+ }
+
+ void fSamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fSamplerParameteriv);
+ mSymbols.fSamplerParameteriv(sampler, pname, param);
+ AFTER_GL_CALL;
+ }
+
+ void fSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fSamplerParameterf);
+ mSymbols.fSamplerParameterf(sampler, pname, param);
+ AFTER_GL_CALL;
+ }
+
+ void fSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fSamplerParameterfv);
+ mSymbols.fSamplerParameterfv(sampler, pname, param);
+ AFTER_GL_CALL;
+ }
+
+ void fGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGetSamplerParameteriv);
+ mSymbols.fGetSamplerParameteriv(sampler, pname, params);
+ AFTER_GL_CALL;
+ }
+
+ void fGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGetSamplerParameterfv);
+ mSymbols.fGetSamplerParameterfv(sampler, pname, params);
+ AFTER_GL_CALL;
+ }
+
+
+// -----------------------------------------------------------------------------
+// Core GL & Extension ARB_uniform_buffer_object
+public:
+ void fGetUniformIndices(GLuint program, GLsizei uniformCount,
+ const GLchar* const* uniformNames, GLuint* uniformIndices)
+ {
+ ASSERT_SYMBOL_PRESENT(fGetUniformIndices);
+ BEFORE_GL_CALL;
+ mSymbols.fGetUniformIndices(program, uniformCount, uniformNames, uniformIndices);
+ AFTER_GL_CALL;
+ }
+
+ void fGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices,
+ GLenum pname, GLint* params)
+ {
+ ASSERT_SYMBOL_PRESENT(fGetActiveUniformsiv);
+ BEFORE_GL_CALL;
+ mSymbols.fGetActiveUniformsiv(program, uniformCount, uniformIndices, pname, params);
+ AFTER_GL_CALL;
+ }
+
+ GLuint fGetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName) {
+ ASSERT_SYMBOL_PRESENT(fGetUniformBlockIndex);
+ BEFORE_GL_CALL;
+ GLuint result = mSymbols.fGetUniformBlockIndex(program, uniformBlockName);
+ AFTER_GL_CALL;
+ return result;
+ }
+
+ void fGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex,
+ GLenum pname, GLint* params)
+ {
+ ASSERT_SYMBOL_PRESENT(fGetActiveUniformBlockiv);
+ BEFORE_GL_CALL;
+ mSymbols.fGetActiveUniformBlockiv(program, uniformBlockIndex, pname, params);
+ AFTER_GL_CALL;
+ }
+
+ void fGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize,
+ GLsizei* length, GLchar* uniformBlockName)
+ {
+ ASSERT_SYMBOL_PRESENT(fGetActiveUniformBlockName);
+ BEFORE_GL_CALL;
+ mSymbols.fGetActiveUniformBlockName(program, uniformBlockIndex, bufSize, length, uniformBlockName);
+ AFTER_GL_CALL;
+ }
+
+ void fUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) {
+ ASSERT_SYMBOL_PRESENT(fUniformBlockBinding);
+ BEFORE_GL_CALL;
+ mSymbols.fUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding);
+ AFTER_GL_CALL;
+ }
+
+// -----------------------------------------------------------------------------
+// Core GL 4.2, GL ES 3.0 & Extension ARB_texture_storage/EXT_texture_storage
+ void fTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fTexStorage2D);
+ mSymbols.fTexStorage2D(target, levels, internalformat, width, height);
+ AFTER_GL_CALL;
+ }
+
+ void fTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fTexStorage3D);
+ mSymbols.fTexStorage3D(target, levels, internalformat, width, height, depth);
+ AFTER_GL_CALL;
+ }
+
+// -----------------------------------------------------------------------------
+// 3D Textures
+ void fTexImage3D(GLenum target, GLint level,
+ GLint internalFormat,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLenum format, GLenum type,
+ const GLvoid * data)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fTexImage3D);
+ mSymbols.fTexImage3D(target, level, internalFormat,
+ width, height, depth,
+ border, format, type,
+ data);
+ AFTER_GL_CALL;
+ }
+
+ void fTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, const GLvoid* pixels)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fTexSubImage3D);
+ mSymbols.fTexSubImage3D(target, level, xoffset, yoffset, zoffset,
+ width, height, depth, format, type,
+ pixels);
+ AFTER_GL_CALL;
+ }
+
+ void fCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset,
+ GLint yoffset, GLint zoffset, GLint x,
+ GLint y, GLsizei width, GLsizei height)
+ {
+ BeforeGLReadCall();
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fCopyTexSubImage3D);
+ mSymbols.fCopyTexSubImage3D(target, level, xoffset, yoffset, zoffset,
+ x, y, width, height);
+ AFTER_GL_CALL;
+ AfterGLReadCall();
+ }
+
+ void fCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLsizei imageSize, const GLvoid* data)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fCompressedTexImage3D);
+ mSymbols.fCompressedTexImage3D(target, level, internalformat,
+ width, height, depth,
+ border, imageSize, data);
+ AFTER_GL_CALL;
+ }
+
+ void fCompressedTexSubImage3D(GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLsizei imageSize, const GLvoid* data)
+ {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fCompressedTexSubImage3D);
+ mSymbols.fCompressedTexSubImage3D(target, level,
+ xoffset, yoffset, zoffset,
+ width, height, depth,
+ format, imageSize, data);
+ AFTER_GL_CALL;
+ }
+
+// -----------------------------------------------------------------------------
+// get_string_indexed
+
+ const GLubyte* fGetStringi(GLenum name, GLuint index) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fGetStringi);
+ const GLubyte* ret = mSymbols.fGetStringi(name, index);
+ AFTER_GL_CALL;
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// APPLE_framebuffer_multisample
+
+ void fResolveMultisampleFramebufferAPPLE() {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fResolveMultisampleFramebufferAPPLE);
+ mSymbols.fResolveMultisampleFramebufferAPPLE();
+ AFTER_GL_CALL;
+ }
+
+// -----------------------------------------------------------------------------
+// prim_restart
+
+ void fPrimitiveRestartIndex(GLuint index) {
+ BEFORE_GL_CALL;
+ ASSERT_SYMBOL_PRESENT(fPrimitiveRestartIndex);
+ mSymbols.fPrimitiveRestartIndex(index);
+ AFTER_GL_CALL;
+ }
+
+// -----------------------------------------------------------------------------
+// Constructor
+protected:
+ explicit GLContext(CreateContextFlags flags, const SurfaceCaps& caps,
+ GLContext* sharedContext = nullptr,
+ bool isOffscreen = false);
+
+
+// -----------------------------------------------------------------------------
+// Destructor
+public:
+ virtual ~GLContext();
+
+ // Mark this context as destroyed. This will nullptr out all
+ // the GL function pointers!
+ void MarkDestroyed();
+
+// -----------------------------------------------------------------------------
+// Everything that isn't standard GL APIs
+protected:
+ typedef gfx::SurfaceFormat SurfaceFormat;
+
+ virtual bool MakeCurrentImpl(bool aForce) = 0;
+
+public:
+#ifdef MOZ_GL_DEBUG
+ static void StaticInit() {
+ PR_NewThreadPrivateIndex(&sCurrentGLContextTLS, nullptr);
+ }
+#endif
+
+ bool MakeCurrent(bool aForce = false) {
+ if (IsDestroyed()) {
+ return false;
+ }
+#ifdef MOZ_GL_DEBUG
+ PR_SetThreadPrivate(sCurrentGLContextTLS, this);
+
+ // XXX this assertion is disabled because it's triggering on Mac;
+ // we need to figure out why and reenable it.
+#if 0
+ // IsOwningThreadCurrent is a bit of a misnomer;
+ // the "owning thread" is the creation thread,
+ // and the only thread that can own this. We don't
+ // support contexts used on multiple threads.
+ NS_ASSERTION(IsOwningThreadCurrent(),
+ "MakeCurrent() called on different thread than this context was created on!");
+#endif
+#endif
+ return MakeCurrentImpl(aForce);
+ }
+
+ virtual bool Init() = 0;
+
+ virtual bool SetupLookupFunction() = 0;
+
+ virtual void ReleaseSurface() {}
+
+ bool IsDestroyed() {
+ // MarkDestroyed will mark all these as null.
+ return mSymbols.fUseProgram == nullptr;
+ }
+
+ GLContext* GetSharedContext() { return mSharedContext; }
+
+ /**
+ * Returns true if the thread on which this context was created is the currently
+ * executing thread.
+ */
+ bool IsOwningThreadCurrent();
+
+ static void PlatformStartup();
+
+public:
+ /**
+ * If this context wraps a double-buffered target, swap the back
+ * and front buffers. It should be assumed that after a swap, the
+ * contents of the new back buffer are undefined.
+ */
+ virtual bool SwapBuffers() { return false; }
+
+ /**
+ * Defines a two-dimensional texture image for context target surface
+ */
+ virtual bool BindTexImage() { return false; }
+ /*
+ * Releases a color buffer that is being used as a texture
+ */
+ virtual bool ReleaseTexImage() { return false; }
+
+ // Before reads from offscreen texture
+ void GuaranteeResolve();
+
+ /*
+ * Resize the current offscreen buffer. Returns true on success.
+ * If it returns false, the context should be treated as unusable
+ * and should be recreated. After the resize, the viewport is not
+ * changed; glViewport should be called as appropriate.
+ *
+ * Only valid if IsOffscreen() returns true.
+ */
+ bool ResizeOffscreen(const gfx::IntSize& size) {
+ return ResizeScreenBuffer(size);
+ }
+
+ /*
+ * Return size of this offscreen context.
+ *
+ * Only valid if IsOffscreen() returns true.
+ */
+ const gfx::IntSize& OffscreenSize() const;
+
+ void BindFB(GLuint fb) {
+ fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, fb);
+ MOZ_ASSERT(!fb || fIsFramebuffer(fb));
+ }
+
+ void BindDrawFB(GLuint fb) {
+ fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, fb);
+ }
+
+ void BindReadFB(GLuint fb) {
+ fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, fb);
+ }
+
+ GLuint GetDrawFB();
+
+ GLuint GetReadFB();
+
+ GLuint GetFB();
+
+private:
+ void GetShaderPrecisionFormatNonES2(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
+ switch (precisiontype) {
+ case LOCAL_GL_LOW_FLOAT:
+ case LOCAL_GL_MEDIUM_FLOAT:
+ case LOCAL_GL_HIGH_FLOAT:
+ // Assume IEEE 754 precision
+ range[0] = 127;
+ range[1] = 127;
+ *precision = 23;
+ break;
+ case LOCAL_GL_LOW_INT:
+ case LOCAL_GL_MEDIUM_INT:
+ case LOCAL_GL_HIGH_INT:
+ // Some (most) hardware only supports single-precision floating-point numbers,
+ // which can accurately represent integers up to +/-16777216
+ range[0] = 24;
+ range[1] = 24;
+ *precision = 0;
+ break;
+ }
+ }
+
+public:
+
+ void ForceDirtyScreen();
+ void CleanDirtyScreen();
+
+ virtual GLenum GetPreferredARGB32Format() const { return LOCAL_GL_RGBA; }
+
+ virtual GLenum GetPreferredEGLImageTextureTarget() const {
+ return IsExtensionSupported(OES_EGL_image_external) ?
+ LOCAL_GL_TEXTURE_EXTERNAL : LOCAL_GL_TEXTURE_2D;
+ }
+
+ virtual bool RenewSurface(nsIWidget* aWidget) { return false; }
+
+ // Shared code for GL extensions and GLX extensions.
+ static bool ListHasExtension(const GLubyte* extensions,
+ const char* extension);
+
+ GLint GetMaxTextureImageSize() { return mMaxTextureImageSize; }
+
+public:
+ std::map<GLuint, SharedSurface*> mFBOMapping;
+
+ enum {
+ DebugFlagEnabled = 1 << 0,
+ DebugFlagTrace = 1 << 1,
+ DebugFlagAbortOnError = 1 << 2
+ };
+
+ const uint8_t mDebugFlags;
+
+protected:
+ RefPtr<GLContext> mSharedContext;
+
+ // The thread id which this context was created.
+ PlatformThreadId mOwningThreadId;
+
+ GLContextSymbols mSymbols;
+
+#ifdef MOZ_GL_DEBUG
+ // Non-zero debug flags will check that we don't send call
+ // to a GLContext that isn't current on the current
+ // thread.
+ // Store the current context when binding to thread local
+ // storage to support debug flags on an arbitrary thread.
+ static unsigned sCurrentGLContextTLS;
+#endif
+
+ UniquePtr<GLBlitHelper> mBlitHelper;
+ UniquePtr<GLReadTexImageHelper> mReadTexImageHelper;
+
+public:
+ GLBlitHelper* BlitHelper();
+ GLBlitTextureImageHelper* BlitTextureImageHelper();
+ GLReadTexImageHelper* ReadTexImageHelper();
+
+ // Assumes shares are created by all sharing with the same global context.
+ bool SharesWith(const GLContext* other) const {
+ MOZ_ASSERT(!this->mSharedContext || !this->mSharedContext->mSharedContext);
+ MOZ_ASSERT(!other->mSharedContext || !other->mSharedContext->mSharedContext);
+ MOZ_ASSERT(!this->mSharedContext ||
+ !other->mSharedContext ||
+ this->mSharedContext == other->mSharedContext);
+
+ const GLContext* thisShared = this->mSharedContext ? this->mSharedContext
+ : this;
+ const GLContext* otherShared = other->mSharedContext ? other->mSharedContext
+ : other;
+
+ return thisShared == otherShared;
+ }
+
+ bool InitOffscreen(const gfx::IntSize& size, const SurfaceCaps& caps);
+
+protected:
+ // Note that it does -not- clear the resized buffers.
+ bool CreateScreenBuffer(const gfx::IntSize& size, const SurfaceCaps& caps) {
+ if (!IsOffscreenSizeAllowed(size))
+ return false;
+
+ return CreateScreenBufferImpl(size, caps);
+ }
+
+ bool CreateScreenBufferImpl(const gfx::IntSize& size,
+ const SurfaceCaps& caps);
+
+public:
+ bool ResizeScreenBuffer(const gfx::IntSize& size);
+
+protected:
+ SurfaceCaps mCaps;
+
+public:
+ const SurfaceCaps& Caps() const {
+ return mCaps;
+ }
+
+ // Only varies based on bpp16 and alpha.
+ GLFormats ChooseGLFormats(const SurfaceCaps& caps) const;
+
+ bool IsFramebufferComplete(GLuint fb, GLenum* status = nullptr);
+
+ // Does not check completeness.
+ void AttachBuffersToFB(GLuint colorTex, GLuint colorRB,
+ GLuint depthRB, GLuint stencilRB,
+ GLuint fb, GLenum target = LOCAL_GL_TEXTURE_2D);
+
+ // Passing null is fine if the value you'd get is 0.
+ bool AssembleOffscreenFBs(const GLuint colorMSRB,
+ const GLuint depthRB,
+ const GLuint stencilRB,
+ const GLuint texture,
+ GLuint* drawFB,
+ GLuint* readFB);
+
+protected:
+ friend class GLScreenBuffer;
+ UniquePtr<GLScreenBuffer> mScreen;
+
+ SharedSurface* mLockedSurface;
+
+public:
+ void LockSurface(SharedSurface* surf) {
+ MOZ_ASSERT(!mLockedSurface);
+ mLockedSurface = surf;
+ }
+
+ void UnlockSurface(SharedSurface* surf) {
+ MOZ_ASSERT(mLockedSurface == surf);
+ mLockedSurface = nullptr;
+ }
+
+ SharedSurface* GetLockedSurface() const {
+ return mLockedSurface;
+ }
+
+ bool IsOffscreen() const {
+ return mIsOffscreen;
+ }
+
+ GLScreenBuffer* Screen() const {
+ return mScreen.get();
+ }
+
+ /* Clear to transparent black, with 0 depth and stencil,
+ * while preserving current ClearColor etc. values.
+ * Useful for resizing offscreen buffers.
+ */
+ void ClearSafely();
+
+ bool WorkAroundDriverBugs() const { return mWorkAroundDriverBugs; }
+
+ bool IsDrawingToDefaultFramebuffer();
+
+protected:
+ RefPtr<TextureGarbageBin> mTexGarbageBin;
+
+public:
+ TextureGarbageBin* TexGarbageBin() {
+ MOZ_ASSERT(mTexGarbageBin);
+ return mTexGarbageBin;
+ }
+
+ void EmptyTexGarbageBin();
+
+ bool IsOffscreenSizeAllowed(const gfx::IntSize& aSize) const;
+
+protected:
+ bool InitWithPrefix(const char* prefix, bool trygl);
+
+private:
+ bool InitWithPrefixImpl(const char* prefix, bool trygl);
+ void LoadMoreSymbols(const char* prefix, bool trygl);
+ bool LoadExtSymbols(const char* prefix, bool trygl, const SymLoadStruct* list,
+ GLExtensions ext);
+ bool LoadFeatureSymbols(const char* prefix, bool trygl, const SymLoadStruct* list,
+ GLFeature feature);
+
+protected:
+ void InitExtensions();
+
+ GLint mViewportRect[4];
+ GLint mScissorRect[4];
+
+ GLint mMaxTextureSize;
+ GLint mMaxCubeMapTextureSize;
+ GLint mMaxTextureImageSize;
+ GLint mMaxRenderbufferSize;
+ GLint mMaxViewportDims[2];
+ GLsizei mMaxSamples;
+ bool mNeedsTextureSizeChecks;
+ bool mNeedsFlushBeforeDeleteFB;
+ bool mTextureAllocCrashesOnMapFailure;
+ bool mNeedsCheckAfterAttachTextureToFb;
+ bool mWorkAroundDriverBugs;
+
+ bool IsTextureSizeSafeToPassToDriver(GLenum target, GLsizei width, GLsizei height) const {
+ if (mNeedsTextureSizeChecks) {
+ // some drivers incorrectly handle some large texture sizes that are below the
+ // max texture size that they report. So we check ourselves against our own values
+ // (mMax[CubeMap]TextureSize).
+ // see bug 737182 for Mac Intel 2D textures
+ // see bug 684882 for Mac Intel cube map textures
+ // see bug 814716 for Mesa Nouveau
+ GLsizei maxSize = target == LOCAL_GL_TEXTURE_CUBE_MAP ||
+ (target >= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
+ target <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
+ ? mMaxCubeMapTextureSize
+ : mMaxTextureSize;
+ return width <= maxSize && height <= maxSize;
+ }
+ return true;
+ }
+
+
+public:
+ GLsizei MaxSamples() const {
+ return mMaxSamples;
+ }
+
+ void fViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
+ if (mViewportRect[0] == x &&
+ mViewportRect[1] == y &&
+ mViewportRect[2] == width &&
+ mViewportRect[3] == height)
+ {
+ return;
+ }
+ mViewportRect[0] = x;
+ mViewportRect[1] = y;
+ mViewportRect[2] = width;
+ mViewportRect[3] = height;
+ BEFORE_GL_CALL;
+ mSymbols.fViewport(x, y, width, height);
+ AFTER_GL_CALL;
+ }
+
+#undef ASSERT_SYMBOL_PRESENT
+
+#ifdef MOZ_GL_DEBUG
+ void CreatedProgram(GLContext* aOrigin, GLuint aName);
+ void CreatedShader(GLContext* aOrigin, GLuint aName);
+ void CreatedBuffers(GLContext* aOrigin, GLsizei aCount, GLuint* aNames);
+ void CreatedQueries(GLContext* aOrigin, GLsizei aCount, GLuint* aNames);
+ void CreatedTextures(GLContext* aOrigin, GLsizei aCount, GLuint* aNames);
+ void CreatedFramebuffers(GLContext* aOrigin, GLsizei aCount, GLuint* aNames);
+ void CreatedRenderbuffers(GLContext* aOrigin, GLsizei aCount, GLuint* aNames);
+ void DeletedProgram(GLContext* aOrigin, GLuint aName);
+ void DeletedShader(GLContext* aOrigin, GLuint aName);
+ void DeletedBuffers(GLContext* aOrigin, GLsizei aCount, const GLuint* aNames);
+ void DeletedQueries(GLContext* aOrigin, GLsizei aCount, const GLuint* aNames);
+ void DeletedTextures(GLContext* aOrigin, GLsizei aCount, const GLuint* aNames);
+ void DeletedFramebuffers(GLContext* aOrigin, GLsizei aCount, const GLuint* aNames);
+ void DeletedRenderbuffers(GLContext* aOrigin, GLsizei aCount, const GLuint* aNames);
+
+ void SharedContextDestroyed(GLContext* aChild);
+ void ReportOutstandingNames();
+
+ struct NamedResource {
+ NamedResource()
+ : origin(nullptr), name(0), originDeleted(false)
+ { }
+
+ NamedResource(GLContext* aOrigin, GLuint aName)
+ : origin(aOrigin), name(aName), originDeleted(false)
+ { }
+
+ GLContext* origin;
+ GLuint name;
+ bool originDeleted;
+
+ // for sorting
+ bool operator<(const NamedResource& aOther) const {
+ if (intptr_t(origin) < intptr_t(aOther.origin))
+ return true;
+ if (name < aOther.name)
+ return true;
+ return false;
+ }
+ bool operator==(const NamedResource& aOther) const {
+ return origin == aOther.origin &&
+ name == aOther.name &&
+ originDeleted == aOther.originDeleted;
+ }
+ };
+
+ nsTArray<NamedResource> mTrackedPrograms;
+ nsTArray<NamedResource> mTrackedShaders;
+ nsTArray<NamedResource> mTrackedTextures;
+ nsTArray<NamedResource> mTrackedFramebuffers;
+ nsTArray<NamedResource> mTrackedRenderbuffers;
+ nsTArray<NamedResource> mTrackedBuffers;
+ nsTArray<NamedResource> mTrackedQueries;
+#endif
+
+
+protected:
+ bool mHeavyGLCallsSinceLastFlush;
+
+public:
+ void FlushIfHeavyGLCallsSinceLastFlush();
+ static bool ShouldSpew();
+ static bool ShouldDumpExts();
+ void Readback(SharedSurface* src, gfx::DataSourceSurface* dest);
+};
+
+bool DoesStringMatch(const char* aString, const char* aWantedString);
+
+void SplitByChar(const nsACString& str, const char delim,
+ std::vector<nsCString>* const out);
+
+template<size_t N>
+bool
+MarkBitfieldByString(const nsACString& str, const char* const (&markStrList)[N],
+ std::bitset<N>* const out_markList)
+{
+ for (size_t i = 0; i < N; i++) {
+ if (str.Equals(markStrList[i])) {
+ (*out_markList)[i] = 1;
+ return true;
+ }
+ }
+ return false;
+}
+
+template<size_t N>
+void
+MarkBitfieldByStrings(const std::vector<nsCString>& strList,
+ bool dumpStrings, const char* const (&markStrList)[N],
+ std::bitset<N>* const out_markList)
+{
+ for (auto itr = strList.begin(); itr != strList.end(); ++itr) {
+ const nsACString& str = *itr;
+ const bool wasMarked = MarkBitfieldByString(str, markStrList,
+ out_markList);
+ if (dumpStrings)
+ printf_stderr(" %s%s\n", str.BeginReading(), wasMarked ? "(*)" : "");
+ }
+}
+
+/**
+ * Helper function that creates a 2D texture aSize.width x aSize.height with
+ * storage type specified by aFormats. Returns GL texture object id.
+ *
+ * See mozilla::gl::CreateTexture.
+ */
+GLuint CreateTextureForOffscreen(GLContext* aGL, const GLFormats& aFormats,
+ const gfx::IntSize& aSize);
+
+/**
+ * Helper function that creates a 2D texture aSize.width x aSize.height with
+ * storage type aInternalFormat. Returns GL texture object id.
+ *
+ * Initialize textyre parameters to:
+ * GL_TEXTURE_MIN_FILTER = GL_LINEAR
+ * GL_TEXTURE_MAG_FILTER = GL_LINEAR
+ * GL_TEXTURE_WRAP_S = GL_CLAMP_TO_EDGE
+ * GL_TEXTURE_WRAP_T = GL_CLAMP_TO_EDGE
+ */
+GLuint CreateTexture(GLContext* aGL, GLenum aInternalFormat, GLenum aFormat,
+ GLenum aType, const gfx::IntSize& aSize, bool linear = true);
+
+/**
+ * Helper function that calculates the number of bytes required per
+ * texel for a texture from its format and type.
+ */
+uint32_t GetBytesPerTexel(GLenum format, GLenum type);
+
+} /* namespace gl */
+} /* namespace mozilla */
+
+#endif /* GLCONTEXT_H_ */
diff --git a/gfx/gl/GLContextCGL.h b/gfx/gl/GLContextCGL.h
new file mode 100644
index 0000000000..12da90aeed
--- /dev/null
+++ b/gfx/gl/GLContextCGL.h
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GLCONTEXTCGL_H_
+#define GLCONTEXTCGL_H_
+
+#include "GLContext.h"
+
+#include "OpenGL/OpenGL.h"
+
+#ifdef __OBJC__
+#include <AppKit/NSOpenGL.h>
+#else
+typedef void NSOpenGLContext;
+#endif
+
+namespace mozilla {
+namespace gl {
+
+class GLContextCGL : public GLContext
+{
+ friend class GLContextProviderCGL;
+
+ NSOpenGLContext* mContext;
+
+public:
+ MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GLContextCGL, override)
+ GLContextCGL(CreateContextFlags flags, const SurfaceCaps& caps,
+ NSOpenGLContext* context, bool isOffscreen, ContextProfile profile);
+
+ ~GLContextCGL();
+
+ virtual GLContextType GetContextType() const override { return GLContextType::CGL; }
+
+ static GLContextCGL* Cast(GLContext* gl) {
+ MOZ_ASSERT(gl->GetContextType() == GLContextType::CGL);
+ return static_cast<GLContextCGL*>(gl);
+ }
+
+ bool Init() override;
+
+ NSOpenGLContext* GetNSOpenGLContext() const { return mContext; }
+ CGLContextObj GetCGLContext() const;
+
+ virtual bool MakeCurrentImpl(bool aForce) override;
+
+ virtual bool IsCurrent() override;
+
+ virtual GLenum GetPreferredARGB32Format() const override;
+
+ virtual bool SetupLookupFunction() override;
+
+ virtual bool IsDoubleBuffered() const override;
+
+ virtual bool SupportsRobustness() const override { return false; }
+
+ virtual bool SwapBuffers() override;
+};
+
+} // namespace gl
+} // namespace mozilla
+
+#endif // GLCONTEXTCGL_H_
diff --git a/gfx/gl/GLContextEAGL.h b/gfx/gl/GLContextEAGL.h
new file mode 100644
index 0000000000..86e9a5b98b
--- /dev/null
+++ b/gfx/gl/GLContextEAGL.h
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GLCONTEXTEAGL_H_
+#define GLCONTEXTEAGL_H_
+
+#include "GLContext.h"
+
+#include <CoreGraphics/CoreGraphics.h>
+#include <OpenGLES/EAGL.h>
+
+namespace mozilla {
+namespace gl {
+
+class GLContextEAGL : public GLContext
+{
+ friend class GLContextProviderEAGL;
+
+ EAGLContext* const mContext;
+
+public:
+ MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GLContextEAGL, override)
+ GLContextEAGL(CreateContextFlags flags, const SurfaceCaps& caps, EAGLContext* context,
+ GLContext* sharedContext, bool isOffscreen, ContextProfile profile);
+
+ ~GLContextEAGL();
+
+ virtual GLContextType GetContextType() const override {
+ return GLContextType::EAGL;
+ }
+
+ static GLContextEAGL* Cast(GLContext* gl) {
+ MOZ_ASSERT(gl->GetContextType() == GLContextType::EAGL);
+ return static_cast<GLContextEAGL*>(gl);
+ }
+
+ bool Init() override;
+
+ bool AttachToWindow(nsIWidget* aWidget);
+
+ EAGLContext* GetEAGLContext() const { return mContext; }
+
+ virtual bool MakeCurrentImpl(bool aForce) override;
+
+ virtual bool IsCurrent() override;
+
+ virtual bool SetupLookupFunction() override;
+
+ virtual bool IsDoubleBuffered() const override;
+
+ virtual bool SupportsRobustness() const override { return false; }
+
+ virtual bool SwapBuffers() override;
+
+ virtual GLuint GetDefaultFramebuffer() override {
+ return mBackbufferFB;
+ }
+
+ virtual bool RenewSurface(nsIWidget* aWidget) override {
+ // FIXME: should use the passed widget instead of the existing one.
+ return RecreateRB();
+ }
+
+private:
+ GLuint mBackbufferRB;
+ GLuint mBackbufferFB;
+
+ void* mLayer;
+
+ bool RecreateRB();
+};
+
+} // namespace gl
+} // namespace mozilla
+
+#endif // GLCONTEXTEAGL_H_
diff --git a/gfx/gl/GLContextEGL.h b/gfx/gl/GLContextEGL.h
new file mode 100644
index 0000000000..9755ecfe79
--- /dev/null
+++ b/gfx/gl/GLContextEGL.h
@@ -0,0 +1,142 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GLCONTEXTEGL_H_
+#define GLCONTEXTEGL_H_
+
+#include "GLContext.h"
+#include "GLLibraryEGL.h"
+
+namespace mozilla {
+namespace gl {
+
+class GLContextEGL : public GLContext
+{
+ friend class TextureImageEGL;
+
+ static already_AddRefed<GLContextEGL>
+ CreateGLContext(CreateContextFlags flags,
+ const SurfaceCaps& caps,
+ GLContextEGL* shareContext,
+ bool isOffscreen,
+ EGLConfig config,
+ EGLSurface surface,
+ nsACString* const out_failureId);
+
+public:
+ MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GLContextEGL, override)
+ GLContextEGL(CreateContextFlags flags,
+ const SurfaceCaps& caps,
+ GLContext* shareContext,
+ bool isOffscreen,
+ EGLConfig config,
+ EGLSurface surface,
+ EGLContext context);
+
+ ~GLContextEGL();
+
+ virtual GLContextType GetContextType() const override { return GLContextType::EGL; }
+
+ static GLContextEGL* Cast(GLContext* gl) {
+ MOZ_ASSERT(gl->GetContextType() == GLContextType::EGL);
+ return static_cast<GLContextEGL*>(gl);
+ }
+
+ static EGLSurface CreateSurfaceForWindow(nsIWidget* aWidget);
+
+ static void DestroySurface(EGLSurface aSurface);
+
+ bool Init() override;
+
+ virtual bool IsDoubleBuffered() const override {
+ return mIsDoubleBuffered;
+ }
+
+ void SetIsDoubleBuffered(bool aIsDB) {
+ mIsDoubleBuffered = aIsDB;
+ }
+
+ virtual bool SupportsRobustness() const override {
+ return sEGLLibrary.HasRobustness();
+ }
+
+ virtual bool IsANGLE() const override {
+ return sEGLLibrary.IsANGLE();
+ }
+
+ virtual bool IsWARP() const override {
+ return sEGLLibrary.IsWARP();
+ }
+
+ virtual bool BindTexImage() override;
+
+ virtual bool ReleaseTexImage() override;
+
+ void SetEGLSurfaceOverride(EGLSurface surf);
+
+ virtual bool MakeCurrentImpl(bool aForce) override;
+
+ virtual bool IsCurrent() override;
+
+ virtual bool RenewSurface(nsIWidget* aWidget) override;
+
+ virtual void ReleaseSurface() override;
+
+ virtual bool SetupLookupFunction() override;
+
+ virtual bool SwapBuffers() override;
+
+ // hold a reference to the given surface
+ // for the lifetime of this context.
+ void HoldSurface(gfxASurface* aSurf);
+
+ EGLSurface GetEGLSurface() const {
+ return mSurface;
+ }
+
+ EGLDisplay GetEGLDisplay() const {
+ return sEGLLibrary.Display();
+ }
+
+ bool BindTex2DOffscreen(GLContext* aOffscreen);
+ void UnbindTex2DOffscreen(GLContext* aOffscreen);
+ void BindOffscreenFramebuffer();
+
+ static already_AddRefed<GLContextEGL>
+ CreateEGLPBufferOffscreenContext(CreateContextFlags flags,
+ const gfx::IntSize& size,
+ const SurfaceCaps& minCaps,
+ nsACString* const out_FailureId);
+
+protected:
+ friend class GLContextProviderEGL;
+
+public:
+ const EGLConfig mConfig;
+protected:
+ EGLSurface mSurface;
+public:
+ const EGLContext mContext;
+protected:
+ EGLSurface mSurfaceOverride;
+ RefPtr<gfxASurface> mThebesSurface;
+ bool mBound;
+
+ bool mIsPBuffer;
+ bool mIsDoubleBuffered;
+ bool mCanBindToTexture;
+ bool mShareWithEGLImage;
+ bool mOwnsContext;
+
+ static EGLSurface CreatePBufferSurfaceTryingPowerOfTwo(EGLConfig config,
+ EGLenum bindToTextureFormat,
+ gfx::IntSize& pbsize);
+};
+
+} // namespace gl
+} // namespace mozilla
+
+#endif // GLCONTEXTEGL_H_
diff --git a/gfx/gl/GLContextFeatures.cpp b/gfx/gl/GLContextFeatures.cpp
new file mode 100644
index 0000000000..0714d96415
--- /dev/null
+++ b/gfx/gl/GLContextFeatures.cpp
@@ -0,0 +1,928 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "GLContext.h"
+#include "nsPrintfCString.h"
+
+namespace mozilla {
+namespace gl {
+
+const size_t kMAX_EXTENSION_GROUP_SIZE = 5;
+
+enum class GLVersion : uint32_t {
+ NONE = 0, // Feature is not supported natively by GL
+ GL1_2 = 120,
+ GL1_3 = 130,
+ GL2 = 200,
+ GL2_1 = 210,
+ GL3 = 300,
+ GL3_1 = 310,
+ GL3_2 = 320,
+ GL3_3 = 330,
+ GL4 = 400,
+ GL4_1 = 410,
+ GL4_2 = 420,
+ GL4_3 = 430,
+};
+
+enum class GLESVersion : uint32_t {
+ NONE = 0, // Feature is not support natively by GL ES
+ ES2 = 200,
+ ES3 = 300,
+ ES3_1 = 310,
+ ES3_2 = 320,
+};
+
+// ARB_ES2_compatibility is natively supported in OpenGL 4.1.
+static const GLVersion kGLCoreVersionForES2Compat = GLVersion::GL4_1;
+
+// ARB_ES3_compatibility is natively supported in OpenGL 4.3.
+static const GLVersion kGLCoreVersionForES3Compat = GLVersion::GL4_3;
+
+struct FeatureInfo
+{
+ const char* mName;
+
+ /* The (desktop) OpenGL version that provides this feature */
+ GLVersion mOpenGLVersion;
+
+ /* The OpenGL ES version that provides this feature */
+ GLESVersion mOpenGLESVersion;
+
+ /* If there is an ARB extension, and its function symbols are
+ * not decorated with an ARB suffix, then its extension ID should go
+ * here, and NOT in mExtensions. For example, ARB_vertex_array_object
+ * functions do not have an ARB suffix, because it is an extension that
+ * was created to match core GL functionality and will never differ.
+ * Some ARB extensions do have a suffix, if they were created before
+ * a core version of the functionality existed.
+ *
+ * If there is no such ARB extension, pass 0 (GLContext::Extension_None)
+ */
+ GLContext::GLExtensions mARBExtensionWithoutARBSuffix;
+
+ /* Extensions that also provide this feature */
+ GLContext::GLExtensions mExtensions[kMAX_EXTENSION_GROUP_SIZE];
+};
+
+static const FeatureInfo sFeatureInfoArr[] = {
+ {
+ "bind_buffer_offset",
+ GLVersion::NONE,
+ GLESVersion::NONE,
+ GLContext::Extension_None,
+ {
+
+ GLContext::EXT_transform_feedback,
+ GLContext::NV_transform_feedback2,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "blend_minmax",
+ GLVersion::GL2,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::EXT_blend_minmax,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "clear_buffers",
+ GLVersion::GL3,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "copy_buffer",
+ GLVersion::GL3_1,
+ GLESVersion::ES3,
+ GLContext::ARB_copy_buffer,
+ {
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "depth_texture",
+ GLVersion::GL2,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::ARB_depth_texture,
+ GLContext::OES_depth_texture,
+ // Intentionally avoid putting ANGLE_depth_texture here,
+ // it does not offer quite the same functionality.
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "draw_buffers",
+ GLVersion::GL2,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::ARB_draw_buffers,
+ GLContext::EXT_draw_buffers,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "draw_instanced",
+ GLVersion::GL3_1,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::ARB_draw_instanced,
+ GLContext::EXT_draw_instanced,
+ GLContext::NV_draw_instanced,
+ GLContext::ANGLE_instanced_arrays,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "draw_range_elements",
+ GLVersion::GL1_2,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::EXT_draw_range_elements,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "element_index_uint",
+ GLVersion::GL2,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::OES_element_index_uint,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "ES2_compatibility",
+ kGLCoreVersionForES2Compat,
+ GLESVersion::ES2, // OpenGL ES version
+ GLContext::ARB_ES2_compatibility, // no suffix on ARB extension
+ {
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "ES3_compatibility",
+ kGLCoreVersionForES3Compat,
+ GLESVersion::ES3, // OpenGL ES version
+ GLContext::ARB_ES3_compatibility, // no suffix on ARB extension
+ {
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "EXT_color_buffer_float",
+ GLVersion::GL3,
+ GLESVersion::ES3_2,
+ GLContext::Extension_None,
+ {
+ GLContext::EXT_color_buffer_float,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ // Removes clamping for float color outputs from frag shaders.
+ "frag_color_float",
+ GLVersion::GL3,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::ARB_color_buffer_float,
+ GLContext::EXT_color_buffer_float,
+ GLContext::EXT_color_buffer_half_float,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "frag_depth",
+ GLVersion::GL2,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::EXT_frag_depth,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ // Check for just the blit framebuffer blit part of
+ // ARB_framebuffer_object
+ "framebuffer_blit",
+ GLVersion::GL3,
+ GLESVersion::ES3,
+ GLContext::ARB_framebuffer_object,
+ {
+ GLContext::ANGLE_framebuffer_blit,
+ GLContext::EXT_framebuffer_blit,
+ GLContext::NV_framebuffer_blit,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ // Check for just the multisample renderbuffer part of
+ // ARB_framebuffer_object
+ "framebuffer_multisample",
+ GLVersion::GL3,
+ GLESVersion::ES3,
+ GLContext::ARB_framebuffer_object,
+ {
+ GLContext::ANGLE_framebuffer_multisample,
+ GLContext::APPLE_framebuffer_multisample,
+ GLContext::EXT_framebuffer_multisample,
+ GLContext::EXT_multisampled_render_to_texture,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ // ARB_framebuffer_object support
+ "framebuffer_object",
+ GLVersion::GL3,
+ GLESVersion::ES3,
+ GLContext::ARB_framebuffer_object,
+ {
+ GLContext::Extensions_End
+ }
+ },
+ {
+ // EXT_framebuffer_object/OES_framebuffer_object support
+ "framebuffer_object_EXT_OES",
+ GLVersion::GL3,
+ GLESVersion::ES2,
+ GLContext::Extension_None,
+ {
+ GLContext::EXT_framebuffer_object,
+ GLContext::OES_framebuffer_object,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "get_integer_indexed",
+ GLVersion::GL3,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::EXT_draw_buffers2,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "get_integer64_indexed",
+ GLVersion::GL3_2,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "get_query_object_i64v",
+ GLVersion::GL3_3,
+ GLESVersion::NONE,
+ GLContext::ARB_timer_query,
+ {
+ GLContext::ANGLE_timer_query,
+ GLContext::EXT_disjoint_timer_query,
+ GLContext::EXT_timer_query,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "get_query_object_iv",
+ GLVersion::GL2,
+ GLESVersion::NONE,
+ GLContext::Extension_None,
+ {
+ GLContext::Extensions_End
+ }
+ /*
+ * XXX_get_query_object_iv only provide GetQueryObjectiv provided by
+ * ARB_occlusion_query (added by OpenGL 2.0).
+ */
+ },
+ {
+ "get_string_indexed",
+ GLVersion::GL3,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::Extensions_End
+ }
+ // glGetStringi
+ },
+ {
+ "gpu_shader4",
+ GLVersion::GL3,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::EXT_gpu_shader4,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "instanced_arrays",
+ GLVersion::GL3_3,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::ARB_instanced_arrays,
+ GLContext::NV_instanced_arrays,
+ GLContext::ANGLE_instanced_arrays,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "instanced_non_arrays",
+ GLVersion::GL3_3,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::ARB_instanced_arrays,
+ GLContext::Extensions_End
+ }
+ /* This is an expanded version of `instanced_arrays` that allows for all
+ * enabled active attrib arrays to have non-zero divisors.
+ * ANGLE_instanced_arrays and NV_instanced_arrays forbid this, but GLES3
+ * has no such restriction.
+ */
+ },
+ {
+ "internalformat_query",
+ GLVersion::GL4_2,
+ GLESVersion::ES3,
+ GLContext::ARB_internalformat_query,
+ {
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "invalidate_framebuffer",
+ GLVersion::GL4_3,
+ GLESVersion::ES3,
+ GLContext::ARB_invalidate_subdata,
+ {
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "map_buffer_range",
+ GLVersion::GL3,
+ GLESVersion::ES3,
+ GLContext::ARB_map_buffer_range,
+ {
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "occlusion_query",
+ GLVersion::GL2,
+ GLESVersion::NONE,
+ GLContext::Extension_None,
+ {
+ GLContext::Extensions_End
+ }
+ // XXX_occlusion_query depend on ARB_occlusion_query (added in OpenGL 2.0)
+ },
+ {
+ "occlusion_query_boolean",
+ kGLCoreVersionForES3Compat,
+ GLESVersion::ES3,
+ GLContext::ARB_ES3_compatibility,
+ {
+ GLContext::EXT_occlusion_query_boolean,
+ GLContext::Extensions_End
+ }
+ /*
+ * XXX_occlusion_query_boolean provide ANY_SAMPLES_PASSED_CONSERVATIVE,
+ * but EXT_occlusion_query_boolean is only a OpenGL ES extension. But
+ * it is supported on desktop if ARB_ES3_compatibility because
+ * EXT_occlusion_query_boolean (added in OpenGL ES 3.0).
+ */
+ },
+ {
+ "occlusion_query2",
+ GLVersion::GL3_3,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::ARB_occlusion_query2,
+ GLContext::ARB_ES3_compatibility,
+ GLContext::EXT_occlusion_query_boolean,
+ GLContext::Extensions_End
+ }
+ /*
+ * XXX_occlusion_query2 (add in OpenGL 3.3) provide ANY_SAMPLES_PASSED,
+ * which is provided by ARB_occlusion_query2, EXT_occlusion_query_boolean
+ * (added in OpenGL ES 3.0) and ARB_ES3_compatibility
+ */
+ },
+ {
+ "packed_depth_stencil",
+ GLVersion::GL3,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::EXT_packed_depth_stencil,
+ GLContext::OES_packed_depth_stencil,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "prim_restart",
+ GLVersion::GL3_1,
+ GLESVersion::NONE,
+ GLContext::Extension_None,
+ {
+ //GLContext::NV_primitive_restart, // Has different enum values.
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "prim_restart_fixed",
+ kGLCoreVersionForES3Compat,
+ GLESVersion::ES3,
+ GLContext::ARB_ES3_compatibility,
+ {
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "query_counter",
+ GLVersion::GL3_3,
+ GLESVersion::NONE,
+ GLContext::ARB_timer_query,
+ {
+ GLContext::ANGLE_timer_query,
+ GLContext::EXT_disjoint_timer_query,
+ // EXT_timer_query does NOT support GL_TIMESTAMP retrieval with
+ // QueryCounter.
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "query_objects",
+ GLVersion::GL2,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::ANGLE_timer_query,
+ GLContext::EXT_disjoint_timer_query,
+ GLContext::EXT_occlusion_query_boolean,
+ GLContext::Extensions_End
+ }
+ /*
+ * XXX_query_objects only provide entry points commonly supported by
+ * ARB_occlusion_query (added in OpenGL 2.0), EXT_occlusion_query_boolean
+ * (added in OpenGL ES 3.0), and ARB_timer_query (added in OpenGL 3.3)
+ */
+ },
+ {
+ "query_time_elapsed",
+ GLVersion::GL3_3,
+ GLESVersion::NONE,
+ GLContext::ARB_timer_query,
+ {
+ GLContext::ANGLE_timer_query,
+ GLContext::EXT_disjoint_timer_query,
+ GLContext::EXT_timer_query,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "read_buffer",
+ GLVersion::GL2,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "renderbuffer_color_float",
+ GLVersion::GL3,
+ GLESVersion::ES3_2,
+ GLContext::Extension_None,
+ {
+ GLContext::ARB_texture_float,
+ GLContext::EXT_color_buffer_float,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "renderbuffer_color_half_float",
+ GLVersion::GL3,
+ GLESVersion::ES3_2,
+ GLContext::Extension_None,
+ {
+ GLContext::ARB_texture_float,
+ GLContext::EXT_color_buffer_float,
+ GLContext::EXT_color_buffer_half_float,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "robustness",
+ GLVersion::NONE,
+ GLESVersion::NONE,
+ GLContext::Extension_None,
+ {
+ GLContext::ARB_robustness,
+ GLContext::EXT_robustness,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "sRGB_framebuffer",
+ GLVersion::GL3,
+ GLESVersion::ES3,
+ GLContext::ARB_framebuffer_sRGB,
+ {
+ GLContext::EXT_framebuffer_sRGB,
+ GLContext::EXT_sRGB_write_control,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "sRGB_texture",
+ GLVersion::GL2_1,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::EXT_sRGB,
+ GLContext::EXT_texture_sRGB,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "sampler_objects",
+ GLVersion::GL3_3,
+ GLESVersion::ES3,
+ GLContext::ARB_sampler_objects,
+ {
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "seamless_cube_map_opt_in",
+ GLVersion::GL3_2,
+ GLESVersion::NONE,
+ GLContext::ARB_seamless_cube_map,
+ {
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "shader_texture_lod",
+ GLVersion::NONE,
+ GLESVersion::NONE,
+ GLContext::Extension_None,
+ {
+ GLContext::ARB_shader_texture_lod,
+ GLContext::EXT_shader_texture_lod,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ // Do we have separate DRAW and READ framebuffer bind points?
+ "split_framebuffer",
+ GLVersion::GL3,
+ GLESVersion::ES3,
+ GLContext::ARB_framebuffer_object,
+ {
+ GLContext::ANGLE_framebuffer_blit,
+ GLContext::APPLE_framebuffer_multisample,
+ GLContext::EXT_framebuffer_blit,
+ GLContext::NV_framebuffer_blit,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "standard_derivatives",
+ GLVersion::GL2,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::OES_standard_derivatives,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "sync",
+ GLVersion::GL3_2,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::ARB_sync,
+ GLContext::APPLE_sync,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "texture_3D",
+ GLVersion::GL1_2,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::EXT_texture3D,
+ GLContext::OES_texture_3D,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "texture_3D_compressed",
+ GLVersion::GL1_3,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::ARB_texture_compression,
+ GLContext::OES_texture_3D,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "texture_3D_copy",
+ GLVersion::GL1_2,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::EXT_copy_texture,
+ GLContext::OES_texture_3D,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "texture_float",
+ GLVersion::GL3,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::ARB_texture_float,
+ GLContext::OES_texture_float,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "texture_float_linear",
+ GLVersion::GL3_1,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::ARB_texture_float,
+ GLContext::OES_texture_float_linear,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "texture_half_float",
+ GLVersion::GL3,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::ARB_half_float_pixel,
+ GLContext::ARB_texture_float,
+ GLContext::NV_half_float,
+ GLContext::Extensions_End
+ }
+ /**
+ * We are not including OES_texture_half_float in this feature, because:
+ * GL_HALF_FLOAT = 0x140B
+ * GL_HALF_FLOAT_ARB = 0x140B == GL_HALF_FLOAT
+ * GL_HALF_FLOAT_NV = 0x140B == GL_HALF_FLOAT
+ * GL_HALF_FLOAT_OES = 0x8D61 != GL_HALF_FLOAT
+ * WebGL handles this specifically with an OES_texture_half_float check.
+ */
+ },
+ {
+ "texture_half_float_linear",
+ GLVersion::GL3_1,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::ARB_half_float_pixel,
+ GLContext::ARB_texture_float,
+ GLContext::NV_half_float,
+ GLContext::OES_texture_half_float_linear,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "texture_non_power_of_two",
+ GLVersion::GL2,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::ARB_texture_non_power_of_two,
+ GLContext::OES_texture_npot,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "texture_rg",
+ GLVersion::GL3,
+ GLESVersion::ES3,
+ GLContext::ARB_texture_rg,
+ {
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "texture_storage",
+ GLVersion::GL4_2,
+ GLESVersion::ES3,
+ GLContext::ARB_texture_storage,
+ {
+ /*
+ * Not including GL_EXT_texture_storage here because it
+ * doesn't guarantee glTexStorage3D, which is required for
+ * WebGL 2.
+ */
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "texture_swizzle",
+ GLVersion::GL3_3,
+ GLESVersion::ES3,
+ GLContext::ARB_texture_swizzle,
+ {
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "transform_feedback2",
+ GLVersion::GL4,
+ GLESVersion::ES3,
+ GLContext::ARB_transform_feedback2,
+ {
+ GLContext::NV_transform_feedback2,
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "uniform_buffer_object",
+ GLVersion::GL3_1,
+ GLESVersion::ES3,
+ GLContext::ARB_uniform_buffer_object,
+ {
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "uniform_matrix_nonsquare",
+ GLVersion::GL2_1,
+ GLESVersion::ES3,
+ GLContext::Extension_None,
+ {
+ GLContext::Extensions_End
+ }
+ },
+ {
+ "vertex_array_object",
+ GLVersion::GL3,
+ GLESVersion::ES3,
+ GLContext::ARB_vertex_array_object, // ARB extension
+ {
+ GLContext::OES_vertex_array_object,
+ GLContext::APPLE_vertex_array_object,
+ GLContext::Extensions_End
+ }
+ }
+};
+
+static inline const FeatureInfo&
+GetFeatureInfo(GLFeature feature)
+{
+ static_assert(MOZ_ARRAY_LENGTH(sFeatureInfoArr) == size_t(GLFeature::EnumMax),
+ "Mismatched lengths for sFeatureInfoInfos and GLFeature enums");
+
+ MOZ_ASSERT(feature < GLFeature::EnumMax,
+ "GLContext::GetFeatureInfoInfo : unknown <feature>");
+
+ return sFeatureInfoArr[size_t(feature)];
+}
+
+static inline uint32_t
+ProfileVersionForFeature(GLFeature feature, ContextProfile profile)
+{
+ MOZ_ASSERT(profile != ContextProfile::Unknown,
+ "GLContext::ProfileVersionForFeature : unknown <profile>");
+
+ const FeatureInfo& featureInfo = GetFeatureInfo(feature);
+
+ if (profile == ContextProfile::OpenGLES)
+ return (uint32_t)featureInfo.mOpenGLESVersion;
+
+ return (uint32_t)featureInfo.mOpenGLVersion;
+}
+
+bool
+IsFeaturePartOfProfileVersion(GLFeature feature,
+ ContextProfile profile, unsigned int version)
+{
+ unsigned int profileVersion = ProfileVersionForFeature(feature, profile);
+
+ /**
+ * if `profileVersion` is zero, it means that no version of the profile
+ * added support for the feature.
+ */
+ return profileVersion && version >= profileVersion;
+}
+
+bool
+GLContext::IsFeatureProvidedByCoreSymbols(GLFeature feature)
+{
+ if (IsFeaturePartOfProfileVersion(feature, mProfile, mVersion))
+ return true;
+
+ if (IsExtensionSupported(GetFeatureInfo(feature).mARBExtensionWithoutARBSuffix))
+ return true;
+
+ return false;
+}
+
+const char*
+GLContext::GetFeatureName(GLFeature feature)
+{
+ return GetFeatureInfo(feature).mName;
+}
+
+void
+GLContext::InitFeatures()
+{
+ for (size_t featureId = 0; featureId < size_t(GLFeature::EnumMax); featureId++) {
+ GLFeature feature = GLFeature(featureId);
+
+ if (IsFeaturePartOfProfileVersion(feature, mProfile, mVersion)) {
+ mAvailableFeatures[featureId] = true;
+ continue;
+ }
+
+ mAvailableFeatures[featureId] = false;
+
+ const FeatureInfo& featureInfo = GetFeatureInfo(feature);
+
+ if (IsExtensionSupported(featureInfo.mARBExtensionWithoutARBSuffix)) {
+ mAvailableFeatures[featureId] = true;
+ continue;
+ }
+
+ for (size_t j = 0; true; j++) {
+ MOZ_ASSERT(j < kMAX_EXTENSION_GROUP_SIZE,
+ "kMAX_EXTENSION_GROUP_SIZE too small");
+
+ if (featureInfo.mExtensions[j] == GLContext::Extensions_End)
+ break;
+
+ if (IsExtensionSupported(featureInfo.mExtensions[j])) {
+ mAvailableFeatures[featureId] = true;
+ break;
+ }
+ }
+ }
+
+ if (ShouldDumpExts()) {
+ for (size_t featureId = 0; featureId < size_t(GLFeature::EnumMax); featureId++) {
+ GLFeature feature = GLFeature(featureId);
+ printf_stderr("[%s] Feature::%s\n",
+ IsSupported(feature) ? "enabled" : "disabled",
+ GetFeatureName(feature));
+ }
+ }
+}
+
+void
+GLContext::MarkUnsupported(GLFeature feature)
+{
+ mAvailableFeatures[size_t(feature)] = false;
+
+ const FeatureInfo& featureInfo = GetFeatureInfo(feature);
+
+ for (size_t i = 0; true; i++) {
+ MOZ_ASSERT(i < kMAX_EXTENSION_GROUP_SIZE, "kMAX_EXTENSION_GROUP_SIZE too small");
+
+ if (featureInfo.mExtensions[i] == GLContext::Extensions_End)
+ break;
+
+ MarkExtensionUnsupported(featureInfo.mExtensions[i]);
+ }
+
+ MOZ_ASSERT(!IsSupported(feature), "GLContext::MarkUnsupported has failed!");
+
+ NS_WARNING(nsPrintfCString("%s marked as unsupported",
+ GetFeatureName(feature)).get());
+}
+
+} /* namespace gl */
+} /* namespace mozilla */
diff --git a/gfx/gl/GLContextGLX.h b/gfx/gl/GLContextGLX.h
new file mode 100644
index 0000000000..ca476baec0
--- /dev/null
+++ b/gfx/gl/GLContextGLX.h
@@ -0,0 +1,99 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GLCONTEXTGLX_H_
+#define GLCONTEXTGLX_H_
+
+#include "GLContext.h"
+#include "GLXLibrary.h"
+#include "mozilla/X11Util.h"
+
+namespace mozilla {
+namespace gl {
+
+class GLContextGLX : public GLContext
+{
+public:
+ MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GLContextGLX, override)
+ static already_AddRefed<GLContextGLX>
+ CreateGLContext(CreateContextFlags flags,
+ const SurfaceCaps& caps,
+ GLContextGLX* shareContext,
+ bool isOffscreen,
+ Display* display,
+ GLXDrawable drawable,
+ GLXFBConfig cfg,
+ bool deleteDrawable,
+ gfxXlibSurface* pixmap = nullptr,
+ ContextProfile profile = ContextProfile::OpenGLCompatibility);
+
+ // Finds a GLXFBConfig compatible with the provided window.
+ static bool
+ FindFBConfigForWindow(Display* display, int screen, Window window,
+ ScopedXFree<GLXFBConfig>* const out_scopedConfigArr,
+ GLXFBConfig* const out_config, int* const out_visid);
+
+ ~GLContextGLX();
+
+ virtual GLContextType GetContextType() const override { return GLContextType::GLX; }
+
+ static GLContextGLX* Cast(GLContext* gl) {
+ MOZ_ASSERT(gl->GetContextType() == GLContextType::GLX);
+ return static_cast<GLContextGLX*>(gl);
+ }
+
+ bool Init() override;
+
+ virtual bool MakeCurrentImpl(bool aForce) override;
+
+ virtual bool IsCurrent() override;
+
+ virtual bool SetupLookupFunction() override;
+
+ virtual bool IsDoubleBuffered() const override;
+
+ virtual bool SupportsRobustness() const override;
+
+ virtual bool SwapBuffers() override;
+
+ // Overrides the current GLXDrawable backing the context and makes the
+ // context current.
+ bool OverrideDrawable(GLXDrawable drawable);
+
+ // Undoes the effect of a drawable override.
+ bool RestoreDrawable();
+
+private:
+ friend class GLContextProviderGLX;
+
+ GLContextGLX(CreateContextFlags flags,
+ const SurfaceCaps& caps,
+ GLContext* shareContext,
+ bool isOffscreen,
+ Display* aDisplay,
+ GLXDrawable aDrawable,
+ GLXContext aContext,
+ bool aDeleteDrawable,
+ bool aDoubleBuffered,
+ gfxXlibSurface* aPixmap,
+ ContextProfile profile);
+
+ GLXContext mContext;
+ Display* mDisplay;
+ GLXDrawable mDrawable;
+ bool mDeleteDrawable;
+ bool mDoubleBuffered;
+
+ GLXLibrary* mGLX;
+
+ RefPtr<gfxXlibSurface> mPixmap;
+ bool mOwnsContext;
+};
+
+}
+}
+
+#endif // GLCONTEXTGLX_H_
diff --git a/gfx/gl/GLContextProvider.h b/gfx/gl/GLContextProvider.h
new file mode 100644
index 0000000000..6e096c1f7e
--- /dev/null
+++ b/gfx/gl/GLContextProvider.h
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GLCONTEXTPROVIDER_H_
+#define GLCONTEXTPROVIDER_H_
+
+#include "GLContextTypes.h"
+#include "SurfaceTypes.h"
+
+#include "nsSize.h" // for gfx::IntSize (needed by GLContextProviderImpl.h below)
+
+class nsIWidget;
+
+namespace mozilla {
+namespace widget {
+ class CompositorWidget;
+}
+namespace gl {
+
+#define IN_GL_CONTEXT_PROVIDER_H
+
+// Null is always there
+#define GL_CONTEXT_PROVIDER_NAME GLContextProviderNull
+#include "GLContextProviderImpl.h"
+#undef GL_CONTEXT_PROVIDER_NAME
+
+#ifdef XP_WIN
+ #define GL_CONTEXT_PROVIDER_NAME GLContextProviderWGL
+ #include "GLContextProviderImpl.h"
+ #undef GL_CONTEXT_PROVIDER_NAME
+ #define GL_CONTEXT_PROVIDER_DEFAULT GLContextProviderWGL
+ #define DEFAULT_IMPL WGL
+#endif
+
+#ifdef XP_MACOSX
+ #define GL_CONTEXT_PROVIDER_NAME GLContextProviderCGL
+ #include "GLContextProviderImpl.h"
+ #undef GL_CONTEXT_PROVIDER_NAME
+ #define GL_CONTEXT_PROVIDER_DEFAULT GLContextProviderCGL
+#endif
+
+#if defined(MOZ_X11)
+ #define GL_CONTEXT_PROVIDER_NAME GLContextProviderGLX
+ #include "GLContextProviderImpl.h"
+ #undef GL_CONTEXT_PROVIDER_NAME
+ #define GL_CONTEXT_PROVIDER_DEFAULT GLContextProviderGLX
+#endif
+
+#define GL_CONTEXT_PROVIDER_NAME GLContextProviderEGL
+#include "GLContextProviderImpl.h"
+#undef GL_CONTEXT_PROVIDER_NAME
+#ifndef GL_CONTEXT_PROVIDER_DEFAULT
+ #define GL_CONTEXT_PROVIDER_DEFAULT GLContextProviderEGL
+#endif
+
+#if defined(MOZ_WIDGET_UIKIT)
+#define GL_CONTEXT_PROVIDER_NAME GLContextProviderEAGL
+#include "GLContextProviderImpl.h"
+#undef GL_CONTEXT_PROVIDER_NAME
+#ifndef GL_CONTEXT_PROVIDER_DEFAULT
+#define GL_CONTEXT_PROVIDER_DEFAULT GLContextProviderEAGL
+#endif
+#endif
+
+#ifdef MOZ_GL_PROVIDER
+ #define GL_CONTEXT_PROVIDER_NAME MOZ_GL_PROVIDER
+ #include "GLContextProviderImpl.h"
+ #undef GL_CONTEXT_PROVIDER_NAME
+ #define GL_CONTEXT_PROVIDER_DEFAULT MOZ_GL_PROVIDER
+#endif
+
+#ifdef GL_CONTEXT_PROVIDER_DEFAULT
+ typedef GL_CONTEXT_PROVIDER_DEFAULT GLContextProvider;
+#else
+ typedef GLContextProviderNull GLContextProvider;
+#endif
+
+#undef IN_GL_CONTEXT_PROVIDER_H
+
+} // namespace gl
+} // namespace mozilla
+
+#endif
diff --git a/gfx/gl/GLContextProviderCGL.mm b/gfx/gl/GLContextProviderCGL.mm
new file mode 100644
index 0000000000..0b8add435a
--- /dev/null
+++ b/gfx/gl/GLContextProviderCGL.mm
@@ -0,0 +1,400 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "GLContextProvider.h"
+#include "GLContextCGL.h"
+#include "nsDebug.h"
+#include "nsIWidget.h"
+#include <OpenGL/gl.h>
+#include "gfxFailure.h"
+#include "gfxPrefs.h"
+#include "prenv.h"
+#include "GeckoProfiler.h"
+#include "mozilla/gfx/MacIOSurface.h"
+#include "mozilla/widget/CompositorWidget.h"
+
+#include <OpenGL/OpenGL.h>
+
+// When running inside a VM, creating an accelerated OpenGL context usually
+// fails. Uncomment this line to emulate that behavior.
+// #define EMULATE_VM
+
+namespace mozilla {
+namespace gl {
+
+using namespace mozilla::gfx;
+using namespace mozilla::widget;
+
+class CGLLibrary
+{
+public:
+ CGLLibrary()
+ : mInitialized(false)
+ , mUseDoubleBufferedWindows(true)
+ , mOGLLibrary(nullptr)
+ {}
+
+ bool EnsureInitialized()
+ {
+ if (mInitialized) {
+ return true;
+ }
+ if (!mOGLLibrary) {
+ mOGLLibrary = PR_LoadLibrary("/System/Library/Frameworks/OpenGL.framework/OpenGL");
+ if (!mOGLLibrary) {
+ NS_WARNING("Couldn't load OpenGL Framework.");
+ return false;
+ }
+ }
+
+ const char* db = PR_GetEnv("MOZ_CGL_DB");
+ if (db) {
+ mUseDoubleBufferedWindows = *db != '0';
+ }
+
+ mInitialized = true;
+ return true;
+ }
+
+ bool UseDoubleBufferedWindows() const {
+ MOZ_ASSERT(mInitialized);
+ return mUseDoubleBufferedWindows;
+ }
+
+private:
+ bool mInitialized;
+ bool mUseDoubleBufferedWindows;
+ PRLibrary* mOGLLibrary;
+};
+
+CGLLibrary sCGLLibrary;
+
+GLContextCGL::GLContextCGL(CreateContextFlags flags, const SurfaceCaps& caps,
+ NSOpenGLContext* context, bool isOffscreen,
+ ContextProfile profile)
+ : GLContext(flags, caps, nullptr, isOffscreen)
+ , mContext(context)
+{
+ SetProfileVersion(profile, 210);
+}
+
+GLContextCGL::~GLContextCGL()
+{
+ MarkDestroyed();
+
+ if (mContext) {
+ if ([NSOpenGLContext currentContext] == mContext) {
+ // Clear the current context before releasing. If we don't do
+ // this, the next time we call [NSOpenGLContext currentContext],
+ // "invalid context" will be printed to the console.
+ [NSOpenGLContext clearCurrentContext];
+ }
+ [mContext release];
+ }
+
+}
+
+bool
+GLContextCGL::Init()
+{
+ if (!InitWithPrefix("gl", true))
+ return false;
+
+ return true;
+}
+
+CGLContextObj
+GLContextCGL::GetCGLContext() const
+{
+ return static_cast<CGLContextObj>([mContext CGLContextObj]);
+}
+
+bool
+GLContextCGL::MakeCurrentImpl(bool aForce)
+{
+ if (!aForce && [NSOpenGLContext currentContext] == mContext) {
+ return true;
+ }
+
+ if (mContext) {
+ [mContext makeCurrentContext];
+ MOZ_ASSERT(IsCurrent());
+ // Use non-blocking swap in "ASAP mode".
+ // ASAP mode means that rendering is iterated as fast as possible.
+ // ASAP mode is entered when layout.frame_rate=0 (requires restart).
+ // If swapInt is 1, then glSwapBuffers will block and wait for a vblank signal.
+ // When we're iterating as fast as possible, however, we want a non-blocking
+ // glSwapBuffers, which will happen when swapInt==0.
+ GLint swapInt = gfxPrefs::LayoutFrameRate() == 0 ? 0 : 1;
+ [mContext setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
+ }
+ return true;
+}
+
+bool
+GLContextCGL::IsCurrent() {
+ return [NSOpenGLContext currentContext] == mContext;
+}
+
+GLenum
+GLContextCGL::GetPreferredARGB32Format() const
+{
+ return LOCAL_GL_BGRA;
+}
+
+bool
+GLContextCGL::SetupLookupFunction()
+{
+ return false;
+}
+
+bool
+GLContextCGL::IsDoubleBuffered() const
+{
+ return sCGLLibrary.UseDoubleBufferedWindows();
+}
+
+bool
+GLContextCGL::SwapBuffers()
+{
+ PROFILER_LABEL("GLContextCGL", "SwapBuffers",
+ js::ProfileEntry::Category::GRAPHICS);
+
+ [mContext flushBuffer];
+ return true;
+}
+
+
+already_AddRefed<GLContext>
+GLContextProviderCGL::CreateWrappingExisting(void*, void*)
+{
+ return nullptr;
+}
+
+static const NSOpenGLPixelFormatAttribute kAttribs_singleBuffered[] = {
+ NSOpenGLPFAAllowOfflineRenderers,
+ 0
+};
+
+static const NSOpenGLPixelFormatAttribute kAttribs_singleBuffered_accel[] = {
+ NSOpenGLPFAAccelerated,
+ NSOpenGLPFAAllowOfflineRenderers,
+ 0
+};
+
+static const NSOpenGLPixelFormatAttribute kAttribs_doubleBuffered[] = {
+ NSOpenGLPFAAllowOfflineRenderers,
+ NSOpenGLPFADoubleBuffer,
+ 0
+};
+
+static const NSOpenGLPixelFormatAttribute kAttribs_doubleBuffered_accel[] = {
+ NSOpenGLPFAAccelerated,
+ NSOpenGLPFAAllowOfflineRenderers,
+ NSOpenGLPFADoubleBuffer,
+ 0
+};
+
+static const NSOpenGLPixelFormatAttribute kAttribs_offscreen[] = {
+ 0
+};
+
+static const NSOpenGLPixelFormatAttribute kAttribs_offscreen_allow_offline[] = {
+ NSOpenGLPFAAllowOfflineRenderers,
+ 0
+};
+
+static const NSOpenGLPixelFormatAttribute kAttribs_offscreen_accel[] = {
+ NSOpenGLPFAAccelerated,
+ 0
+};
+
+static const NSOpenGLPixelFormatAttribute kAttribs_offscreen_coreProfile[] = {
+ NSOpenGLPFAAccelerated,
+ NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
+ 0
+};
+
+static NSOpenGLContext*
+CreateWithFormat(const NSOpenGLPixelFormatAttribute* attribs)
+{
+ NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc]
+ initWithAttributes:attribs];
+ if (!format) {
+ NS_WARNING("Failed to create NSOpenGLPixelFormat.");
+ return nullptr;
+ }
+
+ NSOpenGLContext* context = [[NSOpenGLContext alloc] initWithFormat:format
+ shareContext:nullptr];
+
+ [format release];
+
+ return context;
+}
+
+already_AddRefed<GLContext>
+GLContextProviderCGL::CreateForCompositorWidget(CompositorWidget* aCompositorWidget, bool aForceAccelerated)
+{
+ return CreateForWindow(aCompositorWidget->RealWidget(), aForceAccelerated);
+}
+
+already_AddRefed<GLContext>
+GLContextProviderCGL::CreateForWindow(nsIWidget* aWidget, bool aForceAccelerated)
+{
+ if (!sCGLLibrary.EnsureInitialized()) {
+ return nullptr;
+ }
+
+#ifdef EMULATE_VM
+ if (aForceAccelerated) {
+ return nullptr;
+ }
+#endif
+
+ const NSOpenGLPixelFormatAttribute* attribs;
+ if (sCGLLibrary.UseDoubleBufferedWindows()) {
+ attribs = aForceAccelerated ? kAttribs_doubleBuffered_accel : kAttribs_doubleBuffered;
+ } else {
+ attribs = aForceAccelerated ? kAttribs_singleBuffered_accel : kAttribs_singleBuffered;
+ }
+ NSOpenGLContext* context = CreateWithFormat(attribs);
+ if (!context) {
+ return nullptr;
+ }
+
+ // make the context transparent
+ GLint opaque = 0;
+ [context setValues:&opaque forParameter:NSOpenGLCPSurfaceOpacity];
+
+ SurfaceCaps caps = SurfaceCaps::ForRGBA();
+ ContextProfile profile = ContextProfile::OpenGLCompatibility;
+ RefPtr<GLContextCGL> glContext = new GLContextCGL(CreateContextFlags::NONE, caps,
+ context, false, profile);
+
+ if (!glContext->Init()) {
+ glContext = nullptr;
+ [context release];
+ return nullptr;
+ }
+
+ return glContext.forget();
+}
+
+static already_AddRefed<GLContextCGL>
+CreateOffscreenFBOContext(CreateContextFlags flags)
+{
+ if (!sCGLLibrary.EnsureInitialized()) {
+ return nullptr;
+ }
+
+ ContextProfile profile;
+ NSOpenGLContext* context = nullptr;
+
+ if (!(flags & CreateContextFlags::REQUIRE_COMPAT_PROFILE)) {
+ profile = ContextProfile::OpenGLCore;
+ context = CreateWithFormat(kAttribs_offscreen_coreProfile);
+ }
+ if (!context) {
+ profile = ContextProfile::OpenGLCompatibility;
+
+ if (flags & CreateContextFlags::ALLOW_OFFLINE_RENDERER) {
+ if (gfxPrefs::RequireHardwareGL())
+ context = CreateWithFormat(kAttribs_singleBuffered);
+ else
+ context = CreateWithFormat(kAttribs_offscreen_allow_offline);
+
+ } else {
+ if (gfxPrefs::RequireHardwareGL())
+ context = CreateWithFormat(kAttribs_offscreen_accel);
+ else
+ context = CreateWithFormat(kAttribs_offscreen);
+ }
+ }
+ if (!context) {
+ NS_WARNING("Failed to create NSOpenGLContext.");
+ return nullptr;
+ }
+
+ SurfaceCaps dummyCaps = SurfaceCaps::Any();
+ RefPtr<GLContextCGL> glContext = new GLContextCGL(flags, dummyCaps, context, true,
+ profile);
+
+ if (gfxPrefs::GLMultithreaded()) {
+ CGLEnable(glContext->GetCGLContext(), kCGLCEMPEngine);
+ }
+ return glContext.forget();
+}
+
+already_AddRefed<GLContext>
+GLContextProviderCGL::CreateHeadless(CreateContextFlags flags,
+ nsACString* const out_failureId)
+{
+ RefPtr<GLContextCGL> gl;
+ gl = CreateOffscreenFBOContext(flags);
+ if (!gl) {
+ *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_CGL_FBO");
+ return nullptr;
+ }
+
+ if (!gl->Init()) {
+ *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_CGL_INIT");
+ NS_WARNING("Failed during Init.");
+ return nullptr;
+ }
+
+ return gl.forget();
+}
+
+already_AddRefed<GLContext>
+GLContextProviderCGL::CreateOffscreen(const IntSize& size,
+ const SurfaceCaps& minCaps,
+ CreateContextFlags flags,
+ nsACString* const out_failureId)
+{
+ RefPtr<GLContext> gl = CreateHeadless(flags, out_failureId);
+ if (!gl) {
+ return nullptr;
+ }
+
+ if (!gl->InitOffscreen(size, minCaps)) {
+ *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_CGL_INIT");
+ return nullptr;
+ }
+
+ return gl.forget();
+}
+
+static RefPtr<GLContext> gGlobalContext;
+
+GLContext*
+GLContextProviderCGL::GetGlobalContext()
+{
+ static bool triedToCreateContext = false;
+ if (!triedToCreateContext) {
+ triedToCreateContext = true;
+
+ MOZ_RELEASE_ASSERT(!gGlobalContext);
+ nsCString discardFailureId;
+ RefPtr<GLContext> temp = CreateHeadless(CreateContextFlags::NONE,
+ &discardFailureId);
+ gGlobalContext = temp;
+
+ if (!gGlobalContext) {
+ NS_WARNING("Couldn't init gGlobalContext.");
+ }
+ }
+
+ return gGlobalContext;
+}
+
+void
+GLContextProviderCGL::Shutdown()
+{
+ gGlobalContext = nullptr;
+}
+
+} /* namespace gl */
+} /* namespace mozilla */
diff --git a/gfx/gl/GLContextProviderEAGL.mm b/gfx/gl/GLContextProviderEAGL.mm
new file mode 100644
index 0000000000..784a3e29e0
--- /dev/null
+++ b/gfx/gl/GLContextProviderEAGL.mm
@@ -0,0 +1,281 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "GLContextProvider.h"
+#include "GLContextEAGL.h"
+#include "nsDebug.h"
+#include "nsIWidget.h"
+#include "gfxPrefs.h"
+#include "gfxFailure.h"
+#include "prenv.h"
+#include "mozilla/Preferences.h"
+#include "mozilla/widget/CompositorWidget.h"
+#include "GeckoProfiler.h"
+
+#import <UIKit/UIKit.h>
+
+namespace mozilla {
+namespace gl {
+
+using namespace mozilla::widget;
+
+GLContextEAGL::GLContextEAGL(CreateContextFlags flags, const SurfaceCaps& caps,
+ EAGLContext* context, GLContext* sharedContext,
+ bool isOffscreen, ContextProfile profile)
+ : GLContext(flags, caps, sharedContext, isOffscreen)
+ , mContext(context)
+ , mBackbufferRB(0)
+ , mBackbufferFB(0)
+ , mLayer(nil)
+{
+ SetProfileVersion(ContextProfile::OpenGLES,
+ [context API] == kEAGLRenderingAPIOpenGLES3 ? 300 : 200);
+}
+
+GLContextEAGL::~GLContextEAGL()
+{
+ MakeCurrent();
+
+ if (mBackbufferFB) {
+ fDeleteFramebuffers(1, &mBackbufferFB);
+ }
+
+ if (mBackbufferRB) {
+ fDeleteRenderbuffers(1, &mBackbufferRB);
+ }
+
+ MarkDestroyed();
+
+ if (mLayer) {
+ mLayer = nil;
+ }
+
+ if (mContext) {
+ [EAGLContext setCurrentContext:nil];
+ [mContext release];
+ }
+}
+
+bool
+GLContextEAGL::Init()
+{
+ if (!InitWithPrefix("gl", true))
+ return false;
+
+ return true;
+}
+
+bool
+GLContextEAGL::AttachToWindow(nsIWidget* aWidget)
+{
+ // This should only be called once
+ MOZ_ASSERT(!mBackbufferFB && !mBackbufferRB);
+
+ UIView* view =
+ reinterpret_cast<UIView*>(aWidget->GetNativeData(NS_NATIVE_WIDGET));
+
+ if (!view) {
+ MOZ_CRASH("no view!");
+ }
+
+ mLayer = [view layer];
+
+ fGenFramebuffers(1, &mBackbufferFB);
+ return RecreateRB();
+}
+
+bool
+GLContextEAGL::RecreateRB()
+{
+ MakeCurrent();
+
+ CAEAGLLayer* layer = (CAEAGLLayer*)mLayer;
+
+ if (mBackbufferRB) {
+ // It doesn't seem to be enough to just call renderbufferStorage: below,
+ // we apparently have to recreate the RB.
+ fDeleteRenderbuffers(1, &mBackbufferRB);
+ mBackbufferRB = 0;
+ }
+
+ fGenRenderbuffers(1, &mBackbufferRB);
+ fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, mBackbufferRB);
+
+ [mContext renderbufferStorage:LOCAL_GL_RENDERBUFFER
+ fromDrawable:layer];
+
+ fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mBackbufferFB);
+ fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0,
+ LOCAL_GL_RENDERBUFFER, mBackbufferRB);
+
+ return LOCAL_GL_FRAMEBUFFER_COMPLETE == fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
+}
+
+bool
+GLContextEAGL::MakeCurrentImpl(bool aForce)
+{
+ if (!aForce && [EAGLContext currentContext] == mContext) {
+ return true;
+ }
+
+ if (mContext) {
+ if(![EAGLContext setCurrentContext:mContext]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool
+GLContextEAGL::IsCurrent() {
+ return [EAGLContext currentContext] == mContext;
+}
+
+bool
+GLContextEAGL::SetupLookupFunction()
+{
+ return false;
+}
+
+bool
+GLContextEAGL::IsDoubleBuffered() const
+{
+ return true;
+}
+
+bool
+GLContextEAGL::SwapBuffers()
+{
+ PROFILER_LABEL("GLContextEAGL", "SwapBuffers",
+ js::ProfileEntry::Category::GRAPHICS);
+
+ [mContext presentRenderbuffer:LOCAL_GL_RENDERBUFFER];
+ return true;
+}
+
+
+already_AddRefed<GLContext>
+GLContextProviderEAGL::CreateWrappingExisting(void*, void*)
+{
+ return nullptr;
+}
+
+static GLContextEAGL*
+GetGlobalContextEAGL()
+{
+ return static_cast<GLContextEAGL*>(GLContextProviderEAGL::GetGlobalContext());
+}
+
+static already_AddRefed<GLContext>
+CreateEAGLContext(CreateContextFlags flags, bool aOffscreen, GLContextEAGL* sharedContext)
+{
+ EAGLRenderingAPI apis[] = { kEAGLRenderingAPIOpenGLES3, kEAGLRenderingAPIOpenGLES2 };
+
+ // Try to create a GLES3 context if we can, otherwise fall back to GLES2
+ EAGLContext* context = nullptr;
+ for (EAGLRenderingAPI api : apis) {
+ if (sharedContext) {
+ context = [[EAGLContext alloc] initWithAPI:api
+ sharegroup:sharedContext->GetEAGLContext().sharegroup];
+ } else {
+ context = [[EAGLContext alloc] initWithAPI:api];
+ }
+
+ if (context) {
+ break;
+ }
+ }
+
+ if (!context) {
+ return nullptr;
+ }
+
+ SurfaceCaps caps = SurfaceCaps::ForRGBA();
+ ContextProfile profile = ContextProfile::OpenGLES;
+ RefPtr<GLContextEAGL> glContext = new GLContextEAGL(flags, caps, context,
+ sharedContext,
+ aOffscreen,
+ profile);
+
+ if (!glContext->Init()) {
+ glContext = nullptr;
+ return nullptr;
+ }
+
+ return glContext.forget();
+}
+
+already_AddRefed<GLContext>
+GLContextProviderEAGL::CreateForCompositorWidget(CompositorWidget* aCompositorWidget, bool aForceAccelerated)
+{
+ return CreateForWindow(aCompositorWidget->RealWidget(), aForceAccelerated);
+}
+
+already_AddRefed<GLContext>
+GLContextProviderEAGL::CreateForWindow(nsIWidget* aWidget, bool aForceAccelerated)
+{
+ RefPtr<GLContext> glContext = CreateEAGLContext(CreateContextFlags::NONE, false,
+ GetGlobalContextEAGL());
+ if (!glContext) {
+ return nullptr;
+ }
+
+ if (!GLContextEAGL::Cast(glContext)->AttachToWindow(aWidget)) {
+ return nullptr;
+ }
+
+ return glContext.forget();
+}
+
+already_AddRefed<GLContext>
+GLContextProviderEAGL::CreateHeadless(CreateContextFlags flags,
+ nsACString* const out_failureId)
+{
+ return CreateEAGLContext(flags, true, GetGlobalContextEAGL());
+}
+
+already_AddRefed<GLContext>
+GLContextProviderEAGL::CreateOffscreen(const mozilla::gfx::IntSize& size,
+ const SurfaceCaps& caps,
+ CreateContextFlags flags,
+ nsACString* const out_failureId)
+{
+ RefPtr<GLContext> glContext = CreateHeadless(flags, out_failureId);
+ if (!glContext->InitOffscreen(size, caps)) {
+ return nullptr;
+ }
+
+ return glContext.forget();
+}
+
+static RefPtr<GLContext> gGlobalContext;
+
+GLContext*
+GLContextProviderEAGL::GetGlobalContext()
+{
+ static bool triedToCreateContext = false;
+ if (!triedToCreateContext) {
+ triedToCreateContext = true;
+
+ MOZ_RELEASE_ASSERT(!gGlobalContext, "GFX: Global GL context already initialized.");
+ RefPtr<GLContext> temp = CreateHeadless(CreateContextFlags::NONE);
+ gGlobalContext = temp;
+
+ if (!gGlobalContext) {
+ MOZ_CRASH("Failed to create global context");
+ }
+ }
+
+ return gGlobalContext;
+}
+
+void
+GLContextProviderEAGL::Shutdown()
+{
+ gGlobalContext = nullptr;
+}
+
+} /* namespace gl */
+} /* namespace mozilla */
diff --git a/gfx/gl/GLContextProviderEGL.cpp b/gfx/gl/GLContextProviderEGL.cpp
new file mode 100644
index 0000000000..ca972e0f3c
--- /dev/null
+++ b/gfx/gl/GLContextProviderEGL.cpp
@@ -0,0 +1,1025 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#if defined(MOZ_WIDGET_GTK)
+ #include <gdk/gdkx.h>
+ // we're using default display for now
+ #define GET_NATIVE_WINDOW(aWidget) ((EGLNativeWindowType)GDK_WINDOW_XID((GdkWindow*)aWidget->GetNativeData(NS_NATIVE_WINDOW)))
+#else
+ #define GET_NATIVE_WINDOW(aWidget) ((EGLNativeWindowType)aWidget->GetNativeData(NS_NATIVE_WINDOW))
+#endif
+
+#ifdef MOZ_WIDGET_ANDROID
+ #define GET_JAVA_SURFACE(aWidget) (aWidget->GetNativeData(NS_JAVA_SURFACE))
+#endif
+
+#if defined(XP_UNIX)
+ #ifdef MOZ_WIDGET_ANDROID
+ #include <android/native_window.h>
+ #include <android/native_window_jni.h>
+ #endif
+
+ #ifdef ANDROID
+ #include <android/log.h>
+ #define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk" , ## args)
+ #endif
+
+ #define GLES2_LIB "libGLESv2.so"
+ #define GLES2_LIB2 "libGLESv2.so.2"
+
+#elif defined(XP_WIN)
+ #include "nsIFile.h"
+
+ #define GLES2_LIB "libGLESv2.dll"
+
+ #ifndef WIN32_LEAN_AND_MEAN
+ #define WIN32_LEAN_AND_MEAN 1
+ #endif
+
+ #include <windows.h>
+
+ // a little helper
+ class AutoDestroyHWND {
+ public:
+ AutoDestroyHWND(HWND aWnd = nullptr)
+ : mWnd(aWnd)
+ {
+ }
+
+ ~AutoDestroyHWND() {
+ if (mWnd) {
+ ::DestroyWindow(mWnd);
+ }
+ }
+
+ operator HWND() {
+ return mWnd;
+ }
+
+ HWND forget() {
+ HWND w = mWnd;
+ mWnd = nullptr;
+ return w;
+ }
+
+ HWND operator=(HWND aWnd) {
+ if (mWnd && mWnd != aWnd) {
+ ::DestroyWindow(mWnd);
+ }
+ mWnd = aWnd;
+ return mWnd;
+ }
+
+ HWND mWnd;
+ };
+#else
+ #error "Platform not recognized"
+#endif
+
+#include "gfxASurface.h"
+#include "gfxCrashReporterUtils.h"
+#include "gfxFailure.h"
+#include "gfxPlatform.h"
+#include "gfxUtils.h"
+#include "GLBlitHelper.h"
+#include "GLContextEGL.h"
+#include "GLContextProvider.h"
+#include "GLLibraryEGL.h"
+#include "mozilla/ArrayUtils.h"
+#include "mozilla/Preferences.h"
+#include "mozilla/widget/CompositorWidget.h"
+#include "nsDebug.h"
+#include "nsIWidget.h"
+#include "nsThreadUtils.h"
+#include "ScopedGLHelpers.h"
+#include "TextureImageEGL.h"
+
+using namespace mozilla::gfx;
+
+namespace mozilla {
+namespace gl {
+
+using namespace mozilla::widget;
+
+#define ADD_ATTR_2(_array, _k, _v) do { \
+ (_array).AppendElement(_k); \
+ (_array).AppendElement(_v); \
+} while (0)
+
+#define ADD_ATTR_1(_array, _k) do { \
+ (_array).AppendElement(_k); \
+} while (0)
+
+static bool
+CreateConfig(EGLConfig* aConfig, nsIWidget* aWidget);
+
+// append three zeros at the end of attribs list to work around
+// EGL implementation bugs that iterate until they find 0, instead of
+// EGL_NONE. See bug 948406.
+#define EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS \
+ LOCAL_EGL_NONE, 0, 0, 0
+
+static EGLint gTerminationAttribs[] = {
+ EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS
+};
+
+static int
+next_power_of_two(int v)
+{
+ v--;
+ v |= v >> 1;
+ v |= v >> 2;
+ v |= v >> 4;
+ v |= v >> 8;
+ v |= v >> 16;
+ v++;
+
+ return v;
+}
+
+static bool
+is_power_of_two(int v)
+{
+ NS_ASSERTION(v >= 0, "bad value");
+
+ if (v == 0)
+ return true;
+
+ return (v & (v-1)) == 0;
+}
+
+static void
+DestroySurface(EGLSurface oldSurface) {
+ if (oldSurface != EGL_NO_SURFACE) {
+ sEGLLibrary.fMakeCurrent(EGL_DISPLAY(),
+ EGL_NO_SURFACE, EGL_NO_SURFACE,
+ EGL_NO_CONTEXT);
+ sEGLLibrary.fDestroySurface(EGL_DISPLAY(), oldSurface);
+ }
+}
+
+static EGLSurface
+CreateSurfaceForWindow(nsIWidget* widget, const EGLConfig& config) {
+ EGLSurface newSurface = nullptr;
+
+ MOZ_ASSERT(widget);
+#ifdef MOZ_WIDGET_ANDROID
+ void* javaSurface = GET_JAVA_SURFACE(widget);
+ if (!javaSurface) {
+ MOZ_CRASH("GFX: Failed to get Java surface.\n");
+ }
+ JNIEnv* const env = jni::GetEnvForThread();
+ ANativeWindow* const nativeWindow = ANativeWindow_fromSurface(
+ env, reinterpret_cast<jobject>(javaSurface));
+ newSurface = sEGLLibrary.fCreateWindowSurface(
+ sEGLLibrary.fGetDisplay(EGL_DEFAULT_DISPLAY),
+ config, nativeWindow, 0);
+ ANativeWindow_release(nativeWindow);
+#else
+ newSurface = sEGLLibrary.fCreateWindowSurface(EGL_DISPLAY(), config,
+ GET_NATIVE_WINDOW(widget), 0);
+#endif
+ return newSurface;
+}
+
+GLContextEGL::GLContextEGL(CreateContextFlags flags, const SurfaceCaps& caps,
+ GLContext* shareContext, bool isOffscreen, EGLConfig config,
+ EGLSurface surface, EGLContext context)
+ : GLContext(flags, caps, shareContext, isOffscreen)
+ , mConfig(config)
+ , mSurface(surface)
+ , mContext(context)
+ , mSurfaceOverride(EGL_NO_SURFACE)
+ , mThebesSurface(nullptr)
+ , mBound(false)
+ , mIsPBuffer(false)
+ , mIsDoubleBuffered(false)
+ , mCanBindToTexture(false)
+ , mShareWithEGLImage(false)
+ , mOwnsContext(true)
+{
+ // any EGL contexts will always be GLESv2
+ SetProfileVersion(ContextProfile::OpenGLES, 200);
+
+#ifdef DEBUG
+ printf_stderr("Initializing context %p surface %p on display %p\n", mContext, mSurface, EGL_DISPLAY());
+#endif
+}
+
+GLContextEGL::~GLContextEGL()
+{
+ MarkDestroyed();
+
+ // Wrapped context should not destroy eglContext/Surface
+ if (!mOwnsContext) {
+ return;
+ }
+
+#ifdef DEBUG
+ printf_stderr("Destroying context %p surface %p on display %p\n", mContext, mSurface, EGL_DISPLAY());
+#endif
+
+ sEGLLibrary.fDestroyContext(EGL_DISPLAY(), mContext);
+ sEGLLibrary.UnsetCachedCurrentContext();
+
+ mozilla::gl::DestroySurface(mSurface);
+}
+
+bool
+GLContextEGL::Init()
+{
+#if defined(ANDROID)
+ // We can't use LoadApitraceLibrary here because the GLContext
+ // expects its own handle to the GL library
+ if (!OpenLibrary(APITRACE_LIB))
+#endif
+ if (!OpenLibrary(GLES2_LIB)) {
+#if defined(XP_UNIX)
+ if (!OpenLibrary(GLES2_LIB2)) {
+ NS_WARNING("Couldn't load GLES2 LIB.");
+ return false;
+ }
+#endif
+ }
+
+ SetupLookupFunction();
+ if (!InitWithPrefix("gl", true))
+ return false;
+
+ bool current = MakeCurrent();
+ if (!current) {
+ gfx::LogFailure(NS_LITERAL_CSTRING(
+ "Couldn't get device attachments for device."));
+ return false;
+ }
+
+ static_assert(sizeof(GLint) >= sizeof(int32_t), "GLint is smaller than int32_t");
+ mMaxTextureImageSize = INT32_MAX;
+
+ mShareWithEGLImage = sEGLLibrary.HasKHRImageBase() &&
+ sEGLLibrary.HasKHRImageTexture2D() &&
+ IsExtensionSupported(OES_EGL_image);
+
+ return true;
+}
+
+bool
+GLContextEGL::BindTexImage()
+{
+ if (!mSurface)
+ return false;
+
+ if (mBound && !ReleaseTexImage())
+ return false;
+
+ EGLBoolean success = sEGLLibrary.fBindTexImage(EGL_DISPLAY(),
+ (EGLSurface)mSurface, LOCAL_EGL_BACK_BUFFER);
+ if (success == LOCAL_EGL_FALSE)
+ return false;
+
+ mBound = true;
+ return true;
+}
+
+bool
+GLContextEGL::ReleaseTexImage()
+{
+ if (!mBound)
+ return true;
+
+ if (!mSurface)
+ return false;
+
+ EGLBoolean success;
+ success = sEGLLibrary.fReleaseTexImage(EGL_DISPLAY(),
+ (EGLSurface)mSurface,
+ LOCAL_EGL_BACK_BUFFER);
+ if (success == LOCAL_EGL_FALSE)
+ return false;
+
+ mBound = false;
+ return true;
+}
+
+void
+GLContextEGL::SetEGLSurfaceOverride(EGLSurface surf) {
+ if (Screen()) {
+ /* Blit `draw` to `read` if we need to, before we potentially juggle
+ * `read` around. If we don't, we might attach a different `read`,
+ * and *then* hit AssureBlitted, which will blit a dirty `draw` onto
+ * the wrong `read`!
+ */
+ Screen()->AssureBlitted();
+ }
+
+ mSurfaceOverride = surf;
+ DebugOnly<bool> ok = MakeCurrent(true);
+ MOZ_ASSERT(ok);
+}
+
+bool
+GLContextEGL::MakeCurrentImpl(bool aForce) {
+ bool succeeded = true;
+
+ // Assume that EGL has the same problem as WGL does,
+ // where MakeCurrent with an already-current context is
+ // still expensive.
+ bool hasDifferentContext = false;
+ if (sEGLLibrary.CachedCurrentContext() != mContext) {
+ // even if the cached context doesn't match the current one
+ // might still
+ if (sEGLLibrary.fGetCurrentContext() != mContext) {
+ hasDifferentContext = true;
+ } else {
+ sEGLLibrary.SetCachedCurrentContext(mContext);
+ }
+ }
+
+ if (aForce || hasDifferentContext) {
+ EGLSurface surface = mSurfaceOverride != EGL_NO_SURFACE
+ ? mSurfaceOverride
+ : mSurface;
+ if (surface == EGL_NO_SURFACE) {
+ return false;
+ }
+ succeeded = sEGLLibrary.fMakeCurrent(EGL_DISPLAY(),
+ surface, surface,
+ mContext);
+ if (!succeeded) {
+ int eglError = sEGLLibrary.fGetError();
+ if (eglError == LOCAL_EGL_CONTEXT_LOST) {
+ mContextLost = true;
+ NS_WARNING("EGL context has been lost.");
+ } else {
+ NS_WARNING("Failed to make GL context current!");
+#ifdef DEBUG
+ printf_stderr("EGL Error: 0x%04x\n", eglError);
+#endif
+ }
+ } else {
+ sEGLLibrary.SetCachedCurrentContext(mContext);
+ }
+ } else {
+ MOZ_ASSERT(sEGLLibrary.CachedCurrentContextMatches());
+ }
+
+ return succeeded;
+}
+
+bool
+GLContextEGL::IsCurrent() {
+ return sEGLLibrary.fGetCurrentContext() == mContext;
+}
+
+bool
+GLContextEGL::RenewSurface(nsIWidget* aWidget) {
+ if (!mOwnsContext) {
+ return false;
+ }
+ // unconditionally release the surface and create a new one. Don't try to optimize this away.
+ // If we get here, then by definition we know that we want to get a new surface.
+ ReleaseSurface();
+ mSurface = mozilla::gl::CreateSurfaceForWindow(aWidget, mConfig);
+ if (!mSurface) {
+ return false;
+ }
+ return MakeCurrent(true);
+}
+
+void
+GLContextEGL::ReleaseSurface() {
+ if (mOwnsContext) {
+ mozilla::gl::DestroySurface(mSurface);
+ }
+ if (mSurface == mSurfaceOverride) {
+ mSurfaceOverride = EGL_NO_SURFACE;
+ }
+ mSurface = EGL_NO_SURFACE;
+}
+
+bool
+GLContextEGL::SetupLookupFunction()
+{
+ mLookupFunc = (PlatformLookupFunction)sEGLLibrary.mSymbols.fGetProcAddress;
+ return true;
+}
+
+bool
+GLContextEGL::SwapBuffers()
+{
+ EGLSurface surface = mSurfaceOverride != EGL_NO_SURFACE
+ ? mSurfaceOverride
+ : mSurface;
+ if (surface) {
+ return sEGLLibrary.fSwapBuffers(EGL_DISPLAY(), surface);
+ } else {
+ return false;
+ }
+}
+
+// hold a reference to the given surface
+// for the lifetime of this context.
+void
+GLContextEGL::HoldSurface(gfxASurface* aSurf) {
+ mThebesSurface = aSurf;
+}
+
+/* static */ EGLSurface
+GLContextEGL::CreateSurfaceForWindow(nsIWidget* aWidget)
+{
+ nsCString discardFailureId;
+ if (!sEGLLibrary.EnsureInitialized(false, &discardFailureId)) {
+ MOZ_CRASH("GFX: Failed to load EGL library!\n");
+ return nullptr;
+ }
+
+ EGLConfig config;
+ if (!CreateConfig(&config, aWidget)) {
+ MOZ_CRASH("GFX: Failed to create EGLConfig!\n");
+ return nullptr;
+ }
+
+ EGLSurface surface = mozilla::gl::CreateSurfaceForWindow(aWidget, config);
+ if (!surface) {
+ MOZ_CRASH("GFX: Failed to create EGLSurface for window!\n");
+ return nullptr;
+ }
+ return surface;
+}
+
+/* static */ void
+GLContextEGL::DestroySurface(EGLSurface aSurface)
+{
+ if (aSurface != EGL_NO_SURFACE) {
+ sEGLLibrary.fDestroySurface(EGL_DISPLAY(), aSurface);
+ }
+}
+
+already_AddRefed<GLContextEGL>
+GLContextEGL::CreateGLContext(CreateContextFlags flags,
+ const SurfaceCaps& caps,
+ GLContextEGL* shareContext,
+ bool isOffscreen,
+ EGLConfig config,
+ EGLSurface surface,
+ nsACString* const out_failureId)
+{
+ if (sEGLLibrary.fBindAPI(LOCAL_EGL_OPENGL_ES_API) == LOCAL_EGL_FALSE) {
+ *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_EGL_ES");
+ NS_WARNING("Failed to bind API to GLES!");
+ return nullptr;
+ }
+
+ EGLContext eglShareContext = shareContext ? shareContext->mContext
+ : EGL_NO_CONTEXT;
+
+ nsTArray<EGLint> contextAttribs;
+
+ contextAttribs.AppendElement(LOCAL_EGL_CONTEXT_CLIENT_VERSION);
+ if (flags & CreateContextFlags::PREFER_ES3)
+ contextAttribs.AppendElement(3);
+ else
+ contextAttribs.AppendElement(2);
+
+ if (sEGLLibrary.HasRobustness()) {
+// contextAttribs.AppendElement(LOCAL_EGL_CONTEXT_ROBUST_ACCESS_EXT);
+// contextAttribs.AppendElement(LOCAL_EGL_TRUE);
+ }
+
+ for (size_t i = 0; i < MOZ_ARRAY_LENGTH(gTerminationAttribs); i++) {
+ contextAttribs.AppendElement(gTerminationAttribs[i]);
+ }
+
+ EGLContext context = sEGLLibrary.fCreateContext(EGL_DISPLAY(),
+ config,
+ eglShareContext,
+ contextAttribs.Elements());
+ if (!context && shareContext) {
+ shareContext = nullptr;
+ context = sEGLLibrary.fCreateContext(EGL_DISPLAY(), config, EGL_NO_CONTEXT,
+ contextAttribs.Elements());
+ }
+ if (!context) {
+ *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_EGL_CREATE");
+ NS_WARNING("Failed to create EGLContext!");
+ return nullptr;
+ }
+
+ RefPtr<GLContextEGL> glContext = new GLContextEGL(flags, caps, shareContext,
+ isOffscreen, config, surface,
+ context);
+
+ if (!glContext->Init()) {
+ *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_EGL_INIT");
+ return nullptr;
+ }
+
+ return glContext.forget();
+}
+
+EGLSurface
+GLContextEGL::CreatePBufferSurfaceTryingPowerOfTwo(EGLConfig config,
+ EGLenum bindToTextureFormat,
+ mozilla::gfx::IntSize& pbsize)
+{
+ nsTArray<EGLint> pbattrs(16);
+ EGLSurface surface = nullptr;
+
+TRY_AGAIN_POWER_OF_TWO:
+ pbattrs.Clear();
+ pbattrs.AppendElement(LOCAL_EGL_WIDTH); pbattrs.AppendElement(pbsize.width);
+ pbattrs.AppendElement(LOCAL_EGL_HEIGHT); pbattrs.AppendElement(pbsize.height);
+
+ if (bindToTextureFormat != LOCAL_EGL_NONE) {
+ pbattrs.AppendElement(LOCAL_EGL_TEXTURE_TARGET);
+ pbattrs.AppendElement(LOCAL_EGL_TEXTURE_2D);
+
+ pbattrs.AppendElement(LOCAL_EGL_TEXTURE_FORMAT);
+ pbattrs.AppendElement(bindToTextureFormat);
+ }
+
+ for (size_t i = 0; i < MOZ_ARRAY_LENGTH(gTerminationAttribs); i++) {
+ pbattrs.AppendElement(gTerminationAttribs[i]);
+ }
+
+ surface = sEGLLibrary.fCreatePbufferSurface(EGL_DISPLAY(), config, &pbattrs[0]);
+ if (!surface) {
+ if (!is_power_of_two(pbsize.width) ||
+ !is_power_of_two(pbsize.height))
+ {
+ if (!is_power_of_two(pbsize.width))
+ pbsize.width = next_power_of_two(pbsize.width);
+ if (!is_power_of_two(pbsize.height))
+ pbsize.height = next_power_of_two(pbsize.height);
+
+ NS_WARNING("Failed to create pbuffer, trying power of two dims");
+ goto TRY_AGAIN_POWER_OF_TWO;
+ }
+
+ NS_WARNING("Failed to create pbuffer surface");
+ return nullptr;
+ }
+
+ return surface;
+}
+
+static const EGLint kEGLConfigAttribsOffscreenPBuffer[] = {
+ LOCAL_EGL_SURFACE_TYPE, LOCAL_EGL_PBUFFER_BIT,
+ LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
+ // Old versions of llvmpipe seem to need this to properly create the pbuffer (bug 981856)
+ LOCAL_EGL_RED_SIZE, 8,
+ LOCAL_EGL_GREEN_SIZE, 8,
+ LOCAL_EGL_BLUE_SIZE, 8,
+ LOCAL_EGL_ALPHA_SIZE, 0,
+ EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS
+};
+
+static const EGLint kEGLConfigAttribsRGB16[] = {
+ LOCAL_EGL_SURFACE_TYPE, LOCAL_EGL_WINDOW_BIT,
+ LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
+ LOCAL_EGL_RED_SIZE, 5,
+ LOCAL_EGL_GREEN_SIZE, 6,
+ LOCAL_EGL_BLUE_SIZE, 5,
+ LOCAL_EGL_ALPHA_SIZE, 0,
+ EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS
+};
+
+static const EGLint kEGLConfigAttribsRGB24[] = {
+ LOCAL_EGL_SURFACE_TYPE, LOCAL_EGL_WINDOW_BIT,
+ LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
+ LOCAL_EGL_RED_SIZE, 8,
+ LOCAL_EGL_GREEN_SIZE, 8,
+ LOCAL_EGL_BLUE_SIZE, 8,
+ LOCAL_EGL_ALPHA_SIZE, 0,
+ EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS
+};
+
+static const EGLint kEGLConfigAttribsRGBA32[] = {
+ LOCAL_EGL_SURFACE_TYPE, LOCAL_EGL_WINDOW_BIT,
+ LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
+ LOCAL_EGL_RED_SIZE, 8,
+ LOCAL_EGL_GREEN_SIZE, 8,
+ LOCAL_EGL_BLUE_SIZE, 8,
+ LOCAL_EGL_ALPHA_SIZE, 8,
+ EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS
+};
+
+static bool
+CreateConfig(EGLConfig* aConfig, int32_t depth, nsIWidget* aWidget)
+{
+ EGLConfig configs[64];
+ const EGLint* attribs;
+ EGLint ncfg = ArrayLength(configs);
+
+ switch (depth) {
+ case 16:
+ attribs = kEGLConfigAttribsRGB16;
+ break;
+ case 24:
+ attribs = kEGLConfigAttribsRGB24;
+ break;
+ case 32:
+ attribs = kEGLConfigAttribsRGBA32;
+ break;
+ default:
+ NS_ERROR("Unknown pixel depth");
+ return false;
+ }
+
+ if (!sEGLLibrary.fChooseConfig(EGL_DISPLAY(), attribs,
+ configs, ncfg, &ncfg) ||
+ ncfg < 1) {
+ return false;
+ }
+
+ for (int j = 0; j < ncfg; ++j) {
+ EGLConfig config = configs[j];
+ EGLint r, g, b, a;
+ if (sEGLLibrary.fGetConfigAttrib(EGL_DISPLAY(), config,
+ LOCAL_EGL_RED_SIZE, &r) &&
+ sEGLLibrary.fGetConfigAttrib(EGL_DISPLAY(), config,
+ LOCAL_EGL_GREEN_SIZE, &g) &&
+ sEGLLibrary.fGetConfigAttrib(EGL_DISPLAY(), config,
+ LOCAL_EGL_BLUE_SIZE, &b) &&
+ sEGLLibrary.fGetConfigAttrib(EGL_DISPLAY(), config,
+ LOCAL_EGL_ALPHA_SIZE, &a) &&
+ ((depth == 16 && r == 5 && g == 6 && b == 5) ||
+ (depth == 24 && r == 8 && g == 8 && b == 8) ||
+ (depth == 32 && r == 8 && g == 8 && b == 8 && a == 8)))
+ {
+ *aConfig = config;
+ return true;
+ }
+ }
+ return false;
+}
+
+// Return true if a suitable EGLConfig was found and pass it out
+// through aConfig. Return false otherwise.
+//
+// NB: It's entirely legal for the returned EGLConfig to be valid yet
+// have the value null.
+static bool
+CreateConfig(EGLConfig* aConfig, nsIWidget* aWidget)
+{
+ int32_t depth = gfxPlatform::GetPlatform()->GetScreenDepth();
+ if (!CreateConfig(aConfig, depth, aWidget)) {
+#ifdef MOZ_WIDGET_ANDROID
+ // Bug 736005
+ // Android doesn't always support 16 bit so also try 24 bit
+ if (depth == 16) {
+ return CreateConfig(aConfig, 24, aWidget);
+ }
+ // Bug 970096
+ // Some devices that have 24 bit screens only support 16 bit OpenGL?
+ if (depth == 24) {
+ return CreateConfig(aConfig, 16, aWidget);
+ }
+#endif
+ return false;
+ } else {
+ return true;
+ }
+}
+
+already_AddRefed<GLContext>
+GLContextProviderEGL::CreateWrappingExisting(void* aContext, void* aSurface)
+{
+ nsCString discardFailureId;
+ if (!sEGLLibrary.EnsureInitialized(false, &discardFailureId)) {
+ MOZ_CRASH("GFX: Failed to load EGL library 2!\n");
+ return nullptr;
+ }
+
+ if (!aContext || !aSurface)
+ return nullptr;
+
+ SurfaceCaps caps = SurfaceCaps::Any();
+ EGLConfig config = EGL_NO_CONFIG;
+ RefPtr<GLContextEGL> gl = new GLContextEGL(CreateContextFlags::NONE, caps, nullptr,
+ false, config, (EGLSurface)aSurface,
+ (EGLContext)aContext);
+ gl->SetIsDoubleBuffered(true);
+ gl->mOwnsContext = false;
+
+ return gl.forget();
+}
+
+already_AddRefed<GLContext>
+GLContextProviderEGL::CreateForCompositorWidget(CompositorWidget* aCompositorWidget, bool aForceAccelerated)
+{
+ return CreateForWindow(aCompositorWidget->RealWidget(), aForceAccelerated);
+}
+
+already_AddRefed<GLContext>
+GLContextProviderEGL::CreateForWindow(nsIWidget* aWidget, bool aForceAccelerated)
+{
+ nsCString discardFailureId;
+ if (!sEGLLibrary.EnsureInitialized(false, &discardFailureId)) {
+ MOZ_CRASH("GFX: Failed to load EGL library 3!\n");
+ return nullptr;
+ }
+
+ bool doubleBuffered = true;
+
+ EGLConfig config;
+ if (!CreateConfig(&config, aWidget)) {
+ MOZ_CRASH("GFX: Failed to create EGLConfig!\n");
+ return nullptr;
+ }
+
+ EGLSurface surface = mozilla::gl::CreateSurfaceForWindow(aWidget, config);
+ if (!surface) {
+ MOZ_CRASH("GFX: Failed to create EGLSurface!\n");
+ return nullptr;
+ }
+
+ SurfaceCaps caps = SurfaceCaps::Any();
+ RefPtr<GLContextEGL> gl = GLContextEGL::CreateGLContext(CreateContextFlags::NONE,
+ caps, nullptr, false, config,
+ surface, &discardFailureId);
+ if (!gl) {
+ MOZ_CRASH("GFX: Failed to create EGLContext!\n");
+ mozilla::gl::DestroySurface(surface);
+ return nullptr;
+ }
+
+ gl->MakeCurrent();
+ gl->SetIsDoubleBuffered(doubleBuffered);
+
+ return gl.forget();
+}
+
+#if defined(ANDROID)
+EGLSurface
+GLContextProviderEGL::CreateEGLSurface(void* aWindow)
+{
+ nsCString discardFailureId;
+ if (!sEGLLibrary.EnsureInitialized(false, &discardFailureId)) {
+ MOZ_CRASH("GFX: Failed to load EGL library 4!\n");
+ }
+
+ EGLConfig config;
+ if (!CreateConfig(&config, static_cast<nsIWidget*>(aWindow))) {
+ MOZ_CRASH("GFX: Failed to create EGLConfig 2!\n");
+ }
+
+ MOZ_ASSERT(aWindow);
+
+ EGLSurface surface = sEGLLibrary.fCreateWindowSurface(EGL_DISPLAY(), config, aWindow,
+ 0);
+ if (surface == EGL_NO_SURFACE) {
+ MOZ_CRASH("GFX: Failed to create EGLSurface 2!\n");
+ }
+
+ return surface;
+}
+
+void
+GLContextProviderEGL::DestroyEGLSurface(EGLSurface surface)
+{
+ nsCString discardFailureId;
+ if (!sEGLLibrary.EnsureInitialized(false, &discardFailureId)) {
+ MOZ_CRASH("GFX: Failed to load EGL library 5!\n");
+ }
+
+ sEGLLibrary.fDestroySurface(EGL_DISPLAY(), surface);
+}
+#endif // defined(ANDROID)
+
+static void
+FillContextAttribs(bool alpha, bool depth, bool stencil, bool bpp16,
+ bool es3, nsTArray<EGLint>* out)
+{
+ out->AppendElement(LOCAL_EGL_SURFACE_TYPE);
+ out->AppendElement(LOCAL_EGL_PBUFFER_BIT);
+
+ out->AppendElement(LOCAL_EGL_RENDERABLE_TYPE);
+ if (es3) {
+ out->AppendElement(LOCAL_EGL_OPENGL_ES3_BIT_KHR);
+ } else {
+ out->AppendElement(LOCAL_EGL_OPENGL_ES2_BIT);
+ }
+
+ out->AppendElement(LOCAL_EGL_RED_SIZE);
+ if (bpp16) {
+ out->AppendElement(alpha ? 4 : 5);
+ } else {
+ out->AppendElement(8);
+ }
+
+ out->AppendElement(LOCAL_EGL_GREEN_SIZE);
+ if (bpp16) {
+ out->AppendElement(alpha ? 4 : 6);
+ } else {
+ out->AppendElement(8);
+ }
+
+ out->AppendElement(LOCAL_EGL_BLUE_SIZE);
+ if (bpp16) {
+ out->AppendElement(alpha ? 4 : 5);
+ } else {
+ out->AppendElement(8);
+ }
+
+ out->AppendElement(LOCAL_EGL_ALPHA_SIZE);
+ if (alpha) {
+ out->AppendElement(bpp16 ? 4 : 8);
+ } else {
+ out->AppendElement(0);
+ }
+
+ out->AppendElement(LOCAL_EGL_DEPTH_SIZE);
+ out->AppendElement(depth ? 16 : 0);
+
+ out->AppendElement(LOCAL_EGL_STENCIL_SIZE);
+ out->AppendElement(stencil ? 8 : 0);
+
+ // EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS
+ out->AppendElement(LOCAL_EGL_NONE);
+ out->AppendElement(0);
+
+ out->AppendElement(0);
+ out->AppendElement(0);
+}
+
+static GLint
+GetAttrib(GLLibraryEGL* egl, EGLConfig config, EGLint attrib)
+{
+ EGLint bits = 0;
+ egl->fGetConfigAttrib(egl->Display(), config, attrib, &bits);
+ MOZ_ASSERT(egl->fGetError() == LOCAL_EGL_SUCCESS);
+
+ return bits;
+}
+
+static EGLConfig
+ChooseConfig(GLLibraryEGL* egl, CreateContextFlags flags, const SurfaceCaps& minCaps,
+ SurfaceCaps* const out_configCaps)
+{
+ nsTArray<EGLint> configAttribList;
+ FillContextAttribs(minCaps.alpha, minCaps.depth, minCaps.stencil, minCaps.bpp16,
+ bool(flags & CreateContextFlags::PREFER_ES3), &configAttribList);
+
+ const EGLint* configAttribs = configAttribList.Elements();
+
+ // We're guaranteed to get at least minCaps, and the sorting dictated by the spec for
+ // eglChooseConfig reasonably assures that a reasonable 'best' config is on top.
+ const EGLint kMaxConfigs = 1;
+ EGLConfig configs[kMaxConfigs];
+ EGLint foundConfigs = 0;
+ if (!egl->fChooseConfig(egl->Display(), configAttribs, configs, kMaxConfigs,
+ &foundConfigs)
+ || foundConfigs == 0)
+ {
+ return EGL_NO_CONFIG;
+ }
+
+ EGLConfig config = configs[0];
+
+ *out_configCaps = minCaps; // Pick up any preserve, etc.
+ out_configCaps->color = true;
+ out_configCaps->alpha = bool(GetAttrib(egl, config, LOCAL_EGL_ALPHA_SIZE));
+ out_configCaps->depth = bool(GetAttrib(egl, config, LOCAL_EGL_DEPTH_SIZE));
+ out_configCaps->stencil = bool(GetAttrib(egl, config, LOCAL_EGL_STENCIL_SIZE));
+ out_configCaps->bpp16 = (GetAttrib(egl, config, LOCAL_EGL_RED_SIZE) < 8);
+
+ return config;
+}
+
+/*static*/ already_AddRefed<GLContextEGL>
+GLContextEGL::CreateEGLPBufferOffscreenContext(CreateContextFlags flags,
+ const mozilla::gfx::IntSize& size,
+ const SurfaceCaps& minCaps,
+ nsACString* const out_failureId)
+{
+ bool forceEnableHardware = bool(flags & CreateContextFlags::FORCE_ENABLE_HARDWARE);
+ if (!sEGLLibrary.EnsureInitialized(forceEnableHardware, out_failureId)) {
+ return nullptr;
+ }
+
+ SurfaceCaps configCaps;
+ EGLConfig config = ChooseConfig(&sEGLLibrary, flags, minCaps, &configCaps);
+ if (config == EGL_NO_CONFIG) {
+ *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_EGL_NO_CONFIG");
+ NS_WARNING("Failed to find a compatible config.");
+ return nullptr;
+ }
+
+ if (GLContext::ShouldSpew()) {
+ sEGLLibrary.DumpEGLConfig(config);
+ }
+
+ mozilla::gfx::IntSize pbSize(size);
+ EGLSurface surface = GLContextEGL::CreatePBufferSurfaceTryingPowerOfTwo(config,
+ LOCAL_EGL_NONE,
+ pbSize);
+ if (!surface) {
+ *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_EGL_POT");
+ NS_WARNING("Failed to create PBuffer for context!");
+ return nullptr;
+ }
+
+ RefPtr<GLContextEGL> gl = GLContextEGL::CreateGLContext(flags, configCaps, nullptr,
+ true, config, surface,
+ out_failureId);
+ if (!gl) {
+ NS_WARNING("Failed to create GLContext from PBuffer");
+ sEGLLibrary.fDestroySurface(sEGLLibrary.Display(), surface);
+ return nullptr;
+ }
+
+ return gl.forget();
+}
+
+/*static*/ already_AddRefed<GLContext>
+GLContextProviderEGL::CreateHeadless(CreateContextFlags flags,
+ nsACString* const out_failureId)
+{
+ mozilla::gfx::IntSize dummySize = mozilla::gfx::IntSize(16, 16);
+ SurfaceCaps dummyCaps = SurfaceCaps::Any();
+ return GLContextEGL::CreateEGLPBufferOffscreenContext(flags, dummySize, dummyCaps,
+ out_failureId);
+}
+
+// Under EGL, on Android, pbuffers are supported fine, though
+// often without the ability to texture from them directly.
+/*static*/ already_AddRefed<GLContext>
+GLContextProviderEGL::CreateOffscreen(const mozilla::gfx::IntSize& size,
+ const SurfaceCaps& minCaps,
+ CreateContextFlags flags,
+ nsACString* const out_failureId)
+{
+ bool forceEnableHardware = bool(flags & CreateContextFlags::FORCE_ENABLE_HARDWARE);
+ if (!sEGLLibrary.EnsureInitialized(forceEnableHardware, out_failureId)) { // Needed for IsANGLE().
+ return nullptr;
+ }
+
+ bool canOffscreenUseHeadless = true;
+ if (sEGLLibrary.IsANGLE()) {
+ // ANGLE needs to use PBuffers.
+ canOffscreenUseHeadless = false;
+ }
+
+ RefPtr<GLContext> gl;
+ SurfaceCaps minOffscreenCaps = minCaps;
+
+ if (canOffscreenUseHeadless) {
+ gl = CreateHeadless(flags, out_failureId);
+ if (!gl) {
+ return nullptr;
+ }
+ } else {
+ SurfaceCaps minBackbufferCaps = minOffscreenCaps;
+ if (minOffscreenCaps.antialias) {
+ minBackbufferCaps.antialias = false;
+ minBackbufferCaps.depth = false;
+ minBackbufferCaps.stencil = false;
+ }
+
+ gl = GLContextEGL::CreateEGLPBufferOffscreenContext(flags, size,
+ minBackbufferCaps,
+ out_failureId);
+ if (!gl)
+ return nullptr;
+
+ // Pull the actual resulting caps to ensure that our offscreen matches our
+ // backbuffer.
+ minOffscreenCaps.alpha = gl->Caps().alpha;
+ if (!minOffscreenCaps.antialias) {
+ // Only update these if we don't have AA. If we do have AA, we ignore
+ // backbuffer depth/stencil.
+ minOffscreenCaps.depth = gl->Caps().depth;
+ minOffscreenCaps.stencil = gl->Caps().stencil;
+ }
+ }
+
+ // Init the offscreen with the updated offscreen caps.
+ if (!gl->InitOffscreen(size, minOffscreenCaps)) {
+ *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_EGL_OFFSCREEN");
+ return nullptr;
+ }
+
+ return gl.forget();
+}
+
+// Don't want a global context on Android as 1) share groups across 2 threads fail on many Tegra drivers (bug 759225)
+// and 2) some mobile devices have a very strict limit on global number of GL contexts (bug 754257)
+// and 3) each EGL context eats 750k on B2G (bug 813783)
+/*static*/ GLContext*
+GLContextProviderEGL::GetGlobalContext()
+{
+ return nullptr;
+}
+
+/*static*/ void
+GLContextProviderEGL::Shutdown()
+{
+}
+
+} /* namespace gl */
+} /* namespace mozilla */
+
+#undef EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS
diff --git a/gfx/gl/GLContextProviderGLX.cpp b/gfx/gl/GLContextProviderGLX.cpp
new file mode 100644
index 0000000000..9a1157f330
--- /dev/null
+++ b/gfx/gl/GLContextProviderGLX.cpp
@@ -0,0 +1,1421 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifdef MOZ_WIDGET_GTK
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+#define GET_NATIVE_WINDOW(aWidget) GDK_WINDOW_XID((GdkWindow*) aWidget->GetNativeData(NS_NATIVE_WINDOW))
+#endif
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "X11UndefineNone.h"
+
+#include "mozilla/MathAlgorithms.h"
+#include "mozilla/StaticPtr.h"
+#include "mozilla/widget/CompositorWidget.h"
+#include "mozilla/widget/X11CompositorWidget.h"
+#include "mozilla/Unused.h"
+
+#include "prenv.h"
+#include "GLContextProvider.h"
+#include "GLLibraryLoader.h"
+#include "nsDebug.h"
+#include "nsIWidget.h"
+#include "GLXLibrary.h"
+#include "gfxXlibSurface.h"
+#include "gfxContext.h"
+#include "gfxEnv.h"
+#include "gfxPlatform.h"
+#include "GLContextGLX.h"
+#include "gfxUtils.h"
+#include "gfx2DGlue.h"
+#include "GLScreenBuffer.h"
+#include "gfxPrefs.h"
+
+#include "gfxCrashReporterUtils.h"
+
+#ifdef MOZ_WIDGET_GTK
+#include "gfxPlatformGtk.h"
+#endif
+
+namespace mozilla {
+namespace gl {
+
+using namespace mozilla::gfx;
+using namespace mozilla::widget;
+
+GLXLibrary sGLXLibrary;
+
+// Check that we have at least version aMajor.aMinor .
+bool
+GLXLibrary::GLXVersionCheck(int aMajor, int aMinor)
+{
+ return aMajor < mGLXMajorVersion ||
+ (aMajor == mGLXMajorVersion && aMinor <= mGLXMinorVersion);
+}
+
+static inline bool
+HasExtension(const char* aExtensions, const char* aRequiredExtension)
+{
+ return GLContext::ListHasExtension(
+ reinterpret_cast<const GLubyte*>(aExtensions), aRequiredExtension);
+}
+
+bool
+GLXLibrary::EnsureInitialized()
+{
+ if (mInitialized) {
+ return true;
+ }
+
+ // Don't repeatedly try to initialize.
+ if (mTriedInitializing) {
+ return false;
+ }
+ mTriedInitializing = true;
+
+ // Force enabling s3 texture compression. (Bug 774134)
+ PR_SetEnv("force_s3tc_enable=true");
+
+ if (!mOGLLibrary) {
+ const char* libGLfilename = nullptr;
+ bool forceFeatureReport = false;
+
+ // see e.g. bug 608526: it is intrinsically interesting to know whether we have dynamically linked to libGL.so.1
+ // because at least the NVIDIA implementation requires an executable stack, which causes mprotect calls,
+ // which trigger glibc bug http://sourceware.org/bugzilla/show_bug.cgi?id=12225
+#ifdef __OpenBSD__
+ libGLfilename = "libGL.so";
+#else
+ libGLfilename = "libGL.so.1";
+#endif
+
+ ScopedGfxFeatureReporter reporter(libGLfilename, forceFeatureReport);
+ mOGLLibrary = PR_LoadLibrary(libGLfilename);
+ if (!mOGLLibrary) {
+ NS_WARNING("Couldn't load OpenGL shared library.");
+ return false;
+ }
+ reporter.SetSuccessful();
+ }
+
+ if (gfxEnv::GlxDebug()) {
+ mDebug = true;
+ }
+
+ GLLibraryLoader::SymLoadStruct symbols[] = {
+ /* functions that were in GLX 1.0 */
+ { (PRFuncPtr*) &xDestroyContextInternal, { "glXDestroyContext", nullptr } },
+ { (PRFuncPtr*) &xMakeCurrentInternal, { "glXMakeCurrent", nullptr } },
+ { (PRFuncPtr*) &xSwapBuffersInternal, { "glXSwapBuffers", nullptr } },
+ { (PRFuncPtr*) &xQueryVersionInternal, { "glXQueryVersion", nullptr } },
+ { (PRFuncPtr*) &xGetCurrentContextInternal, { "glXGetCurrentContext", nullptr } },
+ { (PRFuncPtr*) &xWaitGLInternal, { "glXWaitGL", nullptr } },
+ { (PRFuncPtr*) &xWaitXInternal, { "glXWaitX", nullptr } },
+ /* functions introduced in GLX 1.1 */
+ { (PRFuncPtr*) &xQueryExtensionsStringInternal, { "glXQueryExtensionsString", nullptr } },
+ { (PRFuncPtr*) &xGetClientStringInternal, { "glXGetClientString", nullptr } },
+ { (PRFuncPtr*) &xQueryServerStringInternal, { "glXQueryServerString", nullptr } },
+ { nullptr, { nullptr } }
+ };
+
+ GLLibraryLoader::SymLoadStruct symbols13[] = {
+ /* functions introduced in GLX 1.3 */
+ { (PRFuncPtr*) &xChooseFBConfigInternal, { "glXChooseFBConfig", nullptr } },
+ { (PRFuncPtr*) &xGetFBConfigAttribInternal, { "glXGetFBConfigAttrib", nullptr } },
+ // WARNING: xGetFBConfigs not set in symbols13_ext
+ { (PRFuncPtr*) &xGetFBConfigsInternal, { "glXGetFBConfigs", nullptr } },
+ // WARNING: symbols13_ext sets xCreateGLXPixmapWithConfig instead
+ { (PRFuncPtr*) &xCreatePixmapInternal, { "glXCreatePixmap", nullptr } },
+ { (PRFuncPtr*) &xDestroyPixmapInternal, { "glXDestroyPixmap", nullptr } },
+ { (PRFuncPtr*) &xCreateNewContextInternal, { "glXCreateNewContext", nullptr } },
+ { nullptr, { nullptr } }
+ };
+
+ GLLibraryLoader::SymLoadStruct symbols13_ext[] = {
+ /* extension equivalents for functions introduced in GLX 1.3 */
+ // GLX_SGIX_fbconfig extension
+ { (PRFuncPtr*) &xChooseFBConfigInternal, { "glXChooseFBConfigSGIX", nullptr } },
+ { (PRFuncPtr*) &xGetFBConfigAttribInternal, { "glXGetFBConfigAttribSGIX", nullptr } },
+ // WARNING: no xGetFBConfigs equivalent in extensions
+ // WARNING: different from symbols13:
+ { (PRFuncPtr*) &xCreateGLXPixmapWithConfigInternal, { "glXCreateGLXPixmapWithConfigSGIX", nullptr } },
+ { (PRFuncPtr*) &xDestroyPixmapInternal, { "glXDestroyGLXPixmap", nullptr } }, // not from ext
+ { (PRFuncPtr*) &xCreateNewContextInternal, { "glXCreateContextWithConfigSGIX", nullptr } },
+ { nullptr, { nullptr } }
+ };
+
+ GLLibraryLoader::SymLoadStruct symbols14[] = {
+ /* functions introduced in GLX 1.4 */
+ { (PRFuncPtr*) &xGetProcAddressInternal, { "glXGetProcAddress", nullptr } },
+ { nullptr, { nullptr } }
+ };
+
+ GLLibraryLoader::SymLoadStruct symbols14_ext[] = {
+ /* extension equivalents for functions introduced in GLX 1.4 */
+ // GLX_ARB_get_proc_address extension
+ { (PRFuncPtr*) &xGetProcAddressInternal, { "glXGetProcAddressARB", nullptr } },
+ { nullptr, { nullptr } }
+ };
+
+ GLLibraryLoader::SymLoadStruct symbols_texturefrompixmap[] = {
+ { (PRFuncPtr*) &xBindTexImageInternal, { "glXBindTexImageEXT", nullptr } },
+ { (PRFuncPtr*) &xReleaseTexImageInternal, { "glXReleaseTexImageEXT", nullptr } },
+ { nullptr, { nullptr } }
+ };
+
+ GLLibraryLoader::SymLoadStruct symbols_createcontext[] = {
+ { (PRFuncPtr*) &xCreateContextAttribsInternal, { "glXCreateContextAttribsARB", nullptr } },
+ { nullptr, { nullptr } }
+ };
+
+ GLLibraryLoader::SymLoadStruct symbols_videosync[] = {
+ { (PRFuncPtr*) &xGetVideoSyncInternal, { "glXGetVideoSyncSGI", nullptr } },
+ { (PRFuncPtr*) &xWaitVideoSyncInternal, { "glXWaitVideoSyncSGI", nullptr } },
+ { nullptr, { nullptr } }
+ };
+
+ GLLibraryLoader::SymLoadStruct symbols_swapcontrol[] = {
+ { (PRFuncPtr*) &xSwapIntervalInternal, { "glXSwapIntervalEXT", nullptr } },
+ { nullptr, { nullptr } }
+ };
+
+ if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, &symbols[0])) {
+ NS_WARNING("Couldn't find required entry point in OpenGL shared library");
+ return false;
+ }
+
+ Display* display = DefaultXDisplay();
+ int screen = DefaultScreen(display);
+
+ if (!xQueryVersion(display, &mGLXMajorVersion, &mGLXMinorVersion)) {
+ mGLXMajorVersion = 0;
+ mGLXMinorVersion = 0;
+ return false;
+ }
+
+ if (!GLXVersionCheck(1, 1))
+ // Not possible to query for extensions.
+ return false;
+
+ const char* clientVendor = xGetClientString(display, LOCAL_GLX_VENDOR);
+ const char* serverVendor = xQueryServerString(display, screen, LOCAL_GLX_VENDOR);
+ const char* extensionsStr = xQueryExtensionsString(display, screen);
+
+ GLLibraryLoader::SymLoadStruct* sym13;
+ if (!GLXVersionCheck(1, 3)) {
+ // Even if we don't have 1.3, we might have equivalent extensions
+ // (as on the Intel X server).
+ if (!HasExtension(extensionsStr, "GLX_SGIX_fbconfig")) {
+ return false;
+ }
+ sym13 = symbols13_ext;
+ } else {
+ sym13 = symbols13;
+ }
+ if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, sym13)) {
+ NS_WARNING("Couldn't find required entry point in OpenGL shared library");
+ return false;
+ }
+
+ GLLibraryLoader::SymLoadStruct* sym14;
+ if (!GLXVersionCheck(1, 4)) {
+ // Even if we don't have 1.4, we might have equivalent extensions
+ // (as on the Intel X server).
+ if (!HasExtension(extensionsStr, "GLX_ARB_get_proc_address")) {
+ return false;
+ }
+ sym14 = symbols14_ext;
+ } else {
+ sym14 = symbols14;
+ }
+ if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, sym14)) {
+ NS_WARNING("Couldn't find required entry point in OpenGL shared library");
+ return false;
+ }
+
+ if (HasExtension(extensionsStr, "GLX_EXT_texture_from_pixmap") &&
+ GLLibraryLoader::LoadSymbols(mOGLLibrary, symbols_texturefrompixmap,
+ (GLLibraryLoader::PlatformLookupFunction)&xGetProcAddress))
+ {
+ mUseTextureFromPixmap = gfxPrefs::UseGLXTextureFromPixmap();
+ } else {
+ mUseTextureFromPixmap = false;
+ NS_WARNING("Texture from pixmap disabled");
+ }
+
+ if (HasExtension(extensionsStr, "GLX_ARB_create_context") &&
+ HasExtension(extensionsStr, "GLX_ARB_create_context_profile") &&
+ GLLibraryLoader::LoadSymbols(mOGLLibrary, symbols_createcontext,
+ (GLLibraryLoader::PlatformLookupFunction)&xGetProcAddress))
+ {
+ mHasCreateContextAttribs = true;
+ }
+
+ if (HasExtension(extensionsStr, "GLX_ARB_create_context_robustness"))
+ {
+ mHasRobustness = true;
+ }
+
+ if (HasExtension(extensionsStr, "GLX_SGI_video_sync") &&
+ GLLibraryLoader::LoadSymbols(mOGLLibrary, symbols_videosync,
+ (GLLibraryLoader::PlatformLookupFunction)&xGetProcAddress))
+ {
+ mHasVideoSync = true;
+ }
+
+ if (!(HasExtension(extensionsStr, "GLX_EXT_swap_control") &&
+ GLLibraryLoader::LoadSymbols(mOGLLibrary, symbols_swapcontrol)))
+ {
+ NS_WARNING("GLX_swap_control unsupported, ASAP mode may still block on buffer swaps.");
+ }
+
+ mIsATI = serverVendor && DoesStringMatch(serverVendor, "ATI");
+ mIsNVIDIA = serverVendor && DoesStringMatch(serverVendor, "NVIDIA Corporation");
+ mClientIsMesa = clientVendor && DoesStringMatch(clientVendor, "Mesa");
+
+ mInitialized = true;
+
+ return true;
+}
+
+bool
+GLXLibrary::SupportsTextureFromPixmap(gfxASurface* aSurface)
+{
+ if (!EnsureInitialized()) {
+ return false;
+ }
+
+ if (aSurface->GetType() != gfxSurfaceType::Xlib || !mUseTextureFromPixmap) {
+ return false;
+ }
+
+ return true;
+}
+
+bool
+GLXLibrary::SupportsVideoSync()
+{
+ if (!EnsureInitialized()) {
+ return false;
+ }
+
+ return mHasVideoSync;
+}
+
+GLXPixmap
+GLXLibrary::CreatePixmap(gfxASurface* aSurface)
+{
+ if (!SupportsTextureFromPixmap(aSurface)) {
+ return X11None;
+ }
+
+ gfxXlibSurface* xs = static_cast<gfxXlibSurface*>(aSurface);
+ const XRenderPictFormat* format = xs->XRenderFormat();
+ if (!format || format->type != PictTypeDirect) {
+ return X11None;
+ }
+ const XRenderDirectFormat& direct = format->direct;
+ int alphaSize = FloorLog2(direct.alphaMask + 1);
+ NS_ASSERTION((1 << alphaSize) - 1 == direct.alphaMask,
+ "Unexpected render format with non-adjacent alpha bits");
+
+ int attribs[] = { LOCAL_GLX_DOUBLEBUFFER, False,
+ LOCAL_GLX_DRAWABLE_TYPE, LOCAL_GLX_PIXMAP_BIT,
+ LOCAL_GLX_ALPHA_SIZE, alphaSize,
+ (alphaSize ? LOCAL_GLX_BIND_TO_TEXTURE_RGBA_EXT
+ : LOCAL_GLX_BIND_TO_TEXTURE_RGB_EXT), True,
+ LOCAL_GLX_RENDER_TYPE, LOCAL_GLX_RGBA_BIT,
+ X11None };
+
+ int numConfigs = 0;
+ Display* display = xs->XDisplay();
+ int xscreen = DefaultScreen(display);
+
+ ScopedXFree<GLXFBConfig> cfgs(xChooseFBConfig(display,
+ xscreen,
+ attribs,
+ &numConfigs));
+
+ // Find an fbconfig that matches the pixel format used on the Pixmap.
+ int matchIndex = -1;
+ unsigned long redMask =
+ static_cast<unsigned long>(direct.redMask) << direct.red;
+ unsigned long greenMask =
+ static_cast<unsigned long>(direct.greenMask) << direct.green;
+ unsigned long blueMask =
+ static_cast<unsigned long>(direct.blueMask) << direct.blue;
+ // This is true if the Pixmap has bits for alpha or unused bits.
+ bool haveNonColorBits =
+ ~(redMask | greenMask | blueMask) != -1UL << format->depth;
+
+ for (int i = 0; i < numConfigs; i++) {
+ int id = X11None;
+ sGLXLibrary.xGetFBConfigAttrib(display, cfgs[i], LOCAL_GLX_VISUAL_ID, &id);
+ Visual* visual;
+ int depth;
+ FindVisualAndDepth(display, id, &visual, &depth);
+ if (!visual ||
+ visual->c_class != TrueColor ||
+ visual->red_mask != redMask ||
+ visual->green_mask != greenMask ||
+ visual->blue_mask != blueMask ) {
+ continue;
+ }
+
+ // Historically Xlib Visuals did not try to represent an alpha channel
+ // and there was no means to use an alpha channel on a Pixmap. The
+ // Xlib Visual from the fbconfig was not intended to have any
+ // information about alpha bits.
+ //
+ // Since then, RENDER has added formats for 32 bit depth Pixmaps.
+ // Some of these formats have bits for alpha and some have unused
+ // bits.
+ //
+ // Then the Composite extension added a 32 bit depth Visual intended
+ // for Windows with an alpha channel, so bits not in the visual color
+ // masks were expected to be treated as alpha bits.
+ //
+ // Usually GLX counts only color bits in the Visual depth, but the
+ // depth of Composite's ARGB Visual includes alpha bits. However,
+ // bits not in the color masks are not necessarily alpha bits because
+ // sometimes (NVIDIA) 32 bit Visuals are added for fbconfigs with 32
+ // bit BUFFER_SIZE but zero alpha bits and 24 color bits (NVIDIA
+ // again).
+ //
+ // This checks that the depth matches in one of the two ways.
+ // NVIDIA now forces format->depth == depth so only the first way
+ // is checked for NVIDIA
+ if (depth != format->depth &&
+ (mIsNVIDIA || depth != format->depth - alphaSize) ) {
+ continue;
+ }
+
+ // If all bits of the Pixmap are color bits and the Pixmap depth
+ // matches the depth of the fbconfig visual, then we can assume that
+ // the driver will do whatever is necessary to ensure that any
+ // GLXPixmap alpha bits are treated as set. We can skip the
+ // ALPHA_SIZE check in this situation. We need to skip this check for
+ // situations (ATI) where there are no fbconfigs without alpha bits.
+ //
+ // glXChooseFBConfig should prefer configs with smaller
+ // LOCAL_GLX_BUFFER_SIZE, so we should still get zero alpha bits if
+ // available, except perhaps with NVIDIA drivers where buffer size is
+ // not the specified sum of the component sizes.
+ if (haveNonColorBits) {
+ // There are bits in the Pixmap format that haven't been matched
+ // against the fbconfig visual. These bits could either represent
+ // alpha or be unused, so just check that the number of alpha bits
+ // matches.
+ int size = 0;
+ sGLXLibrary.xGetFBConfigAttrib(display, cfgs[i],
+ LOCAL_GLX_ALPHA_SIZE, &size);
+ if (size != alphaSize) {
+ continue;
+ }
+ }
+
+ matchIndex = i;
+ break;
+ }
+ if (matchIndex == -1) {
+ // GLX can't handle A8 surfaces, so this is not really unexpected. The
+ // caller should deal with this situation.
+ NS_WARNING_ASSERTION(
+ format->depth == 8,
+ "[GLX] Couldn't find a FBConfig matching Pixmap format");
+ return X11None;
+ }
+
+ int pixmapAttribs[] = { LOCAL_GLX_TEXTURE_TARGET_EXT, LOCAL_GLX_TEXTURE_2D_EXT,
+ LOCAL_GLX_TEXTURE_FORMAT_EXT,
+ (alphaSize ? LOCAL_GLX_TEXTURE_FORMAT_RGBA_EXT
+ : LOCAL_GLX_TEXTURE_FORMAT_RGB_EXT),
+ X11None};
+
+ GLXPixmap glxpixmap = xCreatePixmap(display,
+ cfgs[matchIndex],
+ xs->XDrawable(),
+ pixmapAttribs);
+
+ return glxpixmap;
+}
+
+void
+GLXLibrary::DestroyPixmap(Display* aDisplay, GLXPixmap aPixmap)
+{
+ if (!mUseTextureFromPixmap) {
+ return;
+ }
+
+ xDestroyPixmap(aDisplay, aPixmap);
+}
+
+void
+GLXLibrary::BindTexImage(Display* aDisplay, GLXPixmap aPixmap)
+{
+ if (!mUseTextureFromPixmap) {
+ return;
+ }
+
+ // Make sure all X drawing to the surface has finished before binding to a texture.
+ if (mClientIsMesa) {
+ // Using XSync instead of Mesa's glXWaitX, because its glxWaitX is a
+ // noop when direct rendering unless the current drawable is a
+ // single-buffer window.
+ FinishX(aDisplay);
+ } else {
+ xWaitX();
+ }
+ xBindTexImage(aDisplay, aPixmap, LOCAL_GLX_FRONT_LEFT_EXT, nullptr);
+}
+
+void
+GLXLibrary::ReleaseTexImage(Display* aDisplay, GLXPixmap aPixmap)
+{
+ if (!mUseTextureFromPixmap) {
+ return;
+ }
+
+ xReleaseTexImage(aDisplay, aPixmap, LOCAL_GLX_FRONT_LEFT_EXT);
+}
+
+void
+GLXLibrary::UpdateTexImage(Display* aDisplay, GLXPixmap aPixmap)
+{
+ // NVIDIA drivers don't require a rebind of the pixmap in order
+ // to display an updated image, and it's faster not to do it.
+ if (mIsNVIDIA) {
+ xWaitX();
+ return;
+ }
+
+ ReleaseTexImage(aDisplay, aPixmap);
+ BindTexImage(aDisplay, aPixmap);
+}
+
+#ifdef DEBUG
+
+static int (*sOldErrorHandler)(Display*, XErrorEvent*);
+ScopedXErrorHandler::ErrorEvent sErrorEvent;
+static int GLXErrorHandler(Display* display, XErrorEvent* ev)
+{
+ if (!sErrorEvent.mError.error_code) {
+ sErrorEvent.mError = *ev;
+ }
+ return 0;
+}
+
+void
+GLXLibrary::BeforeGLXCall()
+{
+ if (mDebug) {
+ sOldErrorHandler = XSetErrorHandler(GLXErrorHandler);
+ }
+}
+
+void
+GLXLibrary::AfterGLXCall()
+{
+ if (mDebug) {
+ FinishX(DefaultXDisplay());
+ if (sErrorEvent.mError.error_code) {
+ char buffer[2048];
+ XGetErrorText(DefaultXDisplay(), sErrorEvent.mError.error_code, buffer, sizeof(buffer));
+ printf_stderr("X ERROR: %s (%i) - Request: %i.%i, Serial: %lu",
+ buffer,
+ sErrorEvent.mError.error_code,
+ sErrorEvent.mError.request_code,
+ sErrorEvent.mError.minor_code,
+ sErrorEvent.mError.serial);
+ NS_ABORT();
+ }
+ XSetErrorHandler(sOldErrorHandler);
+ }
+}
+
+#define BEFORE_GLX_CALL do { \
+ sGLXLibrary.BeforeGLXCall(); \
+} while (0)
+
+#define AFTER_GLX_CALL do { \
+ sGLXLibrary.AfterGLXCall(); \
+} while (0)
+
+#else
+
+#define BEFORE_GLX_CALL do { } while(0)
+#define AFTER_GLX_CALL do { } while(0)
+
+#endif
+
+void
+GLXLibrary::xDestroyContext(Display* display, GLXContext context)
+{
+ BEFORE_GLX_CALL;
+ xDestroyContextInternal(display, context);
+ AFTER_GLX_CALL;
+}
+
+Bool
+GLXLibrary::xMakeCurrent(Display* display,
+ GLXDrawable drawable,
+ GLXContext context)
+{
+ BEFORE_GLX_CALL;
+ Bool result = xMakeCurrentInternal(display, drawable, context);
+ AFTER_GLX_CALL;
+ return result;
+}
+
+GLXContext
+GLXLibrary::xGetCurrentContext()
+{
+ BEFORE_GLX_CALL;
+ GLXContext result = xGetCurrentContextInternal();
+ AFTER_GLX_CALL;
+ return result;
+}
+
+/* static */ void*
+GLXLibrary::xGetProcAddress(const char* procName)
+{
+ BEFORE_GLX_CALL;
+ void* result = sGLXLibrary.xGetProcAddressInternal(procName);
+ AFTER_GLX_CALL;
+ return result;
+}
+
+GLXFBConfig*
+GLXLibrary::xChooseFBConfig(Display* display,
+ int screen,
+ const int* attrib_list,
+ int* nelements)
+{
+ BEFORE_GLX_CALL;
+ GLXFBConfig* result = xChooseFBConfigInternal(display, screen, attrib_list, nelements);
+ AFTER_GLX_CALL;
+ return result;
+}
+
+GLXFBConfig*
+GLXLibrary::xGetFBConfigs(Display* display,
+ int screen,
+ int* nelements)
+{
+ BEFORE_GLX_CALL;
+ GLXFBConfig* result = xGetFBConfigsInternal(display, screen, nelements);
+ AFTER_GLX_CALL;
+ return result;
+}
+
+GLXContext
+GLXLibrary::xCreateNewContext(Display* display,
+ GLXFBConfig config,
+ int render_type,
+ GLXContext share_list,
+ Bool direct)
+{
+ BEFORE_GLX_CALL;
+ GLXContext result = xCreateNewContextInternal(display, config,
+ render_type,
+ share_list, direct);
+ AFTER_GLX_CALL;
+ return result;
+}
+
+int
+GLXLibrary::xGetFBConfigAttrib(Display* display,
+ GLXFBConfig config,
+ int attribute,
+ int* value)
+{
+ BEFORE_GLX_CALL;
+ int result = xGetFBConfigAttribInternal(display, config,
+ attribute, value);
+ AFTER_GLX_CALL;
+ return result;
+}
+
+void
+GLXLibrary::xSwapBuffers(Display* display, GLXDrawable drawable)
+{
+ BEFORE_GLX_CALL;
+ xSwapBuffersInternal(display, drawable);
+ AFTER_GLX_CALL;
+}
+
+const char*
+GLXLibrary::xQueryExtensionsString(Display* display,
+ int screen)
+{
+ BEFORE_GLX_CALL;
+ const char* result = xQueryExtensionsStringInternal(display, screen);
+ AFTER_GLX_CALL;
+ return result;
+}
+
+const char*
+GLXLibrary::xGetClientString(Display* display,
+ int screen)
+{
+ BEFORE_GLX_CALL;
+ const char* result = xGetClientStringInternal(display, screen);
+ AFTER_GLX_CALL;
+ return result;
+}
+
+const char*
+GLXLibrary::xQueryServerString(Display* display,
+ int screen, int name)
+{
+ BEFORE_GLX_CALL;
+ const char* result = xQueryServerStringInternal(display, screen, name);
+ AFTER_GLX_CALL;
+ return result;
+}
+
+GLXPixmap
+GLXLibrary::xCreatePixmap(Display* display,
+ GLXFBConfig config,
+ Pixmap pixmap,
+ const int* attrib_list)
+{
+ BEFORE_GLX_CALL;
+ GLXPixmap result = xCreatePixmapInternal(display, config,
+ pixmap, attrib_list);
+ AFTER_GLX_CALL;
+ return result;
+}
+
+GLXPixmap
+GLXLibrary::xCreateGLXPixmapWithConfig(Display* display,
+ GLXFBConfig config,
+ Pixmap pixmap)
+{
+ BEFORE_GLX_CALL;
+ GLXPixmap result = xCreateGLXPixmapWithConfigInternal(display, config, pixmap);
+ AFTER_GLX_CALL;
+ return result;
+}
+
+void
+GLXLibrary::xDestroyPixmap(Display* display, GLXPixmap pixmap)
+{
+ BEFORE_GLX_CALL;
+ xDestroyPixmapInternal(display, pixmap);
+ AFTER_GLX_CALL;
+}
+
+Bool
+GLXLibrary::xQueryVersion(Display* display,
+ int* major,
+ int* minor)
+{
+ BEFORE_GLX_CALL;
+ Bool result = xQueryVersionInternal(display, major, minor);
+ AFTER_GLX_CALL;
+ return result;
+}
+
+void
+GLXLibrary::xBindTexImage(Display* display,
+ GLXDrawable drawable,
+ int buffer,
+ const int* attrib_list)
+{
+ BEFORE_GLX_CALL;
+ xBindTexImageInternal(display, drawable, buffer, attrib_list);
+ AFTER_GLX_CALL;
+}
+
+void
+GLXLibrary::xReleaseTexImage(Display* display,
+ GLXDrawable drawable,
+ int buffer)
+{
+ BEFORE_GLX_CALL;
+ xReleaseTexImageInternal(display, drawable, buffer);
+ AFTER_GLX_CALL;
+}
+
+void
+GLXLibrary::xWaitGL()
+{
+ BEFORE_GLX_CALL;
+ xWaitGLInternal();
+ AFTER_GLX_CALL;
+}
+
+void
+GLXLibrary::xWaitX()
+{
+ BEFORE_GLX_CALL;
+ xWaitXInternal();
+ AFTER_GLX_CALL;
+}
+
+GLXContext
+GLXLibrary::xCreateContextAttribs(Display* display,
+ GLXFBConfig config,
+ GLXContext share_list,
+ Bool direct,
+ const int* attrib_list)
+{
+ BEFORE_GLX_CALL;
+ GLXContext result = xCreateContextAttribsInternal(display,
+ config,
+ share_list,
+ direct,
+ attrib_list);
+ AFTER_GLX_CALL;
+ return result;
+}
+
+int
+GLXLibrary::xGetVideoSync(unsigned int* count)
+{
+ BEFORE_GLX_CALL;
+ int result = xGetVideoSyncInternal(count);
+ AFTER_GLX_CALL;
+ return result;
+}
+
+int
+GLXLibrary::xWaitVideoSync(int divisor, int remainder, unsigned int* count)
+{
+ BEFORE_GLX_CALL;
+ int result = xWaitVideoSyncInternal(divisor, remainder, count);
+ AFTER_GLX_CALL;
+ return result;
+}
+
+void
+GLXLibrary::xSwapInterval(Display* display, GLXDrawable drawable, int interval)
+{
+ BEFORE_GLX_CALL;
+ xSwapIntervalInternal(display, drawable, interval);
+ AFTER_GLX_CALL;
+}
+
+already_AddRefed<GLContextGLX>
+GLContextGLX::CreateGLContext(CreateContextFlags flags, const SurfaceCaps& caps,
+ GLContextGLX* shareContext, bool isOffscreen,
+ Display* display, GLXDrawable drawable, GLXFBConfig cfg,
+ bool deleteDrawable, gfxXlibSurface* pixmap,
+ ContextProfile profile)
+{
+ GLXLibrary& glx = sGLXLibrary;
+
+ int db = 0;
+ int err = glx.xGetFBConfigAttrib(display, cfg,
+ LOCAL_GLX_DOUBLEBUFFER, &db);
+ if (LOCAL_GLX_BAD_ATTRIBUTE != err) {
+ if (ShouldSpew()) {
+ printf("[GLX] FBConfig is %sdouble-buffered\n", db ? "" : "not ");
+ }
+ }
+
+ GLXContext context;
+ RefPtr<GLContextGLX> glContext;
+ bool error;
+
+ OffMainThreadScopedXErrorHandler xErrorHandler;
+
+ do {
+ error = false;
+
+ GLXContext glxContext = shareContext ? shareContext->mContext : nullptr;
+ if (glx.HasCreateContextAttribs()) {
+ AutoTArray<int, 11> attrib_list;
+ if (glx.HasRobustness()) {
+ int robust_attribs[] = {
+ LOCAL_GL_CONTEXT_FLAGS_ARB, LOCAL_GL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
+ LOCAL_GL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, LOCAL_GL_LOSE_CONTEXT_ON_RESET_ARB,
+ };
+ attrib_list.AppendElements(robust_attribs, MOZ_ARRAY_LENGTH(robust_attribs));
+ }
+ if (profile == ContextProfile::OpenGLCore) {
+ int core_attribs[] = {
+ LOCAL_GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
+ LOCAL_GLX_CONTEXT_MINOR_VERSION_ARB, 2,
+ LOCAL_GLX_CONTEXT_FLAGS_ARB, LOCAL_GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
+ };
+ attrib_list.AppendElements(core_attribs, MOZ_ARRAY_LENGTH(core_attribs));
+ };
+ attrib_list.AppendElement(0);
+
+ context = glx.xCreateContextAttribs(
+ display,
+ cfg,
+ glxContext,
+ True,
+ attrib_list.Elements());
+ } else {
+ context = glx.xCreateNewContext(
+ display,
+ cfg,
+ LOCAL_GLX_RGBA_TYPE,
+ glxContext,
+ True);
+ }
+
+ if (context) {
+ glContext = new GLContextGLX(flags, caps, shareContext, isOffscreen, display,
+ drawable, context, deleteDrawable, db, pixmap,
+ profile);
+ if (!glContext->Init())
+ error = true;
+ } else {
+ error = true;
+ }
+
+ error |= xErrorHandler.SyncAndGetError(display);
+
+ if (error) {
+ if (shareContext) {
+ shareContext = nullptr;
+ continue;
+ }
+
+ NS_WARNING("Failed to create GLXContext!");
+ glContext = nullptr; // note: this must be done while the graceful X error handler is set,
+ // because glxMakeCurrent can give a GLXBadDrawable error
+ }
+
+ return glContext.forget();
+ } while (true);
+}
+
+GLContextGLX::~GLContextGLX()
+{
+ MarkDestroyed();
+
+ // Wrapped context should not destroy glxContext/Surface
+ if (!mOwnsContext) {
+ return;
+ }
+
+ // see bug 659842 comment 76
+#ifdef DEBUG
+ bool success =
+#endif
+ mGLX->xMakeCurrent(mDisplay, X11None, nullptr);
+ MOZ_ASSERT(success,
+ "glXMakeCurrent failed to release GL context before we call "
+ "glXDestroyContext!");
+
+ mGLX->xDestroyContext(mDisplay, mContext);
+
+ if (mDeleteDrawable) {
+ mGLX->xDestroyPixmap(mDisplay, mDrawable);
+ }
+}
+
+
+bool
+GLContextGLX::Init()
+{
+ SetupLookupFunction();
+ if (!InitWithPrefix("gl", true)) {
+ return false;
+ }
+
+ // EXT_framebuffer_object is not supported on Core contexts
+ // so we'll also check for ARB_framebuffer_object
+ if (!IsExtensionSupported(EXT_framebuffer_object) && !IsSupported(GLFeature::framebuffer_object))
+ return false;
+
+ return true;
+}
+
+bool
+GLContextGLX::MakeCurrentImpl(bool aForce)
+{
+ bool succeeded = true;
+
+ // With the ATI FGLRX driver, glxMakeCurrent is very slow even when the context doesn't change.
+ // (This is not the case with other drivers such as NVIDIA).
+ // So avoid calling it more than necessary. Since GLX documentation says that:
+ // "glXGetCurrentContext returns client-side information.
+ // It does not make a round trip to the server."
+ // I assume that it's not worth using our own TLS slot here.
+ if (aForce || mGLX->xGetCurrentContext() != mContext) {
+ if (mGLX->IsMesa()) {
+ // Read into the event queue to ensure that Mesa receives a
+ // DRI2InvalidateBuffers event before drawing. See bug 1280653.
+ Unused << XPending(mDisplay);
+ }
+
+ succeeded = mGLX->xMakeCurrent(mDisplay, mDrawable, mContext);
+ NS_ASSERTION(succeeded, "Failed to make GL context current!");
+
+ if (!IsOffscreen() && mGLX->SupportsSwapControl()) {
+ // Many GLX implementations default to blocking until the next
+ // VBlank when calling glXSwapBuffers. We want to run unthrottled
+ // in ASAP mode. See bug 1280744.
+ const bool isASAP = (gfxPrefs::LayoutFrameRate() == 0);
+ mGLX->xSwapInterval(mDisplay, mDrawable, isASAP ? 0 : 1);
+ }
+ }
+
+ return succeeded;
+}
+
+bool
+GLContextGLX::IsCurrent() {
+ return mGLX->xGetCurrentContext() == mContext;
+}
+
+bool
+GLContextGLX::SetupLookupFunction()
+{
+ mLookupFunc = (PlatformLookupFunction)&GLXLibrary::xGetProcAddress;
+ return true;
+}
+
+bool
+GLContextGLX::IsDoubleBuffered() const
+{
+ return mDoubleBuffered;
+}
+
+bool
+GLContextGLX::SupportsRobustness() const
+{
+ return mGLX->HasRobustness();
+}
+
+bool
+GLContextGLX::SwapBuffers()
+{
+ if (!mDoubleBuffered)
+ return false;
+ mGLX->xSwapBuffers(mDisplay, mDrawable);
+ return true;
+}
+
+bool
+GLContextGLX::OverrideDrawable(GLXDrawable drawable)
+{
+ if (Screen())
+ Screen()->AssureBlitted();
+ Bool result = mGLX->xMakeCurrent(mDisplay, drawable, mContext);
+ return result;
+}
+
+bool
+GLContextGLX::RestoreDrawable()
+{
+ return mGLX->xMakeCurrent(mDisplay, mDrawable, mContext);
+}
+
+GLContextGLX::GLContextGLX(
+ CreateContextFlags flags,
+ const SurfaceCaps& caps,
+ GLContext* shareContext,
+ bool isOffscreen,
+ Display* aDisplay,
+ GLXDrawable aDrawable,
+ GLXContext aContext,
+ bool aDeleteDrawable,
+ bool aDoubleBuffered,
+ gfxXlibSurface* aPixmap,
+ ContextProfile profile)
+ : GLContext(flags, caps, shareContext, isOffscreen),
+ mContext(aContext),
+ mDisplay(aDisplay),
+ mDrawable(aDrawable),
+ mDeleteDrawable(aDeleteDrawable),
+ mDoubleBuffered(aDoubleBuffered),
+ mGLX(&sGLXLibrary),
+ mPixmap(aPixmap),
+ mOwnsContext(true)
+{
+ MOZ_ASSERT(mGLX);
+ // See 899855
+ SetProfileVersion(profile, 200);
+}
+
+
+static GLContextGLX*
+GetGlobalContextGLX()
+{
+ return static_cast<GLContextGLX*>(GLContextProviderGLX::GetGlobalContext());
+}
+
+static bool
+AreCompatibleVisuals(Visual* one, Visual* two)
+{
+ if (one->c_class != two->c_class) {
+ return false;
+ }
+
+ if (one->red_mask != two->red_mask ||
+ one->green_mask != two->green_mask ||
+ one->blue_mask != two->blue_mask) {
+ return false;
+ }
+
+ if (one->bits_per_rgb != two->bits_per_rgb) {
+ return false;
+ }
+
+ return true;
+}
+
+static StaticRefPtr<GLContext> gGlobalContext;
+
+already_AddRefed<GLContext>
+GLContextProviderGLX::CreateWrappingExisting(void* aContext, void* aSurface)
+{
+ if (!sGLXLibrary.EnsureInitialized()) {
+ return nullptr;
+ }
+
+ if (aContext && aSurface) {
+ SurfaceCaps caps = SurfaceCaps::Any();
+ RefPtr<GLContextGLX> glContext =
+ new GLContextGLX(CreateContextFlags::NONE, caps,
+ nullptr, // SharedContext
+ false, // Offscreen
+ (Display*)DefaultXDisplay(), // Display
+ (GLXDrawable)aSurface, (GLXContext)aContext,
+ false, // aDeleteDrawable,
+ true,
+ (gfxXlibSurface*)nullptr,
+ ContextProfile::OpenGLCompatibility);
+
+ glContext->mOwnsContext = false;
+ gGlobalContext = glContext;
+
+ return glContext.forget();
+ }
+
+ return nullptr;
+}
+
+already_AddRefed<GLContext>
+CreateForWidget(Display* aXDisplay, Window aXWindow, bool aForceAccelerated)
+{
+ if (!sGLXLibrary.EnsureInitialized()) {
+ return nullptr;
+ }
+
+ // Currently, we take whatever Visual the window already has, and
+ // try to create an fbconfig for that visual. This isn't
+ // necessarily what we want in the long run; an fbconfig may not
+ // be available for the existing visual, or if it is, the GL
+ // performance might be suboptimal. But using the existing visual
+ // is a relatively safe intermediate step.
+
+ if (!aXDisplay) {
+ NS_ERROR("X Display required for GLX Context provider");
+ return nullptr;
+ }
+
+ int xscreen = DefaultScreen(aXDisplay);
+
+ ScopedXFree<GLXFBConfig> cfgs;
+ GLXFBConfig config;
+ int visid;
+ if (!GLContextGLX::FindFBConfigForWindow(aXDisplay, xscreen, aXWindow, &cfgs,
+ &config, &visid))
+ {
+ return nullptr;
+ }
+
+ SurfaceCaps caps = SurfaceCaps::Any();
+ GLContextGLX* shareContext = GetGlobalContextGLX();
+ RefPtr<GLContextGLX> gl = GLContextGLX::CreateGLContext(CreateContextFlags::NONE,
+ caps, shareContext, false,
+ aXDisplay, aXWindow, config,
+ false);
+ return gl.forget();
+}
+
+already_AddRefed<GLContext>
+GLContextProviderGLX::CreateForCompositorWidget(CompositorWidget* aCompositorWidget, bool aForceAccelerated)
+{
+ X11CompositorWidget* compWidget = aCompositorWidget->AsX11();
+ MOZ_ASSERT(compWidget);
+
+ return CreateForWidget(compWidget->XDisplay(),
+ compWidget->XWindow(),
+ aForceAccelerated);
+}
+
+already_AddRefed<GLContext>
+GLContextProviderGLX::CreateForWindow(nsIWidget* aWidget, bool aForceAccelerated)
+{
+ Display* display = (Display*)aWidget->GetNativeData(NS_NATIVE_COMPOSITOR_DISPLAY);
+ Window window = GET_NATIVE_WINDOW(aWidget);
+
+ return CreateForWidget(display,
+ window,
+ aForceAccelerated);
+}
+
+static bool
+ChooseConfig(GLXLibrary* glx, Display* display, int screen, const SurfaceCaps& minCaps,
+ ScopedXFree<GLXFBConfig>* const out_scopedConfigArr,
+ GLXFBConfig* const out_config, int* const out_visid)
+{
+ ScopedXFree<GLXFBConfig>& scopedConfigArr = *out_scopedConfigArr;
+
+ if (minCaps.antialias)
+ return false;
+
+ int attribs[] = {
+ LOCAL_GLX_DRAWABLE_TYPE, LOCAL_GLX_PIXMAP_BIT,
+ LOCAL_GLX_X_RENDERABLE, True,
+ LOCAL_GLX_RED_SIZE, 8,
+ LOCAL_GLX_GREEN_SIZE, 8,
+ LOCAL_GLX_BLUE_SIZE, 8,
+ LOCAL_GLX_ALPHA_SIZE, minCaps.alpha ? 8 : 0,
+ LOCAL_GLX_DEPTH_SIZE, minCaps.depth ? 16 : 0,
+ LOCAL_GLX_STENCIL_SIZE, minCaps.stencil ? 8 : 0,
+ 0
+ };
+
+ int numConfigs = 0;
+ scopedConfigArr = glx->xChooseFBConfig(display, screen, attribs, &numConfigs);
+ if (!scopedConfigArr || !numConfigs)
+ return false;
+
+ // Issues with glxChooseFBConfig selection and sorting:
+ // * ALPHA_SIZE is sorted as 'largest total RGBA bits first'. If we don't request
+ // alpha bits, we'll probably get RGBA anyways, since 32 is more than 24.
+ // * DEPTH_SIZE is sorted largest first, including for `0` inputs.
+ // * STENCIL_SIZE is smallest first, but it might return `8` even though we ask for
+ // `0`.
+
+ // For now, we don't care about these. We *will* care when we do XPixmap sharing.
+
+ for (int i = 0; i < numConfigs; ++i) {
+ GLXFBConfig curConfig = scopedConfigArr[i];
+
+ int visid;
+ if (glx->xGetFBConfigAttrib(display, curConfig, LOCAL_GLX_VISUAL_ID, &visid)
+ != Success)
+ {
+ continue;
+ }
+
+ if (!visid)
+ continue;
+
+ *out_config = curConfig;
+ *out_visid = visid;
+ return true;
+ }
+
+ return false;
+}
+
+bool
+GLContextGLX::FindFBConfigForWindow(Display* display, int screen, Window window,
+ ScopedXFree<GLXFBConfig>* const out_scopedConfigArr,
+ GLXFBConfig* const out_config, int* const out_visid)
+{
+ ScopedXFree<GLXFBConfig>& cfgs = *out_scopedConfigArr;
+ int numConfigs;
+ if (sGLXLibrary.IsATI() ||
+ !sGLXLibrary.GLXVersionCheck(1, 3)) {
+ const int attribs[] = {
+ LOCAL_GLX_DOUBLEBUFFER, False,
+ 0
+ };
+ cfgs = sGLXLibrary.xChooseFBConfig(display,
+ screen,
+ attribs,
+ &numConfigs);
+ } else {
+ cfgs = sGLXLibrary.xGetFBConfigs(display,
+ screen,
+ &numConfigs);
+ }
+
+ if (!cfgs) {
+ NS_WARNING("[GLX] glXGetFBConfigs() failed");
+ return false;
+ }
+ NS_ASSERTION(numConfigs > 0, "No FBConfigs found!");
+
+ // XXX the visual ID is almost certainly the LOCAL_GLX_FBCONFIG_ID, so
+ // we could probably do this first and replace the glXGetFBConfigs
+ // with glXChooseConfigs. Docs are sparklingly clear as always.
+ XWindowAttributes windowAttrs;
+ if (!XGetWindowAttributes(display, window, &windowAttrs)) {
+ NS_WARNING("[GLX] XGetWindowAttributes() failed");
+ return false;
+ }
+ const VisualID windowVisualID = XVisualIDFromVisual(windowAttrs.visual);
+#ifdef DEBUG
+ printf("[GLX] window %lx has VisualID 0x%lx\n", window, windowVisualID);
+#endif
+
+ for (int i = 0; i < numConfigs; i++) {
+ int visid = X11None;
+ sGLXLibrary.xGetFBConfigAttrib(display, cfgs[i], LOCAL_GLX_VISUAL_ID, &visid);
+ if (!visid) {
+ continue;
+ }
+ if (sGLXLibrary.IsATI()) {
+ int depth;
+ Visual* visual;
+ FindVisualAndDepth(display, visid, &visual, &depth);
+ if (depth == windowAttrs.depth &&
+ AreCompatibleVisuals(windowAttrs.visual, visual)) {
+ *out_config = cfgs[i];
+ *out_visid = visid;
+ return true;
+ }
+ } else {
+ if (windowVisualID == static_cast<VisualID>(visid)) {
+ *out_config = cfgs[i];
+ *out_visid = visid;
+ return true;
+ }
+ }
+ }
+
+ NS_WARNING("[GLX] Couldn't find a FBConfig matching window visual");
+ return false;
+}
+
+static already_AddRefed<GLContextGLX>
+CreateOffscreenPixmapContext(CreateContextFlags flags, const IntSize& size,
+ const SurfaceCaps& minCaps, nsACString* const out_failureId,
+ ContextProfile profile = ContextProfile::OpenGLCompatibility)
+{
+ GLXLibrary* glx = &sGLXLibrary;
+ if (!glx->EnsureInitialized())
+ return nullptr;
+
+ Display* display = DefaultXDisplay();
+ int screen = DefaultScreen(display);
+
+ ScopedXFree<GLXFBConfig> scopedConfigArr;
+ GLXFBConfig config;
+ int visid;
+ if (!ChooseConfig(glx, display, screen, minCaps, &scopedConfigArr, &config, &visid)) {
+ NS_WARNING("Failed to find a compatible config.");
+ return nullptr;
+ }
+
+ Visual* visual;
+ int depth;
+ FindVisualAndDepth(display, visid, &visual, &depth);
+
+ OffMainThreadScopedXErrorHandler xErrorHandler;
+ bool error = false;
+
+ Drawable drawable;
+ GLXPixmap pixmap = 0;
+
+ gfx::IntSize dummySize(16, 16);
+ RefPtr<gfxXlibSurface> surface = gfxXlibSurface::Create(DefaultScreenOfDisplay(display),
+ visual,
+ dummySize);
+ if (surface->CairoStatus() != 0) {
+ mozilla::Unused << xErrorHandler.SyncAndGetError(display);
+ return nullptr;
+ }
+
+ // Handle slightly different signature between glXCreatePixmap and
+ // its pre-GLX-1.3 extension equivalent (though given the ABI, we
+ // might not need to).
+ drawable = surface->XDrawable();
+ if (glx->GLXVersionCheck(1, 3)) {
+ pixmap = glx->xCreatePixmap(display, config, drawable, nullptr);
+ } else {
+ pixmap = glx->xCreateGLXPixmapWithConfig(display, config, drawable);
+ }
+
+ if (pixmap == 0) {
+ error = true;
+ }
+
+ bool serverError = xErrorHandler.SyncAndGetError(display);
+ if (error || serverError)
+ return nullptr;
+
+ GLContextGLX* shareContext = GetGlobalContextGLX();
+ return GLContextGLX::CreateGLContext(flags, minCaps, shareContext, true, display,
+ pixmap, config, true, surface, profile);
+}
+
+/*static*/ already_AddRefed<GLContext>
+GLContextProviderGLX::CreateHeadless(CreateContextFlags flags,
+ nsACString* const out_failureId)
+{
+ IntSize dummySize = IntSize(16, 16);
+ SurfaceCaps dummyCaps = SurfaceCaps::Any();
+ return CreateOffscreenPixmapContext(flags, dummySize, dummyCaps, out_failureId);
+}
+
+/*static*/ already_AddRefed<GLContext>
+GLContextProviderGLX::CreateOffscreen(const IntSize& size,
+ const SurfaceCaps& minCaps,
+ CreateContextFlags flags,
+ nsACString* const out_failureId)
+{
+ SurfaceCaps minBackbufferCaps = minCaps;
+ if (minCaps.antialias) {
+ minBackbufferCaps.antialias = false;
+ minBackbufferCaps.depth = false;
+ minBackbufferCaps.stencil = false;
+ }
+
+ ContextProfile profile = ContextProfile::OpenGLCore;
+ if (flags & CreateContextFlags::REQUIRE_COMPAT_PROFILE) {
+ profile = ContextProfile::OpenGLCompatibility;
+ }
+
+ RefPtr<GLContext> gl;
+ gl = CreateOffscreenPixmapContext(flags, size, minBackbufferCaps, out_failureId,
+ profile);
+ if (!gl)
+ return nullptr;
+
+ if (!gl->InitOffscreen(size, minCaps)) {
+ *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_GLX_INIT");
+ return nullptr;
+ }
+
+ return gl.forget();
+}
+
+/*static*/ GLContext*
+GLContextProviderGLX::GetGlobalContext()
+{
+ // TODO: get GLX context sharing to work well with multiple threads
+ if (gfxEnv::DisableContextSharingGlx())
+ return nullptr;
+
+ static bool triedToCreateContext = false;
+ if (!triedToCreateContext) {
+ triedToCreateContext = true;
+
+ MOZ_RELEASE_ASSERT(!gGlobalContext, "GFX: Global GL context already initialized.");
+ nsCString discardFailureId;
+ RefPtr<GLContext> temp = CreateHeadless(CreateContextFlags::NONE, &discardFailureId);
+ gGlobalContext = temp;
+ }
+
+ return gGlobalContext;
+}
+
+/*static*/ void
+GLContextProviderGLX::Shutdown()
+{
+ gGlobalContext = nullptr;
+}
+
+} /* namespace gl */
+} /* namespace mozilla */
+
diff --git a/gfx/gl/GLContextProviderImpl.h b/gfx/gl/GLContextProviderImpl.h
new file mode 100644
index 0000000000..7b63905e64
--- /dev/null
+++ b/gfx/gl/GLContextProviderImpl.h
@@ -0,0 +1,130 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef IN_GL_CONTEXT_PROVIDER_H
+#error GLContextProviderImpl.h must only be included from GLContextProvider.h
+#endif
+
+#ifndef GL_CONTEXT_PROVIDER_NAME
+#error GL_CONTEXT_PROVIDER_NAME not defined
+#endif
+#if defined(ANDROID)
+typedef void* EGLSurface;
+#endif // defined(ANDROID)
+
+class GL_CONTEXT_PROVIDER_NAME
+{
+public:
+ /**
+ * Create a context that renders to the surface of the widget represented by
+ * the compositor widget that is passed in. The context is always created
+ * with an RGB pixel format, with no alpha, depth or stencil.
+ * If any of those features are needed, either use a framebuffer, or
+ * use CreateOffscreen.
+ *
+ * This context will attempt to share resources with all other window
+ * contexts. As such, it's critical that resources allocated that are not
+ * needed by other contexts be deleted before the context is destroyed.
+ *
+ * The GetSharedContext() method will return non-null if sharing
+ * was successful.
+ *
+ * Note: a context created for a widget /must not/ hold a strong
+ * reference to the widget; otherwise a cycle can be created through
+ * a GL layer manager.
+ *
+ * @param aCompositorWidget Widget whose surface to create a context for
+ * @param aForceAccelerated true if only accelerated contexts are allowed
+ *
+ * @return Context to use for the window
+ */
+ static already_AddRefed<GLContext>
+ CreateForCompositorWidget(mozilla::widget::CompositorWidget* aCompositorWidget, bool aForceAccelerated);
+
+ /**
+ * Create a context that renders to the surface of the widget that is
+ * passed in. The context is always created with an RGB pixel format,
+ * with no alpha, depth or stencil. If any of those features are needed,
+ * either use a framebuffer, or use CreateOffscreen.
+ *
+ * This context will attempt to share resources with all other window
+ * contexts. As such, it's critical that resources allocated that are not
+ * needed by other contexts be deleted before the context is destroyed.
+ *
+ * The GetSharedContext() method will return non-null if sharing
+ * was successful.
+ *
+ * Note: a context created for a widget /must not/ hold a strong
+ * reference to the widget; otherwise a cycle can be created through
+ * a GL layer manager.
+ *
+ * @param aWidget Widget whose surface to create a context for
+ * @param aForceAccelerated true if only accelerated contexts are allowed
+ *
+ * @return Context to use for the window
+ */
+ static already_AddRefed<GLContext>
+ CreateForWindow(nsIWidget* aWidget, bool aForceAccelerated);
+
+ /**
+ * Create a context for offscreen rendering. The target of this
+ * context should be treated as opaque -- it might be a FBO, or a
+ * pbuffer, or some other construct. Users of this GLContext
+ * should bind framebuffer 0 directly to use this offscreen buffer.
+ *
+ * The offscreen context returned by this method will always have
+ * the ability to be rendered into a context created by a window.
+ * It might or might not share resources with the global context;
+ * query GetSharedContext() for a non-null result to check. If
+ * resource sharing can be avoided on the target platform, it will
+ * be, in order to isolate the offscreen context.
+ *
+ * @param size The initial size of this offscreen context.
+ * @param minCaps The required SurfaceCaps for this offscreen context. The resulting
+ * context *may* have more/better caps than requested, but it cannot
+ * have fewer/worse caps than requested.
+ * @param flags The set of CreateContextFlags to be used for this
+ * offscreen context.
+ *
+ * @return Context to use for offscreen rendering
+ */
+ static already_AddRefed<GLContext>
+ CreateOffscreen(const mozilla::gfx::IntSize& size,
+ const SurfaceCaps& minCaps,
+ CreateContextFlags flags,
+ nsACString* const out_failureId);
+
+ // Just create a context. We'll add offscreen stuff ourselves.
+ static already_AddRefed<GLContext>
+ CreateHeadless(CreateContextFlags flags, nsACString* const out_failureId);
+
+ /**
+ * Create wrapping Gecko GLContext for external gl context.
+ *
+ * @param aContext External context which will be wrapped by Gecko GLContext.
+ * @param aSurface External surface which is used for external context.
+ *
+ * @return Wrapping Context to use for rendering
+ */
+ static already_AddRefed<GLContext>
+ CreateWrappingExisting(void* aContext, void* aSurface);
+
+#if defined(ANDROID)
+ static EGLSurface CreateEGLSurface(void* aWindow);
+ static void DestroyEGLSurface(EGLSurface surface);
+#endif // defined(ANDROID)
+
+ /**
+ * Get a pointer to the global context, creating it if it doesn't exist.
+ */
+ static GLContext*
+ GetGlobalContext();
+
+ /**
+ * Free any resources held by this Context Provider.
+ */
+ static void
+ Shutdown();
+};
diff --git a/gfx/gl/GLContextProviderNull.cpp b/gfx/gl/GLContextProviderNull.cpp
new file mode 100644
index 0000000000..513ed2edad
--- /dev/null
+++ b/gfx/gl/GLContextProviderNull.cpp
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "GLContextProvider.h"
+
+namespace mozilla {
+namespace gl {
+
+using namespace mozilla::widget;
+
+already_AddRefed<GLContext>
+GLContextProviderNull::CreateForCompositorWidget(CompositorWidget* aCompositorWidget, bool aForceAccelerated)
+{
+ return nullptr;
+}
+
+already_AddRefed<GLContext>
+GLContextProviderNull::CreateForWindow(nsIWidget* aWidget, bool aForceAccelerated)
+{
+ return nullptr;
+}
+
+already_AddRefed<GLContext>
+GLContextProviderNull::CreateWrappingExisting(void*, void*)
+{
+ return nullptr;
+}
+
+already_AddRefed<GLContext>
+GLContextProviderNull::CreateOffscreen(const gfx::IntSize&,
+ const SurfaceCaps&,
+ CreateContextFlags,
+ nsACString* const out_failureId)
+{
+ *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_NULL");
+ return nullptr;
+}
+
+already_AddRefed<GLContext>
+GLContextProviderNull::CreateHeadless(CreateContextFlags, nsACString* const out_failureId)
+{
+ *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_NULL");
+ return nullptr;
+}
+
+GLContext*
+GLContextProviderNull::GetGlobalContext()
+{
+ return nullptr;
+}
+
+void
+GLContextProviderNull::Shutdown()
+{
+}
+
+} /* namespace gl */
+} /* namespace mozilla */
diff --git a/gfx/gl/GLContextProviderWGL.cpp b/gfx/gl/GLContextProviderWGL.cpp
new file mode 100644
index 0000000000..a1373f78f4
--- /dev/null
+++ b/gfx/gl/GLContextProviderWGL.cpp
@@ -0,0 +1,651 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "GLContextProvider.h"
+#include "GLContextWGL.h"
+#include "GLLibraryLoader.h"
+#include "nsDebug.h"
+#include "nsIWidget.h"
+#include "gfxPlatform.h"
+#include "gfxWindowsSurface.h"
+
+#include "gfxCrashReporterUtils.h"
+
+#include "prenv.h"
+
+#include "mozilla/Preferences.h"
+#include "mozilla/StaticPtr.h"
+#include "mozilla/widget/CompositorWidget.h"
+
+namespace mozilla {
+namespace gl {
+
+using namespace mozilla::gfx;
+using namespace mozilla::widget;
+
+WGLLibrary sWGLLib;
+
+HWND
+WGLLibrary::CreateDummyWindow(HDC* aWindowDC)
+{
+ WNDCLASSW wc;
+ if (!GetClassInfoW(GetModuleHandle(nullptr), L"GLContextWGLClass", &wc)) {
+ ZeroMemory(&wc, sizeof(WNDCLASSW));
+ wc.style = CS_OWNDC;
+ wc.hInstance = GetModuleHandle(nullptr);
+ wc.lpfnWndProc = DefWindowProc;
+ wc.lpszClassName = L"GLContextWGLClass";
+ if (!RegisterClassW(&wc)) {
+ NS_WARNING("Failed to register GLContextWGLClass?!");
+ // er. failed to register our class?
+ return nullptr;
+ }
+ }
+
+ HWND win = CreateWindowW(L"GLContextWGLClass", L"GLContextWGL", 0,
+ 0, 0, 16, 16,
+ nullptr, nullptr, GetModuleHandle(nullptr),
+ nullptr);
+ NS_ENSURE_TRUE(win, nullptr);
+
+ HDC dc = GetDC(win);
+ NS_ENSURE_TRUE(dc, nullptr);
+
+ if (mWindowPixelFormat == 0) {
+ PIXELFORMATDESCRIPTOR pfd;
+ ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR));
+ pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
+ pfd.nVersion = 1;
+ pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
+ pfd.iPixelType = PFD_TYPE_RGBA;
+ pfd.cColorBits = 24;
+ pfd.cRedBits = 8;
+ pfd.cGreenBits = 8;
+ pfd.cBlueBits = 8;
+ pfd.cAlphaBits = 8;
+ pfd.cDepthBits = 0;
+ pfd.iLayerType = PFD_MAIN_PLANE;
+
+ mWindowPixelFormat = ChoosePixelFormat(dc, &pfd);
+ }
+
+ if (!mWindowPixelFormat ||
+ !SetPixelFormat(dc, mWindowPixelFormat, nullptr))
+ {
+ NS_WARNING("SetPixelFormat failed!");
+ DestroyWindow(win);
+ return nullptr;
+ }
+
+ if (aWindowDC) {
+ *aWindowDC = dc;
+ }
+
+ return win;
+}
+
+static inline bool
+HasExtension(const char* aExtensions, const char* aRequiredExtension)
+{
+ return GLContext::ListHasExtension(
+ reinterpret_cast<const GLubyte*>(aExtensions), aRequiredExtension);
+}
+
+bool
+WGLLibrary::EnsureInitialized()
+{
+ if (mInitialized)
+ return true;
+
+ mozilla::ScopedGfxFeatureReporter reporter("WGL");
+
+ std::string libGLFilename = "Opengl32.dll";
+ // SU_SPIES_DIRECTORY is for AMD CodeXL/gDEBugger
+ if (PR_GetEnv("SU_SPIES_DIRECTORY")) {
+ libGLFilename = std::string(PR_GetEnv("SU_SPIES_DIRECTORY")) + "\\opengl32.dll";
+ }
+
+ if (!mOGLLibrary) {
+ mOGLLibrary = PR_LoadLibrary(libGLFilename.c_str());
+ if (!mOGLLibrary) {
+ NS_WARNING("Couldn't load OpenGL library.");
+ return false;
+ }
+ }
+
+ const GLLibraryLoader::SymLoadStruct earlySymbols[] = {
+ { (PRFuncPtr*) &fCreateContext, { "wglCreateContext", nullptr } },
+ { (PRFuncPtr*) &fMakeCurrent, { "wglMakeCurrent", nullptr } },
+ { (PRFuncPtr*) &fGetProcAddress, { "wglGetProcAddress", nullptr } },
+ { (PRFuncPtr*) &fDeleteContext, { "wglDeleteContext", nullptr } },
+ { (PRFuncPtr*) &fGetCurrentContext, { "wglGetCurrentContext", nullptr } },
+ { (PRFuncPtr*) &fGetCurrentDC, { "wglGetCurrentDC", nullptr } },
+ { nullptr, { nullptr } }
+ };
+
+ if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, &earlySymbols[0])) {
+ NS_WARNING("Couldn't find required entry points in OpenGL DLL (early init)");
+ return false;
+ }
+
+ // This is ridiculous -- we have to actually create a context to
+ // get the OpenGL ICD to load.
+ mWindow = CreateDummyWindow(&mWindowDC);
+ NS_ENSURE_TRUE(mWindow, false);
+
+ // create rendering context
+ mWindowGLContext = fCreateContext(mWindowDC);
+ NS_ENSURE_TRUE(mWindowGLContext, false);
+
+ if (!fMakeCurrent(mWindowDC, mWindowGLContext)) {
+ NS_WARNING("wglMakeCurrent failed");
+ return false;
+ }
+
+ const auto curCtx = fGetCurrentContext();
+ const auto curDC = fGetCurrentDC();
+
+ const auto lookupFunc = (GLLibraryLoader::PlatformLookupFunction)fGetProcAddress;
+
+ // Now we can grab all the other symbols that we couldn't without having
+ // a context current.
+ const GLLibraryLoader::SymLoadStruct pbufferSymbols[] = {
+ { (PRFuncPtr*) &fCreatePbuffer, { "wglCreatePbufferARB", "wglCreatePbufferEXT", nullptr } },
+ { (PRFuncPtr*) &fDestroyPbuffer, { "wglDestroyPbufferARB", "wglDestroyPbufferEXT", nullptr } },
+ { (PRFuncPtr*) &fGetPbufferDC, { "wglGetPbufferDCARB", "wglGetPbufferDCEXT", nullptr } },
+ { (PRFuncPtr*) &fBindTexImage, { "wglBindTexImageARB", "wglBindTexImageEXT", nullptr } },
+ { (PRFuncPtr*) &fReleaseTexImage, { "wglReleaseTexImageARB", "wglReleaseTexImageEXT", nullptr } },
+ { nullptr, { nullptr } }
+ };
+
+ const GLLibraryLoader::SymLoadStruct pixFmtSymbols[] = {
+ { (PRFuncPtr*) &fChoosePixelFormat, { "wglChoosePixelFormatARB", "wglChoosePixelFormatEXT", nullptr } },
+ { (PRFuncPtr*) &fGetPixelFormatAttribiv, { "wglGetPixelFormatAttribivARB", "wglGetPixelFormatAttribivEXT", nullptr } },
+ { nullptr, { nullptr } }
+ };
+
+ if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, &pbufferSymbols[0], lookupFunc)) {
+ // this isn't an error, just means that pbuffers aren't supported
+ fCreatePbuffer = nullptr;
+ }
+
+ if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, &pixFmtSymbols[0], lookupFunc)) {
+ // this isn't an error, just means that we don't have the pixel format extension
+ fChoosePixelFormat = nullptr;
+ }
+
+ const GLLibraryLoader::SymLoadStruct extensionsSymbols[] = {
+ { (PRFuncPtr*) &fGetExtensionsString, { "wglGetExtensionsStringARB", nullptr} },
+ { nullptr, { nullptr } }
+ };
+
+ const GLLibraryLoader::SymLoadStruct robustnessSymbols[] = {
+ { (PRFuncPtr*) &fCreateContextAttribs, { "wglCreateContextAttribsARB", nullptr} },
+ { nullptr, { nullptr } }
+ };
+
+ const GLLibraryLoader::SymLoadStruct dxInteropSymbols[] = {
+ { (PRFuncPtr*)&fDXSetResourceShareHandle,{ "wglDXSetResourceShareHandleNV", nullptr } },
+ { (PRFuncPtr*)&fDXOpenDevice, { "wglDXOpenDeviceNV", nullptr } },
+ { (PRFuncPtr*)&fDXCloseDevice, { "wglDXCloseDeviceNV", nullptr } },
+ { (PRFuncPtr*)&fDXRegisterObject, { "wglDXRegisterObjectNV", nullptr } },
+ { (PRFuncPtr*)&fDXUnregisterObject, { "wglDXUnregisterObjectNV", nullptr } },
+ { (PRFuncPtr*)&fDXObjectAccess, { "wglDXObjectAccessNV", nullptr } },
+ { (PRFuncPtr*)&fDXLockObjects, { "wglDXLockObjectsNV", nullptr } },
+ { (PRFuncPtr*)&fDXUnlockObjects, { "wglDXUnlockObjectsNV", nullptr } },
+ { nullptr, { nullptr } }
+ };
+
+ if (GLLibraryLoader::LoadSymbols(mOGLLibrary, &extensionsSymbols[0], lookupFunc)) {
+ const char* extString = fGetExtensionsString(mWindowDC);
+ MOZ_ASSERT(extString);
+ MOZ_ASSERT(HasExtension(extString, "WGL_ARB_extensions_string"));
+
+ if (HasExtension(extString, "WGL_ARB_create_context")) {
+ if (GLLibraryLoader::LoadSymbols(mOGLLibrary, &robustnessSymbols[0], lookupFunc)) {
+ if (HasExtension(extString, "WGL_ARB_create_context_robustness")) {
+ mHasRobustness = true;
+ }
+ } else {
+ NS_ERROR("WGL supports ARB_create_context without supplying its functions.");
+ fCreateContextAttribs = nullptr;
+ }
+ }
+
+ ////
+
+ mHasDXInterop = HasExtension(extString, "WGL_NV_DX_interop");
+ mHasDXInterop2 = HasExtension(extString, "WGL_NV_DX_interop2");
+
+ nsCString blocklistId;
+ if (gfxUtils::IsFeatureBlacklisted(nullptr, nsIGfxInfo::FEATURE_DX_INTEROP2,
+ &blocklistId) &&
+ !gfxPrefs::IgnoreDXInterop2Blacklist())
+ {
+ mHasDXInterop2 = false;
+ }
+
+ if (mHasDXInterop || mHasDXInterop2) {
+ if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, &dxInteropSymbols[0],
+ lookupFunc))
+ {
+ NS_ERROR("WGL supports NV_DX_interop(2) without supplying its functions.");
+ fDXSetResourceShareHandle = nullptr;
+ fDXOpenDevice = nullptr;
+ fDXCloseDevice = nullptr;
+ fDXRegisterObject = nullptr;
+ fDXUnregisterObject = nullptr;
+ fDXObjectAccess = nullptr;
+ fDXLockObjects = nullptr;
+ fDXUnlockObjects = nullptr;
+
+ mHasDXInterop = false;
+ mHasDXInterop2 = false;
+ }
+ }
+ }
+
+ // reset back to the previous context, just in case
+ fMakeCurrent(curDC, curCtx);
+
+ if (mHasRobustness) {
+ fDeleteContext(mWindowGLContext);
+
+ const int attribs[] = {
+ LOCAL_WGL_CONTEXT_FLAGS_ARB, LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
+ LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB,
+ 0
+ };
+
+ mWindowGLContext = fCreateContextAttribs(mWindowDC, nullptr, attribs);
+ if (!mWindowGLContext) {
+ mHasRobustness = false;
+ mWindowGLContext = fCreateContext(mWindowDC);
+ }
+ }
+
+ mInitialized = true;
+
+ reporter.SetSuccessful();
+ return true;
+}
+
+GLContextWGL::GLContextWGL(CreateContextFlags flags, const SurfaceCaps& caps,
+ bool isOffscreen, HDC aDC, HGLRC aContext, HWND aWindow)
+ : GLContext(flags, caps, nullptr, isOffscreen),
+ mDC(aDC),
+ mContext(aContext),
+ mWnd(aWindow),
+ mPBuffer(nullptr),
+ mPixelFormat(0),
+ mIsDoubleBuffered(false)
+{
+ // See 899855
+ SetProfileVersion(ContextProfile::OpenGLCompatibility, 200);
+}
+
+GLContextWGL::GLContextWGL(CreateContextFlags flags, const SurfaceCaps& caps,
+ bool isOffscreen, HANDLE aPbuffer, HDC aDC, HGLRC aContext,
+ int aPixelFormat)
+ : GLContext(flags, caps, nullptr, isOffscreen),
+ mDC(aDC),
+ mContext(aContext),
+ mWnd(nullptr),
+ mPBuffer(aPbuffer),
+ mPixelFormat(aPixelFormat),
+ mIsDoubleBuffered(false)
+{
+ // See 899855
+ SetProfileVersion(ContextProfile::OpenGLCompatibility, 200);
+}
+
+GLContextWGL::~GLContextWGL()
+{
+ MarkDestroyed();
+
+ sWGLLib.fDeleteContext(mContext);
+
+ if (mPBuffer)
+ sWGLLib.fDestroyPbuffer(mPBuffer);
+ if (mWnd)
+ DestroyWindow(mWnd);
+}
+
+bool
+GLContextWGL::Init()
+{
+ if (!mDC || !mContext)
+ return false;
+
+ // see bug 929506 comment 29. wglGetProcAddress requires a current context.
+ if (!sWGLLib.fMakeCurrent(mDC, mContext))
+ return false;
+
+ SetupLookupFunction();
+ if (!InitWithPrefix("gl", true))
+ return false;
+
+ return true;
+}
+
+bool
+GLContextWGL::MakeCurrentImpl(bool aForce)
+{
+ BOOL succeeded = true;
+
+ // wglGetCurrentContext seems to just pull the HGLRC out
+ // of its TLS slot, so no need to do our own tls slot.
+ // You would think that wglMakeCurrent would avoid doing
+ // work if mContext was already current, but not so much..
+ if (aForce || sWGLLib.fGetCurrentContext() != mContext) {
+ succeeded = sWGLLib.fMakeCurrent(mDC, mContext);
+ NS_ASSERTION(succeeded, "Failed to make GL context current!");
+ }
+
+ return succeeded;
+}
+
+bool
+GLContextWGL::IsCurrent()
+{
+ return sWGLLib.fGetCurrentContext() == mContext;
+}
+
+void
+GLContextWGL::SetIsDoubleBuffered(bool aIsDB)
+{
+ mIsDoubleBuffered = aIsDB;
+}
+
+bool
+GLContextWGL::IsDoubleBuffered() const
+{
+ return mIsDoubleBuffered;
+}
+
+bool
+GLContextWGL::SupportsRobustness() const
+{
+ return sWGLLib.HasRobustness();
+}
+
+bool
+GLContextWGL::SwapBuffers() {
+ if (!mIsDoubleBuffered)
+ return false;
+ return ::SwapBuffers(mDC);
+}
+
+bool
+GLContextWGL::SetupLookupFunction()
+{
+ // Make sure that we have a ref to the OGL library;
+ // when run under CodeXL, wglGetProcAddress won't return
+ // the right thing for some core functions.
+ MOZ_ASSERT(mLibrary == nullptr);
+
+ mLibrary = sWGLLib.GetOGLLibrary();
+ mLookupFunc = (PlatformLookupFunction)sWGLLib.fGetProcAddress;
+ return true;
+}
+
+static bool
+GetMaxSize(HDC hDC, int format, IntSize& size)
+{
+ int query[] = {LOCAL_WGL_MAX_PBUFFER_WIDTH_ARB, LOCAL_WGL_MAX_PBUFFER_HEIGHT_ARB};
+ int result[2];
+
+ // (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, int* piValues)
+ if (!sWGLLib.fGetPixelFormatAttribiv(hDC, format, 0, 2, query, result))
+ return false;
+
+ size.width = result[0];
+ size.height = result[1];
+ return true;
+}
+
+static bool
+IsValidSizeForFormat(HDC hDC, int format,
+ const IntSize& requested)
+{
+ IntSize max;
+ if (!GetMaxSize(hDC, format, max))
+ return true;
+
+ if (requested.width > max.width)
+ return false;
+ if (requested.height > max.height)
+ return false;
+
+ return true;
+}
+
+static GLContextWGL*
+GetGlobalContextWGL()
+{
+ return static_cast<GLContextWGL*>(GLContextProviderWGL::GetGlobalContext());
+}
+
+already_AddRefed<GLContext>
+GLContextProviderWGL::CreateWrappingExisting(void*, void*)
+{
+ return nullptr;
+}
+
+already_AddRefed<GLContext>
+GLContextProviderWGL::CreateForCompositorWidget(CompositorWidget* aCompositorWidget, bool aForceAccelerated)
+{
+ return CreateForWindow(aCompositorWidget->RealWidget(), aForceAccelerated);
+}
+
+already_AddRefed<GLContext>
+GLContextProviderWGL::CreateForWindow(nsIWidget* aWidget, bool aForceAccelerated)
+{
+ if (!sWGLLib.EnsureInitialized()) {
+ return nullptr;
+ }
+
+ /**
+ * We need to make sure we call SetPixelFormat -after- calling
+ * EnsureInitialized, otherwise it can load/unload the dll and
+ * wglCreateContext will fail.
+ */
+
+ HDC dc = (HDC)aWidget->GetNativeData(NS_NATIVE_GRAPHIC);
+
+ SetPixelFormat(dc, sWGLLib.GetWindowPixelFormat(), nullptr);
+ HGLRC context;
+
+ if (sWGLLib.HasRobustness()) {
+ int attribs[] = {
+ LOCAL_WGL_CONTEXT_FLAGS_ARB, LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
+ LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB,
+ 0
+ };
+
+ context = sWGLLib.fCreateContextAttribs(dc, nullptr, attribs);
+ } else {
+ context = sWGLLib.fCreateContext(dc);
+ }
+
+ if (!context) {
+ return nullptr;
+ }
+
+ SurfaceCaps caps = SurfaceCaps::ForRGBA();
+ RefPtr<GLContextWGL> glContext = new GLContextWGL(CreateContextFlags::NONE, caps,
+ false, dc, context);
+ if (!glContext->Init()) {
+ return nullptr;
+ }
+
+ glContext->SetIsDoubleBuffered(true);
+
+ return glContext.forget();
+}
+
+static already_AddRefed<GLContextWGL>
+CreatePBufferOffscreenContext(CreateContextFlags flags, const IntSize& aSize)
+{
+ WGLLibrary& wgl = sWGLLib;
+
+ const int pfAttribs[] = {
+ LOCAL_WGL_SUPPORT_OPENGL_ARB, LOCAL_GL_TRUE,
+ LOCAL_WGL_ACCELERATION_ARB, LOCAL_WGL_FULL_ACCELERATION_ARB,
+
+ LOCAL_WGL_DRAW_TO_PBUFFER_ARB, LOCAL_GL_TRUE,
+ LOCAL_WGL_DOUBLE_BUFFER_ARB, LOCAL_GL_FALSE,
+ LOCAL_WGL_STEREO_ARB, LOCAL_GL_FALSE,
+
+ 0
+ };
+
+ // We only need one!
+ static const uint32_t kMaxFormats = 1024;
+ int formats[kMaxFormats];
+ uint32_t foundFormats;
+ HDC windowDC = wgl.GetWindowDC();
+ if (!wgl.fChoosePixelFormat(windowDC, pfAttribs, nullptr, kMaxFormats, formats,
+ &foundFormats)
+ || foundFormats == 0)
+ {
+ return nullptr;
+ }
+
+ // We don't care; just pick the first one.
+ int chosenFormat = formats[0];
+ if (!IsValidSizeForFormat(windowDC, chosenFormat, aSize))
+ return nullptr;
+
+ const int pbAttribs[] = { 0 };
+ HANDLE pbuffer = wgl.fCreatePbuffer(windowDC, chosenFormat, aSize.width, aSize.height,
+ pbAttribs);
+ if (!pbuffer) {
+ return nullptr;
+ }
+
+ HDC pbdc = wgl.fGetPbufferDC(pbuffer);
+ NS_ASSERTION(pbdc, "expected a dc");
+
+ HGLRC context;
+ if (wgl.HasRobustness()) {
+ const int attribs[] = {
+ LOCAL_WGL_CONTEXT_FLAGS_ARB, LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
+ LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB,
+ 0
+ };
+ context = wgl.fCreateContextAttribs(pbdc, nullptr, attribs);
+ } else {
+ context = wgl.fCreateContext(pbdc);
+ }
+
+ if (!context) {
+ wgl.fDestroyPbuffer(pbuffer);
+ return nullptr;
+ }
+
+ SurfaceCaps dummyCaps = SurfaceCaps::Any();
+ RefPtr<GLContextWGL> glContext = new GLContextWGL(flags, dummyCaps, true, pbuffer,
+ pbdc, context, chosenFormat);
+ return glContext.forget();
+}
+
+static already_AddRefed<GLContextWGL>
+CreateWindowOffscreenContext()
+{
+ HDC dc;
+ HWND win = sWGLLib.CreateDummyWindow(&dc);
+ if (!win) {
+ return nullptr;
+ }
+
+ HGLRC context = sWGLLib.fCreateContext(dc);
+ if (sWGLLib.HasRobustness()) {
+ int attribs[] = {
+ LOCAL_WGL_CONTEXT_FLAGS_ARB, LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
+ LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB,
+ 0
+ };
+
+ context = sWGLLib.fCreateContextAttribs(dc, nullptr, attribs);
+ } else {
+ context = sWGLLib.fCreateContext(dc);
+ }
+
+ if (!context) {
+ return nullptr;
+ }
+
+ SurfaceCaps caps = SurfaceCaps::ForRGBA();
+ RefPtr<GLContextWGL> glContext = new GLContextWGL(CreateContextFlags::NONE, caps,
+ true, dc, context, win);
+ return glContext.forget();
+}
+
+/*static*/ already_AddRefed<GLContext>
+GLContextProviderWGL::CreateHeadless(CreateContextFlags flags,
+ nsACString* const out_failureId)
+{
+ if (!sWGLLib.EnsureInitialized()) {
+ return nullptr;
+ }
+
+ RefPtr<GLContextWGL> glContext;
+
+ // Always try to create a pbuffer context first, because we
+ // want the context isolation.
+ if (sWGLLib.fCreatePbuffer &&
+ sWGLLib.fChoosePixelFormat)
+ {
+ IntSize dummySize = IntSize(16, 16);
+ glContext = CreatePBufferOffscreenContext(flags, dummySize);
+ }
+
+ // If it failed, then create a window context and use a FBO.
+ if (!glContext) {
+ glContext = CreateWindowOffscreenContext();
+ }
+
+ if (!glContext ||
+ !glContext->Init())
+ {
+ return nullptr;
+ }
+
+ RefPtr<GLContext> retGL = glContext.get();
+ return retGL.forget();
+}
+
+/*static*/ already_AddRefed<GLContext>
+GLContextProviderWGL::CreateOffscreen(const IntSize& size,
+ const SurfaceCaps& minCaps,
+ CreateContextFlags flags,
+ nsACString* const out_failureId)
+{
+ RefPtr<GLContext> gl = CreateHeadless(flags, out_failureId);
+ if (!gl)
+ return nullptr;
+
+ if (!gl->InitOffscreen(size, minCaps)) {
+ *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WGL_INIT");
+ return nullptr;
+ }
+
+ return gl.forget();
+}
+
+/*static*/ GLContext*
+GLContextProviderWGL::GetGlobalContext()
+{
+ return nullptr;
+}
+
+/*static*/ void
+GLContextProviderWGL::Shutdown()
+{
+}
+
+} /* namespace gl */
+} /* namespace mozilla */
diff --git a/gfx/gl/GLContextSymbols.h b/gfx/gl/GLContextSymbols.h
new file mode 100644
index 0000000000..61069e3f73
--- /dev/null
+++ b/gfx/gl/GLContextSymbols.h
@@ -0,0 +1,705 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GLCONTEXTSYMBOLS_H_
+#define GLCONTEXTSYMBOLS_H_
+
+#include "GLDefs.h"
+
+/*
+ * This file should only be included by GLContext.h, and should be
+ * autogenerated in the future.
+ */
+
+#ifndef GLAPIENTRY
+#ifdef XP_WIN
+#define GLAPIENTRY __stdcall
+#else
+#define GLAPIENTRY
+#endif
+#define GLAPI
+#endif
+
+namespace mozilla {
+namespace gl {
+
+struct GLContextSymbols
+{
+ GLContextSymbols() {
+ Zero();
+ }
+
+ void Zero() {
+ memset(this, 0, sizeof(GLContextSymbols));
+ }
+
+ typedef void (GLAPIENTRY * PFNGLACTIVETEXTUREPROC) (GLenum texture);
+ PFNGLACTIVETEXTUREPROC fActiveTexture;
+ typedef void (GLAPIENTRY * PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
+ PFNGLATTACHSHADERPROC fAttachShader;
+ typedef void (GLAPIENTRY * PFNGLBEGINQUERYPROC) (GLenum target, GLuint id);
+ PFNGLBEGINQUERYPROC fBeginQuery;
+ typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar* name);
+ PFNGLBINDATTRIBLOCATIONPROC fBindAttribLocation;
+ typedef void (GLAPIENTRY * PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
+ PFNGLBINDBUFFERPROC fBindBuffer;
+ typedef void (GLAPIENTRY * PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);
+ PFNGLBINDTEXTUREPROC fBindTexture;
+ typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYPROC) (GLuint array);
+ PFNGLBINDVERTEXARRAYPROC fBindVertexArray;
+ typedef void (GLAPIENTRY * PFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+ PFNGLBLENDCOLORPROC fBlendColor;
+ typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONPROC) (GLenum mode);
+ PFNGLBLENDEQUATIONPROC fBlendEquation;
+ typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum, GLenum);
+ PFNGLBLENDEQUATIONSEPARATEPROC fBlendEquationSeparate;
+ typedef void (GLAPIENTRY * PFNGLBLENDFUNCPROC) (GLenum, GLenum);
+ PFNGLBLENDFUNCPROC fBlendFunc;
+ typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+ PFNGLBLENDFUNCSEPARATEPROC fBlendFuncSeparate;
+ typedef void (GLAPIENTRY * PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
+ PFNGLBUFFERDATAPROC fBufferData;
+ typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
+ PFNGLBUFFERSUBDATAPROC fBufferSubData;
+ typedef void (GLAPIENTRY * PFNGLCLEARPROC) (GLbitfield);
+ PFNGLCLEARPROC fClear;
+ typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+ PFNGLCLEARBUFFERFIPROC fClearBufferfi;
+ typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat* value);
+ PFNGLCLEARBUFFERFVPROC fClearBufferfv;
+ typedef void (GLAPIENTRY * PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint* value);
+ PFNGLCLEARBUFFERIVPROC fClearBufferiv;
+ typedef void (GLAPIENTRY * PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint* value);
+ PFNGLCLEARBUFFERUIVPROC fClearBufferuiv;
+ typedef void (GLAPIENTRY * PFNGLCLEARCOLORPROC) (GLfloat, GLfloat, GLfloat, GLfloat);
+ PFNGLCLEARCOLORPROC fClearColor;
+ typedef void (GLAPIENTRY * PFNGLCLEARSTENCILPROC) (GLint);
+ PFNGLCLEARSTENCILPROC fClearStencil;
+ typedef void (GLAPIENTRY * PFNGLCOLORMASKPROC) (realGLboolean red, realGLboolean green, realGLboolean blue, realGLboolean alpha);
+ PFNGLCOLORMASKPROC fColorMask;
+ typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2D) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* pixels);
+ PFNGLCOMPRESSEDTEXIMAGE2D fCompressedTexImage2D;
+ typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* pixels);
+ PFNGLCOMPRESSEDTEXSUBIMAGE2D fCompressedTexSubImage2D;
+ typedef void (GLAPIENTRY * PFNGLCULLFACEPROC) (GLenum mode);
+ PFNGLCULLFACEPROC fCullFace;
+ typedef void (GLAPIENTRY * PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader);
+ PFNGLDETACHSHADERPROC fDetachShader;
+ typedef void (GLAPIENTRY * PFNGLDEPTHFUNCPROC) (GLenum);
+ PFNGLDEPTHFUNCPROC fDepthFunc;
+ typedef void (GLAPIENTRY * PFNGLDEPTHMASKPROC) (realGLboolean);
+ PFNGLDEPTHMASKPROC fDepthMask;
+ typedef void (GLAPIENTRY * PFNGLDISABLEPROC) (GLenum);
+ PFNGLDISABLEPROC fDisable;
+ typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint);
+ PFNGLDISABLEVERTEXATTRIBARRAYPROC fDisableVertexAttribArray;
+ typedef void (GLAPIENTRY * PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count);
+ PFNGLDRAWARRAYSPROC fDrawArrays;
+ typedef void (GLAPIENTRY * PFNGLDRAWBUFFERPROC) (GLenum mode);
+ PFNGLDRAWBUFFERPROC fDrawBuffer;
+ typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum* bufs);
+ PFNGLDRAWBUFFERSPROC fDrawBuffers;
+ typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);
+ PFNGLDRAWELEMENTSPROC fDrawElements;
+ typedef void (GLAPIENTRY * PFNGLENABLEPROC) (GLenum);
+ PFNGLENABLEPROC fEnable;
+ typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint);
+ PFNGLENABLEVERTEXATTRIBARRAYPROC fEnableVertexAttribArray;
+ typedef void (GLAPIENTRY * PFNGLFINISHPROC) (void);
+ PFNGLFINISHPROC fFinish;
+ typedef void (GLAPIENTRY * PFNGLENDQUERYPROC) (GLenum target);
+ PFNGLENDQUERYPROC fEndQuery;
+ typedef void (GLAPIENTRY * PFNGLFLUSHPROC) (void);
+ PFNGLFLUSHPROC fFlush;
+ typedef void (GLAPIENTRY * PFNGLFRONTFACEPROC) (GLenum);
+ PFNGLFRONTFACEPROC fFrontFace;
+ typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+ PFNGLGETACTIVEATTRIBPROC fGetActiveAttrib;
+ typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+ PFNGLGETACTIVEUNIFORMPROC fGetActiveUniform;
+ typedef void (GLAPIENTRY * PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders);
+ PFNGLGETATTACHEDSHADERSPROC fGetAttachedShaders;
+ typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar* name);
+ PFNGLGETATTRIBLOCATIONPROC fGetAttribLocation;
+ typedef void (GLAPIENTRY * PFNGLGETINTEGERVPROC) (GLenum pname, GLint* params);
+ PFNGLGETINTEGERVPROC fGetIntegerv;
+ typedef void (GLAPIENTRY * PFNGLGETFLOATVPROC) (GLenum pname, GLfloat* params);
+ PFNGLGETFLOATVPROC fGetFloatv;
+ typedef void (GLAPIENTRY * PFNGLGETBOOLEANBPROC) (GLenum pname, realGLboolean* params);
+ PFNGLGETBOOLEANBPROC fGetBooleanv;
+ typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params);
+ PFNGLGETBUFFERPARAMETERIVPROC fGetBufferParameteriv;
+ typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPPROC) (GLenum target);
+ PFNGLGENERATEMIPMAPPROC fGenerateMipmap;
+ typedef GLenum (GLAPIENTRY * PFNGLGETERRORPROC) (void);
+ PFNGLGETERRORPROC fGetError;
+ typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint* param);
+ PFNGLGETPROGRAMIVPROC fGetProgramiv;
+ typedef void (GLAPIENTRY * PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
+ PFNGLGETPROGRAMINFOLOGPROC fGetProgramInfoLog;
+ typedef void (GLAPIENTRY * PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint* params);
+ PFNGLGETQUERYIVPROC fGetQueryiv;
+ typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint* params);
+ PFNGLGETQUERYOBJECTIVPROC fGetQueryObjectiv;
+ typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint* params);
+ PFNGLGETQUERYOBJECTUIVPROC fGetQueryObjectuiv;
+ typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64* params);
+ PFNGLGETQUERYOBJECTI64VPROC fGetQueryObjecti64v;
+ typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64* params);
+ PFNGLGETQUERYOBJECTUI64VPROC fGetQueryObjectui64v;
+ typedef void (GLAPIENTRY * PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target);
+ PFNGLQUERYCOUNTERPROC fQueryCounter;
+ typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
+ PFNGLTEXPARAMETERIPROC fTexParameteri;
+ typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint* param);
+ PFNGLTEXPARAMETERIVPROC fTexParameteriv;
+ typedef void (GLAPIENTRY * PFNGLTEXPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat param);
+ PFNGLTEXPARAMETERFPROC fTexParameterf;
+ typedef GLubyte* (GLAPIENTRY * PFNGLGETSTRINGPROC) (GLenum);
+ PFNGLGETSTRINGPROC fGetString;
+ typedef void (GLAPIENTRY * PFNGLGETTEXIMAGEPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLvoid* image);
+ PFNGLGETTEXIMAGEPROC fGetTexImage;
+ typedef void (GLAPIENTRY * PFNGLGETTEXLEVELPARAMETERIVPROC) (GLenum target, GLint level, GLenum pname, GLint* params);
+ PFNGLGETTEXLEVELPARAMETERIVPROC fGetTexLevelParameteriv;
+ typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat* params);
+ PFNGLGETTEXPARAMETERFVPROC fGetTexParameterfv;
+ typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params);
+ PFNGLGETTEXPARAMETERIVPROC fGetTexParameteriv;
+ typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat* params);
+ PFNGLGETUNIFORMFVPROC fGetUniformfv;
+ typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint* params);
+ PFNGLGETUNIFORMIVPROC fGetUniformiv;
+ typedef void (GLAPIENTRY * PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint* params);
+ PFNGLGETUNIFORMUIVPROC fGetUniformuiv;
+ typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONPROC) (GLint programObj, const GLchar* name);
+ PFNGLGETUNIFORMLOCATIONPROC fGetUniformLocation;
+ typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVPROC) (GLuint, GLenum, GLfloat*);
+ PFNGLGETVERTEXATTRIBFVPROC fGetVertexAttribfv;
+ typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVPROC) (GLuint, GLenum, GLint*);
+ PFNGLGETVERTEXATTRIBIVPROC fGetVertexAttribiv;
+ typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint, GLenum, GLvoid**);
+ PFNGLGETVERTEXATTRIBPOINTERVPROC fGetVertexAttribPointerv;
+ typedef void (GLAPIENTRY * PFNGLHINTPROC) (GLenum target, GLenum mode);
+ PFNGLHINTPROC fHint;
+ typedef realGLboolean (GLAPIENTRY * PFNGLISBUFFERPROC) (GLuint buffer);
+ PFNGLISBUFFERPROC fIsBuffer;
+ typedef realGLboolean (GLAPIENTRY * PFNGLISENABLEDPROC) (GLenum cap);
+ PFNGLISENABLEDPROC fIsEnabled;
+ typedef realGLboolean (GLAPIENTRY * PFNGLISPROGRAMPROC) (GLuint program);
+ PFNGLISPROGRAMPROC fIsProgram;
+ typedef realGLboolean (GLAPIENTRY * PFNGLISQUERYPROC) (GLuint id);
+ PFNGLISQUERYPROC fIsQuery;
+ typedef realGLboolean (GLAPIENTRY * PFNGLISSHADERPROC) (GLuint shader);
+ PFNGLISSHADERPROC fIsShader;
+ typedef realGLboolean (GLAPIENTRY * PFNGLISTEXTUREPROC) (GLuint texture);
+ PFNGLISTEXTUREPROC fIsTexture;
+ typedef void (GLAPIENTRY * PFNGLLINEWIDTHPROC) (GLfloat width);
+ PFNGLLINEWIDTHPROC fLineWidth;
+ typedef void (GLAPIENTRY * PFNGLLINKPROGRAMPROC) (GLuint program);
+ PFNGLLINKPROGRAMPROC fLinkProgram;
+ typedef void (GLAPIENTRY * PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param);
+ PFNGLPIXELSTOREIPROC fPixelStorei;
+ typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param);
+ PFNGLPOINTPARAMETERFPROC fPointParameterf;
+ typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETPROC) (GLfloat factor, GLfloat bias);
+ PFNGLPOLYGONOFFSETPROC fPolygonOffset;
+ typedef void (GLAPIENTRY * PFNGLREADBUFFERPROC) (GLenum);
+ PFNGLREADBUFFERPROC fReadBuffer;
+ typedef void (GLAPIENTRY * PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);
+ PFNGLREADPIXELSPROC fReadPixels;
+ typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEPROC) (GLclampf value, realGLboolean invert);
+ PFNGLSAMPLECOVERAGEPROC fSampleCoverage;
+ typedef void (GLAPIENTRY * PFNGLSTENCILFUNCPROC) (GLenum func, GLint ref, GLuint mask);
+ PFNGLSTENCILFUNCPROC fStencilFunc;
+ typedef void (GLAPIENTRY * PFNGLSTENCILFUNCSEPARATEPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
+ PFNGLSTENCILFUNCSEPARATEPROC fStencilFuncSeparate;
+ typedef void (GLAPIENTRY * PFNGLSTENCILMASKPROC) (GLuint mask);
+ PFNGLSTENCILMASKPROC fStencilMask;
+ typedef void (GLAPIENTRY * PFNGLSTENCILMASKSEPARATEPROC) (GLenum, GLuint);
+ PFNGLSTENCILMASKSEPARATEPROC fStencilMaskSeparate;
+ typedef void (GLAPIENTRY * PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum zpass);
+ PFNGLSTENCILOPPROC fStencilOp;
+ typedef void (GLAPIENTRY * PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+ PFNGLSTENCILOPSEPARATEPROC fStencilOpSeparate;
+ typedef void (GLAPIENTRY * PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+ PFNGLTEXIMAGE2DPROC fTexImage2D;
+ typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels);
+ PFNGLTEXSUBIMAGE2DPROC fTexSubImage2D;
+ typedef void (GLAPIENTRY * PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, GLvoid* pointer);
+ PFNGLTEXTURERANGEAPPLEPROC fTextureRangeAPPLE;
+ typedef void (GLAPIENTRY * PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0);
+ PFNGLUNIFORM1FPROC fUniform1f;
+ typedef void (GLAPIENTRY * PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat* value);
+ PFNGLUNIFORM1FVPROC fUniform1fv;
+ typedef void (GLAPIENTRY * PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
+ PFNGLUNIFORM1IPROC fUniform1i;
+ typedef void (GLAPIENTRY * PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint* value);
+ PFNGLUNIFORM1IVPROC fUniform1iv;
+ typedef void (GLAPIENTRY * PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1);
+ PFNGLUNIFORM2FPROC fUniform2f;
+ typedef void (GLAPIENTRY * PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat* value);
+ PFNGLUNIFORM2FVPROC fUniform2fv;
+ typedef void (GLAPIENTRY * PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1);
+ PFNGLUNIFORM2IPROC fUniform2i;
+ typedef void (GLAPIENTRY * PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint* value);
+ PFNGLUNIFORM2IVPROC fUniform2iv;
+ typedef void (GLAPIENTRY * PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+ PFNGLUNIFORM3FPROC fUniform3f;
+ typedef void (GLAPIENTRY * PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat* value);
+ PFNGLUNIFORM3FVPROC fUniform3fv;
+ typedef void (GLAPIENTRY * PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2);
+ PFNGLUNIFORM3IPROC fUniform3i;
+ typedef void (GLAPIENTRY * PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint* value);
+ PFNGLUNIFORM3IVPROC fUniform3iv;
+ typedef void (GLAPIENTRY * PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+ PFNGLUNIFORM4FPROC fUniform4f;
+ typedef void (GLAPIENTRY * PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat* value);
+ PFNGLUNIFORM4FVPROC fUniform4fv;
+ typedef void (GLAPIENTRY * PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+ PFNGLUNIFORM4IPROC fUniform4i;
+ typedef void (GLAPIENTRY * PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint* value);
+ PFNGLUNIFORM4IVPROC fUniform4iv;
+ typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value);
+ PFNGLUNIFORMMATRIX2FVPROC fUniformMatrix2fv;
+ typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value);
+ PFNGLUNIFORMMATRIX2X3FVPROC fUniformMatrix2x3fv;
+ typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value);
+ PFNGLUNIFORMMATRIX2X4FVPROC fUniformMatrix2x4fv;
+ typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value);
+ PFNGLUNIFORMMATRIX3FVPROC fUniformMatrix3fv;
+ typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value);
+ PFNGLUNIFORMMATRIX3X2FVPROC fUniformMatrix3x2fv;
+ typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value);
+ PFNGLUNIFORMMATRIX3X4FVPROC fUniformMatrix3x4fv;
+ typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value);
+ PFNGLUNIFORMMATRIX4FVPROC fUniformMatrix4fv;
+ typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value);
+ PFNGLUNIFORMMATRIX4X2FVPROC fUniformMatrix4x2fv;
+ typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value);
+ PFNGLUNIFORMMATRIX4X3FVPROC fUniformMatrix4x3fv;
+
+ typedef void (GLAPIENTRY * PFNGLUSEPROGRAMPROC) (GLuint program);
+ PFNGLUSEPROGRAMPROC fUseProgram;
+ typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMPROC) (GLuint program);
+ PFNGLVALIDATEPROGRAMPROC fValidateProgram;
+ typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, realGLboolean normalized, GLsizei stride, const GLvoid* pointer);
+ PFNGLVERTEXATTRIBPOINTERPROC fVertexAttribPointer;
+ typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x);
+ PFNGLVERTEXATTRIB1FPROC fVertexAttrib1f;
+ typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y);
+ PFNGLVERTEXATTRIB2FPROC fVertexAttrib2f;
+ typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+ PFNGLVERTEXATTRIB3FPROC fVertexAttrib3f;
+ typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ PFNGLVERTEXATTRIB4FPROC fVertexAttrib4f;
+ typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat* v);
+ PFNGLVERTEXATTRIB1FVPROC fVertexAttrib1fv;
+ typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat* v);
+ PFNGLVERTEXATTRIB2FVPROC fVertexAttrib2fv;
+ typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat* v);
+ PFNGLVERTEXATTRIB3FVPROC fVertexAttrib3fv;
+ typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat* v);
+ PFNGLVERTEXATTRIB4FVPROC fVertexAttrib4fv;
+ typedef void (GLAPIENTRY * PFNGLCOMPILESHADERPROC) (GLuint shader);
+ PFNGLCOMPILESHADERPROC fCompileShader;
+ typedef void (GLAPIENTRY * PFNGLCOPYTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+ PFNGLCOPYTEXIMAGE2DPROC fCopyTexImage2D;
+ typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+ PFNGLCOPYTEXSUBIMAGE2DPROC fCopyTexSubImage2D;
+ typedef void (GLAPIENTRY * PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint* param);
+ PFNGLGETSHADERIVPROC fGetShaderiv;
+ typedef void (GLAPIENTRY * PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
+ PFNGLGETSHADERINFOLOGPROC fGetShaderInfoLog;
+ typedef void (GLAPIENTRY * PFNGETSHADERPRECISIONFORMAT) (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+ PFNGETSHADERPRECISIONFORMAT fGetShaderPrecisionFormat;
+ typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEPROC) (GLint obj, GLsizei maxLength, GLsizei* length, GLchar* source);
+ PFNGLGETSHADERSOURCEPROC fGetShaderSource;
+ typedef void (GLAPIENTRY * PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* const* strings, const GLint* lengths);
+ PFNGLSHADERSOURCEPROC fShaderSource;
+
+ typedef void (GLAPIENTRY * PFNGLBINDFRAMEBUFFER) (GLenum target, GLuint framebuffer);
+ PFNGLBINDFRAMEBUFFER fBindFramebuffer;
+ typedef void (GLAPIENTRY * PFNGLBINDRENDERBUFFER) (GLenum target, GLuint renderbuffer);
+ PFNGLBINDRENDERBUFFER fBindRenderbuffer;
+ typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUS) (GLenum target);
+ PFNGLCHECKFRAMEBUFFERSTATUS fCheckFramebufferStatus;
+ typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFER) (GLenum target, GLenum attachmentPoint, GLenum renderbufferTarget, GLuint renderbuffer);
+ PFNGLFRAMEBUFFERRENDERBUFFER fFramebufferRenderbuffer;
+ typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2D) (GLenum target, GLenum attachmentPoint, GLenum textureTarget, GLuint texture, GLint level);
+ PFNGLFRAMEBUFFERTEXTURE2D fFramebufferTexture2D;
+ typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+ PFNGLFRAMEBUFFERTEXTURELAYERPROC fFramebufferTextureLayer;
+ typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIV) (GLenum target, GLenum attachment, GLenum pname, GLint* value);
+ PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIV fGetFramebufferAttachmentParameteriv;
+ typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIV) (GLenum target, GLenum pname, GLint* value);
+ PFNGLGETRENDERBUFFERPARAMETERIV fGetRenderbufferParameteriv;
+ typedef realGLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFER) (GLuint framebuffer);
+ PFNGLISFRAMEBUFFER fIsFramebuffer;
+ typedef realGLboolean (GLAPIENTRY * PFNGLISRENDERBUFFER) (GLuint renderbuffer);
+ PFNGLISRENDERBUFFER fIsRenderbuffer;
+ typedef realGLboolean (GLAPIENTRY * PFNGLISVERTEXARRAY) (GLuint array);
+ PFNGLISVERTEXARRAY fIsVertexArray;
+ typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGE) (GLenum target, GLenum internalFormat, GLsizei width, GLsizei height);
+ PFNGLRENDERBUFFERSTORAGE fRenderbufferStorage;
+
+ typedef void (GLAPIENTRY * PFNINVALIDATEFRAMEBUFFER) (GLenum target, GLsizei numAttachments, const GLenum* attachments);
+ PFNINVALIDATEFRAMEBUFFER fInvalidateFramebuffer;
+ typedef void (GLAPIENTRY * PFNINVALIDATESUBFRAMEBUFFER) (GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+ PFNINVALIDATESUBFRAMEBUFFER fInvalidateSubFramebuffer;
+
+ // These functions are only used by Skia/GL in desktop mode.
+ // Other parts of Gecko should avoid using these
+ typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTURE) (GLenum texture);
+ PFNGLCLIENTACTIVETEXTURE fClientActiveTexture;
+ typedef void (GLAPIENTRY * PFNDISABLECLIENTSTATE) (GLenum capability);
+ PFNDISABLECLIENTSTATE fDisableClientState;
+ typedef void (GLAPIENTRY * PFNENABLECLIENTSTATE) (GLenum capability);
+ PFNENABLECLIENTSTATE fEnableClientState;
+ typedef void (GLAPIENTRY * PFNLOADIDENTITY) (void);
+ PFNLOADIDENTITY fLoadIdentity;
+ typedef void (GLAPIENTRY * PFNLOADMATRIXD) (const GLdouble* matrix);
+ PFNLOADMATRIXD fLoadMatrixd;
+ typedef void (GLAPIENTRY * PFNLOADMATRIXF) (const GLfloat* matrix);
+ PFNLOADMATRIXF fLoadMatrixf;
+ typedef void (GLAPIENTRY * PFNMATRIXMODE) (GLenum mode);
+ PFNMATRIXMODE fMatrixMode;
+ typedef void (GLAPIENTRY * PFNTEXGENI) (GLenum coord, GLenum pname, GLint param);
+ PFNTEXGENI fTexGeni;
+ typedef void (GLAPIENTRY * PFNTEXGENF) (GLenum coord, GLenum pname, GLfloat param);
+ PFNTEXGENF fTexGenf;
+ typedef void (GLAPIENTRY * PFNTEXGENFV) (GLenum coord, GLenum pname, const GLfloat* param);
+ PFNTEXGENFV fTexGenfv;
+ typedef void (GLAPIENTRY * PFNVERTEXPOINTER) (GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
+ PFNVERTEXPOINTER fVertexPointer;
+
+ typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFER) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+ PFNGLBLITFRAMEBUFFER fBlitFramebuffer;
+ typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLE) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height);
+ PFNGLRENDERBUFFERSTORAGEMULTISAMPLE fRenderbufferStorageMultisample;
+
+
+ /* These are different between GLES2 and desktop GL; we hide those differences, use the GL
+ * names, but the most limited data type.
+ */
+ typedef void (GLAPIENTRY * PFNGLDEPTHRANGEFPROC) (GLclampf, GLclampf);
+ PFNGLDEPTHRANGEFPROC fDepthRangef;
+ typedef void (GLAPIENTRY * PFNGLCLEARDEPTHFPROC) (GLclampf);
+ PFNGLCLEARDEPTHFPROC fClearDepthf;
+
+ typedef void (GLAPIENTRY * PFNGLDEPTHRANGEPROC) (GLclampd, GLclampd);
+ PFNGLDEPTHRANGEPROC fDepthRange;
+ typedef void (GLAPIENTRY * PFNGLCLEARDEPTHPROC) (GLclampd);
+ PFNGLCLEARDEPTHPROC fClearDepth;
+
+ /* These are special because we end up tracking these so that we don't
+ * have to query the values from GL.
+ */
+
+ typedef void (GLAPIENTRY * PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
+ PFNGLVIEWPORTPROC fViewport;
+ typedef void (GLAPIENTRY * PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
+ PFNGLSCISSORPROC fScissor;
+
+
+ /* These are special -- they create or delete GL resources that can live
+ * in a shared namespace. In DEBUG, we wrap these calls so that we can
+ * check when we have something that failed to do cleanup at the time the
+ * final context is destroyed.
+ */
+
+ typedef GLuint (GLAPIENTRY * PFNGLCREATEPROGRAMPROC) (void);
+ PFNGLCREATEPROGRAMPROC fCreateProgram;
+ typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROC) (GLenum type);
+ PFNGLCREATESHADERPROC fCreateShader;
+ typedef void (GLAPIENTRY * PFNGLGENBUFFERSPROC) (GLsizei n, GLuint* buffers);
+ PFNGLGENBUFFERSPROC fGenBuffers;
+ typedef void (GLAPIENTRY * PFNGLGENQUERIESPROC) (GLsizei n, GLuint* queries);
+ PFNGLGENQUERIESPROC fGenQueries;
+ typedef void (GLAPIENTRY * PFNGLGENTEXTURESPROC) (GLsizei n, GLuint* textures);
+ PFNGLGENTEXTURESPROC fGenTextures;
+ typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERS) (GLsizei n, GLuint* ids);
+ PFNGLGENFRAMEBUFFERS fGenFramebuffers;
+ typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERS) (GLsizei n, GLuint* ids);
+ PFNGLGENRENDERBUFFERS fGenRenderbuffers;
+ typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYS) (GLsizei n, GLuint* arrays);
+ PFNGLGENVERTEXARRAYS fGenVertexArrays;
+
+ typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMPROC) (GLuint program);
+ PFNGLDELETEPROGRAMPROC fDeleteProgram;
+ typedef void (GLAPIENTRY * PFNGLDELETESHADERPROC) (GLuint shader);
+ PFNGLDELETESHADERPROC fDeleteShader;
+ typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint* buffers);
+ PFNGLDELETEBUFFERSPROC fDeleteBuffers;
+ typedef void (GLAPIENTRY * PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint* queries);
+ PFNGLDELETEQUERIESPROC fDeleteQueries;
+ typedef void (GLAPIENTRY * PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint* textures);
+ PFNGLDELETETEXTURESPROC fDeleteTextures;
+ typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERS) (GLsizei n, const GLuint* ids);
+ PFNGLDELETEFRAMEBUFFERS fDeleteFramebuffers;
+ typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERS) (GLsizei n, const GLuint* ids);
+ PFNGLDELETERENDERBUFFERS fDeleteRenderbuffers;
+ typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYS) (GLsizei n, const GLuint* arrays);
+ PFNGLDELETEVERTEXARRAYS fDeleteVertexArrays;
+
+ typedef void* (GLAPIENTRY * PFNGLMAPBUFFER) (GLenum target, GLenum access);
+ PFNGLMAPBUFFER fMapBuffer;
+ typedef realGLboolean (GLAPIENTRY * PFNGLUNMAPBUFFER) (GLenum target);
+ PFNGLUNMAPBUFFER fUnmapBuffer;
+
+ // ARB_copy_buffer / OpenGL 3.1 / OpenGL ES 3.0
+ typedef void (GLAPIENTRY * PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum writeTarget,
+ GLintptr readOffset, GLintptr writeOffset,
+ GLsizeiptr size);
+ PFNGLCOPYBUFFERSUBDATAPROC fCopyBufferSubData;
+
+ typedef GLenum (GLAPIENTRY * PFNGLGETGRAPHICSRESETSTATUS) (void);
+ PFNGLGETGRAPHICSRESETSTATUS fGetGraphicsResetStatus;
+
+ // ARB_sync
+ typedef GLsync (GLAPIENTRY * PFNGLFENCESYNC) (GLenum condition, GLbitfield flags);
+ PFNGLFENCESYNC fFenceSync;
+ typedef realGLboolean (GLAPIENTRY * PFNGLISSYNC) (GLsync sync);
+ PFNGLISSYNC fIsSync;
+ typedef void (GLAPIENTRY * PFNGLDELETESYNC) (GLsync sync);
+ PFNGLDELETESYNC fDeleteSync;
+ typedef GLenum (GLAPIENTRY * PFNGLCLIENTWAITSYNC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+ PFNGLCLIENTWAITSYNC fClientWaitSync;
+ typedef void (GLAPIENTRY * PFNGLWAITSYNC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+ PFNGLWAITSYNC fWaitSync;
+ typedef void (GLAPIENTRY * PFNGLGETINTEGER64V) (GLenum pname, GLint64* params);
+ PFNGLGETINTEGER64V fGetInteger64v;
+ typedef void (GLAPIENTRY * PFNGLGETSYNCIV) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values);
+ PFNGLGETSYNCIV fGetSynciv;
+
+ // OES_egl_image
+ typedef void (GLAPIENTRY * PFNGLEGLIMAGETARGETTEXTURE2D)(GLenum target, GLeglImage image);
+ PFNGLEGLIMAGETARGETTEXTURE2D fEGLImageTargetTexture2D;
+ typedef void (GLAPIENTRY * PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGE)(GLenum target, GLeglImage image);
+ PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGE fEGLImageTargetRenderbufferStorage;
+
+ // ARB_draw_instanced
+ typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCED) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+ PFNGLDRAWARRAYSINSTANCED fDrawArraysInstanced;
+ typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCED) (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei primcount);
+ PFNGLDRAWELEMENTSINSTANCED fDrawElementsInstanced;
+
+ // ARB_instanced_array
+ typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISOR) (GLuint index, GLuint divisor);
+ PFNGLVERTEXATTRIBDIVISOR fVertexAttribDivisor;
+
+ // ARB_internalformat_query
+ typedef void (GLAPIENTRY * PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params);
+ PFNGLGETINTERNALFORMATIVPROC fGetInternalformativ;
+
+ // ARB_transform_feedback2 / OpenGL 4.0 / OpenGL ES 3.0
+ typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASE) (GLenum target, GLuint index, GLuint buffer);
+ PFNGLBINDBUFFERBASE fBindBufferBase;
+ typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGE) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+ PFNGLBINDBUFFERRANGE fBindBufferRange;
+
+ typedef void (GLAPIENTRY * PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint* ids);
+ PFNGLGENTRANSFORMFEEDBACKSPROC fGenTransformFeedbacks;
+ typedef void (GLAPIENTRY * PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint* ids);
+ PFNGLDELETETRANSFORMFEEDBACKSPROC fDeleteTransformFeedbacks;
+ typedef realGLboolean (GLAPIENTRY * PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id);
+ PFNGLISTRANSFORMFEEDBACKPROC fIsTransformFeedback;
+ typedef void (GLAPIENTRY * PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id);
+ PFNGLBINDTRANSFORMFEEDBACKPROC fBindTransformFeedback;
+ typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGS) (GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode);
+ PFNGLTRANSFORMFEEDBACKVARYINGS fTransformFeedbackVaryings;
+ typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYING) (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name);
+ PFNGLGETTRANSFORMFEEDBACKVARYING fGetTransformFeedbackVarying;
+ typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACK) (GLenum primitiveMode);
+ PFNGLBEGINTRANSFORMFEEDBACK fBeginTransformFeedback;
+ typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACK) (void);
+ PFNGLENDTRANSFORMFEEDBACK fEndTransformFeedback;
+ typedef void (GLAPIENTRY * PFNGLPAUSETRANSFORMFEEDBACKPROC) ();
+ PFNGLPAUSETRANSFORMFEEDBACKPROC fPauseTransformFeedback;
+ typedef void (GLAPIENTRY * PFNGLRESUMETRANSFORMFEEDBACKPROC) ();
+ PFNGLRESUMETRANSFORMFEEDBACKPROC fResumeTransformFeedback;
+
+ typedef void (GLAPIENTRY * PFNGLGETINTEGERI_V) (GLenum param, GLuint index, GLint* values);
+ PFNGLGETINTEGERI_V fGetIntegeri_v;
+ typedef void (GLAPIENTRY * PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64* data);
+ PFNGLGETINTEGER64I_VPROC fGetInteger64i_v;
+
+ // EXT_transform_feedback only
+ typedef void (GLAPIENTRY * PFNGLBINDBUFFEROFFSET) (GLenum target, GLuint index, GLuint buffer, GLintptr offset);
+ PFNGLBINDBUFFEROFFSET fBindBufferOffset;
+
+ // KHR_debug
+ typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECONTROL) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, realGLboolean enabled);
+ PFNGLDEBUGMESSAGECONTROL fDebugMessageControl;
+ typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEINSERT) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf);
+ PFNGLDEBUGMESSAGEINSERT fDebugMessageInsert;
+ typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECALLBACK) (GLDEBUGPROC callback, const GLvoid* userParam);
+ PFNGLDEBUGMESSAGECALLBACK fDebugMessageCallback;
+ typedef GLuint (GLAPIENTRY * PFNGLDEBUGMESSAGELOG) (GLuint count, GLsizei bufsize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog);
+ PFNGLDEBUGMESSAGELOG fGetDebugMessageLog;
+ typedef void (GLAPIENTRY * PFNGLGETPOINTERV) (GLenum pname, GLvoid** params);
+ PFNGLGETPOINTERV fGetPointerv;
+ typedef void (GLAPIENTRY * PFNGLPUSHDEBUGGROUP) (GLenum source, GLuint id, GLsizei length, const GLchar* message);
+ PFNGLPUSHDEBUGGROUP fPushDebugGroup;
+ typedef void (GLAPIENTRY * PFNGLPOPDEBUGGROUP) (void);
+ PFNGLPOPDEBUGGROUP fPopDebugGroup;
+ typedef void (GLAPIENTRY * PFNGLOBJECTLABEL) (GLenum identifier, GLuint name, GLsizei length, const GLchar* label);
+ PFNGLOBJECTLABEL fObjectLabel;
+ typedef void (GLAPIENTRY * PFNGLGETOBJECTLABEL) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei* length, GLchar* label);
+ PFNGLGETOBJECTLABEL fGetObjectLabel;
+ typedef void (GLAPIENTRY * PFNGLOBJECTPTRLABEL) (const GLvoid* ptr, GLsizei length, const GLchar* label);
+ PFNGLOBJECTPTRLABEL fObjectPtrLabel;
+ typedef void (GLAPIENTRY * PFNGLGETOBJECTPTRLABEL) (const GLvoid* ptr, GLsizei bufSize, GLsizei* length, GLchar* label);
+ PFNGLGETOBJECTPTRLABEL fGetObjectPtrLabel;
+
+ // draw_range_elements
+ typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTS) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices);
+ PFNGLDRAWRANGEELEMENTS fDrawRangeElements;
+
+ // NV_fence
+ typedef void (GLAPIENTRY * pfnGenFencesT) (GLsizei n, GLuint* fences);
+ pfnGenFencesT fGenFences;
+ typedef void (GLAPIENTRY * pfnDeleteFencesT) (GLsizei n, const GLuint* fences);
+ pfnDeleteFencesT fDeleteFences;
+ typedef void (GLAPIENTRY * pfnSetFenceT) (GLuint fence, GLenum condition);
+ pfnSetFenceT fSetFence;
+ typedef realGLboolean (GLAPIENTRY * pfnTestFenceT) (GLuint fence);
+ pfnTestFenceT fTestFence;
+ typedef void (GLAPIENTRY * pfnFinishFenceT) (GLuint fence);
+ pfnFinishFenceT fFinishFence;
+ typedef realGLboolean (GLAPIENTRY * pfnIsFenceT) (GLuint fence);
+ pfnIsFenceT fIsFence;
+ typedef void (GLAPIENTRY * pfnGetFenceivT) (GLuint fence, GLenum pname, GLint* params);
+ pfnGetFenceivT fGetFenceiv;
+
+ // map_buffer_range
+ typedef void* (GLAPIENTRY * PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+ PFNGLMAPBUFFERRANGEPROC fMapBufferRange;
+ typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length);
+ PFNGLFLUSHMAPPEDBUFFERRANGEPROC fFlushMappedBufferRange;
+
+ // sampler_object
+ typedef void (GLAPIENTRY * PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint* samplers);
+ PFNGLGENSAMPLERSPROC fGenSamplers;
+ typedef void (GLAPIENTRY * PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint* samplers);
+ PFNGLDELETESAMPLERSPROC fDeleteSamplers;
+ typedef realGLboolean (GLAPIENTRY * PFNGLISSAMPLERPROC) (GLuint sampler);
+ PFNGLISSAMPLERPROC fIsSampler;
+ typedef void (GLAPIENTRY * PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler);
+ PFNGLBINDSAMPLERPROC fBindSampler;
+ typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param);
+ PFNGLSAMPLERPARAMETERIPROC fSamplerParameteri;
+ typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint* param);
+ PFNGLSAMPLERPARAMETERIVPROC fSamplerParameteriv;
+ typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param);
+ PFNGLSAMPLERPARAMETERFPROC fSamplerParameterf;
+ typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat* param);
+ PFNGLSAMPLERPARAMETERFVPROC fSamplerParameterfv;
+ typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint* params);
+ PFNGLGETSAMPLERPARAMETERIVPROC fGetSamplerParameteriv;
+ typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat* params);
+ PFNGLGETSAMPLERPARAMETERFVPROC fGetSamplerParameterfv;
+
+ // texture_storage
+ typedef void (GLAPIENTRY * PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+ PFNGLTEXSTORAGE2DPROC fTexStorage2D;
+ typedef void (GLAPIENTRY * PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+ PFNGLTEXSTORAGE3DPROC fTexStorage3D;
+
+ // uniform_buffer_object
+ typedef void (GLAPIENTRY * PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount,
+ const GLchar* const* uniformNames, GLuint* uniformIndices);
+ PFNGLGETUNIFORMINDICESPROC fGetUniformIndices;
+ typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint* uniformIndices,
+ GLenum pname, GLint* params);
+ PFNGLGETACTIVEUNIFORMSIVPROC fGetActiveUniformsiv;
+ typedef GLuint (GLAPIENTRY * PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar* uniformBlockName);
+ PFNGLGETUNIFORMBLOCKINDEXPROC fGetUniformBlockIndex;
+ typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params);
+ PFNGLGETACTIVEUNIFORMBLOCKIVPROC fGetActiveUniformBlockiv;
+ typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName);
+ PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC fGetActiveUniformBlockName;
+ typedef void (GLAPIENTRY * PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+ PFNGLUNIFORMBLOCKBINDINGPROC fUniformBlockBinding;
+
+ // EXT_gpu_shader4
+ typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint* params);
+ PFNGLGETVERTEXATTRIBIIVPROC fGetVertexAttribIiv;
+ typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint* params);
+ PFNGLGETVERTEXATTRIBIUIVPROC fGetVertexAttribIuiv;
+ typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w);
+ PFNGLVERTEXATTRIBI4IPROC fVertexAttribI4i;
+ typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint* v);
+ PFNGLVERTEXATTRIBI4IVPROC fVertexAttribI4iv;
+ typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+ PFNGLVERTEXATTRIBI4UIPROC fVertexAttribI4ui;
+ typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint* v);
+ PFNGLVERTEXATTRIBI4UIVPROC fVertexAttribI4uiv;
+ typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* ptr);
+ PFNGLVERTEXATTRIBIPOINTERPROC fVertexAttribIPointer;
+ typedef void (GLAPIENTRY * PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0);
+ PFNGLUNIFORM1UIPROC fUniform1ui;
+ typedef void (GLAPIENTRY * PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1);
+ PFNGLUNIFORM2UIPROC fUniform2ui;
+ typedef void (GLAPIENTRY * PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2);
+ PFNGLUNIFORM3UIPROC fUniform3ui;
+ typedef void (GLAPIENTRY * PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+ PFNGLUNIFORM4UIPROC fUniform4ui;
+ typedef void (GLAPIENTRY * PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint* value);
+ PFNGLUNIFORM1UIVPROC fUniform1uiv;
+ typedef void (GLAPIENTRY * PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint* value);
+ PFNGLUNIFORM2UIVPROC fUniform2uiv;
+ typedef void (GLAPIENTRY * PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint* value);
+ PFNGLUNIFORM3UIVPROC fUniform3uiv;
+ typedef void (GLAPIENTRY * PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint* value);
+ PFNGLUNIFORM4UIVPROC fUniform4uiv;
+ typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar* name);
+ PFNGLGETFRAGDATALOCATIONPROC fGetFragDataLocation;
+
+ // 3D Textures
+ typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level,
+ GLenum internalFormat,
+ GLenum width, GLsizei height, GLsizei depth,
+ GLint border, GLenum format, GLenum type,
+ const GLvoid* pixels);
+ PFNGLTEXIMAGE3DPROC fTexImage3D;
+ typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset,
+ GLint yoffset, GLint zoffset, GLsizei width,
+ GLsizei height, GLsizei depth, GLenum format,
+ GLenum type, const GLvoid* pixels);
+ PFNGLTEXSUBIMAGE3DPROC fTexSubImage3D;
+ typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset,
+ GLint yoffset, GLint zoffset, GLint x,
+ GLint y, GLsizei width, GLsizei height);
+ PFNGLCOPYTEXSUBIMAGE3DPROC fCopyTexSubImage3D;
+ typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLsizei imageSize, const GLvoid* data);
+ PFNGLCOMPRESSEDTEXIMAGE3DPROC fCompressedTexImage3D;
+ typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLsizei imageSize, const GLvoid* data);
+ PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC fCompressedTexSubImage3D;
+
+ // get_string_indexed
+ typedef const GLubyte* (GLAPIENTRY * PFNGLGETSTRINGIPROC)(GLenum name, GLuint index);
+ PFNGLGETSTRINGIPROC fGetStringi;
+
+ // APPLE_framebuffer_multisample
+ typedef void (GLAPIENTRY * PFNRESOLVEMULTISAMPLEFRAMEBUFFERAPPLE) (void);
+ PFNRESOLVEMULTISAMPLEFRAMEBUFFERAPPLE fResolveMultisampleFramebufferAPPLE;
+
+ // NV_texture_barrier
+ typedef void (GLAPIENTRY * PFNTEXTUREBARRIERPROC) (void);
+ PFNTEXTUREBARRIERPROC fTextureBarrier;
+
+ // NV_primitive_restart
+ void (GLAPIENTRY * fPrimitiveRestartIndex) (GLuint index);
+};
+
+} // namespace gl
+} // namespace mozilla
+
+#endif /* GLCONTEXTSYMBOLS_H_ */
diff --git a/gfx/gl/GLContextTypes.cpp b/gfx/gl/GLContextTypes.cpp
new file mode 100644
index 0000000000..2cca59dc96
--- /dev/null
+++ b/gfx/gl/GLContextTypes.cpp
@@ -0,0 +1,14 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "GLContextTypes.h"
+#include <cstring>
+
+using namespace mozilla::gl;
+
+GLFormats::GLFormats()
+{
+ std::memset(this, 0, sizeof(GLFormats));
+}
diff --git a/gfx/gl/GLContextTypes.h b/gfx/gl/GLContextTypes.h
new file mode 100644
index 0000000000..de59acf491
--- /dev/null
+++ b/gfx/gl/GLContextTypes.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GLCONTEXT_TYPES_H_
+#define GLCONTEXT_TYPES_H_
+
+#include "GLTypes.h"
+#include "mozilla/TypedEnumBits.h"
+
+namespace mozilla {
+namespace gl {
+
+class GLContext;
+
+enum class GLContextType {
+ Unknown,
+ WGL,
+ CGL,
+ GLX,
+ EGL,
+ EAGL
+};
+
+enum class OriginPos : uint8_t {
+ TopLeft,
+ BottomLeft
+};
+
+struct GLFormats
+{
+ // Constructs a zeroed object:
+ GLFormats();
+
+ GLenum color_texInternalFormat;
+ GLenum color_texFormat;
+ GLenum color_texType;
+ GLenum color_rbFormat;
+
+ GLenum depthStencil;
+ GLenum depth;
+ GLenum stencil;
+
+ GLsizei samples;
+};
+
+enum class CreateContextFlags : int8_t {
+ NONE = 0,
+ REQUIRE_COMPAT_PROFILE = 1 << 0,
+ // Force the use of hardware backed GL, don't allow software implementations.
+ FORCE_ENABLE_HARDWARE = 1 << 1,
+ /* Don't force discrete GPU to be used (if applicable) */
+ ALLOW_OFFLINE_RENDERER = 1 << 2,
+ // Ask for ES3 if possible
+ PREFER_ES3 = 1 << 3,
+
+ NO_VALIDATION = 1 << 4,
+};
+MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(CreateContextFlags)
+
+} /* namespace gl */
+} /* namespace mozilla */
+
+#endif /* GLCONTEXT_TYPES_H_ */
diff --git a/gfx/gl/GLContextWGL.h b/gfx/gl/GLContextWGL.h
new file mode 100644
index 0000000000..9d270bf52d
--- /dev/null
+++ b/gfx/gl/GLContextWGL.h
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GLCONTEXTWGL_H_
+#define GLCONTEXTWGL_H_
+
+#include "GLContext.h"
+#include "WGLLibrary.h"
+
+namespace mozilla {
+namespace gl {
+
+class GLContextWGL : public GLContext
+{
+public:
+ MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GLContextWGL, override)
+ // From Window: (possibly for offscreen!)
+ GLContextWGL(CreateContextFlags flags,
+ const SurfaceCaps& caps,
+ bool isOffscreen,
+ HDC aDC,
+ HGLRC aContext,
+ HWND aWindow = nullptr);
+
+ // From PBuffer
+ GLContextWGL(CreateContextFlags flags,
+ const SurfaceCaps& caps,
+ bool isOffscreen,
+ HANDLE aPbuffer,
+ HDC aDC,
+ HGLRC aContext,
+ int aPixelFormat);
+
+ ~GLContextWGL();
+
+ virtual GLContextType GetContextType() const override { return GLContextType::WGL; }
+
+ static GLContextWGL* Cast(GLContext* gl) {
+ MOZ_ASSERT(gl->GetContextType() == GLContextType::WGL);
+ return static_cast<GLContextWGL*>(gl);
+ }
+
+ bool Init() override;
+
+ virtual bool MakeCurrentImpl(bool aForce) override;
+
+ virtual bool IsCurrent() override;
+
+ void SetIsDoubleBuffered(bool aIsDB);
+
+ virtual bool IsDoubleBuffered() const override;
+
+ virtual bool SupportsRobustness() const override;
+
+ virtual bool SwapBuffers() override;
+
+ virtual bool SetupLookupFunction() override;
+
+ HGLRC Context() { return mContext; }
+
+protected:
+ friend class GLContextProviderWGL;
+
+ HDC mDC;
+ HGLRC mContext;
+ HWND mWnd;
+ HANDLE mPBuffer;
+ int mPixelFormat;
+ bool mIsDoubleBuffered;
+};
+
+}
+}
+
+#endif // GLCONTEXTWGL_H_
diff --git a/gfx/gl/GLDebugUtils.cpp b/gfx/gl/GLDebugUtils.cpp
new file mode 100644
index 0000000000..cc8c611d4c
--- /dev/null
+++ b/gfx/gl/GLDebugUtils.cpp
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "GLDebugUtils.h"
+#include "GLConsts.h"
+
+namespace mozilla {
+namespace gl {
+
+const char*
+GLenumToStr(GLenum e) {
+ switch (e) {
+#define HANDLE_GL_ENUM(x) case LOCAL_##x: return #x
+ HANDLE_GL_ENUM(GL_TRIANGLES);
+ HANDLE_GL_ENUM(GL_TRIANGLE_STRIP);
+ HANDLE_GL_ENUM(GL_TRIANGLE_FAN);
+ HANDLE_GL_ENUM(GL_FRAMEBUFFER);
+ HANDLE_GL_ENUM(GL_RENDERBUFFER);
+ HANDLE_GL_ENUM(GL_DEPTH_ATTACHMENT);
+ HANDLE_GL_ENUM(GL_STENCIL_ATTACHMENT);
+ HANDLE_GL_ENUM(GL_DEPTH_STENCIL_ATTACHMENT);
+ HANDLE_GL_ENUM(GL_TEXTURE_2D);
+ HANDLE_GL_ENUM(GL_TEXTURE_CUBE_MAP_NEGATIVE_X);
+ HANDLE_GL_ENUM(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
+ HANDLE_GL_ENUM(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
+ HANDLE_GL_ENUM(GL_TEXTURE_CUBE_MAP_POSITIVE_X);
+ HANDLE_GL_ENUM(GL_TEXTURE_CUBE_MAP_POSITIVE_Y);
+ HANDLE_GL_ENUM(GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
+ HANDLE_GL_ENUM(GL_COLOR_ATTACHMENT0);
+ HANDLE_GL_ENUM(GL_COLOR_ATTACHMENT1);
+ HANDLE_GL_ENUM(GL_COLOR_ATTACHMENT2);
+ HANDLE_GL_ENUM(GL_COLOR_ATTACHMENT3);
+ HANDLE_GL_ENUM(GL_COLOR_ATTACHMENT4);
+ HANDLE_GL_ENUM(GL_COLOR_ATTACHMENT5);
+ HANDLE_GL_ENUM(GL_COLOR_ATTACHMENT6);
+ HANDLE_GL_ENUM(GL_COLOR_ATTACHMENT7);
+ HANDLE_GL_ENUM(GL_COLOR_ATTACHMENT8);
+ HANDLE_GL_ENUM(GL_COLOR_ATTACHMENT9);
+ HANDLE_GL_ENUM(GL_COLOR_ATTACHMENT10);
+ HANDLE_GL_ENUM(GL_COLOR_ATTACHMENT11);
+ HANDLE_GL_ENUM(GL_COLOR_ATTACHMENT12);
+ HANDLE_GL_ENUM(GL_COLOR_ATTACHMENT13);
+ HANDLE_GL_ENUM(GL_COLOR_ATTACHMENT14);
+ HANDLE_GL_ENUM(GL_COLOR_ATTACHMENT15);
+ HANDLE_GL_ENUM(GL_UNSIGNED_BYTE);
+ HANDLE_GL_ENUM(GL_UNSIGNED_SHORT);
+ HANDLE_GL_ENUM(GL_UNSIGNED_INT);
+ HANDLE_GL_ENUM(GL_RGBA);
+ HANDLE_GL_ENUM(GL_DEPTH_COMPONENT);
+#undef HANDLE_GL_ENUM
+ }
+
+ return "(unknown)";
+}
+
+} // namespace gl
+} // namespace mozilla
diff --git a/gfx/gl/GLDebugUtils.h b/gfx/gl/GLDebugUtils.h
new file mode 100644
index 0000000000..d828492526
--- /dev/null
+++ b/gfx/gl/GLDebugUtils.h
@@ -0,0 +1,19 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GLDEBUGUTILS_H_
+#define GLDEBUGUTILS_H_
+
+#include "GLTypes.h"
+
+namespace mozilla {
+namespace gl {
+
+const char* GLenumToStr(GLenum e);
+
+} // namespace gl
+} // namespace mozilla
+
+#endif // !GLDEBUGUTILS_H_
diff --git a/gfx/gl/GLDefs.h b/gfx/gl/GLDefs.h
new file mode 100644
index 0000000000..f580c06703
--- /dev/null
+++ b/gfx/gl/GLDefs.h
@@ -0,0 +1,88 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#if !defined(LOCALGL_H_)
+#define LOCALGL_H_
+
+#include "GLTypes.h"
+#include "GLConsts.h"
+
+// TODO: use official constant names instead of followed ones.
+// IMG_texture_compression_pvrtc
+#define LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1 0x8C00
+#define LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1 0x8C01
+#define LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1 0x8C02
+#define LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1 0x8C03
+
+// OES_EGL_image_external
+#define LOCAL_GL_TEXTURE_EXTERNAL 0x8D65
+#define LOCAL_GL_TEXTURE_BINDING_EXTERNAL 0x8D67
+
+// EGL_KHR_fence_sync
+#define LOCAL_EGL_SYNC_FENCE 0x30F9
+#define LOCAL_EGL_SYNC_TYPE 0x30F7
+#define LOCAL_EGL_SYNC_STATUS 0x30F1
+#define LOCAL_EGL_SYNC_CONDITION 0x30F8
+#define LOCAL_EGL_SIGNALED 0x30F2
+#define LOCAL_EGL_UNSIGNALED 0x30F3
+#define LOCAL_EGL_SYNC_PRIOR_COMMANDS_COMPLETE 0x30F0
+#define LOCAL_EGL_SYNC_FLUSH_COMMANDS_BIT 0x0001
+#define LOCAL_EGL_FOREVER 0xFFFFFFFFFFFFFFFFull
+#define LOCAL_EGL_TIMEOUT_EXPIRED 0x30F5
+#define LOCAL_EGL_CONDITION_SATISFIED 0x30F6
+#define LOCAL_EGL_SUCCESS 0x3000
+
+// EGL_KHR_gl_texture_2D_image
+#define LOCAL_EGL_GL_TEXTURE_2D 0x30B1
+
+// EGL_KHR_image_base (not supplied by EGL_KHR_image!)
+#define LOCAL_EGL_IMAGE_PRESERVED 0x30D2
+
+// AMD_compressed_ATC_texture
+#define LOCAL_GL_ATC_RGB 0x8C92
+#define LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA 0x8C93
+#define LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA 0x87EE
+
+// EGL_ANDROID_image_crop
+#define LOCAL_EGL_IMAGE_CROP_LEFT_ANDROID 0x3148
+#define LOCAL_EGL_IMAGE_CROP_TOP_ANDROID 0x3149
+#define LOCAL_EGL_IMAGE_CROP_RIGHT_ANDROID 0x314A
+#define LOCAL_EGL_IMAGE_CROP_BOTTOM_ANDROID 0x314B
+
+// EGL_ANGLE_platform_angle
+#define LOCAL_EGL_PLATFORM_ANGLE_ANGLE 0x3202
+#define LOCAL_EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203
+#define LOCAL_EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3204
+#define LOCAL_EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3205
+#define LOCAL_EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3206
+
+// EGL_ANGLE_platform_angle_d3d
+#define LOCAL_EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207
+#define LOCAL_EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
+#define LOCAL_EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE 0x3209
+#define LOCAL_EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE 0x320A
+#define LOCAL_EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE 0x320B
+#define LOCAL_EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE 0x320C
+#define LOCAL_EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE 0x320F
+
+// EGL_ANGLE_direct3d_display
+#define LOCAL_EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ((EGLNativeDisplayType)-2)
+#define LOCAL_EGL_D3D11_ONLY_DISPLAY_ANGLE ((EGLNativeDisplayType)-3)
+
+// WGL_NV_DX_interop
+#define LOCAL_WGL_ACCESS_READ_ONLY 0x0000
+#define LOCAL_WGL_ACCESS_READ_WRITE 0x0001
+#define LOCAL_WGL_ACCESS_WRITE_DISCARD 0x0002
+
+// Others
+#define LOCAL_EGL_PRESERVED_RESOURCES 0x3030
+#define LOCAL_EGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_EXT 0x3138
+#define LOCAL_GL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define LOCAL_GL_CONTEXT_LOST 0x9242
+#define LOCAL_GL_CONTEXT_FLAGS_ARB 0x2094
+#define LOCAL_GL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define LOCAL_GL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#define LOCAL_GL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
+
+#endif
diff --git a/gfx/gl/GLLibraryEGL.cpp b/gfx/gl/GLLibraryEGL.cpp
new file mode 100644
index 0000000000..130bce1191
--- /dev/null
+++ b/gfx/gl/GLLibraryEGL.cpp
@@ -0,0 +1,797 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "GLLibraryEGL.h"
+
+#include "angle/Platform.h"
+#include "gfxConfig.h"
+#include "gfxCrashReporterUtils.h"
+#include "gfxUtils.h"
+#include "mozilla/Preferences.h"
+#include "mozilla/Assertions.h"
+#include "mozilla/Telemetry.h"
+#include "mozilla/Tokenizer.h"
+#include "mozilla/ScopeExit.h"
+#include "mozilla/Unused.h"
+#include "nsDirectoryServiceDefs.h"
+#include "nsDirectoryServiceUtils.h"
+#include "nsIGfxInfo.h"
+#include "nsPrintfCString.h"
+#ifdef XP_WIN
+#include "nsWindowsHelpers.h"
+#endif
+#include "OGLShaderProgram.h"
+#include "prenv.h"
+#include "GLContext.h"
+#include "GLContextProvider.h"
+#include "gfxPrefs.h"
+#include "ScopedGLHelpers.h"
+
+namespace mozilla {
+namespace gl {
+
+StaticMutex GLLibraryEGL::sMutex;
+GLLibraryEGL sEGLLibrary;
+#ifdef MOZ_B2G
+MOZ_THREAD_LOCAL(EGLContext) GLLibraryEGL::sCurrentContext;
+#endif
+
+// should match the order of EGLExtensions, and be null-terminated.
+static const char* sEGLExtensionNames[] = {
+ "EGL_KHR_image_base",
+ "EGL_KHR_image_pixmap",
+ "EGL_KHR_gl_texture_2D_image",
+ "EGL_KHR_lock_surface",
+ "EGL_ANGLE_surface_d3d_texture_2d_share_handle",
+ "EGL_EXT_create_context_robustness",
+ "EGL_KHR_image",
+ "EGL_KHR_fence_sync",
+ "EGL_ANDROID_native_fence_sync",
+ "EGL_ANDROID_image_crop",
+ "EGL_ANGLE_platform_angle",
+ "EGL_ANGLE_platform_angle_d3d"
+};
+
+#if defined(ANDROID)
+
+static PRLibrary* LoadApitraceLibrary()
+{
+ // Initialization of gfx prefs here is only needed during the unit tests...
+ gfxPrefs::GetSingleton();
+ if (!gfxPrefs::UseApitrace()) {
+ return nullptr;
+ }
+
+ static PRLibrary* sApitraceLibrary = nullptr;
+
+ if (sApitraceLibrary)
+ return sApitraceLibrary;
+
+ nsCString logFile = Preferences::GetCString("gfx.apitrace.logfile");
+
+ if (logFile.IsEmpty()) {
+ logFile = "firefox.trace";
+ }
+
+ // The firefox process can't write to /data/local, but it can write
+ // to $GRE_HOME/
+ nsAutoCString logPath;
+ logPath.AppendPrintf("%s/%s", getenv("GRE_HOME"), logFile.get());
+
+ // apitrace uses the TRACE_FILE environment variable to determine where
+ // to log trace output to
+ printf_stderr("Logging GL tracing output to %s", logPath.get());
+ setenv("TRACE_FILE", logPath.get(), false);
+
+ printf_stderr("Attempting load of %s\n", APITRACE_LIB);
+
+ sApitraceLibrary = PR_LoadLibrary(APITRACE_LIB);
+
+ return sApitraceLibrary;
+}
+
+#endif // ANDROID
+
+#ifdef XP_WIN
+// see the comment in GLLibraryEGL::EnsureInitialized() for the rationale here.
+static PRLibrary*
+LoadLibraryForEGLOnWindows(const nsAString& filename)
+{
+ nsCOMPtr<nsIFile> file;
+ nsresult rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(file));
+ if (NS_FAILED(rv))
+ return nullptr;
+
+ file->Append(filename);
+ PRLibrary* lib = nullptr;
+ rv = file->Load(&lib);
+ if (NS_FAILED(rv)) {
+ nsPrintfCString msg("Failed to load %s - Expect EGL initialization to fail",
+ NS_LossyConvertUTF16toASCII(filename).get());
+ NS_WARNING(msg.get());
+ }
+ return lib;
+}
+
+#endif // XP_WIN
+
+static EGLDisplay
+GetAndInitWARPDisplay(GLLibraryEGL& egl, void* displayType)
+{
+ EGLint attrib_list[] = { LOCAL_EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE,
+ LOCAL_EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE,
+ // Requires:
+ LOCAL_EGL_PLATFORM_ANGLE_TYPE_ANGLE,
+ LOCAL_EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
+ LOCAL_EGL_NONE };
+ EGLDisplay display = egl.fGetPlatformDisplayEXT(LOCAL_EGL_PLATFORM_ANGLE_ANGLE,
+ displayType,
+ attrib_list);
+
+ if (display == EGL_NO_DISPLAY) {
+ const EGLint err = egl.fGetError();
+ if (err != LOCAL_EGL_SUCCESS) {
+ gfxCriticalError() << "Unexpected GL error: " << gfx::hexa(err);
+ MOZ_CRASH("GFX: Unexpected GL error.");
+ }
+ return EGL_NO_DISPLAY;
+ }
+
+ if (!egl.fInitialize(display, nullptr, nullptr))
+ return EGL_NO_DISPLAY;
+
+ return display;
+}
+
+static bool
+IsAccelAngleSupported(const nsCOMPtr<nsIGfxInfo>& gfxInfo,
+ nsACString* const out_failureId)
+{
+ int32_t angleSupport;
+ nsCString failureId;
+ gfxUtils::ThreadSafeGetFeatureStatus(gfxInfo,
+ nsIGfxInfo::FEATURE_WEBGL_ANGLE,
+ failureId,
+ &angleSupport);
+ if (failureId.IsEmpty() && angleSupport != nsIGfxInfo::FEATURE_STATUS_OK) {
+ // This shouldn't happen, if we see this it's because we've missed
+ // some failure paths
+ failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_ACCL_ANGLE_NOT_OK");
+ }
+ if (out_failureId->IsEmpty()) {
+ *out_failureId = failureId;
+ }
+ return (angleSupport == nsIGfxInfo::FEATURE_STATUS_OK);
+}
+
+static EGLDisplay
+GetAndInitDisplay(GLLibraryEGL& egl, void* displayType)
+{
+ EGLDisplay display = egl.fGetDisplay(displayType);
+ if (display == EGL_NO_DISPLAY)
+ return EGL_NO_DISPLAY;
+
+ if (!egl.fInitialize(display, nullptr, nullptr))
+ return EGL_NO_DISPLAY;
+
+ return display;
+}
+
+class AngleErrorReporting: public angle::Platform {
+public:
+ AngleErrorReporting()
+ {
+ // No static constructor
+ }
+
+ void SetFailureId(nsACString* const aFailureId)
+ {
+ mFailureId = aFailureId;
+ }
+
+ void logError(const char *errorMessage) override
+ {
+ if (!mFailureId) {
+ return;
+ }
+
+ nsCString str(errorMessage);
+ Tokenizer tokenizer(str);
+
+ // Parse "ANGLE Display::initialize error " << error.getID() << ": "
+ // << error.getMessage()
+ nsCString currWord;
+ Tokenizer::Token intToken;
+ if (tokenizer.CheckWord("ANGLE") &&
+ tokenizer.CheckWhite() &&
+ tokenizer.CheckWord("Display") &&
+ tokenizer.CheckChar(':') &&
+ tokenizer.CheckChar(':') &&
+ tokenizer.CheckWord("initialize") &&
+ tokenizer.CheckWhite() &&
+ tokenizer.CheckWord("error") &&
+ tokenizer.CheckWhite() &&
+ tokenizer.Check(Tokenizer::TOKEN_INTEGER, intToken)) {
+ *mFailureId = "FAILURE_ID_ANGLE_ID_";
+ mFailureId->AppendPrintf("%i", intToken.AsInteger());
+ } else {
+ *mFailureId = "FAILURE_ID_ANGLE_UNKNOWN";
+ }
+ }
+private:
+ nsACString* mFailureId;
+};
+
+AngleErrorReporting gAngleErrorReporter;
+
+static EGLDisplay
+GetAndInitDisplayForAccelANGLE(GLLibraryEGL& egl, nsACString* const out_failureId)
+{
+ EGLDisplay ret = 0;
+
+ FeatureState& d3d11ANGLE = gfxConfig::GetFeature(Feature::D3D11_HW_ANGLE);
+
+ if (!gfxPrefs::WebGLANGLETryD3D11())
+ d3d11ANGLE.UserDisable("User disabled D3D11 ANGLE by pref",
+ NS_LITERAL_CSTRING("FAILURE_ID_ANGLE_PREF"));
+
+ if (gfxPrefs::WebGLANGLEForceD3D11())
+ d3d11ANGLE.UserForceEnable("User force-enabled D3D11 ANGLE on disabled hardware");
+
+ gAngleErrorReporter.SetFailureId(out_failureId);
+ egl.fANGLEPlatformInitialize(&gAngleErrorReporter);
+
+ auto guardShutdown = mozilla::MakeScopeExit([&] {
+ gAngleErrorReporter.SetFailureId(nullptr);
+ // NOTE: Ideally we should be calling ANGLEPlatformShutdown after the
+ // ANGLE display is destroyed. However gAngleErrorReporter
+ // will live longer than the ANGLE display so we're fine.
+ });
+
+ if (gfxConfig::IsForcedOnByUser(Feature::D3D11_HW_ANGLE)) {
+ return GetAndInitDisplay(egl, LOCAL_EGL_D3D11_ONLY_DISPLAY_ANGLE);
+ }
+
+ if (d3d11ANGLE.IsEnabled()) {
+ ret = GetAndInitDisplay(egl, LOCAL_EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE);
+ }
+
+ if (!ret) {
+ ret = GetAndInitDisplay(egl, EGL_DEFAULT_DISPLAY);
+ }
+
+ if (!ret && out_failureId->IsEmpty()) {
+ *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_ACCL_ANGLE_NO_DISP");
+ }
+
+ return ret;
+}
+
+bool
+GLLibraryEGL::ReadbackEGLImage(EGLImage image, gfx::DataSourceSurface* out_surface)
+{
+ StaticMutexAutoUnlock lock(sMutex);
+ if (!mReadbackGL) {
+ nsCString discardFailureId;
+ mReadbackGL = gl::GLContextProvider::CreateHeadless(gl::CreateContextFlags::NONE,
+ &discardFailureId);
+ }
+
+ ScopedTexture destTex(mReadbackGL);
+ const GLuint target = mReadbackGL->GetPreferredEGLImageTextureTarget();
+ ScopedBindTexture autoTex(mReadbackGL, destTex.Texture(), target);
+ mReadbackGL->fTexParameteri(target, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
+ mReadbackGL->fTexParameteri(target, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
+ mReadbackGL->fTexParameteri(target, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_NEAREST);
+ mReadbackGL->fTexParameteri(target, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST);
+ mReadbackGL->fEGLImageTargetTexture2D(target, image);
+
+ ShaderConfigOGL config = ShaderConfigFromTargetAndFormat(target,
+ out_surface->GetFormat());
+ int shaderConfig = config.mFeatures;
+ mReadbackGL->ReadTexImageHelper()->ReadTexImage(out_surface, 0, target,
+ out_surface->GetSize(), shaderConfig);
+
+ return true;
+}
+
+bool
+GLLibraryEGL::EnsureInitialized(bool forceAccel, nsACString* const out_failureId)
+{
+ if (mInitialized) {
+ return true;
+ }
+
+ mozilla::ScopedGfxFeatureReporter reporter("EGL");
+
+#ifdef MOZ_B2G
+ if (!sCurrentContext.init())
+ MOZ_CRASH("GFX: Tls init failed");
+#endif
+
+#ifdef XP_WIN
+ if (!mEGLLibrary) {
+ // On Windows, the GLESv2, EGL and DXSDK libraries are shipped with libxul and
+ // we should look for them there. We have to load the libs in this
+ // order, because libEGL.dll depends on libGLESv2.dll which depends on the DXSDK
+ // libraries. This matters especially for WebRT apps which are in a different directory.
+ // See bug 760323 and bug 749459
+
+ // Also note that we intentionally leak the libs we load.
+
+ do {
+ // Windows 8.1 has d3dcompiler_47.dll in the system directory.
+ // Try it first. Note that _46 will never be in the system
+ // directory and we ship with at least _43. So there is no point
+ // trying _46 and _43 in the system directory.
+
+ if (LoadLibrarySystem32(L"d3dcompiler_47.dll"))
+ break;
+
+#ifdef MOZ_D3DCOMPILER_VISTA_DLL
+ if (LoadLibraryForEGLOnWindows(NS_LITERAL_STRING(NS_STRINGIFY(MOZ_D3DCOMPILER_VISTA_DLL))))
+ break;
+#endif
+
+#ifdef MOZ_D3DCOMPILER_XP_DLL
+ if (LoadLibraryForEGLOnWindows(NS_LITERAL_STRING(NS_STRINGIFY(MOZ_D3DCOMPILER_XP_DLL))))
+ break;
+#endif
+
+ MOZ_ASSERT(false, "d3dcompiler DLL loading failed.");
+ } while (false);
+
+ LoadLibraryForEGLOnWindows(NS_LITERAL_STRING("libGLESv2.dll"));
+
+ mEGLLibrary = LoadLibraryForEGLOnWindows(NS_LITERAL_STRING("libEGL.dll"));
+
+ if (!mEGLLibrary) {
+ *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_EGL_LOAD");
+ return false;
+ }
+ }
+
+#else // !Windows
+
+ // On non-Windows (Android) we use system copies of libEGL. We look for
+ // the APITrace lib, libEGL.so, and libEGL.so.1 in that order.
+
+#if defined(ANDROID)
+ if (!mEGLLibrary)
+ mEGLLibrary = LoadApitraceLibrary();
+#endif
+
+ if (!mEGLLibrary) {
+ printf_stderr("Attempting load of libEGL.so\n");
+ mEGLLibrary = PR_LoadLibrary("libEGL.so");
+ }
+#if defined(XP_UNIX)
+ if (!mEGLLibrary) {
+ mEGLLibrary = PR_LoadLibrary("libEGL.so.1");
+ }
+#endif
+
+ if (!mEGLLibrary) {
+ NS_WARNING("Couldn't load EGL LIB.");
+ *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_EGL_LOAD_2");
+ return false;
+ }
+
+#endif // !Windows
+
+#define SYMBOL(name) \
+{ (PRFuncPtr*) &mSymbols.f##name, { "egl" #name, nullptr } }
+
+ GLLibraryLoader::SymLoadStruct earlySymbols[] = {
+ SYMBOL(GetDisplay),
+ SYMBOL(Terminate),
+ SYMBOL(GetCurrentSurface),
+ SYMBOL(GetCurrentContext),
+ SYMBOL(MakeCurrent),
+ SYMBOL(DestroyContext),
+ SYMBOL(CreateContext),
+ SYMBOL(DestroySurface),
+ SYMBOL(CreateWindowSurface),
+ SYMBOL(CreatePbufferSurface),
+ SYMBOL(CreatePixmapSurface),
+ SYMBOL(BindAPI),
+ SYMBOL(Initialize),
+ SYMBOL(ChooseConfig),
+ SYMBOL(GetError),
+ SYMBOL(GetConfigs),
+ SYMBOL(GetConfigAttrib),
+ SYMBOL(WaitNative),
+ SYMBOL(GetProcAddress),
+ SYMBOL(SwapBuffers),
+ SYMBOL(CopyBuffers),
+ SYMBOL(QueryString),
+ SYMBOL(QueryContext),
+ SYMBOL(BindTexImage),
+ SYMBOL(ReleaseTexImage),
+ SYMBOL(QuerySurface),
+ { nullptr, { nullptr } }
+ };
+
+ if (!GLLibraryLoader::LoadSymbols(mEGLLibrary, &earlySymbols[0])) {
+ NS_WARNING("Couldn't find required entry points in EGL library (early init)");
+ *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_EGL_SYM");
+ return false;
+ }
+
+ GLLibraryLoader::SymLoadStruct optionalSymbols[] = {
+ // On Android 4.3 and up, certain features like ANDROID_native_fence_sync
+ // can only be queried by using a special eglQueryString.
+ { (PRFuncPtr*) &mSymbols.fQueryStringImplementationANDROID,
+ { "_Z35eglQueryStringImplementationANDROIDPvi", nullptr } },
+ { nullptr, { nullptr } }
+ };
+
+ // Do not warn about the failure to load this - see bug 1092191
+ Unused << GLLibraryLoader::LoadSymbols(mEGLLibrary, &optionalSymbols[0],
+ nullptr, nullptr, false);
+
+ InitClientExtensions();
+
+ const auto lookupFunction =
+ (GLLibraryLoader::PlatformLookupFunction)mSymbols.fGetProcAddress;
+
+ // Client exts are ready. (But not display exts!)
+ if (IsExtensionSupported(ANGLE_platform_angle_d3d)) {
+ GLLibraryLoader::SymLoadStruct d3dSymbols[] = {
+ { (PRFuncPtr*)&mSymbols.fANGLEPlatformInitialize, { "ANGLEPlatformInitialize", nullptr } },
+ { (PRFuncPtr*)&mSymbols.fANGLEPlatformShutdown, { "ANGLEPlatformShutdown", nullptr } },
+ { (PRFuncPtr*)&mSymbols.fGetPlatformDisplayEXT, { "eglGetPlatformDisplayEXT", nullptr } },
+ { nullptr, { nullptr } }
+ };
+
+ bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
+ &d3dSymbols[0],
+ lookupFunction);
+ if (!success) {
+ NS_ERROR("EGL supports ANGLE_platform_angle_d3d without exposing its functions!");
+
+ MarkExtensionUnsupported(ANGLE_platform_angle_d3d);
+
+ mSymbols.fGetPlatformDisplayEXT = nullptr;
+ }
+ }
+
+ // Check the ANGLE support the system has
+ nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
+ mIsANGLE = IsExtensionSupported(ANGLE_platform_angle);
+
+ EGLDisplay chosenDisplay = nullptr;
+
+ if (IsExtensionSupported(ANGLE_platform_angle_d3d)) {
+ nsCString accelAngleFailureId;
+ bool accelAngleSupport = IsAccelAngleSupported(gfxInfo, &accelAngleFailureId);
+ bool shouldTryAccel = forceAccel || accelAngleSupport;
+ bool shouldTryWARP = !forceAccel; // Only if ANGLE not supported or fails
+
+ // If WARP preferred, will override ANGLE support
+ if (gfxPrefs::WebGLANGLEForceWARP()) {
+ shouldTryWARP = true;
+ shouldTryAccel = false;
+ if (accelAngleFailureId.IsEmpty()) {
+ accelAngleFailureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_FORCE_WARP");
+ }
+ }
+
+ // Hardware accelerated ANGLE path (supported or force accel)
+ if (shouldTryAccel) {
+ chosenDisplay = GetAndInitDisplayForAccelANGLE(*this, out_failureId);
+ }
+
+ // Report the acceleration status to telemetry
+ if (!chosenDisplay) {
+ if (accelAngleFailureId.IsEmpty()) {
+ Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_ACCL_FAILURE_ID,
+ NS_LITERAL_CSTRING("FEATURE_FAILURE_ACCL_ANGLE_UNKNOWN"));
+ } else {
+ Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_ACCL_FAILURE_ID,
+ accelAngleFailureId);
+ }
+ } else {
+ Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_ACCL_FAILURE_ID,
+ NS_LITERAL_CSTRING("SUCCESS"));
+ }
+
+ // Fallback to a WARP display if ANGLE fails, or if WARP is forced
+ if (!chosenDisplay && shouldTryWARP) {
+ chosenDisplay = GetAndInitWARPDisplay(*this, EGL_DEFAULT_DISPLAY);
+ if (!chosenDisplay) {
+ if (out_failureId->IsEmpty()) {
+ *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WARP_FALLBACK");
+ }
+ NS_ERROR("Fallback WARP context failed to initialize.");
+ return false;
+ }
+ mIsWARP = true;
+ }
+ } else {
+ chosenDisplay = GetAndInitDisplay(*this, EGL_DEFAULT_DISPLAY);
+ }
+
+ if (!chosenDisplay) {
+ if (out_failureId->IsEmpty()) {
+ *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_NO_DISPLAY");
+ }
+ NS_WARNING("Failed to initialize a display.");
+ return false;
+ }
+ mEGLDisplay = chosenDisplay;
+
+ InitDisplayExtensions();
+
+ ////////////////////////////////////
+ // Alright, load display exts.
+
+ if (IsExtensionSupported(KHR_lock_surface)) {
+ GLLibraryLoader::SymLoadStruct lockSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fLockSurface, { "eglLockSurfaceKHR", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fUnlockSurface, { "eglUnlockSurfaceKHR", nullptr } },
+ { nullptr, { nullptr } }
+ };
+
+ bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
+ &lockSymbols[0],
+ lookupFunction);
+ if (!success) {
+ NS_ERROR("EGL supports KHR_lock_surface without exposing its functions!");
+
+ MarkExtensionUnsupported(KHR_lock_surface);
+
+ mSymbols.fLockSurface = nullptr;
+ mSymbols.fUnlockSurface = nullptr;
+ }
+ }
+
+ if (IsExtensionSupported(ANGLE_surface_d3d_texture_2d_share_handle)) {
+ GLLibraryLoader::SymLoadStruct d3dSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fQuerySurfacePointerANGLE, { "eglQuerySurfacePointerANGLE", nullptr } },
+ { nullptr, { nullptr } }
+ };
+
+ bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
+ &d3dSymbols[0],
+ lookupFunction);
+ if (!success) {
+ NS_ERROR("EGL supports ANGLE_surface_d3d_texture_2d_share_handle without exposing its functions!");
+
+ MarkExtensionUnsupported(ANGLE_surface_d3d_texture_2d_share_handle);
+
+ mSymbols.fQuerySurfacePointerANGLE = nullptr;
+ }
+ }
+
+ if (IsExtensionSupported(KHR_fence_sync)) {
+ GLLibraryLoader::SymLoadStruct syncSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fCreateSync, { "eglCreateSyncKHR", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDestroySync, { "eglDestroySyncKHR", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fClientWaitSync, { "eglClientWaitSyncKHR", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fGetSyncAttrib, { "eglGetSyncAttribKHR", nullptr } },
+ { nullptr, { nullptr } }
+ };
+
+ bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
+ &syncSymbols[0],
+ lookupFunction);
+ if (!success) {
+ NS_ERROR("EGL supports KHR_fence_sync without exposing its functions!");
+
+ MarkExtensionUnsupported(KHR_fence_sync);
+
+ mSymbols.fCreateSync = nullptr;
+ mSymbols.fDestroySync = nullptr;
+ mSymbols.fClientWaitSync = nullptr;
+ mSymbols.fGetSyncAttrib = nullptr;
+ }
+ }
+
+ if (IsExtensionSupported(KHR_image) || IsExtensionSupported(KHR_image_base)) {
+ GLLibraryLoader::SymLoadStruct imageSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fCreateImage, { "eglCreateImageKHR", nullptr } },
+ { (PRFuncPtr*) &mSymbols.fDestroyImage, { "eglDestroyImageKHR", nullptr } },
+ { nullptr, { nullptr } }
+ };
+
+ bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
+ &imageSymbols[0],
+ lookupFunction);
+ if (!success) {
+ NS_ERROR("EGL supports KHR_image(_base) without exposing its functions!");
+
+ MarkExtensionUnsupported(KHR_image);
+ MarkExtensionUnsupported(KHR_image_base);
+ MarkExtensionUnsupported(KHR_image_pixmap);
+
+ mSymbols.fCreateImage = nullptr;
+ mSymbols.fDestroyImage = nullptr;
+ }
+ } else {
+ MarkExtensionUnsupported(KHR_image_pixmap);
+ }
+
+ if (IsExtensionSupported(ANDROID_native_fence_sync)) {
+ GLLibraryLoader::SymLoadStruct nativeFenceSymbols[] = {
+ { (PRFuncPtr*) &mSymbols.fDupNativeFenceFDANDROID, { "eglDupNativeFenceFDANDROID", nullptr } },
+ { nullptr, { nullptr } }
+ };
+
+ bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
+ &nativeFenceSymbols[0],
+ lookupFunction);
+ if (!success) {
+ NS_ERROR("EGL supports ANDROID_native_fence_sync without exposing its functions!");
+
+ MarkExtensionUnsupported(ANDROID_native_fence_sync);
+
+ mSymbols.fDupNativeFenceFDANDROID = nullptr;
+ }
+ }
+
+ mInitialized = true;
+ reporter.SetSuccessful();
+ return true;
+}
+
+template<size_t N>
+static void
+MarkExtensions(const char* rawExtString, bool shouldDumpExts, const char* extType,
+ std::bitset<N>* const out)
+{
+ MOZ_ASSERT(rawExtString);
+
+ const nsDependentCString extString(rawExtString);
+
+ std::vector<nsCString> extList;
+ SplitByChar(extString, ' ', &extList);
+
+ if (shouldDumpExts) {
+ printf_stderr("%u EGL %s extensions: (*: recognized)\n",
+ (uint32_t)extList.size(), extType);
+ }
+
+ MarkBitfieldByStrings(extList, shouldDumpExts, sEGLExtensionNames, out);
+}
+
+void
+GLLibraryEGL::InitClientExtensions()
+{
+ const bool shouldDumpExts = GLContext::ShouldDumpExts();
+
+ const char* rawExtString = nullptr;
+
+#ifndef ANDROID
+ // Bug 1209612: Crashes on a number of android drivers.
+ // Ideally we would only blocklist this there, but for now we don't need the client
+ // extension list on ANDROID (we mostly need it on ANGLE), and we'd rather not crash.
+ rawExtString = (const char*)fQueryString(nullptr, LOCAL_EGL_EXTENSIONS);
+#endif
+
+ if (!rawExtString) {
+ if (shouldDumpExts) {
+ printf_stderr("No EGL client extensions.\n");
+ }
+ return;
+ }
+
+ MarkExtensions(rawExtString, shouldDumpExts, "client", &mAvailableExtensions);
+}
+
+void
+GLLibraryEGL::InitDisplayExtensions()
+{
+ MOZ_ASSERT(mEGLDisplay);
+
+ const bool shouldDumpExts = GLContext::ShouldDumpExts();
+
+ const auto rawExtString = (const char*)fQueryString(mEGLDisplay,
+ LOCAL_EGL_EXTENSIONS);
+ if (!rawExtString) {
+ NS_WARNING("Failed to query EGL display extensions!.");
+ return;
+ }
+
+ MarkExtensions(rawExtString, shouldDumpExts, "display", &mAvailableExtensions);
+}
+
+void
+GLLibraryEGL::DumpEGLConfig(EGLConfig cfg)
+{
+ int attrval;
+ int err;
+
+#define ATTR(_x) do { \
+ fGetConfigAttrib(mEGLDisplay, cfg, LOCAL_EGL_##_x, &attrval); \
+ if ((err = fGetError()) != 0x3000) { \
+ printf_stderr(" %s: ERROR (0x%04x)\n", #_x, err); \
+ } else { \
+ printf_stderr(" %s: %d (0x%04x)\n", #_x, attrval, attrval); \
+ } \
+ } while(0)
+
+ printf_stderr("EGL Config: %d [%p]\n", (int)(intptr_t)cfg, cfg);
+
+ ATTR(BUFFER_SIZE);
+ ATTR(ALPHA_SIZE);
+ ATTR(BLUE_SIZE);
+ ATTR(GREEN_SIZE);
+ ATTR(RED_SIZE);
+ ATTR(DEPTH_SIZE);
+ ATTR(STENCIL_SIZE);
+ ATTR(CONFIG_CAVEAT);
+ ATTR(CONFIG_ID);
+ ATTR(LEVEL);
+ ATTR(MAX_PBUFFER_HEIGHT);
+ ATTR(MAX_PBUFFER_PIXELS);
+ ATTR(MAX_PBUFFER_WIDTH);
+ ATTR(NATIVE_RENDERABLE);
+ ATTR(NATIVE_VISUAL_ID);
+ ATTR(NATIVE_VISUAL_TYPE);
+ ATTR(PRESERVED_RESOURCES);
+ ATTR(SAMPLES);
+ ATTR(SAMPLE_BUFFERS);
+ ATTR(SURFACE_TYPE);
+ ATTR(TRANSPARENT_TYPE);
+ ATTR(TRANSPARENT_RED_VALUE);
+ ATTR(TRANSPARENT_GREEN_VALUE);
+ ATTR(TRANSPARENT_BLUE_VALUE);
+ ATTR(BIND_TO_TEXTURE_RGB);
+ ATTR(BIND_TO_TEXTURE_RGBA);
+ ATTR(MIN_SWAP_INTERVAL);
+ ATTR(MAX_SWAP_INTERVAL);
+ ATTR(LUMINANCE_SIZE);
+ ATTR(ALPHA_MASK_SIZE);
+ ATTR(COLOR_BUFFER_TYPE);
+ ATTR(RENDERABLE_TYPE);
+ ATTR(CONFORMANT);
+
+#undef ATTR
+}
+
+void
+GLLibraryEGL::DumpEGLConfigs()
+{
+ int nc = 0;
+ fGetConfigs(mEGLDisplay, nullptr, 0, &nc);
+ EGLConfig* ec = new EGLConfig[nc];
+ fGetConfigs(mEGLDisplay, ec, nc, &nc);
+
+ for (int i = 0; i < nc; ++i) {
+ printf_stderr("========= EGL Config %d ========\n", i);
+ DumpEGLConfig(ec[i]);
+ }
+
+ delete [] ec;
+}
+
+#ifdef DEBUG
+static bool
+ShouldTrace()
+{
+ static bool ret = gfxEnv::GlDebugVerbose();
+ return ret;
+}
+
+/*static*/ void
+GLLibraryEGL::BeforeGLCall(const char* glFunction)
+{
+ if (ShouldTrace()) {
+ printf_stderr("[egl] > %s\n", glFunction);
+ }
+}
+
+/*static*/ void
+GLLibraryEGL::AfterGLCall(const char* glFunction)
+{
+ if (ShouldTrace()) {
+ printf_stderr("[egl] < %s\n", glFunction);
+ }
+}
+#endif
+
+} /* namespace gl */
+} /* namespace mozilla */
+
diff --git a/gfx/gl/GLLibraryEGL.h b/gfx/gl/GLLibraryEGL.h
new file mode 100644
index 0000000000..fa6ea748b6
--- /dev/null
+++ b/gfx/gl/GLLibraryEGL.h
@@ -0,0 +1,704 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GLLIBRARYEGL_H_
+#define GLLIBRARYEGL_H_
+
+#if defined(MOZ_X11)
+#include "mozilla/X11Util.h"
+#endif
+
+#include "GLLibraryLoader.h"
+#include "mozilla/StaticMutex.h"
+#include "mozilla/ThreadLocal.h"
+#include "nsIFile.h"
+#include "GeckoProfiler.h"
+
+#include <bitset>
+#include <vector>
+
+#ifdef XP_WIN
+ #ifndef WIN32_LEAN_AND_MEAN
+ #define WIN32_LEAN_AND_MEAN 1
+ #endif
+
+ #include <windows.h>
+
+ typedef HDC EGLNativeDisplayType;
+ typedef HBITMAP EGLNativePixmapType;
+ typedef HWND EGLNativeWindowType;
+#else
+ typedef void* EGLNativeDisplayType;
+ typedef void* EGLNativePixmapType;
+ typedef void* EGLNativeWindowType;
+
+ #ifdef ANDROID
+ // We only need to explicitly dlopen egltrace
+ // on android as we can use LD_PRELOAD or other tricks
+ // on other platforms. We look for it in /data/local
+ // as that's writeable by all users
+ //
+ // This should really go in GLLibraryEGL.cpp but we currently reference
+ // APITRACE_LIB in GLContextProviderEGL.cpp. Further refactoring
+ // will come in subsequent patches on Bug 732865
+ #define APITRACE_LIB "/data/local/tmp/egltrace.so"
+ #endif
+#endif
+
+#if defined(MOZ_X11)
+#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)mozilla::DefaultXDisplay())
+#else
+#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0)
+#endif
+
+namespace angle {
+class Platform;
+}
+
+namespace mozilla {
+
+namespace gfx {
+class DataSourceSurface;
+}
+
+namespace gl {
+
+#undef BEFORE_GL_CALL
+#undef AFTER_GL_CALL
+
+#ifdef DEBUG
+
+#ifndef MOZ_FUNCTION_NAME
+# ifdef __GNUC__
+# define MOZ_FUNCTION_NAME __PRETTY_FUNCTION__
+# elif defined(_MSC_VER)
+# define MOZ_FUNCTION_NAME __FUNCTION__
+# else
+# define MOZ_FUNCTION_NAME __func__ // defined in C99, supported in various C++ compilers. Just raw function name.
+# endif
+#endif
+
+#ifdef MOZ_WIDGET_ANDROID
+// Record the name of the GL call for better hang stacks on Android.
+#define BEFORE_GL_CALL \
+ PROFILER_LABEL_FUNC( \
+ js::ProfileEntry::Category::GRAPHICS);\
+ BeforeGLCall(MOZ_FUNCTION_NAME)
+#else
+#define BEFORE_GL_CALL do { \
+ BeforeGLCall(MOZ_FUNCTION_NAME); \
+} while (0)
+#endif
+
+#define AFTER_GL_CALL do { \
+ AfterGLCall(MOZ_FUNCTION_NAME); \
+} while (0)
+#else
+#ifdef MOZ_WIDGET_ANDROID
+// Record the name of the GL call for better hang stacks on Android.
+#define BEFORE_GL_CALL PROFILER_LABEL_FUNC(js::ProfileEntry::Category::GRAPHICS)
+#else
+#define BEFORE_GL_CALL
+#endif
+#define AFTER_GL_CALL
+#endif
+
+class GLContext;
+
+class GLLibraryEGL
+{
+public:
+ GLLibraryEGL()
+ : mInitialized(false),
+ mEGLLibrary(nullptr),
+ mEGLDisplay(EGL_NO_DISPLAY),
+ mIsANGLE(false),
+ mIsWARP(false)
+ {
+ ClearSymbols();
+ }
+
+ void ClearSymbols() {
+ mSymbols.fANGLEPlatformInitialize = nullptr;
+ mSymbols.fANGLEPlatformShutdown = nullptr;
+ mSymbols.fGetDisplay = nullptr;
+ mSymbols.fGetPlatformDisplayEXT = nullptr;
+ mSymbols.fTerminate = nullptr;
+ mSymbols.fGetCurrentSurface = nullptr;
+ mSymbols.fGetCurrentContext = nullptr;
+ mSymbols.fMakeCurrent = nullptr;
+ mSymbols.fDestroyContext = nullptr;
+ mSymbols.fCreateContext = nullptr;
+ mSymbols.fDestroySurface = nullptr;
+ mSymbols.fCreateWindowSurface = nullptr;
+ mSymbols.fCreatePbufferSurface = nullptr;
+ mSymbols.fCreatePixmapSurface = nullptr;
+ mSymbols.fBindAPI = nullptr;
+ mSymbols.fInitialize = nullptr;
+ mSymbols.fChooseConfig = nullptr;
+ mSymbols.fGetError = nullptr;
+ mSymbols.fGetConfigAttrib = nullptr;
+ mSymbols.fGetConfigs = nullptr;
+ mSymbols.fWaitNative = nullptr;
+ mSymbols.fGetProcAddress = nullptr;
+ mSymbols.fSwapBuffers = nullptr;
+ mSymbols.fCopyBuffers = nullptr;
+ mSymbols.fQueryString = nullptr;
+ mSymbols.fQueryStringImplementationANDROID = nullptr;
+ mSymbols.fQueryContext = nullptr;
+ mSymbols.fBindTexImage = nullptr;
+ mSymbols.fReleaseTexImage = nullptr;
+ mSymbols.fCreateImage = nullptr;
+ mSymbols.fDestroyImage = nullptr;
+ mSymbols.fLockSurface = nullptr;
+ mSymbols.fUnlockSurface = nullptr;
+ mSymbols.fQuerySurface = nullptr;
+ mSymbols.fQuerySurfacePointerANGLE = nullptr;
+ mSymbols.fCreateSync = nullptr;
+ mSymbols.fDestroySync = nullptr;
+ mSymbols.fClientWaitSync = nullptr;
+ mSymbols.fGetSyncAttrib = nullptr;
+ mSymbols.fDupNativeFenceFDANDROID = nullptr;
+ }
+
+ void InitClientExtensions();
+ void InitDisplayExtensions();
+
+ /**
+ * Known GL extensions that can be queried by
+ * IsExtensionSupported. The results of this are cached, and as
+ * such it's safe to use this even in performance critical code.
+ * If you add to this array, remember to add to the string names
+ * in GLContext.cpp.
+ */
+ enum EGLExtensions {
+ KHR_image_base,
+ KHR_image_pixmap,
+ KHR_gl_texture_2D_image,
+ KHR_lock_surface,
+ ANGLE_surface_d3d_texture_2d_share_handle,
+ EXT_create_context_robustness,
+ KHR_image,
+ KHR_fence_sync,
+ ANDROID_native_fence_sync,
+ EGL_ANDROID_image_crop,
+ ANGLE_platform_angle,
+ ANGLE_platform_angle_d3d,
+ Extensions_Max
+ };
+
+ bool IsExtensionSupported(EGLExtensions aKnownExtension) const {
+ return mAvailableExtensions[aKnownExtension];
+ }
+
+ void MarkExtensionUnsupported(EGLExtensions aKnownExtension) {
+ mAvailableExtensions[aKnownExtension] = false;
+ }
+
+protected:
+ std::bitset<Extensions_Max> mAvailableExtensions;
+
+public:
+
+ EGLDisplay fGetDisplay(void* display_id)
+ {
+ BEFORE_GL_CALL;
+ EGLDisplay disp = mSymbols.fGetDisplay(display_id);
+ AFTER_GL_CALL;
+ return disp;
+ }
+
+ EGLDisplay fGetPlatformDisplayEXT(EGLenum platform, void* native_display, const EGLint* attrib_list)
+ {
+ BEFORE_GL_CALL;
+ EGLDisplay disp = mSymbols.fGetPlatformDisplayEXT(platform, native_display, attrib_list);
+ AFTER_GL_CALL;
+ return disp;
+ }
+
+ EGLBoolean fTerminate(EGLDisplay display)
+ {
+ BEFORE_GL_CALL;
+ EGLBoolean ret = mSymbols.fTerminate(display);
+ AFTER_GL_CALL;
+ return ret;
+ }
+
+ EGLSurface fGetCurrentSurface(EGLint id)
+ {
+ BEFORE_GL_CALL;
+ EGLSurface surf = mSymbols.fGetCurrentSurface(id);
+ AFTER_GL_CALL;
+ return surf;
+ }
+
+ EGLContext fGetCurrentContext()
+ {
+ BEFORE_GL_CALL;
+ EGLContext context = mSymbols.fGetCurrentContext();
+ AFTER_GL_CALL;
+ return context;
+ }
+
+ EGLBoolean fMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
+ {
+ BEFORE_GL_CALL;
+ EGLBoolean b = mSymbols.fMakeCurrent(dpy, draw, read, ctx);
+ AFTER_GL_CALL;
+ return b;
+ }
+
+ EGLBoolean fDestroyContext(EGLDisplay dpy, EGLContext ctx)
+ {
+ BEFORE_GL_CALL;
+ EGLBoolean b = mSymbols.fDestroyContext(dpy, ctx);
+ AFTER_GL_CALL;
+ return b;
+ }
+
+ EGLContext fCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint* attrib_list)
+ {
+ BEFORE_GL_CALL;
+ EGLContext ctx = mSymbols.fCreateContext(dpy, config, share_context, attrib_list);
+ AFTER_GL_CALL;
+ return ctx;
+ }
+
+ EGLBoolean fDestroySurface(EGLDisplay dpy, EGLSurface surface)
+ {
+ BEFORE_GL_CALL;
+ EGLBoolean b = mSymbols.fDestroySurface(dpy, surface);
+ AFTER_GL_CALL;
+ return b;
+ }
+
+ EGLSurface fCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint* attrib_list)
+ {
+ BEFORE_GL_CALL;
+ EGLSurface surf = mSymbols.fCreateWindowSurface(dpy, config, win, attrib_list);
+ AFTER_GL_CALL;
+ return surf;
+ }
+
+ EGLSurface fCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list)
+ {
+ BEFORE_GL_CALL;
+ EGLSurface surf = mSymbols.fCreatePbufferSurface(dpy, config, attrib_list);
+ AFTER_GL_CALL;
+ return surf;
+ }
+
+ EGLSurface fCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint* attrib_list)
+ {
+ BEFORE_GL_CALL;
+ EGLSurface surf = mSymbols.fCreatePixmapSurface(dpy, config, pixmap, attrib_list);
+ AFTER_GL_CALL;
+ return surf;
+ }
+
+ EGLBoolean fBindAPI(EGLenum api)
+ {
+ BEFORE_GL_CALL;
+ EGLBoolean b = mSymbols.fBindAPI(api);
+ AFTER_GL_CALL;
+ return b;
+ }
+
+ EGLBoolean fInitialize(EGLDisplay dpy, EGLint* major, EGLint* minor)
+ {
+ BEFORE_GL_CALL;
+ EGLBoolean b = mSymbols.fInitialize(dpy, major, minor);
+ AFTER_GL_CALL;
+ return b;
+ }
+
+ EGLBoolean fChooseConfig(EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, EGLint config_size, EGLint* num_config)
+ {
+ BEFORE_GL_CALL;
+ EGLBoolean b = mSymbols.fChooseConfig(dpy, attrib_list, configs, config_size, num_config);
+ AFTER_GL_CALL;
+ return b;
+ }
+
+ EGLint fGetError()
+ {
+ BEFORE_GL_CALL;
+ EGLint i = mSymbols.fGetError();
+ AFTER_GL_CALL;
+ return i;
+ }
+
+ EGLBoolean fGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value)
+ {
+ BEFORE_GL_CALL;
+ EGLBoolean b = mSymbols.fGetConfigAttrib(dpy, config, attribute, value);
+ AFTER_GL_CALL;
+ return b;
+ }
+
+ EGLBoolean fGetConfigs(EGLDisplay dpy, EGLConfig* configs, EGLint config_size, EGLint* num_config)
+ {
+ BEFORE_GL_CALL;
+ EGLBoolean b = mSymbols.fGetConfigs(dpy, configs, config_size, num_config);
+ AFTER_GL_CALL;
+ return b;
+ }
+
+ EGLBoolean fWaitNative(EGLint engine)
+ {
+ BEFORE_GL_CALL;
+ EGLBoolean b = mSymbols.fWaitNative(engine);
+ AFTER_GL_CALL;
+ return b;
+ }
+
+ EGLCastToRelevantPtr fGetProcAddress(const char* procname)
+ {
+ BEFORE_GL_CALL;
+ EGLCastToRelevantPtr p = mSymbols.fGetProcAddress(procname);
+ AFTER_GL_CALL;
+ return p;
+ }
+
+ EGLBoolean fSwapBuffers(EGLDisplay dpy, EGLSurface surface)
+ {
+ BEFORE_GL_CALL;
+ EGLBoolean b = mSymbols.fSwapBuffers(dpy, surface);
+ AFTER_GL_CALL;
+ return b;
+ }
+
+ EGLBoolean fCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
+ {
+ BEFORE_GL_CALL;
+ EGLBoolean b = mSymbols.fCopyBuffers(dpy, surface, target);
+ AFTER_GL_CALL;
+ return b;
+ }
+
+ const GLubyte* fQueryString(EGLDisplay dpy, EGLint name)
+ {
+ BEFORE_GL_CALL;
+ const GLubyte* b;
+ if (mSymbols.fQueryStringImplementationANDROID) {
+ b = mSymbols.fQueryStringImplementationANDROID(dpy, name);
+ } else {
+ b = mSymbols.fQueryString(dpy, name);
+ }
+ AFTER_GL_CALL;
+ return b;
+ }
+
+ EGLBoolean fQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint* value)
+ {
+ BEFORE_GL_CALL;
+ EGLBoolean b = mSymbols.fQueryContext(dpy, ctx, attribute, value);
+ AFTER_GL_CALL;
+ return b;
+ }
+
+ EGLBoolean fBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+ {
+ BEFORE_GL_CALL;
+ EGLBoolean b = mSymbols.fBindTexImage(dpy, surface, buffer);
+ AFTER_GL_CALL;
+ return b;
+ }
+
+ EGLBoolean fReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+ {
+ BEFORE_GL_CALL;
+ EGLBoolean b = mSymbols.fReleaseTexImage(dpy, surface, buffer);
+ AFTER_GL_CALL;
+ return b;
+ }
+
+ EGLImage fCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint* attrib_list)
+ {
+ BEFORE_GL_CALL;
+ EGLImage i = mSymbols.fCreateImage(dpy, ctx, target, buffer, attrib_list);
+ AFTER_GL_CALL;
+ return i;
+ }
+
+ EGLBoolean fDestroyImage(EGLDisplay dpy, EGLImage image)
+ {
+ BEFORE_GL_CALL;
+ EGLBoolean b = mSymbols.fDestroyImage(dpy, image);
+ AFTER_GL_CALL;
+ return b;
+ }
+
+ // New extension which allow us to lock texture and get raw image pointer
+ EGLBoolean fLockSurface(EGLDisplay dpy, EGLSurface surface, const EGLint* attrib_list)
+ {
+ BEFORE_GL_CALL;
+ EGLBoolean b = mSymbols.fLockSurface(dpy, surface, attrib_list);
+ AFTER_GL_CALL;
+ return b;
+ }
+
+ EGLBoolean fUnlockSurface(EGLDisplay dpy, EGLSurface surface)
+ {
+ BEFORE_GL_CALL;
+ EGLBoolean b = mSymbols.fUnlockSurface(dpy, surface);
+ AFTER_GL_CALL;
+ return b;
+ }
+
+ EGLBoolean fQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint* value)
+ {
+ BEFORE_GL_CALL;
+ EGLBoolean b = mSymbols.fQuerySurface(dpy, surface, attribute, value);
+ AFTER_GL_CALL;
+ return b;
+ }
+
+ EGLBoolean fQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void** value)
+ {
+ BEFORE_GL_CALL;
+ EGLBoolean b = mSymbols.fQuerySurfacePointerANGLE(dpy, surface, attribute, value);
+ AFTER_GL_CALL;
+ return b;
+ }
+
+ EGLSync fCreateSync(EGLDisplay dpy, EGLenum type, const EGLint* attrib_list)
+ {
+ BEFORE_GL_CALL;
+ EGLSync ret = mSymbols.fCreateSync(dpy, type, attrib_list);
+ AFTER_GL_CALL;
+ return ret;
+ }
+
+ EGLBoolean fDestroySync(EGLDisplay dpy, EGLSync sync)
+ {
+ BEFORE_GL_CALL;
+ EGLBoolean b = mSymbols.fDestroySync(dpy, sync);
+ AFTER_GL_CALL;
+ return b;
+ }
+
+ EGLint fClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout)
+ {
+ BEFORE_GL_CALL;
+ EGLint ret = mSymbols.fClientWaitSync(dpy, sync, flags, timeout);
+ AFTER_GL_CALL;
+ return ret;
+ }
+
+ EGLBoolean fGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint* value)
+ {
+ BEFORE_GL_CALL;
+ EGLBoolean b = mSymbols.fGetSyncAttrib(dpy, sync, attribute, value);
+ AFTER_GL_CALL;
+ return b;
+ }
+
+ EGLint fDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSync sync)
+ {
+ MOZ_ASSERT(mSymbols.fDupNativeFenceFDANDROID);
+ BEFORE_GL_CALL;
+ EGLint ret = mSymbols.fDupNativeFenceFDANDROID(dpy, sync);
+ AFTER_GL_CALL;
+ return ret;
+ }
+
+ void fANGLEPlatformInitialize(angle::Platform* platform)
+ {
+ MOZ_ASSERT(mSymbols.fANGLEPlatformInitialize);
+ BEFORE_GL_CALL;
+ mSymbols.fANGLEPlatformInitialize(platform);
+ AFTER_GL_CALL;
+ }
+
+ void fANGLEPlatformShutdown()
+ {
+ MOZ_ASSERT(mSymbols.fANGLEPlatformShutdown);
+ BEFORE_GL_CALL;
+ mSymbols.fANGLEPlatformShutdown();
+ AFTER_GL_CALL;
+ }
+
+ EGLDisplay Display() {
+ MOZ_ASSERT(mInitialized);
+ return mEGLDisplay;
+ }
+
+ bool IsANGLE() const {
+ MOZ_ASSERT(mInitialized);
+ return mIsANGLE;
+ }
+
+ bool IsWARP() const {
+ MOZ_ASSERT(mInitialized);
+ return mIsWARP;
+ }
+
+ bool HasKHRImageBase() {
+ return IsExtensionSupported(KHR_image) || IsExtensionSupported(KHR_image_base);
+ }
+
+ bool HasKHRImagePixmap() {
+ return IsExtensionSupported(KHR_image) || IsExtensionSupported(KHR_image_pixmap);
+ }
+
+ bool HasKHRImageTexture2D() {
+ return IsExtensionSupported(KHR_gl_texture_2D_image);
+ }
+
+ bool HasANGLESurfaceD3DTexture2DShareHandle() {
+ return IsExtensionSupported(ANGLE_surface_d3d_texture_2d_share_handle);
+ }
+
+ bool HasRobustness() const {
+ return IsExtensionSupported(EXT_create_context_robustness);
+ }
+
+ bool ReadbackEGLImage(EGLImage image, gfx::DataSourceSurface* out_surface);
+
+ bool EnsureInitialized(bool forceAccel, nsACString* const out_failureId);
+
+ void DumpEGLConfig(EGLConfig cfg);
+ void DumpEGLConfigs();
+
+ struct {
+ typedef EGLDisplay (GLAPIENTRY * pfnGetDisplay)(void* display_id);
+ pfnGetDisplay fGetDisplay;
+ typedef EGLDisplay(GLAPIENTRY * pfnGetPlatformDisplayEXT)(EGLenum platform, void* native_display, const EGLint* attrib_list);
+ pfnGetPlatformDisplayEXT fGetPlatformDisplayEXT;
+ typedef EGLBoolean (GLAPIENTRY * pfnTerminate)(EGLDisplay dpy);
+ pfnTerminate fTerminate;
+ typedef EGLSurface (GLAPIENTRY * pfnGetCurrentSurface)(EGLint);
+ pfnGetCurrentSurface fGetCurrentSurface;
+ typedef EGLContext (GLAPIENTRY * pfnGetCurrentContext)(void);
+ pfnGetCurrentContext fGetCurrentContext;
+ typedef EGLBoolean (GLAPIENTRY * pfnMakeCurrent)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
+ pfnMakeCurrent fMakeCurrent;
+ typedef EGLBoolean (GLAPIENTRY * pfnDestroyContext)(EGLDisplay dpy, EGLContext ctx);
+ pfnDestroyContext fDestroyContext;
+ typedef EGLContext (GLAPIENTRY * pfnCreateContext)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint* attrib_list);
+ pfnCreateContext fCreateContext;
+ typedef EGLBoolean (GLAPIENTRY * pfnDestroySurface)(EGLDisplay dpy, EGLSurface surface);
+ pfnDestroySurface fDestroySurface;
+ typedef EGLSurface (GLAPIENTRY * pfnCreateWindowSurface)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint* attrib_list);
+ pfnCreateWindowSurface fCreateWindowSurface;
+ typedef EGLSurface (GLAPIENTRY * pfnCreatePbufferSurface)(EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list);
+ pfnCreatePbufferSurface fCreatePbufferSurface;
+ typedef EGLSurface (GLAPIENTRY * pfnCreatePixmapSurface)(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint* attrib_list);
+ pfnCreatePixmapSurface fCreatePixmapSurface;
+ typedef EGLBoolean (GLAPIENTRY * pfnBindAPI)(EGLenum api);
+ pfnBindAPI fBindAPI;
+ typedef EGLBoolean (GLAPIENTRY * pfnInitialize)(EGLDisplay dpy, EGLint* major, EGLint* minor);
+ pfnInitialize fInitialize;
+ typedef EGLBoolean (GLAPIENTRY * pfnChooseConfig)(EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, EGLint config_size, EGLint* num_config);
+ pfnChooseConfig fChooseConfig;
+ typedef EGLint (GLAPIENTRY * pfnGetError)(void);
+ pfnGetError fGetError;
+ typedef EGLBoolean (GLAPIENTRY * pfnGetConfigAttrib)(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value);
+ pfnGetConfigAttrib fGetConfigAttrib;
+ typedef EGLBoolean (GLAPIENTRY * pfnGetConfigs)(EGLDisplay dpy, EGLConfig* configs, EGLint config_size, EGLint* num_config);
+ pfnGetConfigs fGetConfigs;
+ typedef EGLBoolean (GLAPIENTRY * pfnWaitNative)(EGLint engine);
+ pfnWaitNative fWaitNative;
+ typedef EGLCastToRelevantPtr (GLAPIENTRY * pfnGetProcAddress)(const char* procname);
+ pfnGetProcAddress fGetProcAddress;
+ typedef EGLBoolean (GLAPIENTRY * pfnSwapBuffers)(EGLDisplay dpy, EGLSurface surface);
+ pfnSwapBuffers fSwapBuffers;
+ typedef EGLBoolean (GLAPIENTRY * pfnCopyBuffers)(EGLDisplay dpy, EGLSurface surface,
+ EGLNativePixmapType target);
+ pfnCopyBuffers fCopyBuffers;
+ typedef const GLubyte* (GLAPIENTRY * pfnQueryString)(EGLDisplay, EGLint name);
+ pfnQueryString fQueryString;
+ pfnQueryString fQueryStringImplementationANDROID;
+ typedef EGLBoolean (GLAPIENTRY * pfnQueryContext)(EGLDisplay dpy, EGLContext ctx,
+ EGLint attribute, EGLint* value);
+ pfnQueryContext fQueryContext;
+ typedef EGLBoolean (GLAPIENTRY * pfnBindTexImage)(EGLDisplay, EGLSurface surface, EGLint buffer);
+ pfnBindTexImage fBindTexImage;
+ typedef EGLBoolean (GLAPIENTRY * pfnReleaseTexImage)(EGLDisplay, EGLSurface surface, EGLint buffer);
+ pfnReleaseTexImage fReleaseTexImage;
+ typedef EGLImage (GLAPIENTRY * pfnCreateImage)(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint* attrib_list);
+ pfnCreateImage fCreateImage;
+ typedef EGLBoolean (GLAPIENTRY * pfnDestroyImage)(EGLDisplay dpy, EGLImage image);
+ pfnDestroyImage fDestroyImage;
+
+ // New extension which allow us to lock texture and get raw image pointer
+ typedef EGLBoolean (GLAPIENTRY * pfnLockSurface)(EGLDisplay dpy, EGLSurface surface, const EGLint* attrib_list);
+ pfnLockSurface fLockSurface;
+ typedef EGLBoolean (GLAPIENTRY * pfnUnlockSurface)(EGLDisplay dpy, EGLSurface surface);
+ pfnUnlockSurface fUnlockSurface;
+ typedef EGLBoolean (GLAPIENTRY * pfnQuerySurface)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint* value);
+ pfnQuerySurface fQuerySurface;
+
+ typedef EGLBoolean (GLAPIENTRY * pfnQuerySurfacePointerANGLE)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void** value);
+ pfnQuerySurfacePointerANGLE fQuerySurfacePointerANGLE;
+
+ typedef EGLSync (GLAPIENTRY * pfnCreateSync)(EGLDisplay dpy, EGLenum type, const EGLint* attrib_list);
+ pfnCreateSync fCreateSync;
+ typedef EGLBoolean (GLAPIENTRY * pfnDestroySync)(EGLDisplay dpy, EGLSync sync);
+ pfnDestroySync fDestroySync;
+ typedef EGLint (GLAPIENTRY * pfnClientWaitSync)(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout);
+ pfnClientWaitSync fClientWaitSync;
+ typedef EGLBoolean (GLAPIENTRY * pfnGetSyncAttrib)(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint* value);
+ pfnGetSyncAttrib fGetSyncAttrib;
+ typedef EGLint (GLAPIENTRY * pfnDupNativeFenceFDANDROID)(EGLDisplay dpy, EGLSync sync);
+ pfnDupNativeFenceFDANDROID fDupNativeFenceFDANDROID;
+
+ typedef void (GLAPIENTRY * pfnANGLEPlatformInitialize)(angle::Platform* platform);
+ pfnANGLEPlatformInitialize fANGLEPlatformInitialize;
+ typedef void (GLAPIENTRY * pfnANGLEPlatformShutdown)();
+ pfnANGLEPlatformShutdown fANGLEPlatformShutdown;
+ } mSymbols;
+
+#ifdef DEBUG
+ static void BeforeGLCall(const char* glFunction);
+ static void AfterGLCall(const char* glFunction);
+#endif
+
+#ifdef MOZ_B2G
+ EGLContext CachedCurrentContext() {
+ return sCurrentContext.get();
+ }
+ void UnsetCachedCurrentContext() {
+ sCurrentContext.set(nullptr);
+ }
+ void SetCachedCurrentContext(EGLContext aCtx) {
+ sCurrentContext.set(aCtx);
+ }
+ bool CachedCurrentContextMatches() {
+ return sCurrentContext.get() == fGetCurrentContext();
+ }
+
+private:
+ static MOZ_THREAD_LOCAL(EGLContext) sCurrentContext;
+public:
+
+#else
+ EGLContext CachedCurrentContext() {
+ return nullptr;
+ }
+ void UnsetCachedCurrentContext() {}
+ void SetCachedCurrentContext(EGLContext aCtx) { }
+ bool CachedCurrentContextMatches() { return true; }
+#endif
+
+private:
+ bool mInitialized;
+ PRLibrary* mEGLLibrary;
+ EGLDisplay mEGLDisplay;
+ RefPtr<GLContext> mReadbackGL;
+
+ bool mIsANGLE;
+ bool mIsWARP;
+ static StaticMutex sMutex;
+};
+
+extern GLLibraryEGL sEGLLibrary;
+#define EGL_DISPLAY() sEGLLibrary.Display()
+
+} /* namespace gl */
+} /* namespace mozilla */
+
+#endif /* GLLIBRARYEGL_H_ */
+
diff --git a/gfx/gl/GLLibraryLoader.cpp b/gfx/gl/GLLibraryLoader.cpp
new file mode 100644
index 0000000000..801ffe37cd
--- /dev/null
+++ b/gfx/gl/GLLibraryLoader.cpp
@@ -0,0 +1,117 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "GLLibraryLoader.h"
+
+#include "nsDebug.h"
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+namespace mozilla {
+namespace gl {
+
+bool
+GLLibraryLoader::OpenLibrary(const char* library)
+{
+ PRLibSpec lspec;
+ lspec.type = PR_LibSpec_Pathname;
+ lspec.value.pathname = library;
+
+ mLibrary = PR_LoadLibraryWithFlags(lspec, PR_LD_LAZY | PR_LD_LOCAL);
+ if (!mLibrary)
+ return false;
+
+ return true;
+}
+
+bool
+GLLibraryLoader::LoadSymbols(const SymLoadStruct* firstStruct,
+ bool tryplatform,
+ const char* prefix,
+ bool warnOnFailure)
+{
+ return LoadSymbols(mLibrary,
+ firstStruct,
+ tryplatform ? mLookupFunc : nullptr,
+ prefix,
+ warnOnFailure);
+}
+
+PRFuncPtr
+GLLibraryLoader::LookupSymbol(PRLibrary* lib,
+ const char* sym,
+ PlatformLookupFunction lookupFunction)
+{
+ PRFuncPtr res = 0;
+
+ // try finding it in the library directly, if we have one
+ if (lib) {
+ res = PR_FindFunctionSymbol(lib, sym);
+ }
+
+ // then try looking it up via the lookup symbol
+ if (!res && lookupFunction) {
+ res = lookupFunction(sym);
+ }
+
+ // finally just try finding it in the process
+ if (!res) {
+ PRLibrary* leakedLibRef;
+ res = PR_FindFunctionSymbolAndLibrary(sym, &leakedLibRef);
+ }
+
+ return res;
+}
+
+bool
+GLLibraryLoader::LoadSymbols(PRLibrary* lib,
+ const SymLoadStruct* firstStruct,
+ PlatformLookupFunction lookupFunction,
+ const char* prefix,
+ bool warnOnFailure)
+{
+ char sbuf[MAX_SYMBOL_LENGTH * 2];
+ int failCount = 0;
+
+ const SymLoadStruct* ss = firstStruct;
+ while (ss->symPointer) {
+ *ss->symPointer = 0;
+
+ for (int i = 0; i < MAX_SYMBOL_NAMES; i++) {
+ if (ss->symNames[i] == nullptr)
+ break;
+
+ const char* s = ss->symNames[i];
+ if (prefix && *prefix != 0) {
+ strcpy(sbuf, prefix);
+ strcat(sbuf, ss->symNames[i]);
+ s = sbuf;
+ }
+
+ PRFuncPtr p = LookupSymbol(lib, s, lookupFunction);
+ if (p) {
+ *ss->symPointer = p;
+ break;
+ }
+ }
+
+ if (*ss->symPointer == 0) {
+ if (warnOnFailure) {
+ printf_stderr("Can't find symbol '%s'.\n", ss->symNames[0]);
+ }
+
+ failCount++;
+ }
+
+ ss++;
+ }
+
+ return failCount == 0 ? true : false;
+}
+
+} /* namespace gl */
+} /* namespace mozilla */
+
diff --git a/gfx/gl/GLLibraryLoader.h b/gfx/gl/GLLibraryLoader.h
new file mode 100644
index 0000000000..70ba43c4db
--- /dev/null
+++ b/gfx/gl/GLLibraryLoader.h
@@ -0,0 +1,63 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GLLIBRARYLOADER_H_
+#define GLLIBRARYLOADER_H_
+
+#include <stdio.h>
+
+#include "GLDefs.h"
+#include "nscore.h"
+#include "prlink.h"
+
+namespace mozilla {
+namespace gl {
+
+class GLLibraryLoader
+{
+public:
+ bool OpenLibrary(const char* library);
+
+ typedef PRFuncPtr (GLAPIENTRY * PlatformLookupFunction) (const char*);
+
+ enum {
+ MAX_SYMBOL_NAMES = 6,
+ MAX_SYMBOL_LENGTH = 128
+ };
+
+ typedef struct {
+ PRFuncPtr* symPointer;
+ const char* symNames[MAX_SYMBOL_NAMES];
+ } SymLoadStruct;
+
+ bool LoadSymbols(const SymLoadStruct* firstStruct,
+ bool tryplatform = false,
+ const char* prefix = nullptr,
+ bool warnOnFailure = true);
+
+ /*
+ * Static version of the functions in this class
+ */
+ static PRFuncPtr LookupSymbol(PRLibrary* lib,
+ const char* symname,
+ PlatformLookupFunction lookupFunction = nullptr);
+ static bool LoadSymbols(PRLibrary* lib,
+ const SymLoadStruct* firstStruct,
+ PlatformLookupFunction lookupFunction = nullptr,
+ const char* prefix = nullptr,
+ bool warnOnFailure = true);
+protected:
+ GLLibraryLoader() {
+ mLibrary = nullptr;
+ mLookupFunc = nullptr;
+ }
+
+ PRLibrary* mLibrary;
+ PlatformLookupFunction mLookupFunc;
+};
+
+} /* namespace gl */
+} /* namespace mozilla */
+
+#endif /* GLLIBRARYLOADER_H_ */
diff --git a/gfx/gl/GLParseRegistryXML.py b/gfx/gl/GLParseRegistryXML.py
new file mode 100755
index 0000000000..60daca6e56
--- /dev/null
+++ b/gfx/gl/GLParseRegistryXML.py
@@ -0,0 +1,216 @@
+#!/usr/bin/env python
+# coding=utf8
+
+
+################################################################################
+# TUTORIAL
+# This script will generate GLConsts.h
+#
+# Step 1:
+# Download the last gl.xml, egl.xml, glx.xml and wgl.xml from
+# http://www.opengl.org/registry/#specfiles into a directory of your choice
+#
+# Step 2:
+# Execute this script ./GLParseRegistryXML.py [your dir containing XML files]
+#
+# Step 3:
+# Do not add the downloaded XML in the patch
+#
+# Step 4:
+# Enjoy =)
+#
+################################################################################
+
+# includes
+import os
+import sys
+import xml.etree.ElementTree
+
+
+################################################################################
+# export management
+
+class GLConstHeader:
+ def __init__(self, f):
+ self.f = f
+
+
+ def write(self, arg):
+ if isinstance(arg, list):
+ self.f.write('\n'.join(arg) + '\n')
+ elif isinstance(arg, (int, long)):
+ self.f.write('\n' * arg)
+ else:
+ self.f.write(str(arg) + '\n')
+
+
+ def formatFileBegin(self):
+ self.write([
+ '/* This Source Code Form is subject to the terms of the Mozilla Public',
+ ' * License, v. 2.0. If a copy of the MPL was not distributed with this',
+ ' * file, You can obtain one at http://mozilla.org/MPL/2.0/. */',
+ '',
+ '#ifndef GLCONSTS_H_',
+ '#define GLCONSTS_H_',
+ '',
+ '/**',
+ ' * GENERATED FILE, DO NOT MODIFY DIRECTLY.',
+ ' * This is a file generated directly from the official OpenGL registry',
+ ' * xml available http://www.opengl.org/registry/#specfiles.',
+ ' *',
+ ' * To generate this file, see tutorial in \'GLParseRegistryXML.py\'.',
+ ' */',
+ ''
+ ])
+
+
+ def formatLibBegin(self, lib):
+ # lib would be 'GL', 'EGL', 'GLX' or 'WGL'
+ self.write('// ' + lib)
+
+
+ def formatLibConstant(self, lib, name, value):
+ # lib would be 'GL', 'EGL', 'GLX' or 'WGL'
+ # name is the name of the const (example: MAX_TEXTURE_SIZE)
+ # value is the value of the const (example: 0xABCD)
+
+ define = '#define LOCAL_' + lib + '_' + name
+ whitespace = 60 - len(define)
+
+ if whitespace < 0:
+ whitespace = whitespace % 8
+
+ self.write(define + ' ' * whitespace + ' ' + value)
+
+
+ def formatLibEnd(self, lib):
+ # lib would be 'GL', 'EGL', 'GLX' or 'WGL'
+ self.write(2)
+
+
+ def formatFileEnd(self):
+ self.write([
+ '',
+ '#endif // GLCONSTS_H_'
+ ])
+
+
+################################################################################
+# underground code
+
+def getScriptDir():
+ return os.path.dirname(__file__) + '/'
+
+
+def getXMLDir():
+ if len(sys.argv) == 1:
+ return './'
+
+ dirPath = sys.argv[1]
+ if dirPath[-1] != '/':
+ dirPath += '/'
+
+ return dirPath
+
+
+class GLConst:
+ def __init__(self, lib, name, value, type):
+ self.lib = lib
+ self.name = name
+ self.value = value
+ self.type = type
+
+
+class GLDatabase:
+
+ LIBS = ['GL', 'EGL', 'GLX', 'WGL']
+
+ def __init__(self):
+ self.consts = {}
+ self.libs = set(GLDatabase.LIBS)
+ self.vendors = set(['EXT', 'ATI'])
+ # there is no vendor="EXT" and vendor="ATI" in gl.xml,
+ # so we manualy declare them
+
+
+ def loadXML(self, path):
+ xmlPath = getXMLDir() + path
+
+ if not os.path.isfile(xmlPath):
+ print 'missing file "' + xmlPath + '"'
+ return False
+
+ tree = xml.etree.ElementTree.parse(xmlPath)
+ root = tree.getroot()
+
+ for enums in root.iter('enums'):
+ vendor = enums.get('vendor')
+ if not vendor:
+ # there some standart enums that do have the vendor attribute,
+ # so we fake them as ARB's enums
+ vendor = 'ARB'
+
+ if vendor not in self.vendors:
+ # we map this new vendor in the vendors set.
+ self.vendors.add(vendor)
+
+ namespaceType = enums.get('type')
+
+ for enum in enums:
+ if enum.tag != 'enum':
+ # this is not an enum => we skip it
+ continue
+
+ lib = enum.get('name').split('_')[0]
+
+ if lib not in self.libs:
+ # unknown library => we skip it
+ continue
+
+ name = enum.get('name')[len(lib) + 1:]
+ value = enum.get('value')
+ type = enum.get('type')
+
+ if not type:
+ # if no type specified, we get the namespace's default type
+ type = namespaceType
+
+ self.consts[lib + '_' + name] = GLConst(lib, name, value, type)
+
+ return True
+
+
+ def exportConsts(self, path):
+ with open(getScriptDir() + path,'w') as f:
+
+ headerFile = GLConstHeader(f)
+ headerFile.formatFileBegin()
+
+ constNames = self.consts.keys()
+ constNames.sort()
+
+ for lib in GLDatabase.LIBS:
+ headerFile.formatLibBegin(lib)
+
+ for constName in constNames:
+ const = self.consts[constName]
+
+ if const.lib != lib:
+ continue
+
+ headerFile.formatLibConstant(lib, const.name, const.value)
+
+ headerFile.formatLibEnd(lib)
+
+ headerFile.formatFileEnd()
+
+
+glDatabase = GLDatabase()
+
+success = glDatabase.loadXML('gl.xml')
+success = success and glDatabase.loadXML('egl.xml')
+success = success and glDatabase.loadXML('glx.xml')
+success = success and glDatabase.loadXML('wgl.xml')
+
+if success:
+ glDatabase.exportConsts('GLConsts.h')
diff --git a/gfx/gl/GLReadTexImageHelper.cpp b/gfx/gl/GLReadTexImageHelper.cpp
new file mode 100644
index 0000000000..6593782282
--- /dev/null
+++ b/gfx/gl/GLReadTexImageHelper.cpp
@@ -0,0 +1,659 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "GLReadTexImageHelper.h"
+
+#include "gfx2DGlue.h"
+#include "gfxColor.h"
+#include "gfxTypes.h"
+#include "GLContext.h"
+#include "OGLShaderProgram.h"
+#include "ScopedGLHelpers.h"
+
+#include "mozilla/gfx/2D.h"
+#include "mozilla/Move.h"
+
+namespace mozilla {
+namespace gl {
+
+using namespace mozilla::gfx;
+
+GLReadTexImageHelper::GLReadTexImageHelper(GLContext* gl)
+ : mGL(gl)
+{
+ mPrograms[0] = 0;
+ mPrograms[1] = 0;
+ mPrograms[2] = 0;
+ mPrograms[3] = 0;
+}
+
+GLReadTexImageHelper::~GLReadTexImageHelper()
+{
+ if (!mGL->MakeCurrent())
+ return;
+
+ mGL->fDeleteProgram(mPrograms[0]);
+ mGL->fDeleteProgram(mPrograms[1]);
+ mGL->fDeleteProgram(mPrograms[2]);
+ mGL->fDeleteProgram(mPrograms[3]);
+}
+
+static const GLchar
+readTextureImageVS[] =
+ "attribute vec2 aVertex;\n"
+ "attribute vec2 aTexCoord;\n"
+ "varying vec2 vTexCoord;\n"
+ "void main() { gl_Position = vec4(aVertex, 0, 1); vTexCoord = aTexCoord; }";
+
+static const GLchar
+readTextureImageFS_TEXTURE_2D[] =
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "varying vec2 vTexCoord;\n"
+ "uniform sampler2D uTexture;\n"
+ "void main() { gl_FragColor = texture2D(uTexture, vTexCoord); }";
+
+
+static const GLchar
+readTextureImageFS_TEXTURE_2D_BGRA[] =
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "varying vec2 vTexCoord;\n"
+ "uniform sampler2D uTexture;\n"
+ "void main() { gl_FragColor = texture2D(uTexture, vTexCoord).bgra; }";
+
+static const GLchar
+readTextureImageFS_TEXTURE_EXTERNAL[] =
+ "#extension GL_OES_EGL_image_external : require\n"
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "varying vec2 vTexCoord;\n"
+ "uniform samplerExternalOES uTexture;\n"
+ "void main() { gl_FragColor = texture2D(uTexture, vTexCoord); }";
+
+static const GLchar
+readTextureImageFS_TEXTURE_RECTANGLE[] =
+ "#extension GL_ARB_texture_rectangle\n"
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "varying vec2 vTexCoord;\n"
+ "uniform sampler2DRect uTexture;\n"
+ "void main() { gl_FragColor = texture2DRect(uTexture, vTexCoord).bgra; }";
+
+GLuint
+GLReadTexImageHelper::TextureImageProgramFor(GLenum aTextureTarget,
+ int aConfig)
+{
+ int variant = 0;
+ const GLchar* readTextureImageFS = nullptr;
+ if (aTextureTarget == LOCAL_GL_TEXTURE_2D) {
+ if (aConfig & mozilla::layers::ENABLE_TEXTURE_RB_SWAP) {
+ // Need to swizzle R/B.
+ readTextureImageFS = readTextureImageFS_TEXTURE_2D_BGRA;
+ variant = 1;
+ } else {
+ readTextureImageFS = readTextureImageFS_TEXTURE_2D;
+ variant = 0;
+ }
+ } else if (aTextureTarget == LOCAL_GL_TEXTURE_EXTERNAL) {
+ readTextureImageFS = readTextureImageFS_TEXTURE_EXTERNAL;
+ variant = 2;
+ } else if (aTextureTarget == LOCAL_GL_TEXTURE_RECTANGLE) {
+ readTextureImageFS = readTextureImageFS_TEXTURE_RECTANGLE;
+ variant = 3;
+ }
+
+ /* This might be overkill, but assure that we don't access out-of-bounds */
+ MOZ_ASSERT((size_t) variant < ArrayLength(mPrograms));
+ if (!mPrograms[variant]) {
+ GLuint vs = mGL->fCreateShader(LOCAL_GL_VERTEX_SHADER);
+ const GLchar* vsSourcePtr = &readTextureImageVS[0];
+ mGL->fShaderSource(vs, 1, &vsSourcePtr, nullptr);
+ mGL->fCompileShader(vs);
+
+ GLuint fs = mGL->fCreateShader(LOCAL_GL_FRAGMENT_SHADER);
+ mGL->fShaderSource(fs, 1, &readTextureImageFS, nullptr);
+ mGL->fCompileShader(fs);
+
+ GLuint program = mGL->fCreateProgram();
+ mGL->fAttachShader(program, vs);
+ mGL->fAttachShader(program, fs);
+ mGL->fBindAttribLocation(program, 0, "aVertex");
+ mGL->fBindAttribLocation(program, 1, "aTexCoord");
+ mGL->fLinkProgram(program);
+
+ GLint success;
+ mGL->fGetProgramiv(program, LOCAL_GL_LINK_STATUS, &success);
+
+ if (!success) {
+ mGL->fDeleteProgram(program);
+ program = 0;
+ }
+
+ mGL->fDeleteShader(vs);
+ mGL->fDeleteShader(fs);
+
+ mPrograms[variant] = program;
+ }
+
+ return mPrograms[variant];
+}
+
+bool
+GLReadTexImageHelper::DidGLErrorOccur(const char* str)
+{
+ GLenum error = mGL->fGetError();
+ if (error != LOCAL_GL_NO_ERROR) {
+ printf_stderr("GL ERROR: %s (0x%04x) %s\n",
+ mGL->GLErrorToString(error), error, str);
+ return true;
+ }
+
+ return false;
+}
+
+bool
+GetActualReadFormats(GLContext* gl,
+ GLenum destFormat, GLenum destType,
+ GLenum* out_readFormat, GLenum* out_readType)
+{
+ MOZ_ASSERT(out_readFormat);
+ MOZ_ASSERT(out_readType);
+
+ if (destFormat == LOCAL_GL_RGBA &&
+ destType == LOCAL_GL_UNSIGNED_BYTE)
+ {
+ *out_readFormat = destFormat;
+ *out_readType = destType;
+ return true;
+ }
+
+ bool fallback = true;
+ if (gl->IsGLES()) {
+ GLenum auxFormat = 0;
+ GLenum auxType = 0;
+
+ gl->fGetIntegerv(LOCAL_GL_IMPLEMENTATION_COLOR_READ_FORMAT, (GLint*)&auxFormat);
+ gl->fGetIntegerv(LOCAL_GL_IMPLEMENTATION_COLOR_READ_TYPE, (GLint*)&auxType);
+
+ if (destFormat == auxFormat &&
+ destType == auxType)
+ {
+ fallback = false;
+ }
+ } else {
+ switch (destFormat) {
+ case LOCAL_GL_RGB: {
+ if (destType == LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV)
+ fallback = false;
+ break;
+ }
+ case LOCAL_GL_BGRA: {
+ if (destType == LOCAL_GL_UNSIGNED_BYTE ||
+ destType == LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV)
+ {
+ fallback = false;
+ }
+ break;
+ }
+ }
+ }
+
+ if (fallback) {
+ *out_readFormat = LOCAL_GL_RGBA;
+ *out_readType = LOCAL_GL_UNSIGNED_BYTE;
+ return false;
+ } else {
+ *out_readFormat = destFormat;
+ *out_readType = destType;
+ return true;
+ }
+}
+
+void
+SwapRAndBComponents(DataSourceSurface* surf)
+{
+ DataSourceSurface::MappedSurface map;
+ if (!surf->Map(DataSourceSurface::MapType::READ_WRITE, &map)) {
+ MOZ_ASSERT(false, "SwapRAndBComponents: Failed to map surface.");
+ return;
+ }
+ MOZ_ASSERT(map.mStride >= 0);
+
+ const size_t rowBytes = surf->GetSize().width*4;
+ const size_t rowHole = map.mStride - rowBytes;
+
+ uint8_t* row = map.mData;
+ if (!row) {
+ MOZ_ASSERT(false, "SwapRAndBComponents: Failed to get data from"
+ " DataSourceSurface.");
+ surf->Unmap();
+ return;
+ }
+
+ const size_t rows = surf->GetSize().height;
+ for (size_t i = 0; i < rows; i++) {
+ const uint8_t* rowEnd = row + rowBytes;
+
+ while (row != rowEnd) {
+ Swap(row[0], row[2]);
+ row += 4;
+ }
+
+ row += rowHole;
+ }
+
+ surf->Unmap();
+}
+
+static int
+CalcRowStride(int width, int pixelSize, int alignment)
+{
+ MOZ_ASSERT(alignment);
+
+ int rowStride = width * pixelSize;
+ if (rowStride % alignment) { // Extra at the end of the line?
+ int alignmentCount = rowStride / alignment;
+ rowStride = (alignmentCount+1) * alignment;
+ }
+ return rowStride;
+}
+
+static int
+GuessAlignment(int width, int pixelSize, int rowStride)
+{
+ int alignment = 8; // Max GLES allows.
+ while (CalcRowStride(width, pixelSize, alignment) != rowStride) {
+ alignment /= 2;
+ if (!alignment) {
+ NS_WARNING("Bad alignment for GLES. Will use temp surf for readback.");
+ return 0;
+ }
+ }
+ return alignment;
+}
+
+void
+ReadPixelsIntoDataSurface(GLContext* gl, DataSourceSurface* dest)
+{
+ gl->MakeCurrent();
+ MOZ_ASSERT(dest->GetSize().width != 0);
+ MOZ_ASSERT(dest->GetSize().height != 0);
+
+ bool hasAlpha = dest->GetFormat() == SurfaceFormat::B8G8R8A8 ||
+ dest->GetFormat() == SurfaceFormat::R8G8B8A8;
+
+ int destPixelSize;
+ GLenum destFormat;
+ GLenum destType;
+
+ switch (dest->GetFormat()) {
+ case SurfaceFormat::B8G8R8A8:
+ case SurfaceFormat::B8G8R8X8:
+ // Needs host (little) endian ARGB.
+ destFormat = LOCAL_GL_BGRA;
+ destType = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
+ break;
+ case SurfaceFormat::R8G8B8A8:
+ case SurfaceFormat::R8G8B8X8:
+ // Needs host (little) endian ABGR.
+ destFormat = LOCAL_GL_RGBA;
+ destType = LOCAL_GL_UNSIGNED_BYTE;
+ break;
+ case SurfaceFormat::R5G6B5_UINT16:
+ destFormat = LOCAL_GL_RGB;
+ destType = LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV;
+ break;
+ default:
+ MOZ_CRASH("GFX: Bad format, read pixels.");
+ }
+ destPixelSize = BytesPerPixel(dest->GetFormat());
+ MOZ_ASSERT(dest->GetSize().width * destPixelSize <= dest->Stride());
+
+ GLenum readFormat = destFormat;
+ GLenum readType = destType;
+ bool needsTempSurf = !GetActualReadFormats(gl,
+ destFormat, destType,
+ &readFormat, &readType);
+
+ RefPtr<DataSourceSurface> tempSurf;
+ DataSourceSurface* readSurf = dest;
+ int readAlignment = GuessAlignment(dest->GetSize().width,
+ destPixelSize,
+ dest->Stride());
+ if (!readAlignment) {
+ needsTempSurf = true;
+ }
+ if (needsTempSurf) {
+ if (GLContext::ShouldSpew()) {
+ NS_WARNING("Needing intermediary surface for ReadPixels. This will be slow!");
+ }
+ SurfaceFormat readFormatGFX;
+
+ switch (readFormat) {
+ case LOCAL_GL_RGBA: {
+ readFormatGFX = hasAlpha ? SurfaceFormat::R8G8B8A8
+ : SurfaceFormat::R8G8B8X8;
+ break;
+ }
+ case LOCAL_GL_BGRA: {
+ readFormatGFX = hasAlpha ? SurfaceFormat::B8G8R8A8
+ : SurfaceFormat::B8G8R8X8;
+ break;
+ }
+ case LOCAL_GL_RGB: {
+ MOZ_ASSERT(destPixelSize == 2);
+ MOZ_ASSERT(readType == LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV);
+ readFormatGFX = SurfaceFormat::R5G6B5_UINT16;
+ break;
+ }
+ default: {
+ MOZ_CRASH("GFX: Bad read format, read format.");
+ }
+ }
+
+ switch (readType) {
+ case LOCAL_GL_UNSIGNED_BYTE: {
+ MOZ_ASSERT(readFormat == LOCAL_GL_RGBA);
+ readAlignment = 1;
+ break;
+ }
+ case LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV: {
+ MOZ_ASSERT(readFormat == LOCAL_GL_BGRA);
+ readAlignment = 4;
+ break;
+ }
+ case LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV: {
+ MOZ_ASSERT(readFormat == LOCAL_GL_RGB);
+ readAlignment = 2;
+ break;
+ }
+ default: {
+ MOZ_CRASH("GFX: Bad read type, read type.");
+ }
+ }
+
+ int32_t stride = dest->GetSize().width * BytesPerPixel(readFormatGFX);
+ tempSurf = Factory::CreateDataSourceSurfaceWithStride(dest->GetSize(),
+ readFormatGFX,
+ stride);
+ if (NS_WARN_IF(!tempSurf)) {
+ return;
+ }
+
+ readSurf = tempSurf;
+ }
+ MOZ_ASSERT(readAlignment);
+ MOZ_ASSERT(reinterpret_cast<uintptr_t>(readSurf->GetData()) % readAlignment == 0);
+
+ GLsizei width = dest->GetSize().width;
+ GLsizei height = dest->GetSize().height;
+
+ {
+ ScopedPackState safePackState(gl);
+ gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, readAlignment);
+
+ gl->fReadPixels(0, 0,
+ width, height,
+ readFormat, readType,
+ readSurf->GetData());
+ }
+
+ if (readSurf != dest) {
+ MOZ_ASSERT(readFormat == LOCAL_GL_RGBA);
+ MOZ_ASSERT(readType == LOCAL_GL_UNSIGNED_BYTE);
+ gfx::Factory::CopyDataSourceSurface(readSurf, dest);
+ }
+}
+
+already_AddRefed<gfx::DataSourceSurface>
+YInvertImageSurface(gfx::DataSourceSurface* aSurf)
+{
+ RefPtr<DataSourceSurface> temp =
+ Factory::CreateDataSourceSurfaceWithStride(aSurf->GetSize(),
+ aSurf->GetFormat(),
+ aSurf->Stride());
+ if (NS_WARN_IF(!temp)) {
+ return nullptr;
+ }
+
+ DataSourceSurface::MappedSurface map;
+ if (!temp->Map(DataSourceSurface::MapType::WRITE, &map)) {
+ return nullptr;
+ }
+
+ RefPtr<DrawTarget> dt =
+ Factory::CreateDrawTargetForData(BackendType::CAIRO,
+ map.mData,
+ temp->GetSize(),
+ map.mStride,
+ temp->GetFormat());
+ if (!dt) {
+ temp->Unmap();
+ return nullptr;
+ }
+
+ dt->SetTransform(Matrix::Scaling(1.0, -1.0) *
+ Matrix::Translation(0.0, aSurf->GetSize().height));
+ Rect rect(0, 0, aSurf->GetSize().width, aSurf->GetSize().height);
+ dt->DrawSurface(aSurf, rect, rect, DrawSurfaceOptions(),
+ DrawOptions(1.0, CompositionOp::OP_SOURCE, AntialiasMode::NONE));
+ temp->Unmap();
+ return temp.forget();
+}
+
+already_AddRefed<DataSourceSurface>
+ReadBackSurface(GLContext* gl, GLuint aTexture, bool aYInvert, SurfaceFormat aFormat)
+{
+ gl->MakeCurrent();
+ gl->GuaranteeResolve();
+ gl->fActiveTexture(LOCAL_GL_TEXTURE0);
+ gl->fBindTexture(LOCAL_GL_TEXTURE_2D, aTexture);
+
+ IntSize size;
+ gl->fGetTexLevelParameteriv(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_TEXTURE_WIDTH, &size.width);
+ gl->fGetTexLevelParameteriv(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_TEXTURE_HEIGHT, &size.height);
+
+ RefPtr<DataSourceSurface> surf =
+ Factory::CreateDataSourceSurfaceWithStride(size, SurfaceFormat::B8G8R8A8,
+ GetAlignedStride<4>(size.width, BytesPerPixel(SurfaceFormat::B8G8R8A8)));
+
+ if (NS_WARN_IF(!surf)) {
+ return nullptr;
+ }
+
+ uint32_t currentPackAlignment = 0;
+ gl->fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, (GLint*)&currentPackAlignment);
+ if (currentPackAlignment != 4) {
+ gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, 4);
+ }
+
+ gl->fGetTexImage(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, surf->GetData());
+
+ if (currentPackAlignment != 4) {
+ gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, currentPackAlignment);
+ }
+
+ if (aFormat == SurfaceFormat::R8G8B8A8 || aFormat == SurfaceFormat::R8G8B8X8) {
+ SwapRAndBComponents(surf);
+ }
+
+ if (aYInvert) {
+ surf = YInvertImageSurface(surf);
+ }
+
+ return surf.forget();
+}
+
+#define CLEANUP_IF_GLERROR_OCCURRED(x) \
+ if (DidGLErrorOccur(x)) { \
+ return false; \
+ }
+
+already_AddRefed<DataSourceSurface>
+GLReadTexImageHelper::ReadTexImage(GLuint aTextureId,
+ GLenum aTextureTarget,
+ const gfx::IntSize& aSize,
+ /* ShaderConfigOGL.mFeature */ int aConfig,
+ bool aYInvert)
+{
+ /* Allocate resulting image surface */
+ int32_t stride = aSize.width * BytesPerPixel(SurfaceFormat::R8G8B8A8);
+ RefPtr<DataSourceSurface> isurf =
+ Factory::CreateDataSourceSurfaceWithStride(aSize,
+ SurfaceFormat::R8G8B8A8,
+ stride);
+ if (NS_WARN_IF(!isurf)) {
+ return nullptr;
+ }
+
+ if (!ReadTexImage(isurf, aTextureId, aTextureTarget, aSize, aConfig, aYInvert)) {
+ return nullptr;
+ }
+
+ return isurf.forget();
+}
+
+bool
+GLReadTexImageHelper::ReadTexImage(DataSourceSurface* aDest,
+ GLuint aTextureId,
+ GLenum aTextureTarget,
+ const gfx::IntSize& aSize,
+ /* ShaderConfigOGL.mFeature */ int aConfig,
+ bool aYInvert)
+{
+ MOZ_ASSERT(aTextureTarget == LOCAL_GL_TEXTURE_2D ||
+ aTextureTarget == LOCAL_GL_TEXTURE_EXTERNAL ||
+ aTextureTarget == LOCAL_GL_TEXTURE_RECTANGLE_ARB);
+
+ mGL->MakeCurrent();
+
+ GLint oldrb, oldfb, oldprog, oldTexUnit, oldTex;
+ GLuint rb, fb;
+
+ do {
+ mGL->fGetIntegerv(LOCAL_GL_RENDERBUFFER_BINDING, &oldrb);
+ mGL->fGetIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, &oldfb);
+ mGL->fGetIntegerv(LOCAL_GL_CURRENT_PROGRAM, &oldprog);
+ mGL->fGetIntegerv(LOCAL_GL_ACTIVE_TEXTURE, &oldTexUnit);
+ mGL->fActiveTexture(LOCAL_GL_TEXTURE0);
+ switch (aTextureTarget) {
+ case LOCAL_GL_TEXTURE_2D:
+ mGL->fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, &oldTex);
+ break;
+ case LOCAL_GL_TEXTURE_EXTERNAL:
+ mGL->fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_EXTERNAL, &oldTex);
+ break;
+ case LOCAL_GL_TEXTURE_RECTANGLE:
+ mGL->fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_RECTANGLE, &oldTex);
+ break;
+ default: /* Already checked above */
+ break;
+ }
+
+ ScopedGLState scopedScissorTestState(mGL, LOCAL_GL_SCISSOR_TEST, false);
+ ScopedGLState scopedBlendState(mGL, LOCAL_GL_BLEND, false);
+ ScopedViewportRect scopedViewportRect(mGL, 0, 0, aSize.width, aSize.height);
+
+ /* Setup renderbuffer */
+ mGL->fGenRenderbuffers(1, &rb);
+ mGL->fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, rb);
+
+ GLenum rbInternalFormat =
+ mGL->IsGLES()
+ ? (mGL->IsExtensionSupported(GLContext::OES_rgb8_rgba8) ? LOCAL_GL_RGBA8 : LOCAL_GL_RGBA4)
+ : LOCAL_GL_RGBA;
+ mGL->fRenderbufferStorage(LOCAL_GL_RENDERBUFFER, rbInternalFormat, aSize.width, aSize.height);
+ CLEANUP_IF_GLERROR_OCCURRED("when binding and creating renderbuffer");
+
+ /* Setup framebuffer */
+ mGL->fGenFramebuffers(1, &fb);
+ mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, fb);
+ mGL->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0,
+ LOCAL_GL_RENDERBUFFER, rb);
+ CLEANUP_IF_GLERROR_OCCURRED("when binding and creating framebuffer");
+
+ MOZ_ASSERT(mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER) == LOCAL_GL_FRAMEBUFFER_COMPLETE);
+
+ /* Setup vertex and fragment shader */
+ GLuint program = TextureImageProgramFor(aTextureTarget, aConfig);
+ MOZ_ASSERT(program);
+
+ mGL->fUseProgram(program);
+ CLEANUP_IF_GLERROR_OCCURRED("when using program");
+ mGL->fUniform1i(mGL->fGetUniformLocation(program, "uTexture"), 0);
+ CLEANUP_IF_GLERROR_OCCURRED("when setting uniform location");
+
+ /* Setup quad geometry */
+ mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
+
+ float w = (aTextureTarget == LOCAL_GL_TEXTURE_RECTANGLE) ? (float) aSize.width : 1.0f;
+ float h = (aTextureTarget == LOCAL_GL_TEXTURE_RECTANGLE) ? (float) aSize.height : 1.0f;
+
+ const float
+ vertexArray[4*2] = {
+ -1.0f, -1.0f,
+ 1.0f, -1.0f,
+ -1.0f, 1.0f,
+ 1.0f, 1.0f
+ };
+ ScopedVertexAttribPointer autoAttrib0(mGL, 0, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, 0, vertexArray);
+
+ const float u0 = 0.0f;
+ const float u1 = w;
+ const float v0 = aYInvert ? h : 0.0f;
+ const float v1 = aYInvert ? 0.0f : h;
+ const float texCoordArray[8] = { u0, v0,
+ u1, v0,
+ u0, v1,
+ u1, v1 };
+ ScopedVertexAttribPointer autoAttrib1(mGL, 1, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, 0, texCoordArray);
+
+ /* Bind the texture */
+ if (aTextureId) {
+ mGL->fBindTexture(aTextureTarget, aTextureId);
+ CLEANUP_IF_GLERROR_OCCURRED("when binding texture");
+ }
+
+ /* Draw quad */
+ mGL->fClearColor(1.0f, 0.0f, 1.0f, 1.0f);
+ mGL->fClear(LOCAL_GL_COLOR_BUFFER_BIT);
+ CLEANUP_IF_GLERROR_OCCURRED("when clearing color buffer");
+
+ mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
+ CLEANUP_IF_GLERROR_OCCURRED("when drawing texture");
+
+ /* Read-back draw results */
+ ReadPixelsIntoDataSurface(mGL, aDest);
+ CLEANUP_IF_GLERROR_OCCURRED("when reading pixels into surface");
+ } while (false);
+
+ /* Restore GL state */
+ mGL->fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, oldrb);
+ mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, oldfb);
+ mGL->fUseProgram(oldprog);
+
+ // note that deleting 0 has no effect in any of these calls
+ mGL->fDeleteRenderbuffers(1, &rb);
+ mGL->fDeleteFramebuffers(1, &fb);
+
+ if (aTextureId)
+ mGL->fBindTexture(aTextureTarget, oldTex);
+
+ if (oldTexUnit != LOCAL_GL_TEXTURE0)
+ mGL->fActiveTexture(oldTexUnit);
+
+ return true;
+}
+
+#undef CLEANUP_IF_GLERROR_OCCURRED
+
+} // namespace gl
+} // namespace mozilla
diff --git a/gfx/gl/GLReadTexImageHelper.h b/gfx/gl/GLReadTexImageHelper.h
new file mode 100644
index 0000000000..20d229e532
--- /dev/null
+++ b/gfx/gl/GLReadTexImageHelper.h
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GLREADTEXIMAGEHELPER_H_
+#define GLREADTEXIMAGEHELPER_H_
+
+#include "GLContextTypes.h"
+#include "mozilla/Attributes.h"
+#include "nsSize.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/gfx/Types.h"
+
+namespace mozilla {
+
+namespace gfx {
+class DataSourceSurface;
+} // namespace gfx
+
+namespace gl {
+
+// Returns true if the `dest{Format,Type}` are the same as the
+// `read{Format,Type}`.
+bool GetActualReadFormats(GLContext* gl,
+ GLenum destFormat, GLenum destType,
+ GLenum* out_readFormat, GLenum* out_readType);
+
+void ReadPixelsIntoDataSurface(GLContext* aGL,
+ gfx::DataSourceSurface* aSurface);
+
+already_AddRefed<gfx::DataSourceSurface>
+ReadBackSurface(GLContext* gl, GLuint aTexture, bool aYInvert, gfx::SurfaceFormat aFormat);
+
+already_AddRefed<gfx::DataSourceSurface>
+YInvertImageSurface(gfx::DataSourceSurface* aSurf);
+
+void
+SwapRAndBComponents(gfx::DataSourceSurface* surf);
+
+class GLReadTexImageHelper final
+{
+ // The GLContext is the sole owner of the GLBlitHelper.
+ GLContext* mGL;
+
+ GLuint mPrograms[4];
+
+ GLuint TextureImageProgramFor(GLenum aTextureTarget, int aShader);
+
+ bool DidGLErrorOccur(const char* str);
+
+public:
+
+ explicit GLReadTexImageHelper(GLContext* gl);
+ ~GLReadTexImageHelper();
+
+ /**
+ * Read the image data contained in aTexture, and return it as an ImageSurface.
+ * If GL_RGBA is given as the format, a SurfaceFormat::A8R8G8B8_UINT32 surface is returned.
+ * Not implemented yet:
+ * If GL_RGB is given as the format, a SurfaceFormat::X8R8G8B8_UINT32 surface is returned.
+ * If GL_LUMINANCE is given as the format, a SurfaceFormat::A8 surface is returned.
+ *
+ * THIS IS EXPENSIVE. It is ridiculously expensive. Only do this
+ * if you absolutely positively must, and never in any performance
+ * critical path.
+ *
+ * NOTE: aShaderProgram is really mozilla::layers::ShaderProgramType. It is
+ * passed as int to eliminate including LayerManagerOGLProgram.h here.
+ */
+ already_AddRefed<gfx::DataSourceSurface> ReadTexImage(GLuint aTextureId,
+ GLenum aTextureTarget,
+ const gfx::IntSize& aSize,
+ /* ShaderProgramType */ int aShaderProgram,
+ bool aYInvert = false);
+
+ bool ReadTexImage(gfx::DataSourceSurface* aDest,
+ GLuint aTextureId,
+ GLenum aTextureTarget,
+ const gfx::IntSize& aSize,
+ int aShaderProgram,
+ bool aYInvert = false);
+};
+
+} // namespace gl
+} // namespace mozilla
+
+#endif
diff --git a/gfx/gl/GLScreenBuffer.cpp b/gfx/gl/GLScreenBuffer.cpp
new file mode 100755
index 0000000000..463f7ebab3
--- /dev/null
+++ b/gfx/gl/GLScreenBuffer.cpp
@@ -0,0 +1,1044 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "GLScreenBuffer.h"
+
+#include <cstring>
+#include "CompositorTypes.h"
+#include "GLContext.h"
+#include "GLBlitHelper.h"
+#include "GLReadTexImageHelper.h"
+#include "SharedSurfaceEGL.h"
+#include "SharedSurfaceGL.h"
+#include "ScopedGLHelpers.h"
+#include "gfx2DGlue.h"
+#include "../layers/ipc/ShadowLayers.h"
+#include "mozilla/layers/TextureForwarder.h"
+#include "mozilla/layers/TextureClientSharedSurface.h"
+
+#ifdef XP_WIN
+#include "SharedSurfaceANGLE.h" // for SurfaceFactory_ANGLEShareHandle
+#include "SharedSurfaceD3D11Interop.h" // for SurfaceFactory_D3D11Interop
+#include "mozilla/gfx/DeviceManagerDx.h"
+#endif
+
+#ifdef XP_MACOSX
+#include "SharedSurfaceIO.h"
+#endif
+
+#ifdef GL_PROVIDER_GLX
+#include "GLXLibrary.h"
+#include "SharedSurfaceGLX.h"
+#endif
+
+namespace mozilla {
+namespace gl {
+
+using gfx::SurfaceFormat;
+
+UniquePtr<GLScreenBuffer>
+GLScreenBuffer::Create(GLContext* gl,
+ const gfx::IntSize& size,
+ const SurfaceCaps& caps)
+{
+ UniquePtr<GLScreenBuffer> ret;
+ if (caps.antialias &&
+ !gl->IsSupported(GLFeature::framebuffer_multisample))
+ {
+ return Move(ret);
+ }
+
+ layers::TextureFlags flags = layers::TextureFlags::ORIGIN_BOTTOM_LEFT;
+ if (!caps.premultAlpha) {
+ flags |= layers::TextureFlags::NON_PREMULTIPLIED;
+ }
+
+ UniquePtr<SurfaceFactory> factory = MakeUnique<SurfaceFactory_Basic>(gl, caps, flags);
+
+ ret.reset( new GLScreenBuffer(gl, caps, Move(factory)) );
+ return Move(ret);
+}
+
+/* static */ UniquePtr<SurfaceFactory>
+GLScreenBuffer::CreateFactory(GLContext* gl,
+ const SurfaceCaps& caps,
+ KnowsCompositor* compositorConnection,
+ const layers::TextureFlags& flags)
+{
+ return CreateFactory(gl, caps, compositorConnection->GetTextureForwarder(),
+ compositorConnection->GetCompositorBackendType(), flags);
+}
+
+/* static */ UniquePtr<SurfaceFactory>
+GLScreenBuffer::CreateFactory(GLContext* gl,
+ const SurfaceCaps& caps,
+ LayersIPCChannel* ipcChannel,
+ const mozilla::layers::LayersBackend backend,
+ const layers::TextureFlags& flags)
+{
+ UniquePtr<SurfaceFactory> factory = nullptr;
+ if (!gfxPrefs::WebGLForceLayersReadback()) {
+ switch (backend) {
+ case mozilla::layers::LayersBackend::LAYERS_OPENGL: {
+#if defined(XP_MACOSX)
+ factory = SurfaceFactory_IOSurface::Create(gl, caps, ipcChannel, flags);
+#elif defined(GL_PROVIDER_GLX)
+ if (sGLXLibrary.UseTextureFromPixmap())
+ factory = SurfaceFactory_GLXDrawable::Create(gl, caps, ipcChannel, flags);
+#elif defined(MOZ_WIDGET_UIKIT)
+ factory = MakeUnique<SurfaceFactory_GLTexture>(mGLContext, caps, ipcChannel, mFlags);
+#else
+ if (gl->GetContextType() == GLContextType::EGL) {
+ if (XRE_IsParentProcess()) {
+ factory = SurfaceFactory_EGLImage::Create(gl, caps, ipcChannel, flags);
+ }
+ }
+#endif
+ break;
+ }
+ case mozilla::layers::LayersBackend::LAYERS_D3D11: {
+#ifdef XP_WIN
+ // Enable surface sharing only if ANGLE and compositing devices
+ // are both WARP or both not WARP
+ gfx::DeviceManagerDx* dm = gfx::DeviceManagerDx::Get();
+ if (gl->IsANGLE() &&
+ (gl->IsWARP() == dm->IsWARP()) &&
+ dm->TextureSharingWorks())
+ {
+ factory = SurfaceFactory_ANGLEShareHandle::Create(gl, caps, ipcChannel, flags);
+ }
+
+ if (!factory && gfxPrefs::WebGLDXGLEnabled()) {
+ factory = SurfaceFactory_D3D11Interop::Create(gl, caps, ipcChannel, flags);
+ }
+#endif
+ break;
+ }
+ default:
+ break;
+ }
+
+#ifdef GL_PROVIDER_GLX
+ if (!factory && sGLXLibrary.UseTextureFromPixmap()) {
+ factory = SurfaceFactory_GLXDrawable::Create(gl, caps, ipcChannel, flags);
+ }
+#endif
+ }
+
+ return factory;
+}
+
+GLScreenBuffer::GLScreenBuffer(GLContext* gl,
+ const SurfaceCaps& caps,
+ UniquePtr<SurfaceFactory> factory)
+ : mGL(gl)
+ , mCaps(caps)
+ , mFactory(Move(factory))
+ , mNeedsBlit(true)
+ , mUserReadBufferMode(LOCAL_GL_BACK)
+ , mUserDrawBufferMode(LOCAL_GL_BACK)
+ , mUserDrawFB(0)
+ , mUserReadFB(0)
+ , mInternalDrawFB(0)
+ , mInternalReadFB(0)
+#ifdef DEBUG
+ , mInInternalMode_DrawFB(true)
+ , mInInternalMode_ReadFB(true)
+#endif
+{ }
+
+GLScreenBuffer::~GLScreenBuffer()
+{
+ mFactory = nullptr;
+ mDraw = nullptr;
+ mRead = nullptr;
+
+ if (!mBack)
+ return;
+
+ // Detach mBack cleanly.
+ mBack->Surf()->ProducerRelease();
+}
+
+void
+GLScreenBuffer::BindAsFramebuffer(GLContext* const gl, GLenum target) const
+{
+ GLuint drawFB = DrawFB();
+ GLuint readFB = ReadFB();
+
+ if (!gl->IsSupported(GLFeature::split_framebuffer)) {
+ MOZ_ASSERT(drawFB == readFB);
+ gl->raw_fBindFramebuffer(target, readFB);
+ return;
+ }
+
+ switch (target) {
+ case LOCAL_GL_FRAMEBUFFER:
+ gl->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, drawFB);
+ gl->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, readFB);
+ break;
+
+ case LOCAL_GL_DRAW_FRAMEBUFFER_EXT:
+ gl->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, drawFB);
+ break;
+
+ case LOCAL_GL_READ_FRAMEBUFFER_EXT:
+ gl->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, readFB);
+ break;
+
+ default:
+ MOZ_CRASH("GFX: Bad `target` for BindFramebuffer.");
+ }
+}
+
+void
+GLScreenBuffer::BindFB(GLuint fb)
+{
+ GLuint drawFB = DrawFB();
+ GLuint readFB = ReadFB();
+
+ mUserDrawFB = fb;
+ mUserReadFB = fb;
+ mInternalDrawFB = (fb == 0) ? drawFB : fb;
+ mInternalReadFB = (fb == 0) ? readFB : fb;
+
+ if (mInternalDrawFB == mInternalReadFB) {
+ mGL->raw_fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mInternalDrawFB);
+ } else {
+ MOZ_ASSERT(mGL->IsSupported(GLFeature::split_framebuffer));
+ mGL->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, mInternalDrawFB);
+ mGL->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, mInternalReadFB);
+ }
+
+#ifdef DEBUG
+ mInInternalMode_DrawFB = false;
+ mInInternalMode_ReadFB = false;
+#endif
+}
+
+void
+GLScreenBuffer::BindDrawFB(GLuint fb)
+{
+ MOZ_ASSERT(mGL->IsSupported(GLFeature::split_framebuffer));
+
+ GLuint drawFB = DrawFB();
+ mUserDrawFB = fb;
+ mInternalDrawFB = (fb == 0) ? drawFB : fb;
+
+ mGL->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, mInternalDrawFB);
+
+#ifdef DEBUG
+ mInInternalMode_DrawFB = false;
+#endif
+}
+
+void
+GLScreenBuffer::BindReadFB(GLuint fb)
+{
+ MOZ_ASSERT(mGL->IsSupported(GLFeature::split_framebuffer));
+
+ GLuint readFB = ReadFB();
+ mUserReadFB = fb;
+ mInternalReadFB = (fb == 0) ? readFB : fb;
+
+ mGL->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, mInternalReadFB);
+
+#ifdef DEBUG
+ mInInternalMode_ReadFB = false;
+#endif
+}
+
+void
+GLScreenBuffer::BindFB_Internal(GLuint fb)
+{
+ mInternalDrawFB = mUserDrawFB = fb;
+ mInternalReadFB = mUserReadFB = fb;
+ mGL->raw_fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mInternalDrawFB);
+
+#ifdef DEBUG
+ mInInternalMode_DrawFB = true;
+ mInInternalMode_ReadFB = true;
+#endif
+}
+
+void
+GLScreenBuffer::BindDrawFB_Internal(GLuint fb)
+{
+ MOZ_ASSERT(mGL->IsSupported(GLFeature::split_framebuffer));
+
+ mInternalDrawFB = mUserDrawFB = fb;
+ mGL->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, mInternalDrawFB);
+
+#ifdef DEBUG
+ mInInternalMode_DrawFB = true;
+#endif
+}
+
+void
+GLScreenBuffer::BindReadFB_Internal(GLuint fb)
+{
+ MOZ_ASSERT(mGL->IsSupported(GLFeature::split_framebuffer));
+
+ mInternalReadFB = mUserReadFB = fb;
+ mGL->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, mInternalReadFB);
+
+#ifdef DEBUG
+ mInInternalMode_ReadFB = true;
+#endif
+}
+
+
+GLuint
+GLScreenBuffer::GetDrawFB() const
+{
+#ifdef DEBUG
+ MOZ_ASSERT(mGL->IsCurrent());
+ MOZ_ASSERT(!mInInternalMode_DrawFB);
+
+ // Don't need a branch here, because:
+ // LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT == LOCAL_GL_FRAMEBUFFER_BINDING == 0x8CA6
+ // We use raw_ here because this is debug code and we need to see what
+ // the driver thinks.
+ GLuint actual = 0;
+ mGL->raw_fGetIntegerv(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT, (GLint*)&actual);
+
+ GLuint predicted = mInternalDrawFB;
+ if (predicted != actual) {
+ printf_stderr("Misprediction: Bound draw FB predicted: %d. Was: %d.\n",
+ predicted, actual);
+ MOZ_ASSERT(false, "Draw FB binding misprediction!");
+ }
+#endif
+
+ return mUserDrawFB;
+}
+
+GLuint
+GLScreenBuffer::GetReadFB() const
+{
+#ifdef DEBUG
+ MOZ_ASSERT(mGL->IsCurrent());
+ MOZ_ASSERT(!mInInternalMode_ReadFB);
+
+ // We use raw_ here because this is debug code and we need to see what
+ // the driver thinks.
+ GLuint actual = 0;
+ if (mGL->IsSupported(GLFeature::split_framebuffer))
+ mGL->raw_fGetIntegerv(LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT, (GLint*)&actual);
+ else
+ mGL->raw_fGetIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, (GLint*)&actual);
+
+ GLuint predicted = mInternalReadFB;
+ if (predicted != actual) {
+ printf_stderr("Misprediction: Bound read FB predicted: %d. Was: %d.\n",
+ predicted, actual);
+ MOZ_ASSERT(false, "Read FB binding misprediction!");
+ }
+#endif
+
+ return mUserReadFB;
+}
+
+GLuint
+GLScreenBuffer::GetFB() const
+{
+ MOZ_ASSERT(GetDrawFB() == GetReadFB());
+ return GetDrawFB();
+}
+
+
+void
+GLScreenBuffer::DeletingFB(GLuint fb)
+{
+ if (fb == mInternalDrawFB) {
+ mInternalDrawFB = 0;
+ mUserDrawFB = 0;
+ }
+ if (fb == mInternalReadFB) {
+ mInternalReadFB = 0;
+ mUserReadFB = 0;
+ }
+}
+
+
+void
+GLScreenBuffer::AfterDrawCall()
+{
+ if (mUserDrawFB != 0)
+ return;
+
+ RequireBlit();
+}
+
+void
+GLScreenBuffer::BeforeReadCall()
+{
+ if (mUserReadFB != 0)
+ return;
+
+ AssureBlitted();
+}
+
+bool
+GLScreenBuffer::CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x,
+ GLint y, GLsizei width, GLsizei height, GLint border)
+{
+ SharedSurface* surf;
+ if (GetReadFB() == 0) {
+ surf = SharedSurf();
+ } else {
+ surf = mGL->mFBOMapping[GetReadFB()];
+ }
+ if (surf) {
+ return surf->CopyTexImage2D(target, level, internalformat, x, y, width, height, border);
+ }
+
+ return false;
+}
+
+bool
+GLScreenBuffer::ReadPixels(GLint x, GLint y,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ GLvoid* pixels)
+{
+ // If the currently bound framebuffer is backed by a SharedSurface
+ // then it might want to override how we read pixel data from it.
+ // This is normally only the default framebuffer, but we can also
+ // have SharedSurfaces bound to other framebuffers when doing
+ // readback for BasicLayers.
+ SharedSurface* surf;
+ if (GetReadFB() == 0) {
+ surf = SharedSurf();
+ } else {
+ surf = mGL->mFBOMapping[GetReadFB()];
+ }
+ if (surf) {
+ return surf->ReadPixels(x, y, width, height, format, type, pixels);
+ }
+
+ return false;
+}
+
+void
+GLScreenBuffer::RequireBlit()
+{
+ mNeedsBlit = true;
+}
+
+void
+GLScreenBuffer::AssureBlitted()
+{
+ if (!mNeedsBlit)
+ return;
+
+ if (mDraw) {
+ GLuint drawFB = DrawFB();
+ GLuint readFB = ReadFB();
+
+ MOZ_ASSERT(drawFB != 0);
+ MOZ_ASSERT(drawFB != readFB);
+ MOZ_ASSERT(mGL->IsSupported(GLFeature::split_framebuffer));
+ MOZ_ASSERT(mDraw->mSize == mRead->Size());
+
+ ScopedBindFramebuffer boundFB(mGL);
+ ScopedGLState scissor(mGL, LOCAL_GL_SCISSOR_TEST, false);
+
+ BindReadFB_Internal(drawFB);
+ BindDrawFB_Internal(readFB);
+
+ if (mGL->IsSupported(GLFeature::framebuffer_blit)) {
+ const gfx::IntSize& srcSize = mDraw->mSize;
+ const gfx::IntSize& destSize = mRead->Size();
+
+ mGL->raw_fBlitFramebuffer(0, 0, srcSize.width, srcSize.height,
+ 0, 0, destSize.width, destSize.height,
+ LOCAL_GL_COLOR_BUFFER_BIT,
+ LOCAL_GL_NEAREST);
+ } else if (mGL->IsExtensionSupported(GLContext::APPLE_framebuffer_multisample)) {
+ mGL->fResolveMultisampleFramebufferAPPLE();
+ } else {
+ MOZ_CRASH("GFX: No available blit methods.");
+ }
+ // Done!
+ }
+
+ mNeedsBlit = false;
+}
+
+void
+GLScreenBuffer::Morph(UniquePtr<SurfaceFactory> newFactory)
+{
+ MOZ_RELEASE_ASSERT(newFactory, "newFactory must not be null");
+ mFactory = Move(newFactory);
+}
+
+bool
+GLScreenBuffer::Attach(SharedSurface* surf, const gfx::IntSize& size)
+{
+ ScopedBindFramebuffer autoFB(mGL);
+
+ const bool readNeedsUnlock = (mRead && SharedSurf());
+ if (readNeedsUnlock) {
+ SharedSurf()->UnlockProd();
+ }
+
+ surf->LockProd();
+
+ if (mRead &&
+ surf->mAttachType == SharedSurf()->mAttachType &&
+ size == Size())
+ {
+ // Same size, same type, ready for reuse!
+ mRead->Attach(surf);
+ } else {
+ // Else something changed, so resize:
+ UniquePtr<DrawBuffer> draw;
+ bool drawOk = true;
+
+ /* Don't change out the draw buffer unless we resize. In the
+ * preserveDrawingBuffer:true case, prior contents of the buffer must
+ * be retained. If we're using a draw buffer, it's an MSAA buffer, so
+ * even if we copy the previous frame into the (single-sampled) read
+ * buffer, if we need to re-resolve from draw to read (as triggered by
+ * drawing), we'll need the old MSAA content to still be in the draw
+ * buffer.
+ */
+ if (!mDraw || size != Size())
+ drawOk = CreateDraw(size, &draw); // Can be null.
+
+ UniquePtr<ReadBuffer> read = CreateRead(surf);
+ bool readOk = !!read;
+
+ if (!drawOk || !readOk) {
+ surf->UnlockProd();
+ if (readNeedsUnlock) {
+ SharedSurf()->LockProd();
+ }
+ return false;
+ }
+
+ if (draw)
+ mDraw = Move(draw);
+
+ mRead = Move(read);
+ }
+
+ // Check that we're all set up.
+ MOZ_ASSERT(SharedSurf() == surf);
+
+ // Update the ReadBuffer mode.
+ if (mGL->IsSupported(gl::GLFeature::read_buffer)) {
+ BindFB(0);
+ mRead->SetReadBuffer(mUserReadBufferMode);
+ }
+
+ // Update the DrawBuffer mode.
+ if (mGL->IsSupported(gl::GLFeature::draw_buffers)) {
+ BindFB(0);
+ SetDrawBuffer(mUserDrawBufferMode);
+ }
+
+ RequireBlit();
+
+ return true;
+}
+
+bool
+GLScreenBuffer::Swap(const gfx::IntSize& size)
+{
+ RefPtr<SharedSurfaceTextureClient> newBack = mFactory->NewTexClient(size);
+ if (!newBack)
+ return false;
+
+ // In the case of DXGL interop, the new surface needs to be acquired before
+ // it is attached so that the interop surface is locked, which populates
+ // the GL renderbuffer. This results in the renderbuffer being ready and
+ // attachment to framebuffer succeeds in Attach() call.
+ newBack->Surf()->ProducerAcquire();
+
+ if (!Attach(newBack->Surf(), size)) {
+ newBack->Surf()->ProducerRelease();
+ return false;
+ }
+ // Attach was successful.
+
+ mFront = mBack;
+ mBack = newBack;
+
+ if (ShouldPreserveBuffer() &&
+ mFront &&
+ mBack &&
+ !mDraw)
+ {
+ auto src = mFront->Surf();
+ auto dest = mBack->Surf();
+
+ //uint32_t srcPixel = ReadPixel(src);
+ //uint32_t destPixel = ReadPixel(dest);
+ //printf_stderr("Before: src: 0x%08x, dest: 0x%08x\n", srcPixel, destPixel);
+#ifdef DEBUG
+ GLContext::LocalErrorScope errorScope(*mGL);
+#endif
+
+ SharedSurface::ProdCopy(src, dest, mFactory.get());
+
+#ifdef DEBUG
+ MOZ_ASSERT(!errorScope.GetError());
+#endif
+
+ //srcPixel = ReadPixel(src);
+ //destPixel = ReadPixel(dest);
+ //printf_stderr("After: src: 0x%08x, dest: 0x%08x\n", srcPixel, destPixel);
+ }
+
+ // XXX: We would prefer to fence earlier on platforms that don't need
+ // the full ProducerAcquire/ProducerRelease semantics, so that the fence
+ // doesn't include the copy operation. Unfortunately, the current API
+ // doesn't expose a good way to do that.
+ if (mFront) {
+ mFront->Surf()->ProducerRelease();
+ }
+
+ return true;
+}
+
+bool
+GLScreenBuffer::PublishFrame(const gfx::IntSize& size)
+{
+ AssureBlitted();
+
+ bool good = Swap(size);
+ return good;
+}
+
+bool
+GLScreenBuffer::Resize(const gfx::IntSize& size)
+{
+ RefPtr<SharedSurfaceTextureClient> newBack = mFactory->NewTexClient(size);
+ if (!newBack)
+ return false;
+
+ if (!Attach(newBack->Surf(), size))
+ return false;
+
+ if (mBack)
+ mBack->Surf()->ProducerRelease();
+
+ mBack = newBack;
+
+ mBack->Surf()->ProducerAcquire();
+
+ return true;
+}
+
+bool
+GLScreenBuffer::CreateDraw(const gfx::IntSize& size,
+ UniquePtr<DrawBuffer>* out_buffer)
+{
+ GLContext* gl = mFactory->mGL;
+ const GLFormats& formats = mFactory->mFormats;
+ const SurfaceCaps& caps = mFactory->DrawCaps();
+
+ return DrawBuffer::Create(gl, caps, formats, size, out_buffer);
+}
+
+UniquePtr<ReadBuffer>
+GLScreenBuffer::CreateRead(SharedSurface* surf)
+{
+ GLContext* gl = mFactory->mGL;
+ const GLFormats& formats = mFactory->mFormats;
+ const SurfaceCaps& caps = mFactory->ReadCaps();
+
+ return ReadBuffer::Create(gl, caps, formats, surf);
+}
+
+void
+GLScreenBuffer::SetDrawBuffer(GLenum mode)
+{
+ MOZ_ASSERT(mGL->IsSupported(gl::GLFeature::draw_buffers));
+ MOZ_ASSERT(GetDrawFB() == 0);
+
+ if (!mGL->IsSupported(GLFeature::draw_buffers))
+ return;
+
+ mUserDrawBufferMode = mode;
+
+ GLuint fb = mDraw ? mDraw->mFB : mRead->mFB;
+ GLenum internalMode;
+
+ switch (mode) {
+ case LOCAL_GL_BACK:
+ internalMode = (fb == 0) ? LOCAL_GL_BACK
+ : LOCAL_GL_COLOR_ATTACHMENT0;
+ break;
+
+ case LOCAL_GL_NONE:
+ internalMode = LOCAL_GL_NONE;
+ break;
+
+ default:
+ MOZ_CRASH("GFX: Bad value.");
+ }
+
+ mGL->MakeCurrent();
+ mGL->fDrawBuffers(1, &internalMode);
+}
+
+void
+GLScreenBuffer::SetReadBuffer(GLenum mode)
+{
+ MOZ_ASSERT(mGL->IsSupported(gl::GLFeature::read_buffer));
+ MOZ_ASSERT(GetReadFB() == 0);
+
+ mUserReadBufferMode = mode;
+ mRead->SetReadBuffer(mUserReadBufferMode);
+}
+
+bool
+GLScreenBuffer::IsDrawFramebufferDefault() const
+{
+ if (!mDraw)
+ return IsReadFramebufferDefault();
+ return mDraw->mFB == 0;
+}
+
+bool
+GLScreenBuffer::IsReadFramebufferDefault() const
+{
+ return SharedSurf()->mAttachType == AttachmentType::Screen;
+}
+
+uint32_t
+GLScreenBuffer::DepthBits() const
+{
+ const GLFormats& formats = mFactory->mFormats;
+
+ if (formats.depth == LOCAL_GL_DEPTH_COMPONENT16)
+ return 16;
+
+ return 24;
+}
+
+////////////////////////////////////////////////////////////////////////
+// Utils
+
+static void
+RenderbufferStorageBySamples(GLContext* aGL, GLsizei aSamples,
+ GLenum aInternalFormat, const gfx::IntSize& aSize)
+{
+ if (aSamples) {
+ aGL->fRenderbufferStorageMultisample(LOCAL_GL_RENDERBUFFER,
+ aSamples,
+ aInternalFormat,
+ aSize.width, aSize.height);
+ } else {
+ aGL->fRenderbufferStorage(LOCAL_GL_RENDERBUFFER,
+ aInternalFormat,
+ aSize.width, aSize.height);
+ }
+}
+
+static GLuint
+CreateRenderbuffer(GLContext* aGL, GLenum aFormat, GLsizei aSamples,
+ const gfx::IntSize& aSize)
+{
+ GLuint rb = 0;
+ aGL->fGenRenderbuffers(1, &rb);
+ ScopedBindRenderbuffer autoRB(aGL, rb);
+
+ RenderbufferStorageBySamples(aGL, aSamples, aFormat, aSize);
+
+ return rb;
+}
+
+static void
+CreateRenderbuffersForOffscreen(GLContext* aGL, const GLFormats& aFormats,
+ const gfx::IntSize& aSize, bool aMultisample,
+ GLuint* aColorMSRB, GLuint* aDepthRB,
+ GLuint* aStencilRB)
+{
+ GLsizei samples = aMultisample ? aFormats.samples : 0;
+ if (aColorMSRB) {
+ MOZ_ASSERT(aFormats.samples > 0);
+ MOZ_ASSERT(aFormats.color_rbFormat);
+
+ GLenum colorFormat = aFormats.color_rbFormat;
+ if (aGL->IsANGLE()) {
+ MOZ_ASSERT(colorFormat == LOCAL_GL_RGBA8);
+ colorFormat = LOCAL_GL_BGRA8_EXT;
+ }
+
+ *aColorMSRB = CreateRenderbuffer(aGL, colorFormat, samples, aSize);
+ }
+
+ if (aDepthRB &&
+ aStencilRB &&
+ aFormats.depthStencil)
+ {
+ *aDepthRB = CreateRenderbuffer(aGL, aFormats.depthStencil, samples, aSize);
+ *aStencilRB = *aDepthRB;
+ } else {
+ if (aDepthRB) {
+ MOZ_ASSERT(aFormats.depth);
+
+ *aDepthRB = CreateRenderbuffer(aGL, aFormats.depth, samples, aSize);
+ }
+
+ if (aStencilRB) {
+ MOZ_ASSERT(aFormats.stencil);
+
+ *aStencilRB = CreateRenderbuffer(aGL, aFormats.stencil, samples, aSize);
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// DrawBuffer
+
+bool
+DrawBuffer::Create(GLContext* const gl,
+ const SurfaceCaps& caps,
+ const GLFormats& formats,
+ const gfx::IntSize& size,
+ UniquePtr<DrawBuffer>* out_buffer)
+{
+ MOZ_ASSERT(out_buffer);
+ *out_buffer = nullptr;
+
+ if (!caps.color) {
+ MOZ_ASSERT(!caps.alpha && !caps.depth && !caps.stencil);
+
+ // Nothing is needed.
+ return true;
+ }
+
+ if (caps.antialias) {
+ if (formats.samples == 0)
+ return false; // Can't create it.
+
+ MOZ_ASSERT(formats.samples <= gl->MaxSamples());
+ }
+
+ GLuint colorMSRB = 0;
+ GLuint depthRB = 0;
+ GLuint stencilRB = 0;
+
+ GLuint* pColorMSRB = caps.antialias ? &colorMSRB : nullptr;
+ GLuint* pDepthRB = caps.depth ? &depthRB : nullptr;
+ GLuint* pStencilRB = caps.stencil ? &stencilRB : nullptr;
+
+ if (!formats.color_rbFormat)
+ pColorMSRB = nullptr;
+
+ if (pDepthRB && pStencilRB) {
+ if (!formats.depth && !formats.depthStencil)
+ pDepthRB = nullptr;
+
+ if (!formats.stencil && !formats.depthStencil)
+ pStencilRB = nullptr;
+ } else {
+ if (!formats.depth)
+ pDepthRB = nullptr;
+
+ if (!formats.stencil)
+ pStencilRB = nullptr;
+ }
+
+ GLContext::LocalErrorScope localError(*gl);
+
+ CreateRenderbuffersForOffscreen(gl, formats, size, caps.antialias,
+ pColorMSRB, pDepthRB, pStencilRB);
+
+ GLuint fb = 0;
+ gl->fGenFramebuffers(1, &fb);
+ gl->AttachBuffersToFB(0, colorMSRB, depthRB, stencilRB, fb);
+
+ const GLsizei samples = formats.samples;
+ UniquePtr<DrawBuffer> ret( new DrawBuffer(gl, size, samples, fb, colorMSRB,
+ depthRB, stencilRB) );
+
+ GLenum err = localError.GetError();
+ MOZ_ASSERT_IF(err != LOCAL_GL_NO_ERROR, err == LOCAL_GL_OUT_OF_MEMORY);
+ if (err || !gl->IsFramebufferComplete(fb))
+ return false;
+
+ *out_buffer = Move(ret);
+ return true;
+}
+
+DrawBuffer::~DrawBuffer()
+{
+ if (!mGL->MakeCurrent())
+ return;
+
+ GLuint fb = mFB;
+ GLuint rbs[] = {
+ mColorMSRB,
+ mDepthRB,
+ mStencilRB
+ };
+
+ mGL->fDeleteFramebuffers(1, &fb);
+ mGL->fDeleteRenderbuffers(3, rbs);
+}
+
+////////////////////////////////////////////////////////////////////////
+// ReadBuffer
+
+UniquePtr<ReadBuffer>
+ReadBuffer::Create(GLContext* gl,
+ const SurfaceCaps& caps,
+ const GLFormats& formats,
+ SharedSurface* surf)
+{
+ MOZ_ASSERT(surf);
+
+ if (surf->mAttachType == AttachmentType::Screen) {
+ // Don't need anything. Our read buffer will be the 'screen'.
+ return UniquePtr<ReadBuffer>( new ReadBuffer(gl, 0, 0, 0,
+ surf) );
+ }
+
+ GLuint depthRB = 0;
+ GLuint stencilRB = 0;
+
+ GLuint* pDepthRB = caps.depth ? &depthRB : nullptr;
+ GLuint* pStencilRB = caps.stencil ? &stencilRB : nullptr;
+
+ GLContext::LocalErrorScope localError(*gl);
+
+ CreateRenderbuffersForOffscreen(gl, formats, surf->mSize, caps.antialias,
+ nullptr, pDepthRB, pStencilRB);
+
+ GLuint colorTex = 0;
+ GLuint colorRB = 0;
+ GLenum target = 0;
+
+ switch (surf->mAttachType) {
+ case AttachmentType::GLTexture:
+ colorTex = surf->ProdTexture();
+ target = surf->ProdTextureTarget();
+ break;
+ case AttachmentType::GLRenderbuffer:
+ colorRB = surf->ProdRenderbuffer();
+ break;
+ default:
+ MOZ_CRASH("GFX: Unknown attachment type, create?");
+ }
+ MOZ_ASSERT(colorTex || colorRB);
+
+ GLuint fb = 0;
+ gl->fGenFramebuffers(1, &fb);
+ gl->AttachBuffersToFB(colorTex, colorRB, depthRB, stencilRB, fb, target);
+ gl->mFBOMapping[fb] = surf;
+
+ UniquePtr<ReadBuffer> ret( new ReadBuffer(gl, fb, depthRB,
+ stencilRB, surf) );
+
+ GLenum err = localError.GetError();
+ MOZ_ASSERT_IF(err != LOCAL_GL_NO_ERROR, err == LOCAL_GL_OUT_OF_MEMORY);
+ if (err)
+ return nullptr;
+
+ const bool needsAcquire = !surf->IsProducerAcquired();
+ if (needsAcquire) {
+ surf->ProducerReadAcquire();
+ }
+ const bool isComplete = gl->IsFramebufferComplete(fb);
+ if (needsAcquire) {
+ surf->ProducerReadRelease();
+ }
+
+ if (!isComplete)
+ return nullptr;
+
+ return Move(ret);
+}
+
+ReadBuffer::~ReadBuffer()
+{
+ if (!mGL->MakeCurrent())
+ return;
+
+ GLuint fb = mFB;
+ GLuint rbs[] = {
+ mDepthRB,
+ mStencilRB
+ };
+
+ mGL->fDeleteFramebuffers(1, &fb);
+ mGL->fDeleteRenderbuffers(2, rbs);
+ mGL->mFBOMapping.erase(mFB);
+}
+
+void
+ReadBuffer::Attach(SharedSurface* surf)
+{
+ MOZ_ASSERT(surf && mSurf);
+ MOZ_ASSERT(surf->mAttachType == mSurf->mAttachType);
+ MOZ_ASSERT(surf->mSize == mSurf->mSize);
+
+ // Nothing else is needed for AttachType Screen.
+ if (surf->mAttachType != AttachmentType::Screen) {
+ GLuint colorTex = 0;
+ GLuint colorRB = 0;
+ GLenum target = 0;
+
+ switch (surf->mAttachType) {
+ case AttachmentType::GLTexture:
+ colorTex = surf->ProdTexture();
+ target = surf->ProdTextureTarget();
+ break;
+ case AttachmentType::GLRenderbuffer:
+ colorRB = surf->ProdRenderbuffer();
+ break;
+ default:
+ MOZ_CRASH("GFX: Unknown attachment type, attach?");
+ }
+
+ mGL->AttachBuffersToFB(colorTex, colorRB, 0, 0, mFB, target);
+ mGL->mFBOMapping[mFB] = surf;
+ MOZ_ASSERT(mGL->IsFramebufferComplete(mFB));
+ }
+
+ mSurf = surf;
+}
+
+const gfx::IntSize&
+ReadBuffer::Size() const
+{
+ return mSurf->mSize;
+}
+
+void
+ReadBuffer::SetReadBuffer(GLenum userMode) const
+{
+ if (!mGL->IsSupported(GLFeature::read_buffer))
+ return;
+
+ GLenum internalMode;
+
+ switch (userMode) {
+ case LOCAL_GL_BACK:
+ case LOCAL_GL_FRONT:
+ internalMode = (mFB == 0) ? userMode
+ : LOCAL_GL_COLOR_ATTACHMENT0;
+ break;
+
+ case LOCAL_GL_NONE:
+ internalMode = LOCAL_GL_NONE;
+ break;
+
+ default:
+ MOZ_CRASH("GFX: Bad value.");
+ }
+
+ mGL->MakeCurrent();
+ mGL->fReadBuffer(internalMode);
+}
+
+} /* namespace gl */
+} /* namespace mozilla */
diff --git a/gfx/gl/GLScreenBuffer.h b/gfx/gl/GLScreenBuffer.h
new file mode 100644
index 0000000000..6cacf221db
--- /dev/null
+++ b/gfx/gl/GLScreenBuffer.h
@@ -0,0 +1,301 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* GLScreenBuffer is the abstraction for the "default framebuffer" used
+ * by an offscreen GLContext. Since it's only for offscreen GLContext's,
+ * it's only useful for things like WebGL, and is NOT used by the
+ * compositor's GLContext. Remember that GLContext provides an abstraction
+ * so that even if you want to draw to the 'screen', even if that's not
+ * actually the screen, just draw to 0. This GLScreenBuffer class takes the
+ * logic handling out of GLContext.
+*/
+
+#ifndef SCREEN_BUFFER_H_
+#define SCREEN_BUFFER_H_
+
+#include "GLContextTypes.h"
+#include "GLDefs.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/gfx/Point.h"
+#include "mozilla/UniquePtr.h"
+#include "SharedSurface.h"
+#include "SurfaceTypes.h"
+
+namespace mozilla {
+namespace layers {
+class KnowsCompositor;
+class LayersIPCChannel;
+class SharedSurfaceTextureClient;
+} // namespace layers
+
+namespace gl {
+
+class GLContext;
+class SharedSurface;
+class ShSurfHandle;
+class SurfaceFactory;
+
+class DrawBuffer
+{
+public:
+ // Fallible!
+ // But it may return true with *out_buffer==nullptr if unneeded.
+ static bool Create(GLContext* const gl,
+ const SurfaceCaps& caps,
+ const GLFormats& formats,
+ const gfx::IntSize& size,
+ UniquePtr<DrawBuffer>* out_buffer);
+
+protected:
+ GLContext* const mGL;
+public:
+ const gfx::IntSize mSize;
+ const GLsizei mSamples;
+ const GLuint mFB;
+protected:
+ const GLuint mColorMSRB;
+ const GLuint mDepthRB;
+ const GLuint mStencilRB;
+
+ DrawBuffer(GLContext* gl,
+ const gfx::IntSize& size,
+ GLsizei samples,
+ GLuint fb,
+ GLuint colorMSRB,
+ GLuint depthRB,
+ GLuint stencilRB)
+ : mGL(gl)
+ , mSize(size)
+ , mSamples(samples)
+ , mFB(fb)
+ , mColorMSRB(colorMSRB)
+ , mDepthRB(depthRB)
+ , mStencilRB(stencilRB)
+ {}
+
+public:
+ virtual ~DrawBuffer();
+};
+
+class ReadBuffer
+{
+public:
+ // Infallible, always non-null.
+ static UniquePtr<ReadBuffer> Create(GLContext* gl,
+ const SurfaceCaps& caps,
+ const GLFormats& formats,
+ SharedSurface* surf);
+
+protected:
+ GLContext* const mGL;
+public:
+ const GLuint mFB;
+protected:
+ // mFB has the following attachments:
+ const GLuint mDepthRB;
+ const GLuint mStencilRB;
+ // note no mColorRB here: this is provided by mSurf.
+ SharedSurface* mSurf;
+
+ ReadBuffer(GLContext* gl,
+ GLuint fb,
+ GLuint depthRB,
+ GLuint stencilRB,
+ SharedSurface* surf)
+ : mGL(gl)
+ , mFB(fb)
+ , mDepthRB(depthRB)
+ , mStencilRB(stencilRB)
+ , mSurf(surf)
+ {}
+
+public:
+ virtual ~ReadBuffer();
+
+ // Cannot attach a surf of a different AttachType or Size than before.
+ void Attach(SharedSurface* surf);
+
+ const gfx::IntSize& Size() const;
+
+ SharedSurface* SharedSurf() const {
+ return mSurf;
+ }
+
+ void SetReadBuffer(GLenum mode) const;
+};
+
+
+class GLScreenBuffer
+{
+public:
+ // Infallible.
+ static UniquePtr<GLScreenBuffer> Create(GLContext* gl,
+ const gfx::IntSize& size,
+ const SurfaceCaps& caps);
+
+ static UniquePtr<SurfaceFactory>
+ CreateFactory(GLContext* gl,
+ const SurfaceCaps& caps,
+ layers::KnowsCompositor* compositorConnection,
+ const layers::TextureFlags& flags);
+ static UniquePtr<SurfaceFactory>
+ CreateFactory(GLContext* gl,
+ const SurfaceCaps& caps,
+ layers::LayersIPCChannel* ipcChannel,
+ const mozilla::layers::LayersBackend backend,
+ const layers::TextureFlags& flags);
+
+protected:
+ GLContext* const mGL; // Owns us.
+public:
+ const SurfaceCaps mCaps;
+protected:
+ UniquePtr<SurfaceFactory> mFactory;
+
+ RefPtr<layers::SharedSurfaceTextureClient> mBack;
+ RefPtr<layers::SharedSurfaceTextureClient> mFront;
+
+ UniquePtr<DrawBuffer> mDraw;
+ UniquePtr<ReadBuffer> mRead;
+
+ bool mNeedsBlit;
+
+ GLenum mUserReadBufferMode;
+ GLenum mUserDrawBufferMode;
+
+ // Below are the parts that help us pretend to be framebuffer 0:
+ GLuint mUserDrawFB;
+ GLuint mUserReadFB;
+ GLuint mInternalDrawFB;
+ GLuint mInternalReadFB;
+
+#ifdef DEBUG
+ bool mInInternalMode_DrawFB;
+ bool mInInternalMode_ReadFB;
+#endif
+
+ GLScreenBuffer(GLContext* gl,
+ const SurfaceCaps& caps,
+ UniquePtr<SurfaceFactory> factory);
+
+public:
+ virtual ~GLScreenBuffer();
+
+ SurfaceFactory* Factory() const {
+ return mFactory.get();
+ }
+
+ const RefPtr<layers::SharedSurfaceTextureClient>& Front() const {
+ return mFront;
+ }
+
+ SharedSurface* SharedSurf() const {
+ MOZ_ASSERT(mRead);
+ return mRead->SharedSurf();
+ }
+
+ bool ShouldPreserveBuffer() const {
+ return mCaps.preserve;
+ }
+
+ GLuint DrawFB() const {
+ if (!mDraw)
+ return ReadFB();
+
+ return mDraw->mFB;
+ }
+
+ GLuint ReadFB() const {
+ return mRead->mFB;
+ }
+
+ GLsizei Samples() const {
+ if (!mDraw)
+ return 0;
+
+ return mDraw->mSamples;
+ }
+
+ uint32_t DepthBits() const;
+
+ void DeletingFB(GLuint fb);
+
+ const gfx::IntSize& Size() const {
+ MOZ_ASSERT(mRead);
+ MOZ_ASSERT(!mDraw || mDraw->mSize == mRead->Size());
+ return mRead->Size();
+ }
+
+ void BindAsFramebuffer(GLContext* const gl, GLenum target) const;
+
+ void RequireBlit();
+ void AssureBlitted();
+ void AfterDrawCall();
+ void BeforeReadCall();
+
+ bool CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x,
+ GLint y, GLsizei width, GLsizei height, GLint border);
+
+ void SetReadBuffer(GLenum userMode);
+ void SetDrawBuffer(GLenum userMode);
+
+ GLenum GetReadBufferMode() const { return mUserReadBufferMode; }
+ GLenum GetDrawBufferMode() const { return mUserDrawBufferMode; }
+
+ /**
+ * Attempts to read pixels from the current bound framebuffer, if
+ * it is backed by a SharedSurface.
+ *
+ * Returns true if the pixel data has been read back, false
+ * otherwise.
+ */
+ bool ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, GLvoid* pixels);
+
+ // Morph changes the factory used to create surfaces.
+ void Morph(UniquePtr<SurfaceFactory> newFactory);
+
+protected:
+ // Returns false on error or inability to resize.
+ bool Swap(const gfx::IntSize& size);
+
+public:
+ bool PublishFrame(const gfx::IntSize& size);
+
+ bool Resize(const gfx::IntSize& size);
+
+protected:
+ bool Attach(SharedSurface* surf, const gfx::IntSize& size);
+
+ bool CreateDraw(const gfx::IntSize& size, UniquePtr<DrawBuffer>* out_buffer);
+ UniquePtr<ReadBuffer> CreateRead(SharedSurface* surf);
+
+public:
+ /* `fb` in these functions is the framebuffer the GLContext is hoping to
+ * bind. When this is 0, we intercept the call and bind our own
+ * framebuffers. As a client of these functions, just bind 0 when you want
+ * to draw to the default framebuffer/'screen'.
+ */
+ void BindFB(GLuint fb);
+ void BindDrawFB(GLuint fb);
+ void BindReadFB(GLuint fb);
+ GLuint GetFB() const;
+ GLuint GetDrawFB() const;
+ GLuint GetReadFB() const;
+
+ // Here `fb` is the actual framebuffer you want bound. Binding 0 will
+ // bind the (generally useless) default framebuffer.
+ void BindFB_Internal(GLuint fb);
+ void BindDrawFB_Internal(GLuint fb);
+ void BindReadFB_Internal(GLuint fb);
+
+ bool IsDrawFramebufferDefault() const;
+ bool IsReadFramebufferDefault() const;
+};
+
+} // namespace gl
+} // namespace mozilla
+
+#endif // SCREEN_BUFFER_H_
diff --git a/gfx/gl/GLTextureImage.cpp b/gfx/gl/GLTextureImage.cpp
new file mode 100644
index 0000000000..c91d558af4
--- /dev/null
+++ b/gfx/gl/GLTextureImage.cpp
@@ -0,0 +1,521 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "GLTextureImage.h"
+#include "GLContext.h"
+#include "gfxContext.h"
+#include "gfxPlatform.h"
+#include "gfxUtils.h"
+#include "gfx2DGlue.h"
+#include "mozilla/gfx/2D.h"
+#include "ScopedGLHelpers.h"
+#include "GLUploadHelpers.h"
+#include "GfxTexturesReporter.h"
+
+#include "TextureImageEGL.h"
+
+using namespace mozilla::gfx;
+
+namespace mozilla {
+namespace gl {
+
+already_AddRefed<TextureImage>
+CreateTextureImage(GLContext* gl,
+ const gfx::IntSize& aSize,
+ TextureImage::ContentType aContentType,
+ GLenum aWrapMode,
+ TextureImage::Flags aFlags,
+ TextureImage::ImageFormat aImageFormat)
+{
+ switch (gl->GetContextType()) {
+ case GLContextType::EGL:
+ return CreateTextureImageEGL(gl, aSize, aContentType, aWrapMode, aFlags, aImageFormat);
+ default: {
+ GLint maxTextureSize;
+ gl->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &maxTextureSize);
+ if (aSize.width > maxTextureSize || aSize.height > maxTextureSize) {
+ NS_ASSERTION(aWrapMode == LOCAL_GL_CLAMP_TO_EDGE, "Can't support wrapping with tiles!");
+ return CreateTiledTextureImage(gl, aSize, aContentType, aFlags, aImageFormat);
+ } else {
+ return CreateBasicTextureImage(gl, aSize, aContentType, aWrapMode, aFlags);
+ }
+ }
+ }
+}
+
+
+static already_AddRefed<TextureImage>
+TileGenFunc(GLContext* gl,
+ const IntSize& aSize,
+ TextureImage::ContentType aContentType,
+ TextureImage::Flags aFlags,
+ TextureImage::ImageFormat aImageFormat)
+{
+ switch (gl->GetContextType()) {
+ case GLContextType::EGL:
+ return TileGenFuncEGL(gl, aSize, aContentType, aFlags, aImageFormat);
+ default:
+ return CreateBasicTextureImage(gl, aSize, aContentType,
+ LOCAL_GL_CLAMP_TO_EDGE, aFlags);
+ }
+}
+
+already_AddRefed<TextureImage>
+TextureImage::Create(GLContext* gl,
+ const gfx::IntSize& size,
+ TextureImage::ContentType contentType,
+ GLenum wrapMode,
+ TextureImage::Flags flags)
+{
+ return CreateTextureImage(gl, size, contentType, wrapMode, flags);
+}
+
+bool
+TextureImage::UpdateFromDataSource(gfx::DataSourceSurface* aSurface,
+ const nsIntRegion* aDestRegion,
+ const gfx::IntPoint* aSrcPoint)
+{
+ nsIntRegion destRegion = aDestRegion ? *aDestRegion
+ : IntRect(0, 0,
+ aSurface->GetSize().width,
+ aSurface->GetSize().height);
+ gfx::IntPoint srcPoint = aSrcPoint ? *aSrcPoint
+ : gfx::IntPoint(0, 0);
+ return DirectUpdate(aSurface, destRegion, srcPoint);
+}
+
+gfx::IntRect TextureImage::GetTileRect() {
+ return gfx::IntRect(gfx::IntPoint(0,0), mSize);
+}
+
+gfx::IntRect TextureImage::GetSrcTileRect() {
+ return GetTileRect();
+}
+
+void
+TextureImage::UpdateUploadSize(size_t amount)
+{
+ if (mUploadSize > 0) {
+ GfxTexturesReporter::UpdateAmount(GfxTexturesReporter::MemoryFreed, mUploadSize);
+ }
+ mUploadSize = amount;
+ GfxTexturesReporter::UpdateAmount(GfxTexturesReporter::MemoryAllocated, mUploadSize);
+}
+
+BasicTextureImage::~BasicTextureImage()
+{
+ GLContext* ctx = mGLContext;
+ if (ctx->IsDestroyed() || !ctx->IsOwningThreadCurrent()) {
+ ctx = ctx->GetSharedContext();
+ }
+
+ // If we have a context, then we need to delete the texture;
+ // if we don't have a context (either real or shared),
+ // then they went away when the contex was deleted, because it
+ // was the only one that had access to it.
+ if (ctx && ctx->MakeCurrent()) {
+ ctx->fDeleteTextures(1, &mTexture);
+ }
+}
+
+void
+BasicTextureImage::BindTexture(GLenum aTextureUnit)
+{
+ mGLContext->fActiveTexture(aTextureUnit);
+ mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
+ mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0);
+}
+
+bool
+BasicTextureImage::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom /* = gfx::IntPoint(0, 0) */)
+{
+ nsIntRegion region;
+ if (mTextureState == Valid) {
+ region = aRegion;
+ } else {
+ region = nsIntRegion(IntRect(0, 0, mSize.width, mSize.height));
+ }
+ bool needInit = mTextureState == Created;
+ size_t uploadSize;
+
+ mTextureFormat =
+ UploadSurfaceToTexture(mGLContext,
+ aSurf,
+ region,
+ mTexture,
+ mSize,
+ &uploadSize,
+ needInit,
+ aFrom);
+
+ if (uploadSize > 0) {
+ UpdateUploadSize(uploadSize);
+ }
+ mTextureState = Valid;
+ return true;
+}
+
+void
+BasicTextureImage::Resize(const gfx::IntSize& aSize)
+{
+ mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
+
+ // This matches the logic in UploadImageDataToTexture so that
+ // we avoid mixing formats.
+ GLenum format;
+ GLenum type;
+ if (mGLContext->GetPreferredARGB32Format() == LOCAL_GL_BGRA) {
+ MOZ_ASSERT(!mGLContext->IsGLES());
+ format = LOCAL_GL_BGRA;
+ type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
+ } else {
+ format = LOCAL_GL_RGBA;
+ type = LOCAL_GL_UNSIGNED_BYTE;
+ }
+
+ mGLContext->fTexImage2D(LOCAL_GL_TEXTURE_2D,
+ 0,
+ LOCAL_GL_RGBA,
+ aSize.width,
+ aSize.height,
+ 0,
+ format,
+ type,
+ nullptr);
+
+ mTextureState = Allocated;
+ mSize = aSize;
+}
+
+gfx::IntSize TextureImage::GetSize() const {
+ return mSize;
+}
+
+TextureImage::TextureImage(const gfx::IntSize& aSize,
+ GLenum aWrapMode, ContentType aContentType,
+ Flags aFlags)
+ : mSize(aSize)
+ , mWrapMode(aWrapMode)
+ , mContentType(aContentType)
+ , mTextureFormat(gfx::SurfaceFormat::UNKNOWN)
+ , mSamplingFilter(SamplingFilter::GOOD)
+ , mFlags(aFlags)
+ , mUploadSize(0)
+{}
+
+BasicTextureImage::BasicTextureImage(GLuint aTexture,
+ const gfx::IntSize& aSize,
+ GLenum aWrapMode,
+ ContentType aContentType,
+ GLContext* aContext,
+ TextureImage::Flags aFlags)
+ : TextureImage(aSize, aWrapMode, aContentType, aFlags)
+ , mTexture(aTexture)
+ , mTextureState(Created)
+ , mGLContext(aContext)
+{}
+
+static bool
+WantsSmallTiles(GLContext* gl)
+{
+ // We can't use small tiles on the SGX 540, because of races in texture upload.
+ if (gl->WorkAroundDriverBugs() &&
+ gl->Renderer() == GLRenderer::SGX540)
+ return false;
+
+ // We should use small tiles for good performance if we can't use
+ // glTexSubImage2D() for some reason.
+ if (!CanUploadSubTextures(gl))
+ return true;
+
+ // Don't use small tiles otherwise. (If we implement incremental texture upload,
+ // then we will want to revisit this.)
+ return false;
+}
+
+TiledTextureImage::TiledTextureImage(GLContext* aGL,
+ gfx::IntSize aSize,
+ TextureImage::ContentType aContentType,
+ TextureImage::Flags aFlags,
+ TextureImage::ImageFormat aImageFormat)
+ : TextureImage(aSize, LOCAL_GL_CLAMP_TO_EDGE, aContentType, aFlags)
+ , mCurrentImage(0)
+ , mIterationCallback(nullptr)
+ , mIterationCallbackData(nullptr)
+ , mRows(0)
+ , mColumns(0)
+ , mGL(aGL)
+ , mTextureState(Created)
+ , mImageFormat(aImageFormat)
+{
+ if (!(aFlags & TextureImage::DisallowBigImage) && WantsSmallTiles(mGL)) {
+ mTileSize = 256;
+ } else {
+ mGL->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, (GLint*) &mTileSize);
+ }
+ if (aSize.width != 0 && aSize.height != 0) {
+ Resize(aSize);
+ }
+}
+
+TiledTextureImage::~TiledTextureImage()
+{
+}
+
+bool
+TiledTextureImage::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom /* = gfx::IntPoint(0, 0) */)
+{
+ if (mSize.width == 0 || mSize.height == 0) {
+ return true;
+ }
+
+ nsIntRegion region;
+
+ if (mTextureState != Valid) {
+ IntRect bounds = IntRect(0, 0, mSize.width, mSize.height);
+ region = nsIntRegion(bounds);
+ } else {
+ region = aRegion;
+ }
+
+ bool result = true;
+ int oldCurrentImage = mCurrentImage;
+ BeginBigImageIteration();
+ do {
+ IntRect tileRect = GetSrcTileRect();
+ int xPos = tileRect.x;
+ int yPos = tileRect.y;
+
+ nsIntRegion tileRegion;
+ tileRegion.And(region, tileRect); // intersect with tile
+
+ if (tileRegion.IsEmpty())
+ continue;
+
+ tileRegion.MoveBy(-xPos, -yPos); // translate into tile local space
+
+ result &= mImages[mCurrentImage]->
+ DirectUpdate(aSurf, tileRegion, aFrom + gfx::IntPoint(xPos, yPos));
+
+ if (mCurrentImage == mImages.Length() - 1) {
+ // We know we're done, but we still need to ensure that the callback
+ // gets called (e.g. to update the uploaded region).
+ NextTile();
+ break;
+ }
+ // Override a callback cancelling iteration if the texture wasn't valid.
+ // We need to force the update in that situation, or we may end up
+ // showing invalid/out-of-date texture data.
+ } while (NextTile() || (mTextureState != Valid));
+ mCurrentImage = oldCurrentImage;
+
+ mTextureFormat = mImages[0]->GetTextureFormat();
+ mTextureState = Valid;
+ return result;
+}
+
+void TiledTextureImage::BeginBigImageIteration()
+{
+ mCurrentImage = 0;
+}
+
+bool TiledTextureImage::NextTile()
+{
+ bool continueIteration = true;
+
+ if (mIterationCallback)
+ continueIteration = mIterationCallback(this, mCurrentImage,
+ mIterationCallbackData);
+
+ if (mCurrentImage + 1 < mImages.Length()) {
+ mCurrentImage++;
+ return continueIteration;
+ }
+ return false;
+}
+
+void TiledTextureImage::SetIterationCallback(BigImageIterationCallback aCallback,
+ void* aCallbackData)
+{
+ mIterationCallback = aCallback;
+ mIterationCallbackData = aCallbackData;
+}
+
+gfx::IntRect TiledTextureImage::GetTileRect()
+{
+ if (!GetTileCount()) {
+ return gfx::IntRect();
+ }
+ gfx::IntRect rect = mImages[mCurrentImage]->GetTileRect();
+ unsigned int xPos = (mCurrentImage % mColumns) * mTileSize;
+ unsigned int yPos = (mCurrentImage / mColumns) * mTileSize;
+ rect.MoveBy(xPos, yPos);
+ return rect;
+}
+
+gfx::IntRect TiledTextureImage::GetSrcTileRect()
+{
+ gfx::IntRect rect = GetTileRect();
+ const bool needsYFlip = mFlags & OriginBottomLeft;
+ unsigned int srcY = needsYFlip ? mSize.height - rect.height - rect.y
+ : rect.y;
+ return gfx::IntRect(rect.x, srcY, rect.width, rect.height);
+}
+
+void
+TiledTextureImage::BindTexture(GLenum aTextureUnit)
+{
+ if (!GetTileCount()) {
+ return;
+ }
+ mImages[mCurrentImage]->BindTexture(aTextureUnit);
+}
+
+/*
+ * Resize, trying to reuse tiles. The reuse strategy is to decide on reuse per
+ * column. A tile on a column is reused if it hasn't changed size, otherwise it
+ * is discarded/replaced. Extra tiles on a column are pruned after iterating
+ * each column, and extra rows are pruned after iteration over the entire image
+ * finishes.
+ */
+void TiledTextureImage::Resize(const gfx::IntSize& aSize)
+{
+ if (mSize == aSize && mTextureState != Created) {
+ return;
+ }
+
+ // calculate rows and columns, rounding up
+ unsigned int columns = (aSize.width + mTileSize - 1) / mTileSize;
+ unsigned int rows = (aSize.height + mTileSize - 1) / mTileSize;
+
+ // Iterate over old tile-store and insert/remove tiles as necessary
+ int row;
+ unsigned int i = 0;
+ for (row = 0; row < (int)rows; row++) {
+ // If we've gone beyond how many rows there were before, set mColumns to
+ // zero so that we only create new tiles.
+ if (row >= (int)mRows)
+ mColumns = 0;
+
+ // Similarly, if we're on the last row of old tiles and the height has
+ // changed, discard all tiles in that row.
+ // This will cause the pruning of columns not to work, but we don't need
+ // to worry about that, as no more tiles will be reused past this point
+ // anyway.
+ if ((row == (int)mRows - 1) && (aSize.height != mSize.height))
+ mColumns = 0;
+
+ int col;
+ for (col = 0; col < (int)columns; col++) {
+ IntSize size( // use tilesize first, then the remainder
+ (col+1) * mTileSize > (unsigned int)aSize.width ? aSize.width % mTileSize : mTileSize,
+ (row+1) * mTileSize > (unsigned int)aSize.height ? aSize.height % mTileSize : mTileSize);
+
+ bool replace = false;
+
+ // Check if we can re-use old tiles.
+ if (col < (int)mColumns) {
+ // Reuse an existing tile. If the tile is an end-tile and the
+ // width differs, replace it instead.
+ if (mSize.width != aSize.width) {
+ if (col == (int)mColumns - 1) {
+ // Tile at the end of the old column, replace it with
+ // a new one.
+ replace = true;
+ } else if (col == (int)columns - 1) {
+ // Tile at the end of the new column, create a new one.
+ } else {
+ // Before the last column on both the old and new sizes,
+ // reuse existing tile.
+ i++;
+ continue;
+ }
+ } else {
+ // Width hasn't changed, reuse existing tile.
+ i++;
+ continue;
+ }
+ }
+
+ // Create a new tile.
+ RefPtr<TextureImage> teximg =
+ TileGenFunc(mGL, size, mContentType, mFlags, mImageFormat);
+ if (replace)
+ mImages.ReplaceElementAt(i, teximg);
+ else
+ mImages.InsertElementAt(i, teximg);
+ i++;
+ }
+
+ // Prune any unused tiles on the end of the column.
+ if (row < (int)mRows) {
+ for (col = (int)mColumns - col; col > 0; col--) {
+ mImages.RemoveElementAt(i);
+ }
+ }
+ }
+
+ // Prune any unused tiles at the end of the store.
+ unsigned int length = mImages.Length();
+ for (; i < length; i++)
+ mImages.RemoveElementAt(mImages.Length()-1);
+
+ // Reset tile-store properties.
+ mRows = rows;
+ mColumns = columns;
+ mSize = aSize;
+ mTextureState = Allocated;
+ mCurrentImage = 0;
+}
+
+uint32_t TiledTextureImage::GetTileCount()
+{
+ return mImages.Length();
+}
+
+already_AddRefed<TextureImage>
+CreateTiledTextureImage(GLContext* aGL,
+ const gfx::IntSize& aSize,
+ TextureImage::ContentType aContentType,
+ TextureImage::Flags aFlags,
+ TextureImage::ImageFormat aImageFormat)
+{
+ RefPtr<TextureImage> texImage = static_cast<TextureImage*>(
+ new gl::TiledTextureImage(aGL, aSize, aContentType, aFlags, aImageFormat));
+ return texImage.forget();
+}
+
+
+already_AddRefed<TextureImage>
+CreateBasicTextureImage(GLContext* aGL,
+ const gfx::IntSize& aSize,
+ TextureImage::ContentType aContentType,
+ GLenum aWrapMode,
+ TextureImage::Flags aFlags)
+{
+ bool useNearestFilter = aFlags & TextureImage::UseNearestFilter;
+ if (!aGL->MakeCurrent()) {
+ return nullptr;
+ }
+
+ GLuint texture = 0;
+ aGL->fGenTextures(1, &texture);
+
+ ScopedBindTexture bind(aGL, texture);
+
+ GLint texfilter = useNearestFilter ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR;
+ aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, texfilter);
+ aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, texfilter);
+ aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, aWrapMode);
+ aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, aWrapMode);
+
+ RefPtr<BasicTextureImage> texImage =
+ new BasicTextureImage(texture, aSize, aWrapMode, aContentType,
+ aGL, aFlags);
+ return texImage.forget();
+}
+
+} // namespace gl
+} // namespace mozilla
diff --git a/gfx/gl/GLTextureImage.h b/gfx/gl/GLTextureImage.h
new file mode 100644
index 0000000000..1dd22fb543
--- /dev/null
+++ b/gfx/gl/GLTextureImage.h
@@ -0,0 +1,306 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GLTEXTUREIMAGE_H_
+#define GLTEXTUREIMAGE_H_
+
+#include "nsRegion.h"
+#include "nsTArray.h"
+#include "gfxTypes.h"
+#include "GLContextTypes.h"
+#include "mozilla/gfx/Rect.h"
+#include "mozilla/RefPtr.h"
+
+class gfxASurface;
+
+namespace mozilla {
+namespace gfx {
+class DataSourceSurface;
+class DrawTarget;
+} // namespace gfx
+} // namespace mozilla
+
+namespace mozilla {
+namespace gl {
+class GLContext;
+
+/**
+ * A TextureImage provides a mechanism to synchronize data from a
+ * surface to a texture in the server. TextureImages are associated
+ * with one and only one GLContext.
+ */
+class TextureImage
+{
+ NS_INLINE_DECL_REFCOUNTING(TextureImage)
+public:
+ enum TextureState
+ {
+ Created, // Texture created, but has not had glTexImage called to initialize it.
+ Allocated, // Texture memory exists, but contents are invalid.
+ Valid // Texture fully ready to use.
+ };
+
+ enum Flags {
+ NoFlags = 0x0,
+ UseNearestFilter = 0x1,
+ OriginBottomLeft = 0x2,
+ DisallowBigImage = 0x4
+ };
+
+ typedef gfxContentType ContentType;
+ typedef gfxImageFormat ImageFormat;
+
+ static already_AddRefed<TextureImage> Create(
+ GLContext* gl,
+ const gfx::IntSize& aSize,
+ TextureImage::ContentType aContentType,
+ GLenum aWrapMode,
+ TextureImage::Flags aFlags = TextureImage::NoFlags);
+
+ /**
+ * The Image may contain several textures for different regions (tiles).
+ * These functions iterate over each sub texture image tile.
+ */
+ virtual void BeginBigImageIteration() {
+ }
+
+ virtual bool NextTile() {
+ return false;
+ }
+
+ // Function prototype for a tile iteration callback. Returning false will
+ // cause iteration to be interrupted (i.e. the corresponding NextTile call
+ // will return false).
+ typedef bool (* BigImageIterationCallback)(TextureImage* aImage,
+ int aTileNumber,
+ void* aCallbackData);
+
+ // Sets a callback to be called every time NextTile is called.
+ virtual void SetIterationCallback(BigImageIterationCallback aCallback,
+ void* aCallbackData) {
+ }
+
+ virtual gfx::IntRect GetTileRect();
+
+ virtual GLuint GetTextureID() = 0;
+
+ virtual uint32_t GetTileCount() {
+ return 1;
+ }
+
+ /**
+ * Set this TextureImage's size, and ensure a texture has been
+ * allocated.
+ * After a resize, the contents are undefined.
+ */
+ virtual void Resize(const gfx::IntSize& aSize) = 0;
+
+ /**
+ * Mark this texture as having valid contents. Call this after modifying
+ * the texture contents externally.
+ */
+ virtual void MarkValid() {}
+
+ /**
+ * aSurf - the source surface to update from
+ * aRegion - the region in this image to update
+ * aFrom - offset in the source to update from
+ */
+ virtual bool DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom = gfx::IntPoint(0,0)) = 0;
+ bool UpdateFromDataSource(gfx::DataSourceSurface* aSurf,
+ const nsIntRegion* aDstRegion = nullptr,
+ const gfx::IntPoint* aSrcOffset = nullptr);
+
+ virtual void BindTexture(GLenum aTextureUnit) = 0;
+
+ /**
+ * Returns the image format of the texture. Only valid after
+ * DirectUpdate has been called.
+ */
+ virtual gfx::SurfaceFormat GetTextureFormat() {
+ return mTextureFormat;
+ }
+
+ /** Can be called safely at any time. */
+
+ /**
+ * If this TextureImage has a permanent gfxASurface backing,
+ * return it. Otherwise return nullptr.
+ */
+ virtual already_AddRefed<gfxASurface> GetBackingSurface()
+ { return nullptr; }
+
+
+ gfx::IntSize GetSize() const;
+ ContentType GetContentType() const { return mContentType; }
+ GLenum GetWrapMode() const { return mWrapMode; }
+
+ void SetSamplingFilter(gfx::SamplingFilter aSamplingFilter) {
+ mSamplingFilter = aSamplingFilter;
+ }
+
+protected:
+ friend class GLContext;
+
+ void UpdateUploadSize(size_t amount);
+
+ /**
+ * After the ctor, the TextureImage is invalid. Implementations
+ * must allocate resources successfully before returning the new
+ * TextureImage from GLContext::CreateTextureImage(). That is,
+ * clients must not be given partially-constructed TextureImages.
+ */
+ TextureImage(const gfx::IntSize& aSize,
+ GLenum aWrapMode, ContentType aContentType,
+ Flags aFlags = NoFlags);
+
+ // Protected destructor, to discourage deletion outside of Release():
+ virtual ~TextureImage() {
+ UpdateUploadSize(0);
+ }
+
+ virtual gfx::IntRect GetSrcTileRect();
+
+ gfx::IntSize mSize;
+ GLenum mWrapMode;
+ ContentType mContentType;
+ gfx::SurfaceFormat mTextureFormat;
+ gfx::SamplingFilter mSamplingFilter;
+ Flags mFlags;
+ size_t mUploadSize;
+};
+
+/**
+ * BasicTextureImage is the baseline TextureImage implementation ---
+ * it updates its texture by allocating a scratch buffer for the
+ * client to draw into, then using glTexSubImage2D() to upload the new
+ * pixels. Platforms must provide the code to create a new surface
+ * into which the updated pixels will be drawn, and the code to
+ * convert the update surface's pixels into an image on which we can
+ * glTexSubImage2D().
+ */
+class BasicTextureImage
+ : public TextureImage
+{
+public:
+ virtual ~BasicTextureImage();
+
+ BasicTextureImage(GLuint aTexture,
+ const gfx::IntSize& aSize,
+ GLenum aWrapMode,
+ ContentType aContentType,
+ GLContext* aContext,
+ TextureImage::Flags aFlags = TextureImage::NoFlags);
+
+ virtual void BindTexture(GLenum aTextureUnit);
+
+ virtual bool DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom = gfx::IntPoint(0,0));
+ virtual GLuint GetTextureID() { return mTexture; }
+
+ virtual void MarkValid() { mTextureState = Valid; }
+
+ virtual void Resize(const gfx::IntSize& aSize);
+
+protected:
+ GLuint mTexture;
+ TextureState mTextureState;
+ RefPtr<GLContext> mGLContext;
+};
+
+/**
+ * A container class that complements many sub TextureImages into a big TextureImage.
+ * Aims to behave just like the real thing.
+ */
+
+class TiledTextureImage final
+ : public TextureImage
+{
+public:
+ TiledTextureImage(GLContext* aGL,
+ gfx::IntSize aSize,
+ TextureImage::ContentType,
+ TextureImage::Flags aFlags = TextureImage::NoFlags,
+ TextureImage::ImageFormat aImageFormat = gfx::SurfaceFormat::UNKNOWN);
+ ~TiledTextureImage();
+ void DumpDiv();
+ virtual void Resize(const gfx::IntSize& aSize);
+ virtual uint32_t GetTileCount();
+ virtual void BeginBigImageIteration();
+ virtual bool NextTile();
+ virtual void SetIterationCallback(BigImageIterationCallback aCallback,
+ void* aCallbackData);
+ virtual gfx::IntRect GetTileRect();
+ virtual GLuint GetTextureID() {
+ return mImages[mCurrentImage]->GetTextureID();
+ }
+ virtual bool DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom = gfx::IntPoint(0,0));
+ virtual void BindTexture(GLenum);
+
+protected:
+ virtual gfx::IntRect GetSrcTileRect();
+
+ unsigned int mCurrentImage;
+ BigImageIterationCallback mIterationCallback;
+ void* mIterationCallbackData;
+ nsTArray< RefPtr<TextureImage> > mImages;
+ unsigned int mTileSize;
+ unsigned int mRows, mColumns;
+ GLContext* mGL;
+ TextureState mTextureState;
+ TextureImage::ImageFormat mImageFormat;
+};
+
+/**
+ * Creates a TextureImage of the basic implementation, can be useful in cases
+ * where we know we don't want to use platform-specific TextureImage.
+ * In doubt, use GLContext::CreateTextureImage instead.
+ */
+already_AddRefed<TextureImage>
+CreateBasicTextureImage(GLContext* aGL,
+ const gfx::IntSize& aSize,
+ TextureImage::ContentType aContentType,
+ GLenum aWrapMode,
+ TextureImage::Flags aFlags);
+
+/**
+ * Creates a TiledTextureImage backed by platform-specific or basic TextureImages.
+ * In doubt, use GLContext::CreateTextureImage instead.
+ */
+already_AddRefed<TextureImage>
+CreateTiledTextureImage(GLContext* aGL,
+ const gfx::IntSize& aSize,
+ TextureImage::ContentType aContentType,
+ TextureImage::Flags aFlags,
+ TextureImage::ImageFormat aImageFormat);
+
+/**
+ * Return a valid, allocated TextureImage of |aSize| with
+ * |aContentType|. If |aContentType| is COLOR, |aImageFormat| can be used
+ * to hint at the preferred RGB format, however it is not necessarily
+ * respected. The TextureImage's texture is configured to use
+ * |aWrapMode| (usually GL_CLAMP_TO_EDGE or GL_REPEAT) and by
+ * default, GL_LINEAR filtering. Specify
+ * |aFlags=UseNearestFilter| for GL_NEAREST filtering. Specify
+ * |aFlags=OriginBottomLeft| if the image is origin-bottom-left, instead of the
+ * default origin-top-left. Return
+ * nullptr if creating the TextureImage fails.
+ *
+ * The returned TextureImage may only be used with this GLContext.
+ * Attempting to use the returned TextureImage after this
+ * GLContext is destroyed will result in undefined (and likely
+ * crashy) behavior.
+ */
+already_AddRefed<TextureImage>
+CreateTextureImage(GLContext* gl,
+ const gfx::IntSize& aSize,
+ TextureImage::ContentType aContentType,
+ GLenum aWrapMode,
+ TextureImage::Flags aFlags = TextureImage::NoFlags,
+ TextureImage::ImageFormat aImageFormat = gfx::SurfaceFormat::UNKNOWN);
+
+} // namespace gl
+} // namespace mozilla
+
+#endif /* GLTEXTUREIMAGE_H_ */
diff --git a/gfx/gl/GLTypes.h b/gfx/gl/GLTypes.h
new file mode 100644
index 0000000000..af27019862
--- /dev/null
+++ b/gfx/gl/GLTypes.h
@@ -0,0 +1,94 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#if !defined(GLTYPES_H_)
+#define GLTYPES_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#ifndef GLAPIENTRY
+# ifdef WIN32
+# include <windef.h>
+# define GLAPIENTRY APIENTRY
+# define GLAPI
+# else
+# define GLAPIENTRY
+# define GLAPI
+# endif
+#endif
+
+typedef int8_t realGLboolean;
+
+#if !defined(__gltypes_h_) && !defined(__gl_h_)
+#define __gltypes_h_
+#define __gl_h_
+
+typedef uint32_t GLenum;
+typedef uint32_t GLbitfield;
+typedef uint32_t GLuint;
+typedef int32_t GLint;
+typedef int32_t GLsizei;
+typedef int8_t GLbyte;
+typedef int16_t GLshort;
+typedef uint8_t GLubyte;
+typedef uint16_t GLushort;
+typedef float GLfloat;
+typedef float GLclampf;
+#ifndef GLdouble_defined
+typedef double GLdouble;
+#endif
+typedef double GLclampd;
+typedef void GLvoid;
+
+typedef char GLchar;
+#ifndef __gl2_h_
+typedef intptr_t GLsizeiptr;
+typedef intptr_t GLintptr;
+#endif
+
+#endif /* #if !defined(__gltypes_h_) && !defined(__gl_h_) */
+
+#include <stdint.h>
+
+// ARB_sync
+typedef struct __GLsync* GLsync;
+typedef int64_t GLint64;
+typedef uint64_t GLuint64;
+
+// OES_EGL_image (GLES)
+typedef void* GLeglImage;
+
+// KHR_debug
+typedef void (GLAPIENTRY *GLDEBUGPROC)(GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar* message,
+ const GLvoid* userParam);
+
+// EGL types
+typedef void* EGLImage;
+typedef int EGLint;
+typedef unsigned int EGLBoolean;
+typedef unsigned int EGLenum;
+typedef void* EGLConfig;
+typedef void* EGLContext;
+typedef void* EGLDisplay;
+typedef void* EGLSurface;
+typedef void* EGLClientBuffer;
+typedef void* EGLCastToRelevantPtr;
+typedef void* EGLImage;
+typedef void* EGLSync;
+typedef uint64_t EGLTime;
+
+#define EGL_NO_CONTEXT ((EGLContext)0)
+#define EGL_NO_DISPLAY ((EGLDisplay)0)
+#define EGL_NO_SURFACE ((EGLSurface)0)
+#define EGL_NO_CONFIG ((EGLConfig)nullptr)
+#define EGL_NO_SYNC ((EGLSync)0)
+#define EGL_NO_IMAGE ((EGLImage)0)
+
+#endif
diff --git a/gfx/gl/GLUploadHelpers.cpp b/gfx/gl/GLUploadHelpers.cpp
new file mode 100644
index 0000000000..75165eedf7
--- /dev/null
+++ b/gfx/gl/GLUploadHelpers.cpp
@@ -0,0 +1,558 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "GLUploadHelpers.h"
+
+#include "GLContext.h"
+#include "mozilla/gfx/2D.h"
+#include "gfxUtils.h"
+#include "mozilla/gfx/Tools.h" // For BytesPerPixel
+#include "nsRegion.h"
+#include "GfxTexturesReporter.h"
+#include "mozilla/gfx/Logging.h"
+
+namespace mozilla {
+
+using namespace gfx;
+
+namespace gl {
+
+static unsigned int
+DataOffset(const IntPoint& aPoint, int32_t aStride, SurfaceFormat aFormat)
+{
+ unsigned int data = aPoint.y * aStride;
+ data += aPoint.x * BytesPerPixel(aFormat);
+ return data;
+}
+
+static GLint GetAddressAlignment(ptrdiff_t aAddress)
+{
+ if (!(aAddress & 0x7)) {
+ return 8;
+ } else if (!(aAddress & 0x3)) {
+ return 4;
+ } else if (!(aAddress & 0x1)) {
+ return 2;
+ } else {
+ return 1;
+ }
+}
+
+// Take texture data in a given buffer and copy it into a larger buffer,
+// padding out the edge pixels for filtering if necessary
+static void
+CopyAndPadTextureData(const GLvoid* srcBuffer,
+ GLvoid* dstBuffer,
+ GLsizei srcWidth, GLsizei srcHeight,
+ GLsizei dstWidth, GLsizei dstHeight,
+ GLsizei stride, GLint pixelsize)
+{
+ unsigned char* rowDest = static_cast<unsigned char*>(dstBuffer);
+ const unsigned char* source = static_cast<const unsigned char*>(srcBuffer);
+
+ for (GLsizei h = 0; h < srcHeight; ++h) {
+ memcpy(rowDest, source, srcWidth * pixelsize);
+ rowDest += dstWidth * pixelsize;
+ source += stride;
+ }
+
+ GLsizei padHeight = srcHeight;
+
+ // Pad out an extra row of pixels so that edge filtering doesn't use garbage data
+ if (dstHeight > srcHeight) {
+ memcpy(rowDest, source - stride, srcWidth * pixelsize);
+ padHeight++;
+ }
+
+ // Pad out an extra column of pixels
+ if (dstWidth > srcWidth) {
+ rowDest = static_cast<unsigned char*>(dstBuffer) + srcWidth * pixelsize;
+ for (GLsizei h = 0; h < padHeight; ++h) {
+ memcpy(rowDest, rowDest - pixelsize, pixelsize);
+ rowDest += dstWidth * pixelsize;
+ }
+ }
+}
+
+// In both of these cases (for the Adreno at least) it is impossible
+// to determine good or bad driver versions for POT texture uploads,
+// so blacklist them all. Newer drivers use a different rendering
+// string in the form "Adreno (TM) 200" and the drivers we've seen so
+// far work fine with NPOT textures, so don't blacklist those until we
+// have evidence of any problems with them.
+bool
+CanUploadSubTextures(GLContext* gl)
+{
+ if (!gl->WorkAroundDriverBugs())
+ return true;
+
+ // There are certain GPUs that we don't want to use glTexSubImage2D on
+ // because that function can be very slow and/or buggy
+ if (gl->Renderer() == GLRenderer::Adreno200 ||
+ gl->Renderer() == GLRenderer::Adreno205)
+ {
+ return false;
+ }
+
+ // On PowerVR glTexSubImage does a readback, so it will be slower
+ // than just doing a glTexImage2D() directly. i.e. 26ms vs 10ms
+ if (gl->Renderer() == GLRenderer::SGX540 ||
+ gl->Renderer() == GLRenderer::SGX530)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+static void
+TexSubImage2DWithUnpackSubimageGLES(GLContext* gl,
+ GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLsizei stride, GLint pixelsize,
+ GLenum format, GLenum type,
+ const GLvoid* pixels)
+{
+ gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
+ std::min(GetAddressAlignment((ptrdiff_t)pixels),
+ GetAddressAlignment((ptrdiff_t)stride)));
+ // When using GL_UNPACK_ROW_LENGTH, we need to work around a Tegra
+ // driver crash where the driver apparently tries to read
+ // (stride - width * pixelsize) bytes past the end of the last input
+ // row. We only upload the first height-1 rows using GL_UNPACK_ROW_LENGTH,
+ // and then we upload the final row separately. See bug 697990.
+ int rowLength = stride/pixelsize;
+ gl->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, rowLength);
+ gl->fTexSubImage2D(target,
+ level,
+ xoffset,
+ yoffset,
+ width,
+ height-1,
+ format,
+ type,
+ pixels);
+ gl->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, 0);
+ gl->fTexSubImage2D(target,
+ level,
+ xoffset,
+ yoffset+height-1,
+ width,
+ 1,
+ format,
+ type,
+ (const unsigned char*)pixels+(height-1)*stride);
+ gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
+}
+
+static void
+TexSubImage2DWithoutUnpackSubimage(GLContext* gl,
+ GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLsizei stride, GLint pixelsize,
+ GLenum format, GLenum type,
+ const GLvoid* pixels)
+{
+ // Not using the whole row of texture data and GL_UNPACK_ROW_LENGTH
+ // isn't supported. We make a copy of the texture data we're using,
+ // such that we're using the whole row of data in the copy. This turns
+ // out to be more efficient than uploading row-by-row; see bug 698197.
+ unsigned char* newPixels = new (fallible) unsigned char[width*height*pixelsize];
+
+ if (newPixels) {
+ unsigned char* rowDest = newPixels;
+ const unsigned char* rowSource = (const unsigned char*)pixels;
+ for (int h = 0; h < height; h++) {
+ memcpy(rowDest, rowSource, width*pixelsize);
+ rowDest += width*pixelsize;
+ rowSource += stride;
+ }
+
+ stride = width*pixelsize;
+ gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
+ std::min(GetAddressAlignment((ptrdiff_t)newPixels),
+ GetAddressAlignment((ptrdiff_t)stride)));
+ gl->fTexSubImage2D(target,
+ level,
+ xoffset,
+ yoffset,
+ width,
+ height,
+ format,
+ type,
+ newPixels);
+ delete [] newPixels;
+ gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
+
+ } else {
+ // If we did not have sufficient memory for the required
+ // temporary buffer, then fall back to uploading row-by-row.
+ const unsigned char* rowSource = (const unsigned char*)pixels;
+
+ gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
+ std::min(GetAddressAlignment((ptrdiff_t)pixels),
+ GetAddressAlignment((ptrdiff_t)stride)));
+
+ for (int i = 0; i < height; i++) {
+ gl->fTexSubImage2D(target, level,
+ xoffset, yoffset + i,
+ width, 1,
+ format, type, rowSource);
+ rowSource += stride;
+ }
+
+ gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
+ }
+}
+
+static void
+TexSubImage2DHelper(GLContext* gl,
+ GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height, GLsizei stride,
+ GLint pixelsize, GLenum format,
+ GLenum type, const GLvoid* pixels)
+{
+ if (gl->IsGLES()) {
+ if (stride == width * pixelsize) {
+ gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
+ std::min(GetAddressAlignment((ptrdiff_t)pixels),
+ GetAddressAlignment((ptrdiff_t)stride)));
+ gl->fTexSubImage2D(target,
+ level,
+ xoffset,
+ yoffset,
+ width,
+ height,
+ format,
+ type,
+ pixels);
+ gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
+ } else if (gl->IsExtensionSupported(GLContext::EXT_unpack_subimage)) {
+ TexSubImage2DWithUnpackSubimageGLES(gl, target, level, xoffset, yoffset,
+ width, height, stride,
+ pixelsize, format, type, pixels);
+
+ } else {
+ TexSubImage2DWithoutUnpackSubimage(gl, target, level, xoffset, yoffset,
+ width, height, stride,
+ pixelsize, format, type, pixels);
+ }
+ } else {
+ // desktop GL (non-ES) path
+ gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
+ std::min(GetAddressAlignment((ptrdiff_t)pixels),
+ GetAddressAlignment((ptrdiff_t)stride)));
+ int rowLength = stride/pixelsize;
+ gl->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, rowLength);
+ gl->fTexSubImage2D(target,
+ level,
+ xoffset,
+ yoffset,
+ width,
+ height,
+ format,
+ type,
+ pixels);
+ gl->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, 0);
+ gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
+ }
+}
+
+static void
+TexImage2DHelper(GLContext* gl,
+ GLenum target, GLint level, GLint internalformat,
+ GLsizei width, GLsizei height, GLsizei stride,
+ GLint pixelsize, GLint border, GLenum format,
+ GLenum type, const GLvoid* pixels)
+{
+ if (gl->IsGLES()) {
+
+ NS_ASSERTION(format == (GLenum)internalformat,
+ "format and internalformat not the same for glTexImage2D on GLES2");
+
+ MOZ_ASSERT(width >= 0 && height >= 0);
+ if (!CanUploadNonPowerOfTwo(gl)
+ && (stride != width * pixelsize
+ || !IsPowerOfTwo((uint32_t)width)
+ || !IsPowerOfTwo((uint32_t)height))) {
+
+ // Pad out texture width and height to the next power of two
+ // as we don't support/want non power of two texture uploads
+ GLsizei paddedWidth = RoundUpPow2((uint32_t)width);
+ GLsizei paddedHeight = RoundUpPow2((uint32_t)height);
+
+ GLvoid* paddedPixels = new unsigned char[paddedWidth * paddedHeight * pixelsize];
+
+ // Pad out texture data to be in a POT sized buffer for uploading to
+ // a POT sized texture
+ CopyAndPadTextureData(pixels, paddedPixels, width, height,
+ paddedWidth, paddedHeight, stride, pixelsize);
+
+ gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
+ std::min(GetAddressAlignment((ptrdiff_t)paddedPixels),
+ GetAddressAlignment((ptrdiff_t)paddedWidth * pixelsize)));
+ gl->fTexImage2D(target,
+ border,
+ internalformat,
+ paddedWidth,
+ paddedHeight,
+ border,
+ format,
+ type,
+ paddedPixels);
+ gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
+
+ delete[] static_cast<unsigned char*>(paddedPixels);
+ return;
+ }
+
+ if (stride == width * pixelsize) {
+ gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
+ std::min(GetAddressAlignment((ptrdiff_t)pixels),
+ GetAddressAlignment((ptrdiff_t)stride)));
+ gl->fTexImage2D(target,
+ border,
+ internalformat,
+ width,
+ height,
+ border,
+ format,
+ type,
+ pixels);
+ gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
+ } else {
+ // Use GLES-specific workarounds for GL_UNPACK_ROW_LENGTH; these are
+ // implemented in TexSubImage2D.
+ gl->fTexImage2D(target,
+ border,
+ internalformat,
+ width,
+ height,
+ border,
+ format,
+ type,
+ nullptr);
+ TexSubImage2DHelper(gl,
+ target,
+ level,
+ 0,
+ 0,
+ width,
+ height,
+ stride,
+ pixelsize,
+ format,
+ type,
+ pixels);
+ }
+ } else {
+ // desktop GL (non-ES) path
+
+ gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
+ std::min(GetAddressAlignment((ptrdiff_t)pixels),
+ GetAddressAlignment((ptrdiff_t)stride)));
+ int rowLength = stride/pixelsize;
+ gl->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, rowLength);
+ gl->fTexImage2D(target,
+ level,
+ internalformat,
+ width,
+ height,
+ border,
+ format,
+ type,
+ pixels);
+ gl->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, 0);
+ gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
+ }
+}
+
+SurfaceFormat
+UploadImageDataToTexture(GLContext* gl,
+ unsigned char* aData,
+ int32_t aStride,
+ SurfaceFormat aFormat,
+ const nsIntRegion& aDstRegion,
+ GLuint aTexture,
+ const gfx::IntSize& aSize,
+ size_t* aOutUploadSize,
+ bool aNeedInit,
+ GLenum aTextureUnit,
+ GLenum aTextureTarget)
+{
+ gl->MakeCurrent();
+ gl->fActiveTexture(aTextureUnit);
+ gl->fBindTexture(aTextureTarget, aTexture);
+
+ GLenum format = 0;
+ GLenum internalFormat = 0;
+ GLenum type = 0;
+ int32_t pixelSize = BytesPerPixel(aFormat);
+ SurfaceFormat surfaceFormat = gfx::SurfaceFormat::UNKNOWN;
+
+ MOZ_ASSERT(gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA ||
+ gl->GetPreferredARGB32Format() == LOCAL_GL_RGBA);
+
+ switch (aFormat) {
+ case SurfaceFormat::B8G8R8A8:
+ if (gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA) {
+ format = LOCAL_GL_BGRA;
+ surfaceFormat = SurfaceFormat::R8G8B8A8;
+ type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
+ } else {
+ format = LOCAL_GL_RGBA;
+ surfaceFormat = SurfaceFormat::B8G8R8A8;
+ type = LOCAL_GL_UNSIGNED_BYTE;
+ }
+ internalFormat = LOCAL_GL_RGBA;
+ break;
+ case SurfaceFormat::B8G8R8X8:
+ // Treat BGRX surfaces as BGRA except for the surface
+ // format used.
+ if (gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA) {
+ format = LOCAL_GL_BGRA;
+ surfaceFormat = SurfaceFormat::R8G8B8X8;
+ type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
+ } else {
+ format = LOCAL_GL_RGBA;
+ surfaceFormat = SurfaceFormat::B8G8R8X8;
+ type = LOCAL_GL_UNSIGNED_BYTE;
+ }
+ internalFormat = LOCAL_GL_RGBA;
+ break;
+ case SurfaceFormat::R8G8B8A8:
+ if (gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA) {
+ // Upload our RGBA as BGRA, but store that the uploaded format is
+ // BGRA. (sample from R to get B)
+ format = LOCAL_GL_BGRA;
+ type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
+ surfaceFormat = SurfaceFormat::B8G8R8A8;
+ } else {
+ format = LOCAL_GL_RGBA;
+ type = LOCAL_GL_UNSIGNED_BYTE;
+ surfaceFormat = SurfaceFormat::R8G8B8A8;
+ }
+ internalFormat = LOCAL_GL_RGBA;
+ break;
+ case SurfaceFormat::R8G8B8X8:
+ // Treat RGBX surfaces as RGBA except for the surface
+ // format used.
+ if (gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA) {
+ format = LOCAL_GL_BGRA;
+ type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
+ surfaceFormat = SurfaceFormat::B8G8R8X8;
+ } else {
+ format = LOCAL_GL_RGBA;
+ type = LOCAL_GL_UNSIGNED_BYTE;
+ surfaceFormat = SurfaceFormat::R8G8B8X8;
+ }
+ internalFormat = LOCAL_GL_RGBA;
+ break;
+ case SurfaceFormat::R5G6B5_UINT16:
+ internalFormat = format = LOCAL_GL_RGB;
+ type = LOCAL_GL_UNSIGNED_SHORT_5_6_5;
+ surfaceFormat = SurfaceFormat::R5G6B5_UINT16;
+ break;
+ case SurfaceFormat::A8:
+ internalFormat = format = LOCAL_GL_LUMINANCE;
+ type = LOCAL_GL_UNSIGNED_BYTE;
+ // We don't have a specific luminance shader
+ surfaceFormat = SurfaceFormat::A8;
+ break;
+ default:
+ NS_ASSERTION(false, "Unhandled image surface format!");
+ }
+
+ if (aOutUploadSize) {
+ *aOutUploadSize = 0;
+ }
+
+ if (aNeedInit || !CanUploadSubTextures(gl)) {
+ // If the texture needs initialized, or we are unable to
+ // upload sub textures, then initialize and upload the entire
+ // texture.
+ TexImage2DHelper(gl,
+ aTextureTarget,
+ 0,
+ internalFormat,
+ aSize.width,
+ aSize.height,
+ aStride,
+ pixelSize,
+ 0,
+ format,
+ type,
+ aData);
+
+ if (aOutUploadSize && aNeedInit) {
+ uint32_t texelSize = GetBytesPerTexel(internalFormat, type);
+ size_t numTexels = size_t(aSize.width) * size_t(aSize.height);
+ *aOutUploadSize += texelSize * numTexels;
+ }
+ } else {
+ // Upload each rect in the region to the texture
+ for (auto iter = aDstRegion.RectIter(); !iter.Done(); iter.Next()) {
+ const IntRect& rect = iter.Get();
+ const unsigned char* rectData =
+ aData + DataOffset(rect.TopLeft(), aStride, aFormat);
+
+ TexSubImage2DHelper(gl,
+ aTextureTarget,
+ 0,
+ rect.x,
+ rect.y,
+ rect.width,
+ rect.height,
+ aStride,
+ pixelSize,
+ format,
+ type,
+ rectData);
+ }
+ }
+
+ return surfaceFormat;
+}
+
+SurfaceFormat
+UploadSurfaceToTexture(GLContext* gl,
+ DataSourceSurface* aSurface,
+ const nsIntRegion& aDstRegion,
+ GLuint aTexture,
+ const gfx::IntSize& aSize,
+ size_t* aOutUploadSize,
+ bool aNeedInit,
+ const gfx::IntPoint& aSrcPoint,
+ GLenum aTextureUnit,
+ GLenum aTextureTarget)
+{
+
+ int32_t stride = aSurface->Stride();
+ SurfaceFormat format = aSurface->GetFormat();
+ unsigned char* data = aSurface->GetData() +
+ DataOffset(aSrcPoint, stride, format);
+
+ return UploadImageDataToTexture(gl, data, stride, format,
+ aDstRegion, aTexture, aSize,
+ aOutUploadSize, aNeedInit,
+ aTextureUnit, aTextureTarget);
+}
+
+bool
+CanUploadNonPowerOfTwo(GLContext* gl)
+{
+ if (!gl->WorkAroundDriverBugs())
+ return true;
+
+ // Some GPUs driver crash when uploading non power of two 565 textures.
+ return gl->Renderer() != GLRenderer::Adreno200 &&
+ gl->Renderer() != GLRenderer::Adreno205;
+}
+
+} // namespace gl
+} // namespace mozilla
diff --git a/gfx/gl/GLUploadHelpers.h b/gfx/gl/GLUploadHelpers.h
new file mode 100644
index 0000000000..866d44adbe
--- /dev/null
+++ b/gfx/gl/GLUploadHelpers.h
@@ -0,0 +1,84 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GLUploadHelpers_h_
+#define GLUploadHelpers_h_
+
+#include "GLDefs.h"
+#include "mozilla/gfx/Types.h"
+#include "nsPoint.h"
+#include "nsRegionFwd.h"
+
+namespace mozilla {
+
+namespace gfx {
+class DataSourceSurface;
+} // namespace gfx
+
+namespace gl {
+
+class GLContext;
+
+/**
+ * Uploads image data to an OpenGL texture, initializing the texture
+ * first if necessary.
+ *
+ * \param gl The GL Context to use.
+ * \param aData Start of image data of surface to upload.
+ * Corresponds to the first pixel of the texture.
+ * \param aStride The image data's stride.
+ * \param aFormat The image data's format.
+ * \param aDstRegion Region of the texture to upload.
+ * \param aTexture The OpenGL texture to use. Must refer to a valid texture.
+ * \param aSize The full size of the texture.
+ * \param aOutUploadSize If set, the number of bytes the texture requires will
+ * be returned here.
+ * \param aNeedInit Indicates whether a new texture must be allocated.
+ * \param aTextureUnit The texture unit used temporarily to upload the surface.
+ * This may be overridden, so clients should not rely on
+ * the aTexture being bound to aTextureUnit after this call,
+ * or even on aTextureUnit being active.
+ * \param aTextureTarget The texture target to use.
+ * \return Surface format of this texture.
+ */
+gfx::SurfaceFormat
+UploadImageDataToTexture(GLContext* gl,
+ unsigned char* aData,
+ int32_t aStride,
+ gfx::SurfaceFormat aFormat,
+ const nsIntRegion& aDstRegion,
+ GLuint aTexture,
+ const gfx::IntSize& aSize,
+ size_t* aOutUploadSize = nullptr,
+ bool aNeedInit = false,
+ GLenum aTextureUnit = LOCAL_GL_TEXTURE0,
+ GLenum aTextureTarget = LOCAL_GL_TEXTURE_2D);
+
+/**
+ * Convenience wrapper around UploadImageDataToTexture for
+ * gfx::DataSourceSurface's.
+ *
+ * \param aSurface The surface from which to upload image data.
+ * \param aSrcPoint Offset into aSurface where this texture's data begins.
+ */
+gfx::SurfaceFormat
+UploadSurfaceToTexture(GLContext* gl,
+ gfx::DataSourceSurface* aSurface,
+ const nsIntRegion& aDstRegion,
+ GLuint aTexture,
+ const gfx::IntSize& aSize,
+ size_t* aOutUploadSize = nullptr,
+ bool aNeedInit = false,
+ const gfx::IntPoint& aSrcPoint = gfx::IntPoint(0, 0),
+ GLenum aTextureUnit = LOCAL_GL_TEXTURE0,
+ GLenum aTextureTarget = LOCAL_GL_TEXTURE_2D);
+
+bool CanUploadSubTextures(GLContext* gl);
+bool CanUploadNonPowerOfTwo(GLContext* gl);
+
+} // namespace gl
+} // namespace mozilla
+
+#endif
diff --git a/gfx/gl/GLXLibrary.h b/gfx/gl/GLXLibrary.h
new file mode 100644
index 0000000000..d584b3b417
--- /dev/null
+++ b/gfx/gl/GLXLibrary.h
@@ -0,0 +1,274 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GFX_GLXLIBRARY_H
+#define GFX_GLXLIBRARY_H
+
+#include "GLContextTypes.h"
+typedef realGLboolean GLboolean;
+
+// stuff from glx.h
+#include "X11/Xlib.h"
+typedef struct __GLXcontextRec* GLXContext;
+typedef XID GLXPixmap;
+typedef XID GLXDrawable;
+/* GLX 1.3 and later */
+typedef struct __GLXFBConfigRec* GLXFBConfig;
+typedef XID GLXFBConfigID;
+typedef XID GLXContextID;
+typedef XID GLXWindow;
+typedef XID GLXPbuffer;
+// end of stuff from glx.h
+#include "prenv.h"
+
+struct PRLibrary;
+class gfxASurface;
+
+namespace mozilla {
+namespace gl {
+
+class GLXLibrary
+{
+public:
+ constexpr GLXLibrary()
+ : xDestroyContextInternal(nullptr)
+ , xMakeCurrentInternal(nullptr)
+ , xGetCurrentContextInternal(nullptr)
+ , xGetProcAddressInternal(nullptr)
+ , xChooseFBConfigInternal(nullptr)
+ , xGetFBConfigsInternal(nullptr)
+ , xCreateNewContextInternal(nullptr)
+ , xGetFBConfigAttribInternal(nullptr)
+ , xSwapBuffersInternal(nullptr)
+ , xQueryExtensionsStringInternal(nullptr)
+ , xGetClientStringInternal(nullptr)
+ , xQueryServerStringInternal(nullptr)
+ , xCreatePixmapInternal(nullptr)
+ , xCreateGLXPixmapWithConfigInternal(nullptr)
+ , xDestroyPixmapInternal(nullptr)
+ , xQueryVersionInternal(nullptr)
+ , xBindTexImageInternal(nullptr)
+ , xReleaseTexImageInternal(nullptr)
+ , xWaitGLInternal(nullptr)
+ , xWaitXInternal(nullptr)
+ , xCreateContextAttribsInternal(nullptr)
+ , xGetVideoSyncInternal(nullptr)
+ , xWaitVideoSyncInternal(nullptr)
+ , xSwapIntervalInternal(nullptr)
+ , mInitialized(false), mTriedInitializing(false)
+ , mUseTextureFromPixmap(false), mDebug(false)
+ , mHasRobustness(false), mHasCreateContextAttribs(false)
+ , mHasVideoSync(false)
+ , mIsATI(false), mIsNVIDIA(false)
+ , mClientIsMesa(false), mGLXMajorVersion(0)
+ , mGLXMinorVersion(0)
+ , mOGLLibrary(nullptr)
+ {}
+
+ void xDestroyContext(Display* display, GLXContext context);
+ Bool xMakeCurrent(Display* display,
+ GLXDrawable drawable,
+ GLXContext context);
+
+ GLXContext xGetCurrentContext();
+ static void* xGetProcAddress(const char* procName);
+ GLXFBConfig* xChooseFBConfig(Display* display,
+ int screen,
+ const int* attrib_list,
+ int* nelements);
+ GLXFBConfig* xGetFBConfigs(Display* display,
+ int screen,
+ int* nelements);
+ GLXContext xCreateNewContext(Display* display,
+ GLXFBConfig config,
+ int render_type,
+ GLXContext share_list,
+ Bool direct);
+ int xGetFBConfigAttrib(Display* display,
+ GLXFBConfig config,
+ int attribute,
+ int* value);
+ void xSwapBuffers(Display* display, GLXDrawable drawable);
+ const char* xQueryExtensionsString(Display* display,
+ int screen);
+ const char* xGetClientString(Display* display,
+ int screen);
+ const char* xQueryServerString(Display* display,
+ int screen, int name);
+ GLXPixmap xCreatePixmap(Display* display,
+ GLXFBConfig config,
+ Pixmap pixmap,
+ const int* attrib_list);
+ GLXPixmap xCreateGLXPixmapWithConfig(Display* display,
+ GLXFBConfig config,
+ Pixmap pixmap);
+ void xDestroyPixmap(Display* display, GLXPixmap pixmap);
+ Bool xQueryVersion(Display* display,
+ int* major,
+ int* minor);
+ void xBindTexImage(Display* display,
+ GLXDrawable drawable,
+ int buffer,
+ const int* attrib_list);
+ void xReleaseTexImage(Display* display,
+ GLXDrawable drawable,
+ int buffer);
+ void xWaitGL();
+ void xWaitX();
+
+ GLXContext xCreateContextAttribs(Display* display,
+ GLXFBConfig config,
+ GLXContext share_list,
+ Bool direct,
+ const int* attrib_list);
+
+ int xGetVideoSync(unsigned int* count);
+ int xWaitVideoSync(int divisor, int remainder, unsigned int* count);
+ void xSwapInterval(Display* dpy, GLXDrawable drawable, int interval);
+
+ bool EnsureInitialized();
+
+ GLXPixmap CreatePixmap(gfxASurface* aSurface);
+ void DestroyPixmap(Display* aDisplay, GLXPixmap aPixmap);
+ void BindTexImage(Display* aDisplay, GLXPixmap aPixmap);
+ void ReleaseTexImage(Display* aDisplay, GLXPixmap aPixmap);
+ void UpdateTexImage(Display* aDisplay, GLXPixmap aPixmap);
+
+ bool UseTextureFromPixmap() { return mUseTextureFromPixmap; }
+ bool HasRobustness() { return mHasRobustness; }
+ bool HasCreateContextAttribs() { return mHasCreateContextAttribs; }
+ bool SupportsTextureFromPixmap(gfxASurface* aSurface);
+ bool SupportsVideoSync();
+ bool SupportsSwapControl() const { return bool(xSwapIntervalInternal); }
+ bool IsATI() { return mIsATI; }
+ bool IsMesa() { return mClientIsMesa; }
+ bool GLXVersionCheck(int aMajor, int aMinor);
+
+private:
+
+ typedef void (GLAPIENTRY * PFNGLXDESTROYCONTEXTPROC) (Display*,
+ GLXContext);
+ PFNGLXDESTROYCONTEXTPROC xDestroyContextInternal;
+ typedef Bool (GLAPIENTRY * PFNGLXMAKECURRENTPROC) (Display*,
+ GLXDrawable,
+ GLXContext);
+ PFNGLXMAKECURRENTPROC xMakeCurrentInternal;
+ typedef GLXContext (GLAPIENTRY * PFNGLXGETCURRENTCONTEXT) ();
+ PFNGLXGETCURRENTCONTEXT xGetCurrentContextInternal;
+ typedef void* (GLAPIENTRY * PFNGLXGETPROCADDRESSPROC) (const char*);
+ PFNGLXGETPROCADDRESSPROC xGetProcAddressInternal;
+ typedef GLXFBConfig* (GLAPIENTRY * PFNGLXCHOOSEFBCONFIG) (Display*,
+ int,
+ const int*,
+ int*);
+ PFNGLXCHOOSEFBCONFIG xChooseFBConfigInternal;
+ typedef GLXFBConfig* (GLAPIENTRY * PFNGLXGETFBCONFIGS) (Display*,
+ int,
+ int*);
+ PFNGLXGETFBCONFIGS xGetFBConfigsInternal;
+ typedef GLXContext (GLAPIENTRY * PFNGLXCREATENEWCONTEXT) (Display*,
+ GLXFBConfig,
+ int,
+ GLXContext,
+ Bool);
+ PFNGLXCREATENEWCONTEXT xCreateNewContextInternal;
+ typedef int (GLAPIENTRY * PFNGLXGETFBCONFIGATTRIB) (Display*,
+ GLXFBConfig,
+ int,
+ int*);
+ PFNGLXGETFBCONFIGATTRIB xGetFBConfigAttribInternal;
+
+ typedef void (GLAPIENTRY * PFNGLXSWAPBUFFERS) (Display*,
+ GLXDrawable);
+ PFNGLXSWAPBUFFERS xSwapBuffersInternal;
+ typedef const char* (GLAPIENTRY * PFNGLXQUERYEXTENSIONSSTRING) (Display*,
+ int);
+ PFNGLXQUERYEXTENSIONSSTRING xQueryExtensionsStringInternal;
+ typedef const char* (GLAPIENTRY * PFNGLXGETCLIENTSTRING) (Display*,
+ int);
+ PFNGLXGETCLIENTSTRING xGetClientStringInternal;
+ typedef const char* (GLAPIENTRY * PFNGLXQUERYSERVERSTRING) (Display*,
+ int,
+ int);
+ PFNGLXQUERYSERVERSTRING xQueryServerStringInternal;
+
+ typedef GLXPixmap (GLAPIENTRY * PFNGLXCREATEPIXMAP) (Display*,
+ GLXFBConfig,
+ Pixmap,
+ const int*);
+ PFNGLXCREATEPIXMAP xCreatePixmapInternal;
+ typedef GLXPixmap (GLAPIENTRY * PFNGLXCREATEGLXPIXMAPWITHCONFIG)
+ (Display*,
+ GLXFBConfig,
+ Pixmap);
+ PFNGLXCREATEGLXPIXMAPWITHCONFIG xCreateGLXPixmapWithConfigInternal;
+ typedef void (GLAPIENTRY * PFNGLXDESTROYPIXMAP) (Display*,
+ GLXPixmap);
+ PFNGLXDESTROYPIXMAP xDestroyPixmapInternal;
+ typedef Bool (GLAPIENTRY * PFNGLXQUERYVERSION) (Display*,
+ int*,
+ int*);
+ PFNGLXQUERYVERSION xQueryVersionInternal;
+
+ typedef void (GLAPIENTRY * PFNGLXBINDTEXIMAGE) (Display*,
+ GLXDrawable,
+ int,
+ const int*);
+ PFNGLXBINDTEXIMAGE xBindTexImageInternal;
+
+ typedef void (GLAPIENTRY * PFNGLXRELEASETEXIMAGE) (Display*,
+ GLXDrawable,
+ int);
+ PFNGLXRELEASETEXIMAGE xReleaseTexImageInternal;
+
+ typedef void (GLAPIENTRY * PFNGLXWAITGL) ();
+ PFNGLXWAITGL xWaitGLInternal;
+
+ typedef void (GLAPIENTRY * PFNGLXWAITX) ();
+ PFNGLXWAITGL xWaitXInternal;
+
+ typedef GLXContext (GLAPIENTRY * PFNGLXCREATECONTEXTATTRIBS) (Display*,
+ GLXFBConfig,
+ GLXContext,
+ Bool,
+ const int*);
+ PFNGLXCREATECONTEXTATTRIBS xCreateContextAttribsInternal;
+
+ typedef int (GLAPIENTRY * PFNGLXGETVIDEOSYNCSGI) (unsigned int* count);
+ PFNGLXGETVIDEOSYNCSGI xGetVideoSyncInternal;
+
+ typedef int (GLAPIENTRY * PFNGLXWAITVIDEOSYNCSGI) (int divisor, int remainder, unsigned int* count);
+ PFNGLXWAITVIDEOSYNCSGI xWaitVideoSyncInternal;
+
+ typedef void (GLAPIENTRY * PFNGLXSWAPINTERVALEXT) (Display* dpy, GLXDrawable drawable, int interval);
+ PFNGLXSWAPINTERVALEXT xSwapIntervalInternal;
+
+#ifdef DEBUG
+ void BeforeGLXCall();
+ void AfterGLXCall();
+#endif
+
+ bool mInitialized;
+ bool mTriedInitializing;
+ bool mUseTextureFromPixmap;
+ bool mDebug;
+ bool mHasRobustness;
+ bool mHasCreateContextAttribs;
+ bool mHasVideoSync;
+ bool mIsATI;
+ bool mIsNVIDIA;
+ bool mClientIsMesa;
+ int mGLXMajorVersion;
+ int mGLXMinorVersion;
+ PRLibrary* mOGLLibrary;
+};
+
+// a global GLXLibrary instance
+extern GLXLibrary sGLXLibrary;
+
+} /* namespace gl */
+} /* namespace mozilla */
+#endif /* GFX_GLXLIBRARY_H */
+
diff --git a/gfx/gl/GfxTexturesReporter.cpp b/gfx/gl/GfxTexturesReporter.cpp
new file mode 100644
index 0000000000..8007fe6b13
--- /dev/null
+++ b/gfx/gl/GfxTexturesReporter.cpp
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <string>
+#include <sstream>
+#include "GfxTexturesReporter.h"
+#include "gfxPrefs.h"
+
+#ifdef MOZ_CRASHREPORTER
+#include "nsExceptionHandler.h"
+#endif
+
+using namespace mozilla;
+using namespace mozilla::gl;
+
+NS_IMPL_ISUPPORTS(GfxTexturesReporter, nsIMemoryReporter)
+
+Atomic<size_t> GfxTexturesReporter::sAmount(0);
+Atomic<size_t> GfxTexturesReporter::sPeakAmount(0);
+Atomic<size_t> GfxTexturesReporter::sTileWasteAmount(0);
+
+std::string
+FormatBytes(size_t amount)
+{
+ std::stringstream stream;
+ int depth = 0;
+ double val = amount;
+ while (val > 1024) {
+ val /= 1024;
+ depth++;
+ }
+
+ const char* unit;
+ switch(depth) {
+ case 0:
+ unit = "bytes";
+ break;
+ case 1:
+ unit = "KB";
+ break;
+ case 2:
+ unit = "MB";
+ break;
+ case 3:
+ unit = "GB";
+ break;
+ default:
+ unit = "";
+ break;
+ }
+
+ stream << val << " " << unit;
+ return stream.str();
+}
+
+/* static */ void
+GfxTexturesReporter::UpdateAmount(MemoryUse action, size_t amount)
+{
+ if (action == MemoryFreed) {
+ MOZ_RELEASE_ASSERT(amount <= sAmount, "GFX: Current texture usage greater than update amount.");
+ sAmount -= amount;
+
+ if (gfxPrefs::GfxLoggingTextureUsageEnabled()) {
+ printf_stderr("Current texture usage: %s\n", FormatBytes(sAmount).c_str());
+ }
+ } else {
+ sAmount += amount;
+ if (sAmount > sPeakAmount) {
+ sPeakAmount.exchange(sAmount);
+ if (gfxPrefs::GfxLoggingPeakTextureUsageEnabled()) {
+ printf_stderr("Peak texture usage: %s\n", FormatBytes(sPeakAmount).c_str());
+ }
+ }
+ }
+
+#ifdef MOZ_CRASHREPORTER
+ CrashReporter::AnnotateTexturesSize(sAmount);
+#endif
+}
diff --git a/gfx/gl/GfxTexturesReporter.h b/gfx/gl/GfxTexturesReporter.h
new file mode 100644
index 0000000000..ed4603f0a1
--- /dev/null
+++ b/gfx/gl/GfxTexturesReporter.h
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GFXTEXTURESREPORTER_H_
+#define GFXTEXTURESREPORTER_H_
+
+#include "mozilla/Atomics.h"
+#include "nsIMemoryReporter.h"
+#include "GLTypes.h"
+
+namespace mozilla {
+namespace gl {
+
+class GfxTexturesReporter final : public nsIMemoryReporter
+{
+ ~GfxTexturesReporter() {}
+
+public:
+ NS_DECL_ISUPPORTS
+
+ GfxTexturesReporter()
+ {
+#ifdef DEBUG
+ // There must be only one instance of this class, due to |sAmount|
+ // being static. Assert this.
+ static bool hasRun = false;
+ MOZ_ASSERT(!hasRun);
+ hasRun = true;
+#endif
+ }
+
+ enum MemoryUse {
+ // when memory being allocated is reported to a memory reporter
+ MemoryAllocated,
+ // when memory being freed is reported to a memory reporter
+ MemoryFreed
+ };
+
+ // When memory is used/freed for tile textures, call this method to update
+ // the value reported by this memory reporter.
+ static void UpdateAmount(MemoryUse action, size_t amount);
+
+ static void UpdateWasteAmount(size_t delta) {
+ sTileWasteAmount += delta;
+ }
+
+ NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
+ nsISupports* aData, bool aAnonymize) override
+ {
+ MOZ_COLLECT_REPORT(
+ "gfx-tiles-waste", KIND_OTHER, UNITS_BYTES,
+ int64_t(sTileWasteAmount),
+ "Memory lost due to tiles extending past content boundaries");
+
+ MOZ_COLLECT_REPORT(
+ "gfx-textures", KIND_OTHER, UNITS_BYTES,
+ int64_t(sAmount),
+ "Memory used for storing GL textures.");
+
+ MOZ_COLLECT_REPORT(
+ "gfx-textures-peak", KIND_OTHER, UNITS_BYTES,
+ int64_t(sPeakAmount),
+ "Peak memory used for storing GL textures.");
+
+ return NS_OK;
+ }
+
+private:
+ static Atomic<size_t> sAmount;
+ static Atomic<size_t> sPeakAmount;
+ // Count the amount of memory lost to tile waste
+ static Atomic<size_t> sTileWasteAmount;
+};
+
+class GfxTextureWasteTracker {
+public:
+ GfxTextureWasteTracker()
+ : mBytes(0)
+ {
+ MOZ_COUNT_CTOR(GfxTextureWasteTracker);
+ }
+
+ void Update(int32_t aPixelArea, int32_t aBytesPerPixel) {
+ GfxTexturesReporter::UpdateWasteAmount(-mBytes);
+ mBytes = aPixelArea * aBytesPerPixel;
+ GfxTexturesReporter::UpdateWasteAmount(mBytes);
+ }
+
+ ~GfxTextureWasteTracker() {
+ GfxTexturesReporter::UpdateWasteAmount(-mBytes);
+ MOZ_COUNT_DTOR(GfxTextureWasteTracker);
+ }
+private:
+ GfxTextureWasteTracker(const GfxTextureWasteTracker& aRef);
+
+ int32_t mBytes;
+};
+
+} // namespace gl
+} // namespace mozilla
+
+#endif // GFXTEXTURESREPORTER_H_
diff --git a/gfx/gl/HeapCopyOfStackArray.h b/gfx/gl/HeapCopyOfStackArray.h
new file mode 100644
index 0000000000..2fae79245a
--- /dev/null
+++ b/gfx/gl/HeapCopyOfStackArray.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=4 et sw=4 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef HEAPCOPYOFSTACKARRAY_H_
+#define HEAPCOPYOFSTACKARRAY_H_
+
+#include "mozilla/Attributes.h"
+#include "mozilla/UniquePtr.h"
+
+#include <string.h>
+
+namespace mozilla {
+
+// Takes a stack array and copies it into a heap buffer.
+// Useful to retain the convenience of declaring static arrays, while
+// avoiding passing stack pointers to the GL (see bug 1005658).
+
+template <typename ElemType>
+class HeapCopyOfStackArray
+{
+public:
+ template<size_t N>
+ MOZ_IMPLICIT HeapCopyOfStackArray(ElemType (&array)[N])
+ : mArrayLength(N)
+ , mArrayData(MakeUnique<ElemType[]>(N))
+ {
+ memcpy(mArrayData.get(), &array[0], N * sizeof(ElemType));
+ }
+
+ ElemType* Data() const { return mArrayData.get(); }
+ size_t ArrayLength() const { return mArrayLength; }
+ size_t ByteLength() const { return mArrayLength * sizeof(ElemType); }
+
+private:
+ HeapCopyOfStackArray() = delete;
+ HeapCopyOfStackArray(const HeapCopyOfStackArray&) = delete;
+
+ const size_t mArrayLength;
+ UniquePtr<ElemType[]> const mArrayData;
+};
+
+} // namespace mozilla
+
+#endif // HEAPCOPYOFSTACKARRAY_H_
diff --git a/gfx/gl/ScopedGLHelpers.cpp b/gfx/gl/ScopedGLHelpers.cpp
new file mode 100644
index 0000000000..fade357880
--- /dev/null
+++ b/gfx/gl/ScopedGLHelpers.cpp
@@ -0,0 +1,540 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/UniquePtr.h"
+
+#include "GLContext.h"
+#include "ScopedGLHelpers.h"
+
+namespace mozilla {
+namespace gl {
+
+#ifdef DEBUG
+bool
+IsContextCurrent(GLContext* gl)
+{
+ return gl->IsCurrent();
+}
+#endif
+
+/* ScopedGLState - Wraps glEnable/glDisable. **********************************/
+
+// Use |newState = true| to enable, |false| to disable.
+ScopedGLState::ScopedGLState(GLContext* aGL, GLenum aCapability, bool aNewState)
+ : ScopedGLWrapper<ScopedGLState>(aGL)
+ , mCapability(aCapability)
+{
+ mOldState = mGL->fIsEnabled(mCapability);
+
+ // Early out if we're already in the right state.
+ if (aNewState == mOldState)
+ return;
+
+ if (aNewState) {
+ mGL->fEnable(mCapability);
+ } else {
+ mGL->fDisable(mCapability);
+ }
+}
+
+ScopedGLState::ScopedGLState(GLContext* aGL, GLenum aCapability)
+ : ScopedGLWrapper<ScopedGLState>(aGL)
+ , mCapability(aCapability)
+{
+ mOldState = mGL->fIsEnabled(mCapability);
+}
+
+void
+ScopedGLState::UnwrapImpl()
+{
+ if (mOldState) {
+ mGL->fEnable(mCapability);
+ } else {
+ mGL->fDisable(mCapability);
+ }
+}
+
+
+/* ScopedBindFramebuffer - Saves and restores with GetUserBoundFB and BindUserFB. */
+
+void
+ScopedBindFramebuffer::Init()
+{
+ if (mGL->IsSupported(GLFeature::split_framebuffer)) {
+ mOldReadFB = mGL->GetReadFB();
+ mOldDrawFB = mGL->GetDrawFB();
+ } else {
+ mOldReadFB = mOldDrawFB = mGL->GetFB();
+ }
+}
+
+ScopedBindFramebuffer::ScopedBindFramebuffer(GLContext* aGL)
+ : ScopedGLWrapper<ScopedBindFramebuffer>(aGL)
+{
+ Init();
+}
+
+ScopedBindFramebuffer::ScopedBindFramebuffer(GLContext* aGL, GLuint aNewFB)
+ : ScopedGLWrapper<ScopedBindFramebuffer>(aGL)
+{
+ Init();
+ mGL->BindFB(aNewFB);
+}
+
+void
+ScopedBindFramebuffer::UnwrapImpl()
+{
+ if (mOldReadFB == mOldDrawFB) {
+ mGL->BindFB(mOldDrawFB);
+ } else {
+ mGL->BindDrawFB(mOldDrawFB);
+ mGL->BindReadFB(mOldReadFB);
+ }
+}
+
+
+/* ScopedBindTextureUnit ******************************************************/
+
+ScopedBindTextureUnit::ScopedBindTextureUnit(GLContext* aGL, GLenum aTexUnit)
+ : ScopedGLWrapper<ScopedBindTextureUnit>(aGL)
+{
+ MOZ_ASSERT(aTexUnit >= LOCAL_GL_TEXTURE0);
+ mGL->GetUIntegerv(LOCAL_GL_ACTIVE_TEXTURE, &mOldTexUnit);
+ mGL->fActiveTexture(aTexUnit);
+}
+
+void
+ScopedBindTextureUnit::UnwrapImpl() {
+ mGL->fActiveTexture(mOldTexUnit);
+}
+
+
+/* ScopedTexture **************************************************************/
+
+ScopedTexture::ScopedTexture(GLContext* aGL)
+ : ScopedGLWrapper<ScopedTexture>(aGL)
+{
+ mGL->fGenTextures(1, &mTexture);
+}
+
+void
+ScopedTexture::UnwrapImpl()
+{
+ mGL->fDeleteTextures(1, &mTexture);
+}
+
+/* ScopedFramebuffer **************************************************************/
+
+ScopedFramebuffer::ScopedFramebuffer(GLContext* aGL)
+ : ScopedGLWrapper<ScopedFramebuffer>(aGL)
+{
+ mGL->fGenFramebuffers(1, &mFB);
+}
+
+void
+ScopedFramebuffer::UnwrapImpl()
+{
+ mGL->fDeleteFramebuffers(1, &mFB);
+}
+
+
+/* ScopedRenderbuffer **************************************************************/
+
+ScopedRenderbuffer::ScopedRenderbuffer(GLContext* aGL)
+ : ScopedGLWrapper<ScopedRenderbuffer>(aGL)
+{
+ mGL->fGenRenderbuffers(1, &mRB);
+}
+
+void
+ScopedRenderbuffer::UnwrapImpl()
+{
+ mGL->fDeleteRenderbuffers(1, &mRB);
+}
+
+/* ScopedBindTexture **********************************************************/
+
+static GLuint
+GetBoundTexture(GLContext* gl, GLenum texTarget)
+{
+ GLenum bindingTarget;
+ switch (texTarget) {
+ case LOCAL_GL_TEXTURE_2D:
+ bindingTarget = LOCAL_GL_TEXTURE_BINDING_2D;
+ break;
+
+ case LOCAL_GL_TEXTURE_CUBE_MAP:
+ bindingTarget = LOCAL_GL_TEXTURE_BINDING_CUBE_MAP;
+ break;
+
+ case LOCAL_GL_TEXTURE_3D:
+ bindingTarget = LOCAL_GL_TEXTURE_BINDING_3D;
+ break;
+
+ case LOCAL_GL_TEXTURE_2D_ARRAY:
+ bindingTarget = LOCAL_GL_TEXTURE_BINDING_2D_ARRAY;
+ break;
+
+ case LOCAL_GL_TEXTURE_RECTANGLE_ARB:
+ bindingTarget = LOCAL_GL_TEXTURE_BINDING_RECTANGLE_ARB;
+ break;
+
+ case LOCAL_GL_TEXTURE_EXTERNAL:
+ bindingTarget = LOCAL_GL_TEXTURE_BINDING_EXTERNAL;
+ break;
+
+ default:
+ MOZ_CRASH("bad texTarget");
+ }
+
+ GLuint ret = 0;
+ gl->GetUIntegerv(bindingTarget, &ret);
+ return ret;
+}
+
+ScopedBindTexture::ScopedBindTexture(GLContext* aGL, GLuint aNewTex, GLenum aTarget)
+ : ScopedGLWrapper<ScopedBindTexture>(aGL)
+ , mTarget(aTarget)
+ , mOldTex(GetBoundTexture(aGL, aTarget))
+{
+ mGL->fBindTexture(mTarget, aNewTex);
+}
+
+void
+ScopedBindTexture::UnwrapImpl()
+{
+ mGL->fBindTexture(mTarget, mOldTex);
+}
+
+
+/* ScopedBindRenderbuffer *****************************************************/
+
+void
+ScopedBindRenderbuffer::Init()
+{
+ mOldRB = 0;
+ mGL->GetUIntegerv(LOCAL_GL_RENDERBUFFER_BINDING, &mOldRB);
+}
+
+ScopedBindRenderbuffer::ScopedBindRenderbuffer(GLContext* aGL)
+ : ScopedGLWrapper<ScopedBindRenderbuffer>(aGL)
+{
+ Init();
+}
+
+ScopedBindRenderbuffer::ScopedBindRenderbuffer(GLContext* aGL, GLuint aNewRB)
+ : ScopedGLWrapper<ScopedBindRenderbuffer>(aGL)
+{
+ Init();
+ mGL->fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, aNewRB);
+}
+
+void
+ScopedBindRenderbuffer::UnwrapImpl()
+{
+ mGL->fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, mOldRB);
+}
+
+
+/* ScopedFramebufferForTexture ************************************************/
+ScopedFramebufferForTexture::ScopedFramebufferForTexture(GLContext* aGL,
+ GLuint aTexture,
+ GLenum aTarget)
+ : ScopedGLWrapper<ScopedFramebufferForTexture>(aGL)
+ , mComplete(false)
+ , mFB(0)
+{
+ mGL->fGenFramebuffers(1, &mFB);
+ ScopedBindFramebuffer autoFB(aGL, mFB);
+ mGL->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
+ LOCAL_GL_COLOR_ATTACHMENT0,
+ aTarget,
+ aTexture,
+ 0);
+
+ GLenum status = mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
+ if (status == LOCAL_GL_FRAMEBUFFER_COMPLETE) {
+ mComplete = true;
+ } else {
+ mGL->fDeleteFramebuffers(1, &mFB);
+ mFB = 0;
+ }
+}
+
+void ScopedFramebufferForTexture::UnwrapImpl()
+{
+ if (!mFB)
+ return;
+
+ mGL->fDeleteFramebuffers(1, &mFB);
+ mFB = 0;
+}
+
+
+/* ScopedFramebufferForRenderbuffer *******************************************/
+
+
+ScopedFramebufferForRenderbuffer::ScopedFramebufferForRenderbuffer(GLContext* aGL,
+ GLuint aRB)
+ : ScopedGLWrapper<ScopedFramebufferForRenderbuffer>(aGL)
+ , mComplete(false)
+ , mFB(0)
+{
+ mGL->fGenFramebuffers(1, &mFB);
+ ScopedBindFramebuffer autoFB(aGL, mFB);
+ mGL->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
+ LOCAL_GL_COLOR_ATTACHMENT0,
+ LOCAL_GL_RENDERBUFFER,
+ aRB);
+
+ GLenum status = mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
+ if (status == LOCAL_GL_FRAMEBUFFER_COMPLETE) {
+ mComplete = true;
+ } else {
+ mGL->fDeleteFramebuffers(1, &mFB);
+ mFB = 0;
+ }
+}
+
+void
+ScopedFramebufferForRenderbuffer::UnwrapImpl()
+{
+ if (!mFB)
+ return;
+
+ mGL->fDeleteFramebuffers(1, &mFB);
+ mFB = 0;
+}
+
+/* ScopedViewportRect *********************************************************/
+
+ScopedViewportRect::ScopedViewportRect(GLContext* aGL,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height)
+ : ScopedGLWrapper<ScopedViewportRect>(aGL)
+{
+ mGL->fGetIntegerv(LOCAL_GL_VIEWPORT, mSavedViewportRect);
+ mGL->fViewport(x, y, width, height);
+}
+
+void ScopedViewportRect::UnwrapImpl()
+{
+ mGL->fViewport(mSavedViewportRect[0],
+ mSavedViewportRect[1],
+ mSavedViewportRect[2],
+ mSavedViewportRect[3]);
+}
+
+/* ScopedScissorRect **********************************************************/
+
+ScopedScissorRect::ScopedScissorRect(GLContext* aGL,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height)
+ : ScopedGLWrapper<ScopedScissorRect>(aGL)
+{
+ mGL->fGetIntegerv(LOCAL_GL_SCISSOR_BOX, mSavedScissorRect);
+ mGL->fScissor(x, y, width, height);
+}
+
+ScopedScissorRect::ScopedScissorRect(GLContext* aGL)
+ : ScopedGLWrapper<ScopedScissorRect>(aGL)
+{
+ mGL->fGetIntegerv(LOCAL_GL_SCISSOR_BOX, mSavedScissorRect);
+}
+
+void ScopedScissorRect::UnwrapImpl()
+{
+ mGL->fScissor(mSavedScissorRect[0],
+ mSavedScissorRect[1],
+ mSavedScissorRect[2],
+ mSavedScissorRect[3]);
+}
+
+/* ScopedVertexAttribPointer **************************************************/
+
+ScopedVertexAttribPointer::ScopedVertexAttribPointer(GLContext* aGL,
+ GLuint index,
+ GLint size,
+ GLenum type,
+ realGLboolean normalized,
+ GLsizei stride,
+ GLuint buffer,
+ const GLvoid* pointer)
+ : ScopedGLWrapper<ScopedVertexAttribPointer>(aGL)
+{
+ WrapImpl(index);
+ mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, buffer);
+ mGL->fVertexAttribPointer(index, size, type, normalized, stride, pointer);
+ mGL->fEnableVertexAttribArray(index);
+}
+
+ScopedVertexAttribPointer::ScopedVertexAttribPointer(GLContext* aGL,
+ GLuint index)
+ : ScopedGLWrapper<ScopedVertexAttribPointer>(aGL)
+{
+ WrapImpl(index);
+}
+
+void
+ScopedVertexAttribPointer::WrapImpl(GLuint index)
+{
+ mAttribIndex = index;
+
+ /*
+ * mGL->fGetVertexAttribiv takes:
+ * VERTEX_ATTRIB_ARRAY_ENABLED
+ * VERTEX_ATTRIB_ARRAY_SIZE,
+ * VERTEX_ATTRIB_ARRAY_STRIDE,
+ * VERTEX_ATTRIB_ARRAY_TYPE,
+ * VERTEX_ATTRIB_ARRAY_NORMALIZED,
+ * VERTEX_ATTRIB_ARRAY_BUFFER_BINDING,
+ * CURRENT_VERTEX_ATTRIB
+ *
+ * CURRENT_VERTEX_ATTRIB is vertex shader state. \o/
+ * Others appear to be vertex array state,
+ * or alternatively in the internal vertex array state
+ * for a buffer object.
+ */
+
+ mGL->fGetVertexAttribiv(mAttribIndex, LOCAL_GL_VERTEX_ATTRIB_ARRAY_ENABLED, &mAttribEnabled);
+ mGL->fGetVertexAttribiv(mAttribIndex, LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE, &mAttribSize);
+ mGL->fGetVertexAttribiv(mAttribIndex, LOCAL_GL_VERTEX_ATTRIB_ARRAY_STRIDE, &mAttribStride);
+ mGL->fGetVertexAttribiv(mAttribIndex, LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE, &mAttribType);
+ mGL->fGetVertexAttribiv(mAttribIndex, LOCAL_GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &mAttribNormalized);
+ mGL->fGetVertexAttribiv(mAttribIndex, LOCAL_GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &mAttribBufferBinding);
+ mGL->fGetVertexAttribPointerv(mAttribIndex, LOCAL_GL_VERTEX_ATTRIB_ARRAY_POINTER, &mAttribPointer);
+
+ // Note that uniform values are program state, so we don't need to rebind those.
+
+ mGL->GetUIntegerv(LOCAL_GL_ARRAY_BUFFER_BINDING, &mBoundBuffer);
+}
+
+void
+ScopedVertexAttribPointer::UnwrapImpl()
+{
+ mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mAttribBufferBinding);
+ mGL->fVertexAttribPointer(mAttribIndex, mAttribSize, mAttribType, mAttribNormalized, mAttribStride, mAttribPointer);
+ if (mAttribEnabled)
+ mGL->fEnableVertexAttribArray(mAttribIndex);
+ else
+ mGL->fDisableVertexAttribArray(mAttribIndex);
+ mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mBoundBuffer);
+}
+
+ScopedGLDrawState::ScopedGLDrawState(GLContext* aGL)
+ : blend (aGL, LOCAL_GL_BLEND, false)
+ , cullFace (aGL, LOCAL_GL_CULL_FACE, false)
+ , depthTest (aGL, LOCAL_GL_DEPTH_TEST, false)
+ , dither (aGL, LOCAL_GL_DITHER, false)
+ , polyOffsFill(aGL, LOCAL_GL_POLYGON_OFFSET_FILL, false)
+ , sampleAToC (aGL, LOCAL_GL_SAMPLE_ALPHA_TO_COVERAGE, false)
+ , sampleCover (aGL, LOCAL_GL_SAMPLE_COVERAGE, false)
+ , scissor (aGL, LOCAL_GL_SCISSOR_TEST, false)
+ , stencil (aGL, LOCAL_GL_STENCIL_TEST, false)
+ , mGL(aGL)
+{
+ mGL->GetUIntegerv(LOCAL_GL_CURRENT_PROGRAM, &boundProgram);
+ mGL->GetUIntegerv(LOCAL_GL_ARRAY_BUFFER_BINDING, &boundBuffer);
+ mGL->GetUIntegerv(LOCAL_GL_MAX_VERTEX_ATTRIBS, &maxAttrib);
+ attrib_enabled = MakeUnique<GLint[]>(maxAttrib);
+
+ for (GLuint i = 0; i < maxAttrib; i++) {
+ mGL->fGetVertexAttribiv(i, LOCAL_GL_VERTEX_ATTRIB_ARRAY_ENABLED, &attrib_enabled[i]);
+ mGL->fDisableVertexAttribArray(i);
+ }
+ // Only Attrib0's client side state affected
+ mGL->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE, &attrib0_size);
+ mGL->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_STRIDE, &attrib0_stride);
+ mGL->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE, &attrib0_type);
+ mGL->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &attrib0_normalized);
+ mGL->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &attrib0_bufferBinding);
+ mGL->fGetVertexAttribPointerv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_POINTER, &attrib0_pointer);
+ mGL->fGetBooleanv(LOCAL_GL_COLOR_WRITEMASK, colorMask);
+ mGL->fGetIntegerv(LOCAL_GL_VIEWPORT, viewport);
+ mGL->fGetIntegerv(LOCAL_GL_SCISSOR_BOX, scissorBox);
+}
+
+ScopedGLDrawState::~ScopedGLDrawState()
+{
+ MOZ_ASSERT(mGL->IsCurrent());
+
+ mGL->fScissor(scissorBox[0], scissorBox[1],
+ scissorBox[2], scissorBox[3]);
+
+ mGL->fViewport(viewport[0], viewport[1],
+ viewport[2], viewport[3]);
+
+ mGL->fColorMask(colorMask[0],
+ colorMask[1],
+ colorMask[2],
+ colorMask[3]);
+
+ for (unsigned int i = 0; i < maxAttrib; i++) {
+ if (attrib_enabled[i])
+ mGL->fEnableVertexAttribArray(i);
+ else
+ mGL->fDisableVertexAttribArray(i);
+ }
+
+
+ mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, attrib0_bufferBinding);
+ mGL->fVertexAttribPointer(0,
+ attrib0_size,
+ attrib0_type,
+ attrib0_normalized,
+ attrib0_stride,
+ attrib0_pointer);
+
+ mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, boundBuffer);
+
+ mGL->fUseProgram(boundProgram);
+}
+
+////////////////////////////////////////////////////////////////////////
+// ScopedPackState
+
+static bool
+HasPBOState(const GLContext* gl)
+{
+ return (!gl->IsGLES() || gl->Version() >= 300);
+}
+
+ScopedPackState::ScopedPackState(GLContext* gl)
+ : ScopedGLWrapper<ScopedPackState>(gl)
+{
+ mGL->fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, &mAlignment);
+
+ if (mAlignment != 4) mGL->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, 4);
+
+ if (!HasPBOState(mGL))
+ return;
+
+ mGL->fGetIntegerv(LOCAL_GL_PIXEL_PACK_BUFFER_BINDING, (GLint*)&mPixelBuffer);
+ mGL->fGetIntegerv(LOCAL_GL_PACK_ROW_LENGTH, &mRowLength);
+ mGL->fGetIntegerv(LOCAL_GL_PACK_SKIP_PIXELS, &mSkipPixels);
+ mGL->fGetIntegerv(LOCAL_GL_PACK_SKIP_ROWS, &mSkipRows);
+
+ if (mPixelBuffer != 0) mGL->fBindBuffer(LOCAL_GL_PIXEL_PACK_BUFFER, 0);
+ if (mRowLength != 0) mGL->fPixelStorei(LOCAL_GL_PACK_ROW_LENGTH, 0);
+ if (mSkipPixels != 0) mGL->fPixelStorei(LOCAL_GL_PACK_SKIP_PIXELS, 0);
+ if (mSkipRows != 0) mGL->fPixelStorei(LOCAL_GL_PACK_SKIP_ROWS, 0);
+}
+
+void
+ScopedPackState::UnwrapImpl()
+{
+ mGL->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, mAlignment);
+
+ if (!HasPBOState(mGL))
+ return;
+
+ mGL->fBindBuffer(LOCAL_GL_PIXEL_PACK_BUFFER, mPixelBuffer);
+ mGL->fPixelStorei(LOCAL_GL_PACK_ROW_LENGTH, mRowLength);
+ mGL->fPixelStorei(LOCAL_GL_PACK_SKIP_PIXELS, mSkipPixels);
+ mGL->fPixelStorei(LOCAL_GL_PACK_SKIP_ROWS, mSkipRows);
+}
+
+} /* namespace gl */
+} /* namespace mozilla */
diff --git a/gfx/gl/ScopedGLHelpers.h b/gfx/gl/ScopedGLHelpers.h
new file mode 100644
index 0000000000..f0a91c69ab
--- /dev/null
+++ b/gfx/gl/ScopedGLHelpers.h
@@ -0,0 +1,368 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef SCOPEDGLHELPERS_H_
+#define SCOPEDGLHELPERS_H_
+
+#include "GLDefs.h"
+#include "mozilla/UniquePtr.h"
+
+namespace mozilla {
+namespace gl {
+
+class GLContext;
+
+#ifdef DEBUG
+bool IsContextCurrent(GLContext* gl);
+#endif
+
+//RAII via CRTP!
+template <class Derived>
+struct ScopedGLWrapper
+{
+private:
+ bool mIsUnwrapped;
+
+protected:
+ GLContext* const mGL;
+
+ explicit ScopedGLWrapper(GLContext* gl)
+ : mIsUnwrapped(false)
+ , mGL(gl)
+ {
+ MOZ_ASSERT(&ScopedGLWrapper<Derived>::Unwrap == &Derived::Unwrap);
+ MOZ_ASSERT(&Derived::UnwrapImpl);
+ MOZ_ASSERT(IsContextCurrent(mGL));
+ }
+
+ virtual ~ScopedGLWrapper() {
+ if (!mIsUnwrapped)
+ Unwrap();
+ }
+
+public:
+ void Unwrap() {
+ MOZ_ASSERT(!mIsUnwrapped);
+ MOZ_ASSERT(IsContextCurrent(mGL));
+
+ Derived* derived = static_cast<Derived*>(this);
+ derived->UnwrapImpl();
+
+ mIsUnwrapped = true;
+ }
+};
+
+// Wraps glEnable/Disable.
+struct ScopedGLState
+ : public ScopedGLWrapper<ScopedGLState>
+{
+ friend struct ScopedGLWrapper<ScopedGLState>;
+
+protected:
+ const GLenum mCapability;
+ bool mOldState;
+
+public:
+ // Use |newState = true| to enable, |false| to disable.
+ ScopedGLState(GLContext* aGL, GLenum aCapability, bool aNewState);
+ // variant that doesn't change state; simply records existing state to be
+ // restored by the destructor
+ ScopedGLState(GLContext* aGL, GLenum aCapability);
+
+protected:
+ void UnwrapImpl();
+};
+
+// Saves and restores with GetUserBoundFB and BindUserFB.
+struct ScopedBindFramebuffer
+ : public ScopedGLWrapper<ScopedBindFramebuffer>
+{
+ friend struct ScopedGLWrapper<ScopedBindFramebuffer>;
+
+protected:
+ GLuint mOldReadFB;
+ GLuint mOldDrawFB;
+
+private:
+ void Init();
+
+public:
+ explicit ScopedBindFramebuffer(GLContext* aGL);
+ ScopedBindFramebuffer(GLContext* aGL, GLuint aNewFB);
+
+protected:
+ void UnwrapImpl();
+};
+
+struct ScopedBindTextureUnit
+ : public ScopedGLWrapper<ScopedBindTextureUnit>
+{
+ friend struct ScopedGLWrapper<ScopedBindTextureUnit>;
+
+protected:
+ GLenum mOldTexUnit;
+
+public:
+ ScopedBindTextureUnit(GLContext* aGL, GLenum aTexUnit);
+
+protected:
+ void UnwrapImpl();
+};
+
+
+struct ScopedTexture
+ : public ScopedGLWrapper<ScopedTexture>
+{
+ friend struct ScopedGLWrapper<ScopedTexture>;
+
+protected:
+ GLuint mTexture;
+
+public:
+ explicit ScopedTexture(GLContext* aGL);
+ GLuint Texture() { return mTexture; }
+
+protected:
+ void UnwrapImpl();
+};
+
+
+struct ScopedFramebuffer
+ : public ScopedGLWrapper<ScopedFramebuffer>
+{
+ friend struct ScopedGLWrapper<ScopedFramebuffer>;
+
+protected:
+ GLuint mFB;
+
+public:
+ explicit ScopedFramebuffer(GLContext* aGL);
+ GLuint FB() { return mFB; }
+
+protected:
+ void UnwrapImpl();
+};
+
+
+struct ScopedRenderbuffer
+ : public ScopedGLWrapper<ScopedRenderbuffer>
+{
+ friend struct ScopedGLWrapper<ScopedRenderbuffer>;
+
+protected:
+ GLuint mRB;
+
+public:
+ explicit ScopedRenderbuffer(GLContext* aGL);
+ GLuint RB() { return mRB; }
+
+protected:
+ void UnwrapImpl();
+};
+
+
+struct ScopedBindTexture
+ : public ScopedGLWrapper<ScopedBindTexture>
+{
+ friend struct ScopedGLWrapper<ScopedBindTexture>;
+
+protected:
+ const GLenum mTarget;
+ const GLuint mOldTex;
+
+public:
+ ScopedBindTexture(GLContext* aGL, GLuint aNewTex,
+ GLenum aTarget = LOCAL_GL_TEXTURE_2D);
+
+protected:
+ void UnwrapImpl();
+};
+
+
+struct ScopedBindRenderbuffer
+ : public ScopedGLWrapper<ScopedBindRenderbuffer>
+{
+ friend struct ScopedGLWrapper<ScopedBindRenderbuffer>;
+
+protected:
+ GLuint mOldRB;
+
+private:
+ void Init();
+
+public:
+ explicit ScopedBindRenderbuffer(GLContext* aGL);
+
+ ScopedBindRenderbuffer(GLContext* aGL, GLuint aNewRB);
+
+protected:
+ void UnwrapImpl();
+};
+
+
+struct ScopedFramebufferForTexture
+ : public ScopedGLWrapper<ScopedFramebufferForTexture>
+{
+ friend struct ScopedGLWrapper<ScopedFramebufferForTexture>;
+
+protected:
+ bool mComplete; // True if the framebuffer we create is complete.
+ GLuint mFB;
+
+public:
+ ScopedFramebufferForTexture(GLContext* aGL, GLuint aTexture,
+ GLenum aTarget = LOCAL_GL_TEXTURE_2D);
+
+ bool IsComplete() const {
+ return mComplete;
+ }
+
+ GLuint FB() const {
+ MOZ_ASSERT(IsComplete());
+ return mFB;
+ }
+
+protected:
+ void UnwrapImpl();
+};
+
+struct ScopedFramebufferForRenderbuffer
+ : public ScopedGLWrapper<ScopedFramebufferForRenderbuffer>
+{
+ friend struct ScopedGLWrapper<ScopedFramebufferForRenderbuffer>;
+
+protected:
+ bool mComplete; // True if the framebuffer we create is complete.
+ GLuint mFB;
+
+public:
+ ScopedFramebufferForRenderbuffer(GLContext* aGL, GLuint aRB);
+
+ bool IsComplete() const {
+ return mComplete;
+ }
+
+ GLuint FB() const {
+ return mFB;
+ }
+
+protected:
+ void UnwrapImpl();
+};
+
+struct ScopedViewportRect
+ : public ScopedGLWrapper<ScopedViewportRect>
+{
+ friend struct ScopedGLWrapper<ScopedViewportRect>;
+
+protected:
+ GLint mSavedViewportRect[4];
+
+public:
+ ScopedViewportRect(GLContext* aGL, GLint x, GLint y, GLsizei width, GLsizei height);
+
+protected:
+ void UnwrapImpl();
+};
+
+struct ScopedScissorRect
+ : public ScopedGLWrapper<ScopedScissorRect>
+{
+ friend struct ScopedGLWrapper<ScopedScissorRect>;
+
+protected:
+ GLint mSavedScissorRect[4];
+
+public:
+ ScopedScissorRect(GLContext* aGL, GLint x, GLint y, GLsizei width, GLsizei height);
+ explicit ScopedScissorRect(GLContext* aGL);
+
+protected:
+ void UnwrapImpl();
+};
+
+struct ScopedVertexAttribPointer
+ : public ScopedGLWrapper<ScopedVertexAttribPointer>
+{
+ friend struct ScopedGLWrapper<ScopedVertexAttribPointer>;
+
+protected:
+ GLuint mAttribIndex;
+ GLint mAttribEnabled;
+ GLint mAttribSize;
+ GLint mAttribStride;
+ GLint mAttribType;
+ GLint mAttribNormalized;
+ GLint mAttribBufferBinding;
+ void* mAttribPointer;
+ GLuint mBoundBuffer;
+
+public:
+ ScopedVertexAttribPointer(GLContext* aGL, GLuint index, GLint size, GLenum type, realGLboolean normalized,
+ GLsizei stride, GLuint buffer, const GLvoid* pointer);
+ explicit ScopedVertexAttribPointer(GLContext* aGL, GLuint index);
+
+protected:
+ void WrapImpl(GLuint index);
+ void UnwrapImpl();
+};
+
+struct ScopedGLDrawState
+{
+ explicit ScopedGLDrawState(GLContext* gl);
+ ~ScopedGLDrawState();
+
+ GLuint boundProgram;
+ GLuint boundBuffer;
+
+ ScopedGLState blend;
+ ScopedGLState cullFace;
+ ScopedGLState depthTest;
+ ScopedGLState dither;
+ ScopedGLState polyOffsFill;
+ ScopedGLState sampleAToC;
+ ScopedGLState sampleCover;
+ ScopedGLState scissor;
+ ScopedGLState stencil;
+
+ GLuint maxAttrib;
+ UniquePtr<GLint[]> attrib_enabled;
+ GLint attrib0_size;
+ GLint attrib0_stride;
+ GLint attrib0_type;
+ GLint attrib0_normalized;
+ GLint attrib0_bufferBinding;
+ void* attrib0_pointer;
+
+ realGLboolean colorMask[4];
+ GLint viewport[4];
+ GLint scissorBox[4];
+ GLContext* const mGL;
+};
+
+struct ScopedPackState
+ : public ScopedGLWrapper<ScopedPackState>
+{
+ friend struct ScopedGLWrapper<ScopedPackState>;
+
+protected:
+ GLint mAlignment;
+
+ GLuint mPixelBuffer;
+ GLint mRowLength;
+ GLint mSkipPixels;
+ GLint mSkipRows;
+
+public:
+ explicit ScopedPackState(GLContext* gl);
+
+protected:
+ void UnwrapImpl();
+};
+
+} /* namespace gl */
+} /* namespace mozilla */
+
+#endif /* SCOPEDGLHELPERS_H_ */
diff --git a/gfx/gl/SharedSurface.cpp b/gfx/gl/SharedSurface.cpp
new file mode 100644
index 0000000000..fa1d19172f
--- /dev/null
+++ b/gfx/gl/SharedSurface.cpp
@@ -0,0 +1,621 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "SharedSurface.h"
+
+#include "../2d/2D.h"
+#include "GLBlitHelper.h"
+#include "GLContext.h"
+#include "GLReadTexImageHelper.h"
+#include "GLScreenBuffer.h"
+#include "nsThreadUtils.h"
+#include "ScopedGLHelpers.h"
+#include "SharedSurfaceGL.h"
+#include "mozilla/layers/CompositorTypes.h"
+#include "mozilla/layers/TextureClientSharedSurface.h"
+#include "mozilla/layers/TextureForwarder.h"
+#include "mozilla/Unused.h"
+
+namespace mozilla {
+namespace gl {
+
+/*static*/ void
+SharedSurface::ProdCopy(SharedSurface* src, SharedSurface* dest,
+ SurfaceFactory* factory)
+{
+ GLContext* gl = src->mGL;
+
+ // If `src` begins locked, it must end locked, though we may
+ // temporarily unlock it if we need to.
+ MOZ_ASSERT((src == gl->GetLockedSurface()) == src->IsLocked());
+
+ gl->MakeCurrent();
+
+ if (src->mAttachType == AttachmentType::Screen &&
+ dest->mAttachType == AttachmentType::Screen)
+ {
+ // Here, we actually need to blit through a temp surface, so let's make one.
+ UniquePtr<SharedSurface_Basic> tempSurf;
+ tempSurf = SharedSurface_Basic::Create(gl, factory->mFormats, src->mSize,
+ factory->mCaps.alpha);
+
+ ProdCopy(src, tempSurf.get(), factory);
+ ProdCopy(tempSurf.get(), dest, factory);
+ return;
+ }
+
+ if (src->mAttachType == AttachmentType::Screen) {
+ SharedSurface* origLocked = gl->GetLockedSurface();
+ bool srcNeedsUnlock = false;
+ bool origNeedsRelock = false;
+ if (origLocked != src) {
+ if (origLocked) {
+ origLocked->UnlockProd();
+ origNeedsRelock = true;
+ }
+
+ src->LockProd();
+ srcNeedsUnlock = true;
+ }
+
+ if (dest->mAttachType == AttachmentType::GLTexture) {
+ GLuint destTex = dest->ProdTexture();
+ GLenum destTarget = dest->ProdTextureTarget();
+
+ gl->BlitHelper()->BlitFramebufferToTexture(0, destTex,
+ src->mSize,
+ dest->mSize,
+ destTarget,
+ true);
+ } else if (dest->mAttachType == AttachmentType::GLRenderbuffer) {
+ GLuint destRB = dest->ProdRenderbuffer();
+ ScopedFramebufferForRenderbuffer destWrapper(gl, destRB);
+
+ gl->BlitHelper()->BlitFramebufferToFramebuffer(0,
+ destWrapper.FB(),
+ src->mSize,
+ dest->mSize,
+ true);
+ } else {
+ MOZ_CRASH("GFX: Unhandled dest->mAttachType 1.");
+ }
+
+ if (srcNeedsUnlock)
+ src->UnlockProd();
+
+ if (origNeedsRelock)
+ origLocked->LockProd();
+
+ return;
+ }
+
+ if (dest->mAttachType == AttachmentType::Screen) {
+ SharedSurface* origLocked = gl->GetLockedSurface();
+ bool destNeedsUnlock = false;
+ bool origNeedsRelock = false;
+ if (origLocked != dest) {
+ if (origLocked) {
+ origLocked->UnlockProd();
+ origNeedsRelock = true;
+ }
+
+ dest->LockProd();
+ destNeedsUnlock = true;
+ }
+
+ if (src->mAttachType == AttachmentType::GLTexture) {
+ GLuint srcTex = src->ProdTexture();
+ GLenum srcTarget = src->ProdTextureTarget();
+
+ gl->BlitHelper()->BlitTextureToFramebuffer(srcTex, 0,
+ src->mSize,
+ dest->mSize,
+ srcTarget,
+ true);
+ } else if (src->mAttachType == AttachmentType::GLRenderbuffer) {
+ GLuint srcRB = src->ProdRenderbuffer();
+ ScopedFramebufferForRenderbuffer srcWrapper(gl, srcRB);
+
+ gl->BlitHelper()->BlitFramebufferToFramebuffer(srcWrapper.FB(),
+ 0,
+ src->mSize,
+ dest->mSize,
+ true);
+ } else {
+ MOZ_CRASH("GFX: Unhandled src->mAttachType 2.");
+ }
+
+ if (destNeedsUnlock)
+ dest->UnlockProd();
+
+ if (origNeedsRelock)
+ origLocked->LockProd();
+
+ return;
+ }
+
+ // Alright, done with cases involving Screen types.
+ // Only {src,dest}x{texture,renderbuffer} left.
+
+ if (src->mAttachType == AttachmentType::GLTexture) {
+ GLuint srcTex = src->ProdTexture();
+ GLenum srcTarget = src->ProdTextureTarget();
+
+ if (dest->mAttachType == AttachmentType::GLTexture) {
+ GLuint destTex = dest->ProdTexture();
+ GLenum destTarget = dest->ProdTextureTarget();
+
+ gl->BlitHelper()->BlitTextureToTexture(srcTex, destTex,
+ src->mSize, dest->mSize,
+ srcTarget, destTarget);
+
+ return;
+ }
+
+ if (dest->mAttachType == AttachmentType::GLRenderbuffer) {
+ GLuint destRB = dest->ProdRenderbuffer();
+ ScopedFramebufferForRenderbuffer destWrapper(gl, destRB);
+
+ gl->BlitHelper()->BlitTextureToFramebuffer(srcTex, destWrapper.FB(),
+ src->mSize, dest->mSize, srcTarget);
+
+ return;
+ }
+
+ MOZ_CRASH("GFX: Unhandled dest->mAttachType 3.");
+ }
+
+ if (src->mAttachType == AttachmentType::GLRenderbuffer) {
+ GLuint srcRB = src->ProdRenderbuffer();
+ ScopedFramebufferForRenderbuffer srcWrapper(gl, srcRB);
+
+ if (dest->mAttachType == AttachmentType::GLTexture) {
+ GLuint destTex = dest->ProdTexture();
+ GLenum destTarget = dest->ProdTextureTarget();
+
+ gl->BlitHelper()->BlitFramebufferToTexture(srcWrapper.FB(), destTex,
+ src->mSize, dest->mSize, destTarget);
+
+ return;
+ }
+
+ if (dest->mAttachType == AttachmentType::GLRenderbuffer) {
+ GLuint destRB = dest->ProdRenderbuffer();
+ ScopedFramebufferForRenderbuffer destWrapper(gl, destRB);
+
+ gl->BlitHelper()->BlitFramebufferToFramebuffer(srcWrapper.FB(), destWrapper.FB(),
+ src->mSize, dest->mSize);
+
+ return;
+ }
+
+ MOZ_CRASH("GFX: Unhandled dest->mAttachType 4.");
+ }
+
+ MOZ_CRASH("GFX: Unhandled src->mAttachType 5.");
+}
+
+////////////////////////////////////////////////////////////////////////
+// SharedSurface
+
+
+SharedSurface::SharedSurface(SharedSurfaceType type,
+ AttachmentType attachType,
+ GLContext* gl,
+ const gfx::IntSize& size,
+ bool hasAlpha,
+ bool canRecycle)
+ : mType(type)
+ , mAttachType(attachType)
+ , mGL(gl)
+ , mSize(size)
+ , mHasAlpha(hasAlpha)
+ , mCanRecycle(canRecycle)
+ , mIsLocked(false)
+ , mIsProducerAcquired(false)
+#ifdef DEBUG
+ , mOwningThread(NS_GetCurrentThread())
+#endif
+{ }
+
+layers::TextureFlags
+SharedSurface::GetTextureFlags() const
+{
+ return layers::TextureFlags::NO_FLAGS;
+}
+
+void
+SharedSurface::LockProd()
+{
+ MOZ_ASSERT(!mIsLocked);
+
+ LockProdImpl();
+
+ mGL->LockSurface(this);
+ mIsLocked = true;
+}
+
+void
+SharedSurface::UnlockProd()
+{
+ if (!mIsLocked)
+ return;
+
+ UnlockProdImpl();
+
+ mGL->UnlockSurface(this);
+ mIsLocked = false;
+}
+
+////////////////////////////////////////////////////////////////////////
+// SurfaceFactory
+
+static void
+ChooseBufferBits(const SurfaceCaps& caps,
+ SurfaceCaps* const out_drawCaps,
+ SurfaceCaps* const out_readCaps)
+{
+ MOZ_ASSERT(out_drawCaps);
+ MOZ_ASSERT(out_readCaps);
+
+ SurfaceCaps screenCaps;
+
+ screenCaps.color = caps.color;
+ screenCaps.alpha = caps.alpha;
+ screenCaps.bpp16 = caps.bpp16;
+
+ screenCaps.depth = caps.depth;
+ screenCaps.stencil = caps.stencil;
+
+ screenCaps.antialias = caps.antialias;
+ screenCaps.preserve = caps.preserve;
+
+ if (caps.antialias) {
+ *out_drawCaps = screenCaps;
+ out_readCaps->Clear();
+
+ // Color caps need to be duplicated in readCaps.
+ out_readCaps->color = caps.color;
+ out_readCaps->alpha = caps.alpha;
+ out_readCaps->bpp16 = caps.bpp16;
+ } else {
+ out_drawCaps->Clear();
+ *out_readCaps = screenCaps;
+ }
+}
+
+SurfaceFactory::SurfaceFactory(SharedSurfaceType type, GLContext* gl,
+ const SurfaceCaps& caps,
+ const RefPtr<layers::LayersIPCChannel>& allocator,
+ const layers::TextureFlags& flags)
+ : mType(type)
+ , mGL(gl)
+ , mCaps(caps)
+ , mAllocator(allocator)
+ , mFlags(flags)
+ , mFormats(gl->ChooseGLFormats(caps))
+ , mMutex("SurfaceFactor::mMutex")
+{
+ ChooseBufferBits(mCaps, &mDrawCaps, &mReadCaps);
+}
+
+SurfaceFactory::~SurfaceFactory()
+{
+ while (!mRecycleTotalPool.empty()) {
+ RefPtr<layers::SharedSurfaceTextureClient> tex = *mRecycleTotalPool.begin();
+ StopRecycling(tex);
+ tex->CancelWaitForRecycle();
+ }
+
+ MOZ_RELEASE_ASSERT(mRecycleTotalPool.empty(),"GFX: Surface recycle pool not empty.");
+
+ // If we mRecycleFreePool.clear() before StopRecycling(), we may try to recycle it,
+ // fail, call StopRecycling(), then return here and call it again.
+ mRecycleFreePool.clear();
+}
+
+already_AddRefed<layers::SharedSurfaceTextureClient>
+SurfaceFactory::NewTexClient(const gfx::IntSize& size)
+{
+ while (!mRecycleFreePool.empty()) {
+ RefPtr<layers::SharedSurfaceTextureClient> cur = mRecycleFreePool.front();
+ mRecycleFreePool.pop();
+
+ if (cur->Surf()->mSize == size) {
+ cur->Surf()->WaitForBufferOwnership();
+ return cur.forget();
+ }
+
+ StopRecycling(cur);
+ }
+
+ UniquePtr<SharedSurface> surf = Move(CreateShared(size));
+ if (!surf)
+ return nullptr;
+
+ RefPtr<layers::SharedSurfaceTextureClient> ret;
+ ret = layers::SharedSurfaceTextureClient::Create(Move(surf), this, mAllocator, mFlags);
+
+ StartRecycling(ret);
+
+ return ret.forget();
+}
+
+void
+SurfaceFactory::StartRecycling(layers::SharedSurfaceTextureClient* tc)
+{
+ tc->SetRecycleCallback(&SurfaceFactory::RecycleCallback, static_cast<void*>(this));
+
+ bool didInsert = mRecycleTotalPool.insert(tc);
+ MOZ_RELEASE_ASSERT(didInsert, "GFX: Shared surface texture client was not inserted to recycle.");
+ mozilla::Unused << didInsert;
+}
+
+void
+SurfaceFactory::StopRecycling(layers::SharedSurfaceTextureClient* tc)
+{
+ MutexAutoLock autoLock(mMutex);
+ // Must clear before releasing ref.
+ tc->ClearRecycleCallback();
+
+ bool didErase = mRecycleTotalPool.erase(tc);
+ MOZ_RELEASE_ASSERT(didErase, "GFX: Shared texture surface client was not erased.");
+ mozilla::Unused << didErase;
+}
+
+/*static*/ void
+SurfaceFactory::RecycleCallback(layers::TextureClient* rawTC, void* rawFactory)
+{
+ RefPtr<layers::SharedSurfaceTextureClient> tc;
+ tc = static_cast<layers::SharedSurfaceTextureClient*>(rawTC);
+ SurfaceFactory* factory = static_cast<SurfaceFactory*>(rawFactory);
+
+ if (tc->Surf()->mCanRecycle) {
+ if (factory->Recycle(tc))
+ return;
+ }
+
+ // Did not recover the tex client. End the (re)cycle!
+ factory->StopRecycling(tc);
+}
+
+bool
+SurfaceFactory::Recycle(layers::SharedSurfaceTextureClient* texClient)
+{
+ MOZ_ASSERT(texClient);
+ MutexAutoLock autoLock(mMutex);
+
+ if (mRecycleFreePool.size() >= 2) {
+ return false;
+ }
+
+ RefPtr<layers::SharedSurfaceTextureClient> texClientRef = texClient;
+ mRecycleFreePool.push(texClientRef);
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// ScopedReadbackFB
+
+ScopedReadbackFB::ScopedReadbackFB(SharedSurface* src)
+ : mGL(src->mGL)
+ , mAutoFB(mGL)
+ , mTempFB(0)
+ , mTempTex(0)
+ , mSurfToUnlock(nullptr)
+ , mSurfToLock(nullptr)
+{
+ switch (src->mAttachType) {
+ case AttachmentType::GLRenderbuffer:
+ {
+ mGL->fGenFramebuffers(1, &mTempFB);
+ mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mTempFB);
+
+ GLuint rb = src->ProdRenderbuffer();
+ mGL->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
+ LOCAL_GL_COLOR_ATTACHMENT0,
+ LOCAL_GL_RENDERBUFFER, rb);
+ break;
+ }
+ case AttachmentType::GLTexture:
+ {
+ mGL->fGenFramebuffers(1, &mTempFB);
+ mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mTempFB);
+
+ GLuint tex = src->ProdTexture();
+ GLenum texImageTarget = src->ProdTextureTarget();
+ mGL->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
+ LOCAL_GL_COLOR_ATTACHMENT0,
+ texImageTarget, tex, 0);
+ break;
+ }
+ case AttachmentType::Screen:
+ {
+ SharedSurface* origLocked = mGL->GetLockedSurface();
+ if (origLocked != src) {
+ if (origLocked) {
+ mSurfToLock = origLocked;
+ mSurfToLock->UnlockProd();
+ }
+
+ mSurfToUnlock = src;
+ mSurfToUnlock->LockProd();
+ }
+
+ // TODO: This should just be BindFB, but we don't have
+ // the patch for this yet. (bug 1045955)
+ MOZ_ASSERT(mGL->Screen());
+ mGL->Screen()->BindReadFB_Internal(0);
+ break;
+ }
+ default:
+ MOZ_CRASH("GFX: Unhandled `mAttachType`.");
+ }
+
+ if (src->NeedsIndirectReads()) {
+ mGL->fGenTextures(1, &mTempTex);
+
+ {
+ ScopedBindTexture autoTex(mGL, mTempTex);
+
+ GLenum format = src->mHasAlpha ? LOCAL_GL_RGBA
+ : LOCAL_GL_RGB;
+ auto width = src->mSize.width;
+ auto height = src->mSize.height;
+ mGL->fCopyTexImage2D(LOCAL_GL_TEXTURE_2D, 0, format, 0, 0, width,
+ height, 0);
+ }
+
+ mGL->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
+ LOCAL_GL_COLOR_ATTACHMENT0,
+ LOCAL_GL_TEXTURE_2D, mTempTex, 0);
+ }
+}
+
+ScopedReadbackFB::~ScopedReadbackFB()
+{
+ if (mTempFB) {
+ mGL->fDeleteFramebuffers(1, &mTempFB);
+ }
+ if (mTempTex) {
+ mGL->fDeleteTextures(1, &mTempTex);
+ }
+ if (mSurfToUnlock) {
+ mSurfToUnlock->UnlockProd();
+ }
+ if (mSurfToLock) {
+ mSurfToLock->LockProd();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+class AutoLockBits
+{
+ gfx::DrawTarget* mDT;
+ uint8_t* mLockedBits;
+
+public:
+ explicit AutoLockBits(gfx::DrawTarget* dt)
+ : mDT(dt)
+ , mLockedBits(nullptr)
+ {
+ MOZ_ASSERT(mDT);
+ }
+
+ bool Lock(uint8_t** data, gfx::IntSize* size, int32_t* stride,
+ gfx::SurfaceFormat* format)
+ {
+ if (!mDT->LockBits(data, size, stride, format))
+ return false;
+
+ mLockedBits = *data;
+ return true;
+ }
+
+ ~AutoLockBits() {
+ if (mLockedBits)
+ mDT->ReleaseBits(mLockedBits);
+ }
+};
+
+bool
+ReadbackSharedSurface(SharedSurface* src, gfx::DrawTarget* dst)
+{
+ AutoLockBits lock(dst);
+
+ uint8_t* dstBytes;
+ gfx::IntSize dstSize;
+ int32_t dstStride;
+ gfx::SurfaceFormat dstFormat;
+ if (!lock.Lock(&dstBytes, &dstSize, &dstStride, &dstFormat))
+ return false;
+
+ const bool isDstRGBA = (dstFormat == gfx::SurfaceFormat::R8G8B8A8 ||
+ dstFormat == gfx::SurfaceFormat::R8G8B8X8);
+ MOZ_ASSERT_IF(!isDstRGBA, dstFormat == gfx::SurfaceFormat::B8G8R8A8 ||
+ dstFormat == gfx::SurfaceFormat::B8G8R8X8);
+
+ size_t width = src->mSize.width;
+ size_t height = src->mSize.height;
+ MOZ_ASSERT(width == (size_t)dstSize.width);
+ MOZ_ASSERT(height == (size_t)dstSize.height);
+
+ GLenum readGLFormat;
+ GLenum readType;
+
+ {
+ ScopedReadbackFB autoReadback(src);
+
+
+ // We have a source FB, now we need a format.
+ GLenum dstGLFormat = isDstRGBA ? LOCAL_GL_BGRA : LOCAL_GL_RGBA;
+ GLenum dstType = LOCAL_GL_UNSIGNED_BYTE;
+
+ // We actually don't care if they match, since we can handle
+ // any read{Format,Type} we get.
+ GLContext* gl = src->mGL;
+ GetActualReadFormats(gl, dstGLFormat, dstType, &readGLFormat,
+ &readType);
+
+ MOZ_ASSERT(readGLFormat == LOCAL_GL_RGBA ||
+ readGLFormat == LOCAL_GL_BGRA);
+ MOZ_ASSERT(readType == LOCAL_GL_UNSIGNED_BYTE);
+
+ // ReadPixels from the current FB into lockedBits.
+ {
+ size_t alignment = 8;
+ if (dstStride % 4 == 0)
+ alignment = 4;
+
+ ScopedPackState scopedPackState(gl);
+ if (alignment != 4) {
+ gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, alignment);
+ }
+
+ gl->raw_fReadPixels(0, 0, width, height, readGLFormat, readType,
+ dstBytes);
+ }
+ }
+
+ const bool isReadRGBA = readGLFormat == LOCAL_GL_RGBA;
+
+ if (isReadRGBA != isDstRGBA) {
+ for (size_t j = 0; j < height; ++j) {
+ uint8_t* rowItr = dstBytes + j*dstStride;
+ uint8_t* rowEnd = rowItr + 4*width;
+ while (rowItr != rowEnd) {
+ Swap(rowItr[0], rowItr[2]);
+ rowItr += 4;
+ }
+ }
+ }
+
+ return true;
+}
+
+uint32_t
+ReadPixel(SharedSurface* src)
+{
+ GLContext* gl = src->mGL;
+
+ uint32_t pixel;
+
+ ScopedReadbackFB a(src);
+ {
+ ScopedPackState scopedPackState(gl);
+
+ UniquePtr<uint8_t[]> bytes(new uint8_t[4]);
+ gl->raw_fReadPixels(0, 0, 1, 1, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE,
+ bytes.get());
+ memcpy(&pixel, bytes.get(), 4);
+ }
+
+ return pixel;
+}
+
+} // namespace gl
+
+} /* namespace mozilla */
diff --git a/gfx/gl/SharedSurface.h b/gfx/gl/SharedSurface.h
new file mode 100644
index 0000000000..0cd21d1b7b
--- /dev/null
+++ b/gfx/gl/SharedSurface.h
@@ -0,0 +1,333 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* SharedSurface abstracts an actual surface (can be a GL texture, but
+ * not necessarily) that handles sharing.
+ * Its specializations are:
+ * SharedSurface_Basic (client-side bitmap, does readback)
+ * SharedSurface_GLTexture
+ * SharedSurface_EGLImage
+ * SharedSurface_ANGLEShareHandle
+ */
+
+#ifndef SHARED_SURFACE_H_
+#define SHARED_SURFACE_H_
+
+#include <queue>
+#include <set>
+#include <stdint.h>
+
+#include "GLContextTypes.h"
+#include "GLDefs.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/DebugOnly.h"
+#include "mozilla/gfx/Point.h"
+#include "mozilla/Mutex.h"
+#include "mozilla/UniquePtr.h"
+#include "mozilla/WeakPtr.h"
+#include "ScopedGLHelpers.h"
+#include "SurfaceTypes.h"
+
+class nsIThread;
+
+namespace mozilla {
+namespace gfx {
+class DataSourceSurface;
+class DrawTarget;
+} // namespace gfx
+
+namespace layers {
+class LayersIPCChannel;
+class SharedSurfaceTextureClient;
+enum class TextureFlags : uint32_t;
+class SurfaceDescriptor;
+class TextureClient;
+} // namespace layers
+
+namespace gl {
+
+class GLContext;
+class SurfaceFactory;
+class ShSurfHandle;
+
+class SharedSurface
+{
+public:
+ static void ProdCopy(SharedSurface* src, SharedSurface* dest,
+ SurfaceFactory* factory);
+
+ const SharedSurfaceType mType;
+ const AttachmentType mAttachType;
+ const WeakPtr<GLContext> mGL;
+ const gfx::IntSize mSize;
+ const bool mHasAlpha;
+ const bool mCanRecycle;
+protected:
+ bool mIsLocked;
+ bool mIsProducerAcquired;
+#ifdef DEBUG
+ nsIThread* const mOwningThread;
+#endif
+
+ SharedSurface(SharedSurfaceType type,
+ AttachmentType attachType,
+ GLContext* gl,
+ const gfx::IntSize& size,
+ bool hasAlpha,
+ bool canRecycle);
+
+public:
+ virtual ~SharedSurface() {
+ }
+
+ // Specifies to the TextureClient any flags which
+ // are required by the SharedSurface backend.
+ virtual layers::TextureFlags GetTextureFlags() const;
+
+ bool IsLocked() const { return mIsLocked; }
+ bool IsProducerAcquired() const { return mIsProducerAcquired; }
+
+ // This locks the SharedSurface as the production buffer for the context.
+ // This is needed by backends which use PBuffers and/or EGLSurfaces.
+ void LockProd();
+
+ // Unlocking is harmless if we're already unlocked.
+ void UnlockProd();
+
+protected:
+ virtual void LockProdImpl() = 0;
+ virtual void UnlockProdImpl() = 0;
+
+ virtual void ProducerAcquireImpl() = 0;
+ virtual void ProducerReleaseImpl() = 0;
+ virtual void ProducerReadAcquireImpl() { ProducerAcquireImpl(); }
+ virtual void ProducerReadReleaseImpl() { ProducerReleaseImpl(); }
+
+public:
+ void ProducerAcquire() {
+ MOZ_ASSERT(!mIsProducerAcquired);
+ ProducerAcquireImpl();
+ mIsProducerAcquired = true;
+ }
+ void ProducerRelease() {
+ MOZ_ASSERT(mIsProducerAcquired);
+ ProducerReleaseImpl();
+ mIsProducerAcquired = false;
+ }
+ void ProducerReadAcquire() {
+ MOZ_ASSERT(!mIsProducerAcquired);
+ ProducerReadAcquireImpl();
+ mIsProducerAcquired = true;
+ }
+ void ProducerReadRelease() {
+ MOZ_ASSERT(mIsProducerAcquired);
+ ProducerReadReleaseImpl();
+ mIsProducerAcquired = false;
+ }
+
+ // This function waits until the buffer is no longer being used.
+ // To optimize the performance, some implementaions recycle SharedSurfaces
+ // even when its buffer is still being used.
+ virtual void WaitForBufferOwnership() {}
+
+ // For use when AttachType is correct.
+ virtual GLenum ProdTextureTarget() const {
+ MOZ_ASSERT(mAttachType == AttachmentType::GLTexture);
+ return LOCAL_GL_TEXTURE_2D;
+ }
+
+ virtual GLuint ProdTexture() {
+ MOZ_ASSERT(mAttachType == AttachmentType::GLTexture);
+ MOZ_CRASH("GFX: Did you forget to override this function?");
+ }
+
+ virtual GLuint ProdRenderbuffer() {
+ MOZ_ASSERT(mAttachType == AttachmentType::GLRenderbuffer);
+ MOZ_CRASH("GFX: Did you forget to override this function?");
+ }
+
+ virtual bool CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x,
+ GLint y, GLsizei width, GLsizei height, GLint border)
+ {
+ return false;
+ }
+
+ virtual bool ReadPixels(GLint x, GLint y,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ GLvoid* pixels)
+ {
+ return false;
+ }
+
+ virtual bool NeedsIndirectReads() const {
+ return false;
+ }
+
+ virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) = 0;
+
+ virtual bool ReadbackBySharedHandle(gfx::DataSourceSurface* out_surface) {
+ return false;
+ }
+};
+
+template<typename T>
+class RefSet
+{
+ std::set<T*> mSet;
+
+public:
+ ~RefSet() {
+ clear();
+ }
+
+ auto begin() -> decltype(mSet.begin()) {
+ return mSet.begin();
+ }
+
+ void clear() {
+ for (auto itr = mSet.begin(); itr != mSet.end(); ++itr) {
+ (*itr)->Release();
+ }
+ mSet.clear();
+ }
+
+ bool empty() const {
+ return mSet.empty();
+ }
+
+ bool insert(T* x) {
+ if (mSet.insert(x).second) {
+ x->AddRef();
+ return true;
+ }
+
+ return false;
+ }
+
+ bool erase(T* x) {
+ if (mSet.erase(x)) {
+ x->Release();
+ return true;
+ }
+
+ return false;
+ }
+};
+
+template<typename T>
+class RefQueue
+{
+ std::queue<T*> mQueue;
+
+public:
+ ~RefQueue() {
+ clear();
+ }
+
+ void clear() {
+ while (!empty()) {
+ pop();
+ }
+ }
+
+ bool empty() const {
+ return mQueue.empty();
+ }
+
+ size_t size() const {
+ return mQueue.size();
+ }
+
+ void push(T* x) {
+ mQueue.push(x);
+ x->AddRef();
+ }
+
+ T* front() const {
+ return mQueue.front();
+ }
+
+ void pop() {
+ T* x = mQueue.front();
+ x->Release();
+ mQueue.pop();
+ }
+};
+
+class SurfaceFactory : public SupportsWeakPtr<SurfaceFactory>
+{
+public:
+ // Should use the VIRTUAL version, but it's currently incompatible
+ // with SupportsWeakPtr. (bug 1049278)
+ MOZ_DECLARE_WEAKREFERENCE_TYPENAME(SurfaceFactory)
+
+ const SharedSurfaceType mType;
+ GLContext* const mGL;
+ const SurfaceCaps mCaps;
+ const RefPtr<layers::LayersIPCChannel> mAllocator;
+ const layers::TextureFlags mFlags;
+ const GLFormats mFormats;
+ Mutex mMutex;
+protected:
+ SurfaceCaps mDrawCaps;
+ SurfaceCaps mReadCaps;
+ RefQueue<layers::SharedSurfaceTextureClient> mRecycleFreePool;
+ RefSet<layers::SharedSurfaceTextureClient> mRecycleTotalPool;
+
+ SurfaceFactory(SharedSurfaceType type, GLContext* gl, const SurfaceCaps& caps,
+ const RefPtr<layers::LayersIPCChannel>& allocator,
+ const layers::TextureFlags& flags);
+
+public:
+ virtual ~SurfaceFactory();
+
+ const SurfaceCaps& DrawCaps() const {
+ return mDrawCaps;
+ }
+
+ const SurfaceCaps& ReadCaps() const {
+ return mReadCaps;
+ }
+
+protected:
+ virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) = 0;
+
+ void StartRecycling(layers::SharedSurfaceTextureClient* tc);
+ void SetRecycleCallback(layers::SharedSurfaceTextureClient* tc);
+ void StopRecycling(layers::SharedSurfaceTextureClient* tc);
+
+public:
+ UniquePtr<SharedSurface> NewSharedSurface(const gfx::IntSize& size);
+ //already_AddRefed<ShSurfHandle> NewShSurfHandle(const gfx::IntSize& size);
+ already_AddRefed<layers::SharedSurfaceTextureClient> NewTexClient(const gfx::IntSize& size);
+
+ static void RecycleCallback(layers::TextureClient* tc, void* /*closure*/);
+
+ // Auto-deletes surfs of the wrong type.
+ bool Recycle(layers::SharedSurfaceTextureClient* texClient);
+};
+
+class ScopedReadbackFB
+{
+ GLContext* const mGL;
+ ScopedBindFramebuffer mAutoFB;
+ GLuint mTempFB;
+ GLuint mTempTex;
+ SharedSurface* mSurfToUnlock;
+ SharedSurface* mSurfToLock;
+
+public:
+ explicit ScopedReadbackFB(SharedSurface* src);
+ ~ScopedReadbackFB();
+};
+
+bool ReadbackSharedSurface(SharedSurface* src, gfx::DrawTarget* dst);
+uint32_t ReadPixel(SharedSurface* src);
+
+} // namespace gl
+} // namespace mozilla
+
+#endif // SHARED_SURFACE_H_
diff --git a/gfx/gl/SharedSurfaceANGLE.cpp b/gfx/gl/SharedSurfaceANGLE.cpp
new file mode 100644
index 0000000000..e82a24dfd2
--- /dev/null
+++ b/gfx/gl/SharedSurfaceANGLE.cpp
@@ -0,0 +1,354 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "SharedSurfaceANGLE.h"
+
+#include <d3d11.h>
+#include "GLContextEGL.h"
+#include "GLLibraryEGL.h"
+#include "mozilla/gfx/DeviceManagerDx.h"
+#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc
+
+namespace mozilla {
+namespace gl {
+
+// Returns `EGL_NO_SURFACE` (`0`) on error.
+static EGLSurface
+CreatePBufferSurface(GLLibraryEGL* egl,
+ EGLDisplay display,
+ EGLConfig config,
+ const gfx::IntSize& size)
+{
+ auto width = size.width;
+ auto height = size.height;
+
+ EGLint attribs[] = {
+ LOCAL_EGL_WIDTH, width,
+ LOCAL_EGL_HEIGHT, height,
+ LOCAL_EGL_NONE
+ };
+
+ DebugOnly<EGLint> preCallErr = egl->fGetError();
+ MOZ_ASSERT(preCallErr == LOCAL_EGL_SUCCESS);
+ EGLSurface surface = egl->fCreatePbufferSurface(display, config, attribs);
+ EGLint err = egl->fGetError();
+ if (err != LOCAL_EGL_SUCCESS)
+ return 0;
+
+ return surface;
+}
+
+/*static*/ UniquePtr<SharedSurface_ANGLEShareHandle>
+SharedSurface_ANGLEShareHandle::Create(GLContext* gl, EGLConfig config,
+ const gfx::IntSize& size, bool hasAlpha)
+{
+ GLLibraryEGL* egl = &sEGLLibrary;
+ MOZ_ASSERT(egl);
+ MOZ_ASSERT(egl->IsExtensionSupported(
+ GLLibraryEGL::ANGLE_surface_d3d_texture_2d_share_handle));
+ MOZ_ASSERT(config);
+
+ EGLDisplay display = egl->Display();
+ EGLSurface pbuffer = CreatePBufferSurface(egl, display, config, size);
+ if (!pbuffer)
+ return nullptr;
+
+ // Declare everything before 'goto's.
+ HANDLE shareHandle = nullptr;
+ bool ok = egl->fQuerySurfacePointerANGLE(display,
+ pbuffer,
+ LOCAL_EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE,
+ &shareHandle);
+ if (!ok) {
+ egl->fDestroySurface(egl->Display(), pbuffer);
+ return nullptr;
+ }
+ void* opaqueKeyedMutex = nullptr;
+ egl->fQuerySurfacePointerANGLE(display,
+ pbuffer,
+ LOCAL_EGL_DXGI_KEYED_MUTEX_ANGLE,
+ &opaqueKeyedMutex);
+ RefPtr<IDXGIKeyedMutex> keyedMutex = static_cast<IDXGIKeyedMutex*>(opaqueKeyedMutex);
+
+ typedef SharedSurface_ANGLEShareHandle ptrT;
+ UniquePtr<ptrT> ret( new ptrT(gl, egl, size, hasAlpha, pbuffer, shareHandle,
+ keyedMutex) );
+ return Move(ret);
+}
+
+EGLDisplay
+SharedSurface_ANGLEShareHandle::Display()
+{
+ return mEGL->Display();
+}
+
+SharedSurface_ANGLEShareHandle::SharedSurface_ANGLEShareHandle(GLContext* gl,
+ GLLibraryEGL* egl,
+ const gfx::IntSize& size,
+ bool hasAlpha,
+ EGLSurface pbuffer,
+ HANDLE shareHandle,
+ const RefPtr<IDXGIKeyedMutex>& keyedMutex)
+ : SharedSurface(SharedSurfaceType::EGLSurfaceANGLE,
+ AttachmentType::Screen,
+ gl,
+ size,
+ hasAlpha,
+ true)
+ , mEGL(egl)
+ , mPBuffer(pbuffer)
+ , mShareHandle(shareHandle)
+ , mKeyedMutex(keyedMutex)
+{
+}
+
+
+SharedSurface_ANGLEShareHandle::~SharedSurface_ANGLEShareHandle()
+{
+ mEGL->fDestroySurface(Display(), mPBuffer);
+}
+
+void
+SharedSurface_ANGLEShareHandle::LockProdImpl()
+{
+ GLContextEGL::Cast(mGL)->SetEGLSurfaceOverride(mPBuffer);
+}
+
+void
+SharedSurface_ANGLEShareHandle::UnlockProdImpl()
+{
+}
+
+void
+SharedSurface_ANGLEShareHandle::ProducerAcquireImpl()
+{
+ if (mKeyedMutex) {
+ HRESULT hr = mKeyedMutex->AcquireSync(0, 10000);
+ if (hr == WAIT_TIMEOUT) {
+ MOZ_CRASH("GFX: ANGLE share handle timeout");
+ }
+ }
+}
+
+void
+SharedSurface_ANGLEShareHandle::ProducerReleaseImpl()
+{
+ if (mKeyedMutex) {
+ // XXX: ReleaseSync() has an implicit flush of the D3D commands
+ // whether we need Flush() or not depends on the ANGLE semantics.
+ // For now, we'll just do it
+ mGL->fFlush();
+ mKeyedMutex->ReleaseSync(0);
+ return;
+ }
+ mGL->fFinish();
+}
+
+void
+SharedSurface_ANGLEShareHandle::ProducerReadAcquireImpl()
+{
+ ProducerAcquireImpl();
+}
+
+void
+SharedSurface_ANGLEShareHandle::ProducerReadReleaseImpl()
+{
+ if (mKeyedMutex) {
+ mKeyedMutex->ReleaseSync(0);
+ return;
+ }
+}
+
+bool
+SharedSurface_ANGLEShareHandle::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
+{
+ gfx::SurfaceFormat format = mHasAlpha ? gfx::SurfaceFormat::B8G8R8A8
+ : gfx::SurfaceFormat::B8G8R8X8;
+ *out_descriptor = layers::SurfaceDescriptorD3D10((WindowsHandle)mShareHandle, format,
+ mSize);
+ return true;
+}
+
+class ScopedLockTexture final
+{
+public:
+ explicit ScopedLockTexture(ID3D11Texture2D* texture, bool* succeeded)
+ : mIsLocked(false)
+ , mTexture(texture)
+ {
+ MOZ_ASSERT(NS_IsMainThread(), "Must be on the main thread to use d3d11 immediate context");
+ MOZ_ASSERT(mTexture);
+ MOZ_ASSERT(succeeded);
+ *succeeded = false;
+
+ HRESULT hr;
+ mTexture->QueryInterface((IDXGIKeyedMutex**)getter_AddRefs(mMutex));
+ if (mMutex) {
+ hr = mMutex->AcquireSync(0, 10000);
+ if (hr == WAIT_TIMEOUT) {
+ MOZ_CRASH("GFX: ANGLE scoped lock timeout");
+ }
+
+ if (FAILED(hr)) {
+ NS_WARNING("Failed to lock the texture");
+ return;
+ }
+ }
+
+ RefPtr<ID3D11Device> device =
+ gfx::DeviceManagerDx::Get()->GetContentDevice();
+ if (!device) {
+ return;
+ }
+
+ device->GetImmediateContext(getter_AddRefs(mDeviceContext));
+
+ mTexture->GetDesc(&mDesc);
+ mDesc.BindFlags = 0;
+ mDesc.Usage = D3D11_USAGE_STAGING;
+ mDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+ mDesc.MiscFlags = 0;
+
+ hr = device->CreateTexture2D(&mDesc, nullptr, getter_AddRefs(mCopiedTexture));
+
+ if (FAILED(hr)) {
+ return;
+ }
+
+ mDeviceContext->CopyResource(mCopiedTexture, mTexture);
+
+ hr = mDeviceContext->Map(mCopiedTexture, 0, D3D11_MAP_READ, 0, &mSubresource);
+ if (FAILED(hr)) {
+ return;
+ }
+
+ *succeeded = true;
+ mIsLocked = true;
+ }
+
+ ~ScopedLockTexture()
+ {
+ mDeviceContext->Unmap(mCopiedTexture, 0);
+ if (mMutex) {
+ HRESULT hr = mMutex->ReleaseSync(0);
+ if (FAILED(hr)) {
+ NS_WARNING("Failed to unlock the texture");
+ }
+ }
+ mIsLocked = false;
+ }
+
+ bool mIsLocked;
+ RefPtr<ID3D11Texture2D> mTexture;
+ RefPtr<ID3D11Texture2D> mCopiedTexture;
+ RefPtr<IDXGIKeyedMutex> mMutex;
+ RefPtr<ID3D11DeviceContext> mDeviceContext;
+ D3D11_TEXTURE2D_DESC mDesc;
+ D3D11_MAPPED_SUBRESOURCE mSubresource;
+};
+
+bool
+SharedSurface_ANGLEShareHandle::ReadbackBySharedHandle(gfx::DataSourceSurface* out_surface)
+{
+ MOZ_ASSERT(out_surface);
+
+ RefPtr<ID3D11Device> device =
+ gfx::DeviceManagerDx::Get()->GetContentDevice();
+ if (!device) {
+ return false;
+ }
+
+ RefPtr<ID3D11Texture2D> tex;
+ HRESULT hr = device->OpenSharedResource(mShareHandle,
+ __uuidof(ID3D11Texture2D),
+ (void**)(ID3D11Texture2D**)getter_AddRefs(tex));
+
+ if (FAILED(hr)) {
+ return false;
+ }
+
+ bool succeeded = false;
+ ScopedLockTexture scopedLock(tex, &succeeded);
+ if (!succeeded) {
+ return false;
+ }
+
+ const uint8_t* data = reinterpret_cast<uint8_t*>(scopedLock.mSubresource.pData);
+ uint32_t srcStride = scopedLock.mSubresource.RowPitch;
+
+ gfx::DataSourceSurface::ScopedMap map(out_surface, gfx::DataSourceSurface::WRITE);
+ if (!map.IsMapped()) {
+ return false;
+ }
+
+ if (map.GetStride() == srcStride) {
+ memcpy(map.GetData(), data, out_surface->GetSize().height * map.GetStride());
+ } else {
+ const uint8_t bytesPerPixel = BytesPerPixel(out_surface->GetFormat());
+ for (int32_t i = 0; i < out_surface->GetSize().height; i++) {
+ memcpy(map.GetData() + i * map.GetStride(),
+ data + i * srcStride,
+ bytesPerPixel * out_surface->GetSize().width);
+ }
+ }
+
+ DXGI_FORMAT srcFormat = scopedLock.mDesc.Format;
+ MOZ_ASSERT(srcFormat == DXGI_FORMAT_B8G8R8A8_UNORM ||
+ srcFormat == DXGI_FORMAT_B8G8R8X8_UNORM ||
+ srcFormat == DXGI_FORMAT_R8G8B8A8_UNORM);
+ bool isSrcRGB = srcFormat == DXGI_FORMAT_R8G8B8A8_UNORM;
+
+ gfx::SurfaceFormat destFormat = out_surface->GetFormat();
+ MOZ_ASSERT(destFormat == gfx::SurfaceFormat::R8G8B8X8 ||
+ destFormat == gfx::SurfaceFormat::R8G8B8A8 ||
+ destFormat == gfx::SurfaceFormat::B8G8R8X8 ||
+ destFormat == gfx::SurfaceFormat::B8G8R8A8);
+ bool isDestRGB = destFormat == gfx::SurfaceFormat::R8G8B8X8 ||
+ destFormat == gfx::SurfaceFormat::R8G8B8A8;
+
+ if (isSrcRGB != isDestRGB) {
+ SwapRAndBComponents(out_surface);
+ }
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Factory
+
+/*static*/ UniquePtr<SurfaceFactory_ANGLEShareHandle>
+SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl, const SurfaceCaps& caps,
+ const RefPtr<layers::LayersIPCChannel>& allocator,
+ const layers::TextureFlags& flags)
+{
+ GLLibraryEGL* egl = &sEGLLibrary;
+ if (!egl)
+ return nullptr;
+
+ auto ext = GLLibraryEGL::ANGLE_surface_d3d_texture_2d_share_handle;
+ if (!egl->IsExtensionSupported(ext))
+ return nullptr;
+
+ EGLConfig config = GLContextEGL::Cast(gl)->mConfig;
+
+ typedef SurfaceFactory_ANGLEShareHandle ptrT;
+ UniquePtr<ptrT> ret( new ptrT(gl, caps, allocator, flags, egl, config) );
+ return Move(ret);
+}
+
+SurfaceFactory_ANGLEShareHandle::SurfaceFactory_ANGLEShareHandle(GLContext* gl,
+ const SurfaceCaps& caps,
+ const RefPtr<layers::LayersIPCChannel>& allocator,
+ const layers::TextureFlags& flags,
+ GLLibraryEGL* egl,
+ EGLConfig config)
+ : SurfaceFactory(SharedSurfaceType::EGLSurfaceANGLE, gl, caps, allocator, flags)
+ , mProdGL(gl)
+ , mEGL(egl)
+ , mConfig(config)
+{ }
+
+} /* namespace gl */
+} /* namespace mozilla */
diff --git a/gfx/gl/SharedSurfaceANGLE.h b/gfx/gl/SharedSurfaceANGLE.h
new file mode 100644
index 0000000000..5e7fe32f34
--- /dev/null
+++ b/gfx/gl/SharedSurfaceANGLE.h
@@ -0,0 +1,101 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef SHARED_SURFACE_ANGLE_H_
+#define SHARED_SURFACE_ANGLE_H_
+
+#include <windows.h>
+#include "SharedSurface.h"
+
+struct IDXGIKeyedMutex;
+struct ID3D11Texture2D;
+
+namespace mozilla {
+namespace gl {
+
+class GLContext;
+class GLLibraryEGL;
+
+class SharedSurface_ANGLEShareHandle
+ : public SharedSurface
+{
+public:
+ static UniquePtr<SharedSurface_ANGLEShareHandle> Create(GLContext* gl,
+ EGLConfig config,
+ const gfx::IntSize& size,
+ bool hasAlpha);
+
+ static SharedSurface_ANGLEShareHandle* Cast(SharedSurface* surf) {
+ MOZ_ASSERT(surf->mType == SharedSurfaceType::EGLSurfaceANGLE);
+
+ return (SharedSurface_ANGLEShareHandle*)surf;
+ }
+
+protected:
+ GLLibraryEGL* const mEGL;
+ const EGLSurface mPBuffer;
+public:
+ const HANDLE mShareHandle;
+protected:
+ RefPtr<IDXGIKeyedMutex> mKeyedMutex;
+
+ SharedSurface_ANGLEShareHandle(GLContext* gl,
+ GLLibraryEGL* egl,
+ const gfx::IntSize& size,
+ bool hasAlpha,
+ EGLSurface pbuffer,
+ HANDLE shareHandle,
+ const RefPtr<IDXGIKeyedMutex>& keyedMutex);
+
+ EGLDisplay Display();
+
+public:
+ virtual ~SharedSurface_ANGLEShareHandle();
+
+ virtual void LockProdImpl() override;
+ virtual void UnlockProdImpl() override;
+
+ virtual void ProducerAcquireImpl() override;
+ virtual void ProducerReleaseImpl() override;
+ virtual void ProducerReadAcquireImpl() override;
+ virtual void ProducerReadReleaseImpl() override;
+
+ virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override;
+
+ virtual bool ReadbackBySharedHandle(gfx::DataSourceSurface* out_surface) override;
+};
+
+
+
+class SurfaceFactory_ANGLEShareHandle
+ : public SurfaceFactory
+{
+protected:
+ GLContext* const mProdGL;
+ GLLibraryEGL* const mEGL;
+ const EGLConfig mConfig;
+
+public:
+ static UniquePtr<SurfaceFactory_ANGLEShareHandle> Create(GLContext* gl,
+ const SurfaceCaps& caps,
+ const RefPtr<layers::LayersIPCChannel>& allocator,
+ const layers::TextureFlags& flags);
+
+protected:
+ SurfaceFactory_ANGLEShareHandle(GLContext* gl, const SurfaceCaps& caps,
+ const RefPtr<layers::LayersIPCChannel>& allocator,
+ const layers::TextureFlags& flags, GLLibraryEGL* egl,
+ EGLConfig config);
+
+ virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
+ bool hasAlpha = mReadCaps.alpha;
+ return SharedSurface_ANGLEShareHandle::Create(mProdGL, mConfig, size, hasAlpha);
+ }
+};
+
+} /* namespace gfx */
+} /* namespace mozilla */
+
+#endif /* SHARED_SURFACE_ANGLE_H_ */
diff --git a/gfx/gl/SharedSurfaceD3D11Interop.cpp b/gfx/gl/SharedSurfaceD3D11Interop.cpp
new file mode 100644
index 0000000000..e667005d83
--- /dev/null
+++ b/gfx/gl/SharedSurfaceD3D11Interop.cpp
@@ -0,0 +1,425 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "SharedSurfaceD3D11Interop.h"
+
+#include <d3d11.h>
+#include "gfxPrefs.h"
+#include "GLContext.h"
+#include "WGLLibrary.h"
+#include "nsPrintfCString.h"
+#include "mozilla/gfx/DeviceManagerDx.h"
+
+namespace mozilla {
+namespace gl {
+
+/*
+Sample Code for WGL_NV_DX_interop2:
+Example: Render to Direct3D 11 backbuffer with openGL:
+
+// create D3D11 device, context and swap chain.
+ID3D11Device *device;
+ID3D11DeviceContext *devCtx;
+IDXGISwapChain *swapChain;
+
+DXGI_SWAP_CHAIN_DESC scd;
+
+<set appropriate swap chain parameters in scd>
+
+hr = D3D11CreateDeviceAndSwapChain(NULL, // pAdapter
+ D3D_DRIVER_TYPE_HARDWARE, // DriverType
+ NULL, // Software
+ 0, // Flags (Do not set D3D11_CREATE_DEVICE_SINGLETHREADED)
+ NULL, // pFeatureLevels
+ 0, // FeatureLevels
+ D3D11_SDK_VERSION, // SDKVersion
+ &scd, // pSwapChainDesc
+ &swapChain, // ppSwapChain
+ &device, // ppDevice
+ NULL, // pFeatureLevel
+ &devCtx); // ppImmediateContext
+
+// Fetch the swapchain backbuffer
+ID3D11Texture2D *dxColorbuffer;
+swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID *)&dxColorbuffer);
+
+// Create depth stencil texture
+ID3D11Texture2D *dxDepthBuffer;
+D3D11_TEXTURE2D_DESC depthDesc;
+depthDesc.Usage = D3D11_USAGE_DEFAULT;
+<set other depthDesc parameters appropriately>
+
+// Create Views
+ID3D11RenderTargetView *colorBufferView;
+D3D11_RENDER_TARGET_VIEW_DESC rtd;
+<set rtd parameters appropriately>
+device->CreateRenderTargetView(dxColorbuffer, &rtd, &colorBufferView);
+
+ID3D11DepthStencilView *depthBufferView;
+D3D11_DEPTH_STENCIL_VIEW_DESC dsd;
+<set dsd parameters appropriately>
+device->CreateDepthStencilView(dxDepthBuffer, &dsd, &depthBufferView);
+
+// Attach back buffer and depth texture to redertarget for the device.
+devCtx->OMSetRenderTargets(1, &colorBufferView, depthBufferView);
+
+// Register D3D11 device with GL
+HANDLE gl_handleD3D;
+gl_handleD3D = wglDXOpenDeviceNV(device);
+
+// register the Direct3D color and depth/stencil buffers as
+// renderbuffers in opengl
+GLuint gl_names[2];
+HANDLE gl_handles[2];
+
+glGenRenderbuffers(2, gl_names);
+
+gl_handles[0] = wglDXRegisterObjectNV(gl_handleD3D, dxColorBuffer,
+ gl_names[0],
+ GL_RENDERBUFFER,
+ WGL_ACCESS_READ_WRITE_NV);
+
+gl_handles[1] = wglDXRegisterObjectNV(gl_handleD3D, dxDepthBuffer,
+ gl_names[1],
+ GL_RENDERBUFFER,
+ WGL_ACCESS_READ_WRITE_NV);
+
+// attach the Direct3D buffers to an FBO
+glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER, gl_names[0]);
+glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER, gl_names[1]);
+glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, gl_names[1]);
+
+while (!done) {
+ <direct3d renders to the render targets>
+
+ // lock the render targets for GL access
+ wglDXLockObjectsNVX(gl_handleD3D, 2, gl_handles);
+
+ <opengl renders to the render targets>
+
+ // unlock the render targets
+ wglDXUnlockObjectsNVX(gl_handleD3D, 2, gl_handles);
+
+ <direct3d renders to the render targets and presents
+ the results on the screen>
+}
+*/
+
+////////////////////////////////////////////////////////////////////////////////
+// DXInterop2Device
+
+class DXInterop2Device : public RefCounted<DXInterop2Device>
+{
+public:
+ MOZ_DECLARE_REFCOUNTED_TYPENAME(DXInterop2Device)
+
+ WGLLibrary* const mWGL;
+ const RefPtr<ID3D11Device> mD3D; // Only needed for lifetime guarantee.
+ const HANDLE mInteropDevice;
+ GLContext* const mGL;
+
+ static already_AddRefed<DXInterop2Device> Open(WGLLibrary* wgl, GLContext* gl)
+ {
+ MOZ_ASSERT(wgl->HasDXInterop2());
+
+ const RefPtr<ID3D11Device> d3d = gfx::DeviceManagerDx::Get()->GetContentDevice();
+ if (!d3d) {
+ gfxCriticalNote << "DXInterop2Device::Open: Failed to create D3D11 device.";
+ return nullptr;
+ }
+
+ if (!gl->MakeCurrent())
+ return nullptr;
+
+ const auto interopDevice = wgl->fDXOpenDevice(d3d);
+ if (!interopDevice) {
+ gfxCriticalNote << "DXInterop2Device::Open: DXOpenDevice failed.";
+ return nullptr;
+ }
+
+ return MakeAndAddRef<DXInterop2Device>(wgl, d3d, interopDevice, gl);
+ }
+
+ DXInterop2Device(WGLLibrary* wgl, ID3D11Device* d3d, HANDLE interopDevice,
+ GLContext* gl)
+ : mWGL(wgl)
+ , mD3D(d3d)
+ , mInteropDevice(interopDevice)
+ , mGL(gl)
+ { }
+
+ ~DXInterop2Device() {
+ const auto isCurrent = mGL->MakeCurrent();
+
+ if (mWGL->fDXCloseDevice(mInteropDevice))
+ return;
+
+ if (isCurrent) {
+ // That shouldn't have failed.
+ const uint32_t error = GetLastError();
+ const nsPrintfCString errorMessage("wglDXCloseDevice(0x%p) failed:"
+ " GetLastError(): %u\n",
+ mInteropDevice, error);
+ gfxCriticalError() << errorMessage.BeginReading();
+ }
+ }
+
+ HANDLE RegisterObject(void* d3dObject, GLuint name, GLenum type,
+ GLenum access) const
+ {
+ if (!mGL->MakeCurrent())
+ return nullptr;
+
+ const auto ret = mWGL->fDXRegisterObject(mInteropDevice, d3dObject, name, type,
+ access);
+ if (ret)
+ return ret;
+
+ const uint32_t error = GetLastError();
+ const nsPrintfCString errorMessage("wglDXRegisterObject(0x%p, 0x%p, %u, 0x%04x,"
+ " 0x%04x) failed: GetLastError(): %u\n",
+ mInteropDevice, d3dObject, name, type, access,
+ error);
+ gfxCriticalNote << errorMessage.BeginReading();
+ return nullptr;
+ }
+
+ bool UnregisterObject(HANDLE lockHandle) const {
+ const auto isCurrent = mGL->MakeCurrent();
+
+ if (mWGL->fDXUnregisterObject(mInteropDevice, lockHandle))
+ return true;
+
+ if (!isCurrent) {
+ // That shouldn't have failed.
+ const uint32_t error = GetLastError();
+ const nsPrintfCString errorMessage("wglDXUnregisterObject(0x%p, 0x%p) failed:"
+ " GetLastError(): %u\n",
+ mInteropDevice, lockHandle, error);
+ gfxCriticalError() << errorMessage.BeginReading();
+ }
+ return false;
+ }
+
+ bool LockObject(HANDLE lockHandle) const {
+ MOZ_ASSERT(mGL->IsCurrent());
+
+ if (mWGL->fDXLockObjects(mInteropDevice, 1, &lockHandle))
+ return true;
+
+ if (!mGL->MakeCurrent())
+ return false;
+
+ gfxCriticalNote << "wglDXLockObjects called without mGL being current."
+ << " Retrying after MakeCurrent.";
+
+ if (mWGL->fDXLockObjects(mInteropDevice, 1, &lockHandle))
+ return true;
+
+ const uint32_t error = GetLastError();
+ const nsPrintfCString errorMessage("wglDXLockObjects(0x%p, 1, {0x%p}) failed:"
+ " GetLastError(): %u\n",
+ mInteropDevice, lockHandle, error);
+ gfxCriticalError() << errorMessage.BeginReading();
+ return false;
+ }
+
+ bool UnlockObject(HANDLE lockHandle) const {
+ MOZ_ASSERT(mGL->IsCurrent());
+
+ if (mWGL->fDXUnlockObjects(mInteropDevice, 1, &lockHandle))
+ return true;
+
+ if (!mGL->MakeCurrent())
+ return false;
+
+ gfxCriticalNote << "wglDXUnlockObjects called without mGL being current."
+ << " Retrying after MakeCurrent.";
+
+ if (mWGL->fDXUnlockObjects(mInteropDevice, 1, &lockHandle))
+ return true;
+
+ const uint32_t error = GetLastError();
+ const nsPrintfCString errorMessage("wglDXUnlockObjects(0x%p, 1, {0x%p}) failed:"
+ " GetLastError(): %u\n",
+ mInteropDevice, lockHandle, error);
+ gfxCriticalError() << errorMessage.BeginReading();
+ return false;
+ }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Shared Surface
+
+/*static*/ UniquePtr<SharedSurface_D3D11Interop>
+SharedSurface_D3D11Interop::Create(DXInterop2Device* interop,
+ GLContext* gl,
+ const gfx::IntSize& size,
+ bool hasAlpha)
+{
+ const auto& d3d = interop->mD3D;
+
+ // Create a texture in case we need to readback.
+ DXGI_FORMAT format = hasAlpha ? DXGI_FORMAT_B8G8R8A8_UNORM
+ : DXGI_FORMAT_B8G8R8X8_UNORM;
+ CD3D11_TEXTURE2D_DESC desc(format, size.width, size.height, 1, 1);
+ desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
+
+ RefPtr<ID3D11Texture2D> texD3D;
+ auto hr = d3d->CreateTexture2D(&desc, nullptr, getter_AddRefs(texD3D));
+ if (FAILED(hr)) {
+ NS_WARNING("Failed to create texture for CanvasLayer!");
+ return nullptr;
+ }
+
+ RefPtr<IDXGIResource> texDXGI;
+ hr = texD3D->QueryInterface(__uuidof(IDXGIResource), getter_AddRefs(texDXGI));
+ if (FAILED(hr)) {
+ NS_WARNING("Failed to open texture for sharing!");
+ return nullptr;
+ }
+
+ HANDLE dxgiHandle;
+ texDXGI->GetSharedHandle(&dxgiHandle);
+
+ ////
+
+ if (!gl->MakeCurrent()) {
+ NS_WARNING("MakeCurrent failed.");
+ return nullptr;
+ }
+
+ GLuint rbGL = 0;
+ gl->fGenRenderbuffers(1, &rbGL);
+ const auto lockHandle = interop->RegisterObject(texD3D, rbGL, LOCAL_GL_RENDERBUFFER,
+ LOCAL_WGL_ACCESS_WRITE_DISCARD_NV);
+ if (!lockHandle) {
+ NS_WARNING("Failed to register D3D object with WGL.");
+ gl->fDeleteRenderbuffers(1, &rbGL);
+ return nullptr;
+ }
+
+ ////
+
+ typedef SharedSurface_D3D11Interop ptrT;
+ UniquePtr<ptrT> ret ( new ptrT(gl, size, hasAlpha, rbGL, interop, lockHandle,
+ texD3D, dxgiHandle) );
+ return Move(ret);
+}
+
+SharedSurface_D3D11Interop::SharedSurface_D3D11Interop(GLContext* gl,
+ const gfx::IntSize& size,
+ bool hasAlpha, GLuint rbGL,
+ DXInterop2Device* interop,
+ HANDLE lockHandle,
+ ID3D11Texture2D* texD3D,
+ HANDLE dxgiHandle)
+ : SharedSurface(SharedSurfaceType::DXGLInterop2,
+ AttachmentType::GLRenderbuffer,
+ gl,
+ size,
+ hasAlpha,
+ true)
+ , mProdRB(rbGL)
+ , mInterop(interop)
+ , mLockHandle(lockHandle)
+ , mTexD3D(texD3D)
+ , mDXGIHandle(dxgiHandle)
+ , mNeedsFinish(gfxPrefs::WebGLDXGLNeedsFinish())
+ , mLockedForGL(false)
+{ }
+
+SharedSurface_D3D11Interop::~SharedSurface_D3D11Interop()
+{
+ MOZ_ASSERT(!IsProducerAcquired());
+
+ if (!mGL || !mGL->MakeCurrent())
+ return;
+
+ if (!mInterop->UnregisterObject(mLockHandle)) {
+ NS_WARNING("Failed to release mLockHandle, possibly leaking it.");
+ }
+
+ mGL->fDeleteRenderbuffers(1, &mProdRB);
+}
+
+void
+SharedSurface_D3D11Interop::ProducerAcquireImpl()
+{
+ MOZ_ASSERT(!mLockedForGL);
+
+ // Now we have the mutex, we can lock for GL.
+ MOZ_ALWAYS_TRUE( mInterop->LockObject(mLockHandle) );
+
+ mLockedForGL = true;
+}
+
+void
+SharedSurface_D3D11Interop::ProducerReleaseImpl()
+{
+ MOZ_ASSERT(mLockedForGL);
+
+ if (mNeedsFinish) {
+ mGL->fFinish();
+ } else {
+ // We probably don't even need this.
+ mGL->fFlush();
+ }
+ MOZ_ALWAYS_TRUE( mInterop->UnlockObject(mLockHandle) );
+
+ mLockedForGL = false;
+}
+
+bool
+SharedSurface_D3D11Interop::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
+{
+ const auto format = (mHasAlpha ? gfx::SurfaceFormat::B8G8R8A8
+ : gfx::SurfaceFormat::B8G8R8X8);
+ *out_descriptor = layers::SurfaceDescriptorD3D10(WindowsHandle(mDXGIHandle), format,
+ mSize);
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// Factory
+
+/*static*/ UniquePtr<SurfaceFactory_D3D11Interop>
+SurfaceFactory_D3D11Interop::Create(GLContext* gl, const SurfaceCaps& caps,
+ layers::LayersIPCChannel* allocator,
+ const layers::TextureFlags& flags)
+{
+ WGLLibrary* wgl = &sWGLLib;
+ if (!wgl || !wgl->HasDXInterop2())
+ return nullptr;
+
+ const RefPtr<DXInterop2Device> interop = DXInterop2Device::Open(wgl, gl);
+ if (!interop) {
+ NS_WARNING("Failed to open D3D device for use by WGL.");
+ return nullptr;
+ }
+
+ typedef SurfaceFactory_D3D11Interop ptrT;
+ UniquePtr<ptrT> ret(new ptrT(gl, caps, allocator, flags, interop));
+ return Move(ret);
+}
+
+SurfaceFactory_D3D11Interop::SurfaceFactory_D3D11Interop(GLContext* gl,
+ const SurfaceCaps& caps,
+ layers::LayersIPCChannel* allocator,
+ const layers::TextureFlags& flags,
+ DXInterop2Device* interop)
+ : SurfaceFactory(SharedSurfaceType::DXGLInterop2, gl, caps, allocator, flags)
+ , mInterop(interop)
+{ }
+
+SurfaceFactory_D3D11Interop::~SurfaceFactory_D3D11Interop()
+{ }
+
+} // namespace gl
+} // namespace mozilla
diff --git a/gfx/gl/SharedSurfaceD3D11Interop.h b/gfx/gl/SharedSurfaceD3D11Interop.h
new file mode 100644
index 0000000000..0f5bd35cf5
--- /dev/null
+++ b/gfx/gl/SharedSurfaceD3D11Interop.h
@@ -0,0 +1,100 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef SHARED_SURFACE_D3D11_INTEROP_H_
+#define SHARED_SURFACE_D3D11_INTEROP_H_
+
+#include <windows.h>
+#include "SharedSurface.h"
+
+namespace mozilla {
+namespace gl {
+
+class DXInterop2Device;
+class GLContext;
+class WGLLibrary;
+
+class SharedSurface_D3D11Interop
+ : public SharedSurface
+{
+public:
+ const GLuint mProdRB;
+ const RefPtr<DXInterop2Device> mInterop;
+ const HANDLE mLockHandle;
+ const RefPtr<ID3D11Texture2D> mTexD3D;
+ const HANDLE mDXGIHandle;
+ const bool mNeedsFinish;
+
+protected:
+ bool mLockedForGL;
+
+public:
+ static UniquePtr<SharedSurface_D3D11Interop> Create(DXInterop2Device* interop,
+ GLContext* gl,
+ const gfx::IntSize& size,
+ bool hasAlpha);
+
+ static SharedSurface_D3D11Interop* Cast(SharedSurface* surf) {
+ MOZ_ASSERT(surf->mType == SharedSurfaceType::DXGLInterop2);
+ return (SharedSurface_D3D11Interop*)surf;
+ }
+
+protected:
+ SharedSurface_D3D11Interop(GLContext* gl,
+ const gfx::IntSize& size,
+ bool hasAlpha,
+ GLuint renderbufferGL,
+ DXInterop2Device* interop,
+ HANDLE lockHandle,
+ ID3D11Texture2D* texD3D,
+ HANDLE dxgiHandle);
+
+public:
+ virtual ~SharedSurface_D3D11Interop() override;
+
+ virtual void LockProdImpl() override { }
+ virtual void UnlockProdImpl() override { }
+
+ virtual void ProducerAcquireImpl() override;
+ virtual void ProducerReleaseImpl() override;
+
+ virtual GLuint ProdRenderbuffer() override {
+ return mProdRB;
+ }
+
+ virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override;
+};
+
+class SurfaceFactory_D3D11Interop
+ : public SurfaceFactory
+{
+public:
+ const RefPtr<DXInterop2Device> mInterop;
+
+ static UniquePtr<SurfaceFactory_D3D11Interop> Create(GLContext* gl,
+ const SurfaceCaps& caps,
+ layers::LayersIPCChannel* allocator,
+ const layers::TextureFlags& flags);
+
+protected:
+ SurfaceFactory_D3D11Interop(GLContext* gl, const SurfaceCaps& caps,
+ layers::LayersIPCChannel* allocator,
+ const layers::TextureFlags& flags,
+ DXInterop2Device* interop);
+
+public:
+ virtual ~SurfaceFactory_D3D11Interop() override;
+
+protected:
+ virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
+ bool hasAlpha = mReadCaps.alpha;
+ return SharedSurface_D3D11Interop::Create(mInterop, mGL, size, hasAlpha);
+ }
+};
+
+} /* namespace gl */
+} /* namespace mozilla */
+
+#endif /* SHARED_SURFACE_D3D11_INTEROP_H_ */
diff --git a/gfx/gl/SharedSurfaceEGL.cpp b/gfx/gl/SharedSurfaceEGL.cpp
new file mode 100644
index 0000000000..5538138e45
--- /dev/null
+++ b/gfx/gl/SharedSurfaceEGL.cpp
@@ -0,0 +1,191 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "SharedSurfaceEGL.h"
+
+#include "GLBlitHelper.h"
+#include "GLContextEGL.h"
+#include "GLLibraryEGL.h"
+#include "GLReadTexImageHelper.h"
+#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc
+#include "SharedSurface.h"
+#include "TextureGarbageBin.h"
+
+namespace mozilla {
+namespace gl {
+
+/*static*/ UniquePtr<SharedSurface_EGLImage>
+SharedSurface_EGLImage::Create(GLContext* prodGL,
+ const GLFormats& formats,
+ const gfx::IntSize& size,
+ bool hasAlpha,
+ EGLContext context)
+{
+ GLLibraryEGL* egl = &sEGLLibrary;
+ MOZ_ASSERT(egl);
+ MOZ_ASSERT(context);
+
+ UniquePtr<SharedSurface_EGLImage> ret;
+
+ if (!HasExtensions(egl, prodGL)) {
+ return Move(ret);
+ }
+
+ MOZ_ALWAYS_TRUE(prodGL->MakeCurrent());
+ GLuint prodTex = CreateTextureForOffscreen(prodGL, formats, size);
+ if (!prodTex) {
+ return Move(ret);
+ }
+
+ EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(uintptr_t(prodTex));
+ EGLImage image = egl->fCreateImage(egl->Display(), context,
+ LOCAL_EGL_GL_TEXTURE_2D, buffer,
+ nullptr);
+ if (!image) {
+ prodGL->fDeleteTextures(1, &prodTex);
+ return Move(ret);
+ }
+
+ ret.reset( new SharedSurface_EGLImage(prodGL, egl, size, hasAlpha,
+ formats, prodTex, image) );
+ return Move(ret);
+}
+
+bool
+SharedSurface_EGLImage::HasExtensions(GLLibraryEGL* egl, GLContext* gl)
+{
+ return egl->HasKHRImageBase() &&
+ egl->IsExtensionSupported(GLLibraryEGL::KHR_gl_texture_2D_image) &&
+ (gl->IsExtensionSupported(GLContext::OES_EGL_image_external) ||
+ gl->IsExtensionSupported(GLContext::OES_EGL_image));
+}
+
+SharedSurface_EGLImage::SharedSurface_EGLImage(GLContext* gl,
+ GLLibraryEGL* egl,
+ const gfx::IntSize& size,
+ bool hasAlpha,
+ const GLFormats& formats,
+ GLuint prodTex,
+ EGLImage image)
+ : SharedSurface(SharedSurfaceType::EGLImageShare,
+ AttachmentType::GLTexture,
+ gl,
+ size,
+ hasAlpha,
+ false) // Can't recycle, as mSync changes never update TextureHost.
+ , mMutex("SharedSurface_EGLImage mutex")
+ , mEGL(egl)
+ , mFormats(formats)
+ , mProdTex(prodTex)
+ , mImage(image)
+ , mSync(0)
+{}
+
+SharedSurface_EGLImage::~SharedSurface_EGLImage()
+{
+ mEGL->fDestroyImage(Display(), mImage);
+
+ if (mSync) {
+ // We can't call this unless we have the ext, but we will always have
+ // the ext if we have something to destroy.
+ mEGL->fDestroySync(Display(), mSync);
+ mSync = 0;
+ }
+
+ if (!mGL || !mGL->MakeCurrent())
+ return;
+
+ mGL->fDeleteTextures(1, &mProdTex);
+ mProdTex = 0;
+}
+
+layers::TextureFlags
+SharedSurface_EGLImage::GetTextureFlags() const
+{
+ return layers::TextureFlags::DEALLOCATE_CLIENT;
+}
+
+void
+SharedSurface_EGLImage::ProducerReleaseImpl()
+{
+ MutexAutoLock lock(mMutex);
+ mGL->MakeCurrent();
+
+ if (mEGL->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync) &&
+ mGL->IsExtensionSupported(GLContext::OES_EGL_sync))
+ {
+ if (mSync) {
+ MOZ_RELEASE_ASSERT(false, "GFX: Non-recycleable should not Fence twice.");
+ MOZ_ALWAYS_TRUE( mEGL->fDestroySync(Display(), mSync) );
+ mSync = 0;
+ }
+
+ mSync = mEGL->fCreateSync(Display(),
+ LOCAL_EGL_SYNC_FENCE,
+ nullptr);
+ if (mSync) {
+ mGL->fFlush();
+ return;
+ }
+ }
+
+ MOZ_ASSERT(!mSync);
+ mGL->fFinish();
+}
+
+void
+SharedSurface_EGLImage::ProducerReadAcquireImpl()
+{
+ // Wait on the fence, because presumably we're going to want to read this surface
+ if (mSync) {
+ mEGL->fClientWaitSync(Display(), mSync, 0, LOCAL_EGL_FOREVER);
+ }
+}
+
+EGLDisplay
+SharedSurface_EGLImage::Display() const
+{
+ return mEGL->Display();
+}
+
+bool
+SharedSurface_EGLImage::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
+{
+ *out_descriptor = layers::EGLImageDescriptor((uintptr_t)mImage, (uintptr_t)mSync,
+ mSize, mHasAlpha);
+ return true;
+}
+
+bool
+SharedSurface_EGLImage::ReadbackBySharedHandle(gfx::DataSourceSurface* out_surface)
+{
+ MOZ_ASSERT(out_surface);
+ MOZ_ASSERT(NS_IsMainThread());
+ return sEGLLibrary.ReadbackEGLImage(mImage, out_surface);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+/*static*/ UniquePtr<SurfaceFactory_EGLImage>
+SurfaceFactory_EGLImage::Create(GLContext* prodGL, const SurfaceCaps& caps,
+ const RefPtr<layers::LayersIPCChannel>& allocator,
+ const layers::TextureFlags& flags)
+{
+ EGLContext context = GLContextEGL::Cast(prodGL)->mContext;
+
+ typedef SurfaceFactory_EGLImage ptrT;
+ UniquePtr<ptrT> ret;
+
+ GLLibraryEGL* egl = &sEGLLibrary;
+ if (SharedSurface_EGLImage::HasExtensions(egl, prodGL)) {
+ ret.reset( new ptrT(prodGL, caps, allocator, flags, context) );
+ }
+
+ return Move(ret);
+}
+
+} // namespace gl
+
+} /* namespace mozilla */
diff --git a/gfx/gl/SharedSurfaceEGL.h b/gfx/gl/SharedSurfaceEGL.h
new file mode 100644
index 0000000000..98d0850058
--- /dev/null
+++ b/gfx/gl/SharedSurfaceEGL.h
@@ -0,0 +1,118 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef SHARED_SURFACE_EGL_H_
+#define SHARED_SURFACE_EGL_H_
+
+#include "mozilla/Attributes.h"
+#include "mozilla/Mutex.h"
+#include "SharedSurface.h"
+
+namespace mozilla {
+namespace gl {
+
+class GLContext;
+class GLLibraryEGL;
+class TextureGarbageBin;
+
+class SharedSurface_EGLImage
+ : public SharedSurface
+{
+public:
+ static UniquePtr<SharedSurface_EGLImage> Create(GLContext* prodGL,
+ const GLFormats& formats,
+ const gfx::IntSize& size,
+ bool hasAlpha,
+ EGLContext context);
+
+ static SharedSurface_EGLImage* Cast(SharedSurface* surf) {
+ MOZ_ASSERT(surf->mType == SharedSurfaceType::EGLImageShare);
+
+ return (SharedSurface_EGLImage*)surf;
+ }
+
+ static bool HasExtensions(GLLibraryEGL* egl, GLContext* gl);
+
+protected:
+ mutable Mutex mMutex;
+ GLLibraryEGL* const mEGL;
+ const GLFormats mFormats;
+ GLuint mProdTex;
+public:
+ const EGLImage mImage;
+protected:
+ EGLSync mSync;
+
+ SharedSurface_EGLImage(GLContext* gl,
+ GLLibraryEGL* egl,
+ const gfx::IntSize& size,
+ bool hasAlpha,
+ const GLFormats& formats,
+ GLuint prodTex,
+ EGLImage image);
+
+ EGLDisplay Display() const;
+ void UpdateProdTexture(const MutexAutoLock& curAutoLock);
+
+public:
+ virtual ~SharedSurface_EGLImage();
+
+ virtual layers::TextureFlags GetTextureFlags() const override;
+
+ virtual void LockProdImpl() override {}
+ virtual void UnlockProdImpl() override {}
+
+ virtual void ProducerAcquireImpl() override {}
+ virtual void ProducerReleaseImpl() override;
+
+ virtual void ProducerReadAcquireImpl() override;
+ virtual void ProducerReadReleaseImpl() override {};
+
+ virtual GLuint ProdTexture() override {
+ return mProdTex;
+ }
+
+ // Implementation-specific functions below:
+ // Returns texture and target
+ virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override;
+
+ virtual bool ReadbackBySharedHandle(gfx::DataSourceSurface* out_surface) override;
+};
+
+
+
+class SurfaceFactory_EGLImage
+ : public SurfaceFactory
+{
+public:
+ // Fallible:
+ static UniquePtr<SurfaceFactory_EGLImage> Create(GLContext* prodGL,
+ const SurfaceCaps& caps,
+ const RefPtr<layers::LayersIPCChannel>& allocator,
+ const layers::TextureFlags& flags);
+
+protected:
+ const EGLContext mContext;
+
+ SurfaceFactory_EGLImage(GLContext* prodGL, const SurfaceCaps& caps,
+ const RefPtr<layers::LayersIPCChannel>& allocator,
+ const layers::TextureFlags& flags,
+ EGLContext context)
+ : SurfaceFactory(SharedSurfaceType::EGLImageShare, prodGL, caps, allocator, flags)
+ , mContext(context)
+ { }
+
+public:
+ virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
+ bool hasAlpha = mReadCaps.alpha;
+ return SharedSurface_EGLImage::Create(mGL, mFormats, size, hasAlpha, mContext);
+ }
+};
+
+} // namespace gl
+
+} /* namespace mozilla */
+
+#endif /* SHARED_SURFACE_EGL_H_ */
diff --git a/gfx/gl/SharedSurfaceGL.cpp b/gfx/gl/SharedSurfaceGL.cpp
new file mode 100644
index 0000000000..6fba1b4ebf
--- /dev/null
+++ b/gfx/gl/SharedSurfaceGL.cpp
@@ -0,0 +1,190 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "SharedSurfaceGL.h"
+
+#include "GLBlitHelper.h"
+#include "GLContext.h"
+#include "GLReadTexImageHelper.h"
+#include "mozilla/gfx/2D.h"
+#include "ScopedGLHelpers.h"
+
+namespace mozilla {
+namespace gl {
+
+using gfx::IntSize;
+using gfx::SurfaceFormat;
+
+/*static*/ UniquePtr<SharedSurface_Basic>
+SharedSurface_Basic::Create(GLContext* gl,
+ const GLFormats& formats,
+ const IntSize& size,
+ bool hasAlpha)
+{
+ UniquePtr<SharedSurface_Basic> ret;
+ gl->MakeCurrent();
+
+ GLContext::LocalErrorScope localError(*gl);
+ GLuint tex = CreateTextureForOffscreen(gl, formats, size);
+
+ GLenum err = localError.GetError();
+ MOZ_ASSERT_IF(err != LOCAL_GL_NO_ERROR, err == LOCAL_GL_OUT_OF_MEMORY);
+ if (err) {
+ gl->fDeleteTextures(1, &tex);
+ return Move(ret);
+ }
+
+ bool ownsTex = true;
+ ret.reset( new SharedSurface_Basic(gl, size, hasAlpha, tex, ownsTex) );
+ return Move(ret);
+}
+
+
+/*static*/ UniquePtr<SharedSurface_Basic>
+SharedSurface_Basic::Wrap(GLContext* gl,
+ const IntSize& size,
+ bool hasAlpha,
+ GLuint tex)
+{
+ bool ownsTex = false;
+ UniquePtr<SharedSurface_Basic> ret( new SharedSurface_Basic(gl, size, hasAlpha, tex,
+ ownsTex) );
+ return Move(ret);
+}
+
+SharedSurface_Basic::SharedSurface_Basic(GLContext* gl,
+ const IntSize& size,
+ bool hasAlpha,
+ GLuint tex,
+ bool ownsTex)
+ : SharedSurface(SharedSurfaceType::Basic,
+ AttachmentType::GLTexture,
+ gl,
+ size,
+ hasAlpha,
+ true)
+ , mTex(tex)
+ , mOwnsTex(ownsTex)
+ , mFB(0)
+{
+ mGL->MakeCurrent();
+ mGL->fGenFramebuffers(1, &mFB);
+
+ ScopedBindFramebuffer autoFB(mGL, mFB);
+ mGL->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
+ LOCAL_GL_COLOR_ATTACHMENT0,
+ LOCAL_GL_TEXTURE_2D,
+ mTex,
+ 0);
+
+ DebugOnly<GLenum> status = mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
+ MOZ_ASSERT(status == LOCAL_GL_FRAMEBUFFER_COMPLETE);
+}
+
+SharedSurface_Basic::~SharedSurface_Basic()
+{
+ if (!mGL || !mGL->MakeCurrent())
+ return;
+
+ if (mFB)
+ mGL->fDeleteFramebuffers(1, &mFB);
+
+ if (mOwnsTex)
+ mGL->fDeleteTextures(1, &mTex);
+}
+
+
+////////////////////////////////////////////////////////////////////////
+
+SurfaceFactory_Basic::SurfaceFactory_Basic(GLContext* gl, const SurfaceCaps& caps,
+ const layers::TextureFlags& flags)
+ : SurfaceFactory(SharedSurfaceType::Basic, gl, caps, nullptr, flags)
+{ }
+
+
+////////////////////////////////////////////////////////////////////////
+// SharedSurface_GLTexture
+
+/*static*/ UniquePtr<SharedSurface_GLTexture>
+SharedSurface_GLTexture::Create(GLContext* prodGL,
+ const GLFormats& formats,
+ const IntSize& size,
+ bool hasAlpha)
+{
+ MOZ_ASSERT(prodGL);
+
+ prodGL->MakeCurrent();
+
+ UniquePtr<SharedSurface_GLTexture> ret;
+ GLContext::LocalErrorScope localError(*prodGL);
+
+ GLuint tex = CreateTextureForOffscreen(prodGL, formats, size);
+
+ GLenum err = localError.GetError();
+ MOZ_ASSERT_IF(err, err == LOCAL_GL_OUT_OF_MEMORY);
+ if (err) {
+ prodGL->fDeleteTextures(1, &tex);
+ return Move(ret);
+ }
+
+ ret.reset(new SharedSurface_GLTexture(prodGL, size,
+ hasAlpha, tex));
+ return Move(ret);
+}
+
+SharedSurface_GLTexture::~SharedSurface_GLTexture()
+{
+ if (!mGL->MakeCurrent())
+ return;
+
+ if (mTex) {
+ mGL->fDeleteTextures(1, &mTex);
+ }
+
+ if (mSync) {
+ mGL->fDeleteSync(mSync);
+ }
+}
+
+void
+SharedSurface_GLTexture::ProducerReleaseImpl()
+{
+ mGL->MakeCurrent();
+
+ if (mGL->IsSupported(GLFeature::sync)) {
+ if (mSync) {
+ mGL->fDeleteSync(mSync);
+ mSync = 0;
+ }
+
+ mSync = mGL->fFenceSync(LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+ if (mSync) {
+ mGL->fFlush();
+ return;
+ }
+ }
+ MOZ_ASSERT(!mSync);
+
+ mGL->fFinish();
+}
+
+bool
+SharedSurface_GLTexture::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
+{
+ *out_descriptor = layers::SurfaceDescriptorSharedGLTexture(ProdTexture(),
+ ProdTextureTarget(),
+ (uintptr_t)mSync,
+ mSize,
+ mHasAlpha);
+
+ // Transfer ownership of the fence to the host
+ mSync = nullptr;
+ return true;
+}
+
+
+} // namespace gl
+
+} /* namespace mozilla */
diff --git a/gfx/gl/SharedSurfaceGL.h b/gfx/gl/SharedSurfaceGL.h
new file mode 100644
index 0000000000..7574452710
--- /dev/null
+++ b/gfx/gl/SharedSurfaceGL.h
@@ -0,0 +1,167 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef SHARED_SURFACE_GL_H_
+#define SHARED_SURFACE_GL_H_
+
+#include "ScopedGLHelpers.h"
+#include "SharedSurface.h"
+#include "SurfaceTypes.h"
+#include "GLContextTypes.h"
+#include "gfxTypes.h"
+#include "mozilla/Mutex.h"
+
+#include <queue>
+
+namespace mozilla {
+ namespace gl {
+ class GLContext;
+ } // namespace gl
+ namespace gfx {
+ class DataSourceSurface;
+ } // namespace gfx
+} // namespace mozilla
+
+namespace mozilla {
+namespace gl {
+
+// For readback and bootstrapping:
+class SharedSurface_Basic
+ : public SharedSurface
+{
+public:
+ static UniquePtr<SharedSurface_Basic> Create(GLContext* gl,
+ const GLFormats& formats,
+ const gfx::IntSize& size,
+ bool hasAlpha);
+
+ static UniquePtr<SharedSurface_Basic> Wrap(GLContext* gl,
+ const gfx::IntSize& size,
+ bool hasAlpha,
+ GLuint tex);
+
+ static SharedSurface_Basic* Cast(SharedSurface* surf) {
+ MOZ_ASSERT(surf->mType == SharedSurfaceType::Basic);
+
+ return (SharedSurface_Basic*)surf;
+ }
+
+protected:
+ const GLuint mTex;
+ const bool mOwnsTex;
+ GLuint mFB;
+
+ SharedSurface_Basic(GLContext* gl,
+ const gfx::IntSize& size,
+ bool hasAlpha,
+ GLuint tex,
+ bool ownsTex);
+
+public:
+ virtual ~SharedSurface_Basic();
+
+ virtual void LockProdImpl() override {}
+ virtual void UnlockProdImpl() override {}
+
+ virtual void ProducerAcquireImpl() override {}
+ virtual void ProducerReleaseImpl() override {}
+
+ virtual GLuint ProdTexture() override {
+ return mTex;
+ }
+
+ virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override {
+ MOZ_CRASH("GFX: ToSurfaceDescriptor");
+ return false;
+ }
+};
+
+class SurfaceFactory_Basic
+ : public SurfaceFactory
+{
+public:
+ SurfaceFactory_Basic(GLContext* gl, const SurfaceCaps& caps,
+ const layers::TextureFlags& flags);
+
+ virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
+ bool hasAlpha = mReadCaps.alpha;
+ return SharedSurface_Basic::Create(mGL, mFormats, size, hasAlpha);
+ }
+};
+
+
+// Using shared GL textures:
+class SharedSurface_GLTexture
+ : public SharedSurface
+{
+public:
+ static UniquePtr<SharedSurface_GLTexture> Create(GLContext* prodGL,
+ const GLFormats& formats,
+ const gfx::IntSize& size,
+ bool hasAlpha);
+
+ static SharedSurface_GLTexture* Cast(SharedSurface* surf) {
+ MOZ_ASSERT(surf->mType == SharedSurfaceType::SharedGLTexture);
+
+ return (SharedSurface_GLTexture*)surf;
+ }
+
+protected:
+ const GLuint mTex;
+ GLsync mSync;
+
+ SharedSurface_GLTexture(GLContext* prodGL,
+ const gfx::IntSize& size,
+ bool hasAlpha,
+ GLuint tex)
+ : SharedSurface(SharedSurfaceType::SharedGLTexture,
+ AttachmentType::GLTexture,
+ prodGL,
+ size,
+ hasAlpha, true)
+ , mTex(tex)
+ , mSync(0)
+ {
+ }
+
+public:
+ virtual ~SharedSurface_GLTexture();
+
+ virtual void LockProdImpl() override {}
+ virtual void UnlockProdImpl() override {}
+
+ virtual void ProducerAcquireImpl() override {}
+ virtual void ProducerReleaseImpl() override;
+
+ virtual GLuint ProdTexture() override {
+ return mTex;
+ }
+
+ virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override;
+};
+
+class SurfaceFactory_GLTexture
+ : public SurfaceFactory
+{
+public:
+ SurfaceFactory_GLTexture(GLContext* prodGL,
+ const SurfaceCaps& caps,
+ const RefPtr<layers::LayersIPCChannel>& allocator,
+ const layers::TextureFlags& flags)
+ : SurfaceFactory(SharedSurfaceType::SharedGLTexture, prodGL, caps, allocator, flags)
+ {
+ }
+
+ virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
+ bool hasAlpha = mReadCaps.alpha;
+ return SharedSurface_GLTexture::Create(mGL, mFormats, size, hasAlpha);
+ }
+};
+
+} // namespace gl
+
+} /* namespace mozilla */
+
+#endif /* SHARED_SURFACE_GL_H_ */
diff --git a/gfx/gl/SharedSurfaceGLX.cpp b/gfx/gl/SharedSurfaceGLX.cpp
new file mode 100644
index 0000000000..69bee24bad
--- /dev/null
+++ b/gfx/gl/SharedSurfaceGLX.cpp
@@ -0,0 +1,144 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "SharedSurfaceGLX.h"
+#include "gfxXlibSurface.h"
+#include "GLXLibrary.h"
+#include "GLContextProvider.h"
+#include "GLContextGLX.h"
+#include "GLScreenBuffer.h"
+#include "mozilla/gfx/SourceSurfaceCairo.h"
+#include "mozilla/layers/LayersSurfaces.h"
+#include "mozilla/layers/ShadowLayerUtilsX11.h"
+#include "mozilla/layers/ISurfaceAllocator.h"
+#include "mozilla/layers/TextureForwarder.h"
+#include "mozilla/X11Util.h"
+
+namespace mozilla {
+namespace gl {
+
+/* static */
+UniquePtr<SharedSurface_GLXDrawable>
+SharedSurface_GLXDrawable::Create(GLContext* prodGL,
+ const SurfaceCaps& caps,
+ const gfx::IntSize& size,
+ bool deallocateClient,
+ bool inSameProcess)
+{
+ UniquePtr<SharedSurface_GLXDrawable> ret;
+ Display* display = DefaultXDisplay();
+ Screen* screen = XDefaultScreenOfDisplay(display);
+ Visual* visual = gfxXlibSurface::FindVisual(screen, gfx::SurfaceFormat::A8R8G8B8_UINT32);
+
+ RefPtr<gfxXlibSurface> surf = gfxXlibSurface::Create(screen, visual, size);
+ if (!deallocateClient)
+ surf->ReleasePixmap();
+
+ ret.reset(new SharedSurface_GLXDrawable(prodGL, size, inSameProcess, surf));
+ return Move(ret);
+}
+
+
+SharedSurface_GLXDrawable::SharedSurface_GLXDrawable(GLContext* gl,
+ const gfx::IntSize& size,
+ bool inSameProcess,
+ const RefPtr<gfxXlibSurface>& xlibSurface)
+ : SharedSurface(SharedSurfaceType::GLXDrawable,
+ AttachmentType::Screen,
+ gl,
+ size,
+ true,
+ true)
+ , mXlibSurface(xlibSurface)
+ , mInSameProcess(inSameProcess)
+{}
+
+void
+SharedSurface_GLXDrawable::ProducerReleaseImpl()
+{
+ mGL->MakeCurrent();
+ mGL->fFlush();
+}
+
+void
+SharedSurface_GLXDrawable::LockProdImpl()
+{
+ mGL->Screen()->SetReadBuffer(LOCAL_GL_FRONT);
+ GLContextGLX::Cast(mGL)->OverrideDrawable(mXlibSurface->GetGLXPixmap());
+}
+
+void
+SharedSurface_GLXDrawable::UnlockProdImpl()
+{
+ GLContextGLX::Cast(mGL)->RestoreDrawable();
+}
+
+bool
+SharedSurface_GLXDrawable::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
+{
+ if (!mXlibSurface)
+ return false;
+
+ *out_descriptor = layers::SurfaceDescriptorX11(mXlibSurface, mInSameProcess);
+ return true;
+}
+
+bool
+SharedSurface_GLXDrawable::ReadbackBySharedHandle(gfx::DataSourceSurface* out_surface)
+{
+ MOZ_ASSERT(out_surface);
+ RefPtr<gfx::DataSourceSurface> dataSurf =
+ new gfx::DataSourceSurfaceCairo(mXlibSurface->CairoSurface());
+
+ gfx::DataSourceSurface::ScopedMap mapSrc(dataSurf, gfx::DataSourceSurface::READ);
+ if (!mapSrc.IsMapped()) {
+ return false;
+ }
+
+ gfx::DataSourceSurface::ScopedMap mapDest(out_surface, gfx::DataSourceSurface::WRITE);
+ if (!mapDest.IsMapped()) {
+ return false;
+ }
+
+ if (mapDest.GetStride() == mapSrc.GetStride()) {
+ memcpy(mapDest.GetData(),
+ mapSrc.GetData(),
+ out_surface->GetSize().height * mapDest.GetStride());
+ } else {
+ for (int32_t i = 0; i < dataSurf->GetSize().height; i++) {
+ memcpy(mapDest.GetData() + i * mapDest.GetStride(),
+ mapSrc.GetData() + i * mapSrc.GetStride(),
+ std::min(mapSrc.GetStride(), mapDest.GetStride()));
+ }
+ }
+
+ return true;
+}
+
+/* static */
+UniquePtr<SurfaceFactory_GLXDrawable>
+SurfaceFactory_GLXDrawable::Create(GLContext* prodGL,
+ const SurfaceCaps& caps,
+ const RefPtr<layers::LayersIPCChannel>& allocator,
+ const layers::TextureFlags& flags)
+{
+ MOZ_ASSERT(caps.alpha, "GLX surfaces require an alpha channel!");
+
+ typedef SurfaceFactory_GLXDrawable ptrT;
+ UniquePtr<ptrT> ret(new ptrT(prodGL, caps, allocator,
+ flags & ~layers::TextureFlags::ORIGIN_BOTTOM_LEFT));
+ return Move(ret);
+}
+
+UniquePtr<SharedSurface>
+SurfaceFactory_GLXDrawable::CreateShared(const gfx::IntSize& size)
+{
+ bool deallocateClient = !!(mFlags & layers::TextureFlags::DEALLOCATE_CLIENT);
+ return SharedSurface_GLXDrawable::Create(mGL, mCaps, size, deallocateClient,
+ mAllocator->IsSameProcess());
+}
+
+} // namespace gl
+} // namespace mozilla
diff --git a/gfx/gl/SharedSurfaceGLX.h b/gfx/gl/SharedSurfaceGLX.h
new file mode 100644
index 0000000000..19a0338b26
--- /dev/null
+++ b/gfx/gl/SharedSurfaceGLX.h
@@ -0,0 +1,68 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef SHARED_SURFACE_GLX_H_
+#define SHARED_SURFACE_GLX_H_
+
+#include "SharedSurface.h"
+#include "mozilla/RefPtr.h"
+
+class gfxXlibSurface;
+
+namespace mozilla {
+namespace gl {
+
+class SharedSurface_GLXDrawable
+ : public SharedSurface
+{
+public:
+ static UniquePtr<SharedSurface_GLXDrawable> Create(GLContext* prodGL,
+ const SurfaceCaps& caps,
+ const gfx::IntSize& size,
+ bool deallocateClient,
+ bool inSameProcess);
+
+ virtual void ProducerAcquireImpl() override {}
+ virtual void ProducerReleaseImpl() override;
+
+ virtual void LockProdImpl() override;
+ virtual void UnlockProdImpl() override;
+
+ virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override;
+
+ virtual bool ReadbackBySharedHandle(gfx::DataSourceSurface* out_surface) override;
+private:
+ SharedSurface_GLXDrawable(GLContext* gl,
+ const gfx::IntSize& size,
+ bool inSameProcess,
+ const RefPtr<gfxXlibSurface>& xlibSurface);
+
+ RefPtr<gfxXlibSurface> mXlibSurface;
+ bool mInSameProcess;
+};
+
+class SurfaceFactory_GLXDrawable
+ : public SurfaceFactory
+{
+public:
+ static UniquePtr<SurfaceFactory_GLXDrawable> Create(GLContext* prodGL,
+ const SurfaceCaps& caps,
+ const RefPtr<layers::LayersIPCChannel>& allocator,
+ const layers::TextureFlags& flags);
+
+ virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override;
+
+private:
+ SurfaceFactory_GLXDrawable(GLContext* prodGL, const SurfaceCaps& caps,
+ const RefPtr<layers::LayersIPCChannel>& allocator,
+ const layers::TextureFlags& flags)
+ : SurfaceFactory(SharedSurfaceType::GLXDrawable, prodGL, caps, allocator, flags)
+ { }
+};
+
+} // namespace gl
+} // namespace mozilla
+
+#endif // SHARED_SURFACE_GLX_H_
diff --git a/gfx/gl/SharedSurfaceIO.cpp b/gfx/gl/SharedSurfaceIO.cpp
new file mode 100644
index 0000000000..50262d6cce
--- /dev/null
+++ b/gfx/gl/SharedSurfaceIO.cpp
@@ -0,0 +1,248 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "SharedSurfaceIO.h"
+
+#include "GLContextCGL.h"
+#include "mozilla/DebugOnly.h"
+#include "mozilla/gfx/MacIOSurface.h"
+#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc
+#include "ScopedGLHelpers.h"
+
+namespace mozilla {
+namespace gl {
+
+/*static*/ UniquePtr<SharedSurface_IOSurface>
+SharedSurface_IOSurface::Create(const RefPtr<MacIOSurface>& ioSurf,
+ GLContext* gl,
+ bool hasAlpha)
+{
+ MOZ_ASSERT(ioSurf);
+ MOZ_ASSERT(gl);
+
+ auto size = gfx::IntSize::Truncate(ioSurf->GetWidth(), ioSurf->GetHeight());
+
+ typedef SharedSurface_IOSurface ptrT;
+ UniquePtr<ptrT> ret( new ptrT(ioSurf, gl, size, hasAlpha) );
+ return Move(ret);
+}
+
+void
+SharedSurface_IOSurface::ProducerReleaseImpl()
+{
+ mGL->MakeCurrent();
+ mGL->fFlush();
+}
+
+bool
+SharedSurface_IOSurface::CopyTexImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLint border)
+{
+ /* Bug 896693 - OpenGL framebuffers that are backed by IOSurface on OSX expose a bug
+ * in glCopyTexImage2D --- internalformats GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA
+ * return the wrong results. To work around, copy framebuffer to a temporary texture
+ * using GL_RGBA (which works), attach as read framebuffer and glCopyTexImage2D
+ * instead.
+ */
+
+ // https://www.opengl.org/sdk/docs/man3/xhtml/glCopyTexImage2D.xml says that width or
+ // height set to 0 results in a NULL texture. Lets not do any work and punt to
+ // original glCopyTexImage2D, since the FBO below will fail when trying to attach a
+ // texture of 0 width or height.
+ if (width == 0 || height == 0)
+ return false;
+
+ switch (internalformat) {
+ case LOCAL_GL_ALPHA:
+ case LOCAL_GL_LUMINANCE:
+ case LOCAL_GL_LUMINANCE_ALPHA:
+ break;
+
+ default:
+ return false;
+ }
+
+ MOZ_ASSERT(mGL->IsCurrent());
+
+ ScopedTexture destTex(mGL);
+ {
+ ScopedBindTexture bindTex(mGL, destTex.Texture());
+ mGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER,
+ LOCAL_GL_NEAREST);
+ mGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER,
+ LOCAL_GL_NEAREST);
+ mGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S,
+ LOCAL_GL_CLAMP_TO_EDGE);
+ mGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T,
+ LOCAL_GL_CLAMP_TO_EDGE);
+ mGL->raw_fCopyTexImage2D(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_RGBA, x, y, width,
+ height, 0);
+ }
+
+ ScopedFramebufferForTexture tmpFB(mGL, destTex.Texture(), LOCAL_GL_TEXTURE_2D);
+ ScopedBindFramebuffer bindFB(mGL, tmpFB.FB());
+ mGL->raw_fCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
+
+ return true;
+}
+
+bool
+SharedSurface_IOSurface::ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, GLvoid* pixels)
+{
+ // Calling glReadPixels when an IOSurface is bound to the current framebuffer
+ // can cause corruption in following glReadPixel calls (even if they aren't
+ // reading from an IOSurface).
+ // We workaround this by copying to a temporary texture, and doing the readback
+ // from that.
+ MOZ_ASSERT(mGL->IsCurrent());
+
+ ScopedTexture destTex(mGL);
+ {
+ ScopedFramebufferForTexture srcFB(mGL, ProdTexture(), ProdTextureTarget());
+
+ ScopedBindFramebuffer bindFB(mGL, srcFB.FB());
+ ScopedBindTexture bindTex(mGL, destTex.Texture());
+ mGL->raw_fCopyTexImage2D(LOCAL_GL_TEXTURE_2D, 0,
+ mHasAlpha ? LOCAL_GL_RGBA : LOCAL_GL_RGB,
+ x, y,
+ width, height, 0);
+ }
+
+ ScopedFramebufferForTexture destFB(mGL, destTex.Texture());
+
+ ScopedBindFramebuffer bindFB(mGL, destFB.FB());
+ mGL->raw_fReadPixels(0, 0, width, height, format, type, pixels);
+ return true;
+}
+
+static void
+BackTextureWithIOSurf(GLContext* gl, GLuint tex, MacIOSurface* ioSurf)
+{
+ MOZ_ASSERT(gl->IsCurrent());
+
+ ScopedBindTexture texture(gl, tex, LOCAL_GL_TEXTURE_RECTANGLE_ARB);
+
+ gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
+ LOCAL_GL_TEXTURE_MIN_FILTER,
+ LOCAL_GL_LINEAR);
+ gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
+ LOCAL_GL_TEXTURE_MAG_FILTER,
+ LOCAL_GL_LINEAR);
+ gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
+ LOCAL_GL_TEXTURE_WRAP_S,
+ LOCAL_GL_CLAMP_TO_EDGE);
+ gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
+ LOCAL_GL_TEXTURE_WRAP_T,
+ LOCAL_GL_CLAMP_TO_EDGE);
+
+ CGLContextObj cgl = GLContextCGL::Cast(gl)->GetCGLContext();
+ MOZ_ASSERT(cgl);
+
+ ioSurf->CGLTexImageIOSurface2D(cgl);
+}
+
+SharedSurface_IOSurface::SharedSurface_IOSurface(const RefPtr<MacIOSurface>& ioSurf,
+ GLContext* gl,
+ const gfx::IntSize& size,
+ bool hasAlpha)
+ : SharedSurface(SharedSurfaceType::IOSurface,
+ AttachmentType::GLTexture,
+ gl,
+ size,
+ hasAlpha,
+ true)
+ , mIOSurf(ioSurf)
+{
+ gl->MakeCurrent();
+ mProdTex = 0;
+ gl->fGenTextures(1, &mProdTex);
+ BackTextureWithIOSurf(gl, mProdTex, mIOSurf);
+}
+
+SharedSurface_IOSurface::~SharedSurface_IOSurface()
+{
+ if (!mGL || !mGL->MakeCurrent())
+ return;
+
+ mGL->fDeleteTextures(1, &mProdTex);
+}
+
+bool
+SharedSurface_IOSurface::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
+{
+ bool isOpaque = !mHasAlpha;
+ *out_descriptor = layers::SurfaceDescriptorMacIOSurface(mIOSurf->GetIOSurfaceID(),
+ mIOSurf->GetContentsScaleFactor(),
+ isOpaque);
+ return true;
+}
+
+bool
+SharedSurface_IOSurface::ReadbackBySharedHandle(gfx::DataSourceSurface* out_surface)
+{
+ MOZ_ASSERT(out_surface);
+ mIOSurf->Lock();
+ size_t bytesPerRow = mIOSurf->GetBytesPerRow();
+ size_t ioWidth = mIOSurf->GetDevicePixelWidth();
+ size_t ioHeight = mIOSurf->GetDevicePixelHeight();
+
+ const unsigned char* ioData = (unsigned char*)mIOSurf->GetBaseAddress();
+ gfx::DataSourceSurface::ScopedMap map(out_surface, gfx::DataSourceSurface::WRITE);
+ if (!map.IsMapped()) {
+ mIOSurf->Unlock();
+ return false;
+ }
+
+ for (size_t i = 0; i < ioHeight; i++) {
+ memcpy(map.GetData() + i * map.GetStride(),
+ ioData + i * bytesPerRow, ioWidth * 4);
+ }
+
+ mIOSurf->Unlock();
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////
+// SurfaceFactory_IOSurface
+
+/*static*/ UniquePtr<SurfaceFactory_IOSurface>
+SurfaceFactory_IOSurface::Create(GLContext* gl, const SurfaceCaps& caps,
+ const RefPtr<layers::LayersIPCChannel>& allocator,
+ const layers::TextureFlags& flags)
+{
+ auto maxDims = gfx::IntSize::Truncate(MacIOSurface::GetMaxWidth(),
+ MacIOSurface::GetMaxHeight());
+
+ typedef SurfaceFactory_IOSurface ptrT;
+ UniquePtr<ptrT> ret( new ptrT(gl, caps, allocator, flags, maxDims) );
+ return Move(ret);
+}
+
+UniquePtr<SharedSurface>
+SurfaceFactory_IOSurface::CreateShared(const gfx::IntSize& size)
+{
+ if (size.width > mMaxDims.width ||
+ size.height > mMaxDims.height)
+ {
+ return nullptr;
+ }
+
+ bool hasAlpha = mReadCaps.alpha;
+ RefPtr<MacIOSurface> ioSurf;
+ ioSurf = MacIOSurface::CreateIOSurface(size.width, size.height, 1.0,
+ hasAlpha);
+
+ if (!ioSurf) {
+ NS_WARNING("Failed to create MacIOSurface.");
+ return nullptr;
+ }
+
+ return SharedSurface_IOSurface::Create(ioSurf, mGL, hasAlpha);
+}
+
+} // namespace gl
+} // namespace mozilla
diff --git a/gfx/gl/SharedSurfaceIO.h b/gfx/gl/SharedSurfaceIO.h
new file mode 100644
index 0000000000..16e0cbbb7f
--- /dev/null
+++ b/gfx/gl/SharedSurfaceIO.h
@@ -0,0 +1,100 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef SHARED_SURFACEIO_H_
+#define SHARED_SURFACEIO_H_
+
+#include "mozilla/RefPtr.h"
+#include "SharedSurface.h"
+
+class MacIOSurface;
+
+namespace mozilla {
+namespace gl {
+
+class SharedSurface_IOSurface : public SharedSurface
+{
+private:
+ const RefPtr<MacIOSurface> mIOSurf;
+ GLuint mProdTex;
+
+public:
+ static UniquePtr<SharedSurface_IOSurface> Create(const RefPtr<MacIOSurface>& ioSurf,
+ GLContext* gl,
+ bool hasAlpha);
+
+private:
+ SharedSurface_IOSurface(const RefPtr<MacIOSurface>& ioSurf,
+ GLContext* gl, const gfx::IntSize& size,
+ bool hasAlpha);
+
+public:
+ ~SharedSurface_IOSurface();
+
+ virtual void LockProdImpl() override { }
+ virtual void UnlockProdImpl() override { }
+
+ virtual void ProducerAcquireImpl() override {}
+ virtual void ProducerReleaseImpl() override;
+
+ virtual bool CopyTexImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLint border) override;
+ virtual bool ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, GLvoid* pixels) override;
+
+ virtual GLuint ProdTexture() override {
+ return mProdTex;
+ }
+
+ virtual GLenum ProdTextureTarget() const override {
+ return LOCAL_GL_TEXTURE_RECTANGLE_ARB;
+ }
+
+ static SharedSurface_IOSurface* Cast(SharedSurface* surf) {
+ MOZ_ASSERT(surf->mType == SharedSurfaceType::IOSurface);
+ return static_cast<SharedSurface_IOSurface*>(surf);
+ }
+
+ MacIOSurface* GetIOSurface() const {
+ return mIOSurf;
+ }
+
+ virtual bool NeedsIndirectReads() const override {
+ return true;
+ }
+
+ virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override;
+
+ virtual bool ReadbackBySharedHandle(gfx::DataSourceSurface* out_surface) override;
+};
+
+class SurfaceFactory_IOSurface : public SurfaceFactory
+{
+public:
+ // Infallible.
+ static UniquePtr<SurfaceFactory_IOSurface> Create(GLContext* gl,
+ const SurfaceCaps& caps,
+ const RefPtr<layers::LayersIPCChannel>& allocator,
+ const layers::TextureFlags& flags);
+protected:
+ const gfx::IntSize mMaxDims;
+
+ SurfaceFactory_IOSurface(GLContext* gl, const SurfaceCaps& caps,
+ const RefPtr<layers::LayersIPCChannel>& allocator,
+ const layers::TextureFlags& flags,
+ const gfx::IntSize& maxDims)
+ : SurfaceFactory(SharedSurfaceType::IOSurface, gl, caps, allocator, flags)
+ , mMaxDims(maxDims)
+ { }
+
+ virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override;
+};
+
+} // namespace gl
+
+} /* namespace mozilla */
+
+#endif /* SHARED_SURFACEIO_H_ */
diff --git a/gfx/gl/SkiaGLGlue.cpp b/gfx/gl/SkiaGLGlue.cpp
new file mode 100755
index 0000000000..eb84934a66
--- /dev/null
+++ b/gfx/gl/SkiaGLGlue.cpp
@@ -0,0 +1,327 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "skia/include/gpu/GrContext.h"
+#include "skia/include/gpu/gl/GrGLInterface.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/ThreadLocal.h"
+#include "mozilla/DebugOnly.h"
+
+/* SkPostConfig.h includes windows.h, which includes windef.h
+ * which redefines min/max. We don't want that. */
+#ifdef _WIN32
+#undef min
+#undef max
+#endif
+
+#include "GLContext.h"
+#include "SkiaGLGlue.h"
+
+using mozilla::gl::GLContext;
+using mozilla::gl::GLFeature;
+using mozilla::gl::SkiaGLGlue;
+using mozilla::gfx::DrawTarget;
+
+template<typename R, typename... A>
+static inline GrGLFunction<R (*)(A...)>
+WrapGL(RefPtr<GLContext> aContext, R (GLContext::*aFunc)(A...))
+{
+ return [aContext, aFunc] (A... args) -> R
+ {
+ aContext->MakeCurrent();
+ return (aContext->*aFunc)(args...);
+ };
+}
+
+template<typename R, typename... A>
+static inline GrGLFunction<R (*)(A...)>
+WrapGL(RefPtr<GLContext> aContext, R (*aFunc)(GLContext*, A...))
+{
+ return [aContext, aFunc] (A... args) -> R
+ {
+ aContext->MakeCurrent();
+ return (*aFunc)(aContext, args...);
+ };
+}
+
+// Core GL functions required by Ganesh
+
+static const GLubyte*
+glGetString_mozilla(GLContext* aContext, GrGLenum aName)
+{
+ // GLContext only exposes a OpenGL 2.0 style API, so we have to intercept a bunch
+ // of checks that Ganesh makes to determine which capabilities are present
+ // on the GL implementation and change them to match what GLContext actually exposes.
+
+ if (aName == LOCAL_GL_VERSION) {
+ if (aContext->IsGLES()) {
+ return reinterpret_cast<const GLubyte*>("OpenGL ES 2.0");
+ } else {
+ return reinterpret_cast<const GLubyte*>("2.0");
+ }
+ } else if (aName == LOCAL_GL_EXTENSIONS) {
+ // Only expose the bare minimum extensions we want to support to ensure a functional Ganesh
+ // as GLContext only exposes certain extensions
+ static bool extensionsStringBuilt = false;
+ static char extensionsString[1024];
+
+ if (!extensionsStringBuilt) {
+ extensionsString[0] = '\0';
+
+ if (aContext->IsGLES()) {
+ // OES is only applicable to GLES2
+ if (aContext->IsExtensionSupported(GLContext::OES_packed_depth_stencil)) {
+ strcat(extensionsString, "GL_OES_packed_depth_stencil ");
+ }
+
+ if (aContext->IsExtensionSupported(GLContext::OES_rgb8_rgba8)) {
+ strcat(extensionsString, "GL_OES_rgb8_rgba8 ");
+ }
+
+ if (aContext->IsExtensionSupported(GLContext::OES_texture_npot)) {
+ strcat(extensionsString, "GL_OES_texture_npot ");
+ }
+
+ if (aContext->IsExtensionSupported(GLContext::OES_vertex_array_object)) {
+ strcat(extensionsString, "GL_OES_vertex_array_object ");
+ }
+
+ if (aContext->IsSupported(GLFeature::standard_derivatives)) {
+ strcat(extensionsString, "GL_OES_standard_derivatives ");
+ }
+ } else {
+ if (aContext->IsSupported(GLFeature::framebuffer_object)) {
+ strcat(extensionsString, "GL_ARB_framebuffer_object ");
+ } else if (aContext->IsExtensionSupported(GLContext::EXT_framebuffer_object)) {
+ strcat(extensionsString, "GL_EXT_framebuffer_object ");
+ }
+
+ if (aContext->IsSupported(GLFeature::texture_rg)) {
+ strcat(extensionsString, "GL_ARB_texture_rg ");
+ }
+ }
+
+ if (aContext->IsExtensionSupported(GLContext::EXT_texture_format_BGRA8888)) {
+ strcat(extensionsString, "GL_EXT_texture_format_BGRA8888 ");
+ }
+
+ if (aContext->IsExtensionSupported(GLContext::EXT_packed_depth_stencil)) {
+ strcat(extensionsString, "GL_EXT_packed_depth_stencil ");
+ }
+
+ if (aContext->IsExtensionSupported(GLContext::EXT_bgra)) {
+ strcat(extensionsString, "GL_EXT_bgra ");
+ }
+
+ if (aContext->IsExtensionSupported(GLContext::EXT_read_format_bgra)) {
+ strcat(extensionsString, "GL_EXT_read_format_bgra ");
+ }
+
+ extensionsStringBuilt = true;
+#ifdef DEBUG
+ printf_stderr("Exported SkiaGL extensions: %s\n", extensionsString);
+#endif
+ }
+
+ return reinterpret_cast<const GLubyte*>(extensionsString);
+
+ } else if (aName == LOCAL_GL_SHADING_LANGUAGE_VERSION) {
+ if (aContext->IsGLES()) {
+ return reinterpret_cast<const GLubyte*>("OpenGL ES GLSL ES 1.0");
+ } else {
+ return reinterpret_cast<const GLubyte*>("1.10");
+ }
+ }
+
+ return aContext->fGetString(aName);
+}
+
+static GrGLInterface* CreateGrGLInterfaceFromGLContext(GLContext* context)
+{
+ GrGLInterface* i = new GrGLInterface();
+
+ context->MakeCurrent();
+
+ // We support both desktop GL and GLES2
+ if (context->IsGLES()) {
+ i->fStandard = kGLES_GrGLStandard;
+ } else {
+ i->fStandard = kGL_GrGLStandard;
+ }
+
+ GrGLFunction<GrGLGetStringProc> getString = WrapGL(context, &glGetString_mozilla);
+ GrGLFunction<GrGLGetIntegervProc> getIntegerv = WrapGL(context, &GLContext::fGetIntegerv);
+
+ GrGLExtensions extensions;
+ if (!extensions.init(i->fStandard, getString, nullptr, getIntegerv)) {
+ delete i;
+ return nullptr;
+ }
+
+ i->fExtensions.swap(&extensions);
+
+ // Core GL functions required by Ganesh
+ i->fFunctions.fActiveTexture = WrapGL(context, &GLContext::fActiveTexture);
+ i->fFunctions.fAttachShader = WrapGL(context, &GLContext::fAttachShader);
+ i->fFunctions.fBindAttribLocation = WrapGL(context, &GLContext::fBindAttribLocation);
+ i->fFunctions.fBindBuffer = WrapGL(context, &GLContext::fBindBuffer);
+ i->fFunctions.fBindFramebuffer = WrapGL(context, &GLContext::fBindFramebuffer);
+ i->fFunctions.fBindRenderbuffer = WrapGL(context, &GLContext::fBindRenderbuffer);
+ i->fFunctions.fBindTexture = WrapGL(context, &GLContext::fBindTexture);
+ i->fFunctions.fBlendFunc = WrapGL(context, &GLContext::fBlendFunc);
+ i->fFunctions.fBlendColor = WrapGL(context, &GLContext::fBlendColor);
+ i->fFunctions.fBlendEquation = WrapGL(context, &GLContext::fBlendEquation);
+ i->fFunctions.fBufferData = WrapGL(context, &GLContext::fBufferData);
+ i->fFunctions.fBufferSubData = WrapGL(context, &GLContext::fBufferSubData);
+ i->fFunctions.fCheckFramebufferStatus = WrapGL(context, &GLContext::fCheckFramebufferStatus);
+ i->fFunctions.fClear = WrapGL(context, &GLContext::fClear);
+ i->fFunctions.fClearColor = WrapGL(context, &GLContext::fClearColor);
+ i->fFunctions.fClearStencil = WrapGL(context, &GLContext::fClearStencil);
+ i->fFunctions.fColorMask = WrapGL(context, &GLContext::fColorMask);
+ i->fFunctions.fCompileShader = WrapGL(context, &GLContext::fCompileShader);
+ i->fFunctions.fCopyTexSubImage2D = WrapGL(context, &GLContext::fCopyTexSubImage2D);
+ i->fFunctions.fCreateProgram = WrapGL(context, &GLContext::fCreateProgram);
+ i->fFunctions.fCreateShader = WrapGL(context, &GLContext::fCreateShader);
+ i->fFunctions.fCullFace = WrapGL(context, &GLContext::fCullFace);
+ i->fFunctions.fDeleteBuffers = WrapGL(context, &GLContext::fDeleteBuffers);
+ i->fFunctions.fDeleteFramebuffers = WrapGL(context, &GLContext::fDeleteFramebuffers);
+ i->fFunctions.fDeleteProgram = WrapGL(context, &GLContext::fDeleteProgram);
+ i->fFunctions.fDeleteRenderbuffers = WrapGL(context, &GLContext::fDeleteRenderbuffers);
+ i->fFunctions.fDeleteShader = WrapGL(context, &GLContext::fDeleteShader);
+ i->fFunctions.fDeleteTextures = WrapGL(context, &GLContext::fDeleteTextures);
+ i->fFunctions.fDepthMask = WrapGL(context, &GLContext::fDepthMask);
+ i->fFunctions.fDisable = WrapGL(context, &GLContext::fDisable);
+ i->fFunctions.fDisableVertexAttribArray = WrapGL(context, &GLContext::fDisableVertexAttribArray);
+ i->fFunctions.fDrawArrays = WrapGL(context, &GLContext::fDrawArrays);
+ i->fFunctions.fDrawElements = WrapGL(context, &GLContext::fDrawElements);
+ i->fFunctions.fDrawRangeElements = WrapGL(context, &GLContext::fDrawRangeElements);
+ i->fFunctions.fEnable = WrapGL(context, &GLContext::fEnable);
+ i->fFunctions.fEnableVertexAttribArray = WrapGL(context, &GLContext::fEnableVertexAttribArray);
+ i->fFunctions.fFinish = WrapGL(context, &GLContext::fFinish);
+ i->fFunctions.fFlush = WrapGL(context, &GLContext::fFlush);
+ i->fFunctions.fFramebufferRenderbuffer = WrapGL(context, &GLContext::fFramebufferRenderbuffer);
+ i->fFunctions.fFramebufferTexture2D = WrapGL(context, &GLContext::fFramebufferTexture2D);
+ i->fFunctions.fFrontFace = WrapGL(context, &GLContext::fFrontFace);
+ i->fFunctions.fGenBuffers = WrapGL(context, &GLContext::fGenBuffers);
+ i->fFunctions.fGenFramebuffers = WrapGL(context, &GLContext::fGenFramebuffers);
+ i->fFunctions.fGenRenderbuffers = WrapGL(context, &GLContext::fGenRenderbuffers);
+ i->fFunctions.fGetFramebufferAttachmentParameteriv = WrapGL(context, &GLContext::fGetFramebufferAttachmentParameteriv);
+ i->fFunctions.fGenTextures = WrapGL(context, &GLContext::fGenTextures);
+ i->fFunctions.fGenerateMipmap = WrapGL(context, &GLContext::fGenerateMipmap);
+ i->fFunctions.fGetBufferParameteriv = WrapGL(context, &GLContext::fGetBufferParameteriv);
+ i->fFunctions.fGetError = WrapGL(context, &GLContext::fGetError);
+ i->fFunctions.fGetIntegerv = getIntegerv;
+ i->fFunctions.fGetProgramInfoLog = WrapGL(context, &GLContext::fGetProgramInfoLog);
+ i->fFunctions.fGetProgramiv = WrapGL(context, &GLContext::fGetProgramiv);
+ i->fFunctions.fGetRenderbufferParameteriv = WrapGL(context, &GLContext::fGetRenderbufferParameteriv);
+ i->fFunctions.fGetShaderInfoLog = WrapGL(context, &GLContext::fGetShaderInfoLog);
+ i->fFunctions.fGetShaderiv = WrapGL(context, &GLContext::fGetShaderiv);
+ i->fFunctions.fGetShaderPrecisionFormat = WrapGL(context, &GLContext::fGetShaderPrecisionFormat);
+ i->fFunctions.fGetString = getString;
+ i->fFunctions.fGetUniformLocation = WrapGL(context, &GLContext::fGetUniformLocation);
+ i->fFunctions.fLineWidth = WrapGL(context, &GLContext::fLineWidth);
+ i->fFunctions.fLinkProgram = WrapGL(context, &GLContext::fLinkProgram);
+ i->fFunctions.fPixelStorei = WrapGL(context, &GLContext::fPixelStorei);
+ i->fFunctions.fReadPixels = WrapGL(context, &GLContext::fReadPixels);
+ i->fFunctions.fRenderbufferStorage = WrapGL(context, &GLContext::fRenderbufferStorage);
+ i->fFunctions.fScissor = WrapGL(context, &GLContext::fScissor);
+ i->fFunctions.fShaderSource = WrapGL(context, &GLContext::fShaderSource);
+ i->fFunctions.fStencilFunc = WrapGL(context, &GLContext::fStencilFunc);
+ i->fFunctions.fStencilMask = WrapGL(context, &GLContext::fStencilMask);
+ i->fFunctions.fStencilOp = WrapGL(context, &GLContext::fStencilOp);
+ i->fFunctions.fTexImage2D = WrapGL(context, &GLContext::fTexImage2D);
+ i->fFunctions.fTexParameteri = WrapGL(context, &GLContext::fTexParameteri);
+ i->fFunctions.fTexParameteriv = WrapGL(context, &GLContext::fTexParameteriv);
+ i->fFunctions.fTexSubImage2D = WrapGL(context, &GLContext::fTexSubImage2D);
+ i->fFunctions.fUniform1f = WrapGL(context, &GLContext::fUniform1f);
+ i->fFunctions.fUniform1i = WrapGL(context, &GLContext::fUniform1i);
+ i->fFunctions.fUniform1fv = WrapGL(context, &GLContext::fUniform1fv);
+ i->fFunctions.fUniform1iv = WrapGL(context, &GLContext::fUniform1iv);
+ i->fFunctions.fUniform2f = WrapGL(context, &GLContext::fUniform2f);
+ i->fFunctions.fUniform2i = WrapGL(context, &GLContext::fUniform2i);
+ i->fFunctions.fUniform2fv = WrapGL(context, &GLContext::fUniform2fv);
+ i->fFunctions.fUniform2iv = WrapGL(context, &GLContext::fUniform2iv);
+ i->fFunctions.fUniform3f = WrapGL(context, &GLContext::fUniform3f);
+ i->fFunctions.fUniform3i = WrapGL(context, &GLContext::fUniform3i);
+ i->fFunctions.fUniform3fv = WrapGL(context, &GLContext::fUniform3fv);
+ i->fFunctions.fUniform3iv = WrapGL(context, &GLContext::fUniform3iv);
+ i->fFunctions.fUniform4f = WrapGL(context, &GLContext::fUniform4f);
+ i->fFunctions.fUniform4i = WrapGL(context, &GLContext::fUniform4i);
+ i->fFunctions.fUniform4fv = WrapGL(context, &GLContext::fUniform4fv);
+ i->fFunctions.fUniform4iv = WrapGL(context, &GLContext::fUniform4iv);
+ i->fFunctions.fUniformMatrix2fv = WrapGL(context, &GLContext::fUniformMatrix2fv);
+ i->fFunctions.fUniformMatrix3fv = WrapGL(context, &GLContext::fUniformMatrix3fv);
+ i->fFunctions.fUniformMatrix4fv = WrapGL(context, &GLContext::fUniformMatrix4fv);
+ i->fFunctions.fUseProgram = WrapGL(context, &GLContext::fUseProgram);
+ i->fFunctions.fVertexAttrib1f = WrapGL(context, &GLContext::fVertexAttrib1f);
+ i->fFunctions.fVertexAttrib2fv = WrapGL(context, &GLContext::fVertexAttrib2fv);
+ i->fFunctions.fVertexAttrib3fv = WrapGL(context, &GLContext::fVertexAttrib3fv);
+ i->fFunctions.fVertexAttrib4fv = WrapGL(context, &GLContext::fVertexAttrib4fv);
+ i->fFunctions.fVertexAttribPointer = WrapGL(context, &GLContext::fVertexAttribPointer);
+ i->fFunctions.fViewport = WrapGL(context, &GLContext::fViewport);
+
+ // Required for either desktop OpenGL 2.0 or OpenGL ES 2.0
+ i->fFunctions.fStencilFuncSeparate = WrapGL(context, &GLContext::fStencilFuncSeparate);
+ i->fFunctions.fStencilMaskSeparate = WrapGL(context, &GLContext::fStencilMaskSeparate);
+ i->fFunctions.fStencilOpSeparate = WrapGL(context, &GLContext::fStencilOpSeparate);
+
+ // GLContext supports glMapBuffer
+ i->fFunctions.fMapBuffer = WrapGL(context, &GLContext::fMapBuffer);
+ i->fFunctions.fUnmapBuffer = WrapGL(context, &GLContext::fUnmapBuffer);
+
+ // GLContext supports glRenderbufferStorageMultisample/glBlitFramebuffer
+ i->fFunctions.fRenderbufferStorageMultisample = WrapGL(context, &GLContext::fRenderbufferStorageMultisample);
+ i->fFunctions.fBlitFramebuffer = WrapGL(context, &GLContext::fBlitFramebuffer);
+
+ // GLContext supports glCompressedTexImage2D
+ i->fFunctions.fCompressedTexImage2D = WrapGL(context, &GLContext::fCompressedTexImage2D);
+
+ // GL_OES_vertex_array_object
+ i->fFunctions.fBindVertexArray = WrapGL(context, &GLContext::fBindVertexArray);
+ i->fFunctions.fDeleteVertexArrays = WrapGL(context, &GLContext::fDeleteVertexArrays);
+ i->fFunctions.fGenVertexArrays = WrapGL(context, &GLContext::fGenVertexArrays);
+
+ // Desktop GL
+ i->fFunctions.fGetTexLevelParameteriv = WrapGL(context, &GLContext::fGetTexLevelParameteriv);
+ i->fFunctions.fDrawBuffer = WrapGL(context, &GLContext::fDrawBuffer);
+ i->fFunctions.fReadBuffer = WrapGL(context, &GLContext::fReadBuffer);
+
+ // Desktop OpenGL > 1.5
+ i->fFunctions.fGenQueries = WrapGL(context, &GLContext::fGenQueries);
+ i->fFunctions.fDeleteQueries = WrapGL(context, &GLContext::fDeleteQueries);
+ i->fFunctions.fBeginQuery = WrapGL(context, &GLContext::fBeginQuery);
+ i->fFunctions.fEndQuery = WrapGL(context, &GLContext::fEndQuery);
+ i->fFunctions.fGetQueryiv = WrapGL(context, &GLContext::fGetQueryiv);
+ i->fFunctions.fGetQueryObjectiv = WrapGL(context, &GLContext::fGetQueryObjectiv);
+ i->fFunctions.fGetQueryObjectuiv = WrapGL(context, &GLContext::fGetQueryObjectuiv);
+
+ // Desktop OpenGL > 2.0
+ i->fFunctions.fDrawBuffers = WrapGL(context, &GLContext::fDrawBuffers);
+
+ return i;
+}
+
+SkiaGLGlue::SkiaGLGlue(GLContext* context)
+ : mGLContext(context)
+{
+ mGrGLInterface.reset(CreateGrGLInterfaceFromGLContext(mGLContext));
+ mGrContext.reset(GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)mGrGLInterface.get()));
+}
+
+SkiaGLGlue::~SkiaGLGlue()
+{
+ /*
+ * These members have inter-dependencies, but do not keep each other alive, so
+ * destruction order is very important here: mGrContext uses mGrGLInterface, and
+ * through it, uses mGLContext
+ */
+ mGrContext = nullptr;
+ if (mGrGLInterface) {
+ // Ensure that no references to the GLContext remain, even if the GrContext still lives.
+ mGrGLInterface->fFunctions = GrGLInterface::Functions();
+ mGrGLInterface = nullptr;
+ }
+ mGLContext = nullptr;
+}
diff --git a/gfx/gl/SkiaGLGlue.h b/gfx/gl/SkiaGLGlue.h
new file mode 100755
index 0000000000..4110c0c547
--- /dev/null
+++ b/gfx/gl/SkiaGLGlue.h
@@ -0,0 +1,64 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this
+* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef SKIA_GL_GLUE_H_
+#define SKIA_GL_GLUE_H_
+
+#ifdef USE_SKIA_GPU
+
+#include "skia/include/core/SkRefCnt.h"
+#include "mozilla/RefPtr.h"
+
+struct GrGLInterface;
+class GrContext;
+
+namespace mozilla {
+namespace gl {
+
+class GLContext;
+
+class SkiaGLGlue : public GenericAtomicRefCounted
+{
+public:
+ MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SkiaGLGlue)
+ explicit SkiaGLGlue(GLContext* context);
+ GLContext* GetGLContext() const { return mGLContext.get(); }
+ GrContext* GetGrContext() const { return mGrContext.get(); }
+
+protected:
+ virtual ~SkiaGLGlue();
+
+private:
+ RefPtr<GLContext> mGLContext;
+ sk_sp<GrGLInterface> mGrGLInterface;
+ sk_sp<GrContext> mGrContext;
+};
+
+} // namespace gl
+} // namespace mozilla
+
+#else // USE_SKIA_GPU
+
+class GrContext;
+
+namespace mozilla {
+namespace gl {
+
+class GLContext;
+
+class SkiaGLGlue : public GenericAtomicRefCounted
+{
+public:
+ SkiaGLGlue(GLContext* context);
+ GLContext* GetGLContext() const { return nullptr; }
+ GrContext* GetGrContext() const { return nullptr; }
+};
+
+} // namespace gl
+} // namespace mozilla
+
+#endif // USE_SKIA_GPU
+
+#endif // SKIA_GL_GLUE_H_
diff --git a/gfx/gl/SurfaceTypes.cpp b/gfx/gl/SurfaceTypes.cpp
new file mode 100644
index 0000000000..9c3e8a2e14
--- /dev/null
+++ b/gfx/gl/SurfaceTypes.cpp
@@ -0,0 +1,44 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "SurfaceTypes.h"
+
+#include "mozilla/layers/TextureForwarder.h"
+
+namespace mozilla {
+namespace gl {
+
+SurfaceCaps::SurfaceCaps()
+{
+ Clear();
+}
+
+/* These are defined out of line so that we don't need to include
+ * ISurfaceAllocator.h in the header */
+SurfaceCaps::SurfaceCaps(const SurfaceCaps& other) = default;
+SurfaceCaps&
+SurfaceCaps::operator=(const SurfaceCaps& other) = default;
+
+void
+SurfaceCaps::Clear()
+{
+ any = false;
+ color = false;
+ alpha = false;
+ bpp16 = false;
+ depth = false;
+ stencil = false;
+ antialias = false;
+ premultAlpha = true;
+ preserve = false;
+ surfaceAllocator = nullptr;
+}
+
+SurfaceCaps::~SurfaceCaps()
+{
+}
+
+} // namespace gl
+} // namespace mozilla
diff --git a/gfx/gl/SurfaceTypes.h b/gfx/gl/SurfaceTypes.h
new file mode 100644
index 0000000000..aae21e0a9f
--- /dev/null
+++ b/gfx/gl/SurfaceTypes.h
@@ -0,0 +1,98 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef SURFACE_TYPES_H_
+#define SURFACE_TYPES_H_
+
+#include "mozilla/RefPtr.h"
+#include "mozilla/Attributes.h"
+#include <stdint.h>
+
+namespace mozilla {
+namespace layers {
+class LayersIPCChannel;
+} // namespace layers
+
+namespace gl {
+
+struct SurfaceCaps final
+{
+ bool any;
+ bool color, alpha;
+ bool bpp16;
+ bool depth, stencil;
+ bool antialias;
+ bool premultAlpha;
+ bool preserve;
+
+ // The surface allocator that we want to create this
+ // for. May be null.
+ RefPtr<layers::LayersIPCChannel> surfaceAllocator;
+
+ SurfaceCaps();
+ SurfaceCaps(const SurfaceCaps& other);
+ ~SurfaceCaps();
+
+ void Clear();
+
+ SurfaceCaps& operator=(const SurfaceCaps& other);
+
+ // We can't use just 'RGB' here, since it's an ancient Windows macro.
+ static SurfaceCaps ForRGB() {
+ SurfaceCaps caps;
+
+ caps.color = true;
+
+ return caps;
+ }
+
+ static SurfaceCaps ForRGBA() {
+ SurfaceCaps caps;
+
+ caps.color = true;
+ caps.alpha = true;
+
+ return caps;
+ }
+
+ static SurfaceCaps Any() {
+ SurfaceCaps caps;
+
+ caps.any = true;
+
+ return caps;
+ }
+};
+
+enum class SharedSurfaceType : uint8_t {
+ Unknown = 0,
+
+ Basic,
+ EGLImageShare,
+ EGLSurfaceANGLE,
+ DXGLInterop,
+ DXGLInterop2,
+ Gralloc,
+ IOSurface,
+ GLXDrawable,
+ SharedGLTexture,
+
+ Max
+};
+
+enum class AttachmentType : uint8_t {
+ Screen = 0,
+
+ GLTexture,
+ GLRenderbuffer,
+
+ Max
+};
+
+} // namespace gl
+
+} /* namespace mozilla */
+
+#endif /* SURFACE_TYPES_H_ */
diff --git a/gfx/gl/TextureGarbageBin.cpp b/gfx/gl/TextureGarbageBin.cpp
new file mode 100644
index 0000000000..89a9c83553
--- /dev/null
+++ b/gfx/gl/TextureGarbageBin.cpp
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "TextureGarbageBin.h"
+#include "GLContext.h"
+
+using namespace mozilla;
+using namespace mozilla::gl;
+
+void
+TextureGarbageBin::GLContextTeardown()
+{
+ EmptyGarbage();
+
+ MutexAutoLock lock(mMutex);
+ mGL = nullptr;
+}
+
+void
+TextureGarbageBin::Trash(GLuint tex)
+{
+ MutexAutoLock lock(mMutex);
+ if (!mGL)
+ return;
+
+ mGarbageTextures.push(tex);
+}
+
+void
+TextureGarbageBin::EmptyGarbage()
+{
+ MutexAutoLock lock(mMutex);
+ if (!mGL)
+ return;
+
+ MOZ_RELEASE_ASSERT(mGL->IsCurrent(), "GFX: GL context not current.");
+ while (!mGarbageTextures.empty()) {
+ GLuint tex = mGarbageTextures.top();
+ mGarbageTextures.pop();
+ mGL->fDeleteTextures(1, &tex);
+ }
+}
diff --git a/gfx/gl/TextureGarbageBin.h b/gfx/gl/TextureGarbageBin.h
new file mode 100644
index 0000000000..9218c4f265
--- /dev/null
+++ b/gfx/gl/TextureGarbageBin.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef TEXTUREGARBAGEBIN_H_
+#define TEXTUREGARBAGEBIN_H_
+
+#include <stack>
+
+#include "mozilla/Mutex.h"
+#include "nsISupportsImpl.h"
+
+#include "GLContextTypes.h"
+
+namespace mozilla {
+namespace gl {
+
+class TextureGarbageBin final {
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TextureGarbageBin)
+
+private:
+ // Private destructor, to discourage deletion outside of Release():
+ ~TextureGarbageBin()
+ {
+ }
+
+ GLContext* mGL;
+ Mutex mMutex;
+ std::stack<GLuint> mGarbageTextures;
+
+public:
+ explicit TextureGarbageBin(GLContext* gl)
+ : mGL(gl)
+ , mMutex("TextureGarbageBin mutex")
+ {}
+
+ void GLContextTeardown();
+ void Trash(GLuint tex);
+ void EmptyGarbage();
+};
+
+} // namespace gl
+} // namespace mozilla
+
+#endif // TEXTUREGARBAGEBIN_H_
diff --git a/gfx/gl/TextureImageEGL.cpp b/gfx/gl/TextureImageEGL.cpp
new file mode 100644
index 0000000000..87a547c269
--- /dev/null
+++ b/gfx/gl/TextureImageEGL.cpp
@@ -0,0 +1,251 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "TextureImageEGL.h"
+#include "GLLibraryEGL.h"
+#include "GLContext.h"
+#include "GLUploadHelpers.h"
+#include "gfxPlatform.h"
+#include "mozilla/gfx/Types.h"
+
+namespace mozilla {
+namespace gl {
+
+static GLenum
+GLFormatForImage(gfx::SurfaceFormat aFormat)
+{
+ switch (aFormat) {
+ case gfx::SurfaceFormat::B8G8R8A8:
+ case gfx::SurfaceFormat::B8G8R8X8:
+ return LOCAL_GL_RGBA;
+ case gfx::SurfaceFormat::R5G6B5_UINT16:
+ return LOCAL_GL_RGB;
+ case gfx::SurfaceFormat::A8:
+ return LOCAL_GL_LUMINANCE;
+ default:
+ NS_WARNING("Unknown GL format for Surface format");
+ }
+ return 0;
+}
+
+static GLenum
+GLTypeForImage(gfx::SurfaceFormat aFormat)
+{
+ switch (aFormat) {
+ case gfx::SurfaceFormat::B8G8R8A8:
+ case gfx::SurfaceFormat::B8G8R8X8:
+ case gfx::SurfaceFormat::A8:
+ return LOCAL_GL_UNSIGNED_BYTE;
+ case gfx::SurfaceFormat::R5G6B5_UINT16:
+ return LOCAL_GL_UNSIGNED_SHORT_5_6_5;
+ default:
+ NS_WARNING("Unknown GL format for Surface format");
+ }
+ return 0;
+}
+
+TextureImageEGL::TextureImageEGL(GLuint aTexture,
+ const gfx::IntSize& aSize,
+ GLenum aWrapMode,
+ ContentType aContentType,
+ GLContext* aContext,
+ Flags aFlags,
+ TextureState aTextureState,
+ TextureImage::ImageFormat aImageFormat)
+ : TextureImage(aSize, aWrapMode, aContentType, aFlags)
+ , mGLContext(aContext)
+ , mUpdateFormat(gfx::ImageFormatToSurfaceFormat(aImageFormat))
+ , mEGLImage(nullptr)
+ , mTexture(aTexture)
+ , mSurface(nullptr)
+ , mConfig(nullptr)
+ , mTextureState(aTextureState)
+ , mBound(false)
+{
+ if (mUpdateFormat == gfx::SurfaceFormat::UNKNOWN) {
+ mUpdateFormat =
+ gfxPlatform::GetPlatform()->Optimal2DFormatForContent(GetContentType());
+ }
+
+ if (mUpdateFormat == gfx::SurfaceFormat::R5G6B5_UINT16) {
+ mTextureFormat = gfx::SurfaceFormat::R8G8B8X8;
+ } else if (mUpdateFormat == gfx::SurfaceFormat::B8G8R8X8) {
+ mTextureFormat = gfx::SurfaceFormat::B8G8R8X8;
+ } else {
+ mTextureFormat = gfx::SurfaceFormat::B8G8R8A8;
+ }
+}
+
+TextureImageEGL::~TextureImageEGL()
+{
+ if (mGLContext->IsDestroyed() || !mGLContext->IsOwningThreadCurrent()) {
+ return;
+ }
+
+ // If we have a context, then we need to delete the texture;
+ // if we don't have a context (either real or shared),
+ // then they went away when the contex was deleted, because it
+ // was the only one that had access to it.
+ if (mGLContext->MakeCurrent()) {
+ mGLContext->fDeleteTextures(1, &mTexture);
+ }
+ ReleaseTexImage();
+ DestroyEGLSurface();
+}
+
+bool
+TextureImageEGL::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom /* = gfx::IntPoint(0,0) */)
+{
+ gfx::IntRect bounds = aRegion.GetBounds();
+
+ nsIntRegion region;
+ if (mTextureState != Valid) {
+ bounds = gfx::IntRect(0, 0, mSize.width, mSize.height);
+ region = nsIntRegion(bounds);
+ } else {
+ region = aRegion;
+ }
+
+ bool needInit = mTextureState == Created;
+ size_t uploadSize = 0;
+ mTextureFormat =
+ UploadSurfaceToTexture(mGLContext,
+ aSurf,
+ region,
+ mTexture,
+ mSize,
+ &uploadSize,
+ needInit,
+ aFrom);
+ if (uploadSize > 0) {
+ UpdateUploadSize(uploadSize);
+ }
+
+ mTextureState = Valid;
+ return true;
+}
+
+void
+TextureImageEGL::BindTexture(GLenum aTextureUnit)
+{
+ // Ensure the texture is allocated before it is used.
+ if (mTextureState == Created) {
+ Resize(mSize);
+ }
+
+ mGLContext->fActiveTexture(aTextureUnit);
+ mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
+ mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0);
+}
+
+void
+TextureImageEGL::Resize(const gfx::IntSize& aSize)
+{
+ if (mSize == aSize && mTextureState != Created)
+ return;
+
+ mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
+
+ mGLContext->fTexImage2D(LOCAL_GL_TEXTURE_2D,
+ 0,
+ GLFormatForImage(mUpdateFormat),
+ aSize.width,
+ aSize.height,
+ 0,
+ GLFormatForImage(mUpdateFormat),
+ GLTypeForImage(mUpdateFormat),
+ nullptr);
+
+ mTextureState = Allocated;
+ mSize = aSize;
+}
+
+bool
+TextureImageEGL::BindTexImage()
+{
+ if (mBound && !ReleaseTexImage())
+ return false;
+
+ EGLBoolean success =
+ sEGLLibrary.fBindTexImage(EGL_DISPLAY(),
+ (EGLSurface)mSurface,
+ LOCAL_EGL_BACK_BUFFER);
+
+ if (success == LOCAL_EGL_FALSE)
+ return false;
+
+ mBound = true;
+ return true;
+}
+
+bool
+TextureImageEGL::ReleaseTexImage()
+{
+ if (!mBound)
+ return true;
+
+ EGLBoolean success =
+ sEGLLibrary.fReleaseTexImage(EGL_DISPLAY(),
+ (EGLSurface)mSurface,
+ LOCAL_EGL_BACK_BUFFER);
+
+ if (success == LOCAL_EGL_FALSE)
+ return false;
+
+ mBound = false;
+ return true;
+}
+
+void
+TextureImageEGL::DestroyEGLSurface(void)
+{
+ if (!mSurface)
+ return;
+
+ sEGLLibrary.fDestroySurface(EGL_DISPLAY(), mSurface);
+ mSurface = nullptr;
+}
+
+already_AddRefed<TextureImage>
+CreateTextureImageEGL(GLContext* gl,
+ const gfx::IntSize& aSize,
+ TextureImage::ContentType aContentType,
+ GLenum aWrapMode,
+ TextureImage::Flags aFlags,
+ TextureImage::ImageFormat aImageFormat)
+{
+ RefPtr<TextureImage> t = new gl::TiledTextureImage(gl, aSize, aContentType, aFlags, aImageFormat);
+ return t.forget();
+}
+
+already_AddRefed<TextureImage>
+TileGenFuncEGL(GLContext* gl,
+ const gfx::IntSize& aSize,
+ TextureImage::ContentType aContentType,
+ TextureImage::Flags aFlags,
+ TextureImage::ImageFormat aImageFormat)
+{
+ gl->MakeCurrent();
+
+ GLuint texture;
+ gl->fGenTextures(1, &texture);
+
+ RefPtr<TextureImageEGL> teximage =
+ new TextureImageEGL(texture, aSize, LOCAL_GL_CLAMP_TO_EDGE, aContentType,
+ gl, aFlags, TextureImage::Created, aImageFormat);
+
+ teximage->BindTexture(LOCAL_GL_TEXTURE0);
+
+ GLint texfilter = aFlags & TextureImage::UseNearestFilter ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR;
+ gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, texfilter);
+ gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, texfilter);
+ gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
+ gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
+
+ return teximage.forget();
+}
+
+} // namespace gl
+} // namespace mozilla
diff --git a/gfx/gl/TextureImageEGL.h b/gfx/gl/TextureImageEGL.h
new file mode 100644
index 0000000000..fa7075064a
--- /dev/null
+++ b/gfx/gl/TextureImageEGL.h
@@ -0,0 +1,88 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef TEXTUREIMAGEEGL_H_
+#define TEXTUREIMAGEEGL_H_
+
+#include "GLTextureImage.h"
+
+namespace mozilla {
+namespace gl {
+
+class TextureImageEGL final
+ : public TextureImage
+{
+public:
+ TextureImageEGL(GLuint aTexture,
+ const gfx::IntSize& aSize,
+ GLenum aWrapMode,
+ ContentType aContentType,
+ GLContext* aContext,
+ Flags aFlags = TextureImage::NoFlags,
+ TextureState aTextureState = Created,
+ TextureImage::ImageFormat aImageFormat = SurfaceFormat::UNKNOWN);
+
+ virtual ~TextureImageEGL();
+
+ virtual bool DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom = gfx::IntPoint(0,0));
+
+ virtual void BindTexture(GLenum aTextureUnit);
+
+ virtual GLuint GetTextureID()
+ {
+ // Ensure the texture is allocated before it is used.
+ if (mTextureState == Created) {
+ Resize(mSize);
+ }
+ return mTexture;
+ };
+
+ virtual void Resize(const gfx::IntSize& aSize);
+
+ bool BindTexImage();
+
+ bool ReleaseTexImage();
+
+ virtual bool CreateEGLSurface(gfxASurface* aSurface)
+ {
+ return false;
+ }
+
+ virtual void DestroyEGLSurface(void);
+
+protected:
+ typedef gfxImageFormat ImageFormat;
+
+ GLContext* mGLContext;
+
+ gfx::SurfaceFormat mUpdateFormat;
+ EGLImage mEGLImage;
+ GLuint mTexture;
+ EGLSurface mSurface;
+ EGLConfig mConfig;
+ TextureState mTextureState;
+
+ bool mBound;
+};
+
+already_AddRefed<TextureImage>
+CreateTextureImageEGL(GLContext* gl,
+ const gfx::IntSize& aSize,
+ TextureImage::ContentType aContentType,
+ GLenum aWrapMode,
+ TextureImage::Flags aFlags,
+ TextureImage::ImageFormat aImageFormat);
+
+already_AddRefed<TextureImage>
+TileGenFuncEGL(GLContext* gl,
+ const gfx::IntSize& aSize,
+ TextureImage::ContentType aContentType,
+ TextureImage::Flags aFlags,
+ TextureImage::ImageFormat aImageFormat);
+
+} // namespace gl
+} // namespace mozilla
+
+#endif // TEXTUREIMAGEEGL_H_
diff --git a/gfx/gl/WGLLibrary.h b/gfx/gl/WGLLibrary.h
new file mode 100644
index 0000000000..3c261e10d9
--- /dev/null
+++ b/gfx/gl/WGLLibrary.h
@@ -0,0 +1,131 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "GLContextTypes.h"
+#include <windows.h>
+
+struct PRLibrary;
+
+namespace mozilla {
+namespace gl {
+
+class WGLLibrary
+{
+public:
+ WGLLibrary()
+ : mInitialized(false)
+ , mOGLLibrary(nullptr)
+ , mHasRobustness(false)
+ , mHasDXInterop(false)
+ , mHasDXInterop2(false)
+ , mWindow (0)
+ , mWindowDC(0)
+ , mWindowGLContext(0)
+ , mWindowPixelFormat(0)
+ {}
+
+ typedef HGLRC (GLAPIENTRY * PFNWGLCREATECONTEXTPROC) (HDC);
+ PFNWGLCREATECONTEXTPROC fCreateContext;
+ typedef BOOL (GLAPIENTRY * PFNWGLDELETECONTEXTPROC) (HGLRC);
+ PFNWGLDELETECONTEXTPROC fDeleteContext;
+ typedef BOOL (GLAPIENTRY * PFNWGLMAKECURRENTPROC) (HDC, HGLRC);
+ PFNWGLMAKECURRENTPROC fMakeCurrent;
+ typedef PROC (GLAPIENTRY * PFNWGLGETPROCADDRESSPROC) (LPCSTR);
+ PFNWGLGETPROCADDRESSPROC fGetProcAddress;
+ typedef HGLRC (GLAPIENTRY * PFNWGLGETCURRENTCONTEXT) (void);
+ PFNWGLGETCURRENTCONTEXT fGetCurrentContext;
+ typedef HDC (GLAPIENTRY * PFNWGLGETCURRENTDC) (void);
+ PFNWGLGETCURRENTDC fGetCurrentDC;
+ typedef BOOL (GLAPIENTRY * PFNWGLSHARELISTS) (HGLRC oldContext, HGLRC newContext);
+ PFNWGLSHARELISTS fShareLists;
+
+ typedef HANDLE (WINAPI * PFNWGLCREATEPBUFFERPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int* piAttribList);
+ PFNWGLCREATEPBUFFERPROC fCreatePbuffer;
+ typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERPROC) (HANDLE hPbuffer);
+ PFNWGLDESTROYPBUFFERPROC fDestroyPbuffer;
+ typedef HDC (WINAPI * PFNWGLGETPBUFFERDCPROC) (HANDLE hPbuffer);
+ PFNWGLGETPBUFFERDCPROC fGetPbufferDC;
+
+ typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEPROC) (HANDLE hPbuffer, int iBuffer);
+ PFNWGLBINDTEXIMAGEPROC fBindTexImage;
+ typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEPROC) (HANDLE hPbuffer, int iBuffer);
+ PFNWGLRELEASETEXIMAGEPROC fReleaseTexImage;
+
+ typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATPROC) (HDC hdc, const int* piAttribIList, const FLOAT* pfAttribFList, UINT nMaxFormats, int* piFormats, UINT* nNumFormats);
+ PFNWGLCHOOSEPIXELFORMATPROC fChoosePixelFormat;
+ typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, int* piValues);
+ PFNWGLGETPIXELFORMATATTRIBIVPROC fGetPixelFormatAttribiv;
+
+ typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGPROC) (HDC hdc);
+ PFNWGLGETEXTENSIONSSTRINGPROC fGetExtensionsString;
+
+ typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSPROC) (HDC hdc, HGLRC hShareContext, const int* attribList);
+ PFNWGLCREATECONTEXTATTRIBSPROC fCreateContextAttribs;
+
+ // WGL_NV_DX_interop:
+ // BOOL wglDXSetResourceShareHandleNV(void* dxObject, HANDLE shareHandle);
+ typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLEPROC) (void* dxObject, HANDLE shareHandle);
+ PFNWGLDXSETRESOURCESHAREHANDLEPROC fDXSetResourceShareHandle;
+
+ // HANDLE wglDXOpenDeviceNV(void* dxDevice);
+ typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICEPROC) (void* dxDevice);
+ PFNWGLDXOPENDEVICEPROC fDXOpenDevice;
+
+ // BOOL wglDXCloseDeviceNV(HANDLE hDevice);
+ typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICEPROC) (HANDLE hDevice);
+ PFNWGLDXCLOSEDEVICEPROC fDXCloseDevice;
+
+ // HANDLE wglDXRegisterObjectNV(HANDLE hDevice, void* dxObject, GLuint name, GLenum type, GLenum access);
+ typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTPROC) (HANDLE hDevice, void* dxObject, GLuint name, GLenum type, GLenum access);
+ PFNWGLDXREGISTEROBJECTPROC fDXRegisterObject;
+
+ // BOOL wglDXUnregisterObjectNV(HANDLE hDevice, HANDLE hObject);
+ typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECT) (HANDLE hDevice, HANDLE hObject);
+ PFNWGLDXUNREGISTEROBJECT fDXUnregisterObject;
+
+ // BOOL wglDXObjectAccessNV(HANDLE hObject, GLenum access);
+ typedef BOOL (WINAPI * PFNWGLDXOBJECTACCESSPROC) (HANDLE hObject, GLenum access);
+ PFNWGLDXOBJECTACCESSPROC fDXObjectAccess;
+
+ // BOOL wglDXLockObjectsNV(HANDLE hDevice, GLint count, HANDLE* hObjects);
+ typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSPROC) (HANDLE hDevice, GLint count, HANDLE* hObjects);
+ PFNWGLDXLOCKOBJECTSPROC fDXLockObjects;
+
+ // BOOL wglDXUnlockObjectsNV(HANDLE hDevice, GLint count, HANDLE* hObjects);
+ typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSPROC) (HANDLE hDevice, GLint count, HANDLE* hObjects);
+ PFNWGLDXUNLOCKOBJECTSPROC fDXUnlockObjects;
+
+ bool EnsureInitialized();
+ HWND CreateDummyWindow(HDC* aWindowDC = nullptr);
+
+ bool HasRobustness() const { return mHasRobustness; }
+ bool HasDXInterop() const { return mHasDXInterop; }
+ bool HasDXInterop2() const { return mHasDXInterop2; }
+ bool IsInitialized() const { return mInitialized; }
+ HWND GetWindow() const { return mWindow; }
+ HDC GetWindowDC() const {return mWindowDC; }
+ HGLRC GetWindowGLContext() const {return mWindowGLContext; }
+ int GetWindowPixelFormat() const { return mWindowPixelFormat; }
+ PRLibrary* GetOGLLibrary() { return mOGLLibrary; }
+
+private:
+ bool mInitialized;
+ PRLibrary* mOGLLibrary;
+ bool mHasRobustness;
+ bool mHasDXInterop;
+ bool mHasDXInterop2;
+
+ HWND mWindow;
+ HDC mWindowDC;
+ HGLRC mWindowGLContext;
+ int mWindowPixelFormat;
+
+};
+
+// a global WGLLibrary instance
+extern WGLLibrary sWGLLib;
+
+} /* namespace gl */
+} /* namespace mozilla */
diff --git a/gfx/gl/moz.build b/gfx/gl/moz.build
new file mode 100644
index 0000000000..596612bb8e
--- /dev/null
+++ b/gfx/gl/moz.build
@@ -0,0 +1,164 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+gl_provider = 'Null'
+
+if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
+ gl_provider = 'WGL'
+elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
+ gl_provider = 'CGL'
+elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'uikit':
+ gl_provider = 'EAGL'
+elif 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
+ if CONFIG['MOZ_EGL_XRENDER_COMPOSITE']:
+ gl_provider = 'EGL'
+ else:
+ gl_provider = 'GLX'
+elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
+ gl_provider = 'EGL'
+
+if CONFIG['MOZ_GL_PROVIDER']:
+ gl_provider = CONFIG['MOZ_GL_PROVIDER']
+
+EXPORTS += [
+ 'AndroidSurfaceTexture.h',
+ 'DecomposeIntoNoRepeatTriangles.h',
+ 'EGLUtils.h',
+ 'ForceDiscreteGPUHelperCGL.h',
+ 'GfxTexturesReporter.h',
+ 'GLBlitHelper.h',
+ 'GLConsts.h',
+ 'GLContext.h',
+ 'GLContextEGL.h',
+ 'GLContextProvider.h',
+ 'GLContextProviderImpl.h',
+ 'GLContextSymbols.h',
+ 'GLContextTypes.h',
+ 'GLDefs.h',
+ 'GLLibraryEGL.h',
+ 'GLLibraryLoader.h',
+ 'GLReadTexImageHelper.h',
+ 'GLScreenBuffer.h',
+ 'GLTextureImage.h',
+ 'GLTypes.h',
+ 'GLUploadHelpers.h',
+ 'HeapCopyOfStackArray.h',
+ 'ScopedGLHelpers.h',
+ 'SharedSurface.h',
+ 'SharedSurfaceEGL.h',
+ 'SharedSurfaceGL.h',
+ 'SurfaceTypes.h',
+ 'TextureGarbageBin.h',
+]
+
+if CONFIG['MOZ_X11']:
+ EXPORTS += [
+ 'GLContextGLX.h',
+ 'GLXLibrary.h',
+ ]
+
+# Win32 is a special snowflake, for ANGLE
+if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
+ EXPORTS += [
+ 'GLContextWGL.h',
+ 'SharedSurfaceANGLE.h', # Needs <windows.h> for `HANDLE`.
+ 'SharedSurfaceD3D11Interop.h',
+ 'WGLLibrary.h',
+ ]
+ UNIFIED_SOURCES += [
+ 'GLContextProviderWGL.cpp',
+ 'SharedSurfaceANGLE.cpp',
+ 'SharedSurfaceD3D11Interop.cpp',
+ ]
+if CONFIG['MOZ_ENABLE_SKIA_GPU']:
+ EXPORTS += ['SkiaGLGlue.h']
+ SOURCES += [
+ 'SkiaGLGlue.cpp',
+ ]
+ if CONFIG['CLANG_CXX']:
+ # Suppress warnings from Skia header files.
+ SOURCES['SkiaGLGlue.cpp'].flags += ['-Wno-implicit-fallthrough']
+
+if gl_provider == 'CGL':
+ # These files include Mac headers that are unfriendly to unified builds
+ SOURCES += [
+ "GLContextProviderCGL.mm",
+ ]
+ EXPORTS += [
+ 'GLContextCGL.h',
+ 'SharedSurfaceIO.h',
+ ]
+ # SharedSurfaceIO.cpp includes MacIOSurface.h which include Mac headers
+ # which define Size and Point types in root namespace with often conflict with
+ # our own types. While I haven't actually hit this issue in the present case,
+ # it's been an issue in gfx/layers so let's not risk it.
+ SOURCES += [
+ 'SharedSurfaceIO.cpp',
+ ]
+elif gl_provider == 'EAGL':
+ # These files include ObjC headers that are unfriendly to unified builds
+ SOURCES += [
+ 'GLContextProviderEAGL.mm',
+ ]
+ EXPORTS += [
+ 'GLContextEAGL.h',
+ ]
+
+elif gl_provider == 'GLX':
+ # GLContextProviderGLX.cpp needs to be kept out of UNIFIED_SOURCES
+ # as it includes X11 headers which cause conflicts.
+ SOURCES += [
+ 'GLContextProviderGLX.cpp',
+ 'SharedSurfaceGLX.cpp'
+ ]
+ EXPORTS += [
+ 'SharedSurfaceGLX.h'
+ ]
+
+UNIFIED_SOURCES += [
+ 'AndroidSurfaceTexture.cpp',
+ 'DecomposeIntoNoRepeatTriangles.cpp',
+ 'EGLUtils.cpp',
+ 'GfxTexturesReporter.cpp',
+ 'GLBlitHelper.cpp',
+ 'GLContext.cpp',
+ 'GLContextFeatures.cpp',
+ 'GLContextProviderEGL.cpp',
+ 'GLContextTypes.cpp',
+ 'GLDebugUtils.cpp',
+ 'GLLibraryEGL.cpp',
+ 'GLLibraryLoader.cpp',
+ 'GLReadTexImageHelper.cpp',
+ 'GLScreenBuffer.cpp',
+ 'GLTextureImage.cpp',
+ 'GLUploadHelpers.cpp',
+ 'ScopedGLHelpers.cpp',
+ 'SharedSurface.cpp',
+ 'SharedSurfaceEGL.cpp',
+ 'SharedSurfaceGL.cpp',
+ 'SurfaceTypes.cpp',
+ 'TextureGarbageBin.cpp',
+ 'TextureImageEGL.cpp',
+]
+
+include('/ipc/chromium/chromium-config.mozbuild')
+
+FINAL_LIBRARY = 'xul'
+
+if CONFIG['MOZ_D3DCOMPILER_VISTA_DLL']:
+ DEFINES['MOZ_D3DCOMPILER_VISTA_DLL'] = CONFIG['MOZ_D3DCOMPILER_VISTA_DLL']
+if CONFIG['MOZ_D3DCOMPILER_XP_DLL']:
+ DEFINES['MOZ_D3DCOMPILER_XP_DLL'] = CONFIG['MOZ_D3DCOMPILER_XP_DLL']
+
+CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
+CXXFLAGS += CONFIG['TK_CFLAGS']
+CFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
+CFLAGS += CONFIG['TK_CFLAGS']
+
+LOCAL_INCLUDES += CONFIG['SKIA_INCLUDES']
+
+if CONFIG['GNU_CXX']:
+ CXXFLAGS += ['-Wno-error=shadow']