summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/libANGLE/renderer/gl
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/src/libANGLE/renderer/gl')
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/BlitGL.cpp486
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/BlitGL.h83
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/BufferGL.cpp204
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/BufferGL.h62
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/CompilerGL.cpp91
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/CompilerGL.h33
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/ContextGL.cpp370
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/ContextGL.h183
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/DisplayGL.cpp103
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/DisplayGL.h62
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/FeatureSupportGL.md107
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/FenceNVGL.cpp51
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/FenceNVGL.h36
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/FenceSyncGL.cpp67
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/FenceSyncGL.h36
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/FramebufferGL.cpp553
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/FramebufferGL.h113
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/FunctionsGL.cpp2316
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/FunctionsGL.h791
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/PathGL.cpp38
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/PathGL.h44
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/ProgramGL.cpp588
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/ProgramGL.h118
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/QueryGL.cpp222
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/QueryGL.h64
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/RenderbufferGL.cpp96
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/RenderbufferGL.h52
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/RendererGL.cpp561
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/RendererGL.h194
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/SamplerGL.cpp73
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/SamplerGL.h40
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/ShaderGL.cpp143
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/ShaderGL.h44
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/StateManagerGL.cpp1742
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/StateManagerGL.h290
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/SurfaceGL.cpp36
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/SurfaceGL.h36
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/TextureGL.cpp1039
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/TextureGL.h145
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/TransformFeedbackGL.cpp131
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/TransformFeedbackGL.h53
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/VertexArrayGL.cpp499
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/VertexArrayGL.h100
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/WorkaroundsGL.h126
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.h77
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.mm275
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.h65
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.mm143
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h100
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm332
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/egl/DisplayEGL.cpp116
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/egl/DisplayEGL.h43
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGL.cpp340
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGL.h91
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGLDL.cpp74
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGLDL.h42
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/egl/PbufferSurfaceEGL.cpp39
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h36
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/egl/SurfaceEGL.cpp132
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/egl/SurfaceEGL.h55
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/egl/WindowSurfaceEGL.cpp40
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/egl/WindowSurfaceEGL.h37
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.cpp385
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.h78
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/egl/functionsegl_typedefs.h131
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/egl/ozone/DisplayOzone.cpp945
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/egl/ozone/DisplayOzone.h211
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/egl/ozone/SurfaceOzone.cpp98
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/egl/ozone/SurfaceOzone.h52
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/formatutilsgl.cpp553
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/formatutilsgl.h129
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/functionsgl_enums.h1375
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/functionsgl_typedefs.h758
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/glx/DisplayGLX.cpp981
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/glx/DisplayGLX.h151
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/glx/FBConfigCompatibility.md204
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/glx/FunctionsGLX.cpp398
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/glx/FunctionsGLX.h96
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/glx/PbufferSurfaceGLX.cpp143
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/glx/PbufferSurfaceGLX.h64
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/glx/SurfaceGLX.h26
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/glx/WindowSurfaceGLX.cpp244
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/glx/WindowSurfaceGLX.h73
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/glx/functionsglx_typedefs.h52
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/glx/platform_glx.h190
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/renderergl_utils.cpp1045
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/renderergl_utils.h61
-rw-r--r--gfx/angle/src/libANGLE/renderer/gl/wgl/D3DTextureSurfaceWGL.cpp384
-rw-r--r--gfx/angle/src/libANGLE/renderer/gl/wgl/D3DTextureSurfaceWGL.h86
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.cpp553
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.h106
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/wgl/DisplayWGL.cpp741
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/wgl/DisplayWGL.h112
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/wgl/FunctionsWGL.cpp181
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/wgl/FunctionsWGL.h94
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.cpp196
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.h74
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/wgl/WindowSurfaceWGL.cpp178
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/wgl/WindowSurfaceWGL.h64
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/wgl/functionswgl_typedefs.h43
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/wgl/wgl_utils.cpp85
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/wgl/wgl_utils.h32
102 files changed, 25630 insertions, 0 deletions
diff --git a/gfx/angle/src/libANGLE/renderer/gl/BlitGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/BlitGL.cpp
new file mode 100755
index 000000000..b181822ff
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/BlitGL.cpp
@@ -0,0 +1,486 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// BlitGL.cpp: Implements the BlitGL class, a helper for blitting textures
+
+#include "libANGLE/renderer/gl/BlitGL.h"
+
+#include "libANGLE/formatutils.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/renderer/gl/formatutilsgl.h"
+#include "libANGLE/renderer/gl/FramebufferGL.h"
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+#include "libANGLE/renderer/gl/TextureGL.h"
+#include "libANGLE/renderer/gl/StateManagerGL.h"
+#include "libANGLE/renderer/gl/WorkaroundsGL.h"
+
+namespace
+{
+
+gl::Error CheckCompileStatus(const rx::FunctionsGL *functions, GLuint shader)
+{
+ GLint compileStatus = GL_FALSE;
+ functions->getShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
+ ASSERT(compileStatus == GL_TRUE);
+ if (compileStatus == GL_FALSE)
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to compile internal blit shader.");
+ }
+
+ return gl::NoError();
+}
+
+gl::Error CheckLinkStatus(const rx::FunctionsGL *functions, GLuint program)
+{
+ GLint linkStatus = GL_FALSE;
+ functions->getProgramiv(program, GL_LINK_STATUS, &linkStatus);
+ ASSERT(linkStatus == GL_TRUE);
+ if (linkStatus == GL_FALSE)
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to link internal blit program.");
+ }
+
+ return gl::NoError();
+}
+
+} // anonymous namespace
+
+namespace rx
+{
+
+BlitGL::BlitGL(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ StateManagerGL *stateManager)
+ : mFunctions(functions),
+ mWorkarounds(workarounds),
+ mStateManager(stateManager),
+ mBlitProgram(0),
+ mSourceTextureLocation(-1),
+ mScaleLocation(-1),
+ mOffsetLocation(-1),
+ mScratchFBO(0),
+ mVAO(0)
+{
+ for (size_t i = 0; i < ArraySize(mScratchTextures); i++)
+ {
+ mScratchTextures[i] = 0;
+ }
+
+ ASSERT(mFunctions);
+ ASSERT(mStateManager);
+}
+
+BlitGL::~BlitGL()
+{
+ if (mBlitProgram != 0)
+ {
+ mStateManager->deleteProgram(mBlitProgram);
+ mBlitProgram = 0;
+ }
+
+ for (size_t i = 0; i < ArraySize(mScratchTextures); i++)
+ {
+ if (mScratchTextures[i] != 0)
+ {
+ mStateManager->deleteTexture(mScratchTextures[i]);
+ mScratchTextures[i] = 0;
+ }
+ }
+
+ if (mScratchFBO != 0)
+ {
+ mStateManager->deleteFramebuffer(mScratchFBO);
+ mScratchFBO = 0;
+ }
+
+ if (mVAO != 0)
+ {
+ mStateManager->deleteVertexArray(mVAO);
+ mVAO = 0;
+ }
+}
+
+gl::Error BlitGL::copyImageToLUMAWorkaroundTexture(GLuint texture,
+ GLenum textureType,
+ GLenum target,
+ GLenum lumaFormat,
+ size_t level,
+ const gl::Rectangle &sourceArea,
+ GLenum internalFormat,
+ const gl::Framebuffer *source)
+{
+ mStateManager->bindTexture(textureType, texture);
+
+ // Allocate the texture memory
+ const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
+ mFunctions->texImage2D(target, static_cast<GLint>(level), internalFormat, sourceArea.width,
+ sourceArea.height, 0, internalFormatInfo.format,
+ source->getImplementationColorReadType(), nullptr);
+
+ return copySubImageToLUMAWorkaroundTexture(texture, textureType, target, lumaFormat, level,
+ gl::Offset(0, 0, 0), sourceArea, source);
+}
+
+gl::Error BlitGL::copySubImageToLUMAWorkaroundTexture(GLuint texture,
+ GLenum textureType,
+ GLenum target,
+ GLenum lumaFormat,
+ size_t level,
+ const gl::Offset &destOffset,
+ const gl::Rectangle &sourceArea,
+ const gl::Framebuffer *source)
+{
+ ANGLE_TRY(initializeResources());
+
+ // Blit the framebuffer to the first scratch texture
+ const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(source);
+ mStateManager->bindFramebuffer(GL_FRAMEBUFFER, sourceFramebufferGL->getFramebufferID());
+
+ nativegl::CopyTexImageImageFormat copyTexImageFormat = nativegl::GetCopyTexImageImageFormat(
+ mFunctions, mWorkarounds, source->getImplementationColorReadFormat(),
+ source->getImplementationColorReadType());
+ const gl::InternalFormat &internalFormatInfo =
+ gl::GetInternalFormatInfo(copyTexImageFormat.internalFormat);
+
+ mStateManager->bindTexture(GL_TEXTURE_2D, mScratchTextures[0]);
+ mFunctions->copyTexImage2D(GL_TEXTURE_2D, 0, copyTexImageFormat.internalFormat, sourceArea.x,
+ sourceArea.y, sourceArea.width, sourceArea.height, 0);
+
+ // Set the swizzle of the scratch texture so that the channels sample into the correct emulated
+ // LUMA channels.
+ GLint swizzle[4] = {
+ (lumaFormat == GL_ALPHA) ? GL_ALPHA : GL_RED,
+ (lumaFormat == GL_LUMINANCE_ALPHA) ? GL_ALPHA : GL_ZERO, GL_ZERO, GL_ZERO,
+ };
+ mFunctions->texParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
+
+ // Make a temporary framebuffer using the second scratch texture to render the swizzled result
+ // to.
+ mStateManager->bindTexture(GL_TEXTURE_2D, mScratchTextures[1]);
+ mFunctions->texImage2D(GL_TEXTURE_2D, 0, copyTexImageFormat.internalFormat, sourceArea.width,
+ sourceArea.height, 0, internalFormatInfo.format,
+ source->getImplementationColorReadType(), nullptr);
+
+ mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mScratchFBO);
+ mFunctions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+ mScratchTextures[1], 0);
+
+ // Render to the destination texture, sampling from the scratch texture
+ mStateManager->setViewport(gl::Rectangle(0, 0, sourceArea.width, sourceArea.height));
+ mStateManager->setScissorTestEnabled(false);
+ mStateManager->setDepthRange(0.0f, 1.0f);
+ mStateManager->setBlendEnabled(false);
+ mStateManager->setColorMask(true, true, true, true);
+ mStateManager->setSampleAlphaToCoverageEnabled(false);
+ mStateManager->setSampleCoverageEnabled(false);
+ mStateManager->setDepthTestEnabled(false);
+ mStateManager->setStencilTestEnabled(false);
+ mStateManager->setCullFaceEnabled(false);
+ mStateManager->setPolygonOffsetFillEnabled(false);
+ mStateManager->setRasterizerDiscardEnabled(false);
+ mStateManager->bindTexture(GL_TEXTURE_2D, mScratchTextures[0]);
+
+ setScratchTextureParameter(GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ setScratchTextureParameter(GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ mStateManager->activeTexture(0);
+ mStateManager->bindTexture(GL_TEXTURE_2D, mScratchTextures[0]);
+
+ mStateManager->useProgram(mBlitProgram);
+ mFunctions->uniform1i(mSourceTextureLocation, 0);
+ mFunctions->uniform2f(mScaleLocation, 1.0, 1.0);
+ mFunctions->uniform2f(mOffsetLocation, 0.0, 0.0);
+
+ mStateManager->bindVertexArray(mVAO, 0);
+
+ mFunctions->drawArrays(GL_TRIANGLES, 0, 3);
+
+ // Copy the swizzled texture to the destination texture
+ mStateManager->bindTexture(textureType, texture);
+ mFunctions->copyTexSubImage2D(target, static_cast<GLint>(level), destOffset.x, destOffset.y, 0,
+ 0, sourceArea.width, sourceArea.height);
+
+ // Finally orphan the scratch textures so they can be GCed by the driver.
+ orphanScratchTextures();
+
+ return gl::NoError();
+}
+
+gl::Error BlitGL::blitColorBufferWithShader(const gl::Framebuffer *source,
+ const gl::Framebuffer *dest,
+ const gl::Rectangle &sourceAreaIn,
+ const gl::Rectangle &destAreaIn,
+ GLenum filter)
+{
+ ANGLE_TRY(initializeResources());
+
+ // Normalize the destination area to have positive width and height because we will use
+ // glViewport to set it, which doesn't allow negative width or height.
+ gl::Rectangle sourceArea = sourceAreaIn;
+ gl::Rectangle destArea = destAreaIn;
+ if (destArea.width < 0)
+ {
+ destArea.x += destArea.width;
+ destArea.width = -destArea.width;
+ sourceArea.x += sourceArea.width;
+ sourceArea.width = -sourceArea.width;
+ }
+ if (destArea.height < 0)
+ {
+ destArea.y += destArea.height;
+ destArea.height = -destArea.height;
+ sourceArea.y += sourceArea.height;
+ sourceArea.height = -sourceArea.height;
+ }
+
+ const gl::FramebufferAttachment *readAttachment = source->getReadColorbuffer();
+ ASSERT(readAttachment->getSamples() <= 1);
+
+ // Compute the part of the source that will be sampled.
+ gl::Rectangle inBoundsSource;
+ {
+ gl::Extents sourceSize = readAttachment->getSize();
+ gl::Rectangle sourceBounds(0, 0, sourceSize.width, sourceSize.height);
+ gl::ClipRectangle(sourceArea, sourceBounds, &inBoundsSource);
+
+ // Note that inBoundsSource will have lost the orientation information.
+ ASSERT(inBoundsSource.width >= 0 && inBoundsSource.height >= 0);
+
+ // Early out when the sampled part is empty as the blit will be a noop,
+ // and it prevents a division by zero in later computations.
+ if (inBoundsSource.width == 0 || inBoundsSource.height == 0)
+ {
+ return gl::NoError();
+ }
+ }
+
+ // The blit will be emulated by getting the source of the blit in a texture and sampling it
+ // with CLAMP_TO_EDGE. The quad used to draw can trivially compute texture coordinates going
+ // from (0, 0) to (1, 1). These texture coordinates will need to be transformed to make two
+ // regions match:
+ // - The region of the texture representing the source framebuffer region that will be sampled
+ // - The region of the drawn quad that corresponds to non-clamped blit, this is the same as the
+ // region of the source rectangle that is inside the source attachment.
+ //
+ // These two regions, T (texture) and D (dest) are defined by their offset in texcoord space
+ // in (0, 1)^2 and their size in texcoord space in (-1, 1)^2. The size can be negative to
+ // represent the orientation of the blit.
+ //
+ // Then if P is the quad texcoord, Q the texcoord inside T, and R the texture texcoord:
+ // - Q = (P - D.offset) / D.size
+ // - Q = (R - T.offset) / T.size
+ // Hence R = (P - D.offset) / D.size * T.size - T.offset
+ // = P * (T.size / D.size) + (T.offset - D.offset * T.size / D.size)
+
+ GLuint textureId;
+ gl::Vector2 TOffset;
+ gl::Vector2 TSize;
+
+ // TODO(cwallez) once texture dirty bits are landed, reuse attached texture instead of using
+ // CopyTexImage2D
+ {
+ textureId = mScratchTextures[0];
+ TOffset = gl::Vector2(0.0, 0.0);
+ TSize = gl::Vector2(1.0, 1.0);
+ if (sourceArea.width < 0)
+ {
+ TOffset.x = 1.0;
+ TSize.x = -1.0;
+ }
+ if (sourceArea.height < 0)
+ {
+ TOffset.y = 1.0;
+ TSize.y = -1.0;
+ }
+
+ GLenum format = readAttachment->getFormat().info->internalFormat;
+ const FramebufferGL *sourceGL = GetImplAs<FramebufferGL>(source);
+ mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceGL->getFramebufferID());
+ mStateManager->bindTexture(GL_TEXTURE_2D, textureId);
+
+ mFunctions->copyTexImage2D(GL_TEXTURE_2D, 0, format, inBoundsSource.x, inBoundsSource.y,
+ inBoundsSource.width, inBoundsSource.height, 0);
+ }
+
+ // Compute normalized sampled draw quad region
+ // It is the same as the region of the source rectangle that is in bounds.
+ gl::Vector2 DOffset;
+ gl::Vector2 DSize;
+ {
+ ASSERT(sourceArea.width != 0 && sourceArea.height != 0);
+ gl::Rectangle orientedInBounds = inBoundsSource;
+ if (sourceArea.width < 0)
+ {
+ orientedInBounds.x += orientedInBounds.width;
+ orientedInBounds.width = -orientedInBounds.width;
+ }
+ if (sourceArea.height < 0)
+ {
+ orientedInBounds.y += orientedInBounds.height;
+ orientedInBounds.height = -orientedInBounds.height;
+ }
+
+ DOffset =
+ gl::Vector2(static_cast<float>(orientedInBounds.x - sourceArea.x) / sourceArea.width,
+ static_cast<float>(orientedInBounds.y - sourceArea.y) / sourceArea.height);
+ DSize = gl::Vector2(static_cast<float>(orientedInBounds.width) / sourceArea.width,
+ static_cast<float>(orientedInBounds.height) / sourceArea.height);
+ }
+
+ ASSERT(DSize.x != 0.0 && DSize.y != 0.0);
+ gl::Vector2 texCoordScale = gl::Vector2(TSize.x / DSize.x, TSize.y / DSize.y);
+ gl::Vector2 texCoordOffset = gl::Vector2(TOffset.x - DOffset.x * texCoordScale.x,
+ TOffset.y - DOffset.y * texCoordScale.y);
+
+ // Reset all the state except scissor and viewport
+ mStateManager->setDepthRange(0.0f, 1.0f);
+ mStateManager->setBlendEnabled(false);
+ mStateManager->setColorMask(true, true, true, true);
+ mStateManager->setSampleAlphaToCoverageEnabled(false);
+ mStateManager->setSampleCoverageEnabled(false);
+ mStateManager->setDepthTestEnabled(false);
+ mStateManager->setStencilTestEnabled(false);
+ mStateManager->setCullFaceEnabled(false);
+ mStateManager->setPolygonOffsetFillEnabled(false);
+ mStateManager->setRasterizerDiscardEnabled(false);
+
+ // Use the viewport to draw exactly to the destination rectangle
+ mStateManager->setViewport(destArea);
+
+ // Set uniforms
+ setScratchTextureParameter(GL_TEXTURE_MIN_FILTER, filter);
+ setScratchTextureParameter(GL_TEXTURE_MAG_FILTER, filter);
+ setScratchTextureParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ setScratchTextureParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ mStateManager->activeTexture(0);
+ mStateManager->bindTexture(GL_TEXTURE_2D, mScratchTextures[0]);
+
+ mStateManager->useProgram(mBlitProgram);
+ mFunctions->uniform1i(mSourceTextureLocation, 0);
+ mFunctions->uniform2f(mScaleLocation, texCoordScale.x, texCoordScale.y);
+ mFunctions->uniform2f(mOffsetLocation, texCoordOffset.x, texCoordOffset.y);
+
+ const FramebufferGL *destGL = GetImplAs<FramebufferGL>(dest);
+ mStateManager->bindFramebuffer(GL_DRAW_FRAMEBUFFER, destGL->getFramebufferID());
+
+ mStateManager->bindVertexArray(mVAO, 0);
+ mFunctions->drawArrays(GL_TRIANGLES, 0, 3);
+
+ return gl::NoError();
+}
+
+gl::Error BlitGL::initializeResources()
+{
+ if (mBlitProgram == 0)
+ {
+ mBlitProgram = mFunctions->createProgram();
+
+ // Compile the fragment shader
+ // It uses a single, large triangle, to avoid arithmetic precision issues where fragments
+ // with the same Y coordinate don't get exactly the same interpolated texcoord Y.
+ const char *vsSource =
+ "#version 150\n"
+ "out vec2 v_texcoord;\n"
+ "uniform vec2 u_scale;\n"
+ "uniform vec2 u_offset;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " const vec2 quad_positions[3] = vec2[3]\n"
+ " (\n"
+ " vec2(-0.5f, 0.0f),\n"
+ " vec2( 1.5f, 0.0f),\n"
+ " vec2( 0.5f, 2.0f)\n"
+ " );\n"
+ "\n"
+ " gl_Position = vec4((quad_positions[gl_VertexID] * 2.0) - 1.0, 0.0, 1.0);\n"
+ " v_texcoord = quad_positions[gl_VertexID] * u_scale + u_offset;\n"
+ "}\n";
+
+ GLuint vs = mFunctions->createShader(GL_VERTEX_SHADER);
+ mFunctions->shaderSource(vs, 1, &vsSource, nullptr);
+ mFunctions->compileShader(vs);
+ ANGLE_TRY(CheckCompileStatus(mFunctions, vs));
+
+ mFunctions->attachShader(mBlitProgram, vs);
+ mFunctions->deleteShader(vs);
+
+ // Compile the vertex shader
+ // It discards if the texcoord is outside (0, 1)^2 so the blitframebuffer workaround
+ // doesn't write when the point sampled is outside of the source framebuffer.
+ const char *fsSource =
+ "#version 150\n"
+ "uniform sampler2D u_source_texture;\n"
+ "in vec2 v_texcoord;\n"
+ "out vec4 output_color;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " if (clamp(v_texcoord, vec2(0.0), vec2(1.0)) != v_texcoord)\n"
+ " {\n"
+ " discard;\n"
+ " }\n"
+ " output_color = texture(u_source_texture, v_texcoord);\n"
+ "}\n";
+
+ GLuint fs = mFunctions->createShader(GL_FRAGMENT_SHADER);
+ mFunctions->shaderSource(fs, 1, &fsSource, nullptr);
+ mFunctions->compileShader(fs);
+ ANGLE_TRY(CheckCompileStatus(mFunctions, fs));
+
+ mFunctions->attachShader(mBlitProgram, fs);
+ mFunctions->deleteShader(fs);
+
+ mFunctions->linkProgram(mBlitProgram);
+ ANGLE_TRY(CheckLinkStatus(mFunctions, mBlitProgram));
+
+ mSourceTextureLocation = mFunctions->getUniformLocation(mBlitProgram, "u_source_texture");
+ mScaleLocation = mFunctions->getUniformLocation(mBlitProgram, "u_scale");
+ mOffsetLocation = mFunctions->getUniformLocation(mBlitProgram, "u_offset");
+ mStateManager->useProgram(mBlitProgram);
+ }
+
+ for (size_t i = 0; i < ArraySize(mScratchTextures); i++)
+ {
+ if (mScratchTextures[i] == 0)
+ {
+ mFunctions->genTextures(1, &mScratchTextures[i]);
+ }
+ }
+
+ if (mScratchFBO == 0)
+ {
+ mFunctions->genFramebuffers(1, &mScratchFBO);
+ }
+
+ if (mVAO == 0)
+ {
+ mFunctions->genVertexArrays(1, &mVAO);
+ }
+
+ return gl::NoError();
+}
+
+void BlitGL::orphanScratchTextures()
+{
+ for (auto texture : mScratchTextures)
+ {
+ mStateManager->bindTexture(GL_TEXTURE_2D, texture);
+ mFunctions->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
+ }
+}
+
+void BlitGL::setScratchTextureParameter(GLenum param, GLenum value)
+{
+ for (auto texture : mScratchTextures)
+ {
+ mStateManager->bindTexture(GL_TEXTURE_2D, texture);
+ mFunctions->texParameteri(GL_TEXTURE_2D, param, value);
+ mFunctions->texParameteri(GL_TEXTURE_2D, param, value);
+ }
+}
+
+} // namespace rx
diff --git a/gfx/angle/src/libANGLE/renderer/gl/BlitGL.h b/gfx/angle/src/libANGLE/renderer/gl/BlitGL.h
new file mode 100755
index 000000000..b306ede29
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/BlitGL.h
@@ -0,0 +1,83 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// BlitGL.h: Defines the BlitGL class, a helper for blitting textures
+
+#ifndef LIBANGLE_RENDERER_GL_BLITGL_H_
+#define LIBANGLE_RENDERER_GL_BLITGL_H_
+
+#include "angle_gl.h"
+#include "common/angleutils.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/Error.h"
+
+namespace gl
+{
+class Framebuffer;
+}
+
+namespace rx
+{
+
+class FramebufferGL;
+class FunctionsGL;
+class StateManagerGL;
+struct WorkaroundsGL;
+
+class BlitGL : public angle::NonCopyable
+{
+ public:
+ BlitGL(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ StateManagerGL *stateManager);
+ ~BlitGL();
+
+ gl::Error copyImageToLUMAWorkaroundTexture(GLuint texture,
+ GLenum textureType,
+ GLenum target,
+ GLenum lumaFormat,
+ size_t level,
+ const gl::Rectangle &sourceArea,
+ GLenum internalFormat,
+ const gl::Framebuffer *source);
+ gl::Error copySubImageToLUMAWorkaroundTexture(GLuint texture,
+ GLenum textureType,
+ GLenum target,
+ GLenum lumaFormat,
+ size_t level,
+ const gl::Offset &destOffset,
+ const gl::Rectangle &sourceArea,
+ const gl::Framebuffer *source);
+
+ gl::Error blitColorBufferWithShader(const gl::Framebuffer *source,
+ const gl::Framebuffer *dest,
+ const gl::Rectangle &sourceArea,
+ const gl::Rectangle &destArea,
+ GLenum filter);
+
+ gl::Error initializeResources();
+
+ private:
+ void orphanScratchTextures();
+ void setScratchTextureParameter(GLenum param, GLenum value);
+
+ const FunctionsGL *mFunctions;
+ const WorkaroundsGL &mWorkarounds;
+ StateManagerGL *mStateManager;
+
+ GLuint mBlitProgram;
+ GLint mSourceTextureLocation;
+ GLint mScaleLocation;
+ GLint mOffsetLocation;
+
+ GLuint mScratchTextures[2];
+ GLuint mScratchFBO;
+
+ GLuint mVAO;
+};
+}
+
+#endif // LIBANGLE_RENDERER_GL_BLITGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/BufferGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/BufferGL.cpp
new file mode 100755
index 000000000..a5eda6b30
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/BufferGL.cpp
@@ -0,0 +1,204 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// BufferGL.cpp: Implements the class methods for BufferGL.
+
+#include "libANGLE/renderer/gl/BufferGL.h"
+
+#include "common/debug.h"
+#include "common/utilities.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+#include "libANGLE/renderer/gl/StateManagerGL.h"
+#include "libANGLE/renderer/gl/renderergl_utils.h"
+
+namespace rx
+{
+
+// Use the GL_COPY_READ_BUFFER binding when two buffers need to be bound simultaneously.
+// GL_ELEMENT_ARRAY_BUFFER is supported on more versions but can modify the state of the currently
+// bound VAO. Two simultaneous buffer bindings are only needed for glCopyBufferSubData which also
+// adds the GL_COPY_READ_BUFFER binding.
+static const GLenum SourceBufferOperationTarget = GL_COPY_READ_BUFFER;
+
+// Use the GL_ELEMENT_ARRAY_BUFFER binding for most operations since it's available on all
+// supported GL versions and doesn't affect any current state when it changes.
+static const GLenum DestBufferOperationTarget = GL_ARRAY_BUFFER;
+
+BufferGL::BufferGL(const gl::BufferState &state,
+ const FunctionsGL *functions,
+ StateManagerGL *stateManager)
+ : BufferImpl(state),
+ mIsMapped(false),
+ mMapOffset(0),
+ mMapSize(0),
+ mShadowBufferData(!CanMapBufferForRead(functions)),
+ mShadowCopy(),
+ mBufferSize(0),
+ mFunctions(functions),
+ mStateManager(stateManager),
+ mBufferID(0)
+{
+ ASSERT(mFunctions);
+ ASSERT(mStateManager);
+
+ mFunctions->genBuffers(1, &mBufferID);
+}
+
+BufferGL::~BufferGL()
+{
+ mStateManager->deleteBuffer(mBufferID);
+ mBufferID = 0;
+}
+
+gl::Error BufferGL::setData(GLenum /*target*/, const void *data, size_t size, GLenum usage)
+{
+ mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
+ mFunctions->bufferData(DestBufferOperationTarget, size, data, usage);
+
+ if (mShadowBufferData)
+ {
+ if (!mShadowCopy.resize(size))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize buffer data shadow copy.");
+ }
+
+ if (size > 0 && data != nullptr)
+ {
+ memcpy(mShadowCopy.data(), data, size);
+ }
+ }
+
+ mBufferSize = size;
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error BufferGL::setSubData(GLenum /*target*/, const void *data, size_t size, size_t offset)
+{
+ mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
+ mFunctions->bufferSubData(DestBufferOperationTarget, offset, size, data);
+
+ if (mShadowBufferData && size > 0)
+ {
+ memcpy(mShadowCopy.data() + offset, data, size);
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error BufferGL::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
+{
+ BufferGL *sourceGL = GetAs<BufferGL>(source);
+
+ mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
+ mStateManager->bindBuffer(SourceBufferOperationTarget, sourceGL->getBufferID());
+
+ mFunctions->copyBufferSubData(SourceBufferOperationTarget, DestBufferOperationTarget, sourceOffset, destOffset, size);
+
+ if (mShadowBufferData && size > 0)
+ {
+ ASSERT(sourceGL->mShadowBufferData);
+ memcpy(mShadowCopy.data() + destOffset, sourceGL->mShadowCopy.data() + sourceOffset, size);
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error BufferGL::map(GLenum access, GLvoid **mapPtr)
+{
+ if (mShadowBufferData)
+ {
+ *mapPtr = mShadowCopy.data();
+ }
+ else
+ {
+ mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
+ *mapPtr = mFunctions->mapBuffer(DestBufferOperationTarget, access);
+ }
+
+ mIsMapped = true;
+ mMapOffset = 0;
+ mMapSize = mBufferSize;
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error BufferGL::mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr)
+{
+ if (mShadowBufferData)
+ {
+ *mapPtr = mShadowCopy.data() + offset;
+ }
+ else
+ {
+ mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
+ *mapPtr = mFunctions->mapBufferRange(DestBufferOperationTarget, offset, length, access);
+ }
+
+ mIsMapped = true;
+ mMapOffset = offset;
+ mMapSize = length;
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error BufferGL::unmap(GLboolean *result)
+{
+ ASSERT(result);
+ ASSERT(mIsMapped);
+
+ if (mShadowBufferData)
+ {
+ mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
+ mFunctions->bufferSubData(DestBufferOperationTarget, mMapOffset, mMapSize,
+ mShadowCopy.data() + mMapOffset);
+ *result = GL_TRUE;
+ }
+ else
+ {
+ mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
+ *result = mFunctions->unmapBuffer(DestBufferOperationTarget);
+ }
+
+ mIsMapped = false;
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error BufferGL::getIndexRange(GLenum type,
+ size_t offset,
+ size_t count,
+ bool primitiveRestartEnabled,
+ gl::IndexRange *outRange)
+{
+ ASSERT(!mIsMapped);
+
+ if (mShadowBufferData)
+ {
+ *outRange = gl::ComputeIndexRange(type, mShadowCopy.data() + offset, count,
+ primitiveRestartEnabled);
+ }
+ else
+ {
+ mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
+
+ const gl::Type &typeInfo = gl::GetTypeInfo(type);
+ const uint8_t *bufferData = MapBufferRangeWithFallback(
+ mFunctions, DestBufferOperationTarget, offset, count * typeInfo.bytes, GL_MAP_READ_BIT);
+ *outRange = gl::ComputeIndexRange(type, bufferData, count, primitiveRestartEnabled);
+ mFunctions->unmapBuffer(DestBufferOperationTarget);
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+GLuint BufferGL::getBufferID() const
+{
+ return mBufferID;
+}
+
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/BufferGL.h b/gfx/angle/src/libANGLE/renderer/gl/BufferGL.h
new file mode 100755
index 000000000..d886873fe
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/BufferGL.h
@@ -0,0 +1,62 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// BufferGL.h: Defines the class interface for BufferGL.
+
+#ifndef LIBANGLE_RENDERER_GL_BUFFERGL_H_
+#define LIBANGLE_RENDERER_GL_BUFFERGL_H_
+
+#include "common/MemoryBuffer.h"
+#include "libANGLE/renderer/BufferImpl.h"
+
+namespace rx
+{
+
+class FunctionsGL;
+class StateManagerGL;
+
+class BufferGL : public BufferImpl
+{
+ public:
+ BufferGL(const gl::BufferState &state,
+ const FunctionsGL *functions,
+ StateManagerGL *stateManager);
+ ~BufferGL() override;
+
+ gl::Error setData(GLenum target, const void *data, size_t size, GLenum usage) override;
+ gl::Error setSubData(GLenum target, const void *data, size_t size, size_t offset) override;
+ gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) override;
+ gl::Error map(GLenum access, GLvoid **mapPtr) override;
+ gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) override;
+ gl::Error unmap(GLboolean *result) override;
+
+ gl::Error getIndexRange(GLenum type,
+ size_t offset,
+ size_t count,
+ bool primitiveRestartEnabled,
+ gl::IndexRange *outRange) override;
+
+ GLuint getBufferID() const;
+
+ private:
+ bool mIsMapped;
+ size_t mMapOffset;
+ size_t mMapSize;
+
+ bool mShadowBufferData;
+ MemoryBuffer mShadowCopy;
+
+ size_t mBufferSize;
+
+ const FunctionsGL *mFunctions;
+ StateManagerGL *mStateManager;
+
+ GLuint mBufferID;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_BUFFERGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/CompilerGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/CompilerGL.cpp
new file mode 100755
index 000000000..71be15611
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/CompilerGL.cpp
@@ -0,0 +1,91 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// CompilerGL:
+// Implementation of the GL compiler methods.
+//
+
+#include "libANGLE/renderer/gl/CompilerGL.h"
+
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+
+namespace rx
+{
+
+namespace
+{
+
+ShShaderOutput GetShaderOutputType(const FunctionsGL *functions)
+{
+ ASSERT(functions);
+
+ if (functions->standard == STANDARD_GL_DESKTOP)
+ {
+ // GLSL outputs
+ if (functions->isAtLeastGL(gl::Version(4, 5)))
+ {
+ return SH_GLSL_450_CORE_OUTPUT;
+ }
+ else if (functions->isAtLeastGL(gl::Version(4, 4)))
+ {
+ return SH_GLSL_440_CORE_OUTPUT;
+ }
+ else if (functions->isAtLeastGL(gl::Version(4, 3)))
+ {
+ return SH_GLSL_430_CORE_OUTPUT;
+ }
+ else if (functions->isAtLeastGL(gl::Version(4, 2)))
+ {
+ return SH_GLSL_420_CORE_OUTPUT;
+ }
+ else if (functions->isAtLeastGL(gl::Version(4, 1)))
+ {
+ return SH_GLSL_410_CORE_OUTPUT;
+ }
+ else if (functions->isAtLeastGL(gl::Version(4, 0)))
+ {
+ return SH_GLSL_400_CORE_OUTPUT;
+ }
+ else if (functions->isAtLeastGL(gl::Version(3, 3)))
+ {
+ return SH_GLSL_330_CORE_OUTPUT;
+ }
+ else if (functions->isAtLeastGL(gl::Version(3, 2)))
+ {
+ return SH_GLSL_150_CORE_OUTPUT;
+ }
+ else if (functions->isAtLeastGL(gl::Version(3, 1)))
+ {
+ return SH_GLSL_140_OUTPUT;
+ }
+ else if (functions->isAtLeastGL(gl::Version(3, 0)))
+ {
+ return SH_GLSL_130_OUTPUT;
+ }
+ else
+ {
+ return SH_GLSL_COMPATIBILITY_OUTPUT;
+ }
+ }
+ else if (functions->standard == STANDARD_GL_ES)
+ {
+ // ESSL outputs
+ return SH_ESSL_OUTPUT;
+ }
+ else
+ {
+ UNREACHABLE();
+ return ShShaderOutput(0);
+ }
+}
+
+} // anonymous namespace
+
+CompilerGL::CompilerGL(const FunctionsGL *functions)
+ : mTranslatorOutputType(GetShaderOutputType(functions))
+{
+}
+
+} // namespace rx
diff --git a/gfx/angle/src/libANGLE/renderer/gl/CompilerGL.h b/gfx/angle/src/libANGLE/renderer/gl/CompilerGL.h
new file mode 100755
index 000000000..eadbf67ed
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/CompilerGL.h
@@ -0,0 +1,33 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// CompilerGL.h: Defines the class interface for CompilerGL.
+
+#ifndef LIBANGLE_RENDERER_GL_COMPILERGL_H_
+#define LIBANGLE_RENDERER_GL_COMPILERGL_H_
+
+#include "libANGLE/renderer/CompilerImpl.h"
+
+namespace rx
+{
+class FunctionsGL;
+
+class CompilerGL : public CompilerImpl
+{
+ public:
+ CompilerGL(const FunctionsGL *functions);
+ ~CompilerGL() override {}
+
+ gl::Error release() override { return gl::Error(GL_NO_ERROR); }
+ ShShaderOutput getTranslatorOutputType() const override { return mTranslatorOutputType; }
+
+ private:
+ ShShaderOutput mTranslatorOutputType;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_COMPILERGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/ContextGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/ContextGL.cpp
new file mode 100755
index 000000000..8e378a4be
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/ContextGL.cpp
@@ -0,0 +1,370 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ContextGL:
+// OpenGL-specific functionality associated with a GL Context.
+//
+
+#include "libANGLE/renderer/gl/ContextGL.h"
+
+#include "libANGLE/renderer/gl/BufferGL.h"
+#include "libANGLE/renderer/gl/CompilerGL.h"
+#include "libANGLE/renderer/gl/FenceNVGL.h"
+#include "libANGLE/renderer/gl/FenceSyncGL.h"
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+#include "libANGLE/renderer/gl/FramebufferGL.h"
+#include "libANGLE/renderer/gl/PathGL.h"
+#include "libANGLE/renderer/gl/ProgramGL.h"
+#include "libANGLE/renderer/gl/QueryGL.h"
+#include "libANGLE/renderer/gl/RenderbufferGL.h"
+#include "libANGLE/renderer/gl/RendererGL.h"
+#include "libANGLE/renderer/gl/SamplerGL.h"
+#include "libANGLE/renderer/gl/ShaderGL.h"
+#include "libANGLE/renderer/gl/StateManagerGL.h"
+#include "libANGLE/renderer/gl/TextureGL.h"
+#include "libANGLE/renderer/gl/TransformFeedbackGL.h"
+#include "libANGLE/renderer/gl/VertexArrayGL.h"
+
+namespace rx
+{
+
+ContextGL::ContextGL(const gl::ContextState &state, RendererGL *renderer)
+ : ContextImpl(state), mRenderer(renderer)
+{
+}
+
+ContextGL::~ContextGL()
+{
+}
+
+gl::Error ContextGL::initialize()
+{
+ return gl::NoError();
+}
+
+CompilerImpl *ContextGL::createCompiler()
+{
+ return new CompilerGL(getFunctions());
+}
+
+ShaderImpl *ContextGL::createShader(const gl::ShaderState &data)
+{
+ return new ShaderGL(data, getFunctions(), getWorkaroundsGL());
+}
+
+ProgramImpl *ContextGL::createProgram(const gl::ProgramState &data)
+{
+ return new ProgramGL(data, getFunctions(), getWorkaroundsGL(), getStateManager(),
+ getExtensions().pathRendering);
+}
+
+FramebufferImpl *ContextGL::createFramebuffer(const gl::FramebufferState &data)
+{
+ return new FramebufferGL(data, getFunctions(), getStateManager(), getWorkaroundsGL(),
+ mRenderer->getBlitter(), false);
+}
+
+TextureImpl *ContextGL::createTexture(const gl::TextureState &state)
+{
+ return new TextureGL(state, getFunctions(), getWorkaroundsGL(), getStateManager(),
+ mRenderer->getBlitter());
+}
+
+RenderbufferImpl *ContextGL::createRenderbuffer()
+{
+ return new RenderbufferGL(getFunctions(), getWorkaroundsGL(), getStateManager(),
+ getNativeTextureCaps());
+}
+
+BufferImpl *ContextGL::createBuffer(const gl::BufferState &state)
+{
+ return new BufferGL(state, getFunctions(), getStateManager());
+}
+
+VertexArrayImpl *ContextGL::createVertexArray(const gl::VertexArrayState &data)
+{
+ return new VertexArrayGL(data, getFunctions(), getStateManager());
+}
+
+QueryImpl *ContextGL::createQuery(GLenum type)
+{
+ return new QueryGL(type, getFunctions(), getStateManager());
+}
+
+FenceNVImpl *ContextGL::createFenceNV()
+{
+ return new FenceNVGL(getFunctions());
+}
+
+FenceSyncImpl *ContextGL::createFenceSync()
+{
+ return new FenceSyncGL(getFunctions());
+}
+
+TransformFeedbackImpl *ContextGL::createTransformFeedback(const gl::TransformFeedbackState &state)
+{
+ return new TransformFeedbackGL(state, getFunctions(), getStateManager());
+}
+
+SamplerImpl *ContextGL::createSampler()
+{
+ return new SamplerGL(getFunctions(), getStateManager());
+}
+
+std::vector<PathImpl *> ContextGL::createPaths(GLsizei range)
+{
+ const FunctionsGL *funcs = getFunctions();
+
+ std::vector<PathImpl *> ret;
+ ret.reserve(range);
+
+ const GLuint first = funcs->genPathsNV(range);
+ if (first == 0)
+ return ret;
+
+ for (GLsizei i = 0; i < range; ++i)
+ {
+ const auto id = first + i;
+ ret.push_back(new PathGL(funcs, id));
+ }
+
+ return ret;
+}
+
+gl::Error ContextGL::flush()
+{
+ return mRenderer->flush();
+}
+
+gl::Error ContextGL::finish()
+{
+ return mRenderer->finish();
+}
+
+gl::Error ContextGL::drawArrays(GLenum mode, GLint first, GLsizei count)
+{
+ return mRenderer->drawArrays(mState, mode, first, count);
+}
+
+gl::Error ContextGL::drawArraysInstanced(GLenum mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount)
+{
+ return mRenderer->drawArraysInstanced(mState, mode, first, count, instanceCount);
+}
+
+gl::Error ContextGL::drawElements(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ const gl::IndexRange &indexRange)
+{
+ return mRenderer->drawElements(mState, mode, count, type, indices, indexRange);
+}
+
+gl::Error ContextGL::drawElementsInstanced(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ GLsizei instances,
+ const gl::IndexRange &indexRange)
+{
+ return mRenderer->drawElementsInstanced(mState, mode, count, type, indices, instances,
+ indexRange);
+}
+
+gl::Error ContextGL::drawRangeElements(GLenum mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ const gl::IndexRange &indexRange)
+{
+ return mRenderer->drawRangeElements(mState, mode, start, end, count, type, indices, indexRange);
+}
+
+void ContextGL::stencilFillPath(const gl::Path *path, GLenum fillMode, GLuint mask)
+{
+ mRenderer->stencilFillPath(mState, path, fillMode, mask);
+}
+
+void ContextGL::stencilStrokePath(const gl::Path *path, GLint reference, GLuint mask)
+{
+ mRenderer->stencilStrokePath(mState, path, reference, mask);
+}
+
+void ContextGL::coverFillPath(const gl::Path *path, GLenum coverMode)
+{
+ mRenderer->coverFillPath(mState, path, coverMode);
+}
+
+void ContextGL::coverStrokePath(const gl::Path *path, GLenum coverMode)
+{
+ mRenderer->coverStrokePath(mState, path, coverMode);
+}
+
+void ContextGL::stencilThenCoverFillPath(const gl::Path *path,
+ GLenum fillMode,
+ GLuint mask,
+ GLenum coverMode)
+{
+ mRenderer->stencilThenCoverFillPath(mState, path, fillMode, mask, coverMode);
+}
+
+void ContextGL::stencilThenCoverStrokePath(const gl::Path *path,
+ GLint reference,
+ GLuint mask,
+ GLenum coverMode)
+{
+ mRenderer->stencilThenCoverStrokePath(mState, path, reference, mask, coverMode);
+}
+
+void ContextGL::coverFillPathInstanced(const std::vector<gl::Path *> &paths,
+ GLenum coverMode,
+ GLenum transformType,
+ const GLfloat *transformValues)
+{
+ mRenderer->coverFillPathInstanced(mState, paths, coverMode, transformType, transformValues);
+}
+
+void ContextGL::coverStrokePathInstanced(const std::vector<gl::Path *> &paths,
+ GLenum coverMode,
+ GLenum transformType,
+ const GLfloat *transformValues)
+{
+ mRenderer->coverStrokePathInstanced(mState, paths, coverMode, transformType, transformValues);
+}
+
+void ContextGL::stencilFillPathInstanced(const std::vector<gl::Path *> &paths,
+ GLenum fillMode,
+ GLuint mask,
+ GLenum transformType,
+ const GLfloat *transformValues)
+{
+ mRenderer->stencilFillPathInstanced(mState, paths, fillMode, mask, transformType,
+ transformValues);
+}
+
+void ContextGL::stencilStrokePathInstanced(const std::vector<gl::Path *> &paths,
+ GLint reference,
+ GLuint mask,
+ GLenum transformType,
+ const GLfloat *transformValues)
+{
+ mRenderer->stencilStrokePathInstanced(mState, paths, reference, mask, transformType,
+ transformValues);
+}
+
+void ContextGL::stencilThenCoverFillPathInstanced(const std::vector<gl::Path *> &paths,
+ GLenum coverMode,
+ GLenum fillMode,
+ GLuint mask,
+ GLenum transformType,
+ const GLfloat *transformValues)
+{
+ mRenderer->stencilThenCoverFillPathInstanced(mState, paths, coverMode, fillMode, mask,
+ transformType, transformValues);
+}
+
+void ContextGL::stencilThenCoverStrokePathInstanced(const std::vector<gl::Path *> &paths,
+ GLenum coverMode,
+ GLint reference,
+ GLuint mask,
+ GLenum transformType,
+ const GLfloat *transformValues)
+{
+ mRenderer->stencilThenCoverStrokePathInstanced(mState, paths, coverMode, reference, mask,
+ transformType, transformValues);
+}
+
+GLenum ContextGL::getResetStatus()
+{
+ return mRenderer->getResetStatus();
+}
+
+std::string ContextGL::getVendorString() const
+{
+ return mRenderer->getVendorString();
+}
+
+std::string ContextGL::getRendererDescription() const
+{
+ return mRenderer->getRendererDescription();
+}
+
+void ContextGL::insertEventMarker(GLsizei length, const char *marker)
+{
+ mRenderer->insertEventMarker(length, marker);
+}
+
+void ContextGL::pushGroupMarker(GLsizei length, const char *marker)
+{
+ mRenderer->pushGroupMarker(length, marker);
+}
+
+void ContextGL::popGroupMarker()
+{
+ mRenderer->popGroupMarker();
+}
+
+void ContextGL::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits)
+{
+ mRenderer->getStateManager()->syncState(state, dirtyBits);
+}
+
+GLint ContextGL::getGPUDisjoint()
+{
+ return mRenderer->getGPUDisjoint();
+}
+
+GLint64 ContextGL::getTimestamp()
+{
+ return mRenderer->getTimestamp();
+}
+
+void ContextGL::onMakeCurrent(const gl::ContextState &data)
+{
+ // Queries need to be paused/resumed on context switches
+ mRenderer->getStateManager()->onMakeCurrent(data);
+}
+
+const gl::Caps &ContextGL::getNativeCaps() const
+{
+ return mRenderer->getNativeCaps();
+}
+
+const gl::TextureCapsMap &ContextGL::getNativeTextureCaps() const
+{
+ return mRenderer->getNativeTextureCaps();
+}
+
+const gl::Extensions &ContextGL::getNativeExtensions() const
+{
+ return mRenderer->getNativeExtensions();
+}
+
+const gl::Limitations &ContextGL::getNativeLimitations() const
+{
+ return mRenderer->getNativeLimitations();
+}
+
+const FunctionsGL *ContextGL::getFunctions() const
+{
+ return mRenderer->getFunctions();
+}
+
+StateManagerGL *ContextGL::getStateManager()
+{
+ return mRenderer->getStateManager();
+}
+
+const WorkaroundsGL &ContextGL::getWorkaroundsGL()
+{
+ return mRenderer->getWorkarounds();
+}
+
+} // namespace rx
diff --git a/gfx/angle/src/libANGLE/renderer/gl/ContextGL.h b/gfx/angle/src/libANGLE/renderer/gl/ContextGL.h
new file mode 100755
index 000000000..b3d5e0ee8
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/ContextGL.h
@@ -0,0 +1,183 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// ContextGL:
+// OpenGL-specific functionality associated with a GL Context.
+//
+
+#ifndef LIBANGLE_RENDERER_GL_CONTEXTGL_H_
+#define LIBANGLE_RENDERER_GL_CONTEXTGL_H_
+
+#include "libANGLE/renderer/ContextImpl.h"
+
+namespace sh
+{
+struct BlockMemberInfo;
+}
+
+namespace rx
+{
+class FunctionsGL;
+class RendererGL;
+class StateManagerGL;
+struct WorkaroundsGL;
+
+class ContextGL : public ContextImpl
+{
+ public:
+ ContextGL(const gl::ContextState &state, RendererGL *renderer);
+ ~ContextGL() override;
+
+ gl::Error initialize() override;
+
+ // Shader creation
+ CompilerImpl *createCompiler() override;
+ ShaderImpl *createShader(const gl::ShaderState &data) override;
+ ProgramImpl *createProgram(const gl::ProgramState &data) override;
+
+ // Framebuffer creation
+ FramebufferImpl *createFramebuffer(const gl::FramebufferState &data) override;
+
+ // Texture creation
+ TextureImpl *createTexture(const gl::TextureState &state) override;
+
+ // Renderbuffer creation
+ RenderbufferImpl *createRenderbuffer() override;
+
+ // Buffer creation
+ BufferImpl *createBuffer(const gl::BufferState &state) override;
+
+ // Vertex Array creation
+ VertexArrayImpl *createVertexArray(const gl::VertexArrayState &data) override;
+
+ // Query and Fence creation
+ QueryImpl *createQuery(GLenum type) override;
+ FenceNVImpl *createFenceNV() override;
+ FenceSyncImpl *createFenceSync() override;
+
+ // Transform Feedback creation
+ TransformFeedbackImpl *createTransformFeedback(
+ const gl::TransformFeedbackState &state) override;
+
+ // Sampler object creation
+ SamplerImpl *createSampler() override;
+
+ // Path object creation
+ std::vector<PathImpl *> createPaths(GLsizei range) override;
+
+ // Flush and finish.
+ gl::Error flush() override;
+ gl::Error finish() override;
+
+ // Drawing methods.
+ gl::Error drawArrays(GLenum mode, GLint first, GLsizei count) override;
+ gl::Error drawArraysInstanced(GLenum mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount) override;
+
+ gl::Error drawElements(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ const gl::IndexRange &indexRange) override;
+ gl::Error drawElementsInstanced(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ GLsizei instances,
+ const gl::IndexRange &indexRange) override;
+ gl::Error drawRangeElements(GLenum mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ const gl::IndexRange &indexRange) override;
+
+ // CHROMIUM_path_rendering implementation
+ void stencilFillPath(const gl::Path *path, GLenum fillMode, GLuint mask) override;
+ void stencilStrokePath(const gl::Path *path, GLint reference, GLuint mask) override;
+ void coverFillPath(const gl::Path *path, GLenum coverMode) override;
+ void coverStrokePath(const gl::Path *path, GLenum coverMode) override;
+ void stencilThenCoverFillPath(const gl::Path *path,
+ GLenum fillMode,
+ GLuint mask,
+ GLenum coverMode) override;
+ void stencilThenCoverStrokePath(const gl::Path *path,
+ GLint reference,
+ GLuint mask,
+ GLenum coverMode) override;
+ void coverFillPathInstanced(const std::vector<gl::Path *> &paths,
+ GLenum coverMode,
+ GLenum transformType,
+ const GLfloat *transformValues) override;
+ void coverStrokePathInstanced(const std::vector<gl::Path *> &paths,
+ GLenum coverMode,
+ GLenum transformType,
+ const GLfloat *transformValues) override;
+ void stencilFillPathInstanced(const std::vector<gl::Path *> &paths,
+ GLenum fillMode,
+ GLuint mask,
+ GLenum transformType,
+ const GLfloat *transformValues) override;
+ void stencilStrokePathInstanced(const std::vector<gl::Path *> &paths,
+ GLint reference,
+ GLuint mask,
+ GLenum transformType,
+ const GLfloat *transformValues) override;
+ void stencilThenCoverFillPathInstanced(const std::vector<gl::Path *> &paths,
+ GLenum coverMode,
+ GLenum fillMode,
+ GLuint mask,
+ GLenum transformType,
+ const GLfloat *transformValues) override;
+ void stencilThenCoverStrokePathInstanced(const std::vector<gl::Path *> &paths,
+ GLenum coverMode,
+ GLint reference,
+ GLuint mask,
+ GLenum transformType,
+ const GLfloat *transformValues) override;
+
+ // Device loss
+ GLenum getResetStatus() override;
+
+ // Vendor and description strings.
+ std::string getVendorString() const override;
+ std::string getRendererDescription() const override;
+
+ // Debug markers.
+ void insertEventMarker(GLsizei length, const char *marker) override;
+ void pushGroupMarker(GLsizei length, const char *marker) override;
+ void popGroupMarker() override;
+
+ // State sync with dirty bits.
+ void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) override;
+
+ // Disjoint timer queries
+ GLint getGPUDisjoint() override;
+ GLint64 getTimestamp() override;
+
+ // Context switching
+ void onMakeCurrent(const gl::ContextState &data) override;
+
+ // Caps queries
+ const gl::Caps &getNativeCaps() const override;
+ const gl::TextureCapsMap &getNativeTextureCaps() const override;
+ const gl::Extensions &getNativeExtensions() const override;
+ const gl::Limitations &getNativeLimitations() const override;
+
+ // Handle helpers
+ const FunctionsGL *getFunctions() const;
+ StateManagerGL *getStateManager();
+ const WorkaroundsGL &getWorkaroundsGL();
+
+ private:
+ RendererGL *mRenderer;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_GL_CONTEXTGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/DisplayGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/DisplayGL.cpp
new file mode 100755
index 000000000..30c5c7b4e
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/DisplayGL.cpp
@@ -0,0 +1,103 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// DisplayGL.h: GL implementation of egl::Display
+
+#include "libANGLE/renderer/gl/DisplayGL.h"
+
+#include "libANGLE/AttributeMap.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/renderer/gl/ContextGL.h"
+#include "libANGLE/renderer/gl/RendererGL.h"
+#include "libANGLE/renderer/gl/StateManagerGL.h"
+#include "libANGLE/renderer/gl/SurfaceGL.h"
+
+#include <EGL/eglext.h>
+
+namespace rx
+{
+
+DisplayGL::DisplayGL() : mRenderer(nullptr), mCurrentDrawSurface(nullptr)
+{
+}
+
+DisplayGL::~DisplayGL()
+{
+}
+
+egl::Error DisplayGL::initialize(egl::Display *display)
+{
+ mRenderer = new RendererGL(getFunctionsGL(), display->getAttributeMap());
+
+ const gl::Version &maxVersion = mRenderer->getMaxSupportedESVersion();
+ if (maxVersion < gl::Version(2, 0))
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "OpenGL ES 2.0 is not supportable.");
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+void DisplayGL::terminate()
+{
+ SafeDelete(mRenderer);
+}
+
+ImageImpl *DisplayGL::createImage(EGLenum target,
+ egl::ImageSibling *buffer,
+ const egl::AttributeMap &attribs)
+{
+ UNIMPLEMENTED();
+ return nullptr;
+}
+
+ContextImpl *DisplayGL::createContext(const gl::ContextState &state)
+{
+ ASSERT(mRenderer != nullptr);
+ return new ContextGL(state, mRenderer);
+}
+
+StreamProducerImpl *DisplayGL::createStreamProducerD3DTextureNV12(
+ egl::Stream::ConsumerType consumerType,
+ const egl::AttributeMap &attribs)
+{
+ UNIMPLEMENTED();
+ return nullptr;
+}
+
+egl::Error DisplayGL::makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context)
+{
+ // Notify the previous surface (if it still exists) that it is no longer current
+ if (mCurrentDrawSurface && mSurfaceSet.find(mCurrentDrawSurface) != mSurfaceSet.end())
+ {
+ ANGLE_TRY(GetImplAs<SurfaceGL>(mCurrentDrawSurface)->unMakeCurrent());
+ }
+ mCurrentDrawSurface = nullptr;
+
+ if (!drawSurface)
+ {
+ return egl::Error(EGL_SUCCESS);
+ }
+
+ // Pause transform feedback before making a new surface current, to workaround anglebug.com/1426
+ ContextGL *glContext = GetImplAs<ContextGL>(context);
+ glContext->getStateManager()->pauseTransformFeedback(context->getContextState());
+
+ SurfaceGL *glDrawSurface = GetImplAs<SurfaceGL>(drawSurface);
+ ANGLE_TRY(glDrawSurface->makeCurrent());
+ mCurrentDrawSurface = drawSurface;
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+gl::Version DisplayGL::getMaxSupportedESVersion() const
+{
+ ASSERT(mRenderer != nullptr);
+ return mRenderer->getMaxSupportedESVersion();
+}
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/DisplayGL.h b/gfx/angle/src/libANGLE/renderer/gl/DisplayGL.h
new file mode 100755
index 000000000..a63da6bbc
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/DisplayGL.h
@@ -0,0 +1,62 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// DisplayGL.h: Defines the class interface for DisplayGL.
+
+#ifndef LIBANGLE_RENDERER_GL_DISPLAYGL_H_
+#define LIBANGLE_RENDERER_GL_DISPLAYGL_H_
+
+#include "libANGLE/renderer/DisplayImpl.h"
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+
+namespace egl
+{
+class Surface;
+}
+
+namespace rx
+{
+
+class RendererGL;
+
+class DisplayGL : public DisplayImpl
+{
+ public:
+ DisplayGL();
+ ~DisplayGL() override;
+
+ egl::Error initialize(egl::Display *display) override;
+ void terminate() override;
+
+ ImageImpl *createImage(EGLenum target,
+ egl::ImageSibling *buffer,
+ const egl::AttributeMap &attribs) override;
+
+ ContextImpl *createContext(const gl::ContextState &state) override;
+
+ StreamProducerImpl *createStreamProducerD3DTextureNV12(
+ egl::Stream::ConsumerType consumerType,
+ const egl::AttributeMap &attribs) override;
+
+ egl::Error makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context) override;
+
+ virtual egl::Error getDriverVersion(std::string *version) const = 0;
+ gl::Version getMaxSupportedESVersion() const override;
+
+ protected:
+ RendererGL *getRenderer() const { return mRenderer; };
+
+ private:
+ virtual const FunctionsGL *getFunctionsGL() const = 0;
+
+ RendererGL *mRenderer;
+
+ egl::Surface *mCurrentDrawSurface;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_DISPLAYGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/FeatureSupportGL.md b/gfx/angle/src/libANGLE/renderer/gl/FeatureSupportGL.md
new file mode 100755
index 000000000..edc2353ab
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/FeatureSupportGL.md
@@ -0,0 +1,107 @@
+# ANGLE RendererGL feature support
+Documentation of OpenGL ES and EGL features, caps and formats and required extensions.
+
+## OpenGL ES Feature Support
+|Feature|OpenGL version|OpenGL extension|OpenGL ES version|OpenGL ES extension|Notes|
+|---|---|---|---|---|---|
+|Framebuffer/renderbuffer objects|3.0|[GL_EXT_framebuffer_object](https://www.opengl.org/registry/specs/EXT/framebuffer_object.txt)|2.0|--|Can potentially be emulated with Pbuffers but realistically this extension is always required.|
+|Blit framebuffer|3.0|[GL_EXT_framebuffer_blit](https://www.opengl.org/registry/specs/EXT/framebuffer_blit.txt)|3.0|[GL_ANGLE_framebuffer_blit](https://www.khronos.org/registry/gles/extensions/ANGLE/ANGLE_framebuffer_blit.txt) or [GL_NV_framebuffer_blit](https://www.khronos.org/registry/gles/extensions/NV/NV_framebuffer_blit.txt)||
+|Multisampling|3.0|[GL_EXT_framebuffer_multisample](https://www.opengl.org/registry/specs/EXT/framebuffer_multisample.txt)|3.0|[GL_EXT_multisampled_render_to_texture](https://www.khronos.org/registry/gles/extensions/EXT/EXT_multisampled_render_to_texture.txt) or [GL_ANGLE_framebuffer_multisample](https://www.khronos.org/registry/gles/extensions/ANGLE/ANGLE_framebuffer_multisample.txt)||
+|Depth textures|3.0|[GL_ARB_depth_texture](https://www.opengl.org/registry/specs/ARB/depth_texture.txt)|3.0|[GL_OES_depth_texture](https://www.khronos.org/registry/gles/extensions/OES/OES_depth_texture.txt) or [GL_ANGLE_depth_texture](https://www.khronos.org/registry/gles/extensions/ANGLE/ANGLE_depth_texture.txt)
+|Draw buffers (MRT)|2.0?|[GL_ARB_draw_buffers](https://www.opengl.org/registry/specs/ARB/draw_buffers.txt) or [GL_EXT_draw_buffers2](https://www.opengl.org/registry/specs/EXT/draw_buffers2.txt)|3.0|[GL_EXT_draw_buffers](https://www.khronos.org/registry/gles/extensions/EXT/EXT_draw_buffers.txt)||
+|3D textures|1.2|[GL_EXT_texture3D](https://www.opengl.org/registry/specs/EXT/texture3D.txt)|3.0|[GL_OES_texture_3D](https://www.khronos.org/registry/gles/extensions/OES/OES_texture_3D.txt)||
+|Array textures|3.0|[GL_EXT_texture_array](https://www.opengl.org/registry/specs/EXT/texture_array.txt)|3.0|--||
+|Texture storage|4.2|[GL_EXT_texture_storage](https://www.khronos.org/registry/gles/extensions/EXT/EXT_texture_storage.txt)|3.0|[GL_EXT_texture_storage](https://www.khronos.org/registry/gles/extensions/EXT/EXT_texture_storage.txt)|Can be emulated with TexImage calls.|
+|Uniform buffer object|3.1|[GL_ARB_uniform_buffer_object](https://www.opengl.org/registry/specs/ARB/uniform_buffer_object.txt)|3.0|--||
+|Sync objects|3.2|[GL_ARB_sync](https://www.opengl.org/registry/specs/ARB/sync.txt)|3.0|--||
+|Fence objects|--|[GL_NV_fence](https://www.opengl.org/registry/specs/NV/fence.txt)|--|[GL_NV_fence](https://www.opengl.org/registry/specs/NV/fence.txt)||
+|MapBuffer|1.5|--|--|[GL_OES_mapbuffer](https://www.khronos.org/registry/gles/extensions/OES/OES_mapbuffer.txt)||
+|MapBufferRange|3.0|[GL_ARB_map_buffer_range](https://www.opengl.org/registry/specs/ARB/map_buffer_range.txt)|3.0|[GL_EXT_map_buffer_range](https://www.khronos.org/registry/gles/extensions/EXT/EXT_map_buffer_range.txt)||
+|Transform feedback|3.0|[GL_EXT_transform_feedback](GL_EXT_transform_feedback) or [GL_EXT_transform_feedback2](http://developer.download.nvidia.com/opengl/specs/GL_EXT_transform_feedback2.txt) or [GL_ARB_transform_feedback3](https://www.opengl.org/registry/specs/ARB/transform_feedback3.txt)|3.0|--||
+|Sampler object|3.3|[GL_ARB_sampler_objects](https://www.opengl.org/registry/specs/ARB/sampler_objects.txt)|3.0|--||
+|Occlusion query|1.5|[GL_ARB_occlusion_query](https://www.opengl.org/registry/specs/ARB/occlusion_query.txt)|2.0|--||
+|Timer query|3.3|[GL_ARB_timer_query](https://www.opengl.org/registry/specs/ARB/timer_query.txt)|--|[GL_EXT_disjoint_timer_query](https://www.khronos.org/registry/gles/extensions/EXT/EXT_disjoint_timer_query.txt)||
+|Vertex array object|3.0|[GL_ARB_vertex_array_object](https://www.opengl.org/registry/specs/ARB/vertex_array_object.txt)|3.0|[GL_OES_vertex_array_object](https://www.khronos.org/registry/gles/extensions/OES/OES_vertex_array_object.txt)|Can be emulated but costsmany extra API calls. Virtualized contexts also require some kind of emulation of the default attribute state.|
+|Anisotropic filtering|--|[GL_EXT_texture_filter_anisotropic](https://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt)|--|[GL_EXT_texture_filter_anisotropic](https://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt)|Ubiquitous extension.|
+
+## OpenGL ES Caps
+|Cap(s)|OpenGL version|OpenGL extension|OpenGL ES version|OpenGL ES extension|Notes|
+|---|---|---|---|---|---|
+|GL_MAX_ELEMENT_INDEX|4.3|[GL_ARB_ES3_compatibility](https://www.opengl.org/registry/specs/ARB/ES3_compatibility.txt)|3.0|--|Seems pretty safe to use an arbitrary limit, all implementations tested return 0xFFFFFFFF.|
+|GL_MAX_3D_TEXTURE_SIZE|1.2|[GL_EXT_texture3D](https://www.opengl.org/registry/specs/EXT/texture3D.txt)|3.0|[GL_OES_texture_3D](https://www.khronos.org/registry/gles/extensions/OES/OES_texture_3D.txt)||
+|GL_MAX_TEXTURE_SIZE|1.0|--|2.0|--||
+|GL_MAX_CUBE_MAP_TEXTURE_SIZE|1.3|--|2.0||
+|GL_MAX_ARRAY_TEXTURE_LAYERS|3.0|[GL_EXT_texture_array](https://www.opengl.org/registry/specs/EXT/texture_array.txt)|3.0|--||
+|GL_MAX_TEXTURE_LOD_BIAS|1.5|[GL_EXT_texture_lod_bias](https://www.opengl.org/registry/specs/EXT/texture_lod_bias.txt)|3.0|--||
+|GL_MAX_RENDERBUFFER_SIZE GL_MAX_COLOR_ATTACHMENTS|3.0|[GL_EXT_framebuffer_object](https://www.opengl.org/registry/specs/EXT/framebuffer_object.txt) |2.0|--||
+|GL_MAX_DRAW_BUFFERS|2.0?|[GL_ARB_draw_buffers](https://www.opengl.org/registry/specs/ARB/draw_buffers.txt) or [GL_EXT_draw_buffers2](https://www.opengl.org/registry/specs/EXT/draw_buffers2.txt)|3.0|[GL_EXT_draw_buffers](https://www.khronos.org/registry/gles/extensions/EXT/EXT_draw_buffers.txt)||
+|GL_MAX_VIEWPORT_DIMS|1.0|--|2.0|--||
+|GL_ALIASED_POINT_SIZE_RANGE|1.0?|--|2.0|--||
+|GL_ALIASED_LINE_WIDTH_RANGE|1.2|--|2.0|--||
+|GL_ALIASED_LINE_WIDTH_RANGE|1.2|--|2.0|--||
+|GL_MAX_ELEMENTS_INDICES|1.2|--|3.0|--||
+|GL_MAX_ELEMENTS_VERTICES|1.2|--|3.0|--||
+|Shader format precision (glGetShaderPrecisionFormat)|4.1|[GL_ARB_ES2_compatibility](https://www.opengl.org/registry/specs/ARB/ES2_compatibility.txt)|2.0|--|Can use reasonable default values (IEEE float and twos complement integer).|
+|GL_MAX_VERTEX_ATTRIBS|2.0|--|2.0|--||
+|GL_MAX_VERTEX_UNIFORM_COMPONENTS|2.0|--|2.0|--||
+|GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS|2.0|--|2.0|--||
+|GL_MAX_VERTEX_UNIFORM_VECTORS GL_MAX_FRAGMENT_UNIFORM_VECTORS|4.1|[GL_ARB_ES2_compatibility](https://www.opengl.org/registry/specs/ARB/ES2_compatibility.txt)|2.0|--|Defined as GL_MAX_VERTEX_UNIFORM_COMPONENTS / 4 and GL_MAX_FRAGMENT_UNIFORM_COMPONENTS / 4. Can simply use those values when the cap is not available.|
+|GL_MAX_VERTEX_UNIFORM_BLOCKS GL_MAX_FRAGMENT_UNIFORM_BLOCKS GL_MAX_UNIFORM_BUFFER_BINDINGS GL_MAX_UNIFORM_BLOCK_SIZE GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT GL_MAX_COMBINED_UNIFORM_BLOCKS GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS |3.1|[GL_ARB_uniform_buffer_object](https://www.opengl.org/registry/specs/ARB/uniform_buffer_object.txt)|3.0|--||
+|GL_MAX_VERTEX_OUTPUT_COMPONENTS|3.2|--|3.0|--|Doesn't seem to be a desktop extension for this cap, it may be possible to use the minimum ES3 value (64) if lower than GL 3.2.|
+|GL_MAX_FRAGMENT_UNIFORM_COMPONENTS|2.0|--|2.0|--||
+|GL_MAX_TEXTURE_IMAGE_UNITS|2.0|--|2.0|--||
+|GL_MAX_FRAGMENT_INPUT_COMPONENTS|3.2|--|3.0|--|Doesn't seem to be a desktop extension for this cap either, it may be possible to use the minimum ES3 value (60) if lower than GL 3.2.|
+|GL_MIN_PROGRAM_TEXEL_OFFSET GL_MAX_PROGRAM_TEXEL_OFFSET|3.0|--|3.0|--|Could potentially be emulated in the shader by adding the offsets in normalized texture coordinates before sampling.|
+|GL_MAX_VARYING_COMPONENTS|3.0|[GL_ARB_ES3_compatibility](https://www.opengl.org/registry/specs/ARB/ES3_compatibility.txt)|3.0|--|Was depricated in the OpenGL core spec but re-added in GL_ARB_ES3_compatibility|
+|GL_MAX_VARYING_VECTORS|4.1|[GL_ARB_ES2_compatibility](https://www.opengl.org/registry/specs/ARB/ES2_compatibility.txt)|2.0|--|Defined as GL_MAX_VARYING_COMPONENTS / 4.|
+|GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS|3.0|[GL_EXT_transform_feedback](GL_EXT_transform_feedback) or [GL_EXT_transform_feedback2](http://developer.download.nvidia.com/opengl/specs/GL_EXT_transform_feedback2.txt) or [GL_ARB_transform_feedback3](https://www.opengl.org/registry/specs/ARB/transform_feedback3.txt)|3.0|--
+|GL_MAX_SAMPLES|3.0|[GL_EXT_framebuffer_multisample](https://www.opengl.org/registry/specs/EXT/framebuffer_multisample.txt)|3.0|[GL_EXT_multisampled_render_to_texture](https://www.khronos.org/registry/gles/extensions/EXT/EXT_multisampled_render_to_texture.txt) or [GL_ANGLE_framebuffer_multisample](https://www.khronos.org/registry/gles/extensions/ANGLE/ANGLE_framebuffer_multisample.txt)||
+|GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT|--|[GL_EXT_texture_filter_anisotropic](https://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt)|--|[GL_EXT_texture_filter_anisotropic](https://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt)|Ubiquitous extension.|
+|IMPLEMENTATION_COLOR_READ_FORMAT IMPLEMENTATION_COLOR_READ_TYPE|--|[GL_ARB_ES2_compatibility](https://www.opengl.org/registry/specs/ARB/ES2_compatibility.txt)|2.0|--|Desktop GL doesn't as many limitations as ES for ReadPixels, can either always return GL_RGBA/GL_UNSIGNED_BYTE or return the format and type of the read buffer.|
+
+##OpenGL ES Formats (TODO)
+|Format|OpenGL version|OpenGL extension|OpenGL ES version|OpenGL ES extension|Notes|
+|---|---|---|---|---|---|
+|GL_RGBA8<br>GL_RGB8 |1.0|--|3.0|[GL_OES_rgb8_rgba8](https://www.khronos.org/registry/gles/extensions/OES/OES_rgb8_rgba8.txt)||
+
+## ESSL Features (TODO)
+|Feature|GLSL version|Notes|
+|---|---|---|
+|Unsigned integers|1.30||
+|Pack layout std140|1.40||
+
+## ESSL3 Builtins
+Builtins that are added going from ESSL1 to ESSL3.
+
+|Function|GLSL version|Extension|Notes|
+|---|---|---|---|
+|sinh<br>cosh<br>tanh<br>asinh<br>acosh|1.30|||
+|atanh|1.10|||
+|abs (genIType)|1.30|[GL_EXT_gpu_shader4](https://www.opengl.org/registry/specs/EXT/gpu_shader4.txt)||
+|sign (genIType)|1.50|[GL_EXT_gpu_shader4](https://www.opengl.org/registry/specs/EXT/gpu_shader4.txt)|Can be emulated easily.|
+|trunc|1.30|||
+|round<br>roundEven|1.30|||
+|min (genIType, genUType)<br>max (genIType, genUType)<br>clamp (genIType, genUType)|1.30||
+|mix (genBType)|4.50|[GL_EXT_shader_integer_mix](https://www.opengl.org/registry/specs/EXT/shader_integer_mix.txt)|Should be possible to emulate with a ternery operation.|
+|modf|1.30|||
+|isnan|1.30|||
+|isinf|1.10|||
+|floatBitsToInt<br>floatBitsToUint<br>intBitsToFloat<br>uintBitsToFloat|3.30|[GL_ARB_shader_bit_encoding](https://www.opengl.org/registry/specs/ARB/shader_bit_encoding.txt) or [ARB_gpu_shader5](https://www.opengl.org/registry/specs/ARB/gpu_shader5.txt)||
+|packSnorm2x16<br>packHalf2x16<br>unpackSnorm2x16<br>unpackHalf2x16|4.20|[GL_ARB_shading_language_packing](https://www.opengl.org/registry/specs/ARB/shading_language_packing.txt)|Can be emulated using bit casting functions.|
+|packUnorm2x16<br>unpackUnorm2x16|4.10|[GL_ARB_shading_language_packing](https://www.opengl.org/registry/specs/ARB/shading_language_packing.txt)|Can be emulated using bit casting functions.|
+|matrixCompMult (NxM matrices)|1.10|||
+|outerProduct|1.20|||
+|transpose|1.20|||
+|determinant|1.50||Can be emulated.|
+|inverse|1.40||Can be emulated.|
+|lessThan (uvec)<br>lessThanEqual (uvec)<br>greaterThan (uvec)<br>greaterThanEqual (uvec)<br>equal (uvec)<br>notEqual (uvec)|1.30|||
+|texture<br>textureProj<br>textureLod<br>textureOffset<br>textureProjOffset<br>textureLodOffset<br>textureProjLod<br>textureProjLodOffset<br>texelFetch<br>texelFetchOffset<br>textureGrad<br>textureGradOffset<br>textureProjGrad<br>textureProjGradOffset<br>textureSize|1.30||Equivalent to texture2D, textureCube, etc|
+|dFdx<br>dFdy<br>fwidth|1.10||
+
+## EGL Feature Support (TODO)
+|Feature|EGL version|EGL extension|WGL core|WGL extension|GLX version|GLX extensions|Notes|
+|---|---|---|---|---|---|---|---|
+|Pbuffers|||No|[WGL_ARB_pbuffer](https://www.opengl.org/registry/specs/ARB/wgl_pbuffer.txt)||||
+|BindTexImage|||No|[WGL_ARB_render_texture](https://www.opengl.org/registry/specs/ARB/wgl_render_texture.txt)|||Possibly to emulate with OpenGL textures but not strictly required, it is possible only export EGL configs without EGL_BIND_TO_TEXTURE_RGB and EGL_BIND_TO_TEXTURE_RGBA. Bindable pbuffers may be required by Chrome though.|
+|Pixmaps||||||||
+|Swap control|||No|[WGL_EXT_swap_control](https://www.opengl.org/registry/specs/EXT/wgl_swap_control.txt)|No|[GLX_EXT_swap_control](https://www.opengl.org/registry/specs/EXT/swap_control.txt)||
diff --git a/gfx/angle/src/libANGLE/renderer/gl/FenceNVGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/FenceNVGL.cpp
new file mode 100755
index 000000000..b463054c3
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/FenceNVGL.cpp
@@ -0,0 +1,51 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FenceNVGL.cpp: Implements the class methods for FenceNVGL.
+
+#include "libANGLE/renderer/gl/FenceNVGL.h"
+
+#include "common/debug.h"
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+
+
+namespace rx
+{
+
+FenceNVGL::FenceNVGL(const FunctionsGL *functions)
+ : FenceNVImpl(),
+ mFunctions(functions)
+{
+ mFunctions->genFencesNV(1, &mFence);
+}
+
+FenceNVGL::~FenceNVGL()
+{
+ mFunctions->deleteFencesNV(1, &mFence);
+ mFence = 0;
+}
+
+gl::Error FenceNVGL::set(GLenum condition)
+{
+ ASSERT(condition == GL_ALL_COMPLETED_NV);
+ mFunctions->setFenceNV(mFence, condition);
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error FenceNVGL::test(GLboolean *outFinished)
+{
+ ASSERT(outFinished);
+ *outFinished = mFunctions->testFenceNV(mFence);
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error FenceNVGL::finish()
+{
+ mFunctions->finishFenceNV(mFence);
+ return gl::Error(GL_NO_ERROR);
+}
+
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/FenceNVGL.h b/gfx/angle/src/libANGLE/renderer/gl/FenceNVGL.h
new file mode 100755
index 000000000..ffeca8515
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/FenceNVGL.h
@@ -0,0 +1,36 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FenceNVGL.h: Defines the class interface for FenceNVGL.
+
+#ifndef LIBANGLE_RENDERER_GL_FENCENVGL_H_
+#define LIBANGLE_RENDERER_GL_FENCENVGL_H_
+
+#include "libANGLE/renderer/FenceNVImpl.h"
+
+namespace rx
+{
+class FunctionsGL;
+
+class FenceNVGL : public FenceNVImpl
+{
+ public:
+ explicit FenceNVGL(const FunctionsGL *functions);
+ ~FenceNVGL() override;
+
+ gl::Error set(GLenum condition) override;
+ gl::Error test(GLboolean *outFinished) override;
+ gl::Error finish() override;
+
+ private:
+ GLuint mFence;
+
+ const FunctionsGL *mFunctions;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_FENCENVGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/FenceSyncGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/FenceSyncGL.cpp
new file mode 100755
index 000000000..a3589b95e
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/FenceSyncGL.cpp
@@ -0,0 +1,67 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FenceSyncGL.cpp: Implements the class methods for FenceSyncGL.
+
+#include "libANGLE/renderer/gl/FenceSyncGL.h"
+
+#include "common/debug.h"
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+
+namespace rx
+{
+
+FenceSyncGL::FenceSyncGL(const FunctionsGL *functions)
+ : FenceSyncImpl(),
+ mFunctions(functions),
+ mSyncObject(0)
+{
+ ASSERT(mFunctions);
+}
+
+FenceSyncGL::~FenceSyncGL()
+{
+ if (mSyncObject != 0)
+ {
+ mFunctions->deleteSync(mSyncObject);
+ }
+}
+
+gl::Error FenceSyncGL::set(GLenum condition, GLbitfield flags)
+{
+ ASSERT(condition == GL_SYNC_GPU_COMMANDS_COMPLETE && flags == 0);
+ mSyncObject = mFunctions->fenceSync(condition, flags);
+ if (mSyncObject == 0)
+ {
+ // if glFenceSync fails, it returns 0.
+ return gl::Error(GL_OUT_OF_MEMORY, "glFenceSync failed to create a GLsync object.");
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error FenceSyncGL::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult)
+{
+ ASSERT(mSyncObject != 0);
+ *outResult = mFunctions->clientWaitSync(mSyncObject, flags, timeout);
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error FenceSyncGL::serverWait(GLbitfield flags, GLuint64 timeout)
+{
+ ASSERT(mSyncObject != 0);
+ mFunctions->waitSync(mSyncObject, flags, timeout);
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error FenceSyncGL::getStatus(GLint *outResult)
+{
+ ASSERT(mSyncObject != 0);
+ mFunctions->getSynciv(mSyncObject, GL_SYNC_STATUS, 1, nullptr, outResult);
+ return gl::Error(GL_NO_ERROR);
+}
+
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/FenceSyncGL.h b/gfx/angle/src/libANGLE/renderer/gl/FenceSyncGL.h
new file mode 100755
index 000000000..8dfd6632d
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/FenceSyncGL.h
@@ -0,0 +1,36 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FenceSyncGL.h: Defines the class interface for FenceSyncGL.
+
+#ifndef LIBANGLE_RENDERER_GL_FENCESYNCGL_H_
+#define LIBANGLE_RENDERER_GL_FENCESYNCGL_H_
+
+#include "libANGLE/renderer/FenceSyncImpl.h"
+
+namespace rx
+{
+class FunctionsGL;
+
+class FenceSyncGL : public FenceSyncImpl
+{
+ public:
+ explicit FenceSyncGL(const FunctionsGL *functions);
+ ~FenceSyncGL() override;
+
+ gl::Error set(GLenum condition, GLbitfield flags) override;
+ gl::Error clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult) override;
+ gl::Error serverWait(GLbitfield flags, GLuint64 timeout) override;
+ gl::Error getStatus(GLint *outResult) override;
+
+ private:
+ const FunctionsGL *mFunctions;
+ GLsync mSyncObject;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_FENCESYNCGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/FramebufferGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/FramebufferGL.cpp
new file mode 100755
index 000000000..0a058f8ba
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/FramebufferGL.cpp
@@ -0,0 +1,553 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FramebufferGL.cpp: Implements the class methods for FramebufferGL.
+
+#include "libANGLE/renderer/gl/FramebufferGL.h"
+
+#include "common/BitSetIterator.h"
+#include "common/debug.h"
+#include "libANGLE/ContextState.h"
+#include "libANGLE/State.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/ContextImpl.h"
+#include "libANGLE/renderer/gl/BlitGL.h"
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+#include "libANGLE/renderer/gl/RenderbufferGL.h"
+#include "libANGLE/renderer/gl/StateManagerGL.h"
+#include "libANGLE/renderer/gl/TextureGL.h"
+#include "libANGLE/renderer/gl/WorkaroundsGL.h"
+#include "libANGLE/renderer/gl/formatutilsgl.h"
+#include "libANGLE/renderer/gl/renderergl_utils.h"
+#include "platform/Platform.h"
+
+using namespace gl;
+using angle::CheckedNumeric;
+
+namespace rx
+{
+
+FramebufferGL::FramebufferGL(const FramebufferState &state,
+ const FunctionsGL *functions,
+ StateManagerGL *stateManager,
+ const WorkaroundsGL &workarounds,
+ BlitGL *blitter,
+ bool isDefault)
+ : FramebufferImpl(state),
+ mFunctions(functions),
+ mStateManager(stateManager),
+ mWorkarounds(workarounds),
+ mBlitter(blitter),
+ mFramebufferID(0),
+ mIsDefault(isDefault)
+{
+ if (!mIsDefault)
+ {
+ mFunctions->genFramebuffers(1, &mFramebufferID);
+ }
+}
+
+FramebufferGL::FramebufferGL(GLuint id,
+ const FramebufferState &state,
+ const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ BlitGL *blitter,
+ StateManagerGL *stateManager)
+ : FramebufferImpl(state),
+ mFunctions(functions),
+ mStateManager(stateManager),
+ mWorkarounds(workarounds),
+ mBlitter(blitter),
+ mFramebufferID(id),
+ mIsDefault(true)
+{
+}
+
+FramebufferGL::~FramebufferGL()
+{
+ mStateManager->deleteFramebuffer(mFramebufferID);
+ mFramebufferID = 0;
+}
+
+static void BindFramebufferAttachment(const FunctionsGL *functions,
+ GLenum attachmentPoint,
+ const FramebufferAttachment *attachment)
+{
+ if (attachment)
+ {
+ if (attachment->type() == GL_TEXTURE)
+ {
+ const Texture *texture = attachment->getTexture();
+ const TextureGL *textureGL = GetImplAs<TextureGL>(texture);
+
+ if (texture->getTarget() == GL_TEXTURE_2D)
+ {
+ functions->framebufferTexture2D(GL_FRAMEBUFFER, attachmentPoint, GL_TEXTURE_2D,
+ textureGL->getTextureID(), attachment->mipLevel());
+ }
+ else if (texture->getTarget() == GL_TEXTURE_CUBE_MAP)
+ {
+ functions->framebufferTexture2D(GL_FRAMEBUFFER, attachmentPoint, attachment->cubeMapFace(),
+ textureGL->getTextureID(), attachment->mipLevel());
+ }
+ else if (texture->getTarget() == GL_TEXTURE_2D_ARRAY || texture->getTarget() == GL_TEXTURE_3D)
+ {
+ functions->framebufferTextureLayer(GL_FRAMEBUFFER, attachmentPoint, textureGL->getTextureID(),
+ attachment->mipLevel(), attachment->layer());
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ }
+ else if (attachment->type() == GL_RENDERBUFFER)
+ {
+ const Renderbuffer *renderbuffer = attachment->getRenderbuffer();
+ const RenderbufferGL *renderbufferGL = GetImplAs<RenderbufferGL>(renderbuffer);
+
+ functions->framebufferRenderbuffer(GL_FRAMEBUFFER, attachmentPoint, GL_RENDERBUFFER,
+ renderbufferGL->getRenderbufferID());
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ }
+ else
+ {
+ // Unbind this attachment
+ functions->framebufferTexture2D(GL_FRAMEBUFFER, attachmentPoint, GL_TEXTURE_2D, 0, 0);
+ }
+}
+
+Error FramebufferGL::discard(size_t count, const GLenum *attachments)
+{
+ UNIMPLEMENTED();
+ return Error(GL_INVALID_OPERATION);
+}
+
+Error FramebufferGL::invalidate(size_t count, const GLenum *attachments)
+{
+ // Since this function is just a hint and not available until OpenGL 4.3, only call it if it is available.
+ if (mFunctions->invalidateFramebuffer)
+ {
+ mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
+ mFunctions->invalidateFramebuffer(GL_FRAMEBUFFER, static_cast<GLsizei>(count), attachments);
+ }
+
+ return Error(GL_NO_ERROR);
+}
+
+Error FramebufferGL::invalidateSub(size_t count,
+ const GLenum *attachments,
+ const gl::Rectangle &area)
+{
+ // Since this function is just a hint and not available until OpenGL 4.3, only call it if it is available.
+ if (mFunctions->invalidateSubFramebuffer)
+ {
+ mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
+ mFunctions->invalidateSubFramebuffer(GL_FRAMEBUFFER, static_cast<GLsizei>(count),
+ attachments, area.x, area.y, area.width, area.height);
+ }
+
+ return Error(GL_NO_ERROR);
+}
+
+Error FramebufferGL::clear(ContextImpl *context, GLbitfield mask)
+{
+ syncClearState(mask);
+ mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
+ mFunctions->clear(mask);
+
+ return Error(GL_NO_ERROR);
+}
+
+Error FramebufferGL::clearBufferfv(ContextImpl *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLfloat *values)
+{
+ syncClearBufferState(buffer, drawbuffer);
+ mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
+ mFunctions->clearBufferfv(buffer, drawbuffer, values);
+
+ return Error(GL_NO_ERROR);
+}
+
+Error FramebufferGL::clearBufferuiv(ContextImpl *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLuint *values)
+{
+ syncClearBufferState(buffer, drawbuffer);
+ mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
+ mFunctions->clearBufferuiv(buffer, drawbuffer, values);
+
+ return Error(GL_NO_ERROR);
+}
+
+Error FramebufferGL::clearBufferiv(ContextImpl *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLint *values)
+{
+ syncClearBufferState(buffer, drawbuffer);
+ mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
+ mFunctions->clearBufferiv(buffer, drawbuffer, values);
+
+ return Error(GL_NO_ERROR);
+}
+
+Error FramebufferGL::clearBufferfi(ContextImpl *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ GLfloat depth,
+ GLint stencil)
+{
+ syncClearBufferState(buffer, drawbuffer);
+ mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
+ mFunctions->clearBufferfi(buffer, drawbuffer, depth, stencil);
+
+ return Error(GL_NO_ERROR);
+}
+
+GLenum FramebufferGL::getImplementationColorReadFormat() const
+{
+ const auto *readAttachment = mState.getReadAttachment();
+ const Format &format = readAttachment->getFormat();
+ return format.info->getReadPixelsFormat();
+}
+
+GLenum FramebufferGL::getImplementationColorReadType() const
+{
+ const auto *readAttachment = mState.getReadAttachment();
+ const Format &format = readAttachment->getFormat();
+ return format.info->getReadPixelsType();
+}
+
+Error FramebufferGL::readPixels(ContextImpl *context,
+ const gl::Rectangle &area,
+ GLenum format,
+ GLenum type,
+ GLvoid *pixels) const
+{
+ // TODO: don't sync the pixel pack state here once the dirty bits contain the pixel pack buffer
+ // binding
+ const PixelPackState &packState = context->getGLState().getPackState();
+ mStateManager->setPixelPackState(packState);
+
+ nativegl::ReadPixelsFormat readPixelsFormat =
+ nativegl::GetReadPixelsFormat(mFunctions, mWorkarounds, format, type);
+ GLenum readFormat = readPixelsFormat.format;
+ GLenum readType = readPixelsFormat.type;
+
+ mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, mFramebufferID);
+
+ if (mWorkarounds.packOverlappingRowsSeparatelyPackBuffer && packState.pixelBuffer.get() &&
+ packState.rowLength != 0 && packState.rowLength < area.width)
+ {
+ return readPixelsRowByRowWorkaround(area, readFormat, readType, packState, pixels);
+ }
+
+ if (mWorkarounds.packLastRowSeparatelyForPaddingInclusion)
+ {
+ gl::Extents size(area.width, area.height, 1);
+
+ bool apply;
+ ANGLE_TRY_RESULT(ShouldApplyLastRowPaddingWorkaround(size, packState, readFormat, readType,
+ false, pixels),
+ apply);
+
+ if (apply)
+ {
+ return readPixelsPaddingWorkaround(area, readFormat, readType, packState, pixels);
+ }
+ }
+
+ mFunctions->readPixels(area.x, area.y, area.width, area.height, readFormat, readType, pixels);
+
+ return gl::NoError();
+}
+
+Error FramebufferGL::blit(ContextImpl *context,
+ const gl::Rectangle &sourceArea,
+ const gl::Rectangle &destArea,
+ GLbitfield mask,
+ GLenum filter)
+{
+ const Framebuffer *sourceFramebuffer = context->getGLState().getReadFramebuffer();
+ const Framebuffer *destFramebuffer = context->getGLState().getDrawFramebuffer();
+
+ const FramebufferAttachment *colorReadAttachment = sourceFramebuffer->getReadColorbuffer();
+ GLsizei readAttachmentSamples = colorReadAttachment->getSamples();
+
+ bool needManualColorBlit = false;
+
+ // TODO(cwallez) when the filter is LINEAR and both source and destination are SRGB, we
+ // could avoid doing a manual blit.
+
+ // Prior to OpenGL 4.4 BlitFramebuffer (section 18.3.1 of GL 4.3 core profile) reads:
+ // When values are taken from the read buffer, no linearization is performed, even
+ // if the format of the buffer is SRGB.
+ // Starting from OpenGL 4.4 (section 18.3.1) it reads:
+ // When values are taken from the read buffer, if FRAMEBUFFER_SRGB is enabled and the
+ // value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING for the framebuffer attachment
+ // corresponding to the read buffer is SRGB, the red, green, and blue components are
+ // converted from the non-linear sRGB color space according [...].
+ {
+ bool sourceSRGB = colorReadAttachment != nullptr &&
+ colorReadAttachment->getColorEncoding() == GL_SRGB;
+ needManualColorBlit =
+ needManualColorBlit || (sourceSRGB && mFunctions->isAtMostGL(gl::Version(4, 3)));
+ }
+
+ // Prior to OpenGL 4.2 BlitFramebuffer (section 4.3.2 of GL 4.1 core profile) reads:
+ // Blit operations bypass the fragment pipeline. The only fragment operations which
+ // affect a blit are the pixel ownership test and scissor test.
+ // Starting from OpenGL 4.2 (section 4.3.2) it reads:
+ // When values are written to the draw buffers, blit operations bypass the fragment
+ // pipeline. The only fragment operations which affect a blit are the pixel ownership
+ // test, the scissor test and sRGB conversion.
+ if (!needManualColorBlit)
+ {
+ bool destSRGB = false;
+ for (size_t i = 0; i < destFramebuffer->getDrawbufferStateCount(); ++i)
+ {
+ const FramebufferAttachment *attachment = destFramebuffer->getDrawBuffer(i);
+ if (attachment && attachment->getColorEncoding() == GL_SRGB)
+ {
+ destSRGB = true;
+ break;
+ }
+ }
+
+ needManualColorBlit =
+ needManualColorBlit || (destSRGB && mFunctions->isAtMostGL(gl::Version(4, 1)));
+ }
+
+ // Enable FRAMEBUFFER_SRGB if needed
+ mStateManager->setFramebufferSRGBEnabledForFramebuffer(true, this);
+
+ GLenum blitMask = mask;
+ if (needManualColorBlit && (mask & GL_COLOR_BUFFER_BIT) && readAttachmentSamples <= 1)
+ {
+ ANGLE_TRY(mBlitter->blitColorBufferWithShader(sourceFramebuffer, destFramebuffer,
+ sourceArea, destArea, filter));
+ blitMask &= ~GL_COLOR_BUFFER_BIT;
+ }
+
+ if (blitMask == 0)
+ {
+ return gl::NoError();
+ }
+
+ const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(sourceFramebuffer);
+ mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceFramebufferGL->getFramebufferID());
+ mStateManager->bindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebufferID);
+
+ mFunctions->blitFramebuffer(sourceArea.x, sourceArea.y, sourceArea.x1(), sourceArea.y1(),
+ destArea.x, destArea.y, destArea.x1(), destArea.y1(), blitMask,
+ filter);
+
+ return gl::NoError();
+}
+
+bool FramebufferGL::checkStatus() const
+{
+ mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
+ GLenum status = mFunctions->checkFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE)
+ {
+ ANGLEPlatformCurrent()->logWarning("GL framebuffer returned incomplete.");
+ }
+ return (status == GL_FRAMEBUFFER_COMPLETE);
+}
+
+void FramebufferGL::syncState(const Framebuffer::DirtyBits &dirtyBits)
+{
+ // Don't need to sync state for the default FBO.
+ if (mIsDefault)
+ {
+ return;
+ }
+
+ mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
+
+ for (auto dirtyBit : angle::IterateBitSet(dirtyBits))
+ {
+ switch (dirtyBit)
+ {
+ case Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT:
+ BindFramebufferAttachment(mFunctions, GL_DEPTH_ATTACHMENT,
+ mState.getDepthAttachment());
+ break;
+ case Framebuffer::DIRTY_BIT_STENCIL_ATTACHMENT:
+ BindFramebufferAttachment(mFunctions, GL_STENCIL_ATTACHMENT,
+ mState.getStencilAttachment());
+ break;
+ case Framebuffer::DIRTY_BIT_DRAW_BUFFERS:
+ {
+ const auto &drawBuffers = mState.getDrawBufferStates();
+ mFunctions->drawBuffers(static_cast<GLsizei>(drawBuffers.size()),
+ drawBuffers.data());
+ break;
+ }
+ case Framebuffer::DIRTY_BIT_READ_BUFFER:
+ mFunctions->readBuffer(mState.getReadBufferState());
+ break;
+ default:
+ {
+ ASSERT(Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 == 0 &&
+ dirtyBit < Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX);
+ size_t index =
+ static_cast<size_t>(dirtyBit - Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0);
+ BindFramebufferAttachment(mFunctions,
+ static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + index),
+ mState.getColorAttachment(index));
+ break;
+ }
+ }
+ }
+}
+
+GLuint FramebufferGL::getFramebufferID() const
+{
+ return mFramebufferID;
+}
+
+bool FramebufferGL::isDefault() const
+{
+ return mIsDefault;
+}
+
+void FramebufferGL::syncClearState(GLbitfield mask)
+{
+ if (mFunctions->standard == STANDARD_GL_DESKTOP)
+ {
+ if (mWorkarounds.doesSRGBClearsOnLinearFramebufferAttachments &&
+ (mask & GL_COLOR_BUFFER_BIT) != 0 && !mIsDefault)
+ {
+ bool hasSRGBAttachment = false;
+ for (const auto &attachment : mState.getColorAttachments())
+ {
+ if (attachment.isAttached() && attachment.getColorEncoding() == GL_SRGB)
+ {
+ hasSRGBAttachment = true;
+ break;
+ }
+ }
+
+ mStateManager->setFramebufferSRGBEnabled(hasSRGBAttachment);
+ }
+ else
+ {
+ mStateManager->setFramebufferSRGBEnabled(!mIsDefault);
+ }
+ }
+}
+
+void FramebufferGL::syncClearBufferState(GLenum buffer, GLint drawBuffer)
+{
+ if (mFunctions->standard == STANDARD_GL_DESKTOP)
+ {
+ if (mWorkarounds.doesSRGBClearsOnLinearFramebufferAttachments && buffer == GL_COLOR &&
+ !mIsDefault)
+ {
+ // If doing a clear on a color buffer, set SRGB blend enabled only if the color buffer
+ // is an SRGB format.
+ const auto &drawbufferState = mState.getDrawBufferStates();
+ const auto &colorAttachments = mState.getColorAttachments();
+
+ const FramebufferAttachment *attachment = nullptr;
+ if (drawbufferState[drawBuffer] >= GL_COLOR_ATTACHMENT0 &&
+ drawbufferState[drawBuffer] < GL_COLOR_ATTACHMENT0 + colorAttachments.size())
+ {
+ size_t attachmentIdx =
+ static_cast<size_t>(drawbufferState[drawBuffer] - GL_COLOR_ATTACHMENT0);
+ attachment = &colorAttachments[attachmentIdx];
+ }
+
+ if (attachment != nullptr)
+ {
+ mStateManager->setFramebufferSRGBEnabled(attachment->getColorEncoding() == GL_SRGB);
+ }
+ }
+ else
+ {
+ mStateManager->setFramebufferSRGBEnabled(!mIsDefault);
+ }
+ }
+}
+gl::Error FramebufferGL::readPixelsRowByRowWorkaround(const gl::Rectangle &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelPackState &pack,
+ GLvoid *pixels) const
+{
+ intptr_t offset = reinterpret_cast<intptr_t>(pixels);
+
+ const gl::InternalFormat &glFormat =
+ gl::GetInternalFormatInfo(gl::GetSizedInternalFormat(format, type));
+ GLuint rowBytes = 0;
+ ANGLE_TRY_RESULT(glFormat.computeRowPitch(area.width, pack.alignment, pack.rowLength),
+ rowBytes);
+ GLuint skipBytes = 0;
+ ANGLE_TRY_RESULT(glFormat.computeSkipBytes(rowBytes, 0, pack, false), skipBytes);
+
+ gl::PixelPackState directPack;
+ directPack.pixelBuffer = pack.pixelBuffer;
+ directPack.alignment = 1;
+ mStateManager->setPixelPackState(directPack);
+ directPack.pixelBuffer.set(nullptr);
+
+ offset += skipBytes;
+ for (GLint row = 0; row < area.height; ++row)
+ {
+ mFunctions->readPixels(area.x, row + area.y, area.width, 1, format, type,
+ reinterpret_cast<GLvoid *>(offset));
+ offset += row * rowBytes;
+ }
+
+ return gl::NoError();
+}
+
+gl::Error FramebufferGL::readPixelsPaddingWorkaround(const gl::Rectangle &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelPackState &pack,
+ GLvoid *pixels) const
+{
+ const gl::InternalFormat &glFormat =
+ gl::GetInternalFormatInfo(gl::GetSizedInternalFormat(format, type));
+ GLuint rowBytes = 0;
+ ANGLE_TRY_RESULT(glFormat.computeRowPitch(area.width, pack.alignment, pack.rowLength),
+ rowBytes);
+ GLuint skipBytes = 0;
+ ANGLE_TRY_RESULT(glFormat.computeSkipBytes(rowBytes, 0, pack, false), skipBytes);
+
+ // Get all by the last row
+ if (area.height > 1)
+ {
+ mFunctions->readPixels(area.x, area.y, area.width, area.height - 1, format, type, pixels);
+ }
+
+ // Get the last row manually
+ gl::PixelPackState directPack;
+ directPack.pixelBuffer = pack.pixelBuffer;
+ directPack.alignment = 1;
+ mStateManager->setPixelPackState(directPack);
+ directPack.pixelBuffer.set(nullptr);
+
+ intptr_t lastRowOffset =
+ reinterpret_cast<intptr_t>(pixels) + skipBytes + (area.height - 1) * rowBytes;
+ mFunctions->readPixels(area.x, area.y + area.height - 1, area.width, 1, format, type,
+ reinterpret_cast<GLvoid *>(lastRowOffset));
+
+ return gl::NoError();
+}
+} // namespace rx
diff --git a/gfx/angle/src/libANGLE/renderer/gl/FramebufferGL.h b/gfx/angle/src/libANGLE/renderer/gl/FramebufferGL.h
new file mode 100755
index 000000000..a8bcb894c
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/FramebufferGL.h
@@ -0,0 +1,113 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FramebufferGL.h: Defines the class interface for FramebufferGL.
+
+#ifndef LIBANGLE_RENDERER_GL_FRAMEBUFFERGL_H_
+#define LIBANGLE_RENDERER_GL_FRAMEBUFFERGL_H_
+
+#include "libANGLE/renderer/FramebufferImpl.h"
+
+namespace rx
+{
+
+class BlitGL;
+class FunctionsGL;
+class StateManagerGL;
+struct WorkaroundsGL;
+
+class FramebufferGL : public FramebufferImpl
+{
+ public:
+ FramebufferGL(const gl::FramebufferState &data,
+ const FunctionsGL *functions,
+ StateManagerGL *stateManager,
+ const WorkaroundsGL &workarounds,
+ BlitGL *blitter,
+ bool isDefault);
+ // Constructor called when we need to create a FramebufferGL from an
+ // existing framebuffer name, for example for the default framebuffer
+ // on the Mac EGL CGL backend.
+ FramebufferGL(GLuint id,
+ const gl::FramebufferState &data,
+ const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ BlitGL *blitter,
+ StateManagerGL *stateManager);
+ ~FramebufferGL() override;
+
+ gl::Error discard(size_t count, const GLenum *attachments) override;
+ gl::Error invalidate(size_t count, const GLenum *attachments) override;
+ gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) override;
+
+ gl::Error clear(ContextImpl *context, GLbitfield mask) override;
+ gl::Error clearBufferfv(ContextImpl *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLfloat *values) override;
+ gl::Error clearBufferuiv(ContextImpl *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLuint *values) override;
+ gl::Error clearBufferiv(ContextImpl *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLint *values) override;
+ gl::Error clearBufferfi(ContextImpl *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ GLfloat depth,
+ GLint stencil) override;
+
+ GLenum getImplementationColorReadFormat() const override;
+ GLenum getImplementationColorReadType() const override;
+ gl::Error readPixels(ContextImpl *context,
+ const gl::Rectangle &area,
+ GLenum format,
+ GLenum type,
+ GLvoid *pixels) const override;
+
+ gl::Error blit(ContextImpl *context,
+ const gl::Rectangle &sourceArea,
+ const gl::Rectangle &destArea,
+ GLbitfield mask,
+ GLenum filter) override;
+
+ bool checkStatus() const override;
+
+ void syncState(const gl::Framebuffer::DirtyBits &dirtyBits) override;
+
+ GLuint getFramebufferID() const;
+ bool isDefault() const;
+
+ private:
+ void syncClearState(GLbitfield mask);
+ void syncClearBufferState(GLenum buffer, GLint drawBuffer);
+
+ gl::Error readPixelsRowByRowWorkaround(const gl::Rectangle &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelPackState &pack,
+ GLvoid *pixels) const;
+
+ gl::Error readPixelsPaddingWorkaround(const gl::Rectangle &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelPackState &pack,
+ GLvoid *pixels) const;
+
+ const FunctionsGL *mFunctions;
+ StateManagerGL *mStateManager;
+ const WorkaroundsGL &mWorkarounds;
+ BlitGL *mBlitter;
+
+ GLuint mFramebufferID;
+ bool mIsDefault;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_FRAMEBUFFERGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/FunctionsGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/FunctionsGL.cpp
new file mode 100755
index 000000000..fcbf211bc
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/FunctionsGL.cpp
@@ -0,0 +1,2316 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FunctionsGL.cpp: Implements the FuntionsGL class to contain loaded GL functions
+
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+
+#include <algorithm>
+
+#include "common/string_utils.h"
+#include "libANGLE/renderer/gl/renderergl_utils.h"
+
+namespace rx
+{
+
+static void GetGLVersion(PFNGLGETSTRINGPROC getStringFunction, gl::Version *outVersion, StandardGL *outStandard)
+{
+ const std::string version = reinterpret_cast<const char*>(getStringFunction(GL_VERSION));
+ if (version.find("OpenGL ES") == std::string::npos)
+ {
+ // OpenGL spec states the GL_VERSION string will be in the following format:
+ // <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
+ *outStandard = STANDARD_GL_DESKTOP;
+ *outVersion = gl::Version(version[0] - '0', version[2] - '0');
+ }
+ else
+ {
+ // ES spec states that the GL_VERSION string will be in the following format:
+ // "OpenGL ES N.M vendor-specific information"
+ *outStandard = STANDARD_GL_ES;
+ *outVersion = gl::Version(version[10] - '0', version[12] - '0');
+ }
+}
+
+static std::vector<std::string> GetIndexedExtensions(PFNGLGETINTEGERVPROC getIntegerFunction, PFNGLGETSTRINGIPROC getStringIFunction)
+{
+ std::vector<std::string> result;
+
+ GLint numExtensions;
+ getIntegerFunction(GL_NUM_EXTENSIONS, &numExtensions);
+
+ result.reserve(numExtensions);
+
+ for (GLint i = 0; i < numExtensions; i++)
+ {
+ result.push_back(reinterpret_cast<const char*>(getStringIFunction(GL_EXTENSIONS, i)));
+ }
+
+ return result;
+}
+
+template <typename T>
+static void AssignGLEntryPoint(void *function, T *outFunction)
+{
+ *outFunction = reinterpret_cast<T>(function);
+}
+
+template <typename T>
+static void AssignGLExtensionEntryPoint(const std::vector<std::string> &extensions, const char *requiredExtensionString,
+ void *function, T *outFunction)
+{
+ std::vector<std::string> requiredExtensions;
+ angle::SplitStringAlongWhitespace(requiredExtensionString, &requiredExtensions);
+ for (const std::string& requiredExtension : requiredExtensions)
+ {
+ if (std::find(extensions.begin(), extensions.end(), requiredExtension) == extensions.end())
+ {
+ return;
+ }
+ }
+
+ *outFunction = reinterpret_cast<T>(function);
+}
+
+FunctionsGL::FunctionsGL()
+ : version(),
+ standard(),
+ extensions(),
+
+ blendFunc(nullptr),
+ clear(nullptr),
+ clearColor(nullptr),
+ clearDepth(nullptr),
+ clearStencil(nullptr),
+ colorMask(nullptr),
+ cullFace(nullptr),
+ depthFunc(nullptr),
+ depthMask(nullptr),
+ depthRange(nullptr),
+ disable(nullptr),
+ drawBuffer(nullptr),
+ enable(nullptr),
+ finish(nullptr),
+ flush(nullptr),
+ frontFace(nullptr),
+ getBooleanv(nullptr),
+ getDoublev(nullptr),
+ getError(nullptr),
+ getFloatv(nullptr),
+ getIntegerv(nullptr),
+ getString(nullptr),
+ getTexImage(nullptr),
+ getTexLevelParameterfv(nullptr),
+ getTexLevelParameteriv(nullptr),
+ getTexParameterfv(nullptr),
+ getTexParameteriv(nullptr),
+ hint(nullptr),
+ isEnabled(nullptr),
+ lineWidth(nullptr),
+ logicOp(nullptr),
+ pixelStoref(nullptr),
+ pixelStorei(nullptr),
+ pointSize(nullptr),
+ polygonMode(nullptr),
+ readBuffer(nullptr),
+ readPixels(nullptr),
+ scissor(nullptr),
+ stencilFunc(nullptr),
+ stencilMask(nullptr),
+ stencilOp(nullptr),
+ texImage1D(nullptr),
+ texImage2D(nullptr),
+ texParameterf(nullptr),
+ texParameterfv(nullptr),
+ texParameteri(nullptr),
+ texParameteriv(nullptr),
+ viewport(nullptr),
+
+ bindTexture(nullptr),
+ copyTexImage1D(nullptr),
+ copyTexImage2D(nullptr),
+ copyTexSubImage1D(nullptr),
+ copyTexSubImage2D(nullptr),
+ deleteTextures(nullptr),
+ drawArrays(nullptr),
+ drawElements(nullptr),
+ genTextures(nullptr),
+ isTexture(nullptr),
+ polygonOffset(nullptr),
+ texSubImage1D(nullptr),
+ texSubImage2D(nullptr),
+
+ blendColor(nullptr),
+ blendEquation(nullptr),
+ copyTexSubImage3D(nullptr),
+ drawRangeElements(nullptr),
+ texImage3D(nullptr),
+ texSubImage3D(nullptr),
+
+ deleteFencesNV(nullptr),
+ genFencesNV(nullptr),
+ isFenceNV(nullptr),
+ testFenceNV(nullptr),
+ getFenceivNV(nullptr),
+ finishFenceNV(nullptr),
+ setFenceNV(nullptr),
+
+ activeTexture(nullptr),
+ compressedTexImage1D(nullptr),
+ compressedTexImage2D(nullptr),
+ compressedTexImage3D(nullptr),
+ compressedTexSubImage1D(nullptr),
+ compressedTexSubImage2D(nullptr),
+ compressedTexSubImage3D(nullptr),
+ getCompressedTexImage(nullptr),
+ sampleCoverage(nullptr),
+
+ blendFuncSeparate(nullptr),
+ multiDrawArrays(nullptr),
+ multiDrawElements(nullptr),
+ pointParameterf(nullptr),
+ pointParameterfv(nullptr),
+ pointParameteri(nullptr),
+ pointParameteriv(nullptr),
+
+ beginQuery(nullptr),
+ bindBuffer(nullptr),
+ bufferData(nullptr),
+ bufferSubData(nullptr),
+ deleteBuffers(nullptr),
+ deleteQueries(nullptr),
+ endQuery(nullptr),
+ genBuffers(nullptr),
+ genQueries(nullptr),
+ getBufferParameteriv(nullptr),
+ getBufferPointerv(nullptr),
+ getBufferSubData(nullptr),
+ getQueryObjectiv(nullptr),
+ getQueryObjectuiv(nullptr),
+ getQueryiv(nullptr),
+ isBuffer(nullptr),
+ isQuery(nullptr),
+ mapBuffer(nullptr),
+ unmapBuffer(nullptr),
+
+ attachShader(nullptr),
+ bindAttribLocation(nullptr),
+ blendEquationSeparate(nullptr),
+ compileShader(nullptr),
+ createProgram(nullptr),
+ createShader(nullptr),
+ deleteProgram(nullptr),
+ deleteShader(nullptr),
+ detachShader(nullptr),
+ disableVertexAttribArray(nullptr),
+ drawBuffers(nullptr),
+ enableVertexAttribArray(nullptr),
+ getActiveAttrib(nullptr),
+ getActiveUniform(nullptr),
+ getAttachedShaders(nullptr),
+ getAttribLocation(nullptr),
+ getProgramInfoLog(nullptr),
+ getProgramiv(nullptr),
+ getShaderInfoLog(nullptr),
+ getShaderSource(nullptr),
+ getShaderiv(nullptr),
+ getUniformLocation(nullptr),
+ getUniformfv(nullptr),
+ getUniformiv(nullptr),
+ getVertexAttribPointerv(nullptr),
+ getVertexAttribdv(nullptr),
+ getVertexAttribfv(nullptr),
+ getVertexAttribiv(nullptr),
+ isProgram(nullptr),
+ isShader(nullptr),
+ linkProgram(nullptr),
+ shaderSource(nullptr),
+ stencilFuncSeparate(nullptr),
+ stencilMaskSeparate(nullptr),
+ stencilOpSeparate(nullptr),
+ uniform1f(nullptr),
+ uniform1fv(nullptr),
+ uniform1i(nullptr),
+ uniform1iv(nullptr),
+ uniform2f(nullptr),
+ uniform2fv(nullptr),
+ uniform2i(nullptr),
+ uniform2iv(nullptr),
+ uniform3f(nullptr),
+ uniform3fv(nullptr),
+ uniform3i(nullptr),
+ uniform3iv(nullptr),
+ uniform4f(nullptr),
+ uniform4fv(nullptr),
+ uniform4i(nullptr),
+ uniform4iv(nullptr),
+ uniformMatrix2fv(nullptr),
+ uniformMatrix3fv(nullptr),
+ uniformMatrix4fv(nullptr),
+ useProgram(nullptr),
+ validateProgram(nullptr),
+ vertexAttrib1d(nullptr),
+ vertexAttrib1dv(nullptr),
+ vertexAttrib1f(nullptr),
+ vertexAttrib1fv(nullptr),
+ vertexAttrib1s(nullptr),
+ vertexAttrib1sv(nullptr),
+ vertexAttrib2d(nullptr),
+ vertexAttrib2dv(nullptr),
+ vertexAttrib2f(nullptr),
+ vertexAttrib2fv(nullptr),
+ vertexAttrib2s(nullptr),
+ vertexAttrib2sv(nullptr),
+ vertexAttrib3d(nullptr),
+ vertexAttrib3dv(nullptr),
+ vertexAttrib3f(nullptr),
+ vertexAttrib3fv(nullptr),
+ vertexAttrib3s(nullptr),
+ vertexAttrib3sv(nullptr),
+ vertexAttrib4Nbv(nullptr),
+ vertexAttrib4Niv(nullptr),
+ vertexAttrib4Nsv(nullptr),
+ vertexAttrib4Nub(nullptr),
+ vertexAttrib4Nubv(nullptr),
+ vertexAttrib4Nuiv(nullptr),
+ vertexAttrib4Nusv(nullptr),
+ vertexAttrib4bv(nullptr),
+ vertexAttrib4d(nullptr),
+ vertexAttrib4dv(nullptr),
+ vertexAttrib4f(nullptr),
+ vertexAttrib4fv(nullptr),
+ vertexAttrib4iv(nullptr),
+ vertexAttrib4s(nullptr),
+ vertexAttrib4sv(nullptr),
+ vertexAttrib4ubv(nullptr),
+ vertexAttrib4uiv(nullptr),
+ vertexAttrib4usv(nullptr),
+ vertexAttribPointer(nullptr),
+
+ uniformMatrix2x3fv(nullptr),
+ uniformMatrix2x4fv(nullptr),
+ uniformMatrix3x2fv(nullptr),
+ uniformMatrix3x4fv(nullptr),
+ uniformMatrix4x2fv(nullptr),
+ uniformMatrix4x3fv(nullptr),
+
+ beginConditionalRender(nullptr),
+ beginTransformFeedback(nullptr),
+ bindBufferBase(nullptr),
+ bindBufferRange(nullptr),
+ bindFragDataLocation(nullptr),
+ bindFramebuffer(nullptr),
+ bindRenderbuffer(nullptr),
+ bindVertexArray(nullptr),
+ blitFramebuffer(nullptr),
+ checkFramebufferStatus(nullptr),
+ clampColor(nullptr),
+ clearBufferfi(nullptr),
+ clearBufferfv(nullptr),
+ clearBufferiv(nullptr),
+ clearBufferuiv(nullptr),
+ colorMaski(nullptr),
+ deleteFramebuffers(nullptr),
+ deleteRenderbuffers(nullptr),
+ deleteVertexArrays(nullptr),
+ disablei(nullptr),
+ enablei(nullptr),
+ endConditionalRender(nullptr),
+ endTransformFeedback(nullptr),
+ flushMappedBufferRange(nullptr),
+ framebufferRenderbuffer(nullptr),
+ framebufferTexture1D(nullptr),
+ framebufferTexture2D(nullptr),
+ framebufferTexture3D(nullptr),
+ framebufferTextureLayer(nullptr),
+ genFramebuffers(nullptr),
+ genRenderbuffers(nullptr),
+ genVertexArrays(nullptr),
+ generateMipmap(nullptr),
+ getBooleani_v(nullptr),
+ getFragDataLocation(nullptr),
+ getFramebufferAttachmentParameteriv(nullptr),
+ getIntegeri_v(nullptr),
+ getRenderbufferParameteriv(nullptr),
+ getStringi(nullptr),
+ getTexParameterIiv(nullptr),
+ getTexParameterIuiv(nullptr),
+ getTransformFeedbackVarying(nullptr),
+ getUniformuiv(nullptr),
+ getVertexAttribIiv(nullptr),
+ getVertexAttribIuiv(nullptr),
+ isEnabledi(nullptr),
+ isFramebuffer(nullptr),
+ isRenderbuffer(nullptr),
+ isVertexArray(nullptr),
+ mapBufferRange(nullptr),
+ renderbufferStorage(nullptr),
+ renderbufferStorageMultisample(nullptr),
+ texParameterIiv(nullptr),
+ texParameterIuiv(nullptr),
+ transformFeedbackVaryings(nullptr),
+ uniform1ui(nullptr),
+ uniform1uiv(nullptr),
+ uniform2ui(nullptr),
+ uniform2uiv(nullptr),
+ uniform3ui(nullptr),
+ uniform3uiv(nullptr),
+ uniform4ui(nullptr),
+ uniform4uiv(nullptr),
+ vertexAttribI1i(nullptr),
+ vertexAttribI1iv(nullptr),
+ vertexAttribI1ui(nullptr),
+ vertexAttribI1uiv(nullptr),
+ vertexAttribI2i(nullptr),
+ vertexAttribI2iv(nullptr),
+ vertexAttribI2ui(nullptr),
+ vertexAttribI2uiv(nullptr),
+ vertexAttribI3i(nullptr),
+ vertexAttribI3iv(nullptr),
+ vertexAttribI3ui(nullptr),
+ vertexAttribI3uiv(nullptr),
+ vertexAttribI4bv(nullptr),
+ vertexAttribI4i(nullptr),
+ vertexAttribI4iv(nullptr),
+ vertexAttribI4sv(nullptr),
+ vertexAttribI4ubv(nullptr),
+ vertexAttribI4ui(nullptr),
+ vertexAttribI4uiv(nullptr),
+ vertexAttribI4usv(nullptr),
+ vertexAttribIPointer(nullptr),
+
+ copyBufferSubData(nullptr),
+ drawArraysInstanced(nullptr),
+ drawElementsInstanced(nullptr),
+ getActiveUniformBlockName(nullptr),
+ getActiveUniformBlockiv(nullptr),
+ getActiveUniformName(nullptr),
+ getActiveUniformsiv(nullptr),
+ getUniformBlockIndex(nullptr),
+ getUniformIndices(nullptr),
+ primitiveRestartIndex(nullptr),
+ texBuffer(nullptr),
+ uniformBlockBinding(nullptr),
+
+ clientWaitSync(nullptr),
+ deleteSync(nullptr),
+ drawElementsBaseVertex(nullptr),
+ drawElementsInstancedBaseVertex(nullptr),
+ drawRangeElementsBaseVertex(nullptr),
+ fenceSync(nullptr),
+ framebufferTexture(nullptr),
+ getBufferParameteri64v(nullptr),
+ getInteger64i_v(nullptr),
+ getInteger64v(nullptr),
+ getMultisamplefv(nullptr),
+ getSynciv(nullptr),
+ isSync(nullptr),
+ multiDrawElementsBaseVertex(nullptr),
+ provokingVertex(nullptr),
+ sampleMaski(nullptr),
+ texImage2DMultisample(nullptr),
+ texImage3DMultisample(nullptr),
+ waitSync(nullptr),
+
+ matrixLoadEXT(nullptr),
+ genPathsNV(nullptr),
+ delPathsNV(nullptr),
+ pathCommandsNV(nullptr),
+ setPathParameterfNV(nullptr),
+ setPathParameteriNV(nullptr),
+ getPathParameterfNV(nullptr),
+ getPathParameteriNV(nullptr),
+ pathStencilFuncNV(nullptr),
+ stencilFillPathNV(nullptr),
+ stencilStrokePathNV(nullptr),
+ coverFillPathNV(nullptr),
+ coverStrokePathNV(nullptr),
+ stencilThenCoverFillPathNV(nullptr),
+ stencilThenCoverStrokePathNV(nullptr),
+ coverFillPathInstancedNV(nullptr),
+ coverStrokePathInstancedNV(nullptr),
+ stencilFillPathInstancedNV(nullptr),
+ stencilStrokePathInstancedNV(nullptr),
+ stencilThenCoverFillPathInstancedNV(nullptr),
+ stencilThenCoverStrokePathInstancedNV(nullptr),
+ programPathFragmentInputGenNV(nullptr),
+
+ bindFragDataLocationIndexed(nullptr),
+ bindSampler(nullptr),
+ deleteSamplers(nullptr),
+ genSamplers(nullptr),
+ getFragDataIndex(nullptr),
+ getQueryObjecti64v(nullptr),
+ getQueryObjectui64v(nullptr),
+ getSamplerParameterIiv(nullptr),
+ getSamplerParameterIuiv(nullptr),
+ getSamplerParameterfv(nullptr),
+ getSamplerParameteriv(nullptr),
+ isSampler(nullptr),
+ queryCounter(nullptr),
+ samplerParameterIiv(nullptr),
+ samplerParameterIuiv(nullptr),
+ samplerParameterf(nullptr),
+ samplerParameterfv(nullptr),
+ samplerParameteri(nullptr),
+ samplerParameteriv(nullptr),
+ vertexAttribDivisor(nullptr),
+ vertexAttribP1ui(nullptr),
+ vertexAttribP1uiv(nullptr),
+ vertexAttribP2ui(nullptr),
+ vertexAttribP2uiv(nullptr),
+ vertexAttribP3ui(nullptr),
+ vertexAttribP3uiv(nullptr),
+ vertexAttribP4ui(nullptr),
+ vertexAttribP4uiv(nullptr),
+
+ beginQueryIndexed(nullptr),
+ bindTransformFeedback(nullptr),
+ blendEquationSeparatei(nullptr),
+ blendEquationi(nullptr),
+ blendFuncSeparatei(nullptr),
+ blendFunci(nullptr),
+ deleteTransformFeedbacks(nullptr),
+ drawArraysIndirect(nullptr),
+ drawElementsIndirect(nullptr),
+ drawTransformFeedback(nullptr),
+ drawTransformFeedbackStream(nullptr),
+ endQueryIndexed(nullptr),
+ genTransformFeedbacks(nullptr),
+ getActiveSubroutineName(nullptr),
+ getActiveSubroutineUniformName(nullptr),
+ getActiveSubroutineUniformiv(nullptr),
+ getProgramStageiv(nullptr),
+ getQueryIndexediv(nullptr),
+ getSubroutineIndex(nullptr),
+ getSubroutineUniformLocation(nullptr),
+ getUniformSubroutineuiv(nullptr),
+ getUniformdv(nullptr),
+ isTransformFeedback(nullptr),
+ minSampleShading(nullptr),
+ patchParameterfv(nullptr),
+ patchParameteri(nullptr),
+ pauseTransformFeedback(nullptr),
+ resumeTransformFeedback(nullptr),
+ uniform1d(nullptr),
+ uniform1dv(nullptr),
+ uniform2d(nullptr),
+ uniform2dv(nullptr),
+ uniform3d(nullptr),
+ uniform3dv(nullptr),
+ uniform4d(nullptr),
+ uniform4dv(nullptr),
+ uniformMatrix2dv(nullptr),
+ uniformMatrix2x3dv(nullptr),
+ uniformMatrix2x4dv(nullptr),
+ uniformMatrix3dv(nullptr),
+ uniformMatrix3x2dv(nullptr),
+ uniformMatrix3x4dv(nullptr),
+ uniformMatrix4dv(nullptr),
+ uniformMatrix4x2dv(nullptr),
+ uniformMatrix4x3dv(nullptr),
+ uniformSubroutinesuiv(nullptr),
+
+ activeShaderProgram(nullptr),
+ bindProgramPipeline(nullptr),
+ clearDepthf(nullptr),
+ createShaderProgramv(nullptr),
+ deleteProgramPipelines(nullptr),
+ depthRangeArrayv(nullptr),
+ depthRangeIndexed(nullptr),
+ depthRangef(nullptr),
+ genProgramPipelines(nullptr),
+ getDoublei_v(nullptr),
+ getFloati_v(nullptr),
+ getProgramBinary(nullptr),
+ getProgramPipelineInfoLog(nullptr),
+ getProgramPipelineiv(nullptr),
+ getShaderPrecisionFormat(nullptr),
+ getVertexAttribLdv(nullptr),
+ isProgramPipeline(nullptr),
+ programBinary(nullptr),
+ programParameteri(nullptr),
+ programUniform1d(nullptr),
+ programUniform1dv(nullptr),
+ programUniform1f(nullptr),
+ programUniform1fv(nullptr),
+ programUniform1i(nullptr),
+ programUniform1iv(nullptr),
+ programUniform1ui(nullptr),
+ programUniform1uiv(nullptr),
+ programUniform2d(nullptr),
+ programUniform2dv(nullptr),
+ programUniform2f(nullptr),
+ programUniform2fv(nullptr),
+ programUniform2i(nullptr),
+ programUniform2iv(nullptr),
+ programUniform2ui(nullptr),
+ programUniform2uiv(nullptr),
+ programUniform3d(nullptr),
+ programUniform3dv(nullptr),
+ programUniform3f(nullptr),
+ programUniform3fv(nullptr),
+ programUniform3i(nullptr),
+ programUniform3iv(nullptr),
+ programUniform3ui(nullptr),
+ programUniform3uiv(nullptr),
+ programUniform4d(nullptr),
+ programUniform4dv(nullptr),
+ programUniform4f(nullptr),
+ programUniform4fv(nullptr),
+ programUniform4i(nullptr),
+ programUniform4iv(nullptr),
+ programUniform4ui(nullptr),
+ programUniform4uiv(nullptr),
+ programUniformMatrix2dv(nullptr),
+ programUniformMatrix2fv(nullptr),
+ programUniformMatrix2x3dv(nullptr),
+ programUniformMatrix2x3fv(nullptr),
+ programUniformMatrix2x4dv(nullptr),
+ programUniformMatrix2x4fv(nullptr),
+ programUniformMatrix3dv(nullptr),
+ programUniformMatrix3fv(nullptr),
+ programUniformMatrix3x2dv(nullptr),
+ programUniformMatrix3x2fv(nullptr),
+ programUniformMatrix3x4dv(nullptr),
+ programUniformMatrix3x4fv(nullptr),
+ programUniformMatrix4dv(nullptr),
+ programUniformMatrix4fv(nullptr),
+ programUniformMatrix4x2dv(nullptr),
+ programUniformMatrix4x2fv(nullptr),
+ programUniformMatrix4x3dv(nullptr),
+ programUniformMatrix4x3fv(nullptr),
+ releaseShaderCompiler(nullptr),
+ scissorArrayv(nullptr),
+ scissorIndexed(nullptr),
+ scissorIndexedv(nullptr),
+ shaderBinary(nullptr),
+ useProgramStages(nullptr),
+ validateProgramPipeline(nullptr),
+ vertexAttribL1d(nullptr),
+ vertexAttribL1dv(nullptr),
+ vertexAttribL2d(nullptr),
+ vertexAttribL2dv(nullptr),
+ vertexAttribL3d(nullptr),
+ vertexAttribL3dv(nullptr),
+ vertexAttribL4d(nullptr),
+ vertexAttribL4dv(nullptr),
+ vertexAttribLPointer(nullptr),
+ viewportArrayv(nullptr),
+ viewportIndexedf(nullptr),
+ viewportIndexedfv(nullptr),
+
+ bindImageTexture(nullptr),
+ drawArraysInstancedBaseInstance(nullptr),
+ drawElementsInstancedBaseInstance(nullptr),
+ drawElementsInstancedBaseVertexBaseInstance(nullptr),
+ drawTransformFeedbackInstanced(nullptr),
+ drawTransformFeedbackStreamInstanced(nullptr),
+ getActiveAtomicCounterBufferiv(nullptr),
+ getInternalformativ(nullptr),
+ memoryBarrier(nullptr),
+ texStorage1D(nullptr),
+ texStorage2D(nullptr),
+ texStorage3D(nullptr),
+
+ bindVertexBuffer(nullptr),
+ clearBufferData(nullptr),
+ clearBufferSubData(nullptr),
+ copyImageSubData(nullptr),
+ debugMessageCallback(nullptr),
+ debugMessageControl(nullptr),
+ debugMessageInsert(nullptr),
+ dispatchCompute(nullptr),
+ dispatchComputeIndirect(nullptr),
+ framebufferParameteri(nullptr),
+ getDebugMessageLog(nullptr),
+ getFramebufferParameteriv(nullptr),
+ getInternalformati64v(nullptr),
+ getPointerv(nullptr),
+ getObjectLabel(nullptr),
+ getObjectPtrLabel(nullptr),
+ getProgramInterfaceiv(nullptr),
+ getProgramResourceIndex(nullptr),
+ getProgramResourceLocation(nullptr),
+ getProgramResourceLocationIndex(nullptr),
+ getProgramResourceName(nullptr),
+ getProgramResourceiv(nullptr),
+ invalidateBufferData(nullptr),
+ invalidateBufferSubData(nullptr),
+ invalidateFramebuffer(nullptr),
+ invalidateSubFramebuffer(nullptr),
+ invalidateTexImage(nullptr),
+ invalidateTexSubImage(nullptr),
+ multiDrawArraysIndirect(nullptr),
+ multiDrawElementsIndirect(nullptr),
+ objectLabel(nullptr),
+ objectPtrLabel(nullptr),
+ popDebugGroup(nullptr),
+ pushDebugGroup(nullptr),
+ shaderStorageBlockBinding(nullptr),
+ texBufferRange(nullptr),
+ texStorage2DMultisample(nullptr),
+ texStorage3DMultisample(nullptr),
+ textureView(nullptr),
+ vertexAttribBinding(nullptr),
+ vertexAttribFormat(nullptr),
+ vertexAttribIFormat(nullptr),
+ vertexAttribLFormat(nullptr),
+ vertexBindingDivisor(nullptr),
+ coverageModulationNV(nullptr),
+
+ bindBuffersBase(nullptr),
+ bindBuffersRange(nullptr),
+ bindImageTextures(nullptr),
+ bindSamplers(nullptr),
+ bindTextures(nullptr),
+ bindVertexBuffers(nullptr),
+ bufferStorage(nullptr),
+ clearTexImage(nullptr),
+ clearTexSubImage(nullptr),
+
+ bindTextureUnit(nullptr),
+ blitNamedFramebuffer(nullptr),
+ checkNamedFramebufferStatus(nullptr),
+ clearNamedBufferData(nullptr),
+ clearNamedBufferSubData(nullptr),
+ clearNamedFramebufferfi(nullptr),
+ clearNamedFramebufferfv(nullptr),
+ clearNamedFramebufferiv(nullptr),
+ clearNamedFramebufferuiv(nullptr),
+ clipControl(nullptr),
+ compressedTextureSubImage1D(nullptr),
+ compressedTextureSubImage2D(nullptr),
+ compressedTextureSubImage3D(nullptr),
+ copyNamedBufferSubData(nullptr),
+ copyTextureSubImage1D(nullptr),
+ copyTextureSubImage2D(nullptr),
+ copyTextureSubImage3D(nullptr),
+ createBuffers(nullptr),
+ createFramebuffers(nullptr),
+ createProgramPipelines(nullptr),
+ createQueries(nullptr),
+ createRenderbuffers(nullptr),
+ createSamplers(nullptr),
+ createTextures(nullptr),
+ createTransformFeedbacks(nullptr),
+ createVertexArrays(nullptr),
+ disableVertexArrayAttrib(nullptr),
+ enableVertexArrayAttrib(nullptr),
+ flushMappedNamedBufferRange(nullptr),
+ generateTextureMipmap(nullptr),
+ getCompressedTextureImage(nullptr),
+ getCompressedTextureSubImage(nullptr),
+ getGraphicsResetStatus(nullptr),
+ getNamedBufferParameteri64v(nullptr),
+ getNamedBufferParameteriv(nullptr),
+ getNamedBufferPointerv(nullptr),
+ getNamedBufferSubData(nullptr),
+ getNamedFramebufferAttachmentParameteriv(nullptr),
+ getNamedFramebufferParameteriv(nullptr),
+ getNamedRenderbufferParameteriv(nullptr),
+ getQueryBufferObjecti64v(nullptr),
+ getQueryBufferObjectiv(nullptr),
+ getQueryBufferObjectui64v(nullptr),
+ getQueryBufferObjectuiv(nullptr),
+ getTextureImage(nullptr),
+ getTextureLevelParameterfv(nullptr),
+ getTextureLevelParameteriv(nullptr),
+ getTextureParameterIiv(nullptr),
+ getTextureParameterIuiv(nullptr),
+ getTextureParameterfv(nullptr),
+ getTextureParameteriv(nullptr),
+ getTextureSubImage(nullptr),
+ getTransformFeedbacki64_v(nullptr),
+ getTransformFeedbacki_v(nullptr),
+ getTransformFeedbackiv(nullptr),
+ getVertexArrayIndexed64iv(nullptr),
+ getVertexArrayIndexediv(nullptr),
+ getVertexArrayiv(nullptr),
+ getnCompressedTexImage(nullptr),
+ getnTexImage(nullptr),
+ getnUniformdv(nullptr),
+ getnUniformfv(nullptr),
+ getnUniformiv(nullptr),
+ getnUniformuiv(nullptr),
+ invalidateNamedFramebufferData(nullptr),
+ invalidateNamedFramebufferSubData(nullptr),
+ mapNamedBuffer(nullptr),
+ mapNamedBufferRange(nullptr),
+ memoryBarrierByRegion(nullptr),
+ namedBufferData(nullptr),
+ namedBufferStorage(nullptr),
+ namedBufferSubData(nullptr),
+ namedFramebufferDrawBuffer(nullptr),
+ namedFramebufferDrawBuffers(nullptr),
+ namedFramebufferParameteri(nullptr),
+ namedFramebufferReadBuffer(nullptr),
+ namedFramebufferRenderbuffer(nullptr),
+ namedFramebufferTexture(nullptr),
+ namedFramebufferTextureLayer(nullptr),
+ namedRenderbufferStorage(nullptr),
+ namedRenderbufferStorageMultisample(nullptr),
+ readnPixels(nullptr),
+ textureBarrier(nullptr),
+ textureBuffer(nullptr),
+ textureBufferRange(nullptr),
+ textureParameterIiv(nullptr),
+ textureParameterIuiv(nullptr),
+ textureParameterf(nullptr),
+ textureParameterfv(nullptr),
+ textureParameteri(nullptr),
+ textureParameteriv(nullptr),
+ textureStorage1D(nullptr),
+ textureStorage2D(nullptr),
+ textureStorage2DMultisample(nullptr),
+ textureStorage3D(nullptr),
+ textureStorage3DMultisample(nullptr),
+ textureSubImage1D(nullptr),
+ textureSubImage2D(nullptr),
+ textureSubImage3D(nullptr),
+ transformFeedbackBufferBase(nullptr),
+ transformFeedbackBufferRange(nullptr),
+ unmapNamedBuffer(nullptr),
+ vertexArrayAttribBinding(nullptr),
+ vertexArrayAttribFormat(nullptr),
+ vertexArrayAttribIFormat(nullptr),
+ vertexArrayAttribLFormat(nullptr),
+ vertexArrayBindingDivisor(nullptr),
+ vertexArrayElementBuffer(nullptr),
+ vertexArrayVertexBuffer(nullptr),
+ vertexArrayVertexBuffers(nullptr),
+ blendBarrier(nullptr),
+ primitiveBoundingBox(nullptr),
+ eglImageTargetRenderbufferStorageOES(nullptr),
+ eglImageTargetTexture2DOES(nullptr)
+{
+}
+
+FunctionsGL::~FunctionsGL()
+{
+}
+
+void FunctionsGL::initialize()
+{
+ // Grab the version number
+ AssignGLEntryPoint(loadProcAddress("glGetString"), &getString);
+ AssignGLEntryPoint(loadProcAddress("glGetIntegerv"), &getIntegerv);
+ GetGLVersion(getString, &version, &standard);
+
+ // Grab the GL extensions
+ if (isAtLeastGL(gl::Version(3, 0)) || isAtLeastGLES(gl::Version(3, 0)))
+ {
+ AssignGLEntryPoint(loadProcAddress("glGetStringi"), &getStringi);
+ extensions = GetIndexedExtensions(getIntegerv, getStringi);
+ }
+ else
+ {
+ const char *exts = reinterpret_cast<const char*>(getString(GL_EXTENSIONS));
+ angle::SplitStringAlongWhitespace(std::string(exts), &extensions);
+ }
+
+ // Load the entry points
+ switch (standard)
+ {
+ case STANDARD_GL_DESKTOP:
+ initializeProcsDesktopGL();
+ break;
+
+ case STANDARD_GL_ES:
+ initializeProcsGLES();
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void FunctionsGL::initializeProcsDesktopGL()
+{
+ // Check the context profile
+ profile = 0;
+ if (isAtLeastGL(gl::Version(3, 2)))
+ {
+ getIntegerv(GL_CONTEXT_PROFILE_MASK, &profile);
+ }
+
+ // clang-format off
+
+ // Load extensions
+ // Even though extensions are written against specific versions of GL, many drivers expose the extensions
+ // in even older versions. Always try loading the extensions regardless of GL version.
+
+ // GL_ARB_program_interface_query (loading only functions relevant to GL_NV_path_rendering here)
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_program_interface_query", loadProcAddress("glGetProgramInterfaceiv"), &getProgramInterfaceiv);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_program_interface_query", loadProcAddress("glGetProgramResourceName"), &getProgramResourceName);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_program_interface_query", loadProcAddress("glGetProgramResourceiv"), &getProgramResourceiv);
+
+ // GL_NV_path_rendering
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glMatrixLoadfEXT"), &matrixLoadEXT);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glGenPathsNV"), &genPathsNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glDeletePathsNV"), &delPathsNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glPathCommandsNV"), &pathCommandsNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glIsPathNV"), &isPathNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glPathParameterfNV"), &setPathParameterfNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glPathParameteriNV"), &setPathParameteriNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glGetPathParameterfvNV"), &getPathParameterfNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glGetPathParameterivNV"), &getPathParameteriNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glPathStencilFuncNV"), &pathStencilFuncNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilFillPathNV"), &stencilFillPathNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilStrokePathNV"), &stencilStrokePathNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glCoverFillPathNV"), &coverFillPathNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glCoverStrokePathNV"), &coverStrokePathNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilThenCoverFillPathNV"), &stencilThenCoverFillPathNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilThenCoverStrokePathNV"), &stencilThenCoverStrokePathNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glCoverFillPathInstancedNV"), &coverFillPathInstancedNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glCoverStrokePathInstancedNV"), &coverStrokePathInstancedNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilFillPathInstancedNV"), &stencilFillPathInstancedNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilStrokePathInstancedNV"), &stencilStrokePathInstancedNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilThenCoverFillPathInstancedNV"), &stencilThenCoverFillPathInstancedNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilThenCoverStrokePathInstancedNV"), &stencilThenCoverStrokePathInstancedNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glProgramPathFragmentInputGenNV"), &programPathFragmentInputGenNV);
+
+ // GL_NV_framebuffer_mixed_samples
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_framebuffer_mixed_samples", loadProcAddress("glCoverageModulationNV"), &coverageModulationNV);
+
+ // GL_NV_fence
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glDeleteFencesNV"), &deleteFencesNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glGenFencesNV"), &genFencesNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glIsFenceNV"), &isFenceNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glTestFenceNV"), &testFenceNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glGetFenceivNV"), &getFenceivNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glFinishFenceNV"), &finishFenceNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glSetFenceNV"), &setFenceNV);
+
+ // GL_EXT_texture_storage
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_texture_storage", loadProcAddress("glTexStorage1DEXT"), &texStorage1D);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_texture_storage", loadProcAddress("glTexStorage2DEXT"), &texStorage2D);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_texture_storage GL_EXT_texture3D", loadProcAddress("glTexStorage3DEXT"), &texStorage3D);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_texture_storage GL_EXT_direct_state_access", loadProcAddress("glTextureStorage1DEXT"), &textureStorage1D);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_texture_storage GL_EXT_direct_state_access", loadProcAddress("glTextureStorage2DEXT"), &textureStorage2D);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_texture_storage GL_EXT_direct_state_access GL_EXT_texture3D", loadProcAddress("glTextureStorage3DEXT"), &textureStorage3D);
+
+ // GL_ARB_vertex_array_object
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_vertex_array_object", loadProcAddress("glBindVertexArray"), &bindVertexArray);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_vertex_array_object", loadProcAddress("glDeleteVertexArrays"), &deleteVertexArrays);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_vertex_array_object", loadProcAddress("glGenVertexArrays"), &genVertexArrays);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_vertex_array_object", loadProcAddress("glIsVertexArray"), &isVertexArray);
+
+ // GL_ARB_sync
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_sync", loadProcAddress("glClientWaitSync"), &clientWaitSync);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_sync", loadProcAddress("glDeleteSync"), &deleteSync);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_sync", loadProcAddress("glFenceSync"), &fenceSync);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_sync", loadProcAddress("glGetInteger64i_v"), &getInteger64i_v);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_sync", loadProcAddress("glGetInteger64v"), &getInteger64v);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_sync", loadProcAddress("glGetSynciv"), &getSynciv);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_sync", loadProcAddress("glIsSync"), &isSync);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_sync", loadProcAddress("glWaitSync"), &waitSync);
+
+ // GL_EXT_framebuffer_object
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glIsRenderbufferEXT"), &isRenderbuffer);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glBindRenderbufferEXT"), &bindRenderbuffer);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glDeleteRenderbuffersEXT"), &deleteRenderbuffers);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glGenRenderbuffersEXT"), &genRenderbuffers);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glRenderbufferStorageEXT"), &renderbufferStorage);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glGetRenderbufferParameterivEXT"), &getRenderbufferParameteriv);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glIsFramebufferEXT"), &isFramebuffer);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glBindFramebufferEXT"), &bindFramebuffer);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glDeleteFramebuffersEXT"), &deleteFramebuffers);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glGenFramebuffersEXT"), &genFramebuffers);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glCheckFramebufferStatusEXT"), &checkFramebufferStatus);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glFramebufferTexture1DEXT"), &framebufferTexture1D);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glFramebufferTexture2DEXT"), &framebufferTexture2D);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glFramebufferTexture3DEXT"), &framebufferTexture3D);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glFramebufferRenderbufferEXT"), &framebufferRenderbuffer);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glGetFramebufferAttachmentParameterivEXT"), &getFramebufferAttachmentParameteriv);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glGenerateMipmapEXT"), &generateMipmap);
+
+ // GL_EXT_framebuffer_blit
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_blit", loadProcAddress("glBlitFramebufferEXT"), &blitFramebuffer);
+
+ // GL_KHR_debug
+ AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glDebugMessageControl"), &debugMessageControl);
+ AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glDebugMessageInsert"), &debugMessageInsert);
+ AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glDebugMessageCallback"), &debugMessageCallback);
+ AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glGetDebugMessageLog"), &getDebugMessageLog);
+ AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glGetPointerv"), &getPointerv);
+ AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glPushDebugGroup"), &pushDebugGroup);
+ AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glPopDebugGroup"), &popDebugGroup);
+ AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glObjectLabel"), &objectLabel);
+ AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glGetObjectLabel"), &getObjectLabel);
+ AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glObjectPtrLabel"), &objectPtrLabel);
+ AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glGetObjectPtrLabel"), &getObjectPtrLabel);
+
+ // GL_ARB_internalformat_query
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_internalformat_query", loadProcAddress("glGetInternalformativ"), &getInternalformativ);
+
+ // GL_ARB_ES2_compatibility
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_ES2_compatibility", loadProcAddress("glReleaseShaderCompiler"), &releaseShaderCompiler);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_ES2_compatibility", loadProcAddress("glShaderBinary"), &shaderBinary);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_ES2_compatibility", loadProcAddress("glGetShaderPrecisionFormat"), &getShaderPrecisionFormat);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_ES2_compatibility", loadProcAddress("glDepthRangef"), &depthRangef);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_ES2_compatibility", loadProcAddress("glClearDepthf"), &clearDepthf);
+
+ // GL_ARB_instanced_arrays
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_instanced_arrays", loadProcAddress("glVertexAttribDivisorARB"), &vertexAttribDivisor);
+
+ // GL_EXT_draw_instanced
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_draw_instanced", loadProcAddress("glDrawArraysInstancedEXT"), &drawArraysInstanced);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_draw_instanced", loadProcAddress("glDrawElementsInstancedEXT"), &drawElementsInstanced);
+
+ // GL_ARB_draw_instanced
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_draw_instanced", loadProcAddress("glDrawArraysInstancedARB"), &drawArraysInstanced);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_draw_instanced", loadProcAddress("glDrawElementsInstancedARB"), &drawElementsInstanced);
+
+ // GL_ARB_sampler_objects
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glGenSamplers"), &genSamplers);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glDeleteSamplers"), &deleteSamplers);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glIsSampler"), &isSampler);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glBindSampler"), &bindSampler);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glSamplerParameteri"), &samplerParameteri);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glSamplerParameterf"), &samplerParameterf);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glSamplerParameteriv"), &samplerParameteriv);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glSamplerParameterfv"), &samplerParameterfv);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glSamplerParameterIiv"), &samplerParameterIiv);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glSamplerParameterIuiv"), &samplerParameterIuiv);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glGetSamplerParameteriv"), &getSamplerParameteriv);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glGetSamplerParameterfv"), &getSamplerParameterfv);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glGetSamplerParameterIiv"), &getSamplerParameterIiv);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glGetSamplerParameterIuiv"), &getSamplerParameterIuiv);
+
+ // GL_ARB_occlusion_query
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_occlusion_query", loadProcAddress("glGenQueriesARB"), &genQueries);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_occlusion_query", loadProcAddress("glDeleteQueriesARB"), &deleteQueries);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_occlusion_query", loadProcAddress("glIsQueryARB"), &isQuery);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_occlusion_query", loadProcAddress("glBeginQueryARB"), &beginQuery);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_occlusion_query", loadProcAddress("glEndQueryARB"), &endQuery);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_occlusion_query", loadProcAddress("glGetQueryivARB"), &getQueryiv);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_occlusion_query", loadProcAddress("glGetQueryObjectivARB"), &getQueryObjectiv);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_occlusion_query", loadProcAddress("glGetQueryObjectuivARB"), &getQueryObjectuiv);
+
+ // EXT_transform_feedback
+ AssignGLExtensionEntryPoint(extensions, "EXT_transform_feedback", loadProcAddress("glBindBufferRangeEXT"), &bindBufferRange);
+ AssignGLExtensionEntryPoint(extensions, "EXT_transform_feedback", loadProcAddress("glBindBufferBaseEXT"), &bindBufferBase);
+ AssignGLExtensionEntryPoint(extensions, "EXT_transform_feedback", loadProcAddress("glBeginTransformFeedbackEXT"), &beginTransformFeedback);
+ AssignGLExtensionEntryPoint(extensions, "EXT_transform_feedback", loadProcAddress("glEndTransformFeedbackEXT"), &endTransformFeedback);
+ AssignGLExtensionEntryPoint(extensions, "EXT_transform_feedback", loadProcAddress("glTransformFeedbackVaryingsEXT"), &transformFeedbackVaryings);
+ AssignGLExtensionEntryPoint(extensions, "EXT_transform_feedback", loadProcAddress("glGetTransformFeedbackVaryingEXT"), &getTransformFeedbackVarying);
+
+ // GL_ARB_transform_feedback2
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_transform_feedback2", loadProcAddress("glBindTransformFeedback"), &bindTransformFeedback);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_transform_feedback2", loadProcAddress("glDeleteTransformFeedbacks"), &deleteTransformFeedbacks);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_transform_feedback2", loadProcAddress("glGenTransformFeedbacks"), &genTransformFeedbacks);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_transform_feedback2", loadProcAddress("glIsTransformFeedback"), &isTransformFeedback);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_transform_feedback2", loadProcAddress("glPauseTransformFeedback"), &pauseTransformFeedback);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_transform_feedback2", loadProcAddress("glResumeTransformFeedback"), &resumeTransformFeedback);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_transform_feedback2", loadProcAddress("glDrawTransformFeedback"), &drawTransformFeedback);
+
+ // GL_ARB_transform_feedback3
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_transform_feedback3", loadProcAddress("glDrawTransformFeedbackStream"), &drawTransformFeedbackStream);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_transform_feedback3", loadProcAddress("glBeginQueryIndexed"), &beginQueryIndexed);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_transform_feedback3", loadProcAddress("glEndQueryIndexed"), &endQueryIndexed);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_transform_feedback3", loadProcAddress("glGetQueryIndexediv"), &getQueryIndexediv);
+
+ // GL_ARB_get_program_binary
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_get_program_binary", loadProcAddress("glGetProgramBinary"), &getProgramBinary);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_get_program_binary", loadProcAddress("glProgramBinary"), &programBinary);
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_get_program_binary", loadProcAddress("glProgramParameteri"), &programParameteri);
+
+ // GL_ARB_robustness
+ AssignGLExtensionEntryPoint(extensions, "GL_ARB_robustness", loadProcAddress("glGetGraphicsResetStatusARB"), &getGraphicsResetStatus);
+
+ // GL_KHR_robustness
+ AssignGLExtensionEntryPoint(extensions, "GL_KHR_robustness", loadProcAddress("glGetGraphicsResetStatus"), &getGraphicsResetStatus);
+
+ // 1.0
+ if (isAtLeastGL(gl::Version(1, 0)))
+ {
+ AssignGLEntryPoint(loadProcAddress("glBlendFunc"), &blendFunc);
+ AssignGLEntryPoint(loadProcAddress("glClear"), &clear);
+ AssignGLEntryPoint(loadProcAddress("glClearColor"), &clearColor);
+ AssignGLEntryPoint(loadProcAddress("glClearDepth"), &clearDepth);
+ AssignGLEntryPoint(loadProcAddress("glClearStencil"), &clearStencil);
+ AssignGLEntryPoint(loadProcAddress("glColorMask"), &colorMask);
+ AssignGLEntryPoint(loadProcAddress("glCullFace"), &cullFace);
+ AssignGLEntryPoint(loadProcAddress("glDepthFunc"), &depthFunc);
+ AssignGLEntryPoint(loadProcAddress("glDepthMask"), &depthMask);
+ AssignGLEntryPoint(loadProcAddress("glDepthRange"), &depthRange);
+ AssignGLEntryPoint(loadProcAddress("glDisable"), &disable);
+ AssignGLEntryPoint(loadProcAddress("glDrawBuffer"), &drawBuffer);
+ AssignGLEntryPoint(loadProcAddress("glEnable"), &enable);
+ AssignGLEntryPoint(loadProcAddress("glFinish"), &finish);
+ AssignGLEntryPoint(loadProcAddress("glFlush"), &flush);
+ AssignGLEntryPoint(loadProcAddress("glFrontFace"), &frontFace);
+ AssignGLEntryPoint(loadProcAddress("glGetBooleanv"), &getBooleanv);
+ AssignGLEntryPoint(loadProcAddress("glGetDoublev"), &getDoublev);
+ AssignGLEntryPoint(loadProcAddress("glGetError"), &getError);
+ AssignGLEntryPoint(loadProcAddress("glGetFloatv"), &getFloatv);
+ AssignGLEntryPoint(loadProcAddress("glGetIntegerv"), &getIntegerv);
+ AssignGLEntryPoint(loadProcAddress("glGetString"), &getString);
+ AssignGLEntryPoint(loadProcAddress("glGetTexImage"), &getTexImage);
+ AssignGLEntryPoint(loadProcAddress("glGetTexLevelParameterfv"), &getTexLevelParameterfv);
+ AssignGLEntryPoint(loadProcAddress("glGetTexLevelParameteriv"), &getTexLevelParameteriv);
+ AssignGLEntryPoint(loadProcAddress("glGetTexParameterfv"), &getTexParameterfv);
+ AssignGLEntryPoint(loadProcAddress("glGetTexParameteriv"), &getTexParameteriv);
+ AssignGLEntryPoint(loadProcAddress("glHint"), &hint);
+ AssignGLEntryPoint(loadProcAddress("glIsEnabled"), &isEnabled);
+ AssignGLEntryPoint(loadProcAddress("glLineWidth"), &lineWidth);
+ AssignGLEntryPoint(loadProcAddress("glLogicOp"), &logicOp);
+ AssignGLEntryPoint(loadProcAddress("glPixelStoref"), &pixelStoref);
+ AssignGLEntryPoint(loadProcAddress("glPixelStorei"), &pixelStorei);
+ AssignGLEntryPoint(loadProcAddress("glPointSize"), &pointSize);
+ AssignGLEntryPoint(loadProcAddress("glPolygonMode"), &polygonMode);
+ AssignGLEntryPoint(loadProcAddress("glReadBuffer"), &readBuffer);
+ AssignGLEntryPoint(loadProcAddress("glReadPixels"), &readPixels);
+ AssignGLEntryPoint(loadProcAddress("glScissor"), &scissor);
+ AssignGLEntryPoint(loadProcAddress("glStencilFunc"), &stencilFunc);
+ AssignGLEntryPoint(loadProcAddress("glStencilMask"), &stencilMask);
+ AssignGLEntryPoint(loadProcAddress("glStencilOp"), &stencilOp);
+ AssignGLEntryPoint(loadProcAddress("glTexImage1D"), &texImage1D);
+ AssignGLEntryPoint(loadProcAddress("glTexImage2D"), &texImage2D);
+ AssignGLEntryPoint(loadProcAddress("glTexParameterf"), &texParameterf);
+ AssignGLEntryPoint(loadProcAddress("glTexParameterfv"), &texParameterfv);
+ AssignGLEntryPoint(loadProcAddress("glTexParameteri"), &texParameteri);
+ AssignGLEntryPoint(loadProcAddress("glTexParameteriv"), &texParameteriv);
+ AssignGLEntryPoint(loadProcAddress("glViewport"), &viewport);
+ }
+
+ // 1.1
+ if (isAtLeastGL(gl::Version(1, 1)))
+ {
+ AssignGLEntryPoint(loadProcAddress("glBindTexture"), &bindTexture);
+ AssignGLEntryPoint(loadProcAddress("glCopyTexImage1D"), &copyTexImage1D);
+ AssignGLEntryPoint(loadProcAddress("glCopyTexImage2D"), &copyTexImage2D);
+ AssignGLEntryPoint(loadProcAddress("glCopyTexSubImage1D"), &copyTexSubImage1D);
+ AssignGLEntryPoint(loadProcAddress("glCopyTexSubImage2D"), &copyTexSubImage2D);
+ AssignGLEntryPoint(loadProcAddress("glDeleteTextures"), &deleteTextures);
+ AssignGLEntryPoint(loadProcAddress("glDrawArrays"), &drawArrays);
+ AssignGLEntryPoint(loadProcAddress("glDrawElements"), &drawElements);
+ AssignGLEntryPoint(loadProcAddress("glGenTextures"), &genTextures);
+ AssignGLEntryPoint(loadProcAddress("glIsTexture"), &isTexture);
+ AssignGLEntryPoint(loadProcAddress("glPolygonOffset"), &polygonOffset);
+ AssignGLEntryPoint(loadProcAddress("glTexSubImage1D"), &texSubImage1D);
+ AssignGLEntryPoint(loadProcAddress("glTexSubImage2D"), &texSubImage2D);
+ }
+
+ // 1.2
+ if (isAtLeastGL(gl::Version(1, 2)))
+ {
+ AssignGLEntryPoint(loadProcAddress("glBlendColor"), &blendColor);
+ AssignGLEntryPoint(loadProcAddress("glBlendEquation"), &blendEquation);
+ AssignGLEntryPoint(loadProcAddress("glCopyTexSubImage3D"), &copyTexSubImage3D);
+ AssignGLEntryPoint(loadProcAddress("glDrawRangeElements"), &drawRangeElements);
+ AssignGLEntryPoint(loadProcAddress("glTexImage3D"), &texImage3D);
+ AssignGLEntryPoint(loadProcAddress("glTexSubImage3D"), &texSubImage3D);
+ }
+
+ // 1.3
+ if (isAtLeastGL(gl::Version(1, 3)))
+ {
+ AssignGLEntryPoint(loadProcAddress("glActiveTexture"), &activeTexture);
+ AssignGLEntryPoint(loadProcAddress("glCompressedTexImage1D"), &compressedTexImage1D);
+ AssignGLEntryPoint(loadProcAddress("glCompressedTexImage2D"), &compressedTexImage2D);
+ AssignGLEntryPoint(loadProcAddress("glCompressedTexImage3D"), &compressedTexImage3D);
+ AssignGLEntryPoint(loadProcAddress("glCompressedTexSubImage1D"), &compressedTexSubImage1D);
+ AssignGLEntryPoint(loadProcAddress("glCompressedTexSubImage2D"), &compressedTexSubImage2D);
+ AssignGLEntryPoint(loadProcAddress("glCompressedTexSubImage3D"), &compressedTexSubImage3D);
+ AssignGLEntryPoint(loadProcAddress("glGetCompressedTexImage"), &getCompressedTexImage);
+ AssignGLEntryPoint(loadProcAddress("glSampleCoverage"), &sampleCoverage);
+ }
+
+ // 1.4
+ if (isAtLeastGL(gl::Version(1, 4)))
+ {
+ AssignGLEntryPoint(loadProcAddress("glBlendFuncSeparate"), &blendFuncSeparate);
+ AssignGLEntryPoint(loadProcAddress("glMultiDrawArrays"), &multiDrawArrays);
+ AssignGLEntryPoint(loadProcAddress("glMultiDrawElements"), &multiDrawElements);
+ AssignGLEntryPoint(loadProcAddress("glPointParameterf"), &pointParameterf);
+ AssignGLEntryPoint(loadProcAddress("glPointParameterfv"), &pointParameterfv);
+ AssignGLEntryPoint(loadProcAddress("glPointParameteri"), &pointParameteri);
+ AssignGLEntryPoint(loadProcAddress("glPointParameteriv"), &pointParameteriv);
+ }
+
+ // 1.5
+ if (isAtLeastGL(gl::Version(1, 5)))
+ {
+ AssignGLEntryPoint(loadProcAddress("glBeginQuery"), &beginQuery);
+ AssignGLEntryPoint(loadProcAddress("glBindBuffer"), &bindBuffer);
+ AssignGLEntryPoint(loadProcAddress("glBufferData"), &bufferData);
+ AssignGLEntryPoint(loadProcAddress("glBufferSubData"), &bufferSubData);
+ AssignGLEntryPoint(loadProcAddress("glDeleteBuffers"), &deleteBuffers);
+ AssignGLEntryPoint(loadProcAddress("glDeleteQueries"), &deleteQueries);
+ AssignGLEntryPoint(loadProcAddress("glEndQuery"), &endQuery);
+ AssignGLEntryPoint(loadProcAddress("glGenBuffers"), &genBuffers);
+ AssignGLEntryPoint(loadProcAddress("glGenQueries"), &genQueries);
+ AssignGLEntryPoint(loadProcAddress("glGetBufferParameteriv"), &getBufferParameteriv);
+ AssignGLEntryPoint(loadProcAddress("glGetBufferPointerv"), &getBufferPointerv);
+ AssignGLEntryPoint(loadProcAddress("glGetBufferSubData"), &getBufferSubData);
+ AssignGLEntryPoint(loadProcAddress("glGetQueryObjectiv"), &getQueryObjectiv);
+ AssignGLEntryPoint(loadProcAddress("glGetQueryObjectuiv"), &getQueryObjectuiv);
+ AssignGLEntryPoint(loadProcAddress("glGetQueryiv"), &getQueryiv);
+ AssignGLEntryPoint(loadProcAddress("glIsBuffer"), &isBuffer);
+ AssignGLEntryPoint(loadProcAddress("glIsQuery"), &isQuery);
+ AssignGLEntryPoint(loadProcAddress("glMapBuffer"), &mapBuffer);
+ AssignGLEntryPoint(loadProcAddress("glUnmapBuffer"), &unmapBuffer);
+ }
+
+ // 2.0
+ if (isAtLeastGL(gl::Version(2, 0)))
+ {
+ AssignGLEntryPoint(loadProcAddress("glAttachShader"), &attachShader);
+ AssignGLEntryPoint(loadProcAddress("glBindAttribLocation"), &bindAttribLocation);
+ AssignGLEntryPoint(loadProcAddress("glBlendEquationSeparate"), &blendEquationSeparate);
+ AssignGLEntryPoint(loadProcAddress("glCompileShader"), &compileShader);
+ AssignGLEntryPoint(loadProcAddress("glCreateProgram"), &createProgram);
+ AssignGLEntryPoint(loadProcAddress("glCreateShader"), &createShader);
+ AssignGLEntryPoint(loadProcAddress("glDeleteProgram"), &deleteProgram);
+ AssignGLEntryPoint(loadProcAddress("glDeleteShader"), &deleteShader);
+ AssignGLEntryPoint(loadProcAddress("glDetachShader"), &detachShader);
+ AssignGLEntryPoint(loadProcAddress("glDisableVertexAttribArray"), &disableVertexAttribArray);
+ AssignGLEntryPoint(loadProcAddress("glDrawBuffers"), &drawBuffers);
+ AssignGLEntryPoint(loadProcAddress("glEnableVertexAttribArray"), &enableVertexAttribArray);
+ AssignGLEntryPoint(loadProcAddress("glGetActiveAttrib"), &getActiveAttrib);
+ AssignGLEntryPoint(loadProcAddress("glGetActiveUniform"), &getActiveUniform);
+ AssignGLEntryPoint(loadProcAddress("glGetAttachedShaders"), &getAttachedShaders);
+ AssignGLEntryPoint(loadProcAddress("glGetAttribLocation"), &getAttribLocation);
+ AssignGLEntryPoint(loadProcAddress("glGetProgramInfoLog"), &getProgramInfoLog);
+ AssignGLEntryPoint(loadProcAddress("glGetProgramiv"), &getProgramiv);
+ AssignGLEntryPoint(loadProcAddress("glGetShaderInfoLog"), &getShaderInfoLog);
+ AssignGLEntryPoint(loadProcAddress("glGetShaderSource"), &getShaderSource);
+ AssignGLEntryPoint(loadProcAddress("glGetShaderiv"), &getShaderiv);
+ AssignGLEntryPoint(loadProcAddress("glGetUniformLocation"), &getUniformLocation);
+ AssignGLEntryPoint(loadProcAddress("glGetUniformfv"), &getUniformfv);
+ AssignGLEntryPoint(loadProcAddress("glGetUniformiv"), &getUniformiv);
+ AssignGLEntryPoint(loadProcAddress("glGetVertexAttribPointerv"), &getVertexAttribPointerv);
+ AssignGLEntryPoint(loadProcAddress("glGetVertexAttribdv"), &getVertexAttribdv);
+ AssignGLEntryPoint(loadProcAddress("glGetVertexAttribfv"), &getVertexAttribfv);
+ AssignGLEntryPoint(loadProcAddress("glGetVertexAttribiv"), &getVertexAttribiv);
+ AssignGLEntryPoint(loadProcAddress("glIsProgram"), &isProgram);
+ AssignGLEntryPoint(loadProcAddress("glIsShader"), &isShader);
+ AssignGLEntryPoint(loadProcAddress("glLinkProgram"), &linkProgram);
+ AssignGLEntryPoint(loadProcAddress("glShaderSource"), &shaderSource);
+ AssignGLEntryPoint(loadProcAddress("glStencilFuncSeparate"), &stencilFuncSeparate);
+ AssignGLEntryPoint(loadProcAddress("glStencilMaskSeparate"), &stencilMaskSeparate);
+ AssignGLEntryPoint(loadProcAddress("glStencilOpSeparate"), &stencilOpSeparate);
+ AssignGLEntryPoint(loadProcAddress("glUniform1f"), &uniform1f);
+ AssignGLEntryPoint(loadProcAddress("glUniform1fv"), &uniform1fv);
+ AssignGLEntryPoint(loadProcAddress("glUniform1i"), &uniform1i);
+ AssignGLEntryPoint(loadProcAddress("glUniform1iv"), &uniform1iv);
+ AssignGLEntryPoint(loadProcAddress("glUniform2f"), &uniform2f);
+ AssignGLEntryPoint(loadProcAddress("glUniform2fv"), &uniform2fv);
+ AssignGLEntryPoint(loadProcAddress("glUniform2i"), &uniform2i);
+ AssignGLEntryPoint(loadProcAddress("glUniform2iv"), &uniform2iv);
+ AssignGLEntryPoint(loadProcAddress("glUniform3f"), &uniform3f);
+ AssignGLEntryPoint(loadProcAddress("glUniform3fv"), &uniform3fv);
+ AssignGLEntryPoint(loadProcAddress("glUniform3i"), &uniform3i);
+ AssignGLEntryPoint(loadProcAddress("glUniform3iv"), &uniform3iv);
+ AssignGLEntryPoint(loadProcAddress("glUniform4f"), &uniform4f);
+ AssignGLEntryPoint(loadProcAddress("glUniform4fv"), &uniform4fv);
+ AssignGLEntryPoint(loadProcAddress("glUniform4i"), &uniform4i);
+ AssignGLEntryPoint(loadProcAddress("glUniform4iv"), &uniform4iv);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix2fv"), &uniformMatrix2fv);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix3fv"), &uniformMatrix3fv);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix4fv"), &uniformMatrix4fv);
+ AssignGLEntryPoint(loadProcAddress("glUseProgram"), &useProgram);
+ AssignGLEntryPoint(loadProcAddress("glValidateProgram"), &validateProgram);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib1d"), &vertexAttrib1d);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib1dv"), &vertexAttrib1dv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib1f"), &vertexAttrib1f);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib1fv"), &vertexAttrib1fv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib1s"), &vertexAttrib1s);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib1sv"), &vertexAttrib1sv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib2d"), &vertexAttrib2d);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib2dv"), &vertexAttrib2dv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib2f"), &vertexAttrib2f);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib2fv"), &vertexAttrib2fv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib2s"), &vertexAttrib2s);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib2sv"), &vertexAttrib2sv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib3d"), &vertexAttrib3d);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib3dv"), &vertexAttrib3dv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib3f"), &vertexAttrib3f);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib3fv"), &vertexAttrib3fv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib3s"), &vertexAttrib3s);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib3sv"), &vertexAttrib3sv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib4Nbv"), &vertexAttrib4Nbv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib4Niv"), &vertexAttrib4Niv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib4Nsv"), &vertexAttrib4Nsv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib4Nub"), &vertexAttrib4Nub);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib4Nubv"), &vertexAttrib4Nubv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib4Nuiv"), &vertexAttrib4Nuiv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib4Nusv"), &vertexAttrib4Nusv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib4bv"), &vertexAttrib4bv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib4d"), &vertexAttrib4d);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib4dv"), &vertexAttrib4dv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib4f"), &vertexAttrib4f);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib4fv"), &vertexAttrib4fv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib4iv"), &vertexAttrib4iv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib4s"), &vertexAttrib4s);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib4sv"), &vertexAttrib4sv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib4ubv"), &vertexAttrib4ubv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib4uiv"), &vertexAttrib4uiv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib4usv"), &vertexAttrib4usv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribPointer"), &vertexAttribPointer);
+ }
+
+ // 2.1
+ if (isAtLeastGL(gl::Version(2, 1)))
+ {
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix2x3fv"), &uniformMatrix2x3fv);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix2x4fv"), &uniformMatrix2x4fv);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix3x2fv"), &uniformMatrix3x2fv);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix3x4fv"), &uniformMatrix3x4fv);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix4x2fv"), &uniformMatrix4x2fv);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix4x3fv"), &uniformMatrix4x3fv);
+ }
+
+ // 3.0
+ if (isAtLeastGL(gl::Version(3, 0)))
+ {
+ AssignGLEntryPoint(loadProcAddress("glBeginConditionalRender"), &beginConditionalRender);
+ AssignGLEntryPoint(loadProcAddress("glBeginTransformFeedback"), &beginTransformFeedback);
+ AssignGLEntryPoint(loadProcAddress("glBindBufferBase"), &bindBufferBase);
+ AssignGLEntryPoint(loadProcAddress("glBindBufferRange"), &bindBufferRange);
+ AssignGLEntryPoint(loadProcAddress("glBindFragDataLocation"), &bindFragDataLocation);
+ AssignGLEntryPoint(loadProcAddress("glBindFramebuffer"), &bindFramebuffer);
+ AssignGLEntryPoint(loadProcAddress("glBindRenderbuffer"), &bindRenderbuffer);
+ AssignGLEntryPoint(loadProcAddress("glBindVertexArray"), &bindVertexArray);
+ AssignGLEntryPoint(loadProcAddress("glBlitFramebuffer"), &blitFramebuffer);
+ AssignGLEntryPoint(loadProcAddress("glCheckFramebufferStatus"), &checkFramebufferStatus);
+ AssignGLEntryPoint(loadProcAddress("glClampColor"), &clampColor);
+ AssignGLEntryPoint(loadProcAddress("glClearBufferfi"), &clearBufferfi);
+ AssignGLEntryPoint(loadProcAddress("glClearBufferfv"), &clearBufferfv);
+ AssignGLEntryPoint(loadProcAddress("glClearBufferiv"), &clearBufferiv);
+ AssignGLEntryPoint(loadProcAddress("glClearBufferuiv"), &clearBufferuiv);
+ AssignGLEntryPoint(loadProcAddress("glColorMaski"), &colorMaski);
+ AssignGLEntryPoint(loadProcAddress("glDeleteFramebuffers"), &deleteFramebuffers);
+ AssignGLEntryPoint(loadProcAddress("glDeleteRenderbuffers"), &deleteRenderbuffers);
+ AssignGLEntryPoint(loadProcAddress("glDeleteVertexArrays"), &deleteVertexArrays);
+ AssignGLEntryPoint(loadProcAddress("glDisablei"), &disablei);
+ AssignGLEntryPoint(loadProcAddress("glEnablei"), &enablei);
+ AssignGLEntryPoint(loadProcAddress("glEndConditionalRender"), &endConditionalRender);
+ AssignGLEntryPoint(loadProcAddress("glEndTransformFeedback"), &endTransformFeedback);
+ AssignGLEntryPoint(loadProcAddress("glFlushMappedBufferRange"), &flushMappedBufferRange);
+ AssignGLEntryPoint(loadProcAddress("glFramebufferRenderbuffer"), &framebufferRenderbuffer);
+ AssignGLEntryPoint(loadProcAddress("glFramebufferTexture1D"), &framebufferTexture1D);
+ AssignGLEntryPoint(loadProcAddress("glFramebufferTexture2D"), &framebufferTexture2D);
+ AssignGLEntryPoint(loadProcAddress("glFramebufferTexture3D"), &framebufferTexture3D);
+ AssignGLEntryPoint(loadProcAddress("glFramebufferTextureLayer"), &framebufferTextureLayer);
+ AssignGLEntryPoint(loadProcAddress("glGenFramebuffers"), &genFramebuffers);
+ AssignGLEntryPoint(loadProcAddress("glGenRenderbuffers"), &genRenderbuffers);
+ AssignGLEntryPoint(loadProcAddress("glGenVertexArrays"), &genVertexArrays);
+ AssignGLEntryPoint(loadProcAddress("glGenerateMipmap"), &generateMipmap);
+ AssignGLEntryPoint(loadProcAddress("glGetBooleani_v"), &getBooleani_v);
+ AssignGLEntryPoint(loadProcAddress("glGetFragDataLocation"), &getFragDataLocation);
+ AssignGLEntryPoint(loadProcAddress("glGetFramebufferAttachmentParameteriv"), &getFramebufferAttachmentParameteriv);
+ AssignGLEntryPoint(loadProcAddress("glGetIntegeri_v"), &getIntegeri_v);
+ AssignGLEntryPoint(loadProcAddress("glGetRenderbufferParameteriv"), &getRenderbufferParameteriv);
+ AssignGLEntryPoint(loadProcAddress("glGetStringi"), &getStringi);
+ AssignGLEntryPoint(loadProcAddress("glGetTexParameterIiv"), &getTexParameterIiv);
+ AssignGLEntryPoint(loadProcAddress("glGetTexParameterIuiv"), &getTexParameterIuiv);
+ AssignGLEntryPoint(loadProcAddress("glGetTransformFeedbackVarying"), &getTransformFeedbackVarying);
+ AssignGLEntryPoint(loadProcAddress("glGetUniformuiv"), &getUniformuiv);
+ AssignGLEntryPoint(loadProcAddress("glGetVertexAttribIiv"), &getVertexAttribIiv);
+ AssignGLEntryPoint(loadProcAddress("glGetVertexAttribIuiv"), &getVertexAttribIuiv);
+ AssignGLEntryPoint(loadProcAddress("glIsEnabledi"), &isEnabledi);
+ AssignGLEntryPoint(loadProcAddress("glIsFramebuffer"), &isFramebuffer);
+ AssignGLEntryPoint(loadProcAddress("glIsRenderbuffer"), &isRenderbuffer);
+ AssignGLEntryPoint(loadProcAddress("glIsVertexArray"), &isVertexArray);
+ AssignGLEntryPoint(loadProcAddress("glMapBufferRange"), &mapBufferRange);
+ AssignGLEntryPoint(loadProcAddress("glRenderbufferStorage"), &renderbufferStorage);
+ AssignGLEntryPoint(loadProcAddress("glRenderbufferStorageMultisample"), &renderbufferStorageMultisample);
+ AssignGLEntryPoint(loadProcAddress("glTexParameterIiv"), &texParameterIiv);
+ AssignGLEntryPoint(loadProcAddress("glTexParameterIuiv"), &texParameterIuiv);
+ AssignGLEntryPoint(loadProcAddress("glTransformFeedbackVaryings"), &transformFeedbackVaryings);
+ AssignGLEntryPoint(loadProcAddress("glUniform1ui"), &uniform1ui);
+ AssignGLEntryPoint(loadProcAddress("glUniform1uiv"), &uniform1uiv);
+ AssignGLEntryPoint(loadProcAddress("glUniform2ui"), &uniform2ui);
+ AssignGLEntryPoint(loadProcAddress("glUniform2uiv"), &uniform2uiv);
+ AssignGLEntryPoint(loadProcAddress("glUniform3ui"), &uniform3ui);
+ AssignGLEntryPoint(loadProcAddress("glUniform3uiv"), &uniform3uiv);
+ AssignGLEntryPoint(loadProcAddress("glUniform4ui"), &uniform4ui);
+ AssignGLEntryPoint(loadProcAddress("glUniform4uiv"), &uniform4uiv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribI1i"), &vertexAttribI1i);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribI1iv"), &vertexAttribI1iv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribI1ui"), &vertexAttribI1ui);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribI1uiv"), &vertexAttribI1uiv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribI2i"), &vertexAttribI2i);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribI2iv"), &vertexAttribI2iv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribI2ui"), &vertexAttribI2ui);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribI2uiv"), &vertexAttribI2uiv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribI3i"), &vertexAttribI3i);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribI3iv"), &vertexAttribI3iv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribI3ui"), &vertexAttribI3ui);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribI3uiv"), &vertexAttribI3uiv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribI4bv"), &vertexAttribI4bv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribI4i"), &vertexAttribI4i);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribI4iv"), &vertexAttribI4iv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribI4sv"), &vertexAttribI4sv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribI4ubv"), &vertexAttribI4ubv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribI4ui"), &vertexAttribI4ui);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribI4uiv"), &vertexAttribI4uiv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribI4usv"), &vertexAttribI4usv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribIPointer"), &vertexAttribIPointer);
+ }
+
+ // 3.1
+ if (isAtLeastGL(gl::Version(3, 1)))
+ {
+ AssignGLEntryPoint(loadProcAddress("glCopyBufferSubData"), &copyBufferSubData);
+ AssignGLEntryPoint(loadProcAddress("glDrawArraysInstanced"), &drawArraysInstanced);
+ AssignGLEntryPoint(loadProcAddress("glDrawElementsInstanced"), &drawElementsInstanced);
+ AssignGLEntryPoint(loadProcAddress("glGetActiveUniformBlockName"), &getActiveUniformBlockName);
+ AssignGLEntryPoint(loadProcAddress("glGetActiveUniformBlockiv"), &getActiveUniformBlockiv);
+ AssignGLEntryPoint(loadProcAddress("glGetActiveUniformName"), &getActiveUniformName);
+ AssignGLEntryPoint(loadProcAddress("glGetActiveUniformsiv"), &getActiveUniformsiv);
+ AssignGLEntryPoint(loadProcAddress("glGetUniformBlockIndex"), &getUniformBlockIndex);
+ AssignGLEntryPoint(loadProcAddress("glGetUniformIndices"), &getUniformIndices);
+ AssignGLEntryPoint(loadProcAddress("glPrimitiveRestartIndex"), &primitiveRestartIndex);
+ AssignGLEntryPoint(loadProcAddress("glTexBuffer"), &texBuffer);
+ AssignGLEntryPoint(loadProcAddress("glUniformBlockBinding"), &uniformBlockBinding);
+ }
+
+ // 3.2
+ if (isAtLeastGL(gl::Version(3, 2)))
+ {
+ AssignGLEntryPoint(loadProcAddress("glClientWaitSync"), &clientWaitSync);
+ AssignGLEntryPoint(loadProcAddress("glDeleteSync"), &deleteSync);
+ AssignGLEntryPoint(loadProcAddress("glDrawElementsBaseVertex"), &drawElementsBaseVertex);
+ AssignGLEntryPoint(loadProcAddress("glDrawElementsInstancedBaseVertex"), &drawElementsInstancedBaseVertex);
+ AssignGLEntryPoint(loadProcAddress("glDrawRangeElementsBaseVertex"), &drawRangeElementsBaseVertex);
+ AssignGLEntryPoint(loadProcAddress("glFenceSync"), &fenceSync);
+ AssignGLEntryPoint(loadProcAddress("glFramebufferTexture"), &framebufferTexture);
+ AssignGLEntryPoint(loadProcAddress("glGetBufferParameteri64v"), &getBufferParameteri64v);
+ AssignGLEntryPoint(loadProcAddress("glGetInteger64i_v"), &getInteger64i_v);
+ AssignGLEntryPoint(loadProcAddress("glGetInteger64v"), &getInteger64v);
+ AssignGLEntryPoint(loadProcAddress("glGetMultisamplefv"), &getMultisamplefv);
+ AssignGLEntryPoint(loadProcAddress("glGetSynciv"), &getSynciv);
+ AssignGLEntryPoint(loadProcAddress("glIsSync"), &isSync);
+ AssignGLEntryPoint(loadProcAddress("glMultiDrawElementsBaseVertex"), &multiDrawElementsBaseVertex);
+ AssignGLEntryPoint(loadProcAddress("glProvokingVertex"), &provokingVertex);
+ AssignGLEntryPoint(loadProcAddress("glSampleMaski"), &sampleMaski);
+ AssignGLEntryPoint(loadProcAddress("glTexImage2DMultisample"), &texImage2DMultisample);
+ AssignGLEntryPoint(loadProcAddress("glTexImage3DMultisample"), &texImage3DMultisample);
+ AssignGLEntryPoint(loadProcAddress("glWaitSync"), &waitSync);
+ }
+
+ // 3.3
+ if (isAtLeastGL(gl::Version(3, 3)))
+ {
+ AssignGLEntryPoint(loadProcAddress("glBindFragDataLocationIndexed"), &bindFragDataLocationIndexed);
+ AssignGLEntryPoint(loadProcAddress("glBindSampler"), &bindSampler);
+ AssignGLEntryPoint(loadProcAddress("glDeleteSamplers"), &deleteSamplers);
+ AssignGLEntryPoint(loadProcAddress("glGenSamplers"), &genSamplers);
+ AssignGLEntryPoint(loadProcAddress("glGetFragDataIndex"), &getFragDataIndex);
+ AssignGLEntryPoint(loadProcAddress("glGetQueryObjecti64v"), &getQueryObjecti64v);
+ AssignGLEntryPoint(loadProcAddress("glGetQueryObjectui64v"), &getQueryObjectui64v);
+ AssignGLEntryPoint(loadProcAddress("glGetSamplerParameterIiv"), &getSamplerParameterIiv);
+ AssignGLEntryPoint(loadProcAddress("glGetSamplerParameterIuiv"), &getSamplerParameterIuiv);
+ AssignGLEntryPoint(loadProcAddress("glGetSamplerParameterfv"), &getSamplerParameterfv);
+ AssignGLEntryPoint(loadProcAddress("glGetSamplerParameteriv"), &getSamplerParameteriv);
+ AssignGLEntryPoint(loadProcAddress("glIsSampler"), &isSampler);
+ AssignGLEntryPoint(loadProcAddress("glQueryCounter"), &queryCounter);
+ AssignGLEntryPoint(loadProcAddress("glSamplerParameterIiv"), &samplerParameterIiv);
+ AssignGLEntryPoint(loadProcAddress("glSamplerParameterIuiv"), &samplerParameterIuiv);
+ AssignGLEntryPoint(loadProcAddress("glSamplerParameterf"), &samplerParameterf);
+ AssignGLEntryPoint(loadProcAddress("glSamplerParameterfv"), &samplerParameterfv);
+ AssignGLEntryPoint(loadProcAddress("glSamplerParameteri"), &samplerParameteri);
+ AssignGLEntryPoint(loadProcAddress("glSamplerParameteriv"), &samplerParameteriv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribDivisor"), &vertexAttribDivisor);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribP1ui"), &vertexAttribP1ui);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribP1uiv"), &vertexAttribP1uiv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribP2ui"), &vertexAttribP2ui);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribP2uiv"), &vertexAttribP2uiv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribP3ui"), &vertexAttribP3ui);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribP3uiv"), &vertexAttribP3uiv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribP4ui"), &vertexAttribP4ui);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribP4uiv"), &vertexAttribP4uiv);
+ }
+
+ // 4.0
+ if (isAtLeastGL(gl::Version(4, 0)))
+ {
+ AssignGLEntryPoint(loadProcAddress("glBeginQueryIndexed"), &beginQueryIndexed);
+ AssignGLEntryPoint(loadProcAddress("glBindTransformFeedback"), &bindTransformFeedback);
+ AssignGLEntryPoint(loadProcAddress("glBlendEquationSeparatei"), &blendEquationSeparatei);
+ AssignGLEntryPoint(loadProcAddress("glBlendEquationi"), &blendEquationi);
+ AssignGLEntryPoint(loadProcAddress("glBlendFuncSeparatei"), &blendFuncSeparatei);
+ AssignGLEntryPoint(loadProcAddress("glBlendFunci"), &blendFunci);
+ AssignGLEntryPoint(loadProcAddress("glDeleteTransformFeedbacks"), &deleteTransformFeedbacks);
+ AssignGLEntryPoint(loadProcAddress("glDrawArraysIndirect"), &drawArraysIndirect);
+ AssignGLEntryPoint(loadProcAddress("glDrawElementsIndirect"), &drawElementsIndirect);
+ AssignGLEntryPoint(loadProcAddress("glDrawTransformFeedback"), &drawTransformFeedback);
+ AssignGLEntryPoint(loadProcAddress("glDrawTransformFeedbackStream"), &drawTransformFeedbackStream);
+ AssignGLEntryPoint(loadProcAddress("glEndQueryIndexed"), &endQueryIndexed);
+ AssignGLEntryPoint(loadProcAddress("glGenTransformFeedbacks"), &genTransformFeedbacks);
+ AssignGLEntryPoint(loadProcAddress("glGetActiveSubroutineName"), &getActiveSubroutineName);
+ AssignGLEntryPoint(loadProcAddress("glGetActiveSubroutineUniformName"), &getActiveSubroutineUniformName);
+ AssignGLEntryPoint(loadProcAddress("glGetActiveSubroutineUniformiv"), &getActiveSubroutineUniformiv);
+ AssignGLEntryPoint(loadProcAddress("glGetProgramStageiv"), &getProgramStageiv);
+ AssignGLEntryPoint(loadProcAddress("glGetQueryIndexediv"), &getQueryIndexediv);
+ AssignGLEntryPoint(loadProcAddress("glGetSubroutineIndex"), &getSubroutineIndex);
+ AssignGLEntryPoint(loadProcAddress("glGetSubroutineUniformLocation"), &getSubroutineUniformLocation);
+ AssignGLEntryPoint(loadProcAddress("glGetUniformSubroutineuiv"), &getUniformSubroutineuiv);
+ AssignGLEntryPoint(loadProcAddress("glGetUniformdv"), &getUniformdv);
+ AssignGLEntryPoint(loadProcAddress("glIsTransformFeedback"), &isTransformFeedback);
+ AssignGLEntryPoint(loadProcAddress("glMinSampleShading"), &minSampleShading);
+ AssignGLEntryPoint(loadProcAddress("glPatchParameterfv"), &patchParameterfv);
+ AssignGLEntryPoint(loadProcAddress("glPatchParameteri"), &patchParameteri);
+ AssignGLEntryPoint(loadProcAddress("glPauseTransformFeedback"), &pauseTransformFeedback);
+ AssignGLEntryPoint(loadProcAddress("glResumeTransformFeedback"), &resumeTransformFeedback);
+ AssignGLEntryPoint(loadProcAddress("glUniform1d"), &uniform1d);
+ AssignGLEntryPoint(loadProcAddress("glUniform1dv"), &uniform1dv);
+ AssignGLEntryPoint(loadProcAddress("glUniform2d"), &uniform2d);
+ AssignGLEntryPoint(loadProcAddress("glUniform2dv"), &uniform2dv);
+ AssignGLEntryPoint(loadProcAddress("glUniform3d"), &uniform3d);
+ AssignGLEntryPoint(loadProcAddress("glUniform3dv"), &uniform3dv);
+ AssignGLEntryPoint(loadProcAddress("glUniform4d"), &uniform4d);
+ AssignGLEntryPoint(loadProcAddress("glUniform4dv"), &uniform4dv);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix2dv"), &uniformMatrix2dv);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix2x3dv"), &uniformMatrix2x3dv);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix2x4dv"), &uniformMatrix2x4dv);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix3dv"), &uniformMatrix3dv);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix3x2dv"), &uniformMatrix3x2dv);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix3x4dv"), &uniformMatrix3x4dv);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix4dv"), &uniformMatrix4dv);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix4x2dv"), &uniformMatrix4x2dv);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix4x3dv"), &uniformMatrix4x3dv);
+ AssignGLEntryPoint(loadProcAddress("glUniformSubroutinesuiv"), &uniformSubroutinesuiv);
+ }
+
+ // 4.1
+ if (isAtLeastGL(gl::Version(4, 1)))
+ {
+ AssignGLEntryPoint(loadProcAddress("glActiveShaderProgram"), &activeShaderProgram);
+ AssignGLEntryPoint(loadProcAddress("glBindProgramPipeline"), &bindProgramPipeline);
+ AssignGLEntryPoint(loadProcAddress("glClearDepthf"), &clearDepthf);
+ AssignGLEntryPoint(loadProcAddress("glCreateShaderProgramv"), &createShaderProgramv);
+ AssignGLEntryPoint(loadProcAddress("glDeleteProgramPipelines"), &deleteProgramPipelines);
+ AssignGLEntryPoint(loadProcAddress("glDepthRangeArrayv"), &depthRangeArrayv);
+ AssignGLEntryPoint(loadProcAddress("glDepthRangeIndexed"), &depthRangeIndexed);
+ AssignGLEntryPoint(loadProcAddress("glDepthRangef"), &depthRangef);
+ AssignGLEntryPoint(loadProcAddress("glGenProgramPipelines"), &genProgramPipelines);
+ AssignGLEntryPoint(loadProcAddress("glGetDoublei_v"), &getDoublei_v);
+ AssignGLEntryPoint(loadProcAddress("glGetFloati_v"), &getFloati_v);
+ AssignGLEntryPoint(loadProcAddress("glGetProgramBinary"), &getProgramBinary);
+ AssignGLEntryPoint(loadProcAddress("glGetProgramPipelineInfoLog"), &getProgramPipelineInfoLog);
+ AssignGLEntryPoint(loadProcAddress("glGetProgramPipelineiv"), &getProgramPipelineiv);
+ AssignGLEntryPoint(loadProcAddress("glGetShaderPrecisionFormat"), &getShaderPrecisionFormat);
+ AssignGLEntryPoint(loadProcAddress("glGetVertexAttribLdv"), &getVertexAttribLdv);
+ AssignGLEntryPoint(loadProcAddress("glIsProgramPipeline"), &isProgramPipeline);
+ AssignGLEntryPoint(loadProcAddress("glProgramBinary"), &programBinary);
+ AssignGLEntryPoint(loadProcAddress("glProgramParameteri"), &programParameteri);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform1d"), &programUniform1d);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform1dv"), &programUniform1dv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform1f"), &programUniform1f);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform1fv"), &programUniform1fv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform1i"), &programUniform1i);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform1iv"), &programUniform1iv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform1ui"), &programUniform1ui);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform1uiv"), &programUniform1uiv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform2d"), &programUniform2d);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform2dv"), &programUniform2dv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform2f"), &programUniform2f);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform2fv"), &programUniform2fv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform2i"), &programUniform2i);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform2iv"), &programUniform2iv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform2ui"), &programUniform2ui);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform2uiv"), &programUniform2uiv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform3d"), &programUniform3d);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform3dv"), &programUniform3dv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform3f"), &programUniform3f);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform3fv"), &programUniform3fv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform3i"), &programUniform3i);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform3iv"), &programUniform3iv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform3ui"), &programUniform3ui);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform3uiv"), &programUniform3uiv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform4d"), &programUniform4d);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform4dv"), &programUniform4dv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform4f"), &programUniform4f);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform4fv"), &programUniform4fv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform4i"), &programUniform4i);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform4iv"), &programUniform4iv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform4ui"), &programUniform4ui);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform4uiv"), &programUniform4uiv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix2dv"), &programUniformMatrix2dv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix2fv"), &programUniformMatrix2fv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix2x3dv"), &programUniformMatrix2x3dv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix2x3fv"), &programUniformMatrix2x3fv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix2x4dv"), &programUniformMatrix2x4dv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix2x4fv"), &programUniformMatrix2x4fv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix3dv"), &programUniformMatrix3dv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix3fv"), &programUniformMatrix3fv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix3x2dv"), &programUniformMatrix3x2dv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix3x2fv"), &programUniformMatrix3x2fv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix3x4dv"), &programUniformMatrix3x4dv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix3x4fv"), &programUniformMatrix3x4fv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix4dv"), &programUniformMatrix4dv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix4fv"), &programUniformMatrix4fv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix4x2dv"), &programUniformMatrix4x2dv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix4x2fv"), &programUniformMatrix4x2fv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix4x3dv"), &programUniformMatrix4x3dv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix4x3fv"), &programUniformMatrix4x3fv);
+ AssignGLEntryPoint(loadProcAddress("glReleaseShaderCompiler"), &releaseShaderCompiler);
+ AssignGLEntryPoint(loadProcAddress("glScissorArrayv"), &scissorArrayv);
+ AssignGLEntryPoint(loadProcAddress("glScissorIndexed"), &scissorIndexed);
+ AssignGLEntryPoint(loadProcAddress("glScissorIndexedv"), &scissorIndexedv);
+ AssignGLEntryPoint(loadProcAddress("glShaderBinary"), &shaderBinary);
+ AssignGLEntryPoint(loadProcAddress("glUseProgramStages"), &useProgramStages);
+ AssignGLEntryPoint(loadProcAddress("glValidateProgramPipeline"), &validateProgramPipeline);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribL1d"), &vertexAttribL1d);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribL1dv"), &vertexAttribL1dv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribL2d"), &vertexAttribL2d);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribL2dv"), &vertexAttribL2dv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribL3d"), &vertexAttribL3d);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribL3dv"), &vertexAttribL3dv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribL4d"), &vertexAttribL4d);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribL4dv"), &vertexAttribL4dv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribLPointer"), &vertexAttribLPointer);
+ AssignGLEntryPoint(loadProcAddress("glViewportArrayv"), &viewportArrayv);
+ AssignGLEntryPoint(loadProcAddress("glViewportIndexedf"), &viewportIndexedf);
+ AssignGLEntryPoint(loadProcAddress("glViewportIndexedfv"), &viewportIndexedfv);
+ }
+
+ // 4.2
+ if (isAtLeastGL(gl::Version(4, 2)))
+ {
+ AssignGLEntryPoint(loadProcAddress("glBindImageTexture"), &bindImageTexture);
+ AssignGLEntryPoint(loadProcAddress("glDrawArraysInstancedBaseInstance"), &drawArraysInstancedBaseInstance);
+ AssignGLEntryPoint(loadProcAddress("glDrawElementsInstancedBaseInstance"), &drawElementsInstancedBaseInstance);
+ AssignGLEntryPoint(loadProcAddress("glDrawElementsInstancedBaseVertexBaseInstance"), &drawElementsInstancedBaseVertexBaseInstance);
+ AssignGLEntryPoint(loadProcAddress("glDrawTransformFeedbackInstanced"), &drawTransformFeedbackInstanced);
+ AssignGLEntryPoint(loadProcAddress("glDrawTransformFeedbackStreamInstanced"), &drawTransformFeedbackStreamInstanced);
+ AssignGLEntryPoint(loadProcAddress("glGetActiveAtomicCounterBufferiv"), &getActiveAtomicCounterBufferiv);
+ AssignGLEntryPoint(loadProcAddress("glGetInternalformativ"), &getInternalformativ);
+ AssignGLEntryPoint(loadProcAddress("glMemoryBarrier"), &memoryBarrier);
+ AssignGLEntryPoint(loadProcAddress("glTexStorage1D"), &texStorage1D);
+ AssignGLEntryPoint(loadProcAddress("glTexStorage2D"), &texStorage2D);
+ AssignGLEntryPoint(loadProcAddress("glTexStorage3D"), &texStorage3D);
+ }
+
+ // 4.3
+ if (isAtLeastGL(gl::Version(4, 3)))
+ {
+ AssignGLEntryPoint(loadProcAddress("glBindVertexBuffer"), &bindVertexBuffer);
+ AssignGLEntryPoint(loadProcAddress("glClearBufferData"), &clearBufferData);
+ AssignGLEntryPoint(loadProcAddress("glClearBufferSubData"), &clearBufferSubData);
+ AssignGLEntryPoint(loadProcAddress("glCopyImageSubData"), &copyImageSubData);
+ AssignGLEntryPoint(loadProcAddress("glDebugMessageCallback"), &debugMessageCallback);
+ AssignGLEntryPoint(loadProcAddress("glDebugMessageControl"), &debugMessageControl);
+ AssignGLEntryPoint(loadProcAddress("glDebugMessageInsert"), &debugMessageInsert);
+ AssignGLEntryPoint(loadProcAddress("glDispatchCompute"), &dispatchCompute);
+ AssignGLEntryPoint(loadProcAddress("glDispatchComputeIndirect"), &dispatchComputeIndirect);
+ AssignGLEntryPoint(loadProcAddress("glFramebufferParameteri"), &framebufferParameteri);
+ AssignGLEntryPoint(loadProcAddress("glGetDebugMessageLog"), &getDebugMessageLog);
+ AssignGLEntryPoint(loadProcAddress("glGetFramebufferParameteriv"), &getFramebufferParameteriv);
+ AssignGLEntryPoint(loadProcAddress("glGetInternalformati64v"), &getInternalformati64v);
+ AssignGLEntryPoint(loadProcAddress("glGetPointerv"), &getPointerv);
+ AssignGLEntryPoint(loadProcAddress("glGetObjectLabel"), &getObjectLabel);
+ AssignGLEntryPoint(loadProcAddress("glGetObjectPtrLabel"), &getObjectPtrLabel);
+ AssignGLEntryPoint(loadProcAddress("glGetProgramInterfaceiv"), &getProgramInterfaceiv);
+ AssignGLEntryPoint(loadProcAddress("glGetProgramResourceIndex"), &getProgramResourceIndex);
+ AssignGLEntryPoint(loadProcAddress("glGetProgramResourceLocation"), &getProgramResourceLocation);
+ AssignGLEntryPoint(loadProcAddress("glGetProgramResourceLocationIndex"), &getProgramResourceLocationIndex);
+ AssignGLEntryPoint(loadProcAddress("glGetProgramResourceName"), &getProgramResourceName);
+ AssignGLEntryPoint(loadProcAddress("glGetProgramResourceiv"), &getProgramResourceiv);
+ AssignGLEntryPoint(loadProcAddress("glInvalidateBufferData"), &invalidateBufferData);
+ AssignGLEntryPoint(loadProcAddress("glInvalidateBufferSubData"), &invalidateBufferSubData);
+ AssignGLEntryPoint(loadProcAddress("glInvalidateFramebuffer"), &invalidateFramebuffer);
+ AssignGLEntryPoint(loadProcAddress("glInvalidateSubFramebuffer"), &invalidateSubFramebuffer);
+ AssignGLEntryPoint(loadProcAddress("glInvalidateTexImage"), &invalidateTexImage);
+ AssignGLEntryPoint(loadProcAddress("glInvalidateTexSubImage"), &invalidateTexSubImage);
+ AssignGLEntryPoint(loadProcAddress("glMultiDrawArraysIndirect"), &multiDrawArraysIndirect);
+ AssignGLEntryPoint(loadProcAddress("glMultiDrawElementsIndirect"), &multiDrawElementsIndirect);
+ AssignGLEntryPoint(loadProcAddress("glObjectLabel"), &objectLabel);
+ AssignGLEntryPoint(loadProcAddress("glObjectPtrLabel"), &objectPtrLabel);
+ AssignGLEntryPoint(loadProcAddress("glPopDebugGroup"), &popDebugGroup);
+ AssignGLEntryPoint(loadProcAddress("glPushDebugGroup"), &pushDebugGroup);
+ AssignGLEntryPoint(loadProcAddress("glShaderStorageBlockBinding"), &shaderStorageBlockBinding);
+ AssignGLEntryPoint(loadProcAddress("glTexBufferRange"), &texBufferRange);
+ AssignGLEntryPoint(loadProcAddress("glTexStorage2DMultisample"), &texStorage2DMultisample);
+ AssignGLEntryPoint(loadProcAddress("glTexStorage3DMultisample"), &texStorage3DMultisample);
+ AssignGLEntryPoint(loadProcAddress("glTextureView"), &textureView);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribBinding"), &vertexAttribBinding);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribFormat"), &vertexAttribFormat);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribIFormat"), &vertexAttribIFormat);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribLFormat"), &vertexAttribLFormat);
+ AssignGLEntryPoint(loadProcAddress("glVertexBindingDivisor"), &vertexBindingDivisor);
+ }
+
+ // 4.4
+ if (isAtLeastGL(gl::Version(4, 4)))
+ {
+ AssignGLEntryPoint(loadProcAddress("glBindBuffersBase"), &bindBuffersBase);
+ AssignGLEntryPoint(loadProcAddress("glBindBuffersRange"), &bindBuffersRange);
+ AssignGLEntryPoint(loadProcAddress("glBindImageTextures"), &bindImageTextures);
+ AssignGLEntryPoint(loadProcAddress("glBindSamplers"), &bindSamplers);
+ AssignGLEntryPoint(loadProcAddress("glBindTextures"), &bindTextures);
+ AssignGLEntryPoint(loadProcAddress("glBindVertexBuffers"), &bindVertexBuffers);
+ AssignGLEntryPoint(loadProcAddress("glBufferStorage"), &bufferStorage);
+ AssignGLEntryPoint(loadProcAddress("glClearTexImage"), &clearTexImage);
+ AssignGLEntryPoint(loadProcAddress("glClearTexSubImage"), &clearTexSubImage);
+ }
+
+ // 4.5
+ if (isAtLeastGL(gl::Version(4, 5)))
+ {
+ AssignGLEntryPoint(loadProcAddress("glBindTextureUnit"), &bindTextureUnit);
+ AssignGLEntryPoint(loadProcAddress("glBlitNamedFramebuffer"), &blitNamedFramebuffer);
+ AssignGLEntryPoint(loadProcAddress("glCheckNamedFramebufferStatus"), &checkNamedFramebufferStatus);
+ AssignGLEntryPoint(loadProcAddress("glClearNamedBufferData"), &clearNamedBufferData);
+ AssignGLEntryPoint(loadProcAddress("glClearNamedBufferSubData"), &clearNamedBufferSubData);
+ AssignGLEntryPoint(loadProcAddress("glClearNamedFramebufferfi"), &clearNamedFramebufferfi);
+ AssignGLEntryPoint(loadProcAddress("glClearNamedFramebufferfv"), &clearNamedFramebufferfv);
+ AssignGLEntryPoint(loadProcAddress("glClearNamedFramebufferiv"), &clearNamedFramebufferiv);
+ AssignGLEntryPoint(loadProcAddress("glClearNamedFramebufferuiv"), &clearNamedFramebufferuiv);
+ AssignGLEntryPoint(loadProcAddress("glClipControl"), &clipControl);
+ AssignGLEntryPoint(loadProcAddress("glCompressedTextureSubImage1D"), &compressedTextureSubImage1D);
+ AssignGLEntryPoint(loadProcAddress("glCompressedTextureSubImage2D"), &compressedTextureSubImage2D);
+ AssignGLEntryPoint(loadProcAddress("glCompressedTextureSubImage3D"), &compressedTextureSubImage3D);
+ AssignGLEntryPoint(loadProcAddress("glCopyNamedBufferSubData"), &copyNamedBufferSubData);
+ AssignGLEntryPoint(loadProcAddress("glCopyTextureSubImage1D"), &copyTextureSubImage1D);
+ AssignGLEntryPoint(loadProcAddress("glCopyTextureSubImage2D"), &copyTextureSubImage2D);
+ AssignGLEntryPoint(loadProcAddress("glCopyTextureSubImage3D"), &copyTextureSubImage3D);
+ AssignGLEntryPoint(loadProcAddress("glCreateBuffers"), &createBuffers);
+ AssignGLEntryPoint(loadProcAddress("glCreateFramebuffers"), &createFramebuffers);
+ AssignGLEntryPoint(loadProcAddress("glCreateProgramPipelines"), &createProgramPipelines);
+ AssignGLEntryPoint(loadProcAddress("glCreateQueries"), &createQueries);
+ AssignGLEntryPoint(loadProcAddress("glCreateRenderbuffers"), &createRenderbuffers);
+ AssignGLEntryPoint(loadProcAddress("glCreateSamplers"), &createSamplers);
+ AssignGLEntryPoint(loadProcAddress("glCreateTextures"), &createTextures);
+ AssignGLEntryPoint(loadProcAddress("glCreateTransformFeedbacks"), &createTransformFeedbacks);
+ AssignGLEntryPoint(loadProcAddress("glCreateVertexArrays"), &createVertexArrays);
+ AssignGLEntryPoint(loadProcAddress("glDisableVertexArrayAttrib"), &disableVertexArrayAttrib);
+ AssignGLEntryPoint(loadProcAddress("glEnableVertexArrayAttrib"), &enableVertexArrayAttrib);
+ AssignGLEntryPoint(loadProcAddress("glFlushMappedNamedBufferRange"), &flushMappedNamedBufferRange);
+ AssignGLEntryPoint(loadProcAddress("glGenerateTextureMipmap"), &generateTextureMipmap);
+ AssignGLEntryPoint(loadProcAddress("glGetCompressedTextureImage"), &getCompressedTextureImage);
+ AssignGLEntryPoint(loadProcAddress("glGetCompressedTextureSubImage"), &getCompressedTextureSubImage);
+ AssignGLEntryPoint(loadProcAddress("glGetGraphicsResetStatus"), &getGraphicsResetStatus);
+ AssignGLEntryPoint(loadProcAddress("glGetNamedBufferParameteri64v"), &getNamedBufferParameteri64v);
+ AssignGLEntryPoint(loadProcAddress("glGetNamedBufferParameteriv"), &getNamedBufferParameteriv);
+ AssignGLEntryPoint(loadProcAddress("glGetNamedBufferPointerv"), &getNamedBufferPointerv);
+ AssignGLEntryPoint(loadProcAddress("glGetNamedBufferSubData"), &getNamedBufferSubData);
+ AssignGLEntryPoint(loadProcAddress("glGetNamedFramebufferAttachmentParameteriv"), &getNamedFramebufferAttachmentParameteriv);
+ AssignGLEntryPoint(loadProcAddress("glGetNamedFramebufferParameteriv"), &getNamedFramebufferParameteriv);
+ AssignGLEntryPoint(loadProcAddress("glGetNamedRenderbufferParameteriv"), &getNamedRenderbufferParameteriv);
+ AssignGLEntryPoint(loadProcAddress("glGetQueryBufferObjecti64v"), &getQueryBufferObjecti64v);
+ AssignGLEntryPoint(loadProcAddress("glGetQueryBufferObjectiv"), &getQueryBufferObjectiv);
+ AssignGLEntryPoint(loadProcAddress("glGetQueryBufferObjectui64v"), &getQueryBufferObjectui64v);
+ AssignGLEntryPoint(loadProcAddress("glGetQueryBufferObjectuiv"), &getQueryBufferObjectuiv);
+ AssignGLEntryPoint(loadProcAddress("glGetTextureImage"), &getTextureImage);
+ AssignGLEntryPoint(loadProcAddress("glGetTextureLevelParameterfv"), &getTextureLevelParameterfv);
+ AssignGLEntryPoint(loadProcAddress("glGetTextureLevelParameteriv"), &getTextureLevelParameteriv);
+ AssignGLEntryPoint(loadProcAddress("glGetTextureParameterIiv"), &getTextureParameterIiv);
+ AssignGLEntryPoint(loadProcAddress("glGetTextureParameterIuiv"), &getTextureParameterIuiv);
+ AssignGLEntryPoint(loadProcAddress("glGetTextureParameterfv"), &getTextureParameterfv);
+ AssignGLEntryPoint(loadProcAddress("glGetTextureParameteriv"), &getTextureParameteriv);
+ AssignGLEntryPoint(loadProcAddress("glGetTextureSubImage"), &getTextureSubImage);
+ AssignGLEntryPoint(loadProcAddress("glGetTransformFeedbacki64_v"), &getTransformFeedbacki64_v);
+ AssignGLEntryPoint(loadProcAddress("glGetTransformFeedbacki_v"), &getTransformFeedbacki_v);
+ AssignGLEntryPoint(loadProcAddress("glGetTransformFeedbackiv"), &getTransformFeedbackiv);
+ AssignGLEntryPoint(loadProcAddress("glGetVertexArrayIndexed64iv"), &getVertexArrayIndexed64iv);
+ AssignGLEntryPoint(loadProcAddress("glGetVertexArrayIndexediv"), &getVertexArrayIndexediv);
+ AssignGLEntryPoint(loadProcAddress("glGetVertexArrayiv"), &getVertexArrayiv);
+ AssignGLEntryPoint(loadProcAddress("glGetnCompressedTexImage"), &getnCompressedTexImage);
+ AssignGLEntryPoint(loadProcAddress("glGetnTexImage"), &getnTexImage);
+ AssignGLEntryPoint(loadProcAddress("glGetnUniformdv"), &getnUniformdv);
+ AssignGLEntryPoint(loadProcAddress("glGetnUniformfv"), &getnUniformfv);
+ AssignGLEntryPoint(loadProcAddress("glGetnUniformiv"), &getnUniformiv);
+ AssignGLEntryPoint(loadProcAddress("glGetnUniformuiv"), &getnUniformuiv);
+ AssignGLEntryPoint(loadProcAddress("glInvalidateNamedFramebufferData"), &invalidateNamedFramebufferData);
+ AssignGLEntryPoint(loadProcAddress("glInvalidateNamedFramebufferSubData"), &invalidateNamedFramebufferSubData);
+ AssignGLEntryPoint(loadProcAddress("glMapNamedBuffer"), &mapNamedBuffer);
+ AssignGLEntryPoint(loadProcAddress("glMapNamedBufferRange"), &mapNamedBufferRange);
+ AssignGLEntryPoint(loadProcAddress("glMemoryBarrierByRegion"), &memoryBarrierByRegion);
+ AssignGLEntryPoint(loadProcAddress("glNamedBufferData"), &namedBufferData);
+ AssignGLEntryPoint(loadProcAddress("glNamedBufferStorage"), &namedBufferStorage);
+ AssignGLEntryPoint(loadProcAddress("glNamedBufferSubData"), &namedBufferSubData);
+ AssignGLEntryPoint(loadProcAddress("glNamedFramebufferDrawBuffer"), &namedFramebufferDrawBuffer);
+ AssignGLEntryPoint(loadProcAddress("glNamedFramebufferDrawBuffers"), &namedFramebufferDrawBuffers);
+ AssignGLEntryPoint(loadProcAddress("glNamedFramebufferParameteri"), &namedFramebufferParameteri);
+ AssignGLEntryPoint(loadProcAddress("glNamedFramebufferReadBuffer"), &namedFramebufferReadBuffer);
+ AssignGLEntryPoint(loadProcAddress("glNamedFramebufferRenderbuffer"), &namedFramebufferRenderbuffer);
+ AssignGLEntryPoint(loadProcAddress("glNamedFramebufferTexture"), &namedFramebufferTexture);
+ AssignGLEntryPoint(loadProcAddress("glNamedFramebufferTextureLayer"), &namedFramebufferTextureLayer);
+ AssignGLEntryPoint(loadProcAddress("glNamedRenderbufferStorage"), &namedRenderbufferStorage);
+ AssignGLEntryPoint(loadProcAddress("glNamedRenderbufferStorageMultisample"), &namedRenderbufferStorageMultisample);
+ AssignGLEntryPoint(loadProcAddress("glReadnPixels"), &readnPixels);
+ AssignGLEntryPoint(loadProcAddress("glTextureBarrier"), &textureBarrier);
+ AssignGLEntryPoint(loadProcAddress("glTextureBuffer"), &textureBuffer);
+ AssignGLEntryPoint(loadProcAddress("glTextureBufferRange"), &textureBufferRange);
+ AssignGLEntryPoint(loadProcAddress("glTextureParameterIiv"), &textureParameterIiv);
+ AssignGLEntryPoint(loadProcAddress("glTextureParameterIuiv"), &textureParameterIuiv);
+ AssignGLEntryPoint(loadProcAddress("glTextureParameterf"), &textureParameterf);
+ AssignGLEntryPoint(loadProcAddress("glTextureParameterfv"), &textureParameterfv);
+ AssignGLEntryPoint(loadProcAddress("glTextureParameteri"), &textureParameteri);
+ AssignGLEntryPoint(loadProcAddress("glTextureParameteriv"), &textureParameteriv);
+ AssignGLEntryPoint(loadProcAddress("glTextureStorage1D"), &textureStorage1D);
+ AssignGLEntryPoint(loadProcAddress("glTextureStorage2D"), &textureStorage2D);
+ AssignGLEntryPoint(loadProcAddress("glTextureStorage2DMultisample"), &textureStorage2DMultisample);
+ AssignGLEntryPoint(loadProcAddress("glTextureStorage3D"), &textureStorage3D);
+ AssignGLEntryPoint(loadProcAddress("glTextureStorage3DMultisample"), &textureStorage3DMultisample);
+ AssignGLEntryPoint(loadProcAddress("glTextureSubImage1D"), &textureSubImage1D);
+ AssignGLEntryPoint(loadProcAddress("glTextureSubImage2D"), &textureSubImage2D);
+ AssignGLEntryPoint(loadProcAddress("glTextureSubImage3D"), &textureSubImage3D);
+ AssignGLEntryPoint(loadProcAddress("glTransformFeedbackBufferBase"), &transformFeedbackBufferBase);
+ AssignGLEntryPoint(loadProcAddress("glTransformFeedbackBufferRange"), &transformFeedbackBufferRange);
+ AssignGLEntryPoint(loadProcAddress("glUnmapNamedBuffer"), &unmapNamedBuffer);
+ AssignGLEntryPoint(loadProcAddress("glVertexArrayAttribBinding"), &vertexArrayAttribBinding);
+ AssignGLEntryPoint(loadProcAddress("glVertexArrayAttribFormat"), &vertexArrayAttribFormat);
+ AssignGLEntryPoint(loadProcAddress("glVertexArrayAttribIFormat"), &vertexArrayAttribIFormat);
+ AssignGLEntryPoint(loadProcAddress("glVertexArrayAttribLFormat"), &vertexArrayAttribLFormat);
+ AssignGLEntryPoint(loadProcAddress("glVertexArrayBindingDivisor"), &vertexArrayBindingDivisor);
+ AssignGLEntryPoint(loadProcAddress("glVertexArrayElementBuffer"), &vertexArrayElementBuffer);
+ AssignGLEntryPoint(loadProcAddress("glVertexArrayVertexBuffer"), &vertexArrayVertexBuffer);
+ AssignGLEntryPoint(loadProcAddress("glVertexArrayVertexBuffers"), &vertexArrayVertexBuffers);
+ }
+
+ // clang-format on
+}
+
+void FunctionsGL::initializeProcsGLES()
+{
+ // No profiles in GLES
+ profile = 0;
+
+ // clang-format off
+
+ // GL_NV_path_rendering
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glMatrixLoadfEXT"), &matrixLoadEXT);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glGenPathsNV"), &genPathsNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glDeletePathsNV"), &delPathsNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glPathCommandsNV"), &pathCommandsNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glIsPathNV"), &isPathNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glPathParameterfNV"), &setPathParameterfNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glPathParameteriNV"), &setPathParameteriNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glGetPathParameterfvNV"), &getPathParameterfNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glGetPathParameterivNV"), &getPathParameteriNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glPathStencilFuncNV"), &pathStencilFuncNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilFillPathNV"), &stencilFillPathNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilStrokePathNV"), &stencilStrokePathNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glCoverFillPathNV"), &coverFillPathNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glCoverStrokePathNV"), &coverStrokePathNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilThenCoverFillPathNV"), &stencilThenCoverFillPathNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilThenCoverStrokePathNV"), &stencilThenCoverStrokePathNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glCoverFillPathInstancedNV"), &coverFillPathInstancedNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glCoverStrokePathInstancedNV"), &coverStrokePathInstancedNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilFillPathInstancedNV"), &stencilFillPathInstancedNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilStrokePathInstancedNV"), &stencilStrokePathInstancedNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilThenCoverFillPathInstancedNV"), &stencilThenCoverFillPathInstancedNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilThenCoverStrokePathInstancedNV"), &stencilThenCoverStrokePathInstancedNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glProgramPathFragmentInputGenNV"), &programPathFragmentInputGenNV);
+
+ // GL_OES_texture_3D
+ AssignGLExtensionEntryPoint(extensions, "GL_OES_texture_3D", loadProcAddress("glTexImage3DOES"), &texImage3D);
+ AssignGLExtensionEntryPoint(extensions, "GL_OES_texture_3D", loadProcAddress("glTexSubImage3DOES"), &texSubImage3D);
+ AssignGLExtensionEntryPoint(extensions, "GL_OES_texture_3D", loadProcAddress("glCopyTexSubImage3DOES"), &copyTexSubImage3D);
+
+ // GL_NV_framebuffer_mixed_samples
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_framebuffer_mixed_samples", loadProcAddress("glCoverageModulationNV"), &coverageModulationNV);
+
+ // GL_NV_fence
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glDeleteFencesNV"), &deleteFencesNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glGenFencesNV"), &genFencesNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glIsFenceNV"), &isFenceNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glTestFenceNV"), &testFenceNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glGetFenceivNV"), &getFenceivNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glFinishFenceNV"), &finishFenceNV);
+ AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glSetFenceNV"), &setFenceNV);
+
+ // GL_EXT_texture_storage
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_texture_storage", loadProcAddress("glTexStorage2DEXT"), &texStorage2D);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_texture_storage GL_OES_texture3D", loadProcAddress("glTexStorage3DEXT"), &texStorage3D);
+
+ // GL_OES_vertex_array_object
+ AssignGLExtensionEntryPoint(extensions, "GL_OES_vertex_array_object", loadProcAddress("glBindVertexArray"), &bindVertexArray);
+ AssignGLExtensionEntryPoint(extensions, "GL_OES_vertex_array_object", loadProcAddress("glDeleteVertexArrays"), &deleteVertexArrays);
+ AssignGLExtensionEntryPoint(extensions, "GL_OES_vertex_array_object", loadProcAddress("glGenVertexArrays"), &genVertexArrays);
+ AssignGLExtensionEntryPoint(extensions, "GL_OES_vertex_array_object", loadProcAddress("glIsVertexArray"), &isVertexArray);
+
+ // GL_EXT_map_buffer_range
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_map_buffer_range", loadProcAddress("glMapBufferRangeEXT"), &mapBufferRange);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_map_buffer_range", loadProcAddress("glFlushMappedBufferRangeEXT"), &flushMappedBufferRange);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_map_buffer_range", loadProcAddress("glUnmapBufferOES"), &unmapBuffer);
+
+ // GL_OES_mapbuffer
+ AssignGLExtensionEntryPoint(extensions, "GL_OES_mapbuffer", loadProcAddress("glMapBufferOES"), &mapBuffer);
+ AssignGLExtensionEntryPoint(extensions, "GL_OES_mapbuffer", loadProcAddress("glUnmapBufferOES"), &unmapBuffer);
+
+ // GL_KHR_debug
+ AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glDebugMessageControlKHR"), &debugMessageControl);
+ AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glDebugMessageInsertKHR"), &debugMessageInsert);
+ AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glDebugMessageCallbackKHR"), &debugMessageCallback);
+ AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glGetDebugMessageLogKHR"), &getDebugMessageLog);
+ AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glGetPointervKHR"), &getPointerv);
+ AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glPushDebugGroupKHR"), &pushDebugGroup);
+ AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glPopDebugGroupKHR"), &popDebugGroup);
+ AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glObjectLabelKHR"), &objectLabel);
+ AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glGetObjectLabelKHR"), &getObjectLabel);
+ AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glObjectPtrLabelKHR"), &objectPtrLabel);
+ AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glGetObjectPtrLabelKHR"), &getObjectPtrLabel);
+
+ // GL_EXT_draw_instanced
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_draw_instanced", loadProcAddress("glVertexAttribDivisorEXT"), &vertexAttribDivisor);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_draw_instanced", loadProcAddress("glDrawArraysInstancedEXT"), &drawArraysInstanced);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_draw_instanced", loadProcAddress("glDrawElementsInstancedEXT"), &drawElementsInstanced);
+
+ // GL_EXT_occlusion_query_boolean
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_occlusion_query_boolean", loadProcAddress("glGenQueriesEXT"), &genQueries);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_occlusion_query_boolean", loadProcAddress("glDeleteQueriesEXT"), &deleteQueries);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_occlusion_query_boolean", loadProcAddress("glIsQueryEXT"), &isQuery);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_occlusion_query_boolean", loadProcAddress("glBeginQueryEXT"), &beginQuery);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_occlusion_query_boolean", loadProcAddress("glEndQueryEXT"), &endQuery);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_occlusion_query_boolean", loadProcAddress("glGetQueryivEXT"), &getQueryiv);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_occlusion_query_boolean", loadProcAddress("glGetQueryObjectuivEXT"), &getQueryObjectuiv);
+
+ // GL_EXT_disjoint_timer_query
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_disjoint_timer_query", loadProcAddress("glGenQueriesEXT"), &genQueries);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_disjoint_timer_query", loadProcAddress("glDeleteQueriesEXT"), &deleteQueries);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_disjoint_timer_query", loadProcAddress("glIsQueryEXT"), &isQuery);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_disjoint_timer_query", loadProcAddress("glBeginQueryEXT"), &beginQuery);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_disjoint_timer_query", loadProcAddress("glEndQueryEXT"), &endQuery);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_disjoint_timer_query", loadProcAddress("glQueryCounterEXT"), &queryCounter);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_disjoint_timer_query", loadProcAddress("glGetQueryivEXT"), &getQueryiv);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_disjoint_timer_query", loadProcAddress("glGetQueryObjectivEXT"), &getQueryObjectiv);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_disjoint_timer_query", loadProcAddress("glGetQueryObjectuivEXT"), &getQueryObjectuiv);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_disjoint_timer_query", loadProcAddress("glGetQueryObjecti64vEXT"), &getQueryObjecti64v);
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_disjoint_timer_query", loadProcAddress("glGetQueryObjectui64vEXT"), &getQueryObjectui64v);
+
+ // GL_OES_EGL_image
+ AssignGLExtensionEntryPoint(extensions, "GL_OES_EGL_image", loadProcAddress("glEGLImageTargetRenderbufferStorageOES"), &eglImageTargetRenderbufferStorageOES);
+ AssignGLExtensionEntryPoint(extensions, "GL_OES_EGL_image", loadProcAddress("glEGLImageTargetTexture2DOES"), &eglImageTargetTexture2DOES);
+
+ // GL_OES_get_program_binary
+ AssignGLExtensionEntryPoint(extensions, "GL_OES_get_program_binary", loadProcAddress("glGetProgramBinaryOES"), &getProgramBinary);
+ AssignGLExtensionEntryPoint(extensions, "GL_OES_get_program_binary", loadProcAddress("glProgramBinaryOES"), &programBinary);
+
+ // GL_EXT_robustness
+ AssignGLExtensionEntryPoint(extensions, "GL_EXT_robustness", loadProcAddress("glGetGraphicsResetStatusEXT"), &getGraphicsResetStatus);
+
+ // GL_KHR_robustness
+ AssignGLExtensionEntryPoint(extensions, "GL_KHR_robustness", loadProcAddress("glGetGraphicsResetStatusKHR"), &getGraphicsResetStatus);
+
+ // 2.0
+ if (isAtLeastGLES(gl::Version(2, 0)))
+ {
+ AssignGLEntryPoint(loadProcAddress("glActiveTexture"), &activeTexture);
+ AssignGLEntryPoint(loadProcAddress("glAttachShader"), &attachShader);
+ AssignGLEntryPoint(loadProcAddress("glBindAttribLocation"), &bindAttribLocation);
+ AssignGLEntryPoint(loadProcAddress("glBindBuffer"), &bindBuffer);
+ AssignGLEntryPoint(loadProcAddress("glBindFramebuffer"), &bindFramebuffer);
+ AssignGLEntryPoint(loadProcAddress("glBindRenderbuffer"), &bindRenderbuffer);
+ AssignGLEntryPoint(loadProcAddress("glBindTexture"), &bindTexture);
+ AssignGLEntryPoint(loadProcAddress("glBlendColor"), &blendColor);
+ AssignGLEntryPoint(loadProcAddress("glBlendEquation"), &blendEquation);
+ AssignGLEntryPoint(loadProcAddress("glBlendEquationSeparate"), &blendEquationSeparate);
+ AssignGLEntryPoint(loadProcAddress("glBlendFunc"), &blendFunc);
+ AssignGLEntryPoint(loadProcAddress("glBlendFuncSeparate"), &blendFuncSeparate);
+ AssignGLEntryPoint(loadProcAddress("glBufferData"), &bufferData);
+ AssignGLEntryPoint(loadProcAddress("glBufferSubData"), &bufferSubData);
+ AssignGLEntryPoint(loadProcAddress("glCheckFramebufferStatus"), &checkFramebufferStatus);
+ AssignGLEntryPoint(loadProcAddress("glClear"), &clear);
+ AssignGLEntryPoint(loadProcAddress("glClearColor"), &clearColor);
+ AssignGLEntryPoint(loadProcAddress("glClearDepthf"), &clearDepthf);
+ AssignGLEntryPoint(loadProcAddress("glClearStencil"), &clearStencil);
+ AssignGLEntryPoint(loadProcAddress("glColorMask"), &colorMask);
+ AssignGLEntryPoint(loadProcAddress("glCompileShader"), &compileShader);
+ AssignGLEntryPoint(loadProcAddress("glCompressedTexImage2D"), &compressedTexImage2D);
+ AssignGLEntryPoint(loadProcAddress("glCompressedTexSubImage2D"), &compressedTexSubImage2D);
+ AssignGLEntryPoint(loadProcAddress("glCopyTexImage2D"), &copyTexImage2D);
+ AssignGLEntryPoint(loadProcAddress("glCopyTexSubImage2D"), &copyTexSubImage2D);
+ AssignGLEntryPoint(loadProcAddress("glCreateProgram"), &createProgram);
+ AssignGLEntryPoint(loadProcAddress("glCreateShader"), &createShader);
+ AssignGLEntryPoint(loadProcAddress("glCullFace"), &cullFace);
+ AssignGLEntryPoint(loadProcAddress("glDeleteBuffers"), &deleteBuffers);
+ AssignGLEntryPoint(loadProcAddress("glDeleteFramebuffers"), &deleteFramebuffers);
+ AssignGLEntryPoint(loadProcAddress("glDeleteProgram"), &deleteProgram);
+ AssignGLEntryPoint(loadProcAddress("glDeleteRenderbuffers"), &deleteRenderbuffers);
+ AssignGLEntryPoint(loadProcAddress("glDeleteShader"), &deleteShader);
+ AssignGLEntryPoint(loadProcAddress("glDeleteTextures"), &deleteTextures);
+ AssignGLEntryPoint(loadProcAddress("glDepthFunc"), &depthFunc);
+ AssignGLEntryPoint(loadProcAddress("glDepthMask"), &depthMask);
+ AssignGLEntryPoint(loadProcAddress("glDepthRangef"), &depthRangef);
+ AssignGLEntryPoint(loadProcAddress("glDetachShader"), &detachShader);
+ AssignGLEntryPoint(loadProcAddress("glDisable"), &disable);
+ AssignGLEntryPoint(loadProcAddress("glDisableVertexAttribArray"), &disableVertexAttribArray);
+ AssignGLEntryPoint(loadProcAddress("glDrawArrays"), &drawArrays);
+ AssignGLEntryPoint(loadProcAddress("glDrawElements"), &drawElements);
+ AssignGLEntryPoint(loadProcAddress("glEnable"), &enable);
+ AssignGLEntryPoint(loadProcAddress("glEnableVertexAttribArray"), &enableVertexAttribArray);
+ AssignGLEntryPoint(loadProcAddress("glFinish"), &finish);
+ AssignGLEntryPoint(loadProcAddress("glFlush"), &flush);
+ AssignGLEntryPoint(loadProcAddress("glFramebufferRenderbuffer"), &framebufferRenderbuffer);
+ AssignGLEntryPoint(loadProcAddress("glFramebufferTexture2D"), &framebufferTexture2D);
+ AssignGLEntryPoint(loadProcAddress("glFrontFace"), &frontFace);
+ AssignGLEntryPoint(loadProcAddress("glGenBuffers"), &genBuffers);
+ AssignGLEntryPoint(loadProcAddress("glGenerateMipmap"), &generateMipmap);
+ AssignGLEntryPoint(loadProcAddress("glGenFramebuffers"), &genFramebuffers);
+ AssignGLEntryPoint(loadProcAddress("glGenRenderbuffers"), &genRenderbuffers);
+ AssignGLEntryPoint(loadProcAddress("glGenTextures"), &genTextures);
+ AssignGLEntryPoint(loadProcAddress("glGetActiveAttrib"), &getActiveAttrib);
+ AssignGLEntryPoint(loadProcAddress("glGetActiveUniform"), &getActiveUniform);
+ AssignGLEntryPoint(loadProcAddress("glGetAttachedShaders"), &getAttachedShaders);
+ AssignGLEntryPoint(loadProcAddress("glGetAttribLocation"), &getAttribLocation);
+ AssignGLEntryPoint(loadProcAddress("glGetBooleanv"), &getBooleanv);
+ AssignGLEntryPoint(loadProcAddress("glGetBufferParameteriv"), &getBufferParameteriv);
+ AssignGLEntryPoint(loadProcAddress("glGetError"), &getError);
+ AssignGLEntryPoint(loadProcAddress("glGetFloatv"), &getFloatv);
+ AssignGLEntryPoint(loadProcAddress("glGetFramebufferAttachmentParameteriv"), &getFramebufferAttachmentParameteriv);
+ AssignGLEntryPoint(loadProcAddress("glGetIntegerv"), &getIntegerv);
+ AssignGLEntryPoint(loadProcAddress("glGetProgramiv"), &getProgramiv);
+ AssignGLEntryPoint(loadProcAddress("glGetProgramInfoLog"), &getProgramInfoLog);
+ AssignGLEntryPoint(loadProcAddress("glGetRenderbufferParameteriv"), &getRenderbufferParameteriv);
+ AssignGLEntryPoint(loadProcAddress("glGetShaderiv"), &getShaderiv);
+ AssignGLEntryPoint(loadProcAddress("glGetShaderInfoLog"), &getShaderInfoLog);
+ AssignGLEntryPoint(loadProcAddress("glGetShaderPrecisionFormat"), &getShaderPrecisionFormat);
+ AssignGLEntryPoint(loadProcAddress("glGetShaderSource"), &getShaderSource);
+ AssignGLEntryPoint(loadProcAddress("glGetString"), &getString);
+ AssignGLEntryPoint(loadProcAddress("glGetTexParameterfv"), &getTexParameterfv);
+ AssignGLEntryPoint(loadProcAddress("glGetTexParameteriv"), &getTexParameteriv);
+ AssignGLEntryPoint(loadProcAddress("glGetUniformfv"), &getUniformfv);
+ AssignGLEntryPoint(loadProcAddress("glGetUniformiv"), &getUniformiv);
+ AssignGLEntryPoint(loadProcAddress("glGetUniformLocation"), &getUniformLocation);
+ AssignGLEntryPoint(loadProcAddress("glGetVertexAttribfv"), &getVertexAttribfv);
+ AssignGLEntryPoint(loadProcAddress("glGetVertexAttribiv"), &getVertexAttribiv);
+ AssignGLEntryPoint(loadProcAddress("glGetVertexAttribPointerv"), &getVertexAttribPointerv);
+ AssignGLEntryPoint(loadProcAddress("glHint"), &hint);
+ AssignGLEntryPoint(loadProcAddress("glIsBuffer"), &isBuffer);
+ AssignGLEntryPoint(loadProcAddress("glIsEnabled"), &isEnabled);
+ AssignGLEntryPoint(loadProcAddress("glIsFramebuffer"), &isFramebuffer);
+ AssignGLEntryPoint(loadProcAddress("glIsProgram"), &isProgram);
+ AssignGLEntryPoint(loadProcAddress("glIsRenderbuffer"), &isRenderbuffer);
+ AssignGLEntryPoint(loadProcAddress("glIsShader"), &isShader);
+ AssignGLEntryPoint(loadProcAddress("glIsTexture"), &isTexture);
+ AssignGLEntryPoint(loadProcAddress("glLineWidth"), &lineWidth);
+ AssignGLEntryPoint(loadProcAddress("glLinkProgram"), &linkProgram);
+ AssignGLEntryPoint(loadProcAddress("glPixelStorei"), &pixelStorei);
+ AssignGLEntryPoint(loadProcAddress("glPolygonOffset"), &polygonOffset);
+ AssignGLEntryPoint(loadProcAddress("glReadPixels"), &readPixels);
+ AssignGLEntryPoint(loadProcAddress("glReleaseShaderCompiler"), &releaseShaderCompiler);
+ AssignGLEntryPoint(loadProcAddress("glRenderbufferStorage"), &renderbufferStorage);
+ AssignGLEntryPoint(loadProcAddress("glSampleCoverage"), &sampleCoverage);
+ AssignGLEntryPoint(loadProcAddress("glScissor"), &scissor);
+ AssignGLEntryPoint(loadProcAddress("glShaderBinary"), &shaderBinary);
+ AssignGLEntryPoint(loadProcAddress("glShaderSource"), &shaderSource);
+ AssignGLEntryPoint(loadProcAddress("glStencilFunc"), &stencilFunc);
+ AssignGLEntryPoint(loadProcAddress("glStencilFuncSeparate"), &stencilFuncSeparate);
+ AssignGLEntryPoint(loadProcAddress("glStencilMask"), &stencilMask);
+ AssignGLEntryPoint(loadProcAddress("glStencilMaskSeparate"), &stencilMaskSeparate);
+ AssignGLEntryPoint(loadProcAddress("glStencilOp"), &stencilOp);
+ AssignGLEntryPoint(loadProcAddress("glStencilOpSeparate"), &stencilOpSeparate);
+ AssignGLEntryPoint(loadProcAddress("glTexImage2D"), &texImage2D);
+ AssignGLEntryPoint(loadProcAddress("glTexParameterf"), &texParameterf);
+ AssignGLEntryPoint(loadProcAddress("glTexParameterfv"), &texParameterfv);
+ AssignGLEntryPoint(loadProcAddress("glTexParameteri"), &texParameteri);
+ AssignGLEntryPoint(loadProcAddress("glTexParameteriv"), &texParameteriv);
+ AssignGLEntryPoint(loadProcAddress("glTexSubImage2D"), &texSubImage2D);
+ AssignGLEntryPoint(loadProcAddress("glUniform1f"), &uniform1f);
+ AssignGLEntryPoint(loadProcAddress("glUniform1fv"), &uniform1fv);
+ AssignGLEntryPoint(loadProcAddress("glUniform1i"), &uniform1i);
+ AssignGLEntryPoint(loadProcAddress("glUniform1iv"), &uniform1iv);
+ AssignGLEntryPoint(loadProcAddress("glUniform2f"), &uniform2f);
+ AssignGLEntryPoint(loadProcAddress("glUniform2fv"), &uniform2fv);
+ AssignGLEntryPoint(loadProcAddress("glUniform2i"), &uniform2i);
+ AssignGLEntryPoint(loadProcAddress("glUniform2iv"), &uniform2iv);
+ AssignGLEntryPoint(loadProcAddress("glUniform3f"), &uniform3f);
+ AssignGLEntryPoint(loadProcAddress("glUniform3fv"), &uniform3fv);
+ AssignGLEntryPoint(loadProcAddress("glUniform3i"), &uniform3i);
+ AssignGLEntryPoint(loadProcAddress("glUniform3iv"), &uniform3iv);
+ AssignGLEntryPoint(loadProcAddress("glUniform4f"), &uniform4f);
+ AssignGLEntryPoint(loadProcAddress("glUniform4fv"), &uniform4fv);
+ AssignGLEntryPoint(loadProcAddress("glUniform4i"), &uniform4i);
+ AssignGLEntryPoint(loadProcAddress("glUniform4iv"), &uniform4iv);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix2fv"), &uniformMatrix2fv);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix3fv"), &uniformMatrix3fv);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix4fv"), &uniformMatrix4fv);
+ AssignGLEntryPoint(loadProcAddress("glUseProgram"), &useProgram);
+ AssignGLEntryPoint(loadProcAddress("glValidateProgram"), &validateProgram);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib1f"), &vertexAttrib1f);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib1fv"), &vertexAttrib1fv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib2f"), &vertexAttrib2f);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib2fv"), &vertexAttrib2fv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib3f"), &vertexAttrib3f);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib3fv"), &vertexAttrib3fv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib4f"), &vertexAttrib4f);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttrib4fv"), &vertexAttrib4fv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribPointer"), &vertexAttribPointer);
+ AssignGLEntryPoint(loadProcAddress("glViewport"), &viewport);
+ }
+
+ // 3.0
+ if (isAtLeastGLES(gl::Version(3, 0)))
+ {
+ AssignGLEntryPoint(loadProcAddress("glReadBuffer"), &readBuffer);
+ AssignGLEntryPoint(loadProcAddress("glDrawRangeElements"), &drawRangeElements);
+ AssignGLEntryPoint(loadProcAddress("glTexImage3D"), &texImage3D);
+ AssignGLEntryPoint(loadProcAddress("glTexSubImage3D"), &texSubImage3D);
+ AssignGLEntryPoint(loadProcAddress("glCopyTexSubImage3D"), &copyTexSubImage3D);
+ AssignGLEntryPoint(loadProcAddress("glCompressedTexImage3D"), &compressedTexImage3D);
+ AssignGLEntryPoint(loadProcAddress("glCompressedTexSubImage3D"), &compressedTexSubImage3D);
+ AssignGLEntryPoint(loadProcAddress("glGenQueries"), &genQueries);
+ AssignGLEntryPoint(loadProcAddress("glDeleteQueries"), &deleteQueries);
+ AssignGLEntryPoint(loadProcAddress("glIsQuery"), &isQuery);
+ AssignGLEntryPoint(loadProcAddress("glBeginQuery"), &beginQuery);
+ AssignGLEntryPoint(loadProcAddress("glEndQuery"), &endQuery);
+ AssignGLEntryPoint(loadProcAddress("glGetQueryiv"), &getQueryiv);
+ AssignGLEntryPoint(loadProcAddress("glGetQueryObjectuiv"), &getQueryObjectuiv);
+ AssignGLEntryPoint(loadProcAddress("glUnmapBuffer"), &unmapBuffer);
+ AssignGLEntryPoint(loadProcAddress("glGetBufferPointerv"), &getBufferPointerv);
+ AssignGLEntryPoint(loadProcAddress("glDrawBuffers"), &drawBuffers);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix2x3fv"), &uniformMatrix2x3fv);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix3x2fv"), &uniformMatrix3x2fv);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix2x4fv"), &uniformMatrix2x4fv);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix4x2fv"), &uniformMatrix4x2fv);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix3x4fv"), &uniformMatrix3x4fv);
+ AssignGLEntryPoint(loadProcAddress("glUniformMatrix4x3fv"), &uniformMatrix4x3fv);
+ AssignGLEntryPoint(loadProcAddress("glBlitFramebuffer"), &blitFramebuffer);
+ AssignGLEntryPoint(loadProcAddress("glRenderbufferStorageMultisample"), &renderbufferStorageMultisample);
+ AssignGLEntryPoint(loadProcAddress("glFramebufferTextureLayer"), &framebufferTextureLayer);
+ AssignGLEntryPoint(loadProcAddress("glMapBufferRange"), &mapBufferRange);
+ AssignGLEntryPoint(loadProcAddress("glFlushMappedBufferRange"), &flushMappedBufferRange);
+ AssignGLEntryPoint(loadProcAddress("glBindVertexArray"), &bindVertexArray);
+ AssignGLEntryPoint(loadProcAddress("glDeleteVertexArrays"), &deleteVertexArrays);
+ AssignGLEntryPoint(loadProcAddress("glGenVertexArrays"), &genVertexArrays);
+ AssignGLEntryPoint(loadProcAddress("glIsVertexArray"), &isVertexArray);
+ AssignGLEntryPoint(loadProcAddress("glGetIntegeri_v"), &getIntegeri_v);
+ AssignGLEntryPoint(loadProcAddress("glBeginTransformFeedback"), &beginTransformFeedback);
+ AssignGLEntryPoint(loadProcAddress("glEndTransformFeedback"), &endTransformFeedback);
+ AssignGLEntryPoint(loadProcAddress("glBindBufferRange"), &bindBufferRange);
+ AssignGLEntryPoint(loadProcAddress("glBindBufferBase"), &bindBufferBase);
+ AssignGLEntryPoint(loadProcAddress("glTransformFeedbackVaryings"), &transformFeedbackVaryings);
+ AssignGLEntryPoint(loadProcAddress("glGetTransformFeedbackVarying"), &getTransformFeedbackVarying);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribIPointer"), &vertexAttribIPointer);
+ AssignGLEntryPoint(loadProcAddress("glGetVertexAttribIiv"), &getVertexAttribIiv);
+ AssignGLEntryPoint(loadProcAddress("glGetVertexAttribIuiv"), &getVertexAttribIuiv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribI4i"), &vertexAttribI4i);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribI4ui"), &vertexAttribI4ui);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribI4iv"), &vertexAttribI4iv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribI4uiv"), &vertexAttribI4uiv);
+ AssignGLEntryPoint(loadProcAddress("glGetUniformuiv"), &getUniformuiv);
+ AssignGLEntryPoint(loadProcAddress("glGetFragDataLocation"), &getFragDataLocation);
+ AssignGLEntryPoint(loadProcAddress("glUniform1ui"), &uniform1ui);
+ AssignGLEntryPoint(loadProcAddress("glUniform2ui"), &uniform2ui);
+ AssignGLEntryPoint(loadProcAddress("glUniform3ui"), &uniform3ui);
+ AssignGLEntryPoint(loadProcAddress("glUniform4ui"), &uniform4ui);
+ AssignGLEntryPoint(loadProcAddress("glUniform1uiv"), &uniform1uiv);
+ AssignGLEntryPoint(loadProcAddress("glUniform2uiv"), &uniform2uiv);
+ AssignGLEntryPoint(loadProcAddress("glUniform3uiv"), &uniform3uiv);
+ AssignGLEntryPoint(loadProcAddress("glUniform4uiv"), &uniform4uiv);
+ AssignGLEntryPoint(loadProcAddress("glClearBufferiv"), &clearBufferiv);
+ AssignGLEntryPoint(loadProcAddress("glClearBufferuiv"), &clearBufferuiv);
+ AssignGLEntryPoint(loadProcAddress("glClearBufferfv"), &clearBufferfv);
+ AssignGLEntryPoint(loadProcAddress("glClearBufferfi"), &clearBufferfi);
+ AssignGLEntryPoint(loadProcAddress("glGetStringi"), &getStringi);
+ AssignGLEntryPoint(loadProcAddress("glCopyBufferSubData"), &copyBufferSubData);
+ AssignGLEntryPoint(loadProcAddress("glGetUniformIndices"), &getUniformIndices);
+ AssignGLEntryPoint(loadProcAddress("glGetActiveUniformsiv"), &getActiveUniformsiv);
+ AssignGLEntryPoint(loadProcAddress("glGetUniformBlockIndex"), &getUniformBlockIndex);
+ AssignGLEntryPoint(loadProcAddress("glGetActiveUniformBlockiv"), &getActiveUniformBlockiv);
+ AssignGLEntryPoint(loadProcAddress("glGetActiveUniformBlockName"), &getActiveUniformBlockName);
+ AssignGLEntryPoint(loadProcAddress("glUniformBlockBinding"), &uniformBlockBinding);
+ AssignGLEntryPoint(loadProcAddress("glDrawArraysInstanced"), &drawArraysInstanced);
+ AssignGLEntryPoint(loadProcAddress("glDrawElementsInstanced"), &drawElementsInstanced);
+ AssignGLEntryPoint(loadProcAddress("glFenceSync"), &fenceSync);
+ AssignGLEntryPoint(loadProcAddress("glIsSync"), &isSync);
+ AssignGLEntryPoint(loadProcAddress("glDeleteSync"), &deleteSync);
+ AssignGLEntryPoint(loadProcAddress("glClientWaitSync"), &clientWaitSync);
+ AssignGLEntryPoint(loadProcAddress("glWaitSync"), &waitSync);
+ AssignGLEntryPoint(loadProcAddress("glGetInteger64v"), &getInteger64v);
+ AssignGLEntryPoint(loadProcAddress("glGetSynciv"), &getSynciv);
+ AssignGLEntryPoint(loadProcAddress("glGetInteger64i_v"), &getInteger64i_v);
+ AssignGLEntryPoint(loadProcAddress("glGetBufferParameteri64v"), &getBufferParameteri64v);
+ AssignGLEntryPoint(loadProcAddress("glGenSamplers"), &genSamplers);
+ AssignGLEntryPoint(loadProcAddress("glDeleteSamplers"), &deleteSamplers);
+ AssignGLEntryPoint(loadProcAddress("glIsSampler"), &isSampler);
+ AssignGLEntryPoint(loadProcAddress("glBindSampler"), &bindSampler);
+ AssignGLEntryPoint(loadProcAddress("glSamplerParameteri"), &samplerParameteri);
+ AssignGLEntryPoint(loadProcAddress("glSamplerParameteriv"), &samplerParameteriv);
+ AssignGLEntryPoint(loadProcAddress("glSamplerParameterf"), &samplerParameterf);
+ AssignGLEntryPoint(loadProcAddress("glSamplerParameterfv"), &samplerParameterfv);
+ AssignGLEntryPoint(loadProcAddress("glGetSamplerParameteriv"), &getSamplerParameteriv);
+ AssignGLEntryPoint(loadProcAddress("glGetSamplerParameterfv"), &getSamplerParameterfv);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribDivisor"), &vertexAttribDivisor);
+ AssignGLEntryPoint(loadProcAddress("glBindTransformFeedback"), &bindTransformFeedback);
+ AssignGLEntryPoint(loadProcAddress("glDeleteTransformFeedbacks"), &deleteTransformFeedbacks);
+ AssignGLEntryPoint(loadProcAddress("glGenTransformFeedbacks"), &genTransformFeedbacks);
+ AssignGLEntryPoint(loadProcAddress("glIsTransformFeedback"), &isTransformFeedback);
+ AssignGLEntryPoint(loadProcAddress("glPauseTransformFeedback"), &pauseTransformFeedback);
+ AssignGLEntryPoint(loadProcAddress("glResumeTransformFeedback"), &resumeTransformFeedback);
+ AssignGLEntryPoint(loadProcAddress("glGetProgramBinary"), &getProgramBinary);
+ AssignGLEntryPoint(loadProcAddress("glProgramBinary"), &programBinary);
+ AssignGLEntryPoint(loadProcAddress("glProgramParameteri"), &programParameteri);
+ AssignGLEntryPoint(loadProcAddress("glInvalidateFramebuffer"), &invalidateFramebuffer);
+ AssignGLEntryPoint(loadProcAddress("glInvalidateSubFramebuffer"), &invalidateSubFramebuffer);
+ AssignGLEntryPoint(loadProcAddress("glTexStorage2D"), &texStorage2D);
+ AssignGLEntryPoint(loadProcAddress("glTexStorage3D"), &texStorage3D);
+ AssignGLEntryPoint(loadProcAddress("glGetInternalformativ"), &getInternalformativ);
+ }
+
+ // 3.1
+ if (isAtLeastGLES(gl::Version(3, 1)))
+ {
+ AssignGLEntryPoint(loadProcAddress("glDispatchCompute"), &dispatchCompute);
+ AssignGLEntryPoint(loadProcAddress("glDispatchComputeIndirect"), &dispatchComputeIndirect);
+ AssignGLEntryPoint(loadProcAddress("glDrawArraysIndirect"), &drawArraysIndirect);
+ AssignGLEntryPoint(loadProcAddress("glDrawElementsIndirect"), &drawElementsIndirect);
+ AssignGLEntryPoint(loadProcAddress("glFramebufferParameteri"), &framebufferParameteri);
+ AssignGLEntryPoint(loadProcAddress("glGetFramebufferParameteriv"), &getFramebufferParameteriv);
+ AssignGLEntryPoint(loadProcAddress("glGetProgramInterfaceiv"), &getProgramInterfaceiv);
+ AssignGLEntryPoint(loadProcAddress("glGetProgramResourceIndex"), &getProgramResourceIndex);
+ AssignGLEntryPoint(loadProcAddress("glGetProgramResourceName"), &getProgramResourceName);
+ AssignGLEntryPoint(loadProcAddress("glGetProgramResourceiv"), &getProgramResourceiv);
+ AssignGLEntryPoint(loadProcAddress("glGetProgramResourceLocation"), &getProgramResourceLocation);
+ AssignGLEntryPoint(loadProcAddress("glUseProgramStages"), &useProgramStages);
+ AssignGLEntryPoint(loadProcAddress("glActiveShaderProgram"), &activeShaderProgram);
+ AssignGLEntryPoint(loadProcAddress("glCreateShaderProgramv"), &createShaderProgramv);
+ AssignGLEntryPoint(loadProcAddress("glBindProgramPipeline"), &bindProgramPipeline);
+ AssignGLEntryPoint(loadProcAddress("glDeleteProgramPipelines"), &deleteProgramPipelines);
+ AssignGLEntryPoint(loadProcAddress("glGenProgramPipelines"), &genProgramPipelines);
+ AssignGLEntryPoint(loadProcAddress("glIsProgramPipeline"), &isProgramPipeline);
+ AssignGLEntryPoint(loadProcAddress("glGetProgramPipelineiv"), &getProgramPipelineiv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform1i"), &programUniform1i);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform2i"), &programUniform2i);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform3i"), &programUniform3i);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform4i"), &programUniform4i);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform1ui"), &programUniform1ui);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform2ui"), &programUniform2ui);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform3ui"), &programUniform3ui);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform4ui"), &programUniform4ui);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform1f"), &programUniform1f);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform2f"), &programUniform2f);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform3f"), &programUniform3f);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform4f"), &programUniform4f);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform1iv"), &programUniform1iv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform2iv"), &programUniform2iv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform3iv"), &programUniform3iv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform4iv"), &programUniform4iv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform1uiv"), &programUniform1uiv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform2uiv"), &programUniform2uiv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform3uiv"), &programUniform3uiv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform4uiv"), &programUniform4uiv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform1fv"), &programUniform1fv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform2fv"), &programUniform2fv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform3fv"), &programUniform3fv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniform4fv"), &programUniform4fv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix2fv"), &programUniformMatrix2fv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix3fv"), &programUniformMatrix3fv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix4fv"), &programUniformMatrix4fv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix2x3fv"), &programUniformMatrix2x3fv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix3x2fv"), &programUniformMatrix3x2fv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix2x4fv"), &programUniformMatrix2x4fv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix4x2fv"), &programUniformMatrix4x2fv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix3x4fv"), &programUniformMatrix3x4fv);
+ AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix4x3fv"), &programUniformMatrix4x3fv);
+ AssignGLEntryPoint(loadProcAddress("glValidateProgramPipeline"), &validateProgramPipeline);
+ AssignGLEntryPoint(loadProcAddress("glGetProgramPipelineInfoLog"), &getProgramPipelineInfoLog);
+ AssignGLEntryPoint(loadProcAddress("glBindImageTexture"), &bindImageTexture);
+ AssignGLEntryPoint(loadProcAddress("glGetBooleani_v"), &getBooleani_v);
+ AssignGLEntryPoint(loadProcAddress("glMemoryBarrier"), &memoryBarrier);
+ AssignGLEntryPoint(loadProcAddress("glMemoryBarrierByRegion"), &memoryBarrierByRegion);
+ AssignGLEntryPoint(loadProcAddress("glTexStorage2DMultisample"), &texStorage2DMultisample);
+ AssignGLEntryPoint(loadProcAddress("glGetMultisamplefv"), &getMultisamplefv);
+ AssignGLEntryPoint(loadProcAddress("glSampleMaski"), &sampleMaski);
+ AssignGLEntryPoint(loadProcAddress("glGetTexLevelParameteriv"), &getTexLevelParameteriv);
+ AssignGLEntryPoint(loadProcAddress("glGetTexLevelParameterfv"), &getTexLevelParameterfv);
+ AssignGLEntryPoint(loadProcAddress("glBindVertexBuffer"), &bindVertexBuffer);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribFormat"), &vertexAttribFormat);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribIFormat"), &vertexAttribIFormat);
+ AssignGLEntryPoint(loadProcAddress("glVertexAttribBinding"), &vertexAttribBinding);
+ AssignGLEntryPoint(loadProcAddress("glVertexBindingDivisor"), &vertexBindingDivisor);
+ }
+
+ // 3.2
+ if (isAtLeastGLES(gl::Version(3, 2)))
+ {
+ AssignGLEntryPoint(loadProcAddress("glBlendBarrier"), &blendBarrier);
+ AssignGLEntryPoint(loadProcAddress("glCopyImageSubData"), &copyImageSubData);
+ AssignGLEntryPoint(loadProcAddress("glDebugMessageControl"), &debugMessageControl);
+ AssignGLEntryPoint(loadProcAddress("glDebugMessageInsert"), &debugMessageInsert);
+ AssignGLEntryPoint(loadProcAddress("glDebugMessageCallback"), &debugMessageCallback);
+ AssignGLEntryPoint(loadProcAddress("glGetDebugMessageLog"), &getDebugMessageLog);
+ AssignGLEntryPoint(loadProcAddress("glPushDebugGroup"), &pushDebugGroup);
+ AssignGLEntryPoint(loadProcAddress("glPopDebugGroup"), &popDebugGroup);
+ AssignGLEntryPoint(loadProcAddress("glObjectLabel"), &objectLabel);
+ AssignGLEntryPoint(loadProcAddress("glGetObjectLabel"), &getObjectLabel);
+ AssignGLEntryPoint(loadProcAddress("glObjectPtrLabel"), &objectPtrLabel);
+ AssignGLEntryPoint(loadProcAddress("glGetObjectPtrLabel"), &getObjectPtrLabel);
+ AssignGLEntryPoint(loadProcAddress("glGetPointerv"), &getPointerv);
+ AssignGLEntryPoint(loadProcAddress("glEnablei"), &enablei);
+ AssignGLEntryPoint(loadProcAddress("glDisablei"), &disablei);
+ AssignGLEntryPoint(loadProcAddress("glBlendEquationi"), &blendEquationi);
+ AssignGLEntryPoint(loadProcAddress("glBlendEquationSeparatei"), &blendEquationSeparatei);
+ AssignGLEntryPoint(loadProcAddress("glBlendFunci"), &blendFunci);
+ AssignGLEntryPoint(loadProcAddress("glBlendFuncSeparatei"), &blendFuncSeparatei);
+ AssignGLEntryPoint(loadProcAddress("glColorMaski"), &colorMaski);
+ AssignGLEntryPoint(loadProcAddress("glIsEnabledi"), &isEnabledi);
+ AssignGLEntryPoint(loadProcAddress("glDrawElementsBaseVertex"), &drawElementsBaseVertex);
+ AssignGLEntryPoint(loadProcAddress("glDrawRangeElementsBaseVertex"), &drawRangeElementsBaseVertex);
+ AssignGLEntryPoint(loadProcAddress("glDrawElementsInstancedBaseVertex"), &drawElementsInstancedBaseVertex);
+ AssignGLEntryPoint(loadProcAddress("glFramebufferTexture"), &framebufferTexture);
+ AssignGLEntryPoint(loadProcAddress("glPrimitiveBoundingBox"), &primitiveBoundingBox);
+ AssignGLEntryPoint(loadProcAddress("glGetGraphicsResetStatus"), &getGraphicsResetStatus);
+ AssignGLEntryPoint(loadProcAddress("glReadnPixels"), &readnPixels);
+ AssignGLEntryPoint(loadProcAddress("glGetnUniformfv"), &getnUniformfv);
+ AssignGLEntryPoint(loadProcAddress("glGetnUniformiv"), &getnUniformiv);
+ AssignGLEntryPoint(loadProcAddress("glGetnUniformuiv"), &getnUniformuiv);
+ AssignGLEntryPoint(loadProcAddress("glMinSampleShading"), &minSampleShading);
+ AssignGLEntryPoint(loadProcAddress("glPatchParameteri"), &patchParameteri);
+ AssignGLEntryPoint(loadProcAddress("glTexParameterIiv"), &texParameterIiv);
+ AssignGLEntryPoint(loadProcAddress("glTexParameterIuiv"), &texParameterIuiv);
+ AssignGLEntryPoint(loadProcAddress("glGetTexParameterIiv"), &getTexParameterIiv);
+ AssignGLEntryPoint(loadProcAddress("glGetTexParameterIuiv"), &getTexParameterIuiv);
+ AssignGLEntryPoint(loadProcAddress("glSamplerParameterIiv"), &samplerParameterIiv);
+ AssignGLEntryPoint(loadProcAddress("glSamplerParameterIuiv"), &samplerParameterIuiv);
+ AssignGLEntryPoint(loadProcAddress("glGetSamplerParameterIiv"), &getSamplerParameterIiv);
+ AssignGLEntryPoint(loadProcAddress("glGetSamplerParameterIuiv"), &getSamplerParameterIuiv);
+ AssignGLEntryPoint(loadProcAddress("glTexBuffer"), &texBuffer);
+ AssignGLEntryPoint(loadProcAddress("glTexBufferRange"), &texBufferRange);
+ AssignGLEntryPoint(loadProcAddress("glTexStorage3DMultisample"), &texStorage3DMultisample);
+ }
+
+ // clang-format on
+}
+
+bool FunctionsGL::isAtLeastGL(const gl::Version &glVersion) const
+{
+ return standard == STANDARD_GL_DESKTOP && version >= glVersion;
+}
+
+bool FunctionsGL::isAtMostGL(const gl::Version &glVersion) const
+{
+ return standard == STANDARD_GL_DESKTOP && glVersion >= version;
+}
+
+bool FunctionsGL::isAtLeastGLES(const gl::Version &glesVersion) const
+{
+ return standard == STANDARD_GL_ES && version >= glesVersion;
+}
+
+bool FunctionsGL::isAtMostGLES(const gl::Version &glesVersion) const
+{
+ return standard == STANDARD_GL_ES && glesVersion >= version;
+}
+
+bool FunctionsGL::hasExtension(const std::string &ext) const
+{
+ return std::find(extensions.begin(), extensions.end(), ext) != extensions.end();
+}
+
+bool FunctionsGL::hasGLExtension(const std::string &ext) const
+{
+ return standard == STANDARD_GL_DESKTOP && hasExtension(ext);
+}
+
+bool FunctionsGL::hasGLESExtension(const std::string &ext) const
+{
+ return standard == STANDARD_GL_ES && hasExtension(ext);
+}
+
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/FunctionsGL.h b/gfx/angle/src/libANGLE/renderer/gl/FunctionsGL.h
new file mode 100755
index 000000000..fa8634e57
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/FunctionsGL.h
@@ -0,0 +1,791 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FunctionsGL.h: Defines the FuntionsGL class to contain loaded GL functions
+
+#ifndef LIBANGLE_RENDERER_GL_FUNCTIONSGL_H_
+#define LIBANGLE_RENDERER_GL_FUNCTIONSGL_H_
+
+#include "common/debug.h"
+#include "libANGLE/Version.h"
+#include "libANGLE/renderer/gl/functionsgl_enums.h"
+#include "libANGLE/renderer/gl/functionsgl_typedefs.h"
+
+namespace rx
+{
+
+enum StandardGL
+{
+ STANDARD_GL_DESKTOP,
+ STANDARD_GL_ES,
+};
+
+class FunctionsGL
+{
+ public:
+ FunctionsGL();
+ virtual ~FunctionsGL();
+
+ void initialize();
+
+ // Version information
+ gl::Version version;
+ StandardGL standard;
+ GLint profile;
+ bool isAtLeastGL(const gl::Version &glVersion) const;
+ bool isAtMostGL(const gl::Version &glVersion) const;
+ bool isAtLeastGLES(const gl::Version &glesVersion) const;
+ bool isAtMostGLES(const gl::Version &glesVersion) const;
+
+ // Extensions
+ std::vector<std::string> extensions;
+ bool hasExtension(const std::string &ext) const;
+ bool hasGLExtension(const std::string &ext) const;
+ bool hasGLESExtension(const std::string &ext) const;
+
+ // Entry Points
+ // 1.0
+ PFNGLBLENDFUNCPROC blendFunc;
+ PFNGLCLEARPROC clear;
+ PFNGLCLEARCOLORPROC clearColor;
+ PFNGLCLEARDEPTHPROC clearDepth;
+ PFNGLCLEARSTENCILPROC clearStencil;
+ PFNGLCOLORMASKPROC colorMask;
+ PFNGLCULLFACEPROC cullFace;
+ PFNGLDEPTHFUNCPROC depthFunc;
+ PFNGLDEPTHMASKPROC depthMask;
+ PFNGLDEPTHRANGEPROC depthRange;
+ PFNGLDISABLEPROC disable;
+ PFNGLDRAWBUFFERPROC drawBuffer;
+ PFNGLENABLEPROC enable;
+ PFNGLFINISHPROC finish;
+ PFNGLFLUSHPROC flush;
+ PFNGLFRONTFACEPROC frontFace;
+ PFNGLGETBOOLEANVPROC getBooleanv;
+ PFNGLGETDOUBLEVPROC getDoublev;
+ PFNGLGETERRORPROC getError;
+ PFNGLGETFLOATVPROC getFloatv;
+ PFNGLGETINTEGERVPROC getIntegerv;
+ PFNGLGETSTRINGPROC getString;
+ PFNGLGETTEXIMAGEPROC getTexImage;
+ PFNGLGETTEXLEVELPARAMETERFVPROC getTexLevelParameterfv;
+ PFNGLGETTEXLEVELPARAMETERIVPROC getTexLevelParameteriv;
+ PFNGLGETTEXPARAMETERFVPROC getTexParameterfv;
+ PFNGLGETTEXPARAMETERIVPROC getTexParameteriv;
+ PFNGLHINTPROC hint;
+ PFNGLISENABLEDPROC isEnabled;
+ PFNGLLINEWIDTHPROC lineWidth;
+ PFNGLLOGICOPPROC logicOp;
+ PFNGLPIXELSTOREFPROC pixelStoref;
+ PFNGLPIXELSTOREIPROC pixelStorei;
+ PFNGLPOINTSIZEPROC pointSize;
+ PFNGLPOLYGONMODEPROC polygonMode;
+ PFNGLREADBUFFERPROC readBuffer;
+ PFNGLREADPIXELSPROC readPixels;
+ PFNGLSCISSORPROC scissor;
+ PFNGLSTENCILFUNCPROC stencilFunc;
+ PFNGLSTENCILMASKPROC stencilMask;
+ PFNGLSTENCILOPPROC stencilOp;
+ PFNGLTEXIMAGE1DPROC texImage1D;
+ PFNGLTEXIMAGE2DPROC texImage2D;
+ PFNGLTEXPARAMETERFPROC texParameterf;
+ PFNGLTEXPARAMETERFVPROC texParameterfv;
+ PFNGLTEXPARAMETERIPROC texParameteri;
+ PFNGLTEXPARAMETERIVPROC texParameteriv;
+ PFNGLVIEWPORTPROC viewport;
+
+ // 1.1
+ PFNGLBINDTEXTUREPROC bindTexture;
+ PFNGLCOPYTEXIMAGE1DPROC copyTexImage1D;
+ PFNGLCOPYTEXIMAGE2DPROC copyTexImage2D;
+ PFNGLCOPYTEXSUBIMAGE1DPROC copyTexSubImage1D;
+ PFNGLCOPYTEXSUBIMAGE2DPROC copyTexSubImage2D;
+ PFNGLDELETETEXTURESPROC deleteTextures;
+ PFNGLDRAWARRAYSPROC drawArrays;
+ PFNGLDRAWELEMENTSPROC drawElements;
+ PFNGLGENTEXTURESPROC genTextures;
+ PFNGLISTEXTUREPROC isTexture;
+ PFNGLPOLYGONOFFSETPROC polygonOffset;
+ PFNGLTEXSUBIMAGE1DPROC texSubImage1D;
+ PFNGLTEXSUBIMAGE2DPROC texSubImage2D;
+
+ // 1.2
+ PFNGLBLENDCOLORPROC blendColor;
+ PFNGLBLENDEQUATIONPROC blendEquation;
+ PFNGLCOPYTEXSUBIMAGE3DPROC copyTexSubImage3D;
+ PFNGLDRAWRANGEELEMENTSPROC drawRangeElements;
+ PFNGLTEXIMAGE3DPROC texImage3D;
+ PFNGLTEXSUBIMAGE3DPROC texSubImage3D;
+
+ // 1.2 Extensions
+ PFNGLDELETEFENCESNVPROC deleteFencesNV;
+ PFNGLGENFENCESNVPROC genFencesNV;
+ PFNGLISFENCENVPROC isFenceNV;
+ PFNGLTESTFENCENVPROC testFenceNV;
+ PFNGLGETFENCEIVNVPROC getFenceivNV;
+ PFNGLFINISHFENCENVPROC finishFenceNV;
+ PFNGLSETFENCENVPROC setFenceNV;
+
+ // 1.3
+ PFNGLACTIVETEXTUREPROC activeTexture;
+ PFNGLCOMPRESSEDTEXIMAGE1DPROC compressedTexImage1D;
+ PFNGLCOMPRESSEDTEXIMAGE2DPROC compressedTexImage2D;
+ PFNGLCOMPRESSEDTEXIMAGE3DPROC compressedTexImage3D;
+ PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC compressedTexSubImage1D;
+ PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC compressedTexSubImage2D;
+ PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC compressedTexSubImage3D;
+ PFNGLGETCOMPRESSEDTEXIMAGEPROC getCompressedTexImage;
+ PFNGLSAMPLECOVERAGEPROC sampleCoverage;
+
+ // 1.4
+ PFNGLBLENDFUNCSEPARATEPROC blendFuncSeparate;
+ PFNGLMULTIDRAWARRAYSPROC multiDrawArrays;
+ PFNGLMULTIDRAWELEMENTSPROC multiDrawElements;
+ PFNGLPOINTPARAMETERFPROC pointParameterf;
+ PFNGLPOINTPARAMETERFVPROC pointParameterfv;
+ PFNGLPOINTPARAMETERIPROC pointParameteri;
+ PFNGLPOINTPARAMETERIVPROC pointParameteriv;
+
+ // 1.5
+ PFNGLBEGINQUERYPROC beginQuery;
+ PFNGLBINDBUFFERPROC bindBuffer;
+ PFNGLBUFFERDATAPROC bufferData;
+ PFNGLBUFFERSUBDATAPROC bufferSubData;
+ PFNGLDELETEBUFFERSPROC deleteBuffers;
+ PFNGLDELETEQUERIESPROC deleteQueries;
+ PFNGLENDQUERYPROC endQuery;
+ PFNGLGENBUFFERSPROC genBuffers;
+ PFNGLGENQUERIESPROC genQueries;
+ PFNGLGETBUFFERPARAMETERIVPROC getBufferParameteriv;
+ PFNGLGETBUFFERPOINTERVPROC getBufferPointerv;
+ PFNGLGETBUFFERSUBDATAPROC getBufferSubData;
+ PFNGLGETQUERYOBJECTIVPROC getQueryObjectiv;
+ PFNGLGETQUERYOBJECTUIVPROC getQueryObjectuiv;
+ PFNGLGETQUERYIVPROC getQueryiv;
+ PFNGLISBUFFERPROC isBuffer;
+ PFNGLISQUERYPROC isQuery;
+ PFNGLMAPBUFFERPROC mapBuffer;
+ PFNGLUNMAPBUFFERPROC unmapBuffer;
+
+ // 2.0
+ PFNGLATTACHSHADERPROC attachShader;
+ PFNGLBINDATTRIBLOCATIONPROC bindAttribLocation;
+ PFNGLBLENDEQUATIONSEPARATEPROC blendEquationSeparate;
+ PFNGLCOMPILESHADERPROC compileShader;
+ PFNGLCREATEPROGRAMPROC createProgram;
+ PFNGLCREATESHADERPROC createShader;
+ PFNGLDELETEPROGRAMPROC deleteProgram;
+ PFNGLDELETESHADERPROC deleteShader;
+ PFNGLDETACHSHADERPROC detachShader;
+ PFNGLDISABLEVERTEXATTRIBARRAYPROC disableVertexAttribArray;
+ PFNGLDRAWBUFFERSPROC drawBuffers;
+ PFNGLENABLEVERTEXATTRIBARRAYPROC enableVertexAttribArray;
+ PFNGLGETACTIVEATTRIBPROC getActiveAttrib;
+ PFNGLGETACTIVEUNIFORMPROC getActiveUniform;
+ PFNGLGETATTACHEDSHADERSPROC getAttachedShaders;
+ PFNGLGETATTRIBLOCATIONPROC getAttribLocation;
+ PFNGLGETPROGRAMINFOLOGPROC getProgramInfoLog;
+ PFNGLGETPROGRAMIVPROC getProgramiv;
+ PFNGLGETSHADERINFOLOGPROC getShaderInfoLog;
+ PFNGLGETSHADERSOURCEPROC getShaderSource;
+ PFNGLGETSHADERIVPROC getShaderiv;
+ PFNGLGETUNIFORMLOCATIONPROC getUniformLocation;
+ PFNGLGETUNIFORMFVPROC getUniformfv;
+ PFNGLGETUNIFORMIVPROC getUniformiv;
+ PFNGLGETVERTEXATTRIBPOINTERVPROC getVertexAttribPointerv;
+ PFNGLGETVERTEXATTRIBDVPROC getVertexAttribdv;
+ PFNGLGETVERTEXATTRIBFVPROC getVertexAttribfv;
+ PFNGLGETVERTEXATTRIBIVPROC getVertexAttribiv;
+ PFNGLISPROGRAMPROC isProgram;
+ PFNGLISSHADERPROC isShader;
+ PFNGLLINKPROGRAMPROC linkProgram;
+ PFNGLSHADERSOURCEPROC shaderSource;
+ PFNGLSTENCILFUNCSEPARATEPROC stencilFuncSeparate;
+ PFNGLSTENCILMASKSEPARATEPROC stencilMaskSeparate;
+ PFNGLSTENCILOPSEPARATEPROC stencilOpSeparate;
+ PFNGLUNIFORM1FPROC uniform1f;
+ PFNGLUNIFORM1FVPROC uniform1fv;
+ PFNGLUNIFORM1IPROC uniform1i;
+ PFNGLUNIFORM1IVPROC uniform1iv;
+ PFNGLUNIFORM2FPROC uniform2f;
+ PFNGLUNIFORM2FVPROC uniform2fv;
+ PFNGLUNIFORM2IPROC uniform2i;
+ PFNGLUNIFORM2IVPROC uniform2iv;
+ PFNGLUNIFORM3FPROC uniform3f;
+ PFNGLUNIFORM3FVPROC uniform3fv;
+ PFNGLUNIFORM3IPROC uniform3i;
+ PFNGLUNIFORM3IVPROC uniform3iv;
+ PFNGLUNIFORM4FPROC uniform4f;
+ PFNGLUNIFORM4FVPROC uniform4fv;
+ PFNGLUNIFORM4IPROC uniform4i;
+ PFNGLUNIFORM4IVPROC uniform4iv;
+ PFNGLUNIFORMMATRIX2FVPROC uniformMatrix2fv;
+ PFNGLUNIFORMMATRIX3FVPROC uniformMatrix3fv;
+ PFNGLUNIFORMMATRIX4FVPROC uniformMatrix4fv;
+ PFNGLUSEPROGRAMPROC useProgram;
+ PFNGLVALIDATEPROGRAMPROC validateProgram;
+ PFNGLVERTEXATTRIB1DPROC vertexAttrib1d;
+ PFNGLVERTEXATTRIB1DVPROC vertexAttrib1dv;
+ PFNGLVERTEXATTRIB1FPROC vertexAttrib1f;
+ PFNGLVERTEXATTRIB1FVPROC vertexAttrib1fv;
+ PFNGLVERTEXATTRIB1SPROC vertexAttrib1s;
+ PFNGLVERTEXATTRIB1SVPROC vertexAttrib1sv;
+ PFNGLVERTEXATTRIB2DPROC vertexAttrib2d;
+ PFNGLVERTEXATTRIB2DVPROC vertexAttrib2dv;
+ PFNGLVERTEXATTRIB2FPROC vertexAttrib2f;
+ PFNGLVERTEXATTRIB2FVPROC vertexAttrib2fv;
+ PFNGLVERTEXATTRIB2SPROC vertexAttrib2s;
+ PFNGLVERTEXATTRIB2SVPROC vertexAttrib2sv;
+ PFNGLVERTEXATTRIB3DPROC vertexAttrib3d;
+ PFNGLVERTEXATTRIB3DVPROC vertexAttrib3dv;
+ PFNGLVERTEXATTRIB3FPROC vertexAttrib3f;
+ PFNGLVERTEXATTRIB3FVPROC vertexAttrib3fv;
+ PFNGLVERTEXATTRIB3SPROC vertexAttrib3s;
+ PFNGLVERTEXATTRIB3SVPROC vertexAttrib3sv;
+ PFNGLVERTEXATTRIB4NBVPROC vertexAttrib4Nbv;
+ PFNGLVERTEXATTRIB4NIVPROC vertexAttrib4Niv;
+ PFNGLVERTEXATTRIB4NSVPROC vertexAttrib4Nsv;
+ PFNGLVERTEXATTRIB4NUBPROC vertexAttrib4Nub;
+ PFNGLVERTEXATTRIB4NUBVPROC vertexAttrib4Nubv;
+ PFNGLVERTEXATTRIB4NUIVPROC vertexAttrib4Nuiv;
+ PFNGLVERTEXATTRIB4NUSVPROC vertexAttrib4Nusv;
+ PFNGLVERTEXATTRIB4BVPROC vertexAttrib4bv;
+ PFNGLVERTEXATTRIB4DPROC vertexAttrib4d;
+ PFNGLVERTEXATTRIB4DVPROC vertexAttrib4dv;
+ PFNGLVERTEXATTRIB4FPROC vertexAttrib4f;
+ PFNGLVERTEXATTRIB4FVPROC vertexAttrib4fv;
+ PFNGLVERTEXATTRIB4IVPROC vertexAttrib4iv;
+ PFNGLVERTEXATTRIB4SPROC vertexAttrib4s;
+ PFNGLVERTEXATTRIB4SVPROC vertexAttrib4sv;
+ PFNGLVERTEXATTRIB4UBVPROC vertexAttrib4ubv;
+ PFNGLVERTEXATTRIB4UIVPROC vertexAttrib4uiv;
+ PFNGLVERTEXATTRIB4USVPROC vertexAttrib4usv;
+ PFNGLVERTEXATTRIBPOINTERPROC vertexAttribPointer;
+
+ // 2.1
+ PFNGLUNIFORMMATRIX2X3FVPROC uniformMatrix2x3fv;
+ PFNGLUNIFORMMATRIX2X4FVPROC uniformMatrix2x4fv;
+ PFNGLUNIFORMMATRIX3X2FVPROC uniformMatrix3x2fv;
+ PFNGLUNIFORMMATRIX3X4FVPROC uniformMatrix3x4fv;
+ PFNGLUNIFORMMATRIX4X2FVPROC uniformMatrix4x2fv;
+ PFNGLUNIFORMMATRIX4X3FVPROC uniformMatrix4x3fv;
+
+ // 3.0
+ PFNGLBEGINCONDITIONALRENDERPROC beginConditionalRender;
+ PFNGLBEGINTRANSFORMFEEDBACKPROC beginTransformFeedback;
+ PFNGLBINDBUFFERBASEPROC bindBufferBase;
+ PFNGLBINDBUFFERRANGEPROC bindBufferRange;
+ PFNGLBINDFRAGDATALOCATIONPROC bindFragDataLocation;
+ PFNGLBINDFRAMEBUFFERPROC bindFramebuffer;
+ PFNGLBINDRENDERBUFFERPROC bindRenderbuffer;
+ PFNGLBINDVERTEXARRAYPROC bindVertexArray;
+ PFNGLBLITFRAMEBUFFERPROC blitFramebuffer;
+ PFNGLCHECKFRAMEBUFFERSTATUSPROC checkFramebufferStatus;
+ PFNGLCLAMPCOLORPROC clampColor;
+ PFNGLCLEARBUFFERFIPROC clearBufferfi;
+ PFNGLCLEARBUFFERFVPROC clearBufferfv;
+ PFNGLCLEARBUFFERIVPROC clearBufferiv;
+ PFNGLCLEARBUFFERUIVPROC clearBufferuiv;
+ PFNGLCOLORMASKIPROC colorMaski;
+ PFNGLDELETEFRAMEBUFFERSPROC deleteFramebuffers;
+ PFNGLDELETERENDERBUFFERSPROC deleteRenderbuffers;
+ PFNGLDELETEVERTEXARRAYSPROC deleteVertexArrays;
+ PFNGLDISABLEIPROC disablei;
+ PFNGLENABLEIPROC enablei;
+ PFNGLENDCONDITIONALRENDERPROC endConditionalRender;
+ PFNGLENDTRANSFORMFEEDBACKPROC endTransformFeedback;
+ PFNGLFLUSHMAPPEDBUFFERRANGEPROC flushMappedBufferRange;
+ PFNGLFRAMEBUFFERRENDERBUFFERPROC framebufferRenderbuffer;
+ PFNGLFRAMEBUFFERTEXTURE1DPROC framebufferTexture1D;
+ PFNGLFRAMEBUFFERTEXTURE2DPROC framebufferTexture2D;
+ PFNGLFRAMEBUFFERTEXTURE3DPROC framebufferTexture3D;
+ PFNGLFRAMEBUFFERTEXTURELAYERPROC framebufferTextureLayer;
+ PFNGLGENFRAMEBUFFERSPROC genFramebuffers;
+ PFNGLGENRENDERBUFFERSPROC genRenderbuffers;
+ PFNGLGENVERTEXARRAYSPROC genVertexArrays;
+ PFNGLGENERATEMIPMAPPROC generateMipmap;
+ PFNGLGETBOOLEANI_VPROC getBooleani_v;
+ PFNGLGETFRAGDATALOCATIONPROC getFragDataLocation;
+ PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC getFramebufferAttachmentParameteriv;
+ PFNGLGETINTEGERI_VPROC getIntegeri_v;
+ PFNGLGETRENDERBUFFERPARAMETERIVPROC getRenderbufferParameteriv;
+ PFNGLGETSTRINGIPROC getStringi;
+ PFNGLGETTEXPARAMETERIIVPROC getTexParameterIiv;
+ PFNGLGETTEXPARAMETERIUIVPROC getTexParameterIuiv;
+ PFNGLGETTRANSFORMFEEDBACKVARYINGPROC getTransformFeedbackVarying;
+ PFNGLGETUNIFORMUIVPROC getUniformuiv;
+ PFNGLGETVERTEXATTRIBIIVPROC getVertexAttribIiv;
+ PFNGLGETVERTEXATTRIBIUIVPROC getVertexAttribIuiv;
+ PFNGLISENABLEDIPROC isEnabledi;
+ PFNGLISFRAMEBUFFERPROC isFramebuffer;
+ PFNGLISRENDERBUFFERPROC isRenderbuffer;
+ PFNGLISVERTEXARRAYPROC isVertexArray;
+ PFNGLMAPBUFFERRANGEPROC mapBufferRange;
+ PFNGLRENDERBUFFERSTORAGEPROC renderbufferStorage;
+ PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC renderbufferStorageMultisample;
+ PFNGLTEXPARAMETERIIVPROC texParameterIiv;
+ PFNGLTEXPARAMETERIUIVPROC texParameterIuiv;
+ PFNGLTRANSFORMFEEDBACKVARYINGSPROC transformFeedbackVaryings;
+ PFNGLUNIFORM1UIPROC uniform1ui;
+ PFNGLUNIFORM1UIVPROC uniform1uiv;
+ PFNGLUNIFORM2UIPROC uniform2ui;
+ PFNGLUNIFORM2UIVPROC uniform2uiv;
+ PFNGLUNIFORM3UIPROC uniform3ui;
+ PFNGLUNIFORM3UIVPROC uniform3uiv;
+ PFNGLUNIFORM4UIPROC uniform4ui;
+ PFNGLUNIFORM4UIVPROC uniform4uiv;
+ PFNGLVERTEXATTRIBI1IPROC vertexAttribI1i;
+ PFNGLVERTEXATTRIBI1IVPROC vertexAttribI1iv;
+ PFNGLVERTEXATTRIBI1UIPROC vertexAttribI1ui;
+ PFNGLVERTEXATTRIBI1UIVPROC vertexAttribI1uiv;
+ PFNGLVERTEXATTRIBI2IPROC vertexAttribI2i;
+ PFNGLVERTEXATTRIBI2IVPROC vertexAttribI2iv;
+ PFNGLVERTEXATTRIBI2UIPROC vertexAttribI2ui;
+ PFNGLVERTEXATTRIBI2UIVPROC vertexAttribI2uiv;
+ PFNGLVERTEXATTRIBI3IPROC vertexAttribI3i;
+ PFNGLVERTEXATTRIBI3IVPROC vertexAttribI3iv;
+ PFNGLVERTEXATTRIBI3UIPROC vertexAttribI3ui;
+ PFNGLVERTEXATTRIBI3UIVPROC vertexAttribI3uiv;
+ PFNGLVERTEXATTRIBI4BVPROC vertexAttribI4bv;
+ PFNGLVERTEXATTRIBI4IPROC vertexAttribI4i;
+ PFNGLVERTEXATTRIBI4IVPROC vertexAttribI4iv;
+ PFNGLVERTEXATTRIBI4SVPROC vertexAttribI4sv;
+ PFNGLVERTEXATTRIBI4UBVPROC vertexAttribI4ubv;
+ PFNGLVERTEXATTRIBI4UIPROC vertexAttribI4ui;
+ PFNGLVERTEXATTRIBI4UIVPROC vertexAttribI4uiv;
+ PFNGLVERTEXATTRIBI4USVPROC vertexAttribI4usv;
+ PFNGLVERTEXATTRIBIPOINTERPROC vertexAttribIPointer;
+
+ // 3.1
+ PFNGLCOPYBUFFERSUBDATAPROC copyBufferSubData;
+ PFNGLDRAWARRAYSINSTANCEDPROC drawArraysInstanced;
+ PFNGLDRAWELEMENTSINSTANCEDPROC drawElementsInstanced;
+ PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC getActiveUniformBlockName;
+ PFNGLGETACTIVEUNIFORMBLOCKIVPROC getActiveUniformBlockiv;
+ PFNGLGETACTIVEUNIFORMNAMEPROC getActiveUniformName;
+ PFNGLGETACTIVEUNIFORMSIVPROC getActiveUniformsiv;
+ PFNGLGETUNIFORMBLOCKINDEXPROC getUniformBlockIndex;
+ PFNGLGETUNIFORMINDICESPROC getUniformIndices;
+ PFNGLPRIMITIVERESTARTINDEXPROC primitiveRestartIndex;
+ PFNGLTEXBUFFERPROC texBuffer;
+ PFNGLUNIFORMBLOCKBINDINGPROC uniformBlockBinding;
+
+ // 3.2
+ PFNGLCLIENTWAITSYNCPROC clientWaitSync;
+ PFNGLDELETESYNCPROC deleteSync;
+ PFNGLDRAWELEMENTSBASEVERTEXPROC drawElementsBaseVertex;
+ PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC drawElementsInstancedBaseVertex;
+ PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC drawRangeElementsBaseVertex;
+ PFNGLFENCESYNCPROC fenceSync;
+ PFNGLFRAMEBUFFERTEXTUREPROC framebufferTexture;
+ PFNGLGETBUFFERPARAMETERI64VPROC getBufferParameteri64v;
+ PFNGLGETINTEGER64I_VPROC getInteger64i_v;
+ PFNGLGETINTEGER64VPROC getInteger64v;
+ PFNGLGETMULTISAMPLEFVPROC getMultisamplefv;
+ PFNGLGETSYNCIVPROC getSynciv;
+ PFNGLISSYNCPROC isSync;
+ PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC multiDrawElementsBaseVertex;
+ PFNGLPROVOKINGVERTEXPROC provokingVertex;
+ PFNGLSAMPLEMASKIPROC sampleMaski;
+ PFNGLTEXIMAGE2DMULTISAMPLEPROC texImage2DMultisample;
+ PFNGLTEXIMAGE3DMULTISAMPLEPROC texImage3DMultisample;
+ PFNGLWAITSYNCPROC waitSync;
+
+ // NV_path_rendering (originally written against 3.2 compatibility profile)
+ PFNGLMATRIXLOADFEXTPROC matrixLoadEXT;
+ PFNGLGENPATHSNVPROC genPathsNV;
+ PFNGLDELETEPATHSNVPROC delPathsNV;
+ PFNGLPATHCOMMANDSNVPROC pathCommandsNV;
+ PFNGLISPATHNVPROC isPathNV;
+ PFNGLPATHPARAMETERFNVPROC setPathParameterfNV;
+ PFNGLPATHPARAMETERINVPROC setPathParameteriNV;
+ PFNGLGETPATHPARAMETERFVNVPROC getPathParameterfNV;
+ PFNGLGETPATHPARAMETERIVNVPROC getPathParameteriNV;
+ PFNGLPATHSTENCILFUNCNVPROC pathStencilFuncNV;
+ PFNGLSTENCILFILLPATHNVPROC stencilFillPathNV;
+ PFNGLSTENCILSTROKEPATHNVPROC stencilStrokePathNV;
+ PFNGLCOVERFILLPATHNVPROC coverFillPathNV;
+ PFNGLCOVERSTROKEPATHNVPROC coverStrokePathNV;
+ PFNGLSTENCILTHENCOVERFILLPATHNVPROC stencilThenCoverFillPathNV;
+ PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC stencilThenCoverStrokePathNV;
+ PFNGLCOVERFILLPATHINSTANCEDNVPROC coverFillPathInstancedNV;
+ PFNGLCOVERSTROKEPATHINSTANCEDNVPROC coverStrokePathInstancedNV;
+ PFNGLSTENCILFILLPATHINSTANCEDNVPROC stencilFillPathInstancedNV;
+ PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC stencilStrokePathInstancedNV;
+ PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC stencilThenCoverFillPathInstancedNV;
+ PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC stencilThenCoverStrokePathInstancedNV;
+ PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC programPathFragmentInputGenNV;
+
+ // 3.3
+ PFNGLBINDFRAGDATALOCATIONINDEXEDPROC bindFragDataLocationIndexed;
+ PFNGLBINDSAMPLERPROC bindSampler;
+ PFNGLDELETESAMPLERSPROC deleteSamplers;
+ PFNGLGENSAMPLERSPROC genSamplers;
+ PFNGLGETFRAGDATAINDEXPROC getFragDataIndex;
+ PFNGLGETQUERYOBJECTI64VPROC getQueryObjecti64v;
+ PFNGLGETQUERYOBJECTUI64VPROC getQueryObjectui64v;
+ PFNGLGETSAMPLERPARAMETERIIVPROC getSamplerParameterIiv;
+ PFNGLGETSAMPLERPARAMETERIUIVPROC getSamplerParameterIuiv;
+ PFNGLGETSAMPLERPARAMETERFVPROC getSamplerParameterfv;
+ PFNGLGETSAMPLERPARAMETERIVPROC getSamplerParameteriv;
+ PFNGLISSAMPLERPROC isSampler;
+ PFNGLQUERYCOUNTERPROC queryCounter;
+ PFNGLSAMPLERPARAMETERIIVPROC samplerParameterIiv;
+ PFNGLSAMPLERPARAMETERIUIVPROC samplerParameterIuiv;
+ PFNGLSAMPLERPARAMETERFPROC samplerParameterf;
+ PFNGLSAMPLERPARAMETERFVPROC samplerParameterfv;
+ PFNGLSAMPLERPARAMETERIPROC samplerParameteri;
+ PFNGLSAMPLERPARAMETERIVPROC samplerParameteriv;
+ PFNGLVERTEXATTRIBDIVISORPROC vertexAttribDivisor;
+ PFNGLVERTEXATTRIBP1UIPROC vertexAttribP1ui;
+ PFNGLVERTEXATTRIBP1UIVPROC vertexAttribP1uiv;
+ PFNGLVERTEXATTRIBP2UIPROC vertexAttribP2ui;
+ PFNGLVERTEXATTRIBP2UIVPROC vertexAttribP2uiv;
+ PFNGLVERTEXATTRIBP3UIPROC vertexAttribP3ui;
+ PFNGLVERTEXATTRIBP3UIVPROC vertexAttribP3uiv;
+ PFNGLVERTEXATTRIBP4UIPROC vertexAttribP4ui;
+ PFNGLVERTEXATTRIBP4UIVPROC vertexAttribP4uiv;
+
+ // 4.0
+ PFNGLBEGINQUERYINDEXEDPROC beginQueryIndexed;
+ PFNGLBINDTRANSFORMFEEDBACKPROC bindTransformFeedback;
+ PFNGLBLENDEQUATIONSEPARATEIPROC blendEquationSeparatei;
+ PFNGLBLENDEQUATIONIPROC blendEquationi;
+ PFNGLBLENDFUNCSEPARATEIPROC blendFuncSeparatei;
+ PFNGLBLENDFUNCIPROC blendFunci;
+ PFNGLDELETETRANSFORMFEEDBACKSPROC deleteTransformFeedbacks;
+ PFNGLDRAWARRAYSINDIRECTPROC drawArraysIndirect;
+ PFNGLDRAWELEMENTSINDIRECTPROC drawElementsIndirect;
+ PFNGLDRAWTRANSFORMFEEDBACKPROC drawTransformFeedback;
+ PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC drawTransformFeedbackStream;
+ PFNGLENDQUERYINDEXEDPROC endQueryIndexed;
+ PFNGLGENTRANSFORMFEEDBACKSPROC genTransformFeedbacks;
+ PFNGLGETACTIVESUBROUTINENAMEPROC getActiveSubroutineName;
+ PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC getActiveSubroutineUniformName;
+ PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC getActiveSubroutineUniformiv;
+ PFNGLGETPROGRAMSTAGEIVPROC getProgramStageiv;
+ PFNGLGETQUERYINDEXEDIVPROC getQueryIndexediv;
+ PFNGLGETSUBROUTINEINDEXPROC getSubroutineIndex;
+ PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC getSubroutineUniformLocation;
+ PFNGLGETUNIFORMSUBROUTINEUIVPROC getUniformSubroutineuiv;
+ PFNGLGETUNIFORMDVPROC getUniformdv;
+ PFNGLISTRANSFORMFEEDBACKPROC isTransformFeedback;
+ PFNGLMINSAMPLESHADINGPROC minSampleShading;
+ PFNGLPATCHPARAMETERFVPROC patchParameterfv;
+ PFNGLPATCHPARAMETERIPROC patchParameteri;
+ PFNGLPAUSETRANSFORMFEEDBACKPROC pauseTransformFeedback;
+ PFNGLRESUMETRANSFORMFEEDBACKPROC resumeTransformFeedback;
+ PFNGLUNIFORM1DPROC uniform1d;
+ PFNGLUNIFORM1DVPROC uniform1dv;
+ PFNGLUNIFORM2DPROC uniform2d;
+ PFNGLUNIFORM2DVPROC uniform2dv;
+ PFNGLUNIFORM3DPROC uniform3d;
+ PFNGLUNIFORM3DVPROC uniform3dv;
+ PFNGLUNIFORM4DPROC uniform4d;
+ PFNGLUNIFORM4DVPROC uniform4dv;
+ PFNGLUNIFORMMATRIX2DVPROC uniformMatrix2dv;
+ PFNGLUNIFORMMATRIX2X3DVPROC uniformMatrix2x3dv;
+ PFNGLUNIFORMMATRIX2X4DVPROC uniformMatrix2x4dv;
+ PFNGLUNIFORMMATRIX3DVPROC uniformMatrix3dv;
+ PFNGLUNIFORMMATRIX3X2DVPROC uniformMatrix3x2dv;
+ PFNGLUNIFORMMATRIX3X4DVPROC uniformMatrix3x4dv;
+ PFNGLUNIFORMMATRIX4DVPROC uniformMatrix4dv;
+ PFNGLUNIFORMMATRIX4X2DVPROC uniformMatrix4x2dv;
+ PFNGLUNIFORMMATRIX4X3DVPROC uniformMatrix4x3dv;
+ PFNGLUNIFORMSUBROUTINESUIVPROC uniformSubroutinesuiv;
+
+ // 4.1
+ PFNGLACTIVESHADERPROGRAMPROC activeShaderProgram;
+ PFNGLBINDPROGRAMPIPELINEPROC bindProgramPipeline;
+ PFNGLCLEARDEPTHFPROC clearDepthf;
+ PFNGLCREATESHADERPROGRAMVPROC createShaderProgramv;
+ PFNGLDELETEPROGRAMPIPELINESPROC deleteProgramPipelines;
+ PFNGLDEPTHRANGEARRAYVPROC depthRangeArrayv;
+ PFNGLDEPTHRANGEINDEXEDPROC depthRangeIndexed;
+ PFNGLDEPTHRANGEFPROC depthRangef;
+ PFNGLGENPROGRAMPIPELINESPROC genProgramPipelines;
+ PFNGLGETDOUBLEI_VPROC getDoublei_v;
+ PFNGLGETFLOATI_VPROC getFloati_v;
+ PFNGLGETPROGRAMBINARYPROC getProgramBinary;
+ PFNGLGETPROGRAMPIPELINEINFOLOGPROC getProgramPipelineInfoLog;
+ PFNGLGETPROGRAMPIPELINEIVPROC getProgramPipelineiv;
+ PFNGLGETSHADERPRECISIONFORMATPROC getShaderPrecisionFormat;
+ PFNGLGETVERTEXATTRIBLDVPROC getVertexAttribLdv;
+ PFNGLISPROGRAMPIPELINEPROC isProgramPipeline;
+ PFNGLPROGRAMBINARYPROC programBinary;
+ PFNGLPROGRAMPARAMETERIPROC programParameteri;
+ PFNGLPROGRAMUNIFORM1DPROC programUniform1d;
+ PFNGLPROGRAMUNIFORM1DVPROC programUniform1dv;
+ PFNGLPROGRAMUNIFORM1FPROC programUniform1f;
+ PFNGLPROGRAMUNIFORM1FVPROC programUniform1fv;
+ PFNGLPROGRAMUNIFORM1IPROC programUniform1i;
+ PFNGLPROGRAMUNIFORM1IVPROC programUniform1iv;
+ PFNGLPROGRAMUNIFORM1UIPROC programUniform1ui;
+ PFNGLPROGRAMUNIFORM1UIVPROC programUniform1uiv;
+ PFNGLPROGRAMUNIFORM2DPROC programUniform2d;
+ PFNGLPROGRAMUNIFORM2DVPROC programUniform2dv;
+ PFNGLPROGRAMUNIFORM2FPROC programUniform2f;
+ PFNGLPROGRAMUNIFORM2FVPROC programUniform2fv;
+ PFNGLPROGRAMUNIFORM2IPROC programUniform2i;
+ PFNGLPROGRAMUNIFORM2IVPROC programUniform2iv;
+ PFNGLPROGRAMUNIFORM2UIPROC programUniform2ui;
+ PFNGLPROGRAMUNIFORM2UIVPROC programUniform2uiv;
+ PFNGLPROGRAMUNIFORM3DPROC programUniform3d;
+ PFNGLPROGRAMUNIFORM3DVPROC programUniform3dv;
+ PFNGLPROGRAMUNIFORM3FPROC programUniform3f;
+ PFNGLPROGRAMUNIFORM3FVPROC programUniform3fv;
+ PFNGLPROGRAMUNIFORM3IPROC programUniform3i;
+ PFNGLPROGRAMUNIFORM3IVPROC programUniform3iv;
+ PFNGLPROGRAMUNIFORM3UIPROC programUniform3ui;
+ PFNGLPROGRAMUNIFORM3UIVPROC programUniform3uiv;
+ PFNGLPROGRAMUNIFORM4DPROC programUniform4d;
+ PFNGLPROGRAMUNIFORM4DVPROC programUniform4dv;
+ PFNGLPROGRAMUNIFORM4FPROC programUniform4f;
+ PFNGLPROGRAMUNIFORM4FVPROC programUniform4fv;
+ PFNGLPROGRAMUNIFORM4IPROC programUniform4i;
+ PFNGLPROGRAMUNIFORM4IVPROC programUniform4iv;
+ PFNGLPROGRAMUNIFORM4UIPROC programUniform4ui;
+ PFNGLPROGRAMUNIFORM4UIVPROC programUniform4uiv;
+ PFNGLPROGRAMUNIFORMMATRIX2DVPROC programUniformMatrix2dv;
+ PFNGLPROGRAMUNIFORMMATRIX2FVPROC programUniformMatrix2fv;
+ PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC programUniformMatrix2x3dv;
+ PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC programUniformMatrix2x3fv;
+ PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC programUniformMatrix2x4dv;
+ PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC programUniformMatrix2x4fv;
+ PFNGLPROGRAMUNIFORMMATRIX3DVPROC programUniformMatrix3dv;
+ PFNGLPROGRAMUNIFORMMATRIX3FVPROC programUniformMatrix3fv;
+ PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC programUniformMatrix3x2dv;
+ PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC programUniformMatrix3x2fv;
+ PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC programUniformMatrix3x4dv;
+ PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC programUniformMatrix3x4fv;
+ PFNGLPROGRAMUNIFORMMATRIX4DVPROC programUniformMatrix4dv;
+ PFNGLPROGRAMUNIFORMMATRIX4FVPROC programUniformMatrix4fv;
+ PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC programUniformMatrix4x2dv;
+ PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC programUniformMatrix4x2fv;
+ PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC programUniformMatrix4x3dv;
+ PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC programUniformMatrix4x3fv;
+ PFNGLRELEASESHADERCOMPILERPROC releaseShaderCompiler;
+ PFNGLSCISSORARRAYVPROC scissorArrayv;
+ PFNGLSCISSORINDEXEDPROC scissorIndexed;
+ PFNGLSCISSORINDEXEDVPROC scissorIndexedv;
+ PFNGLSHADERBINARYPROC shaderBinary;
+ PFNGLUSEPROGRAMSTAGESPROC useProgramStages;
+ PFNGLVALIDATEPROGRAMPIPELINEPROC validateProgramPipeline;
+ PFNGLVERTEXATTRIBL1DPROC vertexAttribL1d;
+ PFNGLVERTEXATTRIBL1DVPROC vertexAttribL1dv;
+ PFNGLVERTEXATTRIBL2DPROC vertexAttribL2d;
+ PFNGLVERTEXATTRIBL2DVPROC vertexAttribL2dv;
+ PFNGLVERTEXATTRIBL3DPROC vertexAttribL3d;
+ PFNGLVERTEXATTRIBL3DVPROC vertexAttribL3dv;
+ PFNGLVERTEXATTRIBL4DPROC vertexAttribL4d;
+ PFNGLVERTEXATTRIBL4DVPROC vertexAttribL4dv;
+ PFNGLVERTEXATTRIBLPOINTERPROC vertexAttribLPointer;
+ PFNGLVIEWPORTARRAYVPROC viewportArrayv;
+ PFNGLVIEWPORTINDEXEDFPROC viewportIndexedf;
+ PFNGLVIEWPORTINDEXEDFVPROC viewportIndexedfv;
+
+ // 4.2
+ PFNGLBINDIMAGETEXTUREPROC bindImageTexture;
+ PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC drawArraysInstancedBaseInstance;
+ PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC drawElementsInstancedBaseInstance;
+ PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC drawElementsInstancedBaseVertexBaseInstance;
+ PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC drawTransformFeedbackInstanced;
+ PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC drawTransformFeedbackStreamInstanced;
+ PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC getActiveAtomicCounterBufferiv;
+ PFNGLGETINTERNALFORMATIVPROC getInternalformativ;
+ PFNGLMEMORYBARRIERPROC memoryBarrier;
+ PFNGLTEXSTORAGE1DPROC texStorage1D;
+ PFNGLTEXSTORAGE2DPROC texStorage2D;
+ PFNGLTEXSTORAGE3DPROC texStorage3D;
+
+ // 4.3
+ PFNGLBINDVERTEXBUFFERPROC bindVertexBuffer;
+ PFNGLCLEARBUFFERDATAPROC clearBufferData;
+ PFNGLCLEARBUFFERSUBDATAPROC clearBufferSubData;
+ PFNGLCOPYIMAGESUBDATAPROC copyImageSubData;
+ PFNGLDEBUGMESSAGECALLBACKPROC debugMessageCallback;
+ PFNGLDEBUGMESSAGECONTROLPROC debugMessageControl;
+ PFNGLDEBUGMESSAGEINSERTPROC debugMessageInsert;
+ PFNGLDISPATCHCOMPUTEPROC dispatchCompute;
+ PFNGLDISPATCHCOMPUTEINDIRECTPROC dispatchComputeIndirect;
+ PFNGLFRAMEBUFFERPARAMETERIPROC framebufferParameteri;
+ PFNGLGETDEBUGMESSAGELOGPROC getDebugMessageLog;
+ PFNGLGETFRAMEBUFFERPARAMETERIVPROC getFramebufferParameteriv;
+ PFNGLGETINTERNALFORMATI64VPROC getInternalformati64v;
+ PFNGLGETPOINTERVPROC getPointerv;
+ PFNGLGETOBJECTLABELPROC getObjectLabel;
+ PFNGLGETOBJECTPTRLABELPROC getObjectPtrLabel;
+ PFNGLGETPROGRAMINTERFACEIVPROC getProgramInterfaceiv;
+ PFNGLGETPROGRAMRESOURCEINDEXPROC getProgramResourceIndex;
+ PFNGLGETPROGRAMRESOURCELOCATIONPROC getProgramResourceLocation;
+ PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC getProgramResourceLocationIndex;
+ PFNGLGETPROGRAMRESOURCENAMEPROC getProgramResourceName;
+ PFNGLGETPROGRAMRESOURCEIVPROC getProgramResourceiv;
+ PFNGLINVALIDATEBUFFERDATAPROC invalidateBufferData;
+ PFNGLINVALIDATEBUFFERSUBDATAPROC invalidateBufferSubData;
+ PFNGLINVALIDATEFRAMEBUFFERPROC invalidateFramebuffer;
+ PFNGLINVALIDATESUBFRAMEBUFFERPROC invalidateSubFramebuffer;
+ PFNGLINVALIDATETEXIMAGEPROC invalidateTexImage;
+ PFNGLINVALIDATETEXSUBIMAGEPROC invalidateTexSubImage;
+ PFNGLMULTIDRAWARRAYSINDIRECTPROC multiDrawArraysIndirect;
+ PFNGLMULTIDRAWELEMENTSINDIRECTPROC multiDrawElementsIndirect;
+ PFNGLOBJECTLABELPROC objectLabel;
+ PFNGLOBJECTPTRLABELPROC objectPtrLabel;
+ PFNGLPOPDEBUGGROUPPROC popDebugGroup;
+ PFNGLPUSHDEBUGGROUPPROC pushDebugGroup;
+ PFNGLSHADERSTORAGEBLOCKBINDINGPROC shaderStorageBlockBinding;
+ PFNGLTEXBUFFERRANGEPROC texBufferRange;
+ PFNGLTEXSTORAGE2DMULTISAMPLEPROC texStorage2DMultisample;
+ PFNGLTEXSTORAGE3DMULTISAMPLEPROC texStorage3DMultisample;
+ PFNGLTEXTUREVIEWPROC textureView;
+ PFNGLVERTEXATTRIBBINDINGPROC vertexAttribBinding;
+ PFNGLVERTEXATTRIBFORMATPROC vertexAttribFormat;
+ PFNGLVERTEXATTRIBIFORMATPROC vertexAttribIFormat;
+ PFNGLVERTEXATTRIBLFORMATPROC vertexAttribLFormat;
+ PFNGLVERTEXBINDINGDIVISORPROC vertexBindingDivisor;
+ PFNGLCOVERAGEMODULATIONNVPROC coverageModulationNV;
+
+ // 4.4
+ PFNGLBINDBUFFERSBASEPROC bindBuffersBase;
+ PFNGLBINDBUFFERSRANGEPROC bindBuffersRange;
+ PFNGLBINDIMAGETEXTURESPROC bindImageTextures;
+ PFNGLBINDSAMPLERSPROC bindSamplers;
+ PFNGLBINDTEXTURESPROC bindTextures;
+ PFNGLBINDVERTEXBUFFERSPROC bindVertexBuffers;
+ PFNGLBUFFERSTORAGEPROC bufferStorage;
+ PFNGLCLEARTEXIMAGEPROC clearTexImage;
+ PFNGLCLEARTEXSUBIMAGEPROC clearTexSubImage;
+
+ // 4.5
+ PFNGLBINDTEXTUREUNITPROC bindTextureUnit;
+ PFNGLBLITNAMEDFRAMEBUFFERPROC blitNamedFramebuffer;
+ PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC checkNamedFramebufferStatus;
+ PFNGLCLEARNAMEDBUFFERDATAPROC clearNamedBufferData;
+ PFNGLCLEARNAMEDBUFFERSUBDATAPROC clearNamedBufferSubData;
+ PFNGLCLEARNAMEDFRAMEBUFFERFIPROC clearNamedFramebufferfi;
+ PFNGLCLEARNAMEDFRAMEBUFFERFVPROC clearNamedFramebufferfv;
+ PFNGLCLEARNAMEDFRAMEBUFFERIVPROC clearNamedFramebufferiv;
+ PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC clearNamedFramebufferuiv;
+ PFNGLCLIPCONTROLPROC clipControl;
+ PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC compressedTextureSubImage1D;
+ PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC compressedTextureSubImage2D;
+ PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC compressedTextureSubImage3D;
+ PFNGLCOPYNAMEDBUFFERSUBDATAPROC copyNamedBufferSubData;
+ PFNGLCOPYTEXTURESUBIMAGE1DPROC copyTextureSubImage1D;
+ PFNGLCOPYTEXTURESUBIMAGE2DPROC copyTextureSubImage2D;
+ PFNGLCOPYTEXTURESUBIMAGE3DPROC copyTextureSubImage3D;
+ PFNGLCREATEBUFFERSPROC createBuffers;
+ PFNGLCREATEFRAMEBUFFERSPROC createFramebuffers;
+ PFNGLCREATEPROGRAMPIPELINESPROC createProgramPipelines;
+ PFNGLCREATEQUERIESPROC createQueries;
+ PFNGLCREATERENDERBUFFERSPROC createRenderbuffers;
+ PFNGLCREATESAMPLERSPROC createSamplers;
+ PFNGLCREATETEXTURESPROC createTextures;
+ PFNGLCREATETRANSFORMFEEDBACKSPROC createTransformFeedbacks;
+ PFNGLCREATEVERTEXARRAYSPROC createVertexArrays;
+ PFNGLDISABLEVERTEXARRAYATTRIBPROC disableVertexArrayAttrib;
+ PFNGLENABLEVERTEXARRAYATTRIBPROC enableVertexArrayAttrib;
+ PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC flushMappedNamedBufferRange;
+ PFNGLGENERATETEXTUREMIPMAPPROC generateTextureMipmap;
+ PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC getCompressedTextureImage;
+ PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC getCompressedTextureSubImage;
+ PFNGLGETGRAPHICSRESETSTATUSPROC getGraphicsResetStatus;
+ PFNGLGETNAMEDBUFFERPARAMETERI64VPROC getNamedBufferParameteri64v;
+ PFNGLGETNAMEDBUFFERPARAMETERIVPROC getNamedBufferParameteriv;
+ PFNGLGETNAMEDBUFFERPOINTERVPROC getNamedBufferPointerv;
+ PFNGLGETNAMEDBUFFERSUBDATAPROC getNamedBufferSubData;
+ PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC getNamedFramebufferAttachmentParameteriv;
+ PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC getNamedFramebufferParameteriv;
+ PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC getNamedRenderbufferParameteriv;
+ PFNGLGETQUERYBUFFEROBJECTI64VPROC getQueryBufferObjecti64v;
+ PFNGLGETQUERYBUFFEROBJECTIVPROC getQueryBufferObjectiv;
+ PFNGLGETQUERYBUFFEROBJECTUI64VPROC getQueryBufferObjectui64v;
+ PFNGLGETQUERYBUFFEROBJECTUIVPROC getQueryBufferObjectuiv;
+ PFNGLGETTEXTUREIMAGEPROC getTextureImage;
+ PFNGLGETTEXTURELEVELPARAMETERFVPROC getTextureLevelParameterfv;
+ PFNGLGETTEXTURELEVELPARAMETERIVPROC getTextureLevelParameteriv;
+ PFNGLGETTEXTUREPARAMETERIIVPROC getTextureParameterIiv;
+ PFNGLGETTEXTUREPARAMETERIUIVPROC getTextureParameterIuiv;
+ PFNGLGETTEXTUREPARAMETERFVPROC getTextureParameterfv;
+ PFNGLGETTEXTUREPARAMETERIVPROC getTextureParameteriv;
+ PFNGLGETTEXTURESUBIMAGEPROC getTextureSubImage;
+ PFNGLGETTRANSFORMFEEDBACKI64_VPROC getTransformFeedbacki64_v;
+ PFNGLGETTRANSFORMFEEDBACKI_VPROC getTransformFeedbacki_v;
+ PFNGLGETTRANSFORMFEEDBACKIVPROC getTransformFeedbackiv;
+ PFNGLGETVERTEXARRAYINDEXED64IVPROC getVertexArrayIndexed64iv;
+ PFNGLGETVERTEXARRAYINDEXEDIVPROC getVertexArrayIndexediv;
+ PFNGLGETVERTEXARRAYIVPROC getVertexArrayiv;
+ PFNGLGETNCOMPRESSEDTEXIMAGEPROC getnCompressedTexImage;
+ PFNGLGETNTEXIMAGEPROC getnTexImage;
+ PFNGLGETNUNIFORMDVPROC getnUniformdv;
+ PFNGLGETNUNIFORMFVPROC getnUniformfv;
+ PFNGLGETNUNIFORMIVPROC getnUniformiv;
+ PFNGLGETNUNIFORMUIVPROC getnUniformuiv;
+ PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC invalidateNamedFramebufferData;
+ PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC invalidateNamedFramebufferSubData;
+ PFNGLMAPNAMEDBUFFERPROC mapNamedBuffer;
+ PFNGLMAPNAMEDBUFFERRANGEPROC mapNamedBufferRange;
+ PFNGLMEMORYBARRIERBYREGIONPROC memoryBarrierByRegion;
+ PFNGLNAMEDBUFFERDATAPROC namedBufferData;
+ PFNGLNAMEDBUFFERSTORAGEPROC namedBufferStorage;
+ PFNGLNAMEDBUFFERSUBDATAPROC namedBufferSubData;
+ PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC namedFramebufferDrawBuffer;
+ PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC namedFramebufferDrawBuffers;
+ PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC namedFramebufferParameteri;
+ PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC namedFramebufferReadBuffer;
+ PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC namedFramebufferRenderbuffer;
+ PFNGLNAMEDFRAMEBUFFERTEXTUREPROC namedFramebufferTexture;
+ PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC namedFramebufferTextureLayer;
+ PFNGLNAMEDRENDERBUFFERSTORAGEPROC namedRenderbufferStorage;
+ PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC namedRenderbufferStorageMultisample;
+ PFNGLREADNPIXELSPROC readnPixels;
+ PFNGLTEXTUREBARRIERPROC textureBarrier;
+ PFNGLTEXTUREBUFFERPROC textureBuffer;
+ PFNGLTEXTUREBUFFERRANGEPROC textureBufferRange;
+ PFNGLTEXTUREPARAMETERIIVPROC textureParameterIiv;
+ PFNGLTEXTUREPARAMETERIUIVPROC textureParameterIuiv;
+ PFNGLTEXTUREPARAMETERFPROC textureParameterf;
+ PFNGLTEXTUREPARAMETERFVPROC textureParameterfv;
+ PFNGLTEXTUREPARAMETERIPROC textureParameteri;
+ PFNGLTEXTUREPARAMETERIVPROC textureParameteriv;
+ PFNGLTEXTURESTORAGE1DPROC textureStorage1D;
+ PFNGLTEXTURESTORAGE2DPROC textureStorage2D;
+ PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC textureStorage2DMultisample;
+ PFNGLTEXTURESTORAGE3DPROC textureStorage3D;
+ PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC textureStorage3DMultisample;
+ PFNGLTEXTURESUBIMAGE1DPROC textureSubImage1D;
+ PFNGLTEXTURESUBIMAGE2DPROC textureSubImage2D;
+ PFNGLTEXTURESUBIMAGE3DPROC textureSubImage3D;
+ PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC transformFeedbackBufferBase;
+ PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC transformFeedbackBufferRange;
+ PFNGLUNMAPNAMEDBUFFERPROC unmapNamedBuffer;
+ PFNGLVERTEXARRAYATTRIBBINDINGPROC vertexArrayAttribBinding;
+ PFNGLVERTEXARRAYATTRIBFORMATPROC vertexArrayAttribFormat;
+ PFNGLVERTEXARRAYATTRIBIFORMATPROC vertexArrayAttribIFormat;
+ PFNGLVERTEXARRAYATTRIBLFORMATPROC vertexArrayAttribLFormat;
+ PFNGLVERTEXARRAYBINDINGDIVISORPROC vertexArrayBindingDivisor;
+ PFNGLVERTEXARRAYELEMENTBUFFERPROC vertexArrayElementBuffer;
+ PFNGLVERTEXARRAYVERTEXBUFFERPROC vertexArrayVertexBuffer;
+ PFNGLVERTEXARRAYVERTEXBUFFERSPROC vertexArrayVertexBuffers;
+
+ // ES 3.2
+ PFNGLBLENDBARRIERPROC blendBarrier;
+ PFNGLPRIMITIVEBOUNDINGBOXPROC primitiveBoundingBox;
+
+ // ES extensions
+ PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC eglImageTargetRenderbufferStorageOES;
+ PFNGLEGLIMAGETARGETTEXTURE2DOESPROC eglImageTargetTexture2DOES;
+
+ private:
+ void initializeProcsDesktopGL();
+ void initializeProcsGLES();
+
+ virtual void *loadProcAddress(const std::string &function) = 0;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_FUNCTIONSGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/PathGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/PathGL.cpp
new file mode 100755
index 000000000..a859bd759
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/PathGL.cpp
@@ -0,0 +1,38 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// PathGL.cpp: Implementation for PathGL class.
+
+#include "libANGLE/renderer/gl/PathGL.h"
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+
+namespace rx
+{
+
+PathGL::PathGL(const FunctionsGL *functions, GLuint path) : mFunctions(functions), mPathID(path)
+{
+}
+
+PathGL::~PathGL()
+{
+}
+
+gl::Error PathGL::setCommands(GLsizei numCommands,
+ const GLubyte *commands,
+ GLsizei numCoords,
+ GLenum coordType,
+ const void *coords)
+{
+ mFunctions->pathCommandsNV(mPathID, numCommands, commands, numCoords, coordType, coords);
+ return gl::Error(GL_NO_ERROR);
+}
+
+void PathGL::setPathParameter(GLenum pname, GLfloat value)
+{
+ mFunctions->setPathParameterfNV(mPathID, pname, value);
+}
+
+} // rx \ No newline at end of file
diff --git a/gfx/angle/src/libANGLE/renderer/gl/PathGL.h b/gfx/angle/src/libANGLE/renderer/gl/PathGL.h
new file mode 100755
index 000000000..461d39aec
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/PathGL.h
@@ -0,0 +1,44 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// PathGL.h: Class definition for CHROMIUM_path_rendering path object for the
+// GL backend.
+
+#ifndef LIBANGLE_RENDERER_GL_PATHIMPL_H_
+#define LIBANGLE_RENDERER_GL_PATHIMPL_H_
+
+#include "libANGLE/renderer/PathImpl.h"
+
+namespace rx
+{
+
+class FunctionsGL;
+
+class PathGL : public PathImpl
+{
+ public:
+ PathGL(const FunctionsGL *functions, GLuint path);
+ ~PathGL();
+
+ gl::Error setCommands(GLsizei numCommands,
+ const GLubyte *commands,
+ GLsizei numCoords,
+ GLenum coordType,
+ const void *coords) override;
+
+ void setPathParameter(GLenum pname, GLfloat value) override;
+
+ GLuint getPathID() const { return mPathID; }
+
+ private:
+ const FunctionsGL *mFunctions;
+
+ GLuint mPathID;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_GL_PATHIMPL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/ProgramGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/ProgramGL.cpp
new file mode 100755
index 000000000..88c7df720
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/ProgramGL.cpp
@@ -0,0 +1,588 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ProgramGL.cpp: Implements the class methods for ProgramGL.
+
+#include "libANGLE/renderer/gl/ProgramGL.h"
+
+#include "common/angleutils.h"
+#include "common/debug.h"
+#include "common/string_utils.h"
+#include "common/utilities.h"
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+#include "libANGLE/renderer/gl/ShaderGL.h"
+#include "libANGLE/renderer/gl/StateManagerGL.h"
+#include "libANGLE/renderer/gl/WorkaroundsGL.h"
+#include "libANGLE/Uniform.h"
+#include "platform/Platform.h"
+
+namespace rx
+{
+
+ProgramGL::ProgramGL(const gl::ProgramState &data,
+ const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ StateManagerGL *stateManager,
+ bool enablePathRendering)
+ : ProgramImpl(data),
+ mFunctions(functions),
+ mWorkarounds(workarounds),
+ mStateManager(stateManager),
+ mEnablePathRendering(enablePathRendering),
+ mProgramID(0)
+{
+ ASSERT(mFunctions);
+ ASSERT(mStateManager);
+
+ mProgramID = mFunctions->createProgram();
+}
+
+ProgramGL::~ProgramGL()
+{
+ mFunctions->deleteProgram(mProgramID);
+ mProgramID = 0;
+}
+
+LinkResult ProgramGL::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
+{
+ preLink();
+
+ // Read the binary format, size and blob
+ GLenum binaryFormat = stream->readInt<GLenum>();
+ GLint binaryLength = stream->readInt<GLint>();
+ const uint8_t *binary = stream->data() + stream->offset();
+ stream->skip(binaryLength);
+
+ // Load the binary
+ mFunctions->programBinary(mProgramID, binaryFormat, binary, binaryLength);
+
+ // Verify that the program linked
+ if (!checkLinkStatus(infoLog))
+ {
+ return false;
+ }
+
+ postLink();
+
+ return true;
+}
+
+gl::Error ProgramGL::save(gl::BinaryOutputStream *stream)
+{
+ GLint binaryLength = 0;
+ mFunctions->getProgramiv(mProgramID, GL_PROGRAM_BINARY_LENGTH, &binaryLength);
+
+ std::vector<uint8_t> binary(binaryLength);
+ GLenum binaryFormat = GL_NONE;
+ mFunctions->getProgramBinary(mProgramID, binaryLength, &binaryLength, &binaryFormat,
+ &binary[0]);
+
+ stream->writeInt(binaryFormat);
+ stream->writeInt(binaryLength);
+ stream->writeBytes(&binary[0], binaryLength);
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+void ProgramGL::setBinaryRetrievableHint(bool retrievable)
+{
+ // glProgramParameteri isn't always available on ES backends.
+ if (mFunctions->programParameteri)
+ {
+ mFunctions->programParameteri(mProgramID, GL_PROGRAM_BINARY_RETRIEVABLE_HINT,
+ retrievable ? GL_TRUE : GL_FALSE);
+ }
+}
+
+LinkResult ProgramGL::link(const gl::ContextState &data, gl::InfoLog &infoLog)
+{
+ preLink();
+
+ if (mState.getAttachedComputeShader())
+ {
+ const ShaderGL *computeShaderGL = GetImplAs<ShaderGL>(mState.getAttachedComputeShader());
+
+ mFunctions->attachShader(mProgramID, computeShaderGL->getShaderID());
+
+ // Link and verify
+ mFunctions->linkProgram(mProgramID);
+
+ // Detach the shaders
+ mFunctions->detachShader(mProgramID, computeShaderGL->getShaderID());
+ }
+ else
+ {
+ // Set the transform feedback state
+ std::vector<const GLchar *> transformFeedbackVaryings;
+ for (const auto &tfVarying : mState.getTransformFeedbackVaryingNames())
+ {
+ transformFeedbackVaryings.push_back(tfVarying.c_str());
+ }
+
+ if (transformFeedbackVaryings.empty())
+ {
+ if (mFunctions->transformFeedbackVaryings)
+ {
+ mFunctions->transformFeedbackVaryings(mProgramID, 0, nullptr,
+ mState.getTransformFeedbackBufferMode());
+ }
+ }
+ else
+ {
+ ASSERT(mFunctions->transformFeedbackVaryings);
+ mFunctions->transformFeedbackVaryings(
+ mProgramID, static_cast<GLsizei>(transformFeedbackVaryings.size()),
+ &transformFeedbackVaryings[0], mState.getTransformFeedbackBufferMode());
+ }
+
+ const ShaderGL *vertexShaderGL = GetImplAs<ShaderGL>(mState.getAttachedVertexShader());
+ const ShaderGL *fragmentShaderGL = GetImplAs<ShaderGL>(mState.getAttachedFragmentShader());
+
+ // Attach the shaders
+ mFunctions->attachShader(mProgramID, vertexShaderGL->getShaderID());
+ mFunctions->attachShader(mProgramID, fragmentShaderGL->getShaderID());
+
+ // Bind attribute locations to match the GL layer.
+ for (const sh::Attribute &attribute : mState.getAttributes())
+ {
+ if (!attribute.staticUse)
+ {
+ continue;
+ }
+
+ mFunctions->bindAttribLocation(mProgramID, attribute.location, attribute.name.c_str());
+ }
+
+ // Link and verify
+ mFunctions->linkProgram(mProgramID);
+
+ // Detach the shaders
+ mFunctions->detachShader(mProgramID, vertexShaderGL->getShaderID());
+ mFunctions->detachShader(mProgramID, fragmentShaderGL->getShaderID());
+ }
+
+ // Verify the link
+ if (!checkLinkStatus(infoLog))
+ {
+ return false;
+ }
+
+ if (mWorkarounds.alwaysCallUseProgramAfterLink)
+ {
+ mStateManager->forceUseProgram(mProgramID);
+ }
+
+ postLink();
+
+ return true;
+}
+
+GLboolean ProgramGL::validate(const gl::Caps & /*caps*/, gl::InfoLog * /*infoLog*/)
+{
+ // TODO(jmadill): implement validate
+ return true;
+}
+
+void ProgramGL::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ mStateManager->useProgram(mProgramID);
+ mFunctions->uniform1fv(uniLoc(location), count, v);
+}
+
+void ProgramGL::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ mStateManager->useProgram(mProgramID);
+ mFunctions->uniform2fv(uniLoc(location), count, v);
+}
+
+void ProgramGL::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ mStateManager->useProgram(mProgramID);
+ mFunctions->uniform3fv(uniLoc(location), count, v);
+}
+
+void ProgramGL::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ mStateManager->useProgram(mProgramID);
+ mFunctions->uniform4fv(uniLoc(location), count, v);
+}
+
+void ProgramGL::setUniform1iv(GLint location, GLsizei count, const GLint *v)
+{
+ mStateManager->useProgram(mProgramID);
+ mFunctions->uniform1iv(uniLoc(location), count, v);
+
+ const gl::VariableLocation &locationEntry = mState.getUniformLocations()[location];
+
+ size_t samplerIndex = mUniformIndexToSamplerIndex[locationEntry.index];
+ if (samplerIndex != GL_INVALID_INDEX)
+ {
+ std::vector<GLuint> &boundTextureUnits = mSamplerBindings[samplerIndex].boundTextureUnits;
+
+ size_t copyCount =
+ std::min<size_t>(count, boundTextureUnits.size() - locationEntry.element);
+ std::copy(v, v + copyCount, boundTextureUnits.begin() + locationEntry.element);
+ }
+}
+
+void ProgramGL::setUniform2iv(GLint location, GLsizei count, const GLint *v)
+{
+ mStateManager->useProgram(mProgramID);
+ mFunctions->uniform2iv(uniLoc(location), count, v);
+}
+
+void ProgramGL::setUniform3iv(GLint location, GLsizei count, const GLint *v)
+{
+ mStateManager->useProgram(mProgramID);
+ mFunctions->uniform3iv(uniLoc(location), count, v);
+}
+
+void ProgramGL::setUniform4iv(GLint location, GLsizei count, const GLint *v)
+{
+ mStateManager->useProgram(mProgramID);
+ mFunctions->uniform4iv(uniLoc(location), count, v);
+}
+
+void ProgramGL::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
+{
+ mStateManager->useProgram(mProgramID);
+ mFunctions->uniform1uiv(uniLoc(location), count, v);
+}
+
+void ProgramGL::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
+{
+ mStateManager->useProgram(mProgramID);
+ mFunctions->uniform2uiv(uniLoc(location), count, v);
+}
+
+void ProgramGL::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
+{
+ mStateManager->useProgram(mProgramID);
+ mFunctions->uniform3uiv(uniLoc(location), count, v);
+}
+
+void ProgramGL::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
+{
+ mStateManager->useProgram(mProgramID);
+ mFunctions->uniform4uiv(uniLoc(location), count, v);
+}
+
+void ProgramGL::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ mStateManager->useProgram(mProgramID);
+ mFunctions->uniformMatrix2fv(uniLoc(location), count, transpose, value);
+}
+
+void ProgramGL::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ mStateManager->useProgram(mProgramID);
+ mFunctions->uniformMatrix3fv(uniLoc(location), count, transpose, value);
+}
+
+void ProgramGL::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ mStateManager->useProgram(mProgramID);
+ mFunctions->uniformMatrix4fv(uniLoc(location), count, transpose, value);
+}
+
+void ProgramGL::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ mStateManager->useProgram(mProgramID);
+ mFunctions->uniformMatrix2x3fv(uniLoc(location), count, transpose, value);
+}
+
+void ProgramGL::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ mStateManager->useProgram(mProgramID);
+ mFunctions->uniformMatrix3x2fv(uniLoc(location), count, transpose, value);
+}
+
+void ProgramGL::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ mStateManager->useProgram(mProgramID);
+ mFunctions->uniformMatrix2x4fv(uniLoc(location), count, transpose, value);
+}
+
+void ProgramGL::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ mStateManager->useProgram(mProgramID);
+ mFunctions->uniformMatrix4x2fv(uniLoc(location), count, transpose, value);
+}
+
+void ProgramGL::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ mStateManager->useProgram(mProgramID);
+ mFunctions->uniformMatrix3x4fv(uniLoc(location), count, transpose, value);
+}
+
+void ProgramGL::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ mStateManager->useProgram(mProgramID);
+ mFunctions->uniformMatrix4x3fv(uniLoc(location), count, transpose, value);
+}
+
+void ProgramGL::setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
+{
+ // Lazy init
+ if (mUniformBlockRealLocationMap.empty())
+ {
+ mUniformBlockRealLocationMap.reserve(mState.getUniformBlocks().size());
+ for (const gl::UniformBlock &uniformBlock : mState.getUniformBlocks())
+ {
+ const std::string &nameWithIndex = uniformBlock.nameWithArrayIndex();
+ GLuint blockIndex = mFunctions->getUniformBlockIndex(mProgramID, nameWithIndex.c_str());
+ mUniformBlockRealLocationMap.push_back(blockIndex);
+ }
+ }
+
+ GLuint realBlockIndex = mUniformBlockRealLocationMap[uniformBlockIndex];
+ if (realBlockIndex != GL_INVALID_INDEX)
+ {
+ mFunctions->uniformBlockBinding(mProgramID, realBlockIndex, uniformBlockBinding);
+ }
+}
+
+GLuint ProgramGL::getProgramID() const
+{
+ return mProgramID;
+}
+
+const std::vector<SamplerBindingGL> &ProgramGL::getAppliedSamplerUniforms() const
+{
+ return mSamplerBindings;
+}
+
+bool ProgramGL::getUniformBlockSize(const std::string &blockName, size_t *sizeOut) const
+{
+ ASSERT(mProgramID != 0u);
+
+ GLuint blockIndex = mFunctions->getUniformBlockIndex(mProgramID, blockName.c_str());
+ if (blockIndex == GL_INVALID_INDEX)
+ {
+ *sizeOut = 0;
+ return false;
+ }
+
+ GLint dataSize = 0;
+ mFunctions->getActiveUniformBlockiv(mProgramID, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE,
+ &dataSize);
+ *sizeOut = static_cast<size_t>(dataSize);
+ return true;
+}
+
+bool ProgramGL::getUniformBlockMemberInfo(const std::string &memberUniformName,
+ sh::BlockMemberInfo *memberInfoOut) const
+{
+ GLuint uniformIndex;
+ const GLchar *memberNameGLStr = memberUniformName.c_str();
+ mFunctions->getUniformIndices(mProgramID, 1, &memberNameGLStr, &uniformIndex);
+
+ if (uniformIndex == GL_INVALID_INDEX)
+ {
+ *memberInfoOut = sh::BlockMemberInfo::getDefaultBlockInfo();
+ return false;
+ }
+
+ mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_OFFSET,
+ &memberInfoOut->offset);
+ mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_ARRAY_STRIDE,
+ &memberInfoOut->arrayStride);
+ mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_MATRIX_STRIDE,
+ &memberInfoOut->matrixStride);
+
+ // TODO(jmadill): possibly determine this at the gl::Program level.
+ GLint isRowMajorMatrix = 0;
+ mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_IS_ROW_MAJOR,
+ &isRowMajorMatrix);
+ memberInfoOut->isRowMajorMatrix = isRowMajorMatrix != GL_FALSE;
+ return true;
+}
+
+void ProgramGL::setPathFragmentInputGen(const std::string &inputName,
+ GLenum genMode,
+ GLint components,
+ const GLfloat *coeffs)
+{
+ ASSERT(mEnablePathRendering);
+
+ for (const auto &input : mPathRenderingFragmentInputs)
+ {
+ if (input.name == inputName)
+ {
+ mFunctions->programPathFragmentInputGenNV(mProgramID, input.location, genMode,
+ components, coeffs);
+ ASSERT(mFunctions->getError() == GL_NO_ERROR);
+ return;
+ }
+ }
+
+}
+
+void ProgramGL::preLink()
+{
+ // Reset the program state
+ mUniformRealLocationMap.clear();
+ mUniformBlockRealLocationMap.clear();
+ mSamplerBindings.clear();
+ mUniformIndexToSamplerIndex.clear();
+ mPathRenderingFragmentInputs.clear();
+}
+
+bool ProgramGL::checkLinkStatus(gl::InfoLog &infoLog)
+{
+ GLint linkStatus = GL_FALSE;
+ mFunctions->getProgramiv(mProgramID, GL_LINK_STATUS, &linkStatus);
+ if (linkStatus == GL_FALSE)
+ {
+ // Linking failed, put the error into the info log
+ GLint infoLogLength = 0;
+ mFunctions->getProgramiv(mProgramID, GL_INFO_LOG_LENGTH, &infoLogLength);
+
+ std::string warning;
+
+ // Info log length includes the null terminator, so 1 means that the info log is an empty
+ // string.
+ if (infoLogLength > 1)
+ {
+ std::vector<char> buf(infoLogLength);
+ mFunctions->getProgramInfoLog(mProgramID, infoLogLength, nullptr, &buf[0]);
+
+ mFunctions->deleteProgram(mProgramID);
+ mProgramID = 0;
+
+ infoLog << buf.data();
+
+ warning = FormatString("Program link failed unexpectedly: %s", buf.data());
+ }
+ else
+ {
+ warning = "Program link failed unexpectedly with no info log.";
+ }
+ ANGLEPlatformCurrent()->logWarning(warning.c_str());
+ TRACE("\n%s", warning.c_str());
+
+ // TODO, return GL_OUT_OF_MEMORY or just fail the link? This is an unexpected case
+ return false;
+ }
+
+ return true;
+}
+
+void ProgramGL::postLink()
+{
+ // Query the uniform information
+ ASSERT(mUniformRealLocationMap.empty());
+ const auto &uniformLocations = mState.getUniformLocations();
+ const auto &uniforms = mState.getUniforms();
+ mUniformRealLocationMap.resize(uniformLocations.size(), GL_INVALID_INDEX);
+ for (size_t uniformLocation = 0; uniformLocation < uniformLocations.size(); uniformLocation++)
+ {
+ const auto &entry = uniformLocations[uniformLocation];
+ if (!entry.used)
+ {
+ continue;
+ }
+
+ // From the spec:
+ // "Locations for sequential array indices are not required to be sequential."
+ const gl::LinkedUniform &uniform = uniforms[entry.index];
+ std::stringstream fullNameStr;
+ fullNameStr << uniform.name;
+ if (uniform.isArray())
+ {
+ fullNameStr << "[" << entry.element << "]";
+ }
+ const std::string &fullName = fullNameStr.str();
+
+ GLint realLocation = mFunctions->getUniformLocation(mProgramID, fullName.c_str());
+ mUniformRealLocationMap[uniformLocation] = realLocation;
+ }
+
+ mUniformIndexToSamplerIndex.resize(mState.getUniforms().size(), GL_INVALID_INDEX);
+
+ for (size_t uniformId = 0; uniformId < uniforms.size(); ++uniformId)
+ {
+ const gl::LinkedUniform &linkedUniform = uniforms[uniformId];
+
+ if (!linkedUniform.isSampler() || !linkedUniform.staticUse)
+ continue;
+
+ mUniformIndexToSamplerIndex[uniformId] = mSamplerBindings.size();
+
+ // If uniform is a sampler type, insert it into the mSamplerBindings array
+ SamplerBindingGL samplerBinding;
+ samplerBinding.textureType = gl::SamplerTypeToTextureType(linkedUniform.type);
+ samplerBinding.boundTextureUnits.resize(linkedUniform.elementCount(), 0);
+ mSamplerBindings.push_back(samplerBinding);
+ }
+
+ // Discover CHROMIUM_path_rendering fragment inputs if enabled.
+ if (!mEnablePathRendering)
+ return;
+
+ GLint numFragmentInputs = 0;
+ mFunctions->getProgramInterfaceiv(mProgramID, GL_FRAGMENT_INPUT_NV, GL_ACTIVE_RESOURCES,
+ &numFragmentInputs);
+ if (numFragmentInputs <= 0)
+ return;
+
+ GLint maxNameLength = 0;
+ mFunctions->getProgramInterfaceiv(mProgramID, GL_FRAGMENT_INPUT_NV, GL_MAX_NAME_LENGTH,
+ &maxNameLength);
+ ASSERT(maxNameLength);
+
+ for (GLint i = 0; i < numFragmentInputs; ++i)
+ {
+ std::string name;
+ name.resize(maxNameLength);
+
+ GLsizei nameLen = 0;
+ mFunctions->getProgramResourceName(mProgramID, GL_FRAGMENT_INPUT_NV, i, maxNameLength,
+ &nameLen, &name[0]);
+ name.resize(nameLen);
+
+ // Ignore built-ins
+ if (angle::BeginsWith(name, "gl_"))
+ continue;
+
+ const GLenum kQueryProperties[] = {GL_LOCATION, GL_ARRAY_SIZE};
+ GLint queryResults[ArraySize(kQueryProperties)];
+ GLsizei queryLength = 0;
+
+ mFunctions->getProgramResourceiv(
+ mProgramID, GL_FRAGMENT_INPUT_NV, i, static_cast<GLsizei>(ArraySize(kQueryProperties)),
+ kQueryProperties, static_cast<GLsizei>(ArraySize(queryResults)), &queryLength,
+ queryResults);
+
+ ASSERT(queryLength == static_cast<GLsizei>(ArraySize(kQueryProperties)));
+
+ PathRenderingFragmentInput baseElementInput;
+ baseElementInput.name = name;
+ baseElementInput.location = queryResults[0];
+ mPathRenderingFragmentInputs.push_back(std::move(baseElementInput));
+
+ // If the input is an array it's denoted by [0] suffix on the variable
+ // name. We'll then create an entry per each array index where index > 0
+ if (angle::EndsWith(name, "[0]"))
+ {
+ // drop the suffix
+ name.resize(name.size() - 3);
+
+ const auto arraySize = queryResults[1];
+ const auto baseLocation = queryResults[0];
+
+ for (GLint arrayIndex = 1; arrayIndex < arraySize; ++arrayIndex)
+ {
+ PathRenderingFragmentInput arrayElementInput;
+ arrayElementInput.name = name + "[" + ToString(arrayIndex) + "]";
+ arrayElementInput.location = baseLocation + arrayIndex;
+ mPathRenderingFragmentInputs.push_back(std::move(arrayElementInput));
+ }
+ }
+ }
+}
+
+} // namespace rx
diff --git a/gfx/angle/src/libANGLE/renderer/gl/ProgramGL.h b/gfx/angle/src/libANGLE/renderer/gl/ProgramGL.h
new file mode 100755
index 000000000..88e2245fa
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/ProgramGL.h
@@ -0,0 +1,118 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ProgramGL.h: Defines the class interface for ProgramGL.
+
+#ifndef LIBANGLE_RENDERER_GL_PROGRAMGL_H_
+#define LIBANGLE_RENDERER_GL_PROGRAMGL_H_
+
+#include <string>
+#include <vector>
+
+#include "libANGLE/renderer/gl/WorkaroundsGL.h"
+#include "libANGLE/renderer/ProgramImpl.h"
+
+namespace rx
+{
+
+class FunctionsGL;
+class StateManagerGL;
+
+struct SamplerBindingGL
+{
+ GLenum textureType;
+ std::vector<GLuint> boundTextureUnits;
+};
+
+class ProgramGL : public ProgramImpl
+{
+ public:
+ ProgramGL(const gl::ProgramState &data,
+ const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ StateManagerGL *stateManager,
+ bool enablePathRendering);
+ ~ProgramGL() override;
+
+ LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) override;
+ gl::Error save(gl::BinaryOutputStream *stream) override;
+ void setBinaryRetrievableHint(bool retrievable) override;
+
+ LinkResult link(const gl::ContextState &data, gl::InfoLog &infoLog) override;
+ GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
+
+ void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) override;
+ void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) override;
+ void setUniform3fv(GLint location, GLsizei count, const GLfloat *v) override;
+ void setUniform4fv(GLint location, GLsizei count, const GLfloat *v) override;
+ void setUniform1iv(GLint location, GLsizei count, const GLint *v) override;
+ void setUniform2iv(GLint location, GLsizei count, const GLint *v) override;
+ void setUniform3iv(GLint location, GLsizei count, const GLint *v) override;
+ void setUniform4iv(GLint location, GLsizei count, const GLint *v) override;
+ void setUniform1uiv(GLint location, GLsizei count, const GLuint *v) override;
+ void setUniform2uiv(GLint location, GLsizei count, const GLuint *v) override;
+ void setUniform3uiv(GLint location, GLsizei count, const GLuint *v) override;
+ void setUniform4uiv(GLint location, GLsizei count, const GLuint *v) override;
+ void setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) override;
+ void setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) override;
+ void setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) override;
+ void setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) override;
+ void setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) override;
+ void setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) override;
+ void setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) override;
+ void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) override;
+ void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) override;
+
+ void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override;
+
+ bool getUniformBlockSize(const std::string &blockName, size_t *sizeOut) const override;
+ bool getUniformBlockMemberInfo(const std::string &memberUniformName,
+ sh::BlockMemberInfo *memberInfoOut) const override;
+
+ void setPathFragmentInputGen(const std::string &inputName,
+ GLenum genMode,
+ GLint components,
+ const GLfloat *coeffs) override;
+
+ GLuint getProgramID() const;
+ const std::vector<SamplerBindingGL> &getAppliedSamplerUniforms() const;
+
+ private:
+ void preLink();
+ bool checkLinkStatus(gl::InfoLog &infoLog);
+ void postLink();
+
+ // Helper function, makes it simpler to type.
+ GLint uniLoc(GLint glLocation) const { return mUniformRealLocationMap[glLocation]; }
+
+ const FunctionsGL *mFunctions;
+ const WorkaroundsGL &mWorkarounds;
+ StateManagerGL *mStateManager;
+
+ std::vector<GLint> mUniformRealLocationMap;
+ std::vector<GLuint> mUniformBlockRealLocationMap;
+
+ // An array of the samplers that are used by the program
+ std::vector<SamplerBindingGL> mSamplerBindings;
+
+ // A map from a mData.getUniforms() index to a mSamplerBindings index.
+ std::vector<size_t> mUniformIndexToSamplerIndex;
+
+ struct PathRenderingFragmentInput
+ {
+ std::string name;
+ GLint location;
+ };
+ std::vector<PathRenderingFragmentInput> mPathRenderingFragmentInputs;
+
+ bool mEnablePathRendering;
+
+ GLuint mProgramID;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_PROGRAMGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/QueryGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/QueryGL.cpp
new file mode 100755
index 000000000..6d9df5d76
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/QueryGL.cpp
@@ -0,0 +1,222 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// QueryGL.cpp: Implements the class methods for QueryGL.
+
+#include "libANGLE/renderer/gl/QueryGL.h"
+
+#include "common/debug.h"
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+#include "libANGLE/renderer/gl/StateManagerGL.h"
+
+namespace
+{
+
+GLuint64 MergeQueryResults(GLenum type, GLuint64 currentResult, GLuint64 newResult)
+{
+ switch (type)
+ {
+ case GL_ANY_SAMPLES_PASSED:
+ case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
+ return (currentResult == GL_TRUE || newResult == GL_TRUE) ? GL_TRUE : GL_FALSE;
+
+ case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
+ return currentResult + newResult;
+
+ case GL_TIME_ELAPSED:
+ return currentResult + newResult;
+
+ case GL_TIMESTAMP:
+ return newResult;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+} // anonymous namespace
+
+namespace rx
+{
+
+QueryGL::QueryGL(GLenum type, const FunctionsGL *functions, StateManagerGL *stateManager)
+ : QueryImpl(type),
+ mType(type),
+ mFunctions(functions),
+ mStateManager(stateManager),
+ mActiveQuery(0),
+ mPendingQueries(),
+ mResultSum(0)
+{
+}
+
+QueryGL::~QueryGL()
+{
+ mStateManager->deleteQuery(mActiveQuery);
+ mStateManager->onDeleteQueryObject(this);
+ while (!mPendingQueries.empty())
+ {
+ mStateManager->deleteQuery(mPendingQueries.front());
+ mPendingQueries.pop_front();
+ }
+}
+
+gl::Error QueryGL::begin()
+{
+ mResultSum = 0;
+ mStateManager->onBeginQuery(this);
+ return resume();
+}
+
+gl::Error QueryGL::end()
+{
+ return pause();
+}
+
+gl::Error QueryGL::queryCounter()
+{
+ ASSERT(mType == GL_TIMESTAMP);
+
+ // Directly create a query for the timestamp and add it to the pending query queue, as timestamp
+ // queries do not have the traditional begin/end block and never need to be paused/resumed
+ GLuint query;
+ mFunctions->genQueries(1, &query);
+ mFunctions->queryCounter(query, GL_TIMESTAMP);
+ mPendingQueries.push_back(query);
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+template <typename T>
+gl::Error QueryGL::getResultBase(T *params)
+{
+ ASSERT(mActiveQuery == 0);
+
+ gl::Error error = flush(true);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ASSERT(mPendingQueries.empty());
+ *params = static_cast<T>(mResultSum);
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error QueryGL::getResult(GLint *params)
+{
+ return getResultBase(params);
+}
+
+gl::Error QueryGL::getResult(GLuint *params)
+{
+ return getResultBase(params);
+}
+
+gl::Error QueryGL::getResult(GLint64 *params)
+{
+ return getResultBase(params);
+}
+
+gl::Error QueryGL::getResult(GLuint64 *params)
+{
+ return getResultBase(params);
+}
+
+gl::Error QueryGL::isResultAvailable(bool *available)
+{
+ ASSERT(mActiveQuery == 0);
+
+ gl::Error error = flush(false);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ *available = mPendingQueries.empty();
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error QueryGL::pause()
+{
+ if (mActiveQuery != 0)
+ {
+ mStateManager->endQuery(mType, mActiveQuery);
+
+ mPendingQueries.push_back(mActiveQuery);
+ mActiveQuery = 0;
+ }
+
+ // Flush to make sure the pending queries don't add up too much.
+ gl::Error error = flush(false);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error QueryGL::resume()
+{
+ if (mActiveQuery == 0)
+ {
+ // Flush to make sure the pending queries don't add up too much.
+ gl::Error error = flush(false);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ mFunctions->genQueries(1, &mActiveQuery);
+ mStateManager->beginQuery(mType, mActiveQuery);
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error QueryGL::flush(bool force)
+{
+ while (!mPendingQueries.empty())
+ {
+ GLuint id = mPendingQueries.front();
+ if (!force)
+ {
+ GLuint resultAvailable = 0;
+ mFunctions->getQueryObjectuiv(id, GL_QUERY_RESULT_AVAILABLE, &resultAvailable);
+ if (resultAvailable == GL_FALSE)
+ {
+ return gl::Error(GL_NO_ERROR);
+ }
+ }
+
+ // Even though getQueryObjectui64v was introduced for timer queries, there is nothing in the
+ // standard that says that it doesn't work for any other queries. It also passes on all the
+ // trybots, so we use it if it is available
+ if (mFunctions->getQueryObjectui64v != nullptr)
+ {
+ GLuint64 result = 0;
+ mFunctions->getQueryObjectui64v(id, GL_QUERY_RESULT, &result);
+ mResultSum = MergeQueryResults(mType, mResultSum, result);
+ }
+ else
+ {
+ GLuint result = 0;
+ mFunctions->getQueryObjectuiv(id, GL_QUERY_RESULT, &result);
+ mResultSum = MergeQueryResults(mType, mResultSum, static_cast<GLuint64>(result));
+ }
+
+ mStateManager->deleteQuery(id);
+
+ mPendingQueries.pop_front();
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/QueryGL.h b/gfx/angle/src/libANGLE/renderer/gl/QueryGL.h
new file mode 100755
index 000000000..5e280b1f7
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/QueryGL.h
@@ -0,0 +1,64 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// QueryGL.h: Defines the class interface for QueryGL.
+
+#ifndef LIBANGLE_RENDERER_GL_QUERYGL_H_
+#define LIBANGLE_RENDERER_GL_QUERYGL_H_
+
+#include <deque>
+
+#include "libANGLE/renderer/QueryImpl.h"
+
+namespace rx
+{
+
+class FunctionsGL;
+class StateManagerGL;
+
+class QueryGL : public QueryImpl
+{
+ public:
+ QueryGL(GLenum type, const FunctionsGL *functions, StateManagerGL *stateManager);
+ ~QueryGL() override;
+
+ gl::Error begin() override;
+ gl::Error end() override;
+ gl::Error queryCounter() override;
+ gl::Error getResult(GLint *params) override;
+ gl::Error getResult(GLuint *params) override;
+ gl::Error getResult(GLint64 *params) override;
+ gl::Error getResult(GLuint64 *params) override;
+ gl::Error isResultAvailable(bool *available) override;
+
+ // OpenGL is only allowed to have one query of each type active at any given time. Since ANGLE
+ // virtualizes contexts, queries need to be able to be paused and resumed.
+ // A query is "paused" by ending it and pushing the ID into a list of queries awaiting readback.
+ // When it is "resumed", a new query is generated and started.
+ // When a result is required, the queries are "flushed" by iterating over the list of pending
+ // queries and merging their results.
+ gl::Error pause();
+ gl::Error resume();
+
+ private:
+ gl::Error flush(bool force);
+
+ template <typename T>
+ gl::Error getResultBase(T *params);
+
+ GLenum mType;
+
+ const FunctionsGL *mFunctions;
+ StateManagerGL *mStateManager;
+
+ GLuint mActiveQuery;
+ std::deque<GLuint> mPendingQueries;
+ GLuint64 mResultSum;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_QUERYGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/RenderbufferGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/RenderbufferGL.cpp
new file mode 100755
index 000000000..bfc2bb254
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/RenderbufferGL.cpp
@@ -0,0 +1,96 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RenderbufferGL.cpp: Implements the class methods for RenderbufferGL.
+
+#include "libANGLE/renderer/gl/RenderbufferGL.h"
+
+#include "common/debug.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+#include "libANGLE/renderer/gl/StateManagerGL.h"
+#include "libANGLE/renderer/gl/formatutilsgl.h"
+#include "libANGLE/renderer/gl/renderergl_utils.h"
+
+namespace rx
+{
+RenderbufferGL::RenderbufferGL(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ StateManagerGL *stateManager,
+ const gl::TextureCapsMap &textureCaps)
+ : RenderbufferImpl(),
+ mFunctions(functions),
+ mWorkarounds(workarounds),
+ mStateManager(stateManager),
+ mTextureCaps(textureCaps),
+ mRenderbufferID(0)
+{
+ mFunctions->genRenderbuffers(1, &mRenderbufferID);
+ mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mRenderbufferID);
+}
+
+RenderbufferGL::~RenderbufferGL()
+{
+ mStateManager->deleteRenderbuffer(mRenderbufferID);
+ mRenderbufferID = 0;
+}
+
+gl::Error RenderbufferGL::setStorage(GLenum internalformat, size_t width, size_t height)
+{
+ mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mRenderbufferID);
+
+ nativegl::RenderbufferFormat renderbufferFormat =
+ nativegl::GetRenderbufferFormat(mFunctions, mWorkarounds, internalformat);
+ mFunctions->renderbufferStorage(GL_RENDERBUFFER, renderbufferFormat.internalFormat,
+ static_cast<GLsizei>(width), static_cast<GLsizei>(height));
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RenderbufferGL::setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height)
+{
+ mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mRenderbufferID);
+
+ nativegl::RenderbufferFormat renderbufferFormat =
+ nativegl::GetRenderbufferFormat(mFunctions, mWorkarounds, internalformat);
+ mFunctions->renderbufferStorageMultisample(
+ GL_RENDERBUFFER, static_cast<GLsizei>(samples), renderbufferFormat.internalFormat,
+ static_cast<GLsizei>(width), static_cast<GLsizei>(height));
+
+ const gl::TextureCaps &formatCaps = mTextureCaps.get(internalformat);
+ if (samples > formatCaps.getMaxSamples())
+ {
+ // Before version 4.2, it is unknown if the specific internal format can support the requested number
+ // of samples. It is expected that GL_OUT_OF_MEMORY is returned if the renderbuffer cannot be created.
+ GLenum error = GL_NO_ERROR;
+ do
+ {
+ error = mFunctions->getError();
+ if (error == GL_OUT_OF_MEMORY)
+ {
+ return gl::Error(GL_OUT_OF_MEMORY);
+ }
+
+ ASSERT(error == GL_NO_ERROR);
+ } while (error != GL_NO_ERROR);
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RenderbufferGL::setStorageEGLImageTarget(egl::Image *image)
+{
+ UNIMPLEMENTED();
+ return gl::Error(GL_INVALID_OPERATION);
+}
+
+GLuint RenderbufferGL::getRenderbufferID() const
+{
+ return mRenderbufferID;
+}
+
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/RenderbufferGL.h b/gfx/angle/src/libANGLE/renderer/gl/RenderbufferGL.h
new file mode 100755
index 000000000..0ff0faeae
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/RenderbufferGL.h
@@ -0,0 +1,52 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RenderbufferGL.h: Defines the class interface for RenderbufferGL.
+
+#ifndef LIBANGLE_RENDERER_GL_RENDERBUFFERGL_H_
+#define LIBANGLE_RENDERER_GL_RENDERBUFFERGL_H_
+
+#include "libANGLE/renderer/RenderbufferImpl.h"
+
+namespace gl
+{
+class TextureCapsMap;
+}
+
+namespace rx
+{
+
+class FunctionsGL;
+class StateManagerGL;
+struct WorkaroundsGL;
+
+class RenderbufferGL : public RenderbufferImpl
+{
+ public:
+ RenderbufferGL(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ StateManagerGL *stateManager,
+ const gl::TextureCapsMap &textureCaps);
+ ~RenderbufferGL() override;
+
+ virtual gl::Error setStorage(GLenum internalformat, size_t width, size_t height) override;
+ virtual gl::Error setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height) override;
+ virtual gl::Error setStorageEGLImageTarget(egl::Image *image) override;
+
+ GLuint getRenderbufferID() const;
+
+ private:
+ const FunctionsGL *mFunctions;
+ const WorkaroundsGL &mWorkarounds;
+ StateManagerGL *mStateManager;
+ const gl::TextureCapsMap &mTextureCaps;
+
+ GLuint mRenderbufferID;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_RENDERBUFFERGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/RendererGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/RendererGL.cpp
new file mode 100755
index 000000000..da1a65687
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/RendererGL.cpp
@@ -0,0 +1,561 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RendererGL.cpp: Implements the class methods for RendererGL.
+
+#include "libANGLE/renderer/gl/RendererGL.h"
+
+#include <EGL/eglext.h>
+
+#include "common/debug.h"
+#include "libANGLE/AttributeMap.h"
+#include "libANGLE/ContextState.h"
+#include "libANGLE/Path.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/renderer/gl/BlitGL.h"
+#include "libANGLE/renderer/gl/BufferGL.h"
+#include "libANGLE/renderer/gl/CompilerGL.h"
+#include "libANGLE/renderer/gl/ContextGL.h"
+#include "libANGLE/renderer/gl/FenceNVGL.h"
+#include "libANGLE/renderer/gl/FenceSyncGL.h"
+#include "libANGLE/renderer/gl/FramebufferGL.h"
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+#include "libANGLE/renderer/gl/PathGL.h"
+#include "libANGLE/renderer/gl/ProgramGL.h"
+#include "libANGLE/renderer/gl/QueryGL.h"
+#include "libANGLE/renderer/gl/RenderbufferGL.h"
+#include "libANGLE/renderer/gl/SamplerGL.h"
+#include "libANGLE/renderer/gl/ShaderGL.h"
+#include "libANGLE/renderer/gl/StateManagerGL.h"
+#include "libANGLE/renderer/gl/SurfaceGL.h"
+#include "libANGLE/renderer/gl/TextureGL.h"
+#include "libANGLE/renderer/gl/TransformFeedbackGL.h"
+#include "libANGLE/renderer/gl/VertexArrayGL.h"
+#include "libANGLE/renderer/gl/renderergl_utils.h"
+
+namespace
+{
+
+std::vector<GLuint> GatherPaths(const std::vector<gl::Path *> &paths)
+{
+ std::vector<GLuint> ret;
+ ret.reserve(paths.size());
+
+ for (const auto *p : paths)
+ {
+ const auto *pathObj = rx::GetImplAs<rx::PathGL>(p);
+ ret.push_back(pathObj->getPathID());
+ }
+ return ret;
+}
+
+} // namespace
+
+#ifndef NDEBUG
+static void INTERNAL_GL_APIENTRY LogGLDebugMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
+ const GLchar *message, const void *userParam)
+{
+ std::string sourceText;
+ switch (source)
+ {
+ case GL_DEBUG_SOURCE_API: sourceText = "OpenGL"; break;
+ case GL_DEBUG_SOURCE_WINDOW_SYSTEM: sourceText = "Windows"; break;
+ case GL_DEBUG_SOURCE_SHADER_COMPILER: sourceText = "Shader Compiler"; break;
+ case GL_DEBUG_SOURCE_THIRD_PARTY: sourceText = "Third Party"; break;
+ case GL_DEBUG_SOURCE_APPLICATION: sourceText = "Application"; break;
+ case GL_DEBUG_SOURCE_OTHER: sourceText = "Other"; break;
+ default: sourceText = "UNKNOWN"; break;
+ }
+
+ std::string typeText;
+ switch (type)
+ {
+ case GL_DEBUG_TYPE_ERROR: typeText = "Error"; break;
+ case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: typeText = "Deprecated behavior"; break;
+ case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: typeText = "Undefined behavior"; break;
+ case GL_DEBUG_TYPE_PORTABILITY: typeText = "Portability"; break;
+ case GL_DEBUG_TYPE_PERFORMANCE: typeText = "Performance"; break;
+ case GL_DEBUG_TYPE_OTHER: typeText = "Other"; break;
+ case GL_DEBUG_TYPE_MARKER: typeText = "Marker"; break;
+ default: typeText = "UNKNOWN"; break;
+ }
+
+ std::string severityText;
+ switch (severity)
+ {
+ case GL_DEBUG_SEVERITY_HIGH: severityText = "High"; break;
+ case GL_DEBUG_SEVERITY_MEDIUM: severityText = "Medium"; break;
+ case GL_DEBUG_SEVERITY_LOW: severityText = "Low"; break;
+ case GL_DEBUG_SEVERITY_NOTIFICATION: severityText = "Notification"; break;
+ default: severityText = "UNKNOWN"; break;
+ }
+
+ ERR("\n\tSource: %s\n\tType: %s\n\tID: %d\n\tSeverity: %s\n\tMessage: %s", sourceText.c_str(), typeText.c_str(), id,
+ severityText.c_str(), message);
+}
+#endif
+
+namespace rx
+{
+
+RendererGL::RendererGL(const FunctionsGL *functions, const egl::AttributeMap &attribMap)
+ : mMaxSupportedESVersion(0, 0),
+ mFunctions(functions),
+ mStateManager(nullptr),
+ mBlitter(nullptr),
+ mHasDebugOutput(false),
+ mSkipDrawCalls(false),
+ mCapsInitialized(false)
+{
+ ASSERT(mFunctions);
+ mStateManager = new StateManagerGL(mFunctions, getNativeCaps());
+ nativegl_gl::GenerateWorkarounds(mFunctions, &mWorkarounds);
+ mBlitter = new BlitGL(functions, mWorkarounds, mStateManager);
+
+ mHasDebugOutput = mFunctions->isAtLeastGL(gl::Version(4, 3)) ||
+ mFunctions->hasGLExtension("GL_KHR_debug") ||
+ mFunctions->isAtLeastGLES(gl::Version(3, 2)) ||
+ mFunctions->hasGLESExtension("GL_KHR_debug");
+#ifndef NDEBUG
+ if (mHasDebugOutput)
+ {
+ mFunctions->enable(GL_DEBUG_OUTPUT);
+ mFunctions->enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
+ mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0, nullptr, GL_TRUE);
+ mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM, 0, nullptr, GL_TRUE);
+ mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, nullptr, GL_FALSE);
+ mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, GL_FALSE);
+ mFunctions->debugMessageCallback(&LogGLDebugMessage, nullptr);
+ }
+#endif
+
+ EGLint deviceType =
+ static_cast<EGLint>(attribMap.get(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_NONE));
+ if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE)
+ {
+ mSkipDrawCalls = true;
+ }
+
+ if (mWorkarounds.initializeCurrentVertexAttributes)
+ {
+ GLint maxVertexAttribs = 0;
+ mFunctions->getIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
+
+ for (GLint i = 0; i < maxVertexAttribs; ++i)
+ {
+ mFunctions->vertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 1.0f);
+ }
+ }
+}
+
+RendererGL::~RendererGL()
+{
+ SafeDelete(mBlitter);
+ SafeDelete(mStateManager);
+}
+
+gl::Error RendererGL::flush()
+{
+ mFunctions->flush();
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RendererGL::finish()
+{
+#ifdef NDEBUG
+ if (mWorkarounds.finishDoesNotCauseQueriesToBeAvailable && mHasDebugOutput)
+ {
+ mFunctions->enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
+ }
+#endif
+
+ mFunctions->finish();
+
+#ifdef NDEBUG
+ if (mWorkarounds.finishDoesNotCauseQueriesToBeAvailable && mHasDebugOutput)
+ {
+ mFunctions->disable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
+ }
+#endif
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RendererGL::drawArrays(const gl::ContextState &data,
+ GLenum mode,
+ GLint first,
+ GLsizei count)
+{
+ ANGLE_TRY(mStateManager->setDrawArraysState(data, first, count, 0));
+
+ if (!mSkipDrawCalls)
+ {
+ mFunctions->drawArrays(mode, first, count);
+ }
+
+ return gl::NoError();
+}
+
+gl::Error RendererGL::drawArraysInstanced(const gl::ContextState &data,
+ GLenum mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount)
+{
+ ANGLE_TRY(mStateManager->setDrawArraysState(data, first, count, instanceCount));
+
+ if (!mSkipDrawCalls)
+ {
+ mFunctions->drawArraysInstanced(mode, first, count, instanceCount);
+ }
+
+ return gl::NoError();
+}
+
+gl::Error RendererGL::drawElements(const gl::ContextState &data,
+ GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ const gl::IndexRange &indexRange)
+{
+ const GLvoid *drawIndexPtr = nullptr;
+ ANGLE_TRY(mStateManager->setDrawElementsState(data, count, type, indices, 0, &drawIndexPtr));
+
+ if (!mSkipDrawCalls)
+ {
+ mFunctions->drawElements(mode, count, type, drawIndexPtr);
+ }
+
+ return gl::NoError();
+}
+
+gl::Error RendererGL::drawElementsInstanced(const gl::ContextState &data,
+ GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ GLsizei instances,
+ const gl::IndexRange &indexRange)
+{
+ const GLvoid *drawIndexPointer = nullptr;
+ ANGLE_TRY(mStateManager->setDrawElementsState(data, count, type, indices, instances,
+ &drawIndexPointer));
+
+ if (!mSkipDrawCalls)
+ {
+ mFunctions->drawElementsInstanced(mode, count, type, drawIndexPointer, instances);
+ }
+
+ return gl::NoError();
+}
+
+gl::Error RendererGL::drawRangeElements(const gl::ContextState &data,
+ GLenum mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ const gl::IndexRange &indexRange)
+{
+ const GLvoid *drawIndexPointer = nullptr;
+ ANGLE_TRY(
+ mStateManager->setDrawElementsState(data, count, type, indices, 0, &drawIndexPointer));
+
+ if (!mSkipDrawCalls)
+ {
+ mFunctions->drawRangeElements(mode, start, end, count, type, drawIndexPointer);
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+void RendererGL::stencilFillPath(const gl::ContextState &state,
+ const gl::Path *path,
+ GLenum fillMode,
+ GLuint mask)
+{
+ const auto *pathObj = GetImplAs<PathGL>(path);
+
+ mFunctions->stencilFillPathNV(pathObj->getPathID(), fillMode, mask);
+
+ ASSERT(mFunctions->getError() == GL_NO_ERROR);
+}
+
+void RendererGL::stencilStrokePath(const gl::ContextState &state,
+ const gl::Path *path,
+ GLint reference,
+ GLuint mask)
+{
+ const auto *pathObj = GetImplAs<PathGL>(path);
+
+ mFunctions->stencilStrokePathNV(pathObj->getPathID(), reference, mask);
+
+ ASSERT(mFunctions->getError() == GL_NO_ERROR);
+}
+
+void RendererGL::coverFillPath(const gl::ContextState &state,
+ const gl::Path *path,
+ GLenum coverMode)
+{
+
+ const auto *pathObj = GetImplAs<PathGL>(path);
+ mFunctions->coverFillPathNV(pathObj->getPathID(), coverMode);
+
+ ASSERT(mFunctions->getError() == GL_NO_ERROR);
+}
+
+void RendererGL::coverStrokePath(const gl::ContextState &state,
+ const gl::Path *path,
+ GLenum coverMode)
+{
+ const auto *pathObj = GetImplAs<PathGL>(path);
+ mFunctions->coverStrokePathNV(pathObj->getPathID(), coverMode);
+
+ ASSERT(mFunctions->getError() == GL_NO_ERROR);
+}
+
+void RendererGL::stencilThenCoverFillPath(const gl::ContextState &state,
+ const gl::Path *path,
+ GLenum fillMode,
+ GLuint mask,
+ GLenum coverMode)
+{
+
+ const auto *pathObj = GetImplAs<PathGL>(path);
+ mFunctions->stencilThenCoverFillPathNV(pathObj->getPathID(), fillMode, mask, coverMode);
+
+ ASSERT(mFunctions->getError() == GL_NO_ERROR);
+}
+
+void RendererGL::stencilThenCoverStrokePath(const gl::ContextState &state,
+ const gl::Path *path,
+ GLint reference,
+ GLuint mask,
+ GLenum coverMode)
+{
+
+ const auto *pathObj = GetImplAs<PathGL>(path);
+ mFunctions->stencilThenCoverStrokePathNV(pathObj->getPathID(), reference, mask, coverMode);
+
+ ASSERT(mFunctions->getError() == GL_NO_ERROR);
+}
+
+void RendererGL::coverFillPathInstanced(const gl::ContextState &state,
+ const std::vector<gl::Path *> &paths,
+ GLenum coverMode,
+ GLenum transformType,
+ const GLfloat *transformValues)
+{
+ const auto &pathObjs = GatherPaths(paths);
+
+ mFunctions->coverFillPathInstancedNV(static_cast<GLsizei>(pathObjs.size()), GL_UNSIGNED_INT,
+ &pathObjs[0], 0, coverMode, transformType,
+ transformValues);
+
+ ASSERT(mFunctions->getError() == GL_NO_ERROR);
+}
+void RendererGL::coverStrokePathInstanced(const gl::ContextState &state,
+ const std::vector<gl::Path *> &paths,
+ GLenum coverMode,
+ GLenum transformType,
+ const GLfloat *transformValues)
+{
+ const auto &pathObjs = GatherPaths(paths);
+
+ mFunctions->coverStrokePathInstancedNV(static_cast<GLsizei>(pathObjs.size()), GL_UNSIGNED_INT,
+ &pathObjs[0], 0, coverMode, transformType,
+ transformValues);
+
+ ASSERT(mFunctions->getError() == GL_NO_ERROR);
+}
+void RendererGL::stencilFillPathInstanced(const gl::ContextState &state,
+ const std::vector<gl::Path *> &paths,
+ GLenum fillMode,
+ GLuint mask,
+ GLenum transformType,
+ const GLfloat *transformValues)
+{
+ const auto &pathObjs = GatherPaths(paths);
+
+ mFunctions->stencilFillPathInstancedNV(static_cast<GLsizei>(pathObjs.size()), GL_UNSIGNED_INT,
+ &pathObjs[0], 0, fillMode, mask, transformType,
+ transformValues);
+
+ ASSERT(mFunctions->getError() == GL_NO_ERROR);
+}
+void RendererGL::stencilStrokePathInstanced(const gl::ContextState &state,
+ const std::vector<gl::Path *> &paths,
+ GLint reference,
+ GLuint mask,
+ GLenum transformType,
+ const GLfloat *transformValues)
+{
+ const auto &pathObjs = GatherPaths(paths);
+
+ mFunctions->stencilStrokePathInstancedNV(static_cast<GLsizei>(pathObjs.size()), GL_UNSIGNED_INT,
+ &pathObjs[0], 0, reference, mask, transformType,
+ transformValues);
+
+ ASSERT(mFunctions->getError() == GL_NO_ERROR);
+}
+
+void RendererGL::stencilThenCoverFillPathInstanced(const gl::ContextState &state,
+ const std::vector<gl::Path *> &paths,
+ GLenum coverMode,
+ GLenum fillMode,
+ GLuint mask,
+ GLenum transformType,
+ const GLfloat *transformValues)
+{
+ const auto &pathObjs = GatherPaths(paths);
+
+ mFunctions->stencilThenCoverFillPathInstancedNV(
+ static_cast<GLsizei>(pathObjs.size()), GL_UNSIGNED_INT, &pathObjs[0], 0, fillMode, mask,
+ coverMode, transformType, transformValues);
+
+ ASSERT(mFunctions->getError() == GL_NO_ERROR);
+}
+void RendererGL::stencilThenCoverStrokePathInstanced(const gl::ContextState &state,
+ const std::vector<gl::Path *> &paths,
+ GLenum coverMode,
+ GLint reference,
+ GLuint mask,
+ GLenum transformType,
+ const GLfloat *transformValues)
+{
+ const auto &pathObjs = GatherPaths(paths);
+
+ mFunctions->stencilThenCoverStrokePathInstancedNV(
+ static_cast<GLsizei>(pathObjs.size()), GL_UNSIGNED_INT, &pathObjs[0], 0, reference, mask,
+ coverMode, transformType, transformValues);
+
+ ASSERT(mFunctions->getError() == GL_NO_ERROR);
+}
+
+GLenum RendererGL::getResetStatus()
+{
+ return mFunctions->getGraphicsResetStatus();
+}
+
+ContextImpl *RendererGL::createContext(const gl::ContextState &state)
+{
+ return new ContextGL(state, this);
+}
+
+void RendererGL::insertEventMarker(GLsizei length, const char *marker)
+{
+ mFunctions->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 0,
+ GL_DEBUG_SEVERITY_NOTIFICATION, length, marker);
+}
+
+void RendererGL::pushGroupMarker(GLsizei length, const char *marker)
+{
+ mFunctions->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, length, marker);
+}
+
+void RendererGL::popGroupMarker()
+{
+ mFunctions->popDebugGroup();
+}
+
+std::string RendererGL::getVendorString() const
+{
+ return std::string(reinterpret_cast<const char*>(mFunctions->getString(GL_VENDOR)));
+}
+
+std::string RendererGL::getRendererDescription() const
+{
+ std::string nativeVendorString(reinterpret_cast<const char*>(mFunctions->getString(GL_VENDOR)));
+ std::string nativeRendererString(reinterpret_cast<const char*>(mFunctions->getString(GL_RENDERER)));
+
+ std::ostringstream rendererString;
+ rendererString << nativeVendorString << " " << nativeRendererString << " OpenGL";
+ if (mFunctions->standard == STANDARD_GL_ES)
+ {
+ rendererString << " ES";
+ }
+ rendererString << " " << mFunctions->version.major << "." << mFunctions->version.minor;
+ if (mFunctions->standard == STANDARD_GL_DESKTOP)
+ {
+ // Some drivers (NVIDIA) use a profile mask of 0 when in compatibility profile.
+ if ((mFunctions->profile & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) != 0 ||
+ (mFunctions->isAtLeastGL(gl::Version(3, 2)) && mFunctions->profile == 0))
+ {
+ rendererString << " compatibility";
+ }
+ else if ((mFunctions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0)
+ {
+ rendererString << " core";
+ }
+ }
+
+ return rendererString.str();
+}
+
+const gl::Version &RendererGL::getMaxSupportedESVersion() const
+{
+ // Force generation of caps
+ getNativeCaps();
+
+ return mMaxSupportedESVersion;
+}
+
+void RendererGL::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap* outTextureCaps,
+ gl::Extensions *outExtensions,
+ gl::Limitations * /* outLimitations */) const
+{
+ nativegl_gl::GenerateCaps(mFunctions, outCaps, outTextureCaps, outExtensions, &mMaxSupportedESVersion);
+}
+
+GLint RendererGL::getGPUDisjoint()
+{
+ // TODO(ewell): On GLES backends we should find a way to reliably query disjoint events
+ return 0;
+}
+
+GLint64 RendererGL::getTimestamp()
+{
+ GLint64 result = 0;
+ mFunctions->getInteger64v(GL_TIMESTAMP, &result);
+ return result;
+}
+
+void RendererGL::ensureCapsInitialized() const
+{
+ if (!mCapsInitialized)
+ {
+ generateCaps(&mNativeCaps, &mNativeTextureCaps, &mNativeExtensions, &mNativeLimitations);
+ mCapsInitialized = true;
+ }
+}
+
+const gl::Caps &RendererGL::getNativeCaps() const
+{
+ ensureCapsInitialized();
+ return mNativeCaps;
+}
+
+const gl::TextureCapsMap &RendererGL::getNativeTextureCaps() const
+{
+ ensureCapsInitialized();
+ return mNativeTextureCaps;
+}
+
+const gl::Extensions &RendererGL::getNativeExtensions() const
+{
+ ensureCapsInitialized();
+ return mNativeExtensions;
+}
+
+const gl::Limitations &RendererGL::getNativeLimitations() const
+{
+ ensureCapsInitialized();
+ return mNativeLimitations;
+}
+
+} // namespace rx
diff --git a/gfx/angle/src/libANGLE/renderer/gl/RendererGL.h b/gfx/angle/src/libANGLE/renderer/gl/RendererGL.h
new file mode 100755
index 000000000..71f012055
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/RendererGL.h
@@ -0,0 +1,194 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RendererGL.h: Defines the class interface for RendererGL.
+
+#ifndef LIBANGLE_RENDERER_GL_RENDERERGL_H_
+#define LIBANGLE_RENDERER_GL_RENDERERGL_H_
+
+#include "libANGLE/Caps.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/Version.h"
+#include "libANGLE/renderer/gl/WorkaroundsGL.h"
+
+namespace gl
+{
+class ContextState;
+struct IndexRange;
+class Path;
+}
+
+namespace egl
+{
+class AttributeMap;
+}
+
+namespace sh
+{
+struct BlockMemberInfo;
+}
+
+namespace rx
+{
+class BlitGL;
+class ContextImpl;
+class FunctionsGL;
+class StateManagerGL;
+
+class RendererGL : angle::NonCopyable
+{
+ public:
+ RendererGL(const FunctionsGL *functions, const egl::AttributeMap &attribMap);
+ ~RendererGL();
+
+ ContextImpl *createContext(const gl::ContextState &state);
+
+ gl::Error flush();
+ gl::Error finish();
+
+ gl::Error drawArrays(const gl::ContextState &data, GLenum mode, GLint first, GLsizei count);
+ gl::Error drawArraysInstanced(const gl::ContextState &data,
+ GLenum mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount);
+
+ gl::Error drawElements(const gl::ContextState &data,
+ GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ const gl::IndexRange &indexRange);
+ gl::Error drawElementsInstanced(const gl::ContextState &data,
+ GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ GLsizei instances,
+ const gl::IndexRange &indexRange);
+ gl::Error drawRangeElements(const gl::ContextState &data,
+ GLenum mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ const gl::IndexRange &indexRange);
+
+ // CHROMIUM_path_rendering implementation
+ void stencilFillPath(const gl::ContextState &state,
+ const gl::Path *path,
+ GLenum fillMode,
+ GLuint mask);
+ void stencilStrokePath(const gl::ContextState &state,
+ const gl::Path *path,
+ GLint reference,
+ GLuint mask);
+ void coverFillPath(const gl::ContextState &state, const gl::Path *path, GLenum coverMode);
+ void coverStrokePath(const gl::ContextState &state, const gl::Path *path, GLenum coverMode);
+ void stencilThenCoverFillPath(const gl::ContextState &state,
+ const gl::Path *path,
+ GLenum fillMode,
+ GLuint mask,
+ GLenum coverMode);
+ void stencilThenCoverStrokePath(const gl::ContextState &state,
+ const gl::Path *path,
+ GLint reference,
+ GLuint mask,
+ GLenum coverMode);
+ void coverFillPathInstanced(const gl::ContextState &state,
+ const std::vector<gl::Path *> &paths,
+ GLenum coverMode,
+ GLenum transformType,
+ const GLfloat *transformValues);
+ void coverStrokePathInstanced(const gl::ContextState &state,
+ const std::vector<gl::Path *> &paths,
+ GLenum coverMode,
+ GLenum transformType,
+ const GLfloat *transformValues);
+ void stencilFillPathInstanced(const gl::ContextState &state,
+ const std::vector<gl::Path *> &paths,
+ GLenum fillMode,
+ GLuint mask,
+ GLenum transformType,
+ const GLfloat *transformValues);
+ void stencilStrokePathInstanced(const gl::ContextState &state,
+ const std::vector<gl::Path *> &paths,
+ GLint reference,
+ GLuint mask,
+ GLenum transformType,
+ const GLfloat *transformValues);
+
+ void stencilThenCoverFillPathInstanced(const gl::ContextState &state,
+ const std::vector<gl::Path *> &paths,
+ GLenum coverMode,
+ GLenum fillMode,
+ GLuint mask,
+ GLenum transformType,
+ const GLfloat *transformValues);
+ void stencilThenCoverStrokePathInstanced(const gl::ContextState &state,
+ const std::vector<gl::Path *> &paths,
+ GLenum coverMode,
+ GLint reference,
+ GLuint mask,
+ GLenum transformType,
+ const GLfloat *transformValues);
+
+ GLenum getResetStatus();
+
+ // EXT_debug_marker
+ void insertEventMarker(GLsizei length, const char *marker);
+ void pushGroupMarker(GLsizei length, const char *marker);
+ void popGroupMarker();
+
+ std::string getVendorString() const;
+ std::string getRendererDescription() const;
+
+ GLint getGPUDisjoint();
+ GLint64 getTimestamp();
+
+ const gl::Version &getMaxSupportedESVersion() const;
+ const FunctionsGL *getFunctions() const { return mFunctions; }
+ StateManagerGL *getStateManager() const { return mStateManager; }
+ const WorkaroundsGL &getWorkarounds() const { return mWorkarounds; }
+ BlitGL *getBlitter() const { return mBlitter; }
+
+ const gl::Caps &getNativeCaps() const;
+ const gl::TextureCapsMap &getNativeTextureCaps() const;
+ const gl::Extensions &getNativeExtensions() const;
+ const gl::Limitations &getNativeLimitations() const;
+
+ private:
+ void ensureCapsInitialized() const;
+ void generateCaps(gl::Caps *outCaps,
+ gl::TextureCapsMap *outTextureCaps,
+ gl::Extensions *outExtensions,
+ gl::Limitations *outLimitations) const;
+
+ mutable gl::Version mMaxSupportedESVersion;
+
+ const FunctionsGL *mFunctions;
+ StateManagerGL *mStateManager;
+
+ BlitGL *mBlitter;
+
+ WorkaroundsGL mWorkarounds;
+
+ bool mHasDebugOutput;
+
+ // For performance debugging
+ bool mSkipDrawCalls;
+
+ mutable bool mCapsInitialized;
+ mutable gl::Caps mNativeCaps;
+ mutable gl::TextureCapsMap mNativeTextureCaps;
+ mutable gl::Extensions mNativeExtensions;
+ mutable gl::Limitations mNativeLimitations;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_GL_RENDERERGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/SamplerGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/SamplerGL.cpp
new file mode 100755
index 000000000..2a6d81583
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/SamplerGL.cpp
@@ -0,0 +1,73 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// SamplerGL.cpp: Defines the rx::SamplerGL class, an implementation of SamplerImpl.
+
+#include "libANGLE/renderer/gl/SamplerGL.h"
+
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+#include "libANGLE/renderer/gl/StateManagerGL.h"
+
+namespace
+{
+
+template <typename T>
+static inline void SyncSamplerStateMember(const rx::FunctionsGL *functions,
+ GLuint sampler,
+ const gl::SamplerState &newState,
+ gl::SamplerState &curState,
+ GLenum name,
+ T(gl::SamplerState::*samplerMember))
+{
+ if (curState.*samplerMember != newState.*samplerMember)
+ {
+ curState.*samplerMember = newState.*samplerMember;
+ functions->samplerParameterf(sampler, name, static_cast<GLfloat>(curState.*samplerMember));
+ }
+}
+}
+
+namespace rx
+{
+
+SamplerGL::SamplerGL(const FunctionsGL *functions, StateManagerGL *stateManager)
+ : SamplerImpl(),
+ mFunctions(functions),
+ mStateManager(stateManager),
+ mAppliedSamplerState(),
+ mSamplerID(0)
+{
+ mFunctions->genSamplers(1, &mSamplerID);
+}
+
+SamplerGL::~SamplerGL()
+{
+ mStateManager->deleteSampler(mSamplerID);
+ mSamplerID = 0;
+}
+
+void SamplerGL::syncState(const gl::SamplerState &samplerState) const
+{
+ // clang-format off
+ SyncSamplerStateMember(mFunctions, mSamplerID, samplerState, mAppliedSamplerState, GL_TEXTURE_MIN_FILTER, &gl::SamplerState::minFilter);
+ SyncSamplerStateMember(mFunctions, mSamplerID, samplerState, mAppliedSamplerState, GL_TEXTURE_MAG_FILTER, &gl::SamplerState::magFilter);
+ SyncSamplerStateMember(mFunctions, mSamplerID, samplerState, mAppliedSamplerState, GL_TEXTURE_WRAP_S, &gl::SamplerState::wrapS);
+ SyncSamplerStateMember(mFunctions, mSamplerID, samplerState, mAppliedSamplerState, GL_TEXTURE_WRAP_T, &gl::SamplerState::wrapT);
+ SyncSamplerStateMember(mFunctions, mSamplerID, samplerState, mAppliedSamplerState, GL_TEXTURE_WRAP_R, &gl::SamplerState::wrapR);
+ SyncSamplerStateMember(mFunctions, mSamplerID, samplerState, mAppliedSamplerState, GL_TEXTURE_MAX_ANISOTROPY_EXT, &gl::SamplerState::maxAnisotropy);
+ SyncSamplerStateMember(mFunctions, mSamplerID, samplerState, mAppliedSamplerState, GL_TEXTURE_MIN_LOD, &gl::SamplerState::minLod);
+ SyncSamplerStateMember(mFunctions, mSamplerID, samplerState, mAppliedSamplerState, GL_TEXTURE_MAX_LOD, &gl::SamplerState::maxLod);
+ SyncSamplerStateMember(mFunctions, mSamplerID, samplerState, mAppliedSamplerState, GL_TEXTURE_COMPARE_MODE, &gl::SamplerState::compareMode);
+ SyncSamplerStateMember(mFunctions, mSamplerID, samplerState, mAppliedSamplerState, GL_TEXTURE_COMPARE_FUNC, &gl::SamplerState::compareFunc);
+ SyncSamplerStateMember(mFunctions, mSamplerID, samplerState, mAppliedSamplerState, GL_TEXTURE_SRGB_DECODE_EXT, &gl::SamplerState::sRGBDecode);
+ // clang-format on
+}
+
+GLuint SamplerGL::getSamplerID() const
+{
+ return mSamplerID;
+}
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/SamplerGL.h b/gfx/angle/src/libANGLE/renderer/gl/SamplerGL.h
new file mode 100755
index 000000000..c3fcfde80
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/SamplerGL.h
@@ -0,0 +1,40 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// SamplerGL.h: Defines the rx::SamplerGL class, an implementation of SamplerImpl.
+
+#ifndef LIBANGLE_RENDERER_GL_SAMPLERGL_H_
+#define LIBANGLE_RENDERER_GL_SAMPLERGL_H_
+
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/SamplerImpl.h"
+
+namespace rx
+{
+
+class FunctionsGL;
+class StateManagerGL;
+
+class SamplerGL : public SamplerImpl
+{
+ public:
+ SamplerGL(const FunctionsGL *functions, StateManagerGL *stateManager);
+ ~SamplerGL() override;
+
+ void syncState(const gl::SamplerState &samplerState) const;
+
+ GLuint getSamplerID() const;
+
+ private:
+ const FunctionsGL *mFunctions;
+ StateManagerGL *mStateManager;
+
+ mutable gl::SamplerState mAppliedSamplerState;
+ GLuint mSamplerID;
+};
+}
+
+#endif // LIBANGLE_RENDERER_GL_SAMPLERGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/ShaderGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/ShaderGL.cpp
new file mode 100755
index 000000000..c9145b00a
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/ShaderGL.cpp
@@ -0,0 +1,143 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ShaderGL.cpp: Implements the class methods for ShaderGL.
+
+#include "libANGLE/renderer/gl/ShaderGL.h"
+
+#include "common/debug.h"
+#include "libANGLE/Compiler.h"
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+#include "libANGLE/renderer/gl/RendererGL.h"
+#include "libANGLE/renderer/gl/WorkaroundsGL.h"
+
+#include <iostream>
+
+namespace rx
+{
+
+ShaderGL::ShaderGL(const gl::ShaderState &data,
+ const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds)
+ : ShaderImpl(data), mFunctions(functions), mWorkarounds(workarounds), mShaderID(0)
+{
+ ASSERT(mFunctions);
+}
+
+ShaderGL::~ShaderGL()
+{
+ if (mShaderID != 0)
+ {
+ mFunctions->deleteShader(mShaderID);
+ mShaderID = 0;
+ }
+}
+
+ShCompileOptions ShaderGL::prepareSourceAndReturnOptions(std::stringstream *sourceStream,
+ std::string * /*sourcePath*/)
+{
+ // Reset the previous state
+ if (mShaderID != 0)
+ {
+ mFunctions->deleteShader(mShaderID);
+ mShaderID = 0;
+ }
+
+ *sourceStream << mData.getSource();
+
+ ShCompileOptions options = SH_INIT_GL_POSITION;
+
+ if (mWorkarounds.doWhileGLSLCausesGPUHang)
+ {
+ options |= SH_REWRITE_DO_WHILE_LOOPS;
+ }
+
+ if (mWorkarounds.emulateAbsIntFunction)
+ {
+ options |= SH_EMULATE_ABS_INT_FUNCTION;
+ }
+
+ if (mWorkarounds.addAndTrueToLoopCondition)
+ {
+ options |= SH_ADD_AND_TRUE_TO_LOOP_CONDITION;
+ }
+
+ if (mWorkarounds.emulateIsnanFloat)
+ {
+ options |= SH_EMULATE_ISNAN_FLOAT_FUNCTION;
+ }
+
+ if (mWorkarounds.useUnusedBlocksWithStandardOrSharedLayout)
+ {
+ options |= SH_USE_UNUSED_STANDARD_SHARED_BLOCKS;
+ }
+
+ if (mWorkarounds.dontRemoveInvariantForFragmentInput)
+ {
+ options |= SH_DONT_REMOVE_INVARIANT_FOR_FRAGMENT_INPUT;
+ }
+
+ if (mWorkarounds.removeInvariantAndCentroidForESSL3)
+ {
+ options |= SH_REMOVE_INVARIANT_AND_CENTROID_FOR_ESSL3;
+ }
+
+ return options;
+}
+
+bool ShaderGL::postTranslateCompile(gl::Compiler *compiler, std::string *infoLog)
+{
+ // Translate the ESSL into GLSL
+ const char *translatedSourceCString = mData.getTranslatedSource().c_str();
+
+ // Generate a shader object and set the source
+ mShaderID = mFunctions->createShader(mData.getShaderType());
+ mFunctions->shaderSource(mShaderID, 1, &translatedSourceCString, nullptr);
+ mFunctions->compileShader(mShaderID);
+
+ // Check for compile errors from the native driver
+ GLint compileStatus = GL_FALSE;
+ mFunctions->getShaderiv(mShaderID, GL_COMPILE_STATUS, &compileStatus);
+ if (compileStatus == GL_FALSE)
+ {
+ // Compilation failed, put the error into the info log
+ GLint infoLogLength = 0;
+ mFunctions->getShaderiv(mShaderID, GL_INFO_LOG_LENGTH, &infoLogLength);
+
+ // Info log length includes the null terminator, so 1 means that the info log is an empty
+ // string.
+ if (infoLogLength > 1)
+ {
+ std::vector<char> buf(infoLogLength);
+ mFunctions->getShaderInfoLog(mShaderID, infoLogLength, nullptr, &buf[0]);
+
+ mFunctions->deleteShader(mShaderID);
+ mShaderID = 0;
+
+ *infoLog = &buf[0];
+ TRACE("\n%s", infoLog->c_str());
+ }
+ else
+ {
+ TRACE("\nShader compilation failed with no info log.");
+ }
+ return false;
+ }
+
+ return true;
+}
+
+std::string ShaderGL::getDebugInfo() const
+{
+ return std::string();
+}
+
+GLuint ShaderGL::getShaderID() const
+{
+ return mShaderID;
+}
+
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/ShaderGL.h b/gfx/angle/src/libANGLE/renderer/gl/ShaderGL.h
new file mode 100755
index 000000000..0ecd89ce6
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/ShaderGL.h
@@ -0,0 +1,44 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ShaderGL.h: Defines the class interface for ShaderGL.
+
+#ifndef LIBANGLE_RENDERER_GL_SHADERGL_H_
+#define LIBANGLE_RENDERER_GL_SHADERGL_H_
+
+#include "libANGLE/renderer/ShaderImpl.h"
+
+namespace rx
+{
+class FunctionsGL;
+struct WorkaroundsGL;
+
+class ShaderGL : public ShaderImpl
+{
+ public:
+ ShaderGL(const gl::ShaderState &data,
+ const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds);
+ ~ShaderGL() override;
+
+ // ShaderImpl implementation
+ ShCompileOptions prepareSourceAndReturnOptions(std::stringstream *sourceStream,
+ std::string *sourcePath) override;
+ bool postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) override;
+ std::string getDebugInfo() const override;
+
+ GLuint getShaderID() const;
+
+ private:
+ const FunctionsGL *mFunctions;
+ const WorkaroundsGL &mWorkarounds;
+
+ GLuint mShaderID;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_SHADERGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/StateManagerGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/StateManagerGL.cpp
new file mode 100755
index 000000000..3a227906f
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/StateManagerGL.cpp
@@ -0,0 +1,1742 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// StateManagerGL.h: Defines a class for caching applied OpenGL state
+
+#include "libANGLE/renderer/gl/StateManagerGL.h"
+
+#include <limits>
+#include <string.h>
+
+#include "common/BitSetIterator.h"
+#include "common/mathutil.h"
+#include "common/matrix_utils.h"
+#include "libANGLE/ContextState.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/TransformFeedback.h"
+#include "libANGLE/VertexArray.h"
+#include "libANGLE/Query.h"
+#include "libANGLE/renderer/gl/BufferGL.h"
+#include "libANGLE/renderer/gl/FramebufferGL.h"
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+#include "libANGLE/renderer/gl/ProgramGL.h"
+#include "libANGLE/renderer/gl/SamplerGL.h"
+#include "libANGLE/renderer/gl/TextureGL.h"
+#include "libANGLE/renderer/gl/TransformFeedbackGL.h"
+#include "libANGLE/renderer/gl/VertexArrayGL.h"
+#include "libANGLE/renderer/gl/QueryGL.h"
+
+namespace rx
+{
+
+static const GLenum QueryTypes[] = {GL_ANY_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
+ GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_TIME_ELAPSED,
+ GL_COMMANDS_COMPLETED_CHROMIUM};
+
+StateManagerGL::IndexedBufferBinding::IndexedBufferBinding() : offset(0), size(0), buffer(0)
+{
+}
+
+StateManagerGL::StateManagerGL(const FunctionsGL *functions, const gl::Caps &rendererCaps)
+ : mFunctions(functions),
+ mProgram(0),
+ mVAO(0),
+ mVertexAttribCurrentValues(rendererCaps.maxVertexAttributes),
+ mBuffers(),
+ mIndexedBuffers(),
+ mTextureUnitIndex(0),
+ mTextures(),
+ mSamplers(rendererCaps.maxCombinedTextureImageUnits, 0),
+ mTransformFeedback(0),
+ mQueries(),
+ mPrevDrawTransformFeedback(nullptr),
+ mCurrentQueries(),
+ mPrevDrawContext(0),
+ mUnpackAlignment(4),
+ mUnpackRowLength(0),
+ mUnpackSkipRows(0),
+ mUnpackSkipPixels(0),
+ mUnpackImageHeight(0),
+ mUnpackSkipImages(0),
+ mPackAlignment(4),
+ mPackRowLength(0),
+ mPackSkipRows(0),
+ mPackSkipPixels(0),
+ mFramebuffers(angle::FramebufferBindingSingletonMax, 0),
+ mRenderbuffer(0),
+ mScissorTestEnabled(false),
+ mScissor(0, 0, 0, 0),
+ mViewport(0, 0, 0, 0),
+ mNear(0.0f),
+ mFar(1.0f),
+ mBlendEnabled(false),
+ mBlendColor(0, 0, 0, 0),
+ mSourceBlendRGB(GL_ONE),
+ mDestBlendRGB(GL_ZERO),
+ mSourceBlendAlpha(GL_ONE),
+ mDestBlendAlpha(GL_ZERO),
+ mBlendEquationRGB(GL_FUNC_ADD),
+ mBlendEquationAlpha(GL_FUNC_ADD),
+ mColorMaskRed(true),
+ mColorMaskGreen(true),
+ mColorMaskBlue(true),
+ mColorMaskAlpha(true),
+ mSampleAlphaToCoverageEnabled(false),
+ mSampleCoverageEnabled(false),
+ mSampleCoverageValue(1.0f),
+ mSampleCoverageInvert(false),
+ mDepthTestEnabled(false),
+ mDepthFunc(GL_LESS),
+ mDepthMask(true),
+ mStencilTestEnabled(false),
+ mStencilFrontFunc(GL_ALWAYS),
+ mStencilFrontRef(0),
+ mStencilFrontValueMask(static_cast<GLuint>(-1)),
+ mStencilFrontStencilFailOp(GL_KEEP),
+ mStencilFrontStencilPassDepthFailOp(GL_KEEP),
+ mStencilFrontStencilPassDepthPassOp(GL_KEEP),
+ mStencilFrontWritemask(static_cast<GLuint>(-1)),
+ mStencilBackFunc(GL_ALWAYS),
+ mStencilBackRef(0),
+ mStencilBackValueMask(static_cast<GLuint>(-1)),
+ mStencilBackStencilFailOp(GL_KEEP),
+ mStencilBackStencilPassDepthFailOp(GL_KEEP),
+ mStencilBackStencilPassDepthPassOp(GL_KEEP),
+ mStencilBackWritemask(static_cast<GLuint>(-1)),
+ mCullFaceEnabled(false),
+ mCullFace(GL_BACK),
+ mFrontFace(GL_CCW),
+ mPolygonOffsetFillEnabled(false),
+ mPolygonOffsetFactor(0.0f),
+ mPolygonOffsetUnits(0.0f),
+ mRasterizerDiscardEnabled(false),
+ mLineWidth(1.0f),
+ mPrimitiveRestartEnabled(false),
+ mClearColor(0.0f, 0.0f, 0.0f, 0.0f),
+ mClearDepth(1.0f),
+ mClearStencil(0),
+ mFramebufferSRGBEnabled(false),
+ mDitherEnabled(true),
+ mTextureCubemapSeamlessEnabled(false),
+ mMultisamplingEnabled(true),
+ mSampleAlphaToOneEnabled(false),
+ mCoverageModulation(GL_NONE),
+ mPathStencilFunc(GL_ALWAYS),
+ mPathStencilRef(0),
+ mPathStencilMask(std::numeric_limits<GLuint>::max()),
+ mLocalDirtyBits()
+{
+ ASSERT(mFunctions);
+
+ mTextures[GL_TEXTURE_2D].resize(rendererCaps.maxCombinedTextureImageUnits);
+ mTextures[GL_TEXTURE_CUBE_MAP].resize(rendererCaps.maxCombinedTextureImageUnits);
+ mTextures[GL_TEXTURE_2D_ARRAY].resize(rendererCaps.maxCombinedTextureImageUnits);
+ mTextures[GL_TEXTURE_3D].resize(rendererCaps.maxCombinedTextureImageUnits);
+
+ mIndexedBuffers[GL_UNIFORM_BUFFER].resize(rendererCaps.maxCombinedUniformBlocks);
+
+ for (GLenum queryType : QueryTypes)
+ {
+ mQueries[queryType] = 0;
+ }
+
+ // Initialize point sprite state for desktop GL
+ if (mFunctions->standard == STANDARD_GL_DESKTOP)
+ {
+ mFunctions->enable(GL_PROGRAM_POINT_SIZE);
+
+ // GL_POINT_SPRITE was deprecated in the core profile. Point rasterization is always
+ // performed
+ // as though POINT_SPRITE were enabled.
+ if ((mFunctions->profile & GL_CONTEXT_CORE_PROFILE_BIT) == 0)
+ {
+ mFunctions->enable(GL_POINT_SPRITE);
+ }
+ }
+
+ angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
+ angle::Matrix<GLfloat>::setToIdentity(mPathMatrixMV);
+}
+
+void StateManagerGL::deleteProgram(GLuint program)
+{
+ if (program != 0)
+ {
+ if (mProgram == program)
+ {
+ useProgram(0);
+ }
+
+ mFunctions->deleteProgram(program);
+ }
+}
+
+void StateManagerGL::deleteVertexArray(GLuint vao)
+{
+ if (vao != 0)
+ {
+ if (mVAO == vao)
+ {
+ bindVertexArray(0, 0);
+ }
+
+ mFunctions->deleteVertexArrays(1, &vao);
+ }
+}
+
+void StateManagerGL::deleteTexture(GLuint texture)
+{
+ if (texture != 0)
+ {
+ for (const auto &textureTypeIter : mTextures)
+ {
+ const std::vector<GLuint> &textureVector = textureTypeIter.second;
+ for (size_t textureUnitIndex = 0; textureUnitIndex < textureVector.size(); textureUnitIndex++)
+ {
+ if (textureVector[textureUnitIndex] == texture)
+ {
+ activeTexture(textureUnitIndex);
+ bindTexture(textureTypeIter.first, 0);
+ }
+ }
+ }
+
+ mFunctions->deleteTextures(1, &texture);
+ }
+}
+
+void StateManagerGL::deleteSampler(GLuint sampler)
+{
+ if (sampler != 0)
+ {
+ for (size_t unit = 0; unit < mSamplers.size(); unit++)
+ {
+ if (mSamplers[unit] == sampler)
+ {
+ bindSampler(unit, 0);
+ }
+ }
+
+ mFunctions->deleteSamplers(1, &sampler);
+ }
+}
+
+void StateManagerGL::deleteBuffer(GLuint buffer)
+{
+ if (buffer != 0)
+ {
+ for (const auto &bufferTypeIter : mBuffers)
+ {
+ if (bufferTypeIter.second == buffer)
+ {
+ bindBuffer(bufferTypeIter.first, 0);
+ }
+ }
+
+ for (const auto &bufferTypeIter : mIndexedBuffers)
+ {
+ for (size_t bindIndex = 0; bindIndex < bufferTypeIter.second.size(); bindIndex++)
+ {
+ if (bufferTypeIter.second[bindIndex].buffer == buffer)
+ {
+ bindBufferBase(bufferTypeIter.first, bindIndex, 0);
+ }
+ }
+ }
+
+ mFunctions->deleteBuffers(1, &buffer);
+ }
+}
+
+void StateManagerGL::deleteFramebuffer(GLuint fbo)
+{
+ if (fbo != 0)
+ {
+ for (size_t binding = 0; binding < mFramebuffers.size(); ++binding)
+ {
+ if (mFramebuffers[binding] == fbo)
+ {
+ GLenum enumValue = angle::FramebufferBindingToEnum(
+ static_cast<angle::FramebufferBinding>(binding));
+ bindFramebuffer(enumValue, 0);
+ }
+ mFunctions->deleteFramebuffers(1, &fbo);
+ }
+ }
+}
+
+void StateManagerGL::deleteRenderbuffer(GLuint rbo)
+{
+ if (rbo != 0)
+ {
+ if (mRenderbuffer == rbo)
+ {
+ bindRenderbuffer(GL_RENDERBUFFER, 0);
+ }
+
+ mFunctions->deleteRenderbuffers(1, &rbo);
+ }
+}
+
+void StateManagerGL::deleteTransformFeedback(GLuint transformFeedback)
+{
+ if (transformFeedback != 0)
+ {
+ if (mTransformFeedback == transformFeedback)
+ {
+ bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
+ }
+
+ if (mPrevDrawTransformFeedback != nullptr &&
+ mPrevDrawTransformFeedback->getTransformFeedbackID() == transformFeedback)
+ {
+ mPrevDrawTransformFeedback = nullptr;
+ }
+
+ mFunctions->deleteTransformFeedbacks(1, &transformFeedback);
+ }
+}
+
+void StateManagerGL::deleteQuery(GLuint query)
+{
+ if (query != 0)
+ {
+ for (auto &activeQuery : mQueries)
+ {
+ GLuint activeQueryID = activeQuery.second;
+ if (activeQueryID == query)
+ {
+ GLenum type = activeQuery.first;
+ endQuery(type, query);
+ }
+ }
+ }
+}
+
+void StateManagerGL::useProgram(GLuint program)
+{
+ if (mProgram != program)
+ {
+ forceUseProgram(program);
+ }
+}
+
+void StateManagerGL::forceUseProgram(GLuint program)
+{
+ mProgram = program;
+ mFunctions->useProgram(mProgram);
+}
+
+void StateManagerGL::bindVertexArray(GLuint vao, GLuint elementArrayBuffer)
+{
+ if (mVAO != vao)
+ {
+ mVAO = vao;
+ mBuffers[GL_ELEMENT_ARRAY_BUFFER] = elementArrayBuffer;
+ mFunctions->bindVertexArray(vao);
+ }
+}
+
+void StateManagerGL::bindBuffer(GLenum type, GLuint buffer)
+{
+ if (mBuffers[type] != buffer)
+ {
+ mBuffers[type] = buffer;
+ mFunctions->bindBuffer(type, buffer);
+ }
+}
+
+void StateManagerGL::bindBufferBase(GLenum type, size_t index, GLuint buffer)
+{
+ auto &binding = mIndexedBuffers[type][index];
+ if (binding.buffer != buffer || binding.offset != static_cast<size_t>(-1) ||
+ binding.size != static_cast<size_t>(-1))
+ {
+ binding.buffer = buffer;
+ binding.offset = static_cast<size_t>(-1);
+ binding.size = static_cast<size_t>(-1);
+ mFunctions->bindBufferBase(type, static_cast<GLuint>(index), buffer);
+ }
+}
+
+void StateManagerGL::bindBufferRange(GLenum type,
+ size_t index,
+ GLuint buffer,
+ size_t offset,
+ size_t size)
+{
+ auto &binding = mIndexedBuffers[type][index];
+ if (binding.buffer != buffer || binding.offset != offset || binding.size != size)
+ {
+ binding.buffer = buffer;
+ binding.offset = offset;
+ binding.size = size;
+ mFunctions->bindBufferRange(type, static_cast<GLuint>(index), buffer, offset, size);
+ }
+}
+
+void StateManagerGL::activeTexture(size_t unit)
+{
+ if (mTextureUnitIndex != unit)
+ {
+ mTextureUnitIndex = unit;
+ mFunctions->activeTexture(GL_TEXTURE0 + static_cast<GLenum>(mTextureUnitIndex));
+ }
+}
+
+void StateManagerGL::bindTexture(GLenum type, GLuint texture)
+{
+ if (mTextures[type][mTextureUnitIndex] != texture)
+ {
+ mTextures[type][mTextureUnitIndex] = texture;
+ mFunctions->bindTexture(type, texture);
+ }
+}
+
+void StateManagerGL::bindSampler(size_t unit, GLuint sampler)
+{
+ if (mSamplers[unit] != sampler)
+ {
+ mSamplers[unit] = sampler;
+ mFunctions->bindSampler(static_cast<GLuint>(unit), sampler);
+ }
+}
+
+void StateManagerGL::setPixelUnpackState(const gl::PixelUnpackState &unpack)
+{
+ GLuint unpackBufferID = 0;
+ const gl::Buffer *unpackBuffer = unpack.pixelBuffer.get();
+ if (unpackBuffer != nullptr)
+ {
+ unpackBufferID = GetImplAs<BufferGL>(unpackBuffer)->getBufferID();
+ }
+ setPixelUnpackState(unpack.alignment, unpack.rowLength, unpack.skipRows, unpack.skipPixels,
+ unpack.imageHeight, unpack.skipImages, unpackBufferID);
+}
+
+void StateManagerGL::setPixelUnpackState(GLint alignment,
+ GLint rowLength,
+ GLint skipRows,
+ GLint skipPixels,
+ GLint imageHeight,
+ GLint skipImages,
+ GLuint unpackBuffer)
+{
+ if (mUnpackAlignment != alignment)
+ {
+ mUnpackAlignment = alignment;
+ mFunctions->pixelStorei(GL_UNPACK_ALIGNMENT, mUnpackAlignment);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_ALIGNMENT);
+ }
+
+ if (mUnpackRowLength != rowLength)
+ {
+ mUnpackRowLength = rowLength;
+ mFunctions->pixelStorei(GL_UNPACK_ROW_LENGTH, mUnpackRowLength);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_ROW_LENGTH);
+ }
+
+ if (mUnpackSkipRows != skipRows)
+ {
+ mUnpackSkipRows = skipRows;
+ mFunctions->pixelStorei(GL_UNPACK_SKIP_ROWS, mUnpackSkipRows);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_SKIP_ROWS);
+ }
+
+ if (mUnpackSkipPixels != skipPixels)
+ {
+ mUnpackSkipPixels = skipPixels;
+ mFunctions->pixelStorei(GL_UNPACK_SKIP_PIXELS, mUnpackSkipPixels);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
+ }
+
+ if (mUnpackImageHeight != imageHeight)
+ {
+ mUnpackImageHeight = imageHeight;
+ mFunctions->pixelStorei(GL_UNPACK_IMAGE_HEIGHT, mUnpackImageHeight);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
+ }
+
+ if (mUnpackSkipImages != skipImages)
+ {
+ mUnpackSkipImages = skipImages;
+ mFunctions->pixelStorei(GL_UNPACK_SKIP_IMAGES, mUnpackSkipImages);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
+ }
+
+ bindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer);
+}
+
+void StateManagerGL::setPixelPackState(const gl::PixelPackState &pack)
+{
+ GLuint packBufferID = 0;
+ const gl::Buffer *packBuffer = pack.pixelBuffer.get();
+ if (packBuffer != nullptr)
+ {
+ packBufferID = GetImplAs<BufferGL>(packBuffer)->getBufferID();
+ }
+ setPixelPackState(pack.alignment, pack.rowLength, pack.skipRows, pack.skipPixels, packBufferID);
+}
+
+void StateManagerGL::setPixelPackState(GLint alignment,
+ GLint rowLength,
+ GLint skipRows,
+ GLint skipPixels,
+ GLuint packBuffer)
+{
+ if (mPackAlignment != alignment)
+ {
+ mPackAlignment = alignment;
+ mFunctions->pixelStorei(GL_PACK_ALIGNMENT, mPackAlignment);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_PACK_ALIGNMENT);
+ }
+
+ if (mPackRowLength != rowLength)
+ {
+ mPackRowLength = rowLength;
+ mFunctions->pixelStorei(GL_PACK_ROW_LENGTH, mPackRowLength);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_ROW_LENGTH);
+ }
+
+ if (mPackSkipRows != skipRows)
+ {
+ mPackSkipRows = skipRows;
+ mFunctions->pixelStorei(GL_PACK_SKIP_ROWS, mPackSkipRows);
+
+ // TODO: set dirty bit once one exists
+ }
+
+ if (mPackSkipPixels != skipPixels)
+ {
+ mPackSkipPixels = skipPixels;
+ mFunctions->pixelStorei(GL_PACK_SKIP_PIXELS, mPackSkipPixels);
+
+ // TODO: set dirty bit once one exists
+ }
+
+ bindBuffer(GL_PIXEL_PACK_BUFFER, packBuffer);
+}
+
+void StateManagerGL::bindFramebuffer(GLenum type, GLuint framebuffer)
+{
+ if (type == GL_FRAMEBUFFER)
+ {
+ if (mFramebuffers[angle::FramebufferBindingRead] != framebuffer ||
+ mFramebuffers[angle::FramebufferBindingDraw] != framebuffer)
+ {
+ mFramebuffers[angle::FramebufferBindingRead] = framebuffer;
+ mFramebuffers[angle::FramebufferBindingDraw] = framebuffer;
+ mFunctions->bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+ }
+ }
+ else
+ {
+ angle::FramebufferBinding binding = angle::EnumToFramebufferBinding(type);
+
+ if (mFramebuffers[binding] != framebuffer)
+ {
+ mFramebuffers[binding] = framebuffer;
+ mFunctions->bindFramebuffer(type, framebuffer);
+ }
+ }
+}
+
+void StateManagerGL::bindRenderbuffer(GLenum type, GLuint renderbuffer)
+{
+ ASSERT(type == GL_RENDERBUFFER);
+ if (mRenderbuffer != renderbuffer)
+ {
+ mRenderbuffer = renderbuffer;
+ mFunctions->bindRenderbuffer(type, mRenderbuffer);
+ }
+}
+
+void StateManagerGL::bindTransformFeedback(GLenum type, GLuint transformFeedback)
+{
+ ASSERT(type == GL_TRANSFORM_FEEDBACK);
+ if (mTransformFeedback != transformFeedback)
+ {
+ // Pause the current transform feedback if one is active.
+ // To handle virtualized contexts, StateManagerGL needs to be able to bind a new transform
+ // feedback at any time, even if there is one active.
+ if (mPrevDrawTransformFeedback != nullptr &&
+ mPrevDrawTransformFeedback->getTransformFeedbackID() != transformFeedback)
+ {
+ mPrevDrawTransformFeedback->syncPausedState(true);
+ mPrevDrawTransformFeedback = nullptr;
+ }
+
+ mTransformFeedback = transformFeedback;
+ mFunctions->bindTransformFeedback(type, mTransformFeedback);
+ }
+}
+
+void StateManagerGL::beginQuery(GLenum type, GLuint query)
+{
+ // Make sure this is a valid query type and there is no current active query of this type
+ ASSERT(mQueries.find(type) != mQueries.end());
+ ASSERT(mQueries[type] == 0);
+ ASSERT(query != 0);
+
+ mQueries[type] = query;
+ mFunctions->beginQuery(type, query);
+}
+
+void StateManagerGL::endQuery(GLenum type, GLuint query)
+{
+ ASSERT(mQueries[type] == query);
+ mQueries[type] = 0;
+ mFunctions->endQuery(type);
+}
+
+void StateManagerGL::onBeginQuery(QueryGL *query)
+{
+ mCurrentQueries.insert(query);
+}
+
+void StateManagerGL::onDeleteQueryObject(QueryGL *query)
+{
+ mCurrentQueries.erase(query);
+}
+
+gl::Error StateManagerGL::setDrawArraysState(const gl::ContextState &data,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount)
+{
+ const gl::State &state = data.getState();
+
+ const gl::Program *program = state.getProgram();
+
+ const gl::VertexArray *vao = state.getVertexArray();
+ const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(vao);
+
+ gl::Error error = vaoGL->syncDrawArraysState(program->getActiveAttribLocationsMask(), first,
+ count, instanceCount);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ bindVertexArray(vaoGL->getVertexArrayID(), vaoGL->getAppliedElementArrayBufferID());
+
+ return setGenericDrawState(data);
+}
+
+gl::Error StateManagerGL::setDrawElementsState(const gl::ContextState &data,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ GLsizei instanceCount,
+ const GLvoid **outIndices)
+{
+ const gl::State &state = data.getState();
+
+ const gl::Program *program = state.getProgram();
+
+ const gl::VertexArray *vao = state.getVertexArray();
+ const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(vao);
+
+ gl::Error error =
+ vaoGL->syncDrawElementsState(program->getActiveAttribLocationsMask(), count, type, indices,
+ instanceCount, state.isPrimitiveRestartEnabled(), outIndices);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ bindVertexArray(vaoGL->getVertexArrayID(), vaoGL->getAppliedElementArrayBufferID());
+
+ return setGenericDrawState(data);
+}
+
+gl::Error StateManagerGL::pauseTransformFeedback(const gl::ContextState &data)
+{
+ // If the context is going to be changed, pause the previous context's transform feedback
+ if (data.getContext() != mPrevDrawContext)
+ {
+ if (mPrevDrawTransformFeedback != nullptr)
+ {
+ mPrevDrawTransformFeedback->syncPausedState(true);
+ }
+ }
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error StateManagerGL::onMakeCurrent(const gl::ContextState &data)
+{
+ const gl::State &state = data.getState();
+
+ // If the context has changed, pause the previous context's queries
+ if (data.getContext() != mPrevDrawContext)
+ {
+ for (QueryGL *prevQuery : mCurrentQueries)
+ {
+ prevQuery->pause();
+ }
+ }
+ mCurrentQueries.clear();
+ mPrevDrawTransformFeedback = nullptr;
+ mPrevDrawContext = data.getContext();
+
+ // Set the current query state
+ for (GLenum queryType : QueryTypes)
+ {
+ gl::Query *query = state.getActiveQuery(queryType);
+ if (query != nullptr)
+ {
+ QueryGL *queryGL = GetImplAs<QueryGL>(query);
+ queryGL->resume();
+
+ mCurrentQueries.insert(queryGL);
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error StateManagerGL::setGenericDrawState(const gl::ContextState &data)
+{
+ const gl::State &state = data.getState();
+
+ // Sync the current program state
+ const gl::Program *program = state.getProgram();
+ const ProgramGL *programGL = GetImplAs<ProgramGL>(program);
+ useProgram(programGL->getProgramID());
+
+ for (size_t uniformBlockIndex = 0; uniformBlockIndex < program->getActiveUniformBlockCount();
+ uniformBlockIndex++)
+ {
+ GLuint binding = program->getUniformBlockBinding(static_cast<GLuint>(uniformBlockIndex));
+ const auto &uniformBuffer = state.getIndexedUniformBuffer(binding);
+
+ if (uniformBuffer.get() != nullptr)
+ {
+ BufferGL *bufferGL = GetImplAs<BufferGL>(uniformBuffer.get());
+
+ if (uniformBuffer.getSize() == 0)
+ {
+ bindBufferBase(GL_UNIFORM_BUFFER, binding, bufferGL->getBufferID());
+ }
+ else
+ {
+ bindBufferRange(GL_UNIFORM_BUFFER, binding, bufferGL->getBufferID(),
+ uniformBuffer.getOffset(), uniformBuffer.getSize());
+ }
+ }
+ }
+
+ const std::vector<SamplerBindingGL> &appliedSamplerUniforms = programGL->getAppliedSamplerUniforms();
+ for (const SamplerBindingGL &samplerUniform : appliedSamplerUniforms)
+ {
+ GLenum textureType = samplerUniform.textureType;
+ for (GLuint textureUnitIndex : samplerUniform.boundTextureUnits)
+ {
+ gl::Texture *texture = state.getSamplerTexture(textureUnitIndex, textureType);
+ if (texture != nullptr)
+ {
+ const TextureGL *textureGL = GetImplAs<TextureGL>(texture);
+
+ if (mTextures[textureType][textureUnitIndex] != textureGL->getTextureID() ||
+ texture->hasAnyDirtyBit() || textureGL->hasAnyDirtyBit())
+ {
+ activeTexture(textureUnitIndex);
+ bindTexture(textureType, textureGL->getTextureID());
+
+ // TODO: Call this from the gl:: layer once other backends use dirty bits for
+ // texture state.
+ texture->syncImplState();
+ }
+ }
+ else
+ {
+ if (mTextures[textureType][textureUnitIndex] != 0)
+ {
+ activeTexture(textureUnitIndex);
+ bindTexture(textureType, 0);
+ }
+ }
+
+ const gl::Sampler *sampler = state.getSampler(textureUnitIndex);
+ if (sampler != nullptr)
+ {
+ const SamplerGL *samplerGL = GetImplAs<SamplerGL>(sampler);
+ samplerGL->syncState(sampler->getSamplerState());
+ bindSampler(textureUnitIndex, samplerGL->getSamplerID());
+ }
+ else
+ {
+ bindSampler(textureUnitIndex, 0);
+ }
+ }
+ }
+
+ const gl::Framebuffer *framebuffer = state.getDrawFramebuffer();
+ const FramebufferGL *framebufferGL = GetImplAs<FramebufferGL>(framebuffer);
+ bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebufferGL->getFramebufferID());
+
+ // Seamless cubemaps are required for ES3 and higher contexts.
+ setTextureCubemapSeamlessEnabled(data.getClientMajorVersion() >= 3);
+
+ // Set the current transform feedback state
+ gl::TransformFeedback *transformFeedback = state.getCurrentTransformFeedback();
+ if (transformFeedback)
+ {
+ TransformFeedbackGL *transformFeedbackGL =
+ GetImplAs<TransformFeedbackGL>(transformFeedback);
+ bindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbackGL->getTransformFeedbackID());
+ transformFeedbackGL->syncActiveState(transformFeedback->isActive(),
+ transformFeedback->getPrimitiveMode());
+ transformFeedbackGL->syncPausedState(transformFeedback->isPaused());
+ mPrevDrawTransformFeedback = transformFeedbackGL;
+ }
+ else
+ {
+ bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
+ mPrevDrawTransformFeedback = nullptr;
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+void StateManagerGL::setAttributeCurrentData(size_t index,
+ const gl::VertexAttribCurrentValueData &data)
+{
+ if (mVertexAttribCurrentValues[index] != data)
+ {
+ mVertexAttribCurrentValues[index] = data;
+ switch (mVertexAttribCurrentValues[index].Type)
+ {
+ case GL_FLOAT:
+ mFunctions->vertexAttrib4fv(static_cast<GLuint>(index),
+ mVertexAttribCurrentValues[index].FloatValues);
+ break;
+ case GL_INT:
+ mFunctions->vertexAttribI4iv(static_cast<GLuint>(index),
+ mVertexAttribCurrentValues[index].IntValues);
+ break;
+ case GL_UNSIGNED_INT:
+ mFunctions->vertexAttribI4uiv(static_cast<GLuint>(index),
+ mVertexAttribCurrentValues[index].UnsignedIntValues);
+ break;
+ default: UNREACHABLE();
+ }
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_CURRENT_VALUE_0 + index);
+ }
+}
+
+void StateManagerGL::setScissorTestEnabled(bool enabled)
+{
+ if (mScissorTestEnabled != enabled)
+ {
+ mScissorTestEnabled = enabled;
+ if (mScissorTestEnabled)
+ {
+ mFunctions->enable(GL_SCISSOR_TEST);
+ }
+ else
+ {
+ mFunctions->disable(GL_SCISSOR_TEST);
+ }
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
+ }
+}
+
+void StateManagerGL::setScissor(const gl::Rectangle &scissor)
+{
+ if (scissor != mScissor)
+ {
+ mScissor = scissor;
+ mFunctions->scissor(mScissor.x, mScissor.y, mScissor.width, mScissor.height);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_SCISSOR);
+ }
+}
+
+void StateManagerGL::setViewport(const gl::Rectangle &viewport)
+{
+ if (viewport != mViewport)
+ {
+ mViewport = viewport;
+ mFunctions->viewport(mViewport.x, mViewport.y, mViewport.width, mViewport.height);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_VIEWPORT);
+ }
+}
+
+void StateManagerGL::setDepthRange(float near, float far)
+{
+ if (mNear != near || mFar != far)
+ {
+ mNear = near;
+ mFar = far;
+
+ // The glDepthRangef function isn't available until OpenGL 4.1. Prefer it when it is
+ // available because OpenGL ES only works in floats.
+ if (mFunctions->depthRangef)
+ {
+ mFunctions->depthRangef(mNear, mFar);
+ }
+ else
+ {
+ ASSERT(mFunctions->depthRange);
+ mFunctions->depthRange(mNear, mFar);
+ }
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_RANGE);
+ }
+}
+
+void StateManagerGL::setBlendEnabled(bool enabled)
+{
+ if (mBlendEnabled != enabled)
+ {
+ mBlendEnabled = enabled;
+ if (mBlendEnabled)
+ {
+ mFunctions->enable(GL_BLEND);
+ }
+ else
+ {
+ mFunctions->disable(GL_BLEND);
+ }
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_ENABLED);
+ }
+}
+
+void StateManagerGL::setBlendColor(const gl::ColorF &blendColor)
+{
+ if (mBlendColor != blendColor)
+ {
+ mBlendColor = blendColor;
+ mFunctions->blendColor(mBlendColor.red, mBlendColor.green, mBlendColor.blue, mBlendColor.alpha);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_COLOR);
+ }
+}
+
+void StateManagerGL::setBlendFuncs(GLenum sourceBlendRGB,
+ GLenum destBlendRGB,
+ GLenum sourceBlendAlpha,
+ GLenum destBlendAlpha)
+{
+ if (mSourceBlendRGB != sourceBlendRGB || mDestBlendRGB != destBlendRGB ||
+ mSourceBlendAlpha != sourceBlendAlpha || mDestBlendAlpha != destBlendAlpha)
+ {
+ mSourceBlendRGB = sourceBlendRGB;
+ mDestBlendRGB = destBlendRGB;
+ mSourceBlendAlpha = sourceBlendAlpha;
+ mDestBlendAlpha = destBlendAlpha;
+
+ mFunctions->blendFuncSeparate(mSourceBlendRGB, mDestBlendRGB, mSourceBlendAlpha, mDestBlendAlpha);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_FUNCS);
+ }
+}
+
+void StateManagerGL::setBlendEquations(GLenum blendEquationRGB, GLenum blendEquationAlpha)
+{
+ if (mBlendEquationRGB != blendEquationRGB || mBlendEquationAlpha != blendEquationAlpha)
+ {
+ mBlendEquationRGB = blendEquationRGB;
+ mBlendEquationAlpha = blendEquationAlpha;
+
+ mFunctions->blendEquationSeparate(mBlendEquationRGB, mBlendEquationAlpha);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_EQUATIONS);
+ }
+}
+
+void StateManagerGL::setColorMask(bool red, bool green, bool blue, bool alpha)
+{
+ if (mColorMaskRed != red || mColorMaskGreen != green || mColorMaskBlue != blue || mColorMaskAlpha != alpha)
+ {
+ mColorMaskRed = red;
+ mColorMaskGreen = green;
+ mColorMaskBlue = blue;
+ mColorMaskAlpha = alpha;
+ mFunctions->colorMask(mColorMaskRed, mColorMaskGreen, mColorMaskBlue, mColorMaskAlpha);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_COLOR_MASK);
+ }
+}
+
+void StateManagerGL::setSampleAlphaToCoverageEnabled(bool enabled)
+{
+ if (mSampleAlphaToCoverageEnabled != enabled)
+ {
+ mSampleAlphaToCoverageEnabled = enabled;
+ if (mSampleAlphaToCoverageEnabled)
+ {
+ mFunctions->enable(GL_SAMPLE_ALPHA_TO_COVERAGE);
+ }
+ else
+ {
+ mFunctions->disable(GL_SAMPLE_ALPHA_TO_COVERAGE);
+ }
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED);
+ }
+}
+
+void StateManagerGL::setSampleCoverageEnabled(bool enabled)
+{
+ if (mSampleCoverageEnabled != enabled)
+ {
+ mSampleCoverageEnabled = enabled;
+ if (mSampleCoverageEnabled)
+ {
+ mFunctions->enable(GL_SAMPLE_COVERAGE);
+ }
+ else
+ {
+ mFunctions->disable(GL_SAMPLE_COVERAGE);
+ }
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
+ }
+}
+
+void StateManagerGL::setSampleCoverage(float value, bool invert)
+{
+ if (mSampleCoverageValue != value || mSampleCoverageInvert != invert)
+ {
+ mSampleCoverageValue = value;
+ mSampleCoverageInvert = invert;
+ mFunctions->sampleCoverage(mSampleCoverageValue, mSampleCoverageInvert);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_COVERAGE);
+ }
+}
+
+void StateManagerGL::setDepthTestEnabled(bool enabled)
+{
+ if (mDepthTestEnabled != enabled)
+ {
+ mDepthTestEnabled = enabled;
+ if (mDepthTestEnabled)
+ {
+ mFunctions->enable(GL_DEPTH_TEST);
+ }
+ else
+ {
+ mFunctions->disable(GL_DEPTH_TEST);
+ }
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED);
+ }
+}
+
+void StateManagerGL::setDepthFunc(GLenum depthFunc)
+{
+ if (mDepthFunc != depthFunc)
+ {
+ mDepthFunc = depthFunc;
+ mFunctions->depthFunc(mDepthFunc);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_FUNC);
+ }
+}
+
+void StateManagerGL::setDepthMask(bool mask)
+{
+ if (mDepthMask != mask)
+ {
+ mDepthMask = mask;
+ mFunctions->depthMask(mDepthMask);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_MASK);
+ }
+}
+
+void StateManagerGL::setStencilTestEnabled(bool enabled)
+{
+ if (mStencilTestEnabled != enabled)
+ {
+ mStencilTestEnabled = enabled;
+ if (mStencilTestEnabled)
+ {
+ mFunctions->enable(GL_STENCIL_TEST);
+ }
+ else
+ {
+ mFunctions->disable(GL_STENCIL_TEST);
+ }
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED);
+ }
+}
+
+void StateManagerGL::setStencilFrontWritemask(GLuint mask)
+{
+ if (mStencilFrontWritemask != mask)
+ {
+ mStencilFrontWritemask = mask;
+ mFunctions->stencilMaskSeparate(GL_FRONT, mStencilFrontWritemask);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
+ }
+}
+
+void StateManagerGL::setStencilBackWritemask(GLuint mask)
+{
+ if (mStencilBackWritemask != mask)
+ {
+ mStencilBackWritemask = mask;
+ mFunctions->stencilMaskSeparate(GL_BACK, mStencilBackWritemask);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
+ }
+}
+
+void StateManagerGL::setStencilFrontFuncs(GLenum func, GLint ref, GLuint mask)
+{
+ if (mStencilFrontFunc != func || mStencilFrontRef != ref || mStencilFrontValueMask != mask)
+ {
+ mStencilFrontFunc = func;
+ mStencilFrontRef = ref;
+ mStencilFrontValueMask = mask;
+ mFunctions->stencilFuncSeparate(GL_FRONT, mStencilFrontFunc, mStencilFrontRef, mStencilFrontValueMask);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT);
+ }
+}
+
+void StateManagerGL::setStencilBackFuncs(GLenum func, GLint ref, GLuint mask)
+{
+ if (mStencilBackFunc != func || mStencilBackRef != ref || mStencilBackValueMask != mask)
+ {
+ mStencilBackFunc = func;
+ mStencilBackRef = ref;
+ mStencilBackValueMask = mask;
+ mFunctions->stencilFuncSeparate(GL_BACK, mStencilBackFunc, mStencilBackRef, mStencilBackValueMask);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK);
+ }
+}
+
+void StateManagerGL::setStencilFrontOps(GLenum sfail, GLenum dpfail, GLenum dppass)
+{
+ if (mStencilFrontStencilFailOp != sfail || mStencilFrontStencilPassDepthFailOp != dpfail || mStencilFrontStencilPassDepthPassOp != dppass)
+ {
+ mStencilFrontStencilFailOp = sfail;
+ mStencilFrontStencilPassDepthFailOp = dpfail;
+ mStencilFrontStencilPassDepthPassOp = dppass;
+ mFunctions->stencilOpSeparate(GL_FRONT, mStencilFrontStencilFailOp, mStencilFrontStencilPassDepthFailOp, mStencilFrontStencilPassDepthPassOp);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_OPS_FRONT);
+ }
+}
+
+void StateManagerGL::setStencilBackOps(GLenum sfail, GLenum dpfail, GLenum dppass)
+{
+ if (mStencilBackStencilFailOp != sfail || mStencilBackStencilPassDepthFailOp != dpfail || mStencilBackStencilPassDepthPassOp != dppass)
+ {
+ mStencilBackStencilFailOp = sfail;
+ mStencilBackStencilPassDepthFailOp = dpfail;
+ mStencilBackStencilPassDepthPassOp = dppass;
+ mFunctions->stencilOpSeparate(GL_BACK, mStencilBackStencilFailOp, mStencilBackStencilPassDepthFailOp, mStencilBackStencilPassDepthPassOp);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_OPS_BACK);
+ }
+}
+
+void StateManagerGL::setCullFaceEnabled(bool enabled)
+{
+ if (mCullFaceEnabled != enabled)
+ {
+ mCullFaceEnabled = enabled;
+ if (mCullFaceEnabled)
+ {
+ mFunctions->enable(GL_CULL_FACE);
+ }
+ else
+ {
+ mFunctions->disable(GL_CULL_FACE);
+ }
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_CULL_FACE_ENABLED);
+ }
+}
+
+void StateManagerGL::setCullFace(GLenum cullFace)
+{
+ if (mCullFace != cullFace)
+ {
+ mCullFace = cullFace;
+ mFunctions->cullFace(mCullFace);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_CULL_FACE);
+ }
+}
+
+void StateManagerGL::setFrontFace(GLenum frontFace)
+{
+ if (mFrontFace != frontFace)
+ {
+ mFrontFace = frontFace;
+ mFunctions->frontFace(mFrontFace);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_FRONT_FACE);
+ }
+}
+
+void StateManagerGL::setPolygonOffsetFillEnabled(bool enabled)
+{
+ if (mPolygonOffsetFillEnabled != enabled)
+ {
+ mPolygonOffsetFillEnabled = enabled;
+ if (mPolygonOffsetFillEnabled)
+ {
+ mFunctions->enable(GL_POLYGON_OFFSET_FILL);
+ }
+ else
+ {
+ mFunctions->disable(GL_POLYGON_OFFSET_FILL);
+ }
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
+ }
+}
+
+void StateManagerGL::setPolygonOffset(float factor, float units)
+{
+ if (mPolygonOffsetFactor != factor || mPolygonOffsetUnits != units)
+ {
+ mPolygonOffsetFactor = factor;
+ mPolygonOffsetUnits = units;
+ mFunctions->polygonOffset(mPolygonOffsetFactor, mPolygonOffsetUnits);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_POLYGON_OFFSET);
+ }
+}
+
+void StateManagerGL::setRasterizerDiscardEnabled(bool enabled)
+{
+ if (mRasterizerDiscardEnabled != enabled)
+ {
+ mRasterizerDiscardEnabled = enabled;
+ if (mRasterizerDiscardEnabled)
+ {
+ mFunctions->enable(GL_RASTERIZER_DISCARD);
+ }
+ else
+ {
+ mFunctions->disable(GL_RASTERIZER_DISCARD);
+ }
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
+ }
+}
+
+void StateManagerGL::setLineWidth(float width)
+{
+ if (mLineWidth != width)
+ {
+ mLineWidth = width;
+ mFunctions->lineWidth(mLineWidth);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_LINE_WIDTH);
+ }
+}
+
+void StateManagerGL::setPrimitiveRestartEnabled(bool enabled)
+{
+ if (mPrimitiveRestartEnabled != enabled)
+ {
+ mPrimitiveRestartEnabled = enabled;
+
+ if (mPrimitiveRestartEnabled)
+ {
+ mFunctions->enable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
+ }
+ else
+ {
+ mFunctions->disable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
+ }
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
+ }
+}
+
+void StateManagerGL::setClearDepth(float clearDepth)
+{
+ if (mClearDepth != clearDepth)
+ {
+ mClearDepth = clearDepth;
+
+ // The glClearDepthf function isn't available until OpenGL 4.1. Prefer it when it is
+ // available because OpenGL ES only works in floats.
+ if (mFunctions->clearDepthf)
+ {
+ mFunctions->clearDepthf(mClearDepth);
+ }
+ else
+ {
+ ASSERT(mFunctions->clearDepth);
+ mFunctions->clearDepth(mClearDepth);
+ }
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_CLEAR_DEPTH);
+ }
+}
+
+void StateManagerGL::setClearColor(const gl::ColorF &clearColor)
+{
+ if (mClearColor != clearColor)
+ {
+ mClearColor = clearColor;
+ mFunctions->clearColor(mClearColor.red, mClearColor.green, mClearColor.blue, mClearColor.alpha);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_CLEAR_COLOR);
+ }
+}
+
+void StateManagerGL::setClearStencil(GLint clearStencil)
+{
+ if (mClearStencil != clearStencil)
+ {
+ mClearStencil = clearStencil;
+ mFunctions->clearStencil(mClearStencil);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_CLEAR_STENCIL);
+ }
+}
+
+void StateManagerGL::syncState(const gl::State &state, const gl::State::DirtyBits &glDirtyBits)
+{
+ // The the current framebuffer binding sometimes requires resetting the srgb blending
+ if (glDirtyBits[gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING] &&
+ mFunctions->standard == STANDARD_GL_DESKTOP)
+ {
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_FRAMEBUFFER_SRGB);
+ }
+
+ const auto &glAndLocalDirtyBits = (glDirtyBits | mLocalDirtyBits);
+
+ if (!glAndLocalDirtyBits.any())
+ {
+ return;
+ }
+
+ // TODO(jmadill): Investigate only syncing vertex state for active attributes
+ for (auto dirtyBit : angle::IterateBitSet(glAndLocalDirtyBits))
+ {
+ switch (dirtyBit)
+ {
+ case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED:
+ setScissorTestEnabled(state.isScissorTestEnabled());
+ break;
+ case gl::State::DIRTY_BIT_SCISSOR:
+ setScissor(state.getScissor());
+ break;
+ case gl::State::DIRTY_BIT_VIEWPORT:
+ setViewport(state.getViewport());
+ break;
+ case gl::State::DIRTY_BIT_DEPTH_RANGE:
+ setDepthRange(state.getNearPlane(), state.getFarPlane());
+ break;
+ case gl::State::DIRTY_BIT_BLEND_ENABLED:
+ setBlendEnabled(state.isBlendEnabled());
+ break;
+ case gl::State::DIRTY_BIT_BLEND_COLOR:
+ setBlendColor(state.getBlendColor());
+ break;
+ case gl::State::DIRTY_BIT_BLEND_FUNCS:
+ {
+ const auto &blendState = state.getBlendState();
+ setBlendFuncs(blendState.sourceBlendRGB, blendState.destBlendRGB,
+ blendState.sourceBlendAlpha, blendState.destBlendAlpha);
+ break;
+ }
+ case gl::State::DIRTY_BIT_BLEND_EQUATIONS:
+ {
+ const auto &blendState = state.getBlendState();
+ setBlendEquations(blendState.blendEquationRGB, blendState.blendEquationAlpha);
+ break;
+ }
+ case gl::State::DIRTY_BIT_COLOR_MASK:
+ {
+ const auto &blendState = state.getBlendState();
+ setColorMask(blendState.colorMaskRed, blendState.colorMaskGreen,
+ blendState.colorMaskBlue, blendState.colorMaskAlpha);
+ break;
+ }
+ case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED:
+ setSampleAlphaToCoverageEnabled(state.isSampleAlphaToCoverageEnabled());
+ break;
+ case gl::State::DIRTY_BIT_SAMPLE_COVERAGE_ENABLED:
+ setSampleCoverageEnabled(state.isSampleCoverageEnabled());
+ break;
+ case gl::State::DIRTY_BIT_SAMPLE_COVERAGE:
+ setSampleCoverage(state.getSampleCoverageValue(), state.getSampleCoverageInvert());
+ break;
+ case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED:
+ setDepthTestEnabled(state.isDepthTestEnabled());
+ break;
+ case gl::State::DIRTY_BIT_DEPTH_FUNC:
+ setDepthFunc(state.getDepthStencilState().depthFunc);
+ break;
+ case gl::State::DIRTY_BIT_DEPTH_MASK:
+ setDepthMask(state.getDepthStencilState().depthMask);
+ break;
+ case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED:
+ setStencilTestEnabled(state.isStencilTestEnabled());
+ break;
+ case gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT:
+ {
+ const auto &depthStencilState = state.getDepthStencilState();
+ setStencilFrontFuncs(depthStencilState.stencilFunc, state.getStencilRef(),
+ depthStencilState.stencilMask);
+ break;
+ }
+ case gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK:
+ {
+ const auto &depthStencilState = state.getDepthStencilState();
+ setStencilBackFuncs(depthStencilState.stencilBackFunc, state.getStencilBackRef(),
+ depthStencilState.stencilBackMask);
+ break;
+ }
+ case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT:
+ {
+ const auto &depthStencilState = state.getDepthStencilState();
+ setStencilFrontOps(depthStencilState.stencilFail,
+ depthStencilState.stencilPassDepthFail,
+ depthStencilState.stencilPassDepthPass);
+ break;
+ }
+ case gl::State::DIRTY_BIT_STENCIL_OPS_BACK:
+ {
+ const auto &depthStencilState = state.getDepthStencilState();
+ setStencilBackOps(depthStencilState.stencilBackFail,
+ depthStencilState.stencilBackPassDepthFail,
+ depthStencilState.stencilBackPassDepthPass);
+ break;
+ }
+ case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT:
+ setStencilFrontWritemask(state.getDepthStencilState().stencilWritemask);
+ break;
+ case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK:
+ setStencilBackWritemask(state.getDepthStencilState().stencilBackWritemask);
+ break;
+ case gl::State::DIRTY_BIT_CULL_FACE_ENABLED:
+ setCullFaceEnabled(state.isCullFaceEnabled());
+ break;
+ case gl::State::DIRTY_BIT_CULL_FACE:
+ setCullFace(state.getRasterizerState().cullMode);
+ break;
+ case gl::State::DIRTY_BIT_FRONT_FACE:
+ setFrontFace(state.getRasterizerState().frontFace);
+ break;
+ case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED:
+ setPolygonOffsetFillEnabled(state.isPolygonOffsetFillEnabled());
+ break;
+ case gl::State::DIRTY_BIT_POLYGON_OFFSET:
+ {
+ const auto &rasterizerState = state.getRasterizerState();
+ setPolygonOffset(rasterizerState.polygonOffsetFactor,
+ rasterizerState.polygonOffsetUnits);
+ break;
+ }
+ case gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED:
+ setRasterizerDiscardEnabled(state.isRasterizerDiscardEnabled());
+ break;
+ case gl::State::DIRTY_BIT_LINE_WIDTH:
+ setLineWidth(state.getLineWidth());
+ break;
+ case gl::State::DIRTY_BIT_PRIMITIVE_RESTART_ENABLED:
+ setPrimitiveRestartEnabled(state.isPrimitiveRestartEnabled());
+ break;
+ case gl::State::DIRTY_BIT_CLEAR_COLOR:
+ setClearColor(state.getColorClearValue());
+ break;
+ case gl::State::DIRTY_BIT_CLEAR_DEPTH:
+ setClearDepth(state.getDepthClearValue());
+ break;
+ case gl::State::DIRTY_BIT_CLEAR_STENCIL:
+ setClearStencil(state.getStencilClearValue());
+ break;
+ case gl::State::DIRTY_BIT_UNPACK_ALIGNMENT:
+ // TODO(jmadill): split this
+ setPixelUnpackState(state.getUnpackState());
+ break;
+ case gl::State::DIRTY_BIT_UNPACK_ROW_LENGTH:
+ // TODO(jmadill): split this
+ setPixelUnpackState(state.getUnpackState());
+ break;
+ case gl::State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT:
+ // TODO(jmadill): split this
+ setPixelUnpackState(state.getUnpackState());
+ break;
+ case gl::State::DIRTY_BIT_UNPACK_SKIP_IMAGES:
+ // TODO(jmadill): split this
+ setPixelUnpackState(state.getUnpackState());
+ break;
+ case gl::State::DIRTY_BIT_UNPACK_SKIP_ROWS:
+ // TODO(jmadill): split this
+ setPixelUnpackState(state.getUnpackState());
+ break;
+ case gl::State::DIRTY_BIT_UNPACK_SKIP_PIXELS:
+ // TODO(jmadill): split this
+ setPixelUnpackState(state.getUnpackState());
+ break;
+ case gl::State::DIRTY_BIT_UNPACK_BUFFER_BINDING:
+ // TODO(jmadill): split this
+ setPixelUnpackState(state.getUnpackState());
+ break;
+ case gl::State::DIRTY_BIT_PACK_ALIGNMENT:
+ // TODO(jmadill): split this
+ setPixelPackState(state.getPackState());
+ break;
+ case gl::State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER:
+ // TODO(jmadill): split this
+ setPixelPackState(state.getPackState());
+ break;
+ case gl::State::DIRTY_BIT_PACK_ROW_LENGTH:
+ // TODO(jmadill): split this
+ setPixelPackState(state.getPackState());
+ break;
+ case gl::State::DIRTY_BIT_PACK_SKIP_ROWS:
+ // TODO(jmadill): split this
+ setPixelPackState(state.getPackState());
+ break;
+ case gl::State::DIRTY_BIT_PACK_SKIP_PIXELS:
+ // TODO(jmadill): split this
+ setPixelPackState(state.getPackState());
+ break;
+ case gl::State::DIRTY_BIT_PACK_BUFFER_BINDING:
+ // TODO(jmadill): split this
+ setPixelPackState(state.getPackState());
+ break;
+ case gl::State::DIRTY_BIT_DITHER_ENABLED:
+ setDitherEnabled(state.isDitherEnabled());
+ break;
+ case gl::State::DIRTY_BIT_GENERATE_MIPMAP_HINT:
+ // TODO(jmadill): implement this
+ break;
+ case gl::State::DIRTY_BIT_SHADER_DERIVATIVE_HINT:
+ // TODO(jmadill): implement this
+ break;
+ case gl::State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING:
+ // TODO(jmadill): implement this
+ break;
+ case gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING:
+ // TODO(jmadill): implement this
+ break;
+ case gl::State::DIRTY_BIT_RENDERBUFFER_BINDING:
+ // TODO(jmadill): implement this
+ break;
+ case gl::State::DIRTY_BIT_VERTEX_ARRAY_BINDING:
+ // TODO(jmadill): implement this
+ break;
+ case gl::State::DIRTY_BIT_PROGRAM_BINDING:
+ // TODO(jmadill): implement this
+ break;
+ case gl::State::DIRTY_BIT_MULTISAMPLING:
+ setMultisamplingStateEnabled(state.isMultisamplingEnabled());
+ break;
+ case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_ONE:
+ setSampleAlphaToOneStateEnabled(state.isSampleAlphaToOneEnabled());
+ case gl::State::DIRTY_BIT_COVERAGE_MODULATION:
+ setCoverageModulation(state.getCoverageModulation());
+ break;
+ case gl::State::DIRTY_BIT_PATH_RENDERING_MATRIX_MV:
+ setPathRenderingModelViewMatrix(
+ state.getPathRenderingMatrix(GL_PATH_MODELVIEW_MATRIX_CHROMIUM));
+ break;
+ case gl::State::DIRTY_BIT_PATH_RENDERING_MATRIX_PROJ:
+ setPathRenderingProjectionMatrix(
+ state.getPathRenderingMatrix(GL_PATH_PROJECTION_MATRIX_CHROMIUM));
+ break;
+ case gl::State::DIRTY_BIT_PATH_RENDERING_STENCIL_STATE:
+ setPathRenderingStencilState(state.getPathStencilFunc(), state.getPathStencilRef(),
+ state.getPathStencilMask());
+ break;
+ case gl::State::DIRTY_BIT_FRAMEBUFFER_SRGB:
+ setFramebufferSRGBEnabledForFramebuffer(
+ state.getFramebufferSRGB(),
+ GetImplAs<FramebufferGL>(state.getDrawFramebuffer()));
+ break;
+ default:
+ {
+ ASSERT(dirtyBit >= gl::State::DIRTY_BIT_CURRENT_VALUE_0 &&
+ dirtyBit < gl::State::DIRTY_BIT_CURRENT_VALUE_MAX);
+ size_t attribIndex =
+ static_cast<size_t>(dirtyBit) - gl::State::DIRTY_BIT_CURRENT_VALUE_0;
+ setAttributeCurrentData(attribIndex, state.getVertexAttribCurrentValue(
+ static_cast<unsigned int>(attribIndex)));
+ break;
+ }
+ }
+
+ mLocalDirtyBits.reset();
+ }
+}
+
+void StateManagerGL::setFramebufferSRGBEnabled(bool enabled)
+{
+ if (mFramebufferSRGBEnabled != enabled)
+ {
+ mFramebufferSRGBEnabled = enabled;
+ if (mFramebufferSRGBEnabled)
+ {
+ mFunctions->enable(GL_FRAMEBUFFER_SRGB);
+ }
+ else
+ {
+ mFunctions->disable(GL_FRAMEBUFFER_SRGB);
+ }
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_FRAMEBUFFER_SRGB);
+ }
+}
+
+void StateManagerGL::setFramebufferSRGBEnabledForFramebuffer(bool enabled,
+ const FramebufferGL *framebuffer)
+{
+ if (mFunctions->standard == STANDARD_GL_DESKTOP && framebuffer->isDefault())
+ {
+ // Obey the framebuffer sRGB state for blending on all framebuffers except the default
+ // framebuffer on Desktop OpenGL.
+ // When SRGB blending is enabled, only SRGB capable formats will use it but the default
+ // framebuffer will always use it if it is enabled.
+ // TODO(geofflang): Update this when the framebuffer binding dirty changes, when it exists.
+ setFramebufferSRGBEnabled(false);
+ }
+ else
+ {
+ setFramebufferSRGBEnabled(enabled);
+ }
+}
+
+void StateManagerGL::setDitherEnabled(bool enabled)
+{
+ if (mDitherEnabled != enabled)
+ {
+ mDitherEnabled = enabled;
+ if (mDitherEnabled)
+ {
+ mFunctions->enable(GL_DITHER);
+ }
+ else
+ {
+ mFunctions->disable(GL_DITHER);
+ }
+ }
+}
+
+void StateManagerGL::setMultisamplingStateEnabled(bool enabled)
+{
+ if (mMultisamplingEnabled != enabled)
+ {
+ mMultisamplingEnabled = enabled;
+ if (mMultisamplingEnabled)
+ {
+ mFunctions->enable(GL_MULTISAMPLE_EXT);
+ }
+ else
+ {
+ mFunctions->disable(GL_MULTISAMPLE_EXT);
+ }
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_MULTISAMPLING);
+ }
+}
+
+void StateManagerGL::setSampleAlphaToOneStateEnabled(bool enabled)
+{
+ if (mSampleAlphaToOneEnabled != enabled)
+ {
+ mSampleAlphaToOneEnabled = enabled;
+ if (mSampleAlphaToOneEnabled)
+ {
+ mFunctions->enable(GL_SAMPLE_ALPHA_TO_ONE);
+ }
+ else
+ {
+ mFunctions->disable(GL_SAMPLE_ALPHA_TO_ONE);
+ }
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_ONE);
+ }
+}
+
+void StateManagerGL::setCoverageModulation(GLenum components)
+{
+ if (mCoverageModulation != components)
+ {
+ mCoverageModulation = components;
+ mFunctions->coverageModulationNV(components);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_COVERAGE_MODULATION);
+ }
+}
+
+void StateManagerGL::setPathRenderingModelViewMatrix(const GLfloat *m)
+{
+ if (memcmp(mPathMatrixMV, m, sizeof(mPathMatrixMV)) != 0)
+ {
+ memcpy(mPathMatrixMV, m, sizeof(mPathMatrixMV));
+ mFunctions->matrixLoadEXT(GL_PATH_MODELVIEW_CHROMIUM, m);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_PATH_RENDERING_MATRIX_MV);
+ }
+}
+
+void StateManagerGL::setPathRenderingProjectionMatrix(const GLfloat *m)
+{
+ if (memcmp(mPathMatrixProj, m, sizeof(mPathMatrixProj)) != 0)
+ {
+ memcpy(mPathMatrixProj, m, sizeof(mPathMatrixProj));
+ mFunctions->matrixLoadEXT(GL_PATH_PROJECTION_CHROMIUM, m);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_PATH_RENDERING_MATRIX_PROJ);
+ }
+}
+
+void StateManagerGL::setPathRenderingStencilState(GLenum func, GLint ref, GLuint mask)
+{
+ if (func != mPathStencilFunc || ref != mPathStencilRef || mask != mPathStencilMask)
+ {
+ mPathStencilFunc = func;
+ mPathStencilRef = ref;
+ mPathStencilMask = mask;
+ mFunctions->pathStencilFuncNV(func, ref, mask);
+
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_PATH_RENDERING_STENCIL_STATE);
+ }
+}
+
+void StateManagerGL::setTextureCubemapSeamlessEnabled(bool enabled)
+{
+ if (mTextureCubemapSeamlessEnabled != enabled)
+ {
+ mTextureCubemapSeamlessEnabled = enabled;
+ if (mTextureCubemapSeamlessEnabled)
+ {
+ mFunctions->enable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
+ }
+ else
+ {
+ mFunctions->disable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
+ }
+ }
+}
+
+GLuint StateManagerGL::getBoundBuffer(GLenum type)
+{
+ ASSERT(mBuffers.find(type) != mBuffers.end());
+ return mBuffers[type];
+}
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/StateManagerGL.h b/gfx/angle/src/libANGLE/renderer/gl/StateManagerGL.h
new file mode 100755
index 000000000..3c8c5389f
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/StateManagerGL.h
@@ -0,0 +1,290 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// StateManagerGL.h: Defines a class for caching applied OpenGL state
+
+#ifndef LIBANGLE_RENDERER_GL_STATEMANAGERGL_H_
+#define LIBANGLE_RENDERER_GL_STATEMANAGERGL_H_
+
+#include "common/debug.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/State.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/gl/functionsgl_typedefs.h"
+
+#include <map>
+
+namespace gl
+{
+struct Caps;
+class ContextState;
+class State;
+}
+
+namespace rx
+{
+
+class FramebufferGL;
+class FunctionsGL;
+class TransformFeedbackGL;
+class QueryGL;
+
+class StateManagerGL final : angle::NonCopyable
+{
+ public:
+ StateManagerGL(const FunctionsGL *functions, const gl::Caps &rendererCaps);
+
+ void deleteProgram(GLuint program);
+ void deleteVertexArray(GLuint vao);
+ void deleteTexture(GLuint texture);
+ void deleteSampler(GLuint sampler);
+ void deleteBuffer(GLuint buffer);
+ void deleteFramebuffer(GLuint fbo);
+ void deleteRenderbuffer(GLuint rbo);
+ void deleteTransformFeedback(GLuint transformFeedback);
+ void deleteQuery(GLuint query);
+
+ void useProgram(GLuint program);
+ void forceUseProgram(GLuint program);
+ void bindVertexArray(GLuint vao, GLuint elementArrayBuffer);
+ void bindBuffer(GLenum type, GLuint buffer);
+ void bindBufferBase(GLenum type, size_t index, GLuint buffer);
+ void bindBufferRange(GLenum type, size_t index, GLuint buffer, size_t offset, size_t size);
+ void activeTexture(size_t unit);
+ void bindTexture(GLenum type, GLuint texture);
+ void bindSampler(size_t unit, GLuint sampler);
+ void bindFramebuffer(GLenum type, GLuint framebuffer);
+ void bindRenderbuffer(GLenum type, GLuint renderbuffer);
+ void bindTransformFeedback(GLenum type, GLuint transformFeedback);
+ void beginQuery(GLenum type, GLuint query);
+ void endQuery(GLenum type, GLuint query);
+ void onBeginQuery(QueryGL *query);
+
+ void setAttributeCurrentData(size_t index, const gl::VertexAttribCurrentValueData &data);
+
+ void setScissorTestEnabled(bool enabled);
+ void setScissor(const gl::Rectangle &scissor);
+
+ void setViewport(const gl::Rectangle &viewport);
+ void setDepthRange(float near, float far);
+
+ void setBlendEnabled(bool enabled);
+ void setBlendColor(const gl::ColorF &blendColor);
+ void setBlendFuncs(GLenum sourceBlendRGB,
+ GLenum destBlendRGB,
+ GLenum sourceBlendAlpha,
+ GLenum destBlendAlpha);
+ void setBlendEquations(GLenum blendEquationRGB, GLenum blendEquationAlpha);
+ void setColorMask(bool red, bool green, bool blue, bool alpha);
+ void setSampleAlphaToCoverageEnabled(bool enabled);
+ void setSampleCoverageEnabled(bool enabled);
+ void setSampleCoverage(float value, bool invert);
+
+ void setDepthTestEnabled(bool enabled);
+ void setDepthFunc(GLenum depthFunc);
+ void setDepthMask(bool mask);
+ void setStencilTestEnabled(bool enabled);
+ void setStencilFrontWritemask(GLuint mask);
+ void setStencilBackWritemask(GLuint mask);
+ void setStencilFrontFuncs(GLenum func, GLint ref, GLuint mask);
+ void setStencilBackFuncs(GLenum func, GLint ref, GLuint mask);
+ void setStencilFrontOps(GLenum sfail, GLenum dpfail, GLenum dppass);
+ void setStencilBackOps(GLenum sfail, GLenum dpfail, GLenum dppass);
+
+ void setCullFaceEnabled(bool enabled);
+ void setCullFace(GLenum cullFace);
+ void setFrontFace(GLenum frontFace);
+ void setPolygonOffsetFillEnabled(bool enabled);
+ void setPolygonOffset(float factor, float units);
+ void setRasterizerDiscardEnabled(bool enabled);
+ void setLineWidth(float width);
+
+ void setPrimitiveRestartEnabled(bool enabled);
+
+ void setClearColor(const gl::ColorF &clearColor);
+ void setClearDepth(float clearDepth);
+ void setClearStencil(GLint clearStencil);
+
+ void setPixelUnpackState(const gl::PixelUnpackState &unpack);
+ void setPixelUnpackState(GLint alignment,
+ GLint rowLength,
+ GLint skipRows,
+ GLint skipPixels,
+ GLint imageHeight,
+ GLint skipImages,
+ GLuint unpackBuffer);
+ void setPixelPackState(const gl::PixelPackState &pack);
+ void setPixelPackState(GLint alignment,
+ GLint rowLength,
+ GLint skipRows,
+ GLint skipPixels,
+ GLuint packBuffer);
+
+ void setFramebufferSRGBEnabled(bool enabled);
+ void setFramebufferSRGBEnabledForFramebuffer(bool enabled, const FramebufferGL *framebuffer);
+
+ void setDitherEnabled(bool enabled);
+
+ void setMultisamplingStateEnabled(bool enabled);
+ void setSampleAlphaToOneStateEnabled(bool enabled);
+
+ void setCoverageModulation(GLenum components);
+
+ void setPathRenderingModelViewMatrix(const GLfloat *m);
+ void setPathRenderingProjectionMatrix(const GLfloat *m);
+ void setPathRenderingStencilState(GLenum func, GLint ref, GLuint mask);
+
+ void onDeleteQueryObject(QueryGL *query);
+
+ gl::Error setDrawArraysState(const gl::ContextState &data,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount);
+ gl::Error setDrawElementsState(const gl::ContextState &data,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ GLsizei instanceCount,
+ const GLvoid **outIndices);
+
+ gl::Error pauseTransformFeedback(const gl::ContextState &data);
+ gl::Error onMakeCurrent(const gl::ContextState &data);
+
+ void syncState(const gl::State &state, const gl::State::DirtyBits &glDirtyBits);
+
+ GLuint getBoundBuffer(GLenum type);
+
+ private:
+ gl::Error setGenericDrawState(const gl::ContextState &data);
+
+ void setTextureCubemapSeamlessEnabled(bool enabled);
+
+ const FunctionsGL *mFunctions;
+
+ GLuint mProgram;
+
+ GLuint mVAO;
+ std::vector<gl::VertexAttribCurrentValueData> mVertexAttribCurrentValues;
+
+ std::map<GLenum, GLuint> mBuffers;
+
+ struct IndexedBufferBinding
+ {
+ IndexedBufferBinding();
+
+ size_t offset;
+ size_t size;
+ GLuint buffer;
+ };
+ std::map<GLenum, std::vector<IndexedBufferBinding>> mIndexedBuffers;
+
+ size_t mTextureUnitIndex;
+ std::map<GLenum, std::vector<GLuint>> mTextures;
+ std::vector<GLuint> mSamplers;
+
+ GLuint mTransformFeedback;
+
+ std::map<GLenum, GLuint> mQueries;
+
+ TransformFeedbackGL *mPrevDrawTransformFeedback;
+ std::set<QueryGL *> mCurrentQueries;
+ uintptr_t mPrevDrawContext;
+
+ GLint mUnpackAlignment;
+ GLint mUnpackRowLength;
+ GLint mUnpackSkipRows;
+ GLint mUnpackSkipPixels;
+ GLint mUnpackImageHeight;
+ GLint mUnpackSkipImages;
+
+ GLint mPackAlignment;
+ GLint mPackRowLength;
+ GLint mPackSkipRows;
+ GLint mPackSkipPixels;
+
+ // TODO(jmadill): Convert to std::array when available
+ std::vector<GLenum> mFramebuffers;
+ GLuint mRenderbuffer;
+
+ bool mScissorTestEnabled;
+ gl::Rectangle mScissor;
+
+ gl::Rectangle mViewport;
+ float mNear;
+ float mFar;
+
+ bool mBlendEnabled;
+ gl::ColorF mBlendColor;
+ GLenum mSourceBlendRGB;
+ GLenum mDestBlendRGB;
+ GLenum mSourceBlendAlpha;
+ GLenum mDestBlendAlpha;
+ GLenum mBlendEquationRGB;
+ GLenum mBlendEquationAlpha;
+ bool mColorMaskRed;
+ bool mColorMaskGreen;
+ bool mColorMaskBlue;
+ bool mColorMaskAlpha;
+ bool mSampleAlphaToCoverageEnabled;
+ bool mSampleCoverageEnabled;
+ float mSampleCoverageValue;
+ bool mSampleCoverageInvert;
+
+ bool mDepthTestEnabled;
+ GLenum mDepthFunc;
+ bool mDepthMask;
+ bool mStencilTestEnabled;
+ GLenum mStencilFrontFunc;
+ GLint mStencilFrontRef;
+ GLuint mStencilFrontValueMask;
+ GLenum mStencilFrontStencilFailOp;
+ GLenum mStencilFrontStencilPassDepthFailOp;
+ GLenum mStencilFrontStencilPassDepthPassOp;
+ GLuint mStencilFrontWritemask;
+ GLenum mStencilBackFunc;
+ GLint mStencilBackRef;
+ GLuint mStencilBackValueMask;
+ GLenum mStencilBackStencilFailOp;
+ GLenum mStencilBackStencilPassDepthFailOp;
+ GLenum mStencilBackStencilPassDepthPassOp;
+ GLuint mStencilBackWritemask;
+
+ bool mCullFaceEnabled;
+ GLenum mCullFace;
+ GLenum mFrontFace;
+ bool mPolygonOffsetFillEnabled;
+ GLfloat mPolygonOffsetFactor;
+ GLfloat mPolygonOffsetUnits;
+ bool mRasterizerDiscardEnabled;
+ float mLineWidth;
+
+ bool mPrimitiveRestartEnabled;
+
+ gl::ColorF mClearColor;
+ float mClearDepth;
+ GLint mClearStencil;
+
+ bool mFramebufferSRGBEnabled;
+ bool mDitherEnabled;
+ bool mTextureCubemapSeamlessEnabled;
+
+ bool mMultisamplingEnabled;
+ bool mSampleAlphaToOneEnabled;
+
+ GLenum mCoverageModulation;
+
+ GLfloat mPathMatrixMV[16];
+ GLfloat mPathMatrixProj[16];
+ GLenum mPathStencilFunc;
+ GLint mPathStencilRef;
+ GLuint mPathStencilMask;
+
+ gl::State::DirtyBits mLocalDirtyBits;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_STATEMANAGERGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/SurfaceGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/SurfaceGL.cpp
new file mode 100755
index 000000000..a1f0abba7
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/SurfaceGL.cpp
@@ -0,0 +1,36 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// SurfaceGL.cpp: OpenGL implementation of egl::Surface
+
+#include "libANGLE/renderer/gl/SurfaceGL.h"
+
+#include "libANGLE/renderer/gl/FramebufferGL.h"
+#include "libANGLE/renderer/gl/RendererGL.h"
+
+namespace rx
+{
+
+SurfaceGL::SurfaceGL(const egl::SurfaceState &state, RendererGL *renderer)
+ : SurfaceImpl(state), mRenderer(renderer)
+{
+}
+
+SurfaceGL::~SurfaceGL()
+{
+}
+
+FramebufferImpl *SurfaceGL::createDefaultFramebuffer(const gl::FramebufferState &data)
+{
+ return new FramebufferGL(data, mRenderer->getFunctions(), mRenderer->getStateManager(),
+ mRenderer->getWorkarounds(), mRenderer->getBlitter(), true);
+}
+
+egl::Error SurfaceGL::unMakeCurrent()
+{
+ return egl::Error(EGL_SUCCESS);
+}
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/SurfaceGL.h b/gfx/angle/src/libANGLE/renderer/gl/SurfaceGL.h
new file mode 100755
index 000000000..681c365d2
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/SurfaceGL.h
@@ -0,0 +1,36 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// SurfaceGL.h: Defines the class interface for SurfaceGL.
+
+#ifndef LIBANGLE_RENDERER_GL_SURFACEGL_H_
+#define LIBANGLE_RENDERER_GL_SURFACEGL_H_
+
+#include "libANGLE/renderer/SurfaceImpl.h"
+
+namespace rx
+{
+
+class RendererGL;
+
+class SurfaceGL : public SurfaceImpl
+{
+ public:
+ SurfaceGL(const egl::SurfaceState &state, RendererGL *renderer);
+ ~SurfaceGL() override;
+
+ FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &data) override;
+
+ virtual egl::Error makeCurrent() = 0;
+ virtual egl::Error unMakeCurrent();
+
+ private:
+ RendererGL *mRenderer;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_SURFACEGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/TextureGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/TextureGL.cpp
new file mode 100755
index 000000000..589580505
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/TextureGL.cpp
@@ -0,0 +1,1039 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// TextureGL.cpp: Implements the class methods for TextureGL.
+
+#include "libANGLE/renderer/gl/TextureGL.h"
+
+#include "common/BitSetIterator.h"
+#include "common/debug.h"
+#include "common/utilities.h"
+#include "libANGLE/State.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/gl/BlitGL.h"
+#include "libANGLE/renderer/gl/BufferGL.h"
+#include "libANGLE/renderer/gl/FramebufferGL.h"
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+#include "libANGLE/renderer/gl/StateManagerGL.h"
+#include "libANGLE/renderer/gl/WorkaroundsGL.h"
+#include "libANGLE/renderer/gl/formatutilsgl.h"
+#include "libANGLE/renderer/gl/renderergl_utils.h"
+
+using angle::CheckedNumeric;
+
+namespace rx
+{
+
+namespace
+{
+
+bool UseTexImage2D(GLenum textureType)
+{
+ return textureType == GL_TEXTURE_2D || textureType == GL_TEXTURE_CUBE_MAP;
+}
+
+bool UseTexImage3D(GLenum textureType)
+{
+ return textureType == GL_TEXTURE_2D_ARRAY || textureType == GL_TEXTURE_3D;
+}
+
+bool CompatibleTextureTarget(GLenum textureType, GLenum textureTarget)
+{
+ if (textureType != GL_TEXTURE_CUBE_MAP)
+ {
+ return textureType == textureTarget;
+ }
+ else
+ {
+ return gl::IsCubeMapTextureTarget(textureTarget);
+ }
+}
+
+bool IsLUMAFormat(GLenum format)
+{
+ return format == GL_LUMINANCE || format == GL_ALPHA || format == GL_LUMINANCE_ALPHA;
+}
+
+LUMAWorkaroundGL GetLUMAWorkaroundInfo(const gl::InternalFormat &originalFormatInfo,
+ GLenum destinationFormat)
+{
+ if (IsLUMAFormat(originalFormatInfo.format))
+ {
+ const gl::InternalFormat &destinationFormatInfo =
+ gl::GetInternalFormatInfo(destinationFormat);
+ return LUMAWorkaroundGL(!IsLUMAFormat(destinationFormatInfo.format),
+ destinationFormatInfo.format);
+ }
+ else
+ {
+ return LUMAWorkaroundGL(false, GL_NONE);
+ }
+}
+
+bool IsDepthStencilFormat(GLenum format)
+{
+ return format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL;
+}
+
+bool GetDepthStencilWorkaround(const gl::InternalFormat &originalFormatInfo)
+{
+ return IsDepthStencilFormat(originalFormatInfo.format);
+}
+
+LevelInfoGL GetLevelInfo(GLenum originalFormat, GLenum destinationFormat)
+{
+ const gl::InternalFormat &originalFormatInfo = gl::GetInternalFormatInfo(originalFormat);
+ return LevelInfoGL(originalFormat, GetDepthStencilWorkaround(originalFormatInfo),
+ GetLUMAWorkaroundInfo(originalFormatInfo, destinationFormat));
+}
+
+gl::Texture::DirtyBits GetLevelWorkaroundDirtyBits()
+{
+ gl::Texture::DirtyBits bits;
+ bits.set(gl::Texture::DIRTY_BIT_SWIZZLE_RED);
+ bits.set(gl::Texture::DIRTY_BIT_SWIZZLE_GREEN);
+ bits.set(gl::Texture::DIRTY_BIT_SWIZZLE_BLUE);
+ bits.set(gl::Texture::DIRTY_BIT_SWIZZLE_ALPHA);
+ return bits;
+}
+
+} // anonymous namespace
+
+LUMAWorkaroundGL::LUMAWorkaroundGL() : LUMAWorkaroundGL(false, GL_NONE)
+{
+}
+
+LUMAWorkaroundGL::LUMAWorkaroundGL(bool enabled_, GLenum workaroundFormat_)
+ : enabled(enabled_), workaroundFormat(workaroundFormat_)
+{
+}
+
+LevelInfoGL::LevelInfoGL() : LevelInfoGL(GL_NONE, false, LUMAWorkaroundGL())
+{
+}
+
+LevelInfoGL::LevelInfoGL(GLenum sourceFormat_,
+ bool depthStencilWorkaround_,
+ const LUMAWorkaroundGL &lumaWorkaround_)
+ : sourceFormat(sourceFormat_),
+ depthStencilWorkaround(depthStencilWorkaround_),
+ lumaWorkaround(lumaWorkaround_)
+{
+}
+
+TextureGL::TextureGL(const gl::TextureState &state,
+ const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ StateManagerGL *stateManager,
+ BlitGL *blitter)
+ : TextureImpl(state),
+ mFunctions(functions),
+ mWorkarounds(workarounds),
+ mStateManager(stateManager),
+ mBlitter(blitter),
+ mLevelInfo(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS + 1),
+ mAppliedTextureState(state.mTarget),
+ mTextureID(0)
+{
+ ASSERT(mFunctions);
+ ASSERT(mStateManager);
+ ASSERT(mBlitter);
+
+ mFunctions->genTextures(1, &mTextureID);
+ mStateManager->bindTexture(mState.mTarget, mTextureID);
+}
+
+TextureGL::~TextureGL()
+{
+ mStateManager->deleteTexture(mTextureID);
+ mTextureID = 0;
+}
+
+gl::Error TextureGL::setImage(GLenum target,
+ size_t level,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ const uint8_t *pixels)
+{
+ if (mWorkarounds.unpackOverlappingRowsSeparatelyUnpackBuffer && unpack.pixelBuffer.get() &&
+ unpack.rowLength != 0 && unpack.rowLength < size.width)
+ {
+ // The rows overlap in unpack memory. Upload the texture row by row to work around
+ // driver bug.
+ reserveTexImageToBeFilled(target, level, internalFormat, size, format, type);
+
+ if (size.width == 0 || size.height == 0 || size.depth == 0)
+ {
+ return gl::NoError();
+ }
+
+ gl::Box area(0, 0, 0, size.width, size.height, size.depth);
+ return setSubImageRowByRowWorkaround(target, level, area, format, type, unpack, pixels);
+ }
+
+ if (mWorkarounds.unpackLastRowSeparatelyForPaddingInclusion)
+ {
+ bool apply;
+ ANGLE_TRY_RESULT(ShouldApplyLastRowPaddingWorkaround(size, unpack, format, type,
+ UseTexImage3D(mState.mTarget), pixels),
+ apply);
+
+ // The driver will think the pixel buffer doesn't have enough data, work around this bug
+ // by uploading the last row (and last level if 3D) separately.
+ if (apply)
+ {
+ reserveTexImageToBeFilled(target, level, internalFormat, size, format, type);
+
+ if (size.width == 0 || size.height == 0 || size.depth == 0)
+ {
+ return gl::NoError();
+ }
+
+ gl::Box area(0, 0, 0, size.width, size.height, size.depth);
+ return setSubImagePaddingWorkaround(target, level, area, format, type, unpack, pixels);
+ }
+ }
+
+ setImageHelper(target, level, internalFormat, size, format, type, pixels);
+
+ return gl::NoError();
+}
+
+void TextureGL::setImageHelper(GLenum target,
+ size_t level,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ GLenum format,
+ GLenum type,
+ const uint8_t *pixels)
+{
+ ASSERT(CompatibleTextureTarget(mState.mTarget, target));
+
+ nativegl::TexImageFormat texImageFormat =
+ nativegl::GetTexImageFormat(mFunctions, mWorkarounds, internalFormat, format, type);
+
+ mStateManager->bindTexture(mState.mTarget, mTextureID);
+
+ if (UseTexImage2D(mState.mTarget))
+ {
+ ASSERT(size.depth == 1);
+ mFunctions->texImage2D(target, static_cast<GLint>(level), texImageFormat.internalFormat,
+ size.width, size.height, 0, texImageFormat.format,
+ texImageFormat.type, pixels);
+ }
+ else if (UseTexImage3D(mState.mTarget))
+ {
+ mFunctions->texImage3D(target, static_cast<GLint>(level), texImageFormat.internalFormat,
+ size.width, size.height, size.depth, 0, texImageFormat.format,
+ texImageFormat.type, pixels);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+
+ setLevelInfo(level, 1, GetLevelInfo(internalFormat, texImageFormat.internalFormat));
+}
+
+void TextureGL::reserveTexImageToBeFilled(GLenum target,
+ size_t level,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ GLenum format,
+ GLenum type)
+{
+ GLuint unpackBuffer = mStateManager->getBoundBuffer(GL_PIXEL_UNPACK_BUFFER);
+ mStateManager->bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+ gl::PixelUnpackState unpack;
+ setImageHelper(target, level, internalFormat, size, format, type, nullptr);
+ mStateManager->bindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer);
+}
+
+gl::Error TextureGL::setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels)
+{
+ ASSERT(CompatibleTextureTarget(mState.mTarget, target));
+
+ nativegl::TexSubImageFormat texSubImageFormat =
+ nativegl::GetTexSubImageFormat(mFunctions, mWorkarounds, format, type);
+
+ ASSERT(mLevelInfo[level].lumaWorkaround.enabled ==
+ GetLevelInfo(format, texSubImageFormat.format).lumaWorkaround.enabled);
+
+ mStateManager->bindTexture(mState.mTarget, mTextureID);
+ if (mWorkarounds.unpackOverlappingRowsSeparatelyUnpackBuffer && unpack.pixelBuffer.get() &&
+ unpack.rowLength != 0 && unpack.rowLength < area.width)
+ {
+ return setSubImageRowByRowWorkaround(target, level, area, format, type, unpack, pixels);
+ }
+
+ if (mWorkarounds.unpackLastRowSeparatelyForPaddingInclusion)
+ {
+ gl::Extents size(area.width, area.height, area.depth);
+
+ bool apply;
+ ANGLE_TRY_RESULT(ShouldApplyLastRowPaddingWorkaround(size, unpack, format, type,
+ UseTexImage3D(mState.mTarget), pixels),
+ apply);
+
+ // The driver will think the pixel buffer doesn't have enough data, work around this bug
+ // by uploading the last row (and last level if 3D) separately.
+ if (apply)
+ {
+ return setSubImagePaddingWorkaround(target, level, area, format, type, unpack, pixels);
+ }
+ }
+
+ if (UseTexImage2D(mState.mTarget))
+ {
+ ASSERT(area.z == 0 && area.depth == 1);
+ mFunctions->texSubImage2D(target, static_cast<GLint>(level), area.x, area.y, area.width,
+ area.height, texSubImageFormat.format, texSubImageFormat.type,
+ pixels);
+ }
+ else
+ {
+ ASSERT(UseTexImage3D(mState.mTarget));
+ mFunctions->texSubImage3D(target, static_cast<GLint>(level), area.x, area.y, area.z,
+ area.width, area.height, area.depth, texSubImageFormat.format,
+ texSubImageFormat.type, pixels);
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error TextureGL::setSubImageRowByRowWorkaround(GLenum target,
+ size_t level,
+ const gl::Box &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ const uint8_t *pixels)
+{
+ gl::PixelUnpackState directUnpack;
+ directUnpack.pixelBuffer = unpack.pixelBuffer;
+ directUnpack.alignment = 1;
+ mStateManager->setPixelUnpackState(directUnpack);
+ directUnpack.pixelBuffer.set(nullptr);
+
+ const gl::InternalFormat &glFormat =
+ gl::GetInternalFormatInfo(gl::GetSizedInternalFormat(format, type));
+ GLuint rowBytes = 0;
+ ANGLE_TRY_RESULT(glFormat.computeRowPitch(area.width, unpack.alignment, unpack.rowLength),
+ rowBytes);
+ GLuint imageBytes = 0;
+ ANGLE_TRY_RESULT(gl::InternalFormat::computeDepthPitch(area.height, unpack.imageHeight, rowBytes),
+ imageBytes);
+ bool useTexImage3D = UseTexImage3D(mState.mTarget);
+ GLuint skipBytes = 0;
+ ANGLE_TRY_RESULT(glFormat.computeSkipBytes(rowBytes, imageBytes, unpack, useTexImage3D),
+ skipBytes);
+
+ const uint8_t *pixelsWithSkip = pixels + skipBytes;
+ if (useTexImage3D)
+ {
+ for (GLint image = 0; image < area.depth; ++image)
+ {
+ GLint imageByteOffset = image * imageBytes;
+ for (GLint row = 0; row < area.height; ++row)
+ {
+ GLint byteOffset = imageByteOffset + row * rowBytes;
+ const GLubyte *rowPixels = pixelsWithSkip + byteOffset;
+ mFunctions->texSubImage3D(target, static_cast<GLint>(level), area.x, row + area.y,
+ image + area.z, area.width, 1, 1, format, type,
+ rowPixels);
+ }
+ }
+ }
+ else
+ {
+ ASSERT(UseTexImage2D(mState.mTarget));
+ for (GLint row = 0; row < area.height; ++row)
+ {
+ GLint byteOffset = row * rowBytes;
+ const GLubyte *rowPixels = pixelsWithSkip + byteOffset;
+ mFunctions->texSubImage2D(target, static_cast<GLint>(level), area.x, row + area.y,
+ area.width, 1, format, type, rowPixels);
+ }
+ }
+ return gl::NoError();
+}
+
+gl::Error TextureGL::setSubImagePaddingWorkaround(GLenum target,
+ size_t level,
+ const gl::Box &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ const uint8_t *pixels)
+{
+ const gl::InternalFormat &glFormat =
+ gl::GetInternalFormatInfo(gl::GetSizedInternalFormat(format, type));
+ GLuint rowBytes = 0;
+ ANGLE_TRY_RESULT(glFormat.computeRowPitch(area.width, unpack.alignment, unpack.rowLength),
+ rowBytes);
+ GLuint imageBytes = 0;
+ ANGLE_TRY_RESULT(gl::InternalFormat::computeDepthPitch(area.height, unpack.imageHeight, rowBytes),
+ imageBytes);
+ bool useTexImage3D = UseTexImage3D(mState.mTarget);
+ GLuint skipBytes = 0;
+ ANGLE_TRY_RESULT(glFormat.computeSkipBytes(rowBytes, imageBytes, unpack, useTexImage3D),
+ skipBytes);
+
+ gl::PixelUnpackState directUnpack;
+ directUnpack.pixelBuffer = unpack.pixelBuffer;
+ directUnpack.alignment = 1;
+
+ if (useTexImage3D)
+ {
+ // Upload all but the last slice
+ if (area.depth > 1)
+ {
+ mFunctions->texSubImage3D(target, static_cast<GLint>(level), area.x, area.y, area.z,
+ area.width, area.height, area.depth - 1, format, type,
+ pixels);
+ }
+
+ // Upload the last slice but its last row
+ if (area.height > 1)
+ {
+ // Do not include skipBytes in the last image pixel start offset as it will be done by
+ // the driver
+ GLint lastImageOffset = (area.depth - 1) * imageBytes;
+ const GLubyte *lastImagePixels = pixels + lastImageOffset;
+ mFunctions->texSubImage3D(target, static_cast<GLint>(level), area.x, area.y,
+ area.z + area.depth - 1, area.width, area.height - 1, 1,
+ format, type, lastImagePixels);
+ }
+
+ // Upload the last row of the last slice "manually"
+ mStateManager->setPixelUnpackState(directUnpack);
+
+ GLint lastRowOffset =
+ skipBytes + (area.depth - 1) * imageBytes + (area.height - 1) * rowBytes;
+ const GLubyte *lastRowPixels = pixels + lastRowOffset;
+ mFunctions->texSubImage3D(target, static_cast<GLint>(level), area.x,
+ area.y + area.height - 1, area.z + area.depth - 1, area.width, 1,
+ 1, format, type, lastRowPixels);
+ }
+ else
+ {
+ ASSERT(UseTexImage2D(mState.mTarget));
+
+ // Upload all but the last row
+ if (area.height > 1)
+ {
+ mFunctions->texSubImage2D(target, static_cast<GLint>(level), area.x, area.y, area.width,
+ area.height - 1, format, type, pixels);
+ }
+
+ // Upload the last row "manually"
+ mStateManager->setPixelUnpackState(directUnpack);
+
+ GLint lastRowOffset = skipBytes + (area.height - 1) * rowBytes;
+ const GLubyte *lastRowPixels = pixels + lastRowOffset;
+ mFunctions->texSubImage2D(target, static_cast<GLint>(level), area.x,
+ area.y + area.height - 1, area.width, 1, format, type,
+ lastRowPixels);
+ }
+
+ directUnpack.pixelBuffer.set(nullptr);
+
+ return gl::NoError();
+}
+
+gl::Error TextureGL::setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size,
+ const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels)
+{
+ ASSERT(CompatibleTextureTarget(mState.mTarget, target));
+
+ nativegl::CompressedTexImageFormat compressedTexImageFormat =
+ nativegl::GetCompressedTexImageFormat(mFunctions, mWorkarounds, internalFormat);
+
+ mStateManager->bindTexture(mState.mTarget, mTextureID);
+ if (UseTexImage2D(mState.mTarget))
+ {
+ ASSERT(size.depth == 1);
+ mFunctions->compressedTexImage2D(target, static_cast<GLint>(level),
+ compressedTexImageFormat.internalFormat, size.width,
+ size.height, 0, static_cast<GLsizei>(imageSize), pixels);
+ }
+ else if (UseTexImage3D(mState.mTarget))
+ {
+ mFunctions->compressedTexImage3D(
+ target, static_cast<GLint>(level), compressedTexImageFormat.internalFormat, size.width,
+ size.height, size.depth, 0, static_cast<GLsizei>(imageSize), pixels);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+
+ setLevelInfo(level, 1, GetLevelInfo(internalFormat, compressedTexImageFormat.internalFormat));
+ ASSERT(!mLevelInfo[level].lumaWorkaround.enabled);
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error TextureGL::setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format,
+ const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels)
+{
+ ASSERT(CompatibleTextureTarget(mState.mTarget, target));
+
+ nativegl::CompressedTexSubImageFormat compressedTexSubImageFormat =
+ nativegl::GetCompressedSubTexImageFormat(mFunctions, mWorkarounds, format);
+
+ mStateManager->bindTexture(mState.mTarget, mTextureID);
+ if (UseTexImage2D(mState.mTarget))
+ {
+ ASSERT(area.z == 0 && area.depth == 1);
+ mFunctions->compressedTexSubImage2D(
+ target, static_cast<GLint>(level), area.x, area.y, area.width, area.height,
+ compressedTexSubImageFormat.format, static_cast<GLsizei>(imageSize), pixels);
+ }
+ else if (UseTexImage3D(mState.mTarget))
+ {
+ mFunctions->compressedTexSubImage3D(target, static_cast<GLint>(level), area.x, area.y,
+ area.z, area.width, area.height, area.depth,
+ compressedTexSubImageFormat.format,
+ static_cast<GLsizei>(imageSize), pixels);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+
+ ASSERT(!mLevelInfo[level].lumaWorkaround.enabled &&
+ !GetLevelInfo(format, compressedTexSubImageFormat.format).lumaWorkaround.enabled);
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error TextureGL::copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat,
+ const gl::Framebuffer *source)
+{
+ nativegl::CopyTexImageImageFormat copyTexImageFormat = nativegl::GetCopyTexImageImageFormat(
+ mFunctions, mWorkarounds, internalFormat, source->getImplementationColorReadType());
+
+ LevelInfoGL levelInfo = GetLevelInfo(internalFormat, copyTexImageFormat.internalFormat);
+ if (levelInfo.lumaWorkaround.enabled)
+ {
+ gl::Error error = mBlitter->copyImageToLUMAWorkaroundTexture(
+ mTextureID, mState.mTarget, target, levelInfo.sourceFormat, level, sourceArea,
+ copyTexImageFormat.internalFormat, source);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ else
+ {
+ const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(source);
+
+ mStateManager->bindTexture(mState.mTarget, mTextureID);
+ mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER,
+ sourceFramebufferGL->getFramebufferID());
+
+ if (UseTexImage2D(mState.mTarget))
+ {
+ mFunctions->copyTexImage2D(target, static_cast<GLint>(level),
+ copyTexImageFormat.internalFormat, sourceArea.x,
+ sourceArea.y, sourceArea.width, sourceArea.height, 0);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ }
+
+ setLevelInfo(level, 1, levelInfo);
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error TextureGL::copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea,
+ const gl::Framebuffer *source)
+{
+ const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(source);
+
+ mStateManager->bindTexture(mState.mTarget, mTextureID);
+ mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceFramebufferGL->getFramebufferID());
+
+ const LevelInfoGL &levelInfo = mLevelInfo[level];
+ if (levelInfo.lumaWorkaround.enabled)
+ {
+ gl::Error error = mBlitter->copySubImageToLUMAWorkaroundTexture(
+ mTextureID, mState.mTarget, target, levelInfo.sourceFormat, level, destOffset,
+ sourceArea, source);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ else
+ {
+ if (UseTexImage2D(mState.mTarget))
+ {
+ ASSERT(destOffset.z == 0);
+ mFunctions->copyTexSubImage2D(target, static_cast<GLint>(level), destOffset.x,
+ destOffset.y, sourceArea.x, sourceArea.y,
+ sourceArea.width, sourceArea.height);
+ }
+ else if (UseTexImage3D(mState.mTarget))
+ {
+ mFunctions->copyTexSubImage3D(target, static_cast<GLint>(level), destOffset.x,
+ destOffset.y, destOffset.z, sourceArea.x, sourceArea.y,
+ sourceArea.width, sourceArea.height);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size)
+{
+ // TODO: emulate texture storage with TexImage calls if on GL version <4.2 or the
+ // ARB_texture_storage extension is not available.
+
+ nativegl::TexStorageFormat texStorageFormat =
+ nativegl::GetTexStorageFormat(mFunctions, mWorkarounds, internalFormat);
+
+ mStateManager->bindTexture(mState.mTarget, mTextureID);
+ if (UseTexImage2D(mState.mTarget))
+ {
+ ASSERT(size.depth == 1);
+ if (mFunctions->texStorage2D)
+ {
+ mFunctions->texStorage2D(target, static_cast<GLsizei>(levels),
+ texStorageFormat.internalFormat, size.width, size.height);
+ }
+ else
+ {
+ // Make sure no pixel unpack buffer is bound
+ mStateManager->bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+
+ const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
+
+ // Internal format must be sized
+ ASSERT(internalFormatInfo.pixelBytes != 0);
+
+ for (size_t level = 0; level < levels; level++)
+ {
+ gl::Extents levelSize(std::max(size.width >> level, 1),
+ std::max(size.height >> level, 1),
+ 1);
+
+ if (mState.mTarget == GL_TEXTURE_2D)
+ {
+ if (internalFormatInfo.compressed)
+ {
+ GLuint dataSize = 0;
+ ANGLE_TRY_RESULT(internalFormatInfo.computeCompressedImageSize(levelSize),
+ dataSize);
+ mFunctions->compressedTexImage2D(target, static_cast<GLint>(level),
+ texStorageFormat.internalFormat,
+ levelSize.width, levelSize.height, 0,
+ static_cast<GLsizei>(dataSize), nullptr);
+ }
+ else
+ {
+ mFunctions->texImage2D(target, static_cast<GLint>(level),
+ texStorageFormat.internalFormat, levelSize.width,
+ levelSize.height, 0, internalFormatInfo.format,
+ internalFormatInfo.type, nullptr);
+ }
+ }
+ else if (mState.mTarget == GL_TEXTURE_CUBE_MAP)
+ {
+ for (GLenum face = gl::FirstCubeMapTextureTarget; face <= gl::LastCubeMapTextureTarget; face++)
+ {
+ if (internalFormatInfo.compressed)
+ {
+ GLuint dataSize = 0;
+ ANGLE_TRY_RESULT(internalFormatInfo.computeCompressedImageSize(
+ levelSize),
+ dataSize);
+ mFunctions->compressedTexImage2D(
+ face, static_cast<GLint>(level), texStorageFormat.internalFormat,
+ levelSize.width, levelSize.height, 0,
+ static_cast<GLsizei>(dataSize), nullptr);
+ }
+ else
+ {
+ mFunctions->texImage2D(face, static_cast<GLint>(level),
+ texStorageFormat.internalFormat, levelSize.width,
+ levelSize.height, 0, internalFormatInfo.format,
+ internalFormatInfo.type, nullptr);
+ }
+ }
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ }
+ }
+ }
+ else if (UseTexImage3D(mState.mTarget))
+ {
+ if (mFunctions->texStorage3D)
+ {
+ mFunctions->texStorage3D(target, static_cast<GLsizei>(levels),
+ texStorageFormat.internalFormat, size.width, size.height,
+ size.depth);
+ }
+ else
+ {
+ // Make sure no pixel unpack buffer is bound
+ mStateManager->bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+
+ const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
+
+ // Internal format must be sized
+ ASSERT(internalFormatInfo.pixelBytes != 0);
+
+ for (GLsizei i = 0; i < static_cast<GLsizei>(levels); i++)
+ {
+ gl::Extents levelSize(
+ std::max(size.width >> i, 1), std::max(size.height >> i, 1),
+ mState.mTarget == GL_TEXTURE_3D ? std::max(size.depth >> i, 1) : size.depth);
+
+ if (internalFormatInfo.compressed)
+ {
+ GLuint dataSize = 0;
+ ANGLE_TRY_RESULT(
+ internalFormatInfo.computeCompressedImageSize(levelSize),
+ dataSize);
+ mFunctions->compressedTexImage3D(target, i, texStorageFormat.internalFormat,
+ levelSize.width, levelSize.height,
+ levelSize.depth, 0,
+ static_cast<GLsizei>(dataSize), nullptr);
+ }
+ else
+ {
+ mFunctions->texImage3D(target, i, texStorageFormat.internalFormat,
+ levelSize.width, levelSize.height, levelSize.depth, 0,
+ internalFormatInfo.format, internalFormatInfo.type,
+ nullptr);
+ }
+ }
+ }
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+
+ setLevelInfo(0, levels, GetLevelInfo(internalFormat, texStorageFormat.internalFormat));
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error TextureGL::setImageExternal(GLenum target,
+ egl::Stream *stream,
+ const egl::Stream::GLTextureDescription &desc)
+{
+ UNIMPLEMENTED();
+ return gl::Error(GL_INVALID_OPERATION);
+}
+
+gl::Error TextureGL::generateMipmap()
+{
+ mStateManager->bindTexture(mState.mTarget, mTextureID);
+ mFunctions->generateMipmap(mState.mTarget);
+
+ const GLuint effectiveBaseLevel = mState.getEffectiveBaseLevel();
+ const GLuint maxLevel = mState.getMipmapMaxLevel();
+
+ ASSERT(maxLevel < mLevelInfo.size());
+
+ setLevelInfo(effectiveBaseLevel, maxLevel - effectiveBaseLevel, mLevelInfo[effectiveBaseLevel]);
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+void TextureGL::bindTexImage(egl::Surface *surface)
+{
+ ASSERT(mState.mTarget == GL_TEXTURE_2D);
+
+ // Make sure this texture is bound
+ mStateManager->bindTexture(mState.mTarget, mTextureID);
+
+ setLevelInfo(0, 1, LevelInfoGL());
+}
+
+void TextureGL::releaseTexImage()
+{
+ // Not all Surface implementations reset the size of mip 0 when releasing, do it manually
+ ASSERT(mState.mTarget == GL_TEXTURE_2D);
+
+ mStateManager->bindTexture(mState.mTarget, mTextureID);
+ if (UseTexImage2D(mState.mTarget))
+ {
+ mFunctions->texImage2D(mState.mTarget, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+}
+
+gl::Error TextureGL::setEGLImageTarget(GLenum target, egl::Image *image)
+{
+ UNIMPLEMENTED();
+ return gl::Error(GL_INVALID_OPERATION);
+}
+
+void TextureGL::syncState(const gl::Texture::DirtyBits &dirtyBits)
+{
+ if (dirtyBits.none() && mLocalDirtyBits.none())
+ {
+ return;
+ }
+
+ mStateManager->bindTexture(mState.mTarget, mTextureID);
+
+ if (dirtyBits[gl::Texture::DIRTY_BIT_BASE_LEVEL] || dirtyBits[gl::Texture::DIRTY_BIT_MAX_LEVEL])
+ {
+ // Don't know if the previous base level was using any workarounds, always re-sync the
+ // workaround dirty bits
+ mLocalDirtyBits |= GetLevelWorkaroundDirtyBits();
+ }
+
+ for (auto dirtyBit : angle::IterateBitSet(dirtyBits | mLocalDirtyBits))
+ {
+ switch (dirtyBit)
+ {
+ case gl::Texture::DIRTY_BIT_MIN_FILTER:
+ mFunctions->texParameteri(mState.mTarget, GL_TEXTURE_MIN_FILTER,
+ mState.getSamplerState().minFilter);
+ break;
+ case gl::Texture::DIRTY_BIT_MAG_FILTER:
+ mFunctions->texParameteri(mState.mTarget, GL_TEXTURE_MAG_FILTER,
+ mState.getSamplerState().magFilter);
+ break;
+ case gl::Texture::DIRTY_BIT_WRAP_S:
+ mFunctions->texParameteri(mState.mTarget, GL_TEXTURE_WRAP_S,
+ mState.getSamplerState().wrapS);
+ break;
+ case gl::Texture::DIRTY_BIT_WRAP_T:
+ mFunctions->texParameteri(mState.mTarget, GL_TEXTURE_WRAP_T,
+ mState.getSamplerState().wrapT);
+ break;
+ case gl::Texture::DIRTY_BIT_WRAP_R:
+ mFunctions->texParameteri(mState.mTarget, GL_TEXTURE_WRAP_R,
+ mState.getSamplerState().wrapR);
+ break;
+ case gl::Texture::DIRTY_BIT_MAX_ANISOTROPY:
+ mFunctions->texParameterf(mState.mTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT,
+ mState.getSamplerState().maxAnisotropy);
+ break;
+ case gl::Texture::DIRTY_BIT_MIN_LOD:
+ mFunctions->texParameterf(mState.mTarget, GL_TEXTURE_MIN_LOD,
+ mState.getSamplerState().minLod);
+ break;
+ case gl::Texture::DIRTY_BIT_MAX_LOD:
+ mFunctions->texParameterf(mState.mTarget, GL_TEXTURE_MAX_LOD,
+ mState.getSamplerState().maxLod);
+ break;
+ case gl::Texture::DIRTY_BIT_COMPARE_MODE:
+ mFunctions->texParameteri(mState.mTarget, GL_TEXTURE_COMPARE_MODE,
+ mState.getSamplerState().compareMode);
+ break;
+ case gl::Texture::DIRTY_BIT_COMPARE_FUNC:
+ mFunctions->texParameteri(mState.mTarget, GL_TEXTURE_COMPARE_FUNC,
+ mState.getSamplerState().compareFunc);
+ break;
+ case gl::Texture::DIRTY_BIT_SRGB_DECODE:
+ mFunctions->texParameteri(mState.mTarget, GL_TEXTURE_SRGB_DECODE_EXT,
+ mState.getSamplerState().sRGBDecode);
+ break;
+
+ // Texture state
+ case gl::Texture::DIRTY_BIT_SWIZZLE_RED:
+ syncTextureStateSwizzle(mFunctions, GL_TEXTURE_SWIZZLE_R,
+ mState.getSwizzleState().swizzleRed);
+ break;
+ case gl::Texture::DIRTY_BIT_SWIZZLE_GREEN:
+ syncTextureStateSwizzle(mFunctions, GL_TEXTURE_SWIZZLE_G,
+ mState.getSwizzleState().swizzleGreen);
+ break;
+ case gl::Texture::DIRTY_BIT_SWIZZLE_BLUE:
+ syncTextureStateSwizzle(mFunctions, GL_TEXTURE_SWIZZLE_B,
+ mState.getSwizzleState().swizzleBlue);
+ break;
+ case gl::Texture::DIRTY_BIT_SWIZZLE_ALPHA:
+ syncTextureStateSwizzle(mFunctions, GL_TEXTURE_SWIZZLE_A,
+ mState.getSwizzleState().swizzleAlpha);
+ break;
+ case gl::Texture::DIRTY_BIT_BASE_LEVEL:
+ mFunctions->texParameteri(mState.mTarget, GL_TEXTURE_BASE_LEVEL,
+ mState.getEffectiveBaseLevel());
+ break;
+ case gl::Texture::DIRTY_BIT_MAX_LEVEL:
+ mFunctions->texParameteri(mState.mTarget, GL_TEXTURE_MAX_LEVEL,
+ mState.getEffectiveMaxLevel());
+ break;
+ case gl::Texture::DIRTY_BIT_USAGE:
+ break;
+
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ mLocalDirtyBits.reset();
+}
+
+bool TextureGL::hasAnyDirtyBit() const
+{
+ return mLocalDirtyBits.any();
+}
+
+void TextureGL::syncTextureStateSwizzle(const FunctionsGL *functions, GLenum name, GLenum value)
+{
+ const LevelInfoGL &levelInfo = mLevelInfo[mState.getEffectiveBaseLevel()];
+ GLenum resultSwizzle = value;
+ if (levelInfo.lumaWorkaround.enabled || levelInfo.depthStencilWorkaround)
+ {
+ if (levelInfo.lumaWorkaround.enabled)
+ {
+ switch (value)
+ {
+ case GL_RED:
+ case GL_GREEN:
+ case GL_BLUE:
+ if (levelInfo.sourceFormat == GL_LUMINANCE ||
+ levelInfo.sourceFormat == GL_LUMINANCE_ALPHA)
+ {
+ // Texture is backed by a RED or RG texture, point all color channels at the red
+ // channel.
+ ASSERT(levelInfo.lumaWorkaround.workaroundFormat == GL_RED ||
+ levelInfo.lumaWorkaround.workaroundFormat == GL_RG);
+ resultSwizzle = GL_RED;
+ }
+ else if (levelInfo.sourceFormat == GL_ALPHA)
+ {
+ // Color channels are not supposed to exist, make them always sample 0.
+ resultSwizzle = GL_ZERO;
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ break;
+
+ case GL_ALPHA:
+ if (levelInfo.sourceFormat == GL_LUMINANCE)
+ {
+ // Alpha channel is not supposed to exist, make it always sample 1.
+ resultSwizzle = GL_ONE;
+ }
+ else if (levelInfo.sourceFormat == GL_ALPHA)
+ {
+ // Texture is backed by a RED texture, point the alpha channel at the red
+ // channel.
+ ASSERT(levelInfo.lumaWorkaround.workaroundFormat == GL_RED);
+ resultSwizzle = GL_RED;
+ }
+ else if (levelInfo.sourceFormat == GL_LUMINANCE_ALPHA)
+ {
+ // Texture is backed by an RG texture, point the alpha channel at the green
+ // channel.
+ ASSERT(levelInfo.lumaWorkaround.workaroundFormat == GL_RG);
+ resultSwizzle = GL_GREEN;
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ break;
+
+ case GL_ZERO:
+ case GL_ONE:
+ // Don't modify the swizzle state when requesting ZERO or ONE.
+ resultSwizzle = value;
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ else if (levelInfo.depthStencilWorkaround)
+ {
+ switch (value)
+ {
+ case GL_RED:
+ // Don't modify the swizzle state when requesting the red channel.
+ resultSwizzle = value;
+ break;
+
+ case GL_GREEN:
+ case GL_BLUE:
+ // Depth textures should sample 0 from the green and blue channels.
+ resultSwizzle = GL_ZERO;
+ break;
+
+ case GL_ALPHA:
+ // Depth textures should sample 1 from the alpha channel.
+ resultSwizzle = GL_ONE;
+ break;
+
+ case GL_ZERO:
+ case GL_ONE:
+ // Don't modify the swizzle state when requesting ZERO or ONE.
+ resultSwizzle = value;
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+
+ }
+
+ functions->texParameteri(mState.mTarget, name, resultSwizzle);
+}
+
+void TextureGL::setLevelInfo(size_t level, size_t levelCount, const LevelInfoGL &levelInfo)
+{
+ ASSERT(levelCount > 0 && level + levelCount < mLevelInfo.size());
+
+ GLuint baseLevel = mState.getEffectiveBaseLevel();
+ bool needsResync = level <= baseLevel && level + levelCount >= baseLevel &&
+ (levelInfo.depthStencilWorkaround || levelInfo.lumaWorkaround.enabled);
+ if (needsResync)
+ {
+ mLocalDirtyBits |= GetLevelWorkaroundDirtyBits();
+ }
+
+ for (size_t i = level; i < level + levelCount; i++)
+ {
+ mLevelInfo[i] = levelInfo;
+ }
+}
+
+GLuint TextureGL::getTextureID() const
+{
+ return mTextureID;
+}
+
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/TextureGL.h b/gfx/angle/src/libANGLE/renderer/gl/TextureGL.h
new file mode 100755
index 000000000..068284c5b
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/TextureGL.h
@@ -0,0 +1,145 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// TextureGL.h: Defines the class interface for TextureGL.
+
+#ifndef LIBANGLE_RENDERER_GL_TEXTUREGL_H_
+#define LIBANGLE_RENDERER_GL_TEXTUREGL_H_
+
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/TextureImpl.h"
+#include "libANGLE/Texture.h"
+
+namespace rx
+{
+
+class BlitGL;
+class FunctionsGL;
+class StateManagerGL;
+struct WorkaroundsGL;
+
+struct LUMAWorkaroundGL
+{
+ bool enabled;
+ GLenum workaroundFormat;
+
+ LUMAWorkaroundGL();
+ LUMAWorkaroundGL(bool enabled, GLenum workaroundFormat);
+};
+
+// Structure containing information about format and workarounds for each mip level of the
+// TextureGL.
+struct LevelInfoGL
+{
+ // Format of the data used in this mip level.
+ GLenum sourceFormat;
+
+ // If this mip level requires sampler-state re-writing so that only a red channel is exposed.
+ bool depthStencilWorkaround;
+
+ // Information about luminance alpha texture workarounds in the core profile.
+ LUMAWorkaroundGL lumaWorkaround;
+
+ LevelInfoGL();
+ LevelInfoGL(GLenum sourceFormat,
+ bool depthStencilWorkaround,
+ const LUMAWorkaroundGL &lumaWorkaround);
+};
+
+class TextureGL : public TextureImpl
+{
+ public:
+ TextureGL(const gl::TextureState &state,
+ const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ StateManagerGL *stateManager,
+ BlitGL *blitter);
+ ~TextureGL() override;
+
+ gl::Error setImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels) override;
+ gl::Error setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels) override;
+
+ gl::Error setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size,
+ const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) override;
+ gl::Error setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format,
+ const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) override;
+
+ gl::Error copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat,
+ const gl::Framebuffer *source) override;
+ gl::Error copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea,
+ const gl::Framebuffer *source) override;
+
+ gl::Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) override;
+
+ gl::Error setImageExternal(GLenum target,
+ egl::Stream *stream,
+ const egl::Stream::GLTextureDescription &desc) override;
+
+ gl::Error generateMipmap() override;
+
+ void bindTexImage(egl::Surface *surface) override;
+ void releaseTexImage() override;
+
+ gl::Error setEGLImageTarget(GLenum target, egl::Image *image) override;
+
+ GLuint getTextureID() const;
+
+ void setBaseLevel(GLuint) override {}
+
+ void syncState(const gl::Texture::DirtyBits &dirtyBits) override;
+ bool hasAnyDirtyBit() const;
+
+ private:
+ void setImageHelper(GLenum target,
+ size_t level,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ GLenum format,
+ GLenum type,
+ const uint8_t *pixels);
+ void reserveTexImageToBeFilled(GLenum target,
+ size_t level,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ GLenum format,
+ GLenum type);
+ gl::Error setSubImageRowByRowWorkaround(GLenum target,
+ size_t level,
+ const gl::Box &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ const uint8_t *pixels);
+
+ gl::Error setSubImagePaddingWorkaround(GLenum target,
+ size_t level,
+ const gl::Box &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ const uint8_t *pixels);
+
+ void syncTextureStateSwizzle(const FunctionsGL *functions, GLenum name, GLenum value);
+
+ void setLevelInfo(size_t level, size_t levelCount, const LevelInfoGL &levelInfo);
+
+ const FunctionsGL *mFunctions;
+ const WorkaroundsGL &mWorkarounds;
+ StateManagerGL *mStateManager;
+ BlitGL *mBlitter;
+
+ std::vector<LevelInfoGL> mLevelInfo;
+ gl::Texture::DirtyBits mLocalDirtyBits;
+
+ mutable gl::TextureState mAppliedTextureState;
+ GLuint mTextureID;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_TEXTUREGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/TransformFeedbackGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/TransformFeedbackGL.cpp
new file mode 100755
index 000000000..ae75a0f47
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/TransformFeedbackGL.cpp
@@ -0,0 +1,131 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// TransformFeedbackGL.cpp: Implements the class methods for TransformFeedbackGL.
+
+#include "libANGLE/renderer/gl/TransformFeedbackGL.h"
+
+#include "common/debug.h"
+#include "libANGLE/ContextState.h"
+#include "libANGLE/renderer/gl/BufferGL.h"
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+#include "libANGLE/renderer/gl/StateManagerGL.h"
+
+namespace rx
+{
+
+TransformFeedbackGL::TransformFeedbackGL(const gl::TransformFeedbackState &state,
+ const FunctionsGL *functions,
+ StateManagerGL *stateManager)
+ : TransformFeedbackImpl(state),
+ mFunctions(functions),
+ mStateManager(stateManager),
+ mTransformFeedbackID(0),
+ mIsActive(false),
+ mIsPaused(false)
+{
+ mFunctions->genTransformFeedbacks(1, &mTransformFeedbackID);
+}
+
+TransformFeedbackGL::~TransformFeedbackGL()
+{
+ mStateManager->deleteTransformFeedback(mTransformFeedbackID);
+ mTransformFeedbackID = 0;
+}
+
+void TransformFeedbackGL::begin(GLenum primitiveMode)
+{
+ // Do not begin directly, StateManagerGL will handle beginning and resuming transform feedback.
+}
+
+void TransformFeedbackGL::end()
+{
+ syncActiveState(false, GL_NONE);
+}
+
+void TransformFeedbackGL::pause()
+{
+ syncPausedState(true);
+}
+
+void TransformFeedbackGL::resume()
+{
+ // Do not resume directly, StateManagerGL will handle beginning and resuming transform feedback.
+}
+
+void TransformFeedbackGL::bindGenericBuffer(const BindingPointer<gl::Buffer> &binding)
+{
+}
+
+void TransformFeedbackGL::bindIndexedBuffer(size_t index, const OffsetBindingPointer<gl::Buffer> &binding)
+{
+ // Directly bind buffer (not through the StateManager methods) because the buffer bindings are
+ // tracked per transform feedback object
+ mStateManager->bindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedbackID);
+ if (binding.get() != nullptr)
+ {
+ const BufferGL *bufferGL = GetImplAs<BufferGL>(binding.get());
+ if (binding.getSize() != 0)
+ {
+ mFunctions->bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast<GLuint>(index),
+ bufferGL->getBufferID(), binding.getOffset(),
+ binding.getSize());
+ }
+ else
+ {
+ mFunctions->bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast<GLuint>(index),
+ bufferGL->getBufferID());
+ }
+ }
+ else
+ {
+ mFunctions->bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast<GLuint>(index), 0);
+ }
+}
+
+GLuint TransformFeedbackGL::getTransformFeedbackID() const
+{
+ return mTransformFeedbackID;
+}
+
+void TransformFeedbackGL::syncActiveState(bool active, GLenum primitiveMode) const
+{
+ if (mIsActive != active)
+ {
+ mIsActive = active;
+ mIsPaused = false;
+
+ mStateManager->bindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedbackID);
+ if (mIsActive)
+ {
+ mFunctions->beginTransformFeedback(primitiveMode);
+ }
+ else
+ {
+ mFunctions->endTransformFeedback();
+ }
+ }
+}
+
+void TransformFeedbackGL::syncPausedState(bool paused) const
+{
+ if (mIsActive && mIsPaused != paused)
+ {
+ mIsPaused = paused;
+
+ mStateManager->bindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedbackID);
+ if (mIsPaused)
+ {
+ mFunctions->pauseTransformFeedback();
+ }
+ else
+ {
+ mFunctions->resumeTransformFeedback();
+ }
+ }
+}
+
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/TransformFeedbackGL.h b/gfx/angle/src/libANGLE/renderer/gl/TransformFeedbackGL.h
new file mode 100755
index 000000000..f84edc0b7
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/TransformFeedbackGL.h
@@ -0,0 +1,53 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// TransformFeedbackGL.h: Defines the class interface for TransformFeedbackGL.
+
+#ifndef LIBANGLE_RENDERER_GL_TRANSFORMFEEDBACKGL_H_
+#define LIBANGLE_RENDERER_GL_TRANSFORMFEEDBACKGL_H_
+
+#include "libANGLE/renderer/TransformFeedbackImpl.h"
+
+namespace rx
+{
+
+class FunctionsGL;
+class StateManagerGL;
+
+class TransformFeedbackGL : public TransformFeedbackImpl
+{
+ public:
+ TransformFeedbackGL(const gl::TransformFeedbackState &state,
+ const FunctionsGL *functions,
+ StateManagerGL *stateManager);
+ ~TransformFeedbackGL() override;
+
+ void begin(GLenum primitiveMode) override;
+ void end() override;
+ void pause() override;
+ void resume() override;
+
+ void bindGenericBuffer(const BindingPointer<gl::Buffer> &binding) override;
+ void bindIndexedBuffer(size_t index, const OffsetBindingPointer<gl::Buffer> &binding) override;
+
+ GLuint getTransformFeedbackID() const;
+
+ void syncActiveState(bool active, GLenum primitiveMode) const;
+ void syncPausedState(bool paused) const;
+
+ private:
+ const FunctionsGL *mFunctions;
+ StateManagerGL *mStateManager;
+
+ GLuint mTransformFeedbackID;
+
+ mutable bool mIsActive;
+ mutable bool mIsPaused;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_TRANSFORMFEEDBACKGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/VertexArrayGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/VertexArrayGL.cpp
new file mode 100755
index 000000000..1e7fa030f
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/VertexArrayGL.cpp
@@ -0,0 +1,499 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// VertexArrayGL.cpp: Implements the class methods for VertexArrayGL.
+
+#include "libANGLE/renderer/gl/VertexArrayGL.h"
+
+#include "common/BitSetIterator.h"
+#include "common/debug.h"
+#include "common/mathutil.h"
+#include "common/utilities.h"
+#include "libANGLE/Buffer.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/gl/BufferGL.h"
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+#include "libANGLE/renderer/gl/renderergl_utils.h"
+#include "libANGLE/renderer/gl/StateManagerGL.h"
+
+using namespace gl;
+
+namespace rx
+{
+namespace
+{
+bool AttributeNeedsStreaming(const VertexAttribute &attribute)
+{
+ return (attribute.enabled && attribute.buffer.get() == nullptr);
+}
+
+} // anonymous namespace
+
+VertexArrayGL::VertexArrayGL(const VertexArrayState &state,
+ const FunctionsGL *functions,
+ StateManagerGL *stateManager)
+ : VertexArrayImpl(state),
+ mFunctions(functions),
+ mStateManager(stateManager),
+ mVertexArrayID(0),
+ mAppliedElementArrayBuffer(),
+ mStreamingElementArrayBufferSize(0),
+ mStreamingElementArrayBuffer(0),
+ mStreamingArrayBufferSize(0),
+ mStreamingArrayBuffer(0)
+{
+ ASSERT(mFunctions);
+ ASSERT(mStateManager);
+ mFunctions->genVertexArrays(1, &mVertexArrayID);
+
+ // Set the cached vertex attribute array size
+ GLint maxVertexAttribs = 0;
+ mFunctions->getIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
+ mAppliedAttributes.resize(maxVertexAttribs);
+}
+
+VertexArrayGL::~VertexArrayGL()
+{
+ mStateManager->deleteVertexArray(mVertexArrayID);
+ mVertexArrayID = 0;
+
+ mStateManager->deleteBuffer(mStreamingElementArrayBuffer);
+ mStreamingElementArrayBufferSize = 0;
+ mStreamingElementArrayBuffer = 0;
+
+ mStateManager->deleteBuffer(mStreamingArrayBuffer);
+ mStreamingArrayBufferSize = 0;
+ mStreamingArrayBuffer = 0;
+
+ mAppliedElementArrayBuffer.set(nullptr);
+ for (size_t idx = 0; idx < mAppliedAttributes.size(); idx++)
+ {
+ mAppliedAttributes[idx].buffer.set(nullptr);
+ }
+}
+
+gl::Error VertexArrayGL::syncDrawArraysState(const gl::AttributesMask &activeAttributesMask,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount) const
+{
+ return syncDrawState(activeAttributesMask, first, count, GL_NONE, nullptr, instanceCount, false,
+ nullptr);
+}
+
+gl::Error VertexArrayGL::syncDrawElementsState(const gl::AttributesMask &activeAttributesMask,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ GLsizei instanceCount,
+ bool primitiveRestartEnabled,
+ const GLvoid **outIndices) const
+{
+ return syncDrawState(activeAttributesMask, 0, count, type, indices, instanceCount,
+ primitiveRestartEnabled, outIndices);
+}
+
+gl::Error VertexArrayGL::syncDrawState(const gl::AttributesMask &activeAttributesMask,
+ GLint first,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ GLsizei instanceCount,
+ bool primitiveRestartEnabled,
+ const GLvoid **outIndices) const
+{
+ mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID());
+
+ // Check if any attributes need to be streamed, determines if the index range needs to be computed
+ bool attributesNeedStreaming = mAttributesNeedStreaming.any();
+
+ // Determine if an index buffer needs to be streamed and the range of vertices that need to be copied
+ IndexRange indexRange;
+ if (type != GL_NONE)
+ {
+ Error error = syncIndexData(count, type, indices, primitiveRestartEnabled,
+ attributesNeedStreaming, &indexRange, outIndices);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ else
+ {
+ // Not an indexed call, set the range to [first, first + count - 1]
+ indexRange.start = first;
+ indexRange.end = first + count - 1;
+ }
+
+ if (attributesNeedStreaming)
+ {
+ Error error = streamAttributes(activeAttributesMask, instanceCount, indexRange);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ return Error(GL_NO_ERROR);
+}
+
+Error VertexArrayGL::syncIndexData(GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ bool primitiveRestartEnabled,
+ bool attributesNeedStreaming,
+ IndexRange *outIndexRange,
+ const GLvoid **outIndices) const
+{
+ ASSERT(outIndices);
+
+ gl::Buffer *elementArrayBuffer = mData.getElementArrayBuffer().get();
+
+ // Need to check the range of indices if attributes need to be streamed
+ if (elementArrayBuffer != nullptr)
+ {
+ if (elementArrayBuffer != mAppliedElementArrayBuffer.get())
+ {
+ const BufferGL *bufferGL = GetImplAs<BufferGL>(elementArrayBuffer);
+ mStateManager->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferGL->getBufferID());
+ mAppliedElementArrayBuffer.set(elementArrayBuffer);
+ }
+
+ // Only compute the index range if the attributes also need to be streamed
+ if (attributesNeedStreaming)
+ {
+ ptrdiff_t elementArrayBufferOffset = reinterpret_cast<ptrdiff_t>(indices);
+ Error error = mData.getElementArrayBuffer()->getIndexRange(
+ type, elementArrayBufferOffset, count, primitiveRestartEnabled, outIndexRange);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ // Indices serves as an offset into the index buffer in this case, use the same value for the draw call
+ *outIndices = indices;
+ }
+ else
+ {
+ // Need to stream the index buffer
+ // TODO: if GLES, nothing needs to be streamed
+
+ // Only compute the index range if the attributes also need to be streamed
+ if (attributesNeedStreaming)
+ {
+ *outIndexRange = ComputeIndexRange(type, indices, count, primitiveRestartEnabled);
+ }
+
+ // Allocate the streaming element array buffer
+ if (mStreamingElementArrayBuffer == 0)
+ {
+ mFunctions->genBuffers(1, &mStreamingElementArrayBuffer);
+ mStreamingElementArrayBufferSize = 0;
+ }
+
+ mStateManager->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, mStreamingElementArrayBuffer);
+ mAppliedElementArrayBuffer.set(nullptr);
+
+ // Make sure the element array buffer is large enough
+ const Type &indexTypeInfo = GetTypeInfo(type);
+ size_t requiredStreamingBufferSize = indexTypeInfo.bytes * count;
+ if (requiredStreamingBufferSize > mStreamingElementArrayBufferSize)
+ {
+ // Copy the indices in while resizing the buffer
+ mFunctions->bufferData(GL_ELEMENT_ARRAY_BUFFER, requiredStreamingBufferSize, indices, GL_DYNAMIC_DRAW);
+ mStreamingElementArrayBufferSize = requiredStreamingBufferSize;
+ }
+ else
+ {
+ // Put the indices at the beginning of the buffer
+ mFunctions->bufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, requiredStreamingBufferSize, indices);
+ }
+
+ // Set the index offset for the draw call to zero since the supplied index pointer is to client data
+ *outIndices = nullptr;
+ }
+
+ return Error(GL_NO_ERROR);
+}
+
+void VertexArrayGL::computeStreamingAttributeSizes(const gl::AttributesMask &activeAttributesMask,
+ GLsizei instanceCount,
+ const gl::IndexRange &indexRange,
+ size_t *outStreamingDataSize,
+ size_t *outMaxAttributeDataSize) const
+{
+ *outStreamingDataSize = 0;
+ *outMaxAttributeDataSize = 0;
+
+ ASSERT(mAttributesNeedStreaming.any());
+
+ const auto &attribs = mData.getVertexAttributes();
+ for (auto idx : angle::IterateBitSet(mAttributesNeedStreaming & activeAttributesMask))
+ {
+ const auto &attrib = attribs[idx];
+ ASSERT(AttributeNeedsStreaming(attrib));
+
+ // If streaming is going to be required, compute the size of the required buffer
+ // and how much slack space at the beginning of the buffer will be required by determining
+ // the attribute with the largest data size.
+ size_t typeSize = ComputeVertexAttributeTypeSize(attrib);
+ *outStreamingDataSize += typeSize * ComputeVertexAttributeElementCount(
+ attrib, indexRange.vertexCount(), instanceCount);
+ *outMaxAttributeDataSize = std::max(*outMaxAttributeDataSize, typeSize);
+ }
+}
+
+gl::Error VertexArrayGL::streamAttributes(const gl::AttributesMask &activeAttributesMask,
+ GLsizei instanceCount,
+ const gl::IndexRange &indexRange) const
+{
+ // Sync the vertex attribute state and track what data needs to be streamed
+ size_t streamingDataSize = 0;
+ size_t maxAttributeDataSize = 0;
+
+ computeStreamingAttributeSizes(activeAttributesMask, instanceCount, indexRange,
+ &streamingDataSize, &maxAttributeDataSize);
+
+ if (streamingDataSize == 0)
+ {
+ return gl::Error(GL_NO_ERROR);
+ }
+
+ if (mStreamingArrayBuffer == 0)
+ {
+ mFunctions->genBuffers(1, &mStreamingArrayBuffer);
+ mStreamingArrayBufferSize = 0;
+ }
+
+ // If first is greater than zero, a slack space needs to be left at the beginning of the buffer so that
+ // the same 'first' argument can be passed into the draw call.
+ const size_t bufferEmptySpace = maxAttributeDataSize * indexRange.start;
+ const size_t requiredBufferSize = streamingDataSize + bufferEmptySpace;
+
+ mStateManager->bindBuffer(GL_ARRAY_BUFFER, mStreamingArrayBuffer);
+ if (requiredBufferSize > mStreamingArrayBufferSize)
+ {
+ mFunctions->bufferData(GL_ARRAY_BUFFER, requiredBufferSize, nullptr, GL_DYNAMIC_DRAW);
+ mStreamingArrayBufferSize = requiredBufferSize;
+ }
+
+ // Unmapping a buffer can return GL_FALSE to indicate that the system has corrupted the data
+ // somehow (such as by a screen change), retry writing the data a few times and return OUT_OF_MEMORY
+ // if that fails.
+ GLboolean unmapResult = GL_FALSE;
+ size_t unmapRetryAttempts = 5;
+ while (unmapResult != GL_TRUE && --unmapRetryAttempts > 0)
+ {
+ uint8_t *bufferPointer = MapBufferRangeWithFallback(mFunctions, GL_ARRAY_BUFFER, 0,
+ requiredBufferSize, GL_MAP_WRITE_BIT);
+ size_t curBufferOffset = bufferEmptySpace;
+
+ const auto &attribs = mData.getVertexAttributes();
+ for (auto idx : angle::IterateBitSet(mAttributesNeedStreaming & activeAttributesMask))
+ {
+ const auto &attrib = attribs[idx];
+ ASSERT(AttributeNeedsStreaming(attrib));
+
+ const size_t streamedVertexCount =
+ ComputeVertexAttributeElementCount(attrib, indexRange.vertexCount(), instanceCount);
+
+ const size_t sourceStride = ComputeVertexAttributeStride(attrib);
+ const size_t destStride = ComputeVertexAttributeTypeSize(attrib);
+
+ const uint8_t *inputPointer = reinterpret_cast<const uint8_t *>(attrib.pointer);
+
+ // Pack the data when copying it, user could have supplied a very large stride that
+ // would cause the buffer to be much larger than needed.
+ if (destStride == sourceStride)
+ {
+ // Can copy in one go, the data is packed
+ memcpy(bufferPointer + curBufferOffset,
+ inputPointer + (sourceStride * indexRange.start),
+ destStride * streamedVertexCount);
+ }
+ else
+ {
+ // Copy each vertex individually
+ for (size_t vertexIdx = 0; vertexIdx < streamedVertexCount; vertexIdx++)
+ {
+ uint8_t *out = bufferPointer + curBufferOffset + (destStride * vertexIdx);
+ const uint8_t *in =
+ inputPointer + sourceStride * (vertexIdx + indexRange.start);
+ memcpy(out, in, destStride);
+ }
+ }
+
+ // Compute where the 0-index vertex would be.
+ const size_t vertexStartOffset = curBufferOffset - (indexRange.start * destStride);
+
+ if (attrib.pureInteger)
+ {
+ ASSERT(!attrib.normalized);
+ mFunctions->vertexAttribIPointer(
+ static_cast<GLuint>(idx), attrib.size, attrib.type,
+ static_cast<GLsizei>(destStride),
+ reinterpret_cast<const GLvoid *>(vertexStartOffset));
+ }
+ else
+ {
+ mFunctions->vertexAttribPointer(
+ static_cast<GLuint>(idx), attrib.size, attrib.type, attrib.normalized,
+ static_cast<GLsizei>(destStride),
+ reinterpret_cast<const GLvoid *>(vertexStartOffset));
+ }
+
+ curBufferOffset += destStride * streamedVertexCount;
+
+ // Mark the applied attribute as dirty by setting an invalid size so that if it doesn't
+ // need to be streamed later, there is no chance that the caching will skip it.
+ mAppliedAttributes[idx].size = static_cast<GLuint>(-1);
+ }
+
+ unmapResult = mFunctions->unmapBuffer(GL_ARRAY_BUFFER);
+ }
+
+ if (unmapResult != GL_TRUE)
+ {
+ return Error(GL_OUT_OF_MEMORY, "Failed to unmap the client data streaming buffer.");
+ }
+
+ return Error(GL_NO_ERROR);
+}
+
+GLuint VertexArrayGL::getVertexArrayID() const
+{
+ return mVertexArrayID;
+}
+
+GLuint VertexArrayGL::getAppliedElementArrayBufferID() const
+{
+ if (mAppliedElementArrayBuffer.get() == nullptr)
+ {
+ return mStreamingElementArrayBuffer;
+ }
+
+ return GetImplAs<BufferGL>(mAppliedElementArrayBuffer.get())->getBufferID();
+}
+
+void VertexArrayGL::updateNeedsStreaming(size_t attribIndex)
+{
+ const VertexAttribute &attrib = mData.getVertexAttribute(attribIndex);
+ mAttributesNeedStreaming.set(attribIndex, AttributeNeedsStreaming(attrib));
+}
+
+void VertexArrayGL::updateAttribEnabled(size_t attribIndex)
+{
+ const VertexAttribute &attrib = mData.getVertexAttribute(attribIndex);
+ if (mAppliedAttributes[attribIndex].enabled == attrib.enabled)
+ {
+ return;
+ }
+
+ updateNeedsStreaming(attribIndex);
+
+ mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID());
+ if (attrib.enabled)
+ {
+ mFunctions->enableVertexAttribArray(static_cast<GLuint>(attribIndex));
+ }
+ else
+ {
+ mFunctions->disableVertexAttribArray(static_cast<GLuint>(attribIndex));
+ }
+ mAppliedAttributes[attribIndex].enabled = attrib.enabled;
+}
+
+void VertexArrayGL::updateAttribPointer(size_t attribIndex)
+{
+ const VertexAttribute &attrib = mData.getVertexAttribute(attribIndex);
+ if (mAppliedAttributes[attribIndex] == attrib)
+ {
+ return;
+ }
+
+ updateNeedsStreaming(attribIndex);
+
+ // If we need to stream, defer the attribPointer to the draw call.
+ if (mAttributesNeedStreaming[attribIndex])
+ {
+ return;
+ }
+
+ mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID());
+ const Buffer *arrayBuffer = attrib.buffer.get();
+ if (arrayBuffer != nullptr)
+ {
+ const BufferGL *arrayBufferGL = GetImplAs<BufferGL>(arrayBuffer);
+ mStateManager->bindBuffer(GL_ARRAY_BUFFER, arrayBufferGL->getBufferID());
+ }
+ else
+ {
+ mStateManager->bindBuffer(GL_ARRAY_BUFFER, 0);
+ }
+ mAppliedAttributes[attribIndex].buffer = attrib.buffer;
+
+ if (attrib.pureInteger)
+ {
+ mFunctions->vertexAttribIPointer(static_cast<GLuint>(attribIndex), attrib.size, attrib.type,
+ attrib.stride, attrib.pointer);
+ }
+ else
+ {
+ mFunctions->vertexAttribPointer(static_cast<GLuint>(attribIndex), attrib.size, attrib.type,
+ attrib.normalized, attrib.stride, attrib.pointer);
+ }
+ mAppliedAttributes[attribIndex].size = attrib.size;
+ mAppliedAttributes[attribIndex].type = attrib.type;
+ mAppliedAttributes[attribIndex].normalized = attrib.normalized;
+ mAppliedAttributes[attribIndex].pureInteger = attrib.pureInteger;
+ mAppliedAttributes[attribIndex].stride = attrib.stride;
+ mAppliedAttributes[attribIndex].pointer = attrib.pointer;
+}
+
+void VertexArrayGL::syncState(const VertexArray::DirtyBits &dirtyBits)
+{
+ for (unsigned long dirtyBit : angle::IterateBitSet(dirtyBits))
+ {
+ if (dirtyBit == VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER)
+ {
+ // TODO(jmadill): Element array buffer bindings
+ }
+ else if (dirtyBit >= VertexArray::DIRTY_BIT_ATTRIB_0_ENABLED &&
+ dirtyBit < VertexArray::DIRTY_BIT_ATTRIB_MAX_ENABLED)
+ {
+ size_t attribIndex =
+ static_cast<size_t>(dirtyBit) - VertexArray::DIRTY_BIT_ATTRIB_0_ENABLED;
+ updateAttribEnabled(attribIndex);
+ }
+ else if (dirtyBit >= VertexArray::DIRTY_BIT_ATTRIB_0_POINTER &&
+ dirtyBit < VertexArray::DIRTY_BIT_ATTRIB_MAX_POINTER)
+ {
+ size_t attribIndex =
+ static_cast<size_t>(dirtyBit) - VertexArray::DIRTY_BIT_ATTRIB_0_POINTER;
+ updateAttribPointer(attribIndex);
+ }
+ else if (dirtyBit >= VertexArray::DIRTY_BIT_ATTRIB_0_DIVISOR &&
+ dirtyBit < VertexArray::DIRTY_BIT_ATTRIB_MAX_DIVISOR)
+ {
+ size_t attribIndex =
+ static_cast<size_t>(dirtyBit) - VertexArray::DIRTY_BIT_ATTRIB_0_DIVISOR;
+ const VertexAttribute &attrib = mData.getVertexAttribute(attribIndex);
+
+ if (mAppliedAttributes[attribIndex].divisor != attrib.divisor)
+ {
+ mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID());
+ mFunctions->vertexAttribDivisor(static_cast<GLuint>(attribIndex), attrib.divisor);
+ mAppliedAttributes[attribIndex].divisor = attrib.divisor;
+ }
+ }
+ else
+ UNREACHABLE();
+ }
+}
+
+} // rx
diff --git a/gfx/angle/src/libANGLE/renderer/gl/VertexArrayGL.h b/gfx/angle/src/libANGLE/renderer/gl/VertexArrayGL.h
new file mode 100755
index 000000000..261b63d91
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/VertexArrayGL.h
@@ -0,0 +1,100 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// VertexArrayGL.h: Defines the class interface for VertexArrayGL.
+
+#ifndef LIBANGLE_RENDERER_GL_VERTEXARRAYGL_H_
+#define LIBANGLE_RENDERER_GL_VERTEXARRAYGL_H_
+
+#include "libANGLE/renderer/VertexArrayImpl.h"
+
+namespace rx
+{
+
+class FunctionsGL;
+class StateManagerGL;
+
+class VertexArrayGL : public VertexArrayImpl
+{
+ public:
+ VertexArrayGL(const gl::VertexArrayState &data,
+ const FunctionsGL *functions,
+ StateManagerGL *stateManager);
+ ~VertexArrayGL() override;
+
+ gl::Error syncDrawArraysState(const gl::AttributesMask &activeAttributesMask,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount) const;
+ gl::Error syncDrawElementsState(const gl::AttributesMask &activeAttributesMask,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ GLsizei instanceCount,
+ bool primitiveRestartEnabled,
+ const GLvoid **outIndices) const;
+
+ GLuint getVertexArrayID() const;
+ GLuint getAppliedElementArrayBufferID() const;
+
+ void syncState(const gl::VertexArray::DirtyBits &dirtyBits) override;
+
+ private:
+ gl::Error syncDrawState(const gl::AttributesMask &activeAttributesMask,
+ GLint first,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ GLsizei instanceCount,
+ bool primitiveRestartEnabled,
+ const GLvoid **outIndices) const;
+
+ // Apply index data, only sets outIndexRange if attributesNeedStreaming is true
+ gl::Error syncIndexData(GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ bool primitiveRestartEnabled,
+ bool attributesNeedStreaming,
+ gl::IndexRange *outIndexRange,
+ const GLvoid **outIndices) const;
+
+ // Returns the amount of space needed to stream all attributes that need streaming
+ // and the data size of the largest attribute
+ void computeStreamingAttributeSizes(const gl::AttributesMask &activeAttributesMask,
+ GLsizei instanceCount,
+ const gl::IndexRange &indexRange,
+ size_t *outStreamingDataSize,
+ size_t *outMaxAttributeDataSize) const;
+
+ // Stream attributes that have client data
+ gl::Error streamAttributes(const gl::AttributesMask &activeAttributesMask,
+ GLsizei instanceCount,
+ const gl::IndexRange &indexRange) const;
+
+ void updateNeedsStreaming(size_t attribIndex);
+ void updateAttribEnabled(size_t attribIndex);
+ void updateAttribPointer(size_t attribIndex);
+
+ const FunctionsGL *mFunctions;
+ StateManagerGL *mStateManager;
+
+ GLuint mVertexArrayID;
+
+ mutable BindingPointer<gl::Buffer> mAppliedElementArrayBuffer;
+ mutable std::vector<gl::VertexAttribute> mAppliedAttributes;
+
+ mutable size_t mStreamingElementArrayBufferSize;
+ mutable GLuint mStreamingElementArrayBuffer;
+
+ mutable size_t mStreamingArrayBufferSize;
+ mutable GLuint mStreamingArrayBuffer;
+
+ gl::AttributesMask mAttributesNeedStreaming;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_VERTEXARRAYGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/WorkaroundsGL.h b/gfx/angle/src/libANGLE/renderer/gl/WorkaroundsGL.h
new file mode 100755
index 000000000..105f94089
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/WorkaroundsGL.h
@@ -0,0 +1,126 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// WorkaroundsGL.h: Workarounds for GL driver bugs and other issues.
+
+#ifndef LIBANGLE_RENDERER_GL_WORKAROUNDSGL_H_
+#define LIBANGLE_RENDERER_GL_WORKAROUNDSGL_H_
+
+namespace rx
+{
+
+struct WorkaroundsGL
+{
+ WorkaroundsGL()
+ : avoid1BitAlphaTextureFormats(false),
+ rgba4IsNotSupportedForColorRendering(false),
+ doesSRGBClearsOnLinearFramebufferAttachments(false),
+ doWhileGLSLCausesGPUHang(false),
+ finishDoesNotCauseQueriesToBeAvailable(false),
+ alwaysCallUseProgramAfterLink(false),
+ unpackOverlappingRowsSeparatelyUnpackBuffer(false),
+ emulateAbsIntFunction(false),
+ addAndTrueToLoopCondition(false),
+ emulateIsnanFloat(false),
+ useUnusedBlocksWithStandardOrSharedLayout(false),
+ dontRemoveInvariantForFragmentInput(false),
+ removeInvariantAndCentroidForESSL3(false)
+ {
+ }
+
+ // When writing a float to a normalized integer framebuffer, desktop OpenGL is allowed to write
+ // one of the two closest normalized integer representations (although round to nearest is
+ // preferred) (see section 2.3.5.2 of the GL 4.5 core specification). OpenGL ES requires that
+ // round-to-nearest is used (see "Conversion from Floating-Point to Framebuffer Fixed-Point" in
+ // section 2.1.2 of the OpenGL ES 2.0.25 spec). This issue only shows up on Intel and AMD
+ // drivers on framebuffer formats that have 1-bit alpha, work around this by using higher
+ // precision formats instead.
+ bool avoid1BitAlphaTextureFormats;
+
+ // On some older Intel drivers, GL_RGBA4 is not color renderable, glCheckFramebufferStatus
+ // returns GL_FRAMEBUFFER_UNSUPPORTED. Work around this by using a known color-renderable
+ // format.
+ bool rgba4IsNotSupportedForColorRendering;
+
+ // When clearing a framebuffer on Intel or AMD drivers, when GL_FRAMEBUFFER_SRGB is enabled, the
+ // driver clears to the linearized clear color despite the framebuffer not supporting SRGB
+ // blending. It only seems to do this when the framebuffer has only linear attachments, mixed
+ // attachments appear to get the correct clear color.
+ bool doesSRGBClearsOnLinearFramebufferAttachments;
+
+ // On Mac some GLSL constructs involving do-while loops cause GPU hangs, such as the following:
+ // int i = 1;
+ // do {
+ // i --;
+ // continue;
+ // } while (i > 0)
+ // Work around this by rewriting the do-while to use another GLSL construct (block + while)
+ bool doWhileGLSLCausesGPUHang;
+
+ // Calling glFinish doesn't cause all queries to report that the result is available on some
+ // (NVIDIA) drivers. It was found that enabling GL_DEBUG_OUTPUT_SYNCHRONOUS before the finish
+ // causes it to fully finish.
+ bool finishDoesNotCauseQueriesToBeAvailable;
+
+ // Always call useProgram after a successful link to avoid a driver bug.
+ // This workaround is meant to reproduce the use_current_program_after_successful_link
+ // workaround in Chromium (http://crbug.com/110263). It has been shown that this workaround is
+ // not necessary for MacOSX 10.9 and higher (http://crrev.com/39eb535b).
+ bool alwaysCallUseProgramAfterLink;
+
+ // In the case of unpacking from a pixel unpack buffer, unpack overlapping rows row by row.
+ bool unpackOverlappingRowsSeparatelyUnpackBuffer;
+ // In the case of packing to a pixel pack buffer, pack overlapping rows row by row.
+ bool packOverlappingRowsSeparatelyPackBuffer;
+
+ // During initialization, assign the current vertex attributes to the spec-mandated defaults.
+ bool initializeCurrentVertexAttributes;
+
+ // abs(i) where i is an integer returns unexpected result on Intel Mac.
+ // Emulate abs(i) with i * sign(i).
+ bool emulateAbsIntFunction;
+
+ // On Intel Mac, calculation of loop conditions in for and while loop has bug.
+ // Add "&& true" to the end of the condition expression to work around the bug.
+ bool addAndTrueToLoopCondition;
+
+ // When uploading textures from an unpack buffer, some drivers count an extra row padding when
+ // checking if the pixel unpack buffer is big enough. Tracking bug: http://anglebug.com/1512
+ // For example considering the pixel buffer below where in memory, each row data (D) of the
+ // texture is followed by some unused data (the dots):
+ // +-------+--+
+ // |DDDDDDD|..|
+ // |DDDDDDD|..|
+ // |DDDDDDD|..|
+ // |DDDDDDD|..|
+ // +-------A--B
+ // The last pixel read will be A, but the driver will think it is B, causing it to generate an
+ // error when the pixel buffer is just big enough.
+ bool unpackLastRowSeparatelyForPaddingInclusion;
+
+ // Equivalent workaround when uploading data from a pixel pack buffer.
+ bool packLastRowSeparatelyForPaddingInclusion;
+
+ // On some Intel drivers, using isnan() on highp float will get wrong answer. To work around
+ // this bug, we use an expression to emulate function isnan().
+ // Tracking bug: http://crbug.com/650547
+ bool emulateIsnanFloat;
+
+ // On Mac with OpenGL version 4.1, unused std140 or shared uniform blocks will be
+ // treated as inactive which is not consistent with WebGL2.0 spec. Reference all members in a
+ // unused std140 or shared uniform block at the beginning of main to work around it.
+ bool useUnusedBlocksWithStandardOrSharedLayout;
+
+ // This flag will keep invariant declaration for input in fragment shader for GLSL >=4.20
+ // on AMD.
+ bool dontRemoveInvariantForFragmentInput;
+
+ // This flag is used to fix spec difference between GLSL 4.1 or lower and ESSL3.
+ bool removeInvariantAndCentroidForESSL3;
+};
+}
+
+#endif // LIBANGLE_RENDERER_GL_WORKAROUNDSGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.h b/gfx/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.h
new file mode 100755
index 000000000..cc1b17bb7
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.h
@@ -0,0 +1,77 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// DisplayCGL.h: CGL implementation of egl::Display
+
+#ifndef LIBANGLE_RENDERER_GL_CGL_DISPLAYCGL_H_
+#define LIBANGLE_RENDERER_GL_CGL_DISPLAYCGL_H_
+
+#include "libANGLE/renderer/gl/DisplayGL.h"
+
+struct _CGLContextObject;
+typedef _CGLContextObject *CGLContextObj;
+
+namespace rx
+{
+
+class DisplayCGL : public DisplayGL
+{
+ public:
+ DisplayCGL();
+ ~DisplayCGL() override;
+
+ egl::Error initialize(egl::Display *display) override;
+ void terminate() override;
+
+ SurfaceImpl *createWindowSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLNativeWindowType window,
+ const egl::AttributeMap &attribs) override;
+ SurfaceImpl *createPbufferSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ const egl::AttributeMap &attribs) override;
+ SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs) override;
+ SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ NativePixmapType nativePixmap,
+ const egl::AttributeMap &attribs) override;
+
+ egl::ConfigSet generateConfigs() override;
+
+ bool testDeviceLost() override;
+ egl::Error restoreLostDevice() override;
+
+ bool isValidNativeWindow(EGLNativeWindowType window) const override;
+
+ egl::Error getDevice(DeviceImpl **device) override;
+
+ std::string getVendorString() const override;
+
+ egl::Error waitClient() const override;
+ egl::Error waitNative(EGLint engine,
+ egl::Surface *drawSurface,
+ egl::Surface *readSurface) const override;
+
+ egl::Error getDriverVersion(std::string *version) const override;
+
+ private:
+ const FunctionsGL *getFunctionsGL() const override;
+
+ void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
+ void generateCaps(egl::Caps *outCaps) const override;
+
+ egl::Display *mEGLDisplay;
+ FunctionsGL *mFunctions;
+ CGLContextObj mContext;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_CGL_DISPLAYCGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.mm b/gfx/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.mm
new file mode 100755
index 000000000..f87134c82
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.mm
@@ -0,0 +1,275 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// DisplayCGL.mm: CGL implementation of egl::Display
+
+#include "libANGLE/renderer/gl/cgl/DisplayCGL.h"
+
+#import <Cocoa/Cocoa.h>
+#include <dlfcn.h>
+#include <EGL/eglext.h>
+
+#include "common/debug.h"
+#include "libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.h"
+#include "libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h"
+
+namespace
+{
+
+const char *kDefaultOpenGLDylibName =
+ "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib";
+const char *kFallbackOpenGLDylibName = "GL";
+
+}
+
+namespace rx
+{
+
+class FunctionsGLCGL : public FunctionsGL
+{
+ public:
+ FunctionsGLCGL(void *dylibHandle) : mDylibHandle(dylibHandle) {}
+
+ ~FunctionsGLCGL() override { dlclose(mDylibHandle); }
+
+ private:
+ void *loadProcAddress(const std::string &function) override
+ {
+ return dlsym(mDylibHandle, function.c_str());
+ }
+
+ void *mDylibHandle;
+};
+
+DisplayCGL::DisplayCGL() : DisplayGL(), mEGLDisplay(nullptr), mFunctions(nullptr), mContext(nullptr)
+{
+}
+
+DisplayCGL::~DisplayCGL()
+{
+}
+
+egl::Error DisplayCGL::initialize(egl::Display *display)
+{
+ mEGLDisplay = display;
+
+ CGLPixelFormatObj pixelFormat;
+ {
+ // TODO(cwallez) investigate which pixel format we want
+ CGLPixelFormatAttribute attribs[] = {
+ kCGLPFAOpenGLProfile, static_cast<CGLPixelFormatAttribute>(kCGLOGLPVersion_3_2_Core),
+ static_cast<CGLPixelFormatAttribute>(0)};
+ GLint nVirtualScreens = 0;
+ CGLChoosePixelFormat(attribs, &pixelFormat, &nVirtualScreens);
+
+ if (pixelFormat == nullptr)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Could not create the context's pixel format.");
+ }
+ }
+
+ CGLCreateContext(pixelFormat, nullptr, &mContext);
+ if (mContext == nullptr)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Could not create the CGL context.");
+ }
+ CGLSetCurrentContext(mContext);
+
+ // There is no equivalent getProcAddress in CGL so we open the dylib directly
+ void *handle = dlopen(kDefaultOpenGLDylibName, RTLD_NOW);
+ if (!handle)
+ {
+ handle = dlopen(kFallbackOpenGLDylibName, RTLD_NOW);
+ }
+ if (!handle)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Could not open the OpenGL Framework.");
+ }
+
+ mFunctions = new FunctionsGLCGL(handle);
+ mFunctions->initialize();
+
+ return DisplayGL::initialize(display);
+}
+
+void DisplayCGL::terminate()
+{
+ DisplayGL::terminate();
+
+ if (mContext != nullptr)
+ {
+ CGLSetCurrentContext(nullptr);
+ CGLReleaseContext(mContext);
+ mContext = nullptr;
+ }
+
+ SafeDelete(mFunctions);
+}
+
+SurfaceImpl *DisplayCGL::createWindowSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLNativeWindowType window,
+ const egl::AttributeMap &attribs)
+{
+ return new WindowSurfaceCGL(state, this->getRenderer(), window, mFunctions, mContext);
+}
+
+SurfaceImpl *DisplayCGL::createPbufferSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ const egl::AttributeMap &attribs)
+{
+ EGLint width = static_cast<EGLint>(attribs.get(EGL_WIDTH, 0));
+ EGLint height = static_cast<EGLint>(attribs.get(EGL_HEIGHT, 0));
+ return new PbufferSurfaceCGL(state, this->getRenderer(), width, height, mFunctions);
+}
+
+SurfaceImpl *DisplayCGL::createPbufferFromClientBuffer(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs)
+{
+ UNIMPLEMENTED();
+ return nullptr;
+}
+
+SurfaceImpl *DisplayCGL::createPixmapSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ NativePixmapType nativePixmap,
+ const egl::AttributeMap &attribs)
+{
+ UNIMPLEMENTED();
+ return nullptr;
+}
+
+egl::Error DisplayCGL::getDevice(DeviceImpl **device)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_BAD_DISPLAY);
+}
+
+egl::ConfigSet DisplayCGL::generateConfigs()
+{
+ // TODO(cwallez): generate more config permutations
+ egl::ConfigSet configs;
+
+ const gl::Version &maxVersion = getMaxSupportedESVersion();
+ ASSERT(maxVersion >= gl::Version(2, 0));
+ bool supportsES3 = maxVersion >= gl::Version(3, 0);
+
+ egl::Config config;
+
+ // Native stuff
+ config.nativeVisualID = 0;
+ config.nativeVisualType = 0;
+ config.nativeRenderable = EGL_TRUE;
+
+ // Buffer sizes
+ config.redSize = 8;
+ config.greenSize = 8;
+ config.blueSize = 8;
+ config.alphaSize = 8;
+ config.depthSize = 24;
+ config.stencilSize = 8;
+
+ config.colorBufferType = EGL_RGB_BUFFER;
+ config.luminanceSize = 0;
+ config.alphaMaskSize = 0;
+
+ config.bufferSize = config.redSize + config.greenSize + config.blueSize + config.alphaSize;
+
+ config.transparentType = EGL_NONE;
+
+ // Pbuffer
+ config.maxPBufferWidth = 4096;
+ config.maxPBufferHeight = 4096;
+ config.maxPBufferPixels = 4096 * 4096;
+
+ // Caveat
+ config.configCaveat = EGL_NONE;
+
+ // Misc
+ config.sampleBuffers = 0;
+ config.samples = 0;
+ config.level = 0;
+ config.bindToTextureRGB = EGL_FALSE;
+ config.bindToTextureRGBA = EGL_FALSE;
+
+ config.surfaceType = EGL_WINDOW_BIT | EGL_PBUFFER_BIT;
+
+ config.minSwapInterval = 1;
+ config.maxSwapInterval = 1;
+
+ config.renderTargetFormat = GL_RGBA8;
+ config.depthStencilFormat = GL_DEPTH24_STENCIL8;
+
+ config.conformant = EGL_OPENGL_ES2_BIT | (supportsES3 ? EGL_OPENGL_ES3_BIT_KHR : 0);
+ config.renderableType = config.conformant;
+
+ config.matchNativePixmap = EGL_NONE;
+
+ configs.add(config);
+ return configs;
+}
+
+bool DisplayCGL::testDeviceLost()
+{
+ // TODO(cwallez) investigate implementing this
+ return false;
+}
+
+egl::Error DisplayCGL::restoreLostDevice()
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_BAD_DISPLAY);
+}
+
+bool DisplayCGL::isValidNativeWindow(EGLNativeWindowType window) const
+{
+ // TODO(cwallez) investigate implementing this
+ return true;
+}
+
+std::string DisplayCGL::getVendorString() const
+{
+ // TODO(cwallez) find a useful vendor string
+ return "";
+}
+
+const FunctionsGL *DisplayCGL::getFunctionsGL() const
+{
+ return mFunctions;
+}
+
+void DisplayCGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
+{
+}
+
+void DisplayCGL::generateCaps(egl::Caps *outCaps) const
+{
+ outCaps->textureNPOT = true;
+}
+
+egl::Error DisplayCGL::waitClient() const
+{
+ // TODO(cwallez) UNIMPLEMENTED()
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DisplayCGL::waitNative(EGLint engine,
+ egl::Surface *drawSurface,
+ egl::Surface *readSurface) const
+{
+ // TODO(cwallez) UNIMPLEMENTED()
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DisplayCGL::getDriverVersion(std::string *version) const
+{
+ *version = "";
+ return egl::Error(EGL_SUCCESS);
+}
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.h b/gfx/angle/src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.h
new file mode 100755
index 000000000..7cbb74da4
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.h
@@ -0,0 +1,65 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// PBufferSurfaceCGL.h: an implementation of egl::Surface for PBuffers for the CLG backend,
+// currently implemented using renderbuffers
+
+#ifndef LIBANGLE_RENDERER_GL_CGL_PBUFFERSURFACECGL_H_
+#define LIBANGLE_RENDERER_GL_CGL_PBUFFERSURFACECGL_H_
+
+#include "libANGLE/renderer/gl/SurfaceGL.h"
+
+namespace rx
+{
+
+class FunctionsGL;
+class StateManagerGL;
+struct WorkaroundsGL;
+
+class PbufferSurfaceCGL : public SurfaceGL
+{
+ public:
+ PbufferSurfaceCGL(const egl::SurfaceState &state,
+ RendererGL *renderer,
+ EGLint width,
+ EGLint height,
+ const FunctionsGL *functions);
+ ~PbufferSurfaceCGL() override;
+
+ egl::Error initialize() override;
+ egl::Error makeCurrent() override;
+
+ egl::Error swap() override;
+ egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override;
+ egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override;
+ egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) override;
+ egl::Error releaseTexImage(EGLint buffer) override;
+ void setSwapInterval(EGLint interval) override;
+
+ EGLint getWidth() const override;
+ EGLint getHeight() const override;
+
+ EGLint isPostSubBufferSupported() const override;
+ EGLint getSwapBehavior() const override;
+
+ FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override;
+
+ private:
+ unsigned mWidth;
+ unsigned mHeight;
+
+ const FunctionsGL *mFunctions;
+ StateManagerGL *mStateManager;
+ RendererGL *mRenderer;
+
+ GLuint mFramebuffer;
+ GLuint mColorRenderbuffer;
+ GLuint mDSRenderbuffer;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_CGL_PBUFFERSURFACECGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.mm b/gfx/angle/src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.mm
new file mode 100755
index 000000000..c03d3836f
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.mm
@@ -0,0 +1,143 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// PBufferSurfaceCGL.cpp: an implementation of egl::Surface for PBuffers for the CLG backend,
+// currently implemented using renderbuffers
+
+#include "libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.h"
+
+#include "common/debug.h"
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+#include "libANGLE/renderer/gl/FramebufferGL.h"
+#include "libANGLE/renderer/gl/RendererGL.h"
+#include "libANGLE/renderer/gl/StateManagerGL.h"
+
+namespace rx
+{
+
+PbufferSurfaceCGL::PbufferSurfaceCGL(const egl::SurfaceState &state,
+ RendererGL *renderer,
+ EGLint width,
+ EGLint height,
+ const FunctionsGL *functions)
+ : SurfaceGL(state, renderer),
+ mWidth(width),
+ mHeight(height),
+ mFunctions(functions),
+ mStateManager(renderer->getStateManager()),
+ mRenderer(renderer),
+ mFramebuffer(0),
+ mColorRenderbuffer(0),
+ mDSRenderbuffer(0)
+{
+}
+
+PbufferSurfaceCGL::~PbufferSurfaceCGL()
+{
+ if (mFramebuffer != 0)
+ {
+ mFunctions->deleteFramebuffers(1, &mFramebuffer);
+ mFramebuffer = 0;
+ }
+
+ if (mColorRenderbuffer != 0)
+ {
+ mFunctions->deleteRenderbuffers(1, &mColorRenderbuffer);
+ mColorRenderbuffer = 0;
+ }
+ if (mDSRenderbuffer != 0)
+ {
+ mFunctions->deleteRenderbuffers(1, &mDSRenderbuffer);
+ mDSRenderbuffer = 0;
+ }
+}
+
+egl::Error PbufferSurfaceCGL::initialize()
+{
+ mFunctions->genRenderbuffers(1, &mColorRenderbuffer);
+ mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer);
+ mFunctions->renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, mWidth, mHeight);
+
+ mFunctions->genRenderbuffers(1, &mDSRenderbuffer);
+ mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mDSRenderbuffer);
+ mFunctions->renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, mWidth, mHeight);
+
+ mFunctions->genFramebuffers(1, &mFramebuffer);
+ mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
+ mFunctions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
+ mColorRenderbuffer);
+ mFunctions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, mDSRenderbuffer);
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error PbufferSurfaceCGL::makeCurrent()
+{
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error PbufferSurfaceCGL::swap()
+{
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error PbufferSurfaceCGL::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
+{
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error PbufferSurfaceCGL::querySurfacePointerANGLE(EGLint attribute, void **value)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error PbufferSurfaceCGL::bindTexImage(gl::Texture *texture, EGLint buffer)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error PbufferSurfaceCGL::releaseTexImage(EGLint buffer)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+void PbufferSurfaceCGL::setSwapInterval(EGLint interval)
+{
+}
+
+EGLint PbufferSurfaceCGL::getWidth() const
+{
+ return mWidth;
+}
+
+EGLint PbufferSurfaceCGL::getHeight() const
+{
+ return mHeight;
+}
+
+EGLint PbufferSurfaceCGL::isPostSubBufferSupported() const
+{
+ UNIMPLEMENTED();
+ return EGL_FALSE;
+}
+
+EGLint PbufferSurfaceCGL::getSwapBehavior() const
+{
+ return EGL_BUFFER_PRESERVED;
+}
+
+FramebufferImpl *PbufferSurfaceCGL::createDefaultFramebuffer(const gl::FramebufferState &state)
+{
+ // TODO(cwallez) assert it happens only once?
+ return new FramebufferGL(mFramebuffer, state, mFunctions, mRenderer->getWorkarounds(),
+ mRenderer->getBlitter(), mStateManager);
+}
+
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h b/gfx/angle/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h
new file mode 100755
index 000000000..165ab0486
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h
@@ -0,0 +1,100 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// WindowSurfaceCGL.h: CGL implementation of egl::Surface for windows
+
+#ifndef LIBANGLE_RENDERER_GL_CGL_WINDOWSURFACECGL_H_
+#define LIBANGLE_RENDERER_GL_CGL_WINDOWSURFACECGL_H_
+
+#include "libANGLE/renderer/gl/SurfaceGL.h"
+
+struct _CGLContextObject;
+typedef _CGLContextObject *CGLContextObj;
+@class CALayer;
+struct __IOSurface;
+typedef __IOSurface *IOSurfaceRef;
+
+@class SwapLayer;
+
+namespace rx
+{
+
+class DisplayCGL;
+class FramebufferGL;
+class FunctionsGL;
+class StateManagerGL;
+struct WorkaroundsGL;
+
+struct SharedSwapState
+{
+ struct SwapTexture
+ {
+ GLuint texture;
+ unsigned int width;
+ unsigned int height;
+ uint64_t swapId;
+ };
+
+ SwapTexture textures[3];
+
+ // This code path is not going to be used by Chrome so we take the liberty
+ // to use pthreads directly instead of using mutexes and condition variables
+ // via the Platform API.
+ pthread_mutex_t mutex;
+ // The following members should be accessed only when holding the mutex
+ // (or doing construction / destruction)
+ SwapTexture *beingRendered;
+ SwapTexture *lastRendered;
+ SwapTexture *beingPresented;
+};
+
+class WindowSurfaceCGL : public SurfaceGL
+{
+ public:
+ WindowSurfaceCGL(const egl::SurfaceState &state,
+ RendererGL *renderer,
+ CALayer *layer,
+ const FunctionsGL *functions,
+ CGLContextObj context);
+ ~WindowSurfaceCGL() override;
+
+ egl::Error initialize() override;
+ egl::Error makeCurrent() override;
+
+ egl::Error swap() override;
+ egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override;
+ egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override;
+ egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) override;
+ egl::Error releaseTexImage(EGLint buffer) override;
+ void setSwapInterval(EGLint interval) override;
+
+ EGLint getWidth() const override;
+ EGLint getHeight() const override;
+
+ EGLint isPostSubBufferSupported() const override;
+ EGLint getSwapBehavior() const override;
+
+ FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override;
+
+ private:
+ SwapLayer *mSwapLayer;
+ SharedSwapState mSwapState;
+ uint64_t mCurrentSwapId;
+
+ CALayer *mLayer;
+ CGLContextObj mContext;
+ const FunctionsGL *mFunctions;
+ StateManagerGL *mStateManager;
+ RendererGL *mRenderer;
+ const WorkaroundsGL &mWorkarounds;
+
+ GLuint mFramebuffer;
+ GLuint mDSRenderbuffer;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_CGL_WINDOWSURFACECGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm b/gfx/angle/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm
new file mode 100755
index 000000000..c2ac4dca4
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm
@@ -0,0 +1,332 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// WindowSurfaceCGL.cpp: CGL implementation of egl::Surface for windows
+
+#include "libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h"
+
+#import <Cocoa/Cocoa.h>
+#include <OpenGL/OpenGL.h>
+#import <QuartzCore/QuartzCore.h>
+
+#include "common/debug.h"
+#include "libANGLE/renderer/gl/cgl/DisplayCGL.h"
+#include "libANGLE/renderer/gl/FramebufferGL.h"
+#include "libANGLE/renderer/gl/RendererGL.h"
+#include "libANGLE/renderer/gl/StateManagerGL.h"
+
+@interface SwapLayer : CAOpenGLLayer
+{
+ CGLContextObj mDisplayContext;
+
+ bool initialized;
+ rx::SharedSwapState *mSwapState;
+ const rx::FunctionsGL *mFunctions;
+
+ GLuint mReadFramebuffer;
+}
+- (id)initWithSharedState:(rx::SharedSwapState *)swapState
+ withContext:(CGLContextObj)displayContext
+ withFunctions:(const rx::FunctionsGL *)functions;
+@end
+
+@implementation SwapLayer
+- (id)initWithSharedState:(rx::SharedSwapState *)swapState
+ withContext:(CGLContextObj)displayContext
+ withFunctions:(const rx::FunctionsGL *)functions
+ {
+ self = [super init];
+ if (self != nil)
+ {
+ self.asynchronous = YES;
+ mDisplayContext = displayContext;
+
+ initialized = false;
+ mSwapState = swapState;
+ mFunctions = functions;
+
+ [self setFrame:CGRectMake(0, 0, mSwapState->textures[0].width,
+ mSwapState->textures[0].height)];
+ }
+ return self;
+ }
+
+ - (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask
+ {
+ CGLPixelFormatAttribute attribs[] = {
+ kCGLPFADisplayMask, static_cast<CGLPixelFormatAttribute>(mask), kCGLPFAOpenGLProfile,
+ static_cast<CGLPixelFormatAttribute>(kCGLOGLPVersion_3_2_Core),
+ static_cast<CGLPixelFormatAttribute>(0)};
+
+ CGLPixelFormatObj pixelFormat = nullptr;
+ GLint numFormats = 0;
+ CGLChoosePixelFormat(attribs, &pixelFormat, &numFormats);
+
+ return pixelFormat;
+ }
+
+ - (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat
+ {
+ CGLContextObj context = nullptr;
+ CGLCreateContext(pixelFormat, mDisplayContext, &context);
+ return context;
+ }
+
+ - (BOOL)canDrawInCGLContext:(CGLContextObj)glContext
+ pixelFormat:(CGLPixelFormatObj)pixelFormat
+ forLayerTime:(CFTimeInterval)timeInterval
+ displayTime:(const CVTimeStamp *)timeStamp
+ {
+ BOOL result = NO;
+
+ pthread_mutex_lock(&mSwapState->mutex);
+ {
+ if (mSwapState->lastRendered->swapId > mSwapState->beingPresented->swapId)
+ {
+ std::swap(mSwapState->lastRendered, mSwapState->beingPresented);
+ result = YES;
+ }
+ }
+ pthread_mutex_unlock(&mSwapState->mutex);
+
+ return result;
+ }
+
+ - (void)drawInCGLContext:(CGLContextObj)glContext
+ pixelFormat:(CGLPixelFormatObj)pixelFormat
+ forLayerTime:(CFTimeInterval)timeInterval
+ displayTime:(const CVTimeStamp *)timeStamp
+ {
+ CGLSetCurrentContext(glContext);
+ if (!initialized)
+ {
+ initialized = true;
+
+ mFunctions->genFramebuffers(1, &mReadFramebuffer);
+ }
+
+ const auto &texture = *mSwapState->beingPresented;
+ if ([self frame].size.width != texture.width || [self frame].size.height != texture.height)
+ {
+ [self setFrame:CGRectMake(0, 0, texture.width, texture.height)];
+
+ // Without this, the OSX compositor / window system doesn't see the resize.
+ [self setNeedsDisplay];
+ }
+
+ // TODO(cwallez) support 2.1 contexts too that don't have blitFramebuffer nor the
+ // GL_DRAW_FRAMEBUFFER_BINDING query
+ GLint drawFBO;
+ mFunctions->getIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &drawFBO);
+
+ mFunctions->bindFramebuffer(GL_FRAMEBUFFER, mReadFramebuffer);
+ mFunctions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+ texture.texture, 0);
+
+ mFunctions->bindFramebuffer(GL_READ_FRAMEBUFFER, mReadFramebuffer);
+ mFunctions->bindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO);
+ mFunctions->blitFramebuffer(0, 0, texture.width, texture.height, 0, 0, texture.width,
+ texture.height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+
+ // Call the super method to flush the context
+ [super drawInCGLContext:glContext
+ pixelFormat:pixelFormat
+ forLayerTime:timeInterval
+ displayTime:timeStamp];
+ }
+ @end
+
+ namespace rx
+ {
+
+ WindowSurfaceCGL::WindowSurfaceCGL(const egl::SurfaceState &state,
+ RendererGL *renderer,
+ CALayer *layer,
+ const FunctionsGL *functions,
+ CGLContextObj context)
+ : SurfaceGL(state, renderer),
+ mSwapLayer(nil),
+ mCurrentSwapId(0),
+ mLayer(layer),
+ mContext(context),
+ mFunctions(functions),
+ mStateManager(renderer->getStateManager()),
+ mRenderer(renderer),
+ mWorkarounds(renderer->getWorkarounds()),
+ mFramebuffer(0),
+ mDSRenderbuffer(0)
+ {
+ pthread_mutex_init(&mSwapState.mutex, nullptr);
+}
+
+WindowSurfaceCGL::~WindowSurfaceCGL()
+{
+ pthread_mutex_destroy(&mSwapState.mutex);
+ if (mFramebuffer != 0)
+ {
+ mFunctions->deleteFramebuffers(1, &mFramebuffer);
+ mFramebuffer = 0;
+ }
+
+ if (mDSRenderbuffer != 0)
+ {
+ mFunctions->deleteRenderbuffers(1, &mDSRenderbuffer);
+ mDSRenderbuffer = 0;
+ }
+
+ if (mSwapLayer != nil)
+ {
+ [mSwapLayer removeFromSuperlayer];
+ [mSwapLayer release];
+ mSwapLayer = nil;
+ }
+
+ for (size_t i = 0; i < ArraySize(mSwapState.textures); ++i)
+ {
+ if (mSwapState.textures[i].texture != 0)
+ {
+ mFunctions->deleteTextures(1, &mSwapState.textures[i].texture);
+ mSwapState.textures[i].texture = 0;
+ }
+ }
+}
+
+egl::Error WindowSurfaceCGL::initialize()
+{
+ unsigned width = getWidth();
+ unsigned height = getHeight();
+
+ for (size_t i = 0; i < ArraySize(mSwapState.textures); ++i)
+ {
+ mFunctions->genTextures(1, &mSwapState.textures[i].texture);
+ mStateManager->bindTexture(GL_TEXTURE_2D, mSwapState.textures[i].texture);
+ mFunctions->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, nullptr);
+ mSwapState.textures[i].width = width;
+ mSwapState.textures[i].height = height;
+ mSwapState.textures[i].swapId = 0;
+ }
+ mSwapState.beingRendered = &mSwapState.textures[0];
+ mSwapState.lastRendered = &mSwapState.textures[1];
+ mSwapState.beingPresented = &mSwapState.textures[2];
+
+ mSwapLayer = [[SwapLayer alloc] initWithSharedState:&mSwapState
+ withContext:mContext
+ withFunctions:mFunctions];
+ [mLayer addSublayer:mSwapLayer];
+
+ mFunctions->genRenderbuffers(1, &mDSRenderbuffer);
+ mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mDSRenderbuffer);
+ mFunctions->renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
+
+ mFunctions->genFramebuffers(1, &mFramebuffer);
+ mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
+ mFunctions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+ mSwapState.beingRendered->texture, 0);
+ mFunctions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
+ mDSRenderbuffer);
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error WindowSurfaceCGL::makeCurrent()
+{
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error WindowSurfaceCGL::swap()
+{
+ mFunctions->flush();
+ mSwapState.beingRendered->swapId = ++mCurrentSwapId;
+
+ pthread_mutex_lock(&mSwapState.mutex);
+ {
+ std::swap(mSwapState.beingRendered, mSwapState.lastRendered);
+ }
+ pthread_mutex_unlock(&mSwapState.mutex);
+
+ unsigned width = getWidth();
+ unsigned height = getHeight();
+ auto &texture = *mSwapState.beingRendered;
+
+ if (texture.width != width || texture.height != height)
+ {
+ mStateManager->bindTexture(GL_TEXTURE_2D, texture.texture);
+ mFunctions->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, nullptr);
+
+ mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mDSRenderbuffer);
+ mFunctions->renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
+
+ texture.width = width;
+ texture.height = height;
+ }
+
+ mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
+ mFunctions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+ mSwapState.beingRendered->texture, 0);
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error WindowSurfaceCGL::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error WindowSurfaceCGL::querySurfacePointerANGLE(EGLint attribute, void **value)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error WindowSurfaceCGL::bindTexImage(gl::Texture *texture, EGLint buffer)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error WindowSurfaceCGL::releaseTexImage(EGLint buffer)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+void WindowSurfaceCGL::setSwapInterval(EGLint interval)
+{
+ // TODO(cwallez) investigate implementing swap intervals other than 0
+}
+
+EGLint WindowSurfaceCGL::getWidth() const
+{
+ return CGRectGetWidth([mLayer frame]);
+}
+
+EGLint WindowSurfaceCGL::getHeight() const
+{
+ return CGRectGetHeight([mLayer frame]);
+}
+
+EGLint WindowSurfaceCGL::isPostSubBufferSupported() const
+{
+ UNIMPLEMENTED();
+ return EGL_FALSE;
+}
+
+EGLint WindowSurfaceCGL::getSwapBehavior() const
+{
+ return EGL_BUFFER_DESTROYED;
+}
+
+FramebufferImpl *WindowSurfaceCGL::createDefaultFramebuffer(const gl::FramebufferState &state)
+{
+ // TODO(cwallez) assert it happens only once?
+ return new FramebufferGL(mFramebuffer, state, mFunctions, mWorkarounds, mRenderer->getBlitter(),
+ mStateManager);
+}
+
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/egl/DisplayEGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/egl/DisplayEGL.cpp
new file mode 100755
index 000000000..988b233b4
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/DisplayEGL.cpp
@@ -0,0 +1,116 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// DisplayEGL.cpp: Common across EGL parts of platform specific egl::Display implementations
+
+#include "libANGLE/renderer/gl/egl/DisplayEGL.h"
+
+namespace rx
+{
+
+#define EGL_NO_CONFIG ((EGLConfig)0)
+
+DisplayEGL::DisplayEGL()
+ : DisplayGL(),
+ mEGL(nullptr),
+ mConfig(EGL_NO_CONFIG),
+ mContext(EGL_NO_CONTEXT),
+ mFunctionsGL(nullptr)
+{
+}
+
+DisplayEGL::~DisplayEGL()
+{
+}
+
+std::string DisplayEGL::getVendorString() const
+{
+ const char *vendor = mEGL->queryString(EGL_VENDOR);
+ ASSERT(vendor);
+ return vendor;
+}
+
+egl::Error DisplayEGL::initializeContext(const egl::AttributeMap &eglAttributes)
+{
+ gl::Version eglVersion(mEGL->majorVersion, mEGL->minorVersion);
+
+ EGLint requestedMajor =
+ eglAttributes.getAsInt(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, EGL_DONT_CARE);
+ EGLint requestedMinor =
+ eglAttributes.getAsInt(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, EGL_DONT_CARE);
+ bool initializeRequested = requestedMajor != EGL_DONT_CARE && requestedMinor != EGL_DONT_CARE;
+
+ static_assert(EGL_CONTEXT_MAJOR_VERSION == EGL_CONTEXT_MAJOR_VERSION_KHR,
+ "Major Version define should match");
+ static_assert(EGL_CONTEXT_MINOR_VERSION == EGL_CONTEXT_MINOR_VERSION_KHR,
+ "Minor Version define should match");
+
+ std::vector<std::vector<EGLint>> contextAttribLists;
+ if (eglVersion >= gl::Version(1, 5) || mEGL->hasExtension("EGL_KHR_create_context"))
+ {
+ if (initializeRequested)
+ {
+ contextAttribLists.push_back({EGL_CONTEXT_MAJOR_VERSION, requestedMajor,
+ EGL_CONTEXT_MINOR_VERSION, requestedMinor, EGL_NONE});
+ }
+ else
+ {
+ // clang-format off
+ const gl::Version esVersionsFrom2_0[] = {
+ gl::Version(3, 2),
+ gl::Version(3, 1),
+ gl::Version(3, 0),
+ gl::Version(2, 0),
+ };
+ // clang-format on
+
+ for (const auto &version : esVersionsFrom2_0)
+ {
+ contextAttribLists.push_back(
+ {EGL_CONTEXT_MAJOR_VERSION, static_cast<EGLint>(version.major),
+ EGL_CONTEXT_MINOR_VERSION, static_cast<EGLint>(version.minor), EGL_NONE});
+ }
+ }
+ }
+ else
+ {
+ if (initializeRequested && (requestedMajor != 2 || requestedMinor != 0))
+ {
+ return egl::Error(EGL_BAD_ATTRIBUTE, "Unsupported requested context version");
+ }
+ contextAttribLists.push_back({EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE});
+ }
+
+ for (auto &attribList : contextAttribLists)
+ {
+ mContext = mEGL->createContext(mConfig, EGL_NO_CONTEXT, attribList.data());
+ if (mContext != EGL_NO_CONTEXT)
+ {
+ return egl::Error(EGL_SUCCESS);
+ }
+ }
+
+ return egl::Error(mEGL->getError(), "eglCreateContext failed");
+}
+
+void DisplayEGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
+{
+ outExtensions->createContextRobustness =
+ mEGL->hasExtension("EGL_EXT_create_context_robustness");
+
+ outExtensions->postSubBuffer = false; // Since SurfaceEGL::postSubBuffer is not implemented
+}
+
+void DisplayEGL::generateCaps(egl::Caps *outCaps) const
+{
+ outCaps->textureNPOT = true; // Since we request GLES >= 2
+}
+
+const FunctionsGL *DisplayEGL::getFunctionsGL() const
+{
+ return mFunctionsGL;
+}
+} // namespace rx
diff --git a/gfx/angle/src/libANGLE/renderer/gl/egl/DisplayEGL.h b/gfx/angle/src/libANGLE/renderer/gl/egl/DisplayEGL.h
new file mode 100755
index 000000000..e498cd79a
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/DisplayEGL.h
@@ -0,0 +1,43 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// DisplayEGL.h: Common across EGL parts of platform specific egl::Display implementations
+
+#ifndef LIBANGLE_RENDERER_GL_EGL_DISPLAYEGL_H_
+#define LIBANGLE_RENDERER_GL_EGL_DISPLAYEGL_H_
+
+#include "libANGLE/renderer/gl/DisplayGL.h"
+#include "libANGLE/renderer/gl/egl/FunctionsEGL.h"
+
+namespace rx
+{
+
+class DisplayEGL : public DisplayGL
+{
+ public:
+ DisplayEGL();
+ ~DisplayEGL() override;
+
+ std::string getVendorString() const override;
+
+ protected:
+ egl::Error initializeContext(const egl::AttributeMap &eglAttributes);
+
+ FunctionsEGL *mEGL;
+ EGLConfig mConfig;
+ EGLContext mContext;
+ FunctionsGL *mFunctionsGL;
+
+ private:
+ void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
+ void generateCaps(egl::Caps *outCaps) const override;
+
+ const FunctionsGL *getFunctionsGL() const override;
+};
+
+} // namespace rx
+
+#endif /* LIBANGLE_RENDERER_GL_EGL_DISPLAYEGL_H_ */
diff --git a/gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGL.cpp
new file mode 100755
index 000000000..c0b0f846f
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGL.cpp
@@ -0,0 +1,340 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FunctionsEGL.cpp: Implements the FunctionsEGL class.
+
+#include "libANGLE/renderer/gl/egl/FunctionsEGL.h"
+
+#include <algorithm>
+
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+#include "libANGLE/renderer/gl/egl/functionsegl_typedefs.h"
+#include "common/string_utils.h"
+
+namespace
+{
+
+template <typename T>
+bool SetPtr(T *dst, void *src)
+{
+ if (src)
+ {
+ *dst = reinterpret_cast<T>(src);
+ return true;
+ }
+ return false;
+}
+} // namespace
+
+namespace rx
+{
+
+struct FunctionsEGL::EGLDispatchTable
+{
+ EGLDispatchTable()
+ : bindAPIPtr(nullptr),
+ chooseConfigPtr(nullptr),
+ createContextPtr(nullptr),
+ createPbufferSurfacePtr(nullptr),
+ createWindowSurfacePtr(nullptr),
+ destroyContextPtr(nullptr),
+ destroySurfacePtr(nullptr),
+ getConfigAttribPtr(nullptr),
+ getDisplayPtr(nullptr),
+ getErrorPtr(nullptr),
+ initializePtr(nullptr),
+ makeCurrentPtr(nullptr),
+ queryStringPtr(nullptr),
+ querySurfacePtr(nullptr),
+ swapBuffersPtr(nullptr),
+ terminatePtr(nullptr),
+
+ bindTexImagePtr(nullptr),
+ releaseTexImagePtr(nullptr),
+ swapIntervalPtr(nullptr),
+
+ createImageKHRPtr(nullptr),
+ destroyImageKHRPtr(nullptr),
+
+ clientWaitSyncKHRPtr(nullptr),
+ createSyncKHRPtr(nullptr),
+ destroySyncKHRPtr(nullptr),
+ getSyncAttribKHRPtr(nullptr)
+ {
+ }
+
+ // 1.0
+ PFNEGLBINDAPIPROC bindAPIPtr;
+ PFNEGLCHOOSECONFIGPROC chooseConfigPtr;
+ PFNEGLCREATECONTEXTPROC createContextPtr;
+ PFNEGLCREATEPBUFFERSURFACEPROC createPbufferSurfacePtr;
+ PFNEGLCREATEWINDOWSURFACEPROC createWindowSurfacePtr;
+ PFNEGLDESTROYCONTEXTPROC destroyContextPtr;
+ PFNEGLDESTROYSURFACEPROC destroySurfacePtr;
+ PFNEGLGETCONFIGATTRIBPROC getConfigAttribPtr;
+ PFNEGLGETDISPLAYPROC getDisplayPtr;
+ PFNEGLGETERRORPROC getErrorPtr;
+ PFNEGLINITIALIZEPROC initializePtr;
+ PFNEGLMAKECURRENTPROC makeCurrentPtr;
+ PFNEGLQUERYSTRINGPROC queryStringPtr;
+ PFNEGLQUERYSURFACEPROC querySurfacePtr;
+ PFNEGLSWAPBUFFERSPROC swapBuffersPtr;
+ PFNEGLTERMINATEPROC terminatePtr;
+
+ // 1.1
+ PFNEGLBINDTEXIMAGEPROC bindTexImagePtr;
+ PFNEGLRELEASETEXIMAGEPROC releaseTexImagePtr;
+ PFNEGLSWAPINTERVALPROC swapIntervalPtr;
+
+ // EGL_KHR_image
+ PFNEGLCREATEIMAGEKHRPROC createImageKHRPtr;
+ PFNEGLDESTROYIMAGEKHRPROC destroyImageKHRPtr;
+
+ // EGL_KHR_fence_sync
+ PFNEGLCLIENTWAITSYNCKHRPROC clientWaitSyncKHRPtr;
+ PFNEGLCREATESYNCKHRPROC createSyncKHRPtr;
+ PFNEGLDESTROYSYNCKHRPROC destroySyncKHRPtr;
+ PFNEGLGETSYNCATTRIBKHRPROC getSyncAttribKHRPtr;
+};
+
+FunctionsEGL::FunctionsEGL()
+ : majorVersion(0), minorVersion(0), mFnPtrs(new EGLDispatchTable()), mEGLDisplay(EGL_NO_DISPLAY)
+{
+}
+
+FunctionsEGL::~FunctionsEGL()
+{
+ SafeDelete(mFnPtrs);
+}
+
+egl::Error FunctionsEGL::initialize(EGLNativeDisplayType nativeDisplay)
+{
+#define ANGLE_GET_PROC_OR_ERROR(MEMBER, NAME) \
+ if (!SetPtr(MEMBER, getProcAddress(#NAME))) \
+ { \
+ return egl::Error(EGL_NOT_INITIALIZED, "Could not load EGL entry point " #NAME); \
+ }
+
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->bindAPIPtr, eglBindAPI);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->chooseConfigPtr, eglChooseConfig);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->createContextPtr, eglCreateContext);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->createPbufferSurfacePtr, eglCreatePbufferSurface);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->createWindowSurfacePtr, eglCreateWindowSurface);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->destroyContextPtr, eglDestroyContext);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->destroySurfacePtr, eglDestroySurface);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getConfigAttribPtr, eglGetConfigAttrib);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getDisplayPtr, eglGetDisplay);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getErrorPtr, eglGetError);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->initializePtr, eglInitialize);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->makeCurrentPtr, eglMakeCurrent);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->queryStringPtr, eglQueryString);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->querySurfacePtr, eglQuerySurface);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->swapBuffersPtr, eglSwapBuffers);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->terminatePtr, eglTerminate);
+
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->bindTexImagePtr, eglBindTexImage);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->releaseTexImagePtr, eglReleaseTexImage);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->swapIntervalPtr, eglSwapInterval);
+
+ mEGLDisplay = mFnPtrs->getDisplayPtr(nativeDisplay);
+ if (mEGLDisplay == EGL_NO_DISPLAY)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Failed to get system egl display");
+ }
+ if (mFnPtrs->initializePtr(mEGLDisplay, &majorVersion, &minorVersion) != EGL_TRUE)
+ {
+ return egl::Error(mFnPtrs->getErrorPtr(), "Failed to initialize system egl");
+ }
+ if (majorVersion < 1 || (majorVersion == 1 && minorVersion < 4))
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Unsupported EGL version (require at least 1.4).");
+ }
+ if (mFnPtrs->bindAPIPtr(EGL_OPENGL_ES_API) != EGL_TRUE)
+ {
+ return egl::Error(mFnPtrs->getErrorPtr(), "Failed to bind API in system egl");
+ }
+
+ const char *extensions = queryString(EGL_EXTENSIONS);
+ if (!extensions)
+ {
+ return egl::Error(mFnPtrs->getErrorPtr(), "Faild to query extensions in system egl");
+ }
+ angle::SplitStringAlongWhitespace(extensions, &mExtensions);
+
+ if (hasExtension("EGL_KHR_image_base"))
+ {
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->createImageKHRPtr, eglCreateImageKHR);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->destroyImageKHRPtr, eglDestroyImageKHR);
+ }
+ if (hasExtension("EGL_KHR_fence_sync"))
+ {
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->clientWaitSyncKHRPtr, eglClientWaitSyncKHR);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->createSyncKHRPtr, eglCreateSyncKHR);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->destroySyncKHRPtr, eglDestroySyncKHR);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getSyncAttribKHRPtr, eglGetSyncAttribKHR);
+ }
+
+#undef ANGLE_GET_PROC_OR_ERROR
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error FunctionsEGL::terminate()
+{
+ if (mFnPtrs->terminatePtr(mEGLDisplay) == EGL_TRUE)
+ {
+ mEGLDisplay = nullptr;
+ return egl::Error(EGL_SUCCESS);
+ }
+ return egl::Error(mFnPtrs->getErrorPtr());
+}
+
+class FunctionsGLEGL : public FunctionsGL
+{
+ public:
+ FunctionsGLEGL(const FunctionsEGL &egl) : mEGL(egl) {}
+
+ ~FunctionsGLEGL() override {}
+
+ private:
+ void *loadProcAddress(const std::string &function) override
+ {
+ return mEGL.getProcAddress(function.c_str());
+ }
+
+ const FunctionsEGL &mEGL;
+};
+
+FunctionsGL *FunctionsEGL::makeFunctionsGL(void) const
+{
+ return new FunctionsGLEGL(*this);
+}
+
+bool FunctionsEGL::hasExtension(const char *extension) const
+{
+ return std::find(mExtensions.begin(), mExtensions.end(), extension) != mExtensions.end();
+}
+
+EGLDisplay FunctionsEGL::getDisplay() const
+{
+ return mEGLDisplay;
+}
+
+EGLint FunctionsEGL::getError() const
+{
+ return mFnPtrs->getErrorPtr();
+}
+
+EGLBoolean FunctionsEGL::chooseConfig(EGLint const *attribList,
+ EGLConfig *configs,
+ EGLint configSize,
+ EGLint *numConfig) const
+{
+ return mFnPtrs->chooseConfigPtr(mEGLDisplay, attribList, configs, configSize, numConfig);
+}
+
+EGLBoolean FunctionsEGL::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value) const
+{
+ return mFnPtrs->getConfigAttribPtr(mEGLDisplay, config, attribute, value);
+}
+
+EGLContext FunctionsEGL::createContext(EGLConfig config,
+ EGLContext share_context,
+ EGLint const *attrib_list) const
+{
+ return mFnPtrs->createContextPtr(mEGLDisplay, config, share_context, attrib_list);
+}
+
+EGLSurface FunctionsEGL::createPbufferSurface(EGLConfig config, const EGLint *attrib_list) const
+{
+ return mFnPtrs->createPbufferSurfacePtr(mEGLDisplay, config, attrib_list);
+}
+
+EGLSurface FunctionsEGL::createWindowSurface(EGLConfig config,
+ EGLNativeWindowType win,
+ const EGLint *attrib_list) const
+{
+ return mFnPtrs->createWindowSurfacePtr(mEGLDisplay, config, win, attrib_list);
+}
+
+EGLBoolean FunctionsEGL::destroyContext(EGLContext context) const
+{
+ return mFnPtrs->destroyContextPtr(mEGLDisplay, context);
+}
+
+EGLBoolean FunctionsEGL::destroySurface(EGLSurface surface) const
+{
+ return mFnPtrs->destroySurfacePtr(mEGLDisplay, surface);
+}
+
+EGLBoolean FunctionsEGL::makeCurrent(EGLSurface surface, EGLContext context) const
+{
+ return mFnPtrs->makeCurrentPtr(mEGLDisplay, surface, surface, context);
+}
+
+char const *FunctionsEGL::queryString(EGLint name) const
+{
+ return mFnPtrs->queryStringPtr(mEGLDisplay, name);
+}
+
+EGLBoolean FunctionsEGL::querySurface(EGLSurface surface, EGLint attribute, EGLint *value) const
+{
+ return mFnPtrs->querySurfacePtr(mEGLDisplay, surface, attribute, value);
+}
+
+EGLBoolean FunctionsEGL::swapBuffers(EGLSurface surface) const
+{
+ return mFnPtrs->swapBuffersPtr(mEGLDisplay, surface);
+}
+
+EGLBoolean FunctionsEGL::bindTexImage(EGLSurface surface, EGLint buffer) const
+{
+ return mFnPtrs->bindTexImagePtr(mEGLDisplay, surface, buffer);
+}
+
+EGLBoolean FunctionsEGL::releaseTexImage(EGLSurface surface, EGLint buffer) const
+{
+ return mFnPtrs->releaseTexImagePtr(mEGLDisplay, surface, buffer);
+}
+
+EGLBoolean FunctionsEGL::swapInterval(EGLint interval) const
+{
+ return mFnPtrs->swapIntervalPtr(mEGLDisplay, interval);
+}
+
+EGLImageKHR FunctionsEGL::createImageKHR(EGLContext context,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const EGLint *attrib_list) const
+{
+ return mFnPtrs->createImageKHRPtr(mEGLDisplay, context, target, buffer, attrib_list);
+}
+
+EGLBoolean FunctionsEGL::destroyImageKHR(EGLImageKHR image) const
+{
+ return mFnPtrs->destroyImageKHRPtr(mEGLDisplay, image);
+}
+
+EGLSyncKHR FunctionsEGL::createSyncKHR(EGLenum type, const EGLint *attrib_list)
+{
+ return mFnPtrs->createSyncKHRPtr(mEGLDisplay, type, attrib_list);
+}
+
+EGLBoolean FunctionsEGL::destroySyncKHR(EGLSyncKHR sync)
+{
+ return mFnPtrs->destroySyncKHRPtr(mEGLDisplay, sync);
+}
+
+EGLint FunctionsEGL::clientWaitSyncKHR(EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
+{
+ return mFnPtrs->clientWaitSyncKHRPtr(mEGLDisplay, sync, flags, timeout);
+}
+
+EGLBoolean FunctionsEGL::getSyncAttribKHR(EGLSyncKHR sync, EGLint attribute, EGLint *value)
+{
+ return mFnPtrs->getSyncAttribKHRPtr(mEGLDisplay, sync, attribute, value);
+}
+} // namespace rx
diff --git a/gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGL.h b/gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGL.h
new file mode 100755
index 000000000..43d5622e6
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGL.h
@@ -0,0 +1,91 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FunctionsEGL.h: Defines the FunctionsEGL class to load functions and data from EGL
+
+#ifndef LIBANGLE_RENDERER_GL_CROS_FUNCTIONSEGL_H_
+#define LIBANGLE_RENDERER_GL_CROS_FUNCTIONSEGL_H_
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include <string>
+#include <vector>
+
+#include "libANGLE/Error.h"
+
+namespace rx
+{
+
+class FunctionsGL;
+
+class FunctionsEGL
+{
+ public:
+ FunctionsEGL();
+ virtual ~FunctionsEGL();
+
+ int majorVersion;
+ int minorVersion;
+
+ egl::Error initialize(EGLNativeDisplayType nativeDisplay);
+ egl::Error terminate();
+
+ virtual void *getProcAddress(const char *name) const = 0;
+
+ FunctionsGL *makeFunctionsGL() const;
+ bool hasExtension(const char *extension) const;
+ EGLDisplay getDisplay() const;
+ EGLint getError() const;
+
+ EGLBoolean chooseConfig(EGLint const *attrib_list,
+ EGLConfig *configs,
+ EGLint config_size,
+ EGLint *num_config) const;
+ EGLBoolean getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value) const;
+ EGLContext createContext(EGLConfig config,
+ EGLContext share_context,
+ EGLint const *attrib_list) const;
+ EGLSurface createPbufferSurface(EGLConfig config, const EGLint *attrib_list) const;
+ EGLSurface createWindowSurface(EGLConfig config,
+ EGLNativeWindowType win,
+ const EGLint *attrib_list) const;
+ EGLBoolean destroyContext(EGLContext context) const;
+ EGLBoolean destroySurface(EGLSurface surface) const;
+ EGLBoolean makeCurrent(EGLSurface surface, EGLContext context) const;
+ const char *queryString(EGLint name) const;
+ EGLBoolean querySurface(EGLSurface surface, EGLint attribute, EGLint *value) const;
+ EGLBoolean swapBuffers(EGLSurface surface) const;
+
+ EGLBoolean bindTexImage(EGLSurface surface, EGLint buffer) const;
+ EGLBoolean releaseTexImage(EGLSurface surface, EGLint buffer) const;
+ EGLBoolean swapInterval(EGLint interval) const;
+
+ EGLImageKHR createImageKHR(EGLContext context,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const EGLint *attrib_list) const;
+ EGLBoolean destroyImageKHR(EGLImageKHR image) const;
+
+ EGLSyncKHR createSyncKHR(EGLenum type, const EGLint *attrib_list);
+ EGLBoolean destroySyncKHR(EGLSyncKHR sync);
+ EGLint clientWaitSyncKHR(EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
+ EGLBoolean getSyncAttribKHR(EGLSyncKHR sync, EGLint attribute, EGLint *value);
+
+ private:
+ // So as to isolate from angle we do not include angleutils.h and cannot
+ // use angle::NonCopyable so we replicated it here instead.
+ FunctionsEGL(const FunctionsEGL &) = delete;
+ void operator=(const FunctionsEGL &) = delete;
+
+ struct EGLDispatchTable;
+ EGLDispatchTable *mFnPtrs;
+ EGLDisplay mEGLDisplay;
+ std::vector<std::string> mExtensions;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_GL_CROS_FUNCTIONSEGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGLDL.cpp b/gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGLDL.cpp
new file mode 100755
index 000000000..e6ef45d8d
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGLDL.cpp
@@ -0,0 +1,74 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FunctionsEGLDL.cpp: Implements the FunctionsEGLDL class.
+
+#include "libANGLE/renderer/gl/egl/FunctionsEGLDL.h"
+
+#include <dlfcn.h>
+
+namespace rx
+{
+
+DynamicLib::DynamicLib() : handle(nullptr)
+{
+}
+
+DynamicLib::~DynamicLib()
+{
+ if (handle)
+ {
+ dlclose(handle);
+ handle = nullptr;
+ }
+}
+
+// Due to a bug in Mesa (or maybe libdl) it's not possible to close and re-open libEGL.so
+// an arbitrary number of times. End2end tests would die after a couple hundred tests.
+// So we use a static object with a destructor to close the library when the program exits.
+// TODO(fjhenigman) File a bug and put a link here.
+DynamicLib FunctionsEGLDL::sNativeLib;
+
+FunctionsEGLDL::FunctionsEGLDL() : mGetProcAddressPtr(nullptr)
+{
+}
+
+FunctionsEGLDL::~FunctionsEGLDL()
+{
+}
+
+egl::Error FunctionsEGLDL::initialize(EGLNativeDisplayType nativeDisplay, const char *libName)
+{
+ if (!sNativeLib.handle)
+ {
+ sNativeLib.handle = dlopen(libName, RTLD_NOW);
+ if (!sNativeLib.handle)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Could not dlopen native EGL: %s", dlerror());
+ }
+ }
+
+ mGetProcAddressPtr =
+ reinterpret_cast<PFNEGLGETPROCADDRESSPROC>(dlsym(sNativeLib.handle, "eglGetProcAddress"));
+ if (!mGetProcAddressPtr)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Could not find eglGetProcAddress");
+ }
+
+ return FunctionsEGL::initialize(nativeDisplay);
+}
+
+void *FunctionsEGLDL::getProcAddress(const char *name) const
+{
+ void *f = reinterpret_cast<void *>(mGetProcAddressPtr(name));
+ if (f)
+ {
+ return f;
+ }
+ return dlsym(sNativeLib.handle, name);
+}
+
+} // namespace rx
diff --git a/gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGLDL.h b/gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGLDL.h
new file mode 100755
index 000000000..d69df77ab
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGLDL.h
@@ -0,0 +1,42 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FunctionsEGL.h: Implements FunctionsEGL with dlopen/dlsym/dlclose
+
+#ifndef LIBANGLE_RENDERER_GL_CROS_FUNCTIONSEGLDL_H_
+#define LIBANGLE_RENDERER_GL_CROS_FUNCTIONSEGLDL_H_
+
+#include "libANGLE/renderer/gl/egl/FunctionsEGL.h"
+#include "libANGLE/renderer/gl/egl/functionsegl_typedefs.h"
+
+namespace rx
+{
+
+class DynamicLib final
+{
+ public:
+ void *handle;
+
+ DynamicLib();
+ ~DynamicLib();
+};
+
+class FunctionsEGLDL : public FunctionsEGL
+{
+ public:
+ FunctionsEGLDL();
+ ~FunctionsEGLDL() override;
+
+ egl::Error initialize(EGLNativeDisplayType nativeDisplay, const char *libName);
+ void *getProcAddress(const char *name) const override;
+
+ private:
+ PFNEGLGETPROCADDRESSPROC mGetProcAddressPtr;
+ static DynamicLib sNativeLib;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_GL_CROS_FUNCTIONSEGLDL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/egl/PbufferSurfaceEGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/egl/PbufferSurfaceEGL.cpp
new file mode 100755
index 000000000..68da9f2b8
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/PbufferSurfaceEGL.cpp
@@ -0,0 +1,39 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// PbufferSurfaceEGL.h: EGL implementation of egl::Surface for pbuffers
+
+#include "libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h"
+
+namespace rx
+{
+
+PbufferSurfaceEGL::PbufferSurfaceEGL(const egl::SurfaceState &state,
+ const FunctionsEGL *egl,
+ EGLConfig config,
+ const std::vector<EGLint> &attribList,
+ EGLContext context,
+ RendererGL *renderer)
+ : SurfaceEGL(state, egl, config, attribList, context, renderer)
+{
+}
+
+PbufferSurfaceEGL::~PbufferSurfaceEGL()
+{
+}
+
+egl::Error PbufferSurfaceEGL::initialize()
+{
+ mSurface = mEGL->createPbufferSurface(mConfig, mAttribList.data());
+ if (mSurface == EGL_NO_SURFACE)
+ {
+ return egl::Error(mEGL->getError(), "eglCreatePbufferSurface failed");
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+} // namespace rx
diff --git a/gfx/angle/src/libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h b/gfx/angle/src/libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h
new file mode 100755
index 000000000..ff557f2ca
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h
@@ -0,0 +1,36 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// PbufferSurfaceEGL.h: EGL implementation of egl::Surface for pbuffers
+
+#ifndef LIBANGLE_RENDERER_GL_EGL_PBUFFERSURFACEEGL_H_
+#define LIBANGLE_RENDERER_GL_EGL_PBUFFERSURFACEEGL_H_
+
+#include <vector>
+#include <EGL/egl.h>
+
+#include "libANGLE/renderer/gl/egl/SurfaceEGL.h"
+
+namespace rx
+{
+
+class PbufferSurfaceEGL : public SurfaceEGL
+{
+ public:
+ PbufferSurfaceEGL(const egl::SurfaceState &state,
+ const FunctionsEGL *egl,
+ EGLConfig config,
+ const std::vector<EGLint> &attribList,
+ EGLContext context,
+ RendererGL *renderer);
+ ~PbufferSurfaceEGL() override;
+
+ egl::Error initialize() override;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_GL_EGL_PBUFFERSURFACEEGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/egl/SurfaceEGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/egl/SurfaceEGL.cpp
new file mode 100755
index 000000000..693b61c9c
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/SurfaceEGL.cpp
@@ -0,0 +1,132 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// SurfaceEGL.cpp: EGL implementation of egl::Surface
+
+#include "libANGLE/renderer/gl/egl/SurfaceEGL.h"
+
+#include "common/debug.h"
+
+namespace rx
+{
+
+SurfaceEGL::SurfaceEGL(const egl::SurfaceState &state,
+ const FunctionsEGL *egl,
+ EGLConfig config,
+ const std::vector<EGLint> &attribList,
+ EGLContext context,
+ RendererGL *renderer)
+ : SurfaceGL(state, renderer),
+ mEGL(egl),
+ mConfig(config),
+ mAttribList(attribList),
+ mSurface(EGL_NO_SURFACE),
+ mContext(context)
+{
+}
+
+SurfaceEGL::~SurfaceEGL()
+{
+ if (mSurface != EGL_NO_SURFACE)
+ {
+ EGLBoolean success = mEGL->destroySurface(mSurface);
+ ASSERT(success == EGL_TRUE);
+ }
+}
+
+egl::Error SurfaceEGL::makeCurrent()
+{
+ EGLBoolean success = mEGL->makeCurrent(mSurface, mContext);
+ if (success == EGL_FALSE)
+ {
+ return egl::Error(mEGL->getError(), "eglMakeCurrent failed");
+ }
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error SurfaceEGL::swap()
+{
+ EGLBoolean success = mEGL->swapBuffers(mSurface);
+ if (success == EGL_FALSE)
+ {
+ return egl::Error(mEGL->getError(), "eglSwapBuffers failed");
+ }
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error SurfaceEGL::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_BAD_SURFACE);
+}
+
+egl::Error SurfaceEGL::querySurfacePointerANGLE(EGLint attribute, void **value)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_BAD_SURFACE);
+}
+
+egl::Error SurfaceEGL::bindTexImage(gl::Texture *texture, EGLint buffer)
+{
+ EGLBoolean success = mEGL->bindTexImage(mSurface, buffer);
+ if (success == EGL_FALSE)
+ {
+ return egl::Error(mEGL->getError(), "eglBindTexImage failed");
+ }
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error SurfaceEGL::releaseTexImage(EGLint buffer)
+{
+ EGLBoolean success = mEGL->releaseTexImage(mSurface, buffer);
+ if (success == EGL_FALSE)
+ {
+ return egl::Error(mEGL->getError(), "eglReleaseTexImage failed");
+ }
+ return egl::Error(EGL_SUCCESS);
+}
+
+void SurfaceEGL::setSwapInterval(EGLint interval)
+{
+ EGLBoolean success = mEGL->swapInterval(interval);
+ if (success == EGL_FALSE)
+ {
+ ERR("eglSwapInterval error 0x%04x", mEGL->getError());
+ ASSERT(false);
+ }
+}
+
+EGLint SurfaceEGL::getWidth() const
+{
+ EGLint value;
+ EGLBoolean success = mEGL->querySurface(mSurface, EGL_WIDTH, &value);
+ ASSERT(success == EGL_TRUE);
+ return value;
+}
+
+EGLint SurfaceEGL::getHeight() const
+{
+ EGLint value;
+ EGLBoolean success = mEGL->querySurface(mSurface, EGL_HEIGHT, &value);
+ ASSERT(success == EGL_TRUE);
+ return value;
+}
+
+EGLint SurfaceEGL::isPostSubBufferSupported() const
+{
+ UNIMPLEMENTED();
+ return 0;
+}
+
+EGLint SurfaceEGL::getSwapBehavior() const
+{
+ EGLint value;
+ EGLBoolean success = mEGL->querySurface(mSurface, EGL_SWAP_BEHAVIOR, &value);
+ ASSERT(success == EGL_TRUE);
+ return value;
+}
+
+} // namespace rx
diff --git a/gfx/angle/src/libANGLE/renderer/gl/egl/SurfaceEGL.h b/gfx/angle/src/libANGLE/renderer/gl/egl/SurfaceEGL.h
new file mode 100755
index 000000000..ee1568c9e
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/SurfaceEGL.h
@@ -0,0 +1,55 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// SurfaceEGL.h: common interface for EGL surfaces
+
+#ifndef LIBANGLE_RENDERER_GL_EGL_SURFACEEGL_H_
+#define LIBANGLE_RENDERER_GL_EGL_SURFACEEGL_H_
+
+#include <EGL/egl.h>
+
+#include "libANGLE/renderer/gl/SurfaceGL.h"
+#include "libANGLE/renderer/gl/egl/FunctionsEGL.h"
+
+namespace rx
+{
+
+class SurfaceEGL : public SurfaceGL
+{
+ public:
+ SurfaceEGL(const egl::SurfaceState &state,
+ const FunctionsEGL *egl,
+ EGLConfig config,
+ const std::vector<EGLint> &attribList,
+ EGLContext context,
+ RendererGL *renderer);
+ ~SurfaceEGL() override;
+
+ egl::Error makeCurrent() override;
+ egl::Error swap() override;
+ egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override;
+ egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override;
+ egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) override;
+ egl::Error releaseTexImage(EGLint buffer) override;
+ void setSwapInterval(EGLint interval) override;
+ EGLint getWidth() const override;
+ EGLint getHeight() const override;
+ EGLint isPostSubBufferSupported() const override;
+ EGLint getSwapBehavior() const override;
+
+ protected:
+ const FunctionsEGL *mEGL;
+ EGLConfig mConfig;
+ std::vector<EGLint> mAttribList;
+ EGLSurface mSurface;
+
+ private:
+ EGLContext mContext;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_GL_EGL_SURFACEEGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/egl/WindowSurfaceEGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/egl/WindowSurfaceEGL.cpp
new file mode 100755
index 000000000..db226ee18
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/WindowSurfaceEGL.cpp
@@ -0,0 +1,40 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// WindowSurfaceEGL.h: EGL implementation of egl::Surface for windows
+
+#include "libANGLE/renderer/gl/egl/WindowSurfaceEGL.h"
+
+namespace rx
+{
+
+WindowSurfaceEGL::WindowSurfaceEGL(const egl::SurfaceState &state,
+ const FunctionsEGL *egl,
+ EGLConfig config,
+ EGLNativeWindowType window,
+ const std::vector<EGLint> &attribList,
+ EGLContext context,
+ RendererGL *renderer)
+ : SurfaceEGL(state, egl, config, attribList, context, renderer), mWindow(window)
+{
+}
+
+WindowSurfaceEGL::~WindowSurfaceEGL()
+{
+}
+
+egl::Error WindowSurfaceEGL::initialize()
+{
+ mSurface = mEGL->createWindowSurface(mConfig, mWindow, mAttribList.data());
+ if (mSurface == EGL_NO_SURFACE)
+ {
+ return egl::Error(mEGL->getError(), "eglCreateWindowSurface failed");
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+} // namespace rx
diff --git a/gfx/angle/src/libANGLE/renderer/gl/egl/WindowSurfaceEGL.h b/gfx/angle/src/libANGLE/renderer/gl/egl/WindowSurfaceEGL.h
new file mode 100755
index 000000000..f9da4c27c
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/WindowSurfaceEGL.h
@@ -0,0 +1,37 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// WindowSurfaceEGL.h: EGL implementation of egl::Surface for windows
+
+#ifndef LIBANGLE_RENDERER_GL_EGL_WINDOWSURFACEEGL_H_
+#define LIBANGLE_RENDERER_GL_EGL_WINDOWSURFACEEGL_H_
+
+#include "libANGLE/renderer/gl/egl/SurfaceEGL.h"
+
+namespace rx
+{
+
+class WindowSurfaceEGL : public SurfaceEGL
+{
+ public:
+ WindowSurfaceEGL(const egl::SurfaceState &state,
+ const FunctionsEGL *egl,
+ EGLConfig config,
+ EGLNativeWindowType window,
+ const std::vector<EGLint> &attribList,
+ EGLContext context,
+ RendererGL *renderer);
+ ~WindowSurfaceEGL() override;
+
+ egl::Error initialize() override;
+
+ private:
+ EGLNativeWindowType mWindow;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_GL_EGL_WINDOWSURFACEEGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.cpp b/gfx/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.cpp
new file mode 100755
index 000000000..b689578c9
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.cpp
@@ -0,0 +1,385 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// DisplayAndroid.cpp: Android implementation of egl::Display
+
+#include <android/native_window.h>
+
+#include "common/debug.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/renderer/gl/renderergl_utils.h"
+#include "libANGLE/renderer/gl/egl/android/DisplayAndroid.h"
+#include "libANGLE/renderer/gl/egl/FunctionsEGLDL.h"
+#include "libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h"
+#include "libANGLE/renderer/gl/egl/WindowSurfaceEGL.h"
+
+namespace
+{
+const char *GetEGLPath()
+{
+#if defined(__LP64__)
+ return "/system/lib64/libEGL.so";
+#else
+ return "/system/lib/libEGL.so";
+#endif
+}
+} // namespace
+
+namespace rx
+{
+
+DisplayAndroid::DisplayAndroid() : DisplayEGL(), mDummyPbuffer(EGL_NO_SURFACE)
+{
+}
+
+DisplayAndroid::~DisplayAndroid()
+{
+}
+
+egl::Error DisplayAndroid::initialize(egl::Display *display)
+{
+ FunctionsEGLDL *egl = new FunctionsEGLDL();
+ mEGL = egl;
+ ANGLE_TRY(egl->initialize(display->getNativeDisplayId(), GetEGLPath()));
+
+ gl::Version eglVersion(mEGL->majorVersion, mEGL->minorVersion);
+ ASSERT(eglVersion >= gl::Version(1, 4));
+
+ static_assert(EGL_OPENGL_ES3_BIT == EGL_OPENGL_ES3_BIT_KHR, "Extension define must match core");
+ EGLint esBit = (eglVersion >= gl::Version(1, 5) || mEGL->hasExtension("EGL_KHR_create_context"))
+ ? EGL_OPENGL_ES3_BIT
+ : EGL_OPENGL_ES2_BIT;
+
+ // clang-format off
+ mConfigAttribList =
+ {
+ // Choose RGBA8888
+ EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ // EGL1.5 spec Section 2.2 says that depth, multisample and stencil buffer depths
+ // must match for contexts to be compatible.
+ EGL_DEPTH_SIZE, 24,
+ EGL_STENCIL_SIZE, 8,
+ EGL_SAMPLE_BUFFERS, 0,
+ // Android doesn't support pixmaps
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
+ EGL_CONFIG_CAVEAT, EGL_NONE,
+ EGL_CONFORMANT, esBit,
+ EGL_RENDERABLE_TYPE, esBit,
+ EGL_NONE
+ };
+ // clang-format on
+ EGLint numConfig;
+
+ EGLBoolean success = mEGL->chooseConfig(mConfigAttribList.data(), &mConfig, 1, &numConfig);
+ if (success == EGL_FALSE)
+ {
+ return egl::Error(mEGL->getError(), "eglChooseConfig failed");
+ }
+
+ ANGLE_TRY(initializeContext(display->getAttributeMap()));
+
+ int dummyPbufferAttribs[] = {
+ EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE,
+ };
+ mDummyPbuffer = mEGL->createPbufferSurface(mConfig, dummyPbufferAttribs);
+ if (mDummyPbuffer == EGL_NO_SURFACE)
+ {
+ return egl::Error(mEGL->getError(), "eglCreatePbufferSurface failed");
+ }
+
+ success = mEGL->makeCurrent(mDummyPbuffer, mContext);
+ if (success == EGL_FALSE)
+ {
+ return egl::Error(mEGL->getError(), "eglMakeCurrent failed");
+ }
+
+ mFunctionsGL = mEGL->makeFunctionsGL();
+ mFunctionsGL->initialize();
+
+ return DisplayGL::initialize(display);
+}
+
+void DisplayAndroid::terminate()
+{
+ DisplayGL::terminate();
+
+ EGLBoolean success = mEGL->makeCurrent(EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ if (success == EGL_FALSE)
+ {
+ ERR("eglMakeCurrent error 0x%04x", mEGL->getError());
+ }
+
+ if (mDummyPbuffer != EGL_NO_SURFACE)
+ {
+ success = mEGL->destroySurface(mDummyPbuffer);
+ mDummyPbuffer = EGL_NO_SURFACE;
+ if (success == EGL_FALSE)
+ {
+ ERR("eglDestroySurface error 0x%04x", mEGL->getError());
+ }
+ }
+
+ if (mContext != EGL_NO_CONTEXT)
+ {
+ success = mEGL->destroyContext(mContext);
+ mContext = EGL_NO_CONTEXT;
+ if (success == EGL_FALSE)
+ {
+ ERR("eglDestroyContext error 0x%04x", mEGL->getError());
+ }
+ }
+
+ egl::Error result = mEGL->terminate();
+ if (result.isError())
+ {
+ ERR("eglTerminate error 0x%04x", result.getCode());
+ }
+
+ SafeDelete(mEGL);
+ SafeDelete(mFunctionsGL);
+}
+
+SurfaceImpl *DisplayAndroid::createWindowSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLNativeWindowType window,
+ const egl::AttributeMap &attribs)
+{
+ EGLConfig config;
+ EGLint numConfig;
+ EGLBoolean success;
+
+ const EGLint configAttribList[] = {EGL_CONFIG_ID, mConfigIds[configuration->configID],
+ EGL_NONE};
+ success = mEGL->chooseConfig(configAttribList, &config, 1, &numConfig);
+ ASSERT(success && numConfig == 1);
+
+ return new WindowSurfaceEGL(state, mEGL, config, window, attribs.toIntVector(), mContext,
+ getRenderer());
+}
+
+SurfaceImpl *DisplayAndroid::createPbufferSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ const egl::AttributeMap &attribs)
+{
+ EGLConfig config;
+ EGLint numConfig;
+ EGLBoolean success;
+
+ const EGLint configAttribList[] = {EGL_CONFIG_ID, mConfigIds[configuration->configID],
+ EGL_NONE};
+ success = mEGL->chooseConfig(configAttribList, &config, 1, &numConfig);
+ ASSERT(success && numConfig == 1);
+
+ return new PbufferSurfaceEGL(state, mEGL, config, attribs.toIntVector(), mContext,
+ getRenderer());
+}
+
+SurfaceImpl *DisplayAndroid::createPbufferFromClientBuffer(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs)
+{
+ UNIMPLEMENTED();
+ return nullptr;
+}
+
+SurfaceImpl *DisplayAndroid::createPixmapSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ NativePixmapType nativePixmap,
+ const egl::AttributeMap &attribs)
+{
+ UNIMPLEMENTED();
+ return nullptr;
+}
+
+ImageImpl *DisplayAndroid::createImage(EGLenum target,
+ egl::ImageSibling *buffer,
+ const egl::AttributeMap &attribs)
+{
+ UNIMPLEMENTED();
+ return DisplayGL::createImage(target, buffer, attribs);
+}
+
+template <typename T>
+void DisplayAndroid::getConfigAttrib(EGLConfig config, EGLint attribute, T *value) const
+{
+ EGLint tmp;
+ EGLBoolean success = mEGL->getConfigAttrib(config, attribute, &tmp);
+ ASSERT(success == EGL_TRUE);
+ *value = tmp;
+}
+
+egl::ConfigSet DisplayAndroid::generateConfigs()
+{
+ egl::ConfigSet configSet;
+ mConfigIds.clear();
+
+ EGLint numConfigs;
+ EGLBoolean success = mEGL->chooseConfig(mConfigAttribList.data(), nullptr, 0, &numConfigs);
+ ASSERT(success == EGL_TRUE && numConfigs > 0);
+
+ std::vector<EGLConfig> configs(numConfigs);
+ EGLint numConfigs2;
+ success =
+ mEGL->chooseConfig(mConfigAttribList.data(), configs.data(), numConfigs, &numConfigs2);
+ ASSERT(success == EGL_TRUE && numConfigs2 == numConfigs);
+
+ for (int i = 0; i < numConfigs; i++)
+ {
+ egl::Config config;
+
+ getConfigAttrib(configs[i], EGL_BUFFER_SIZE, &config.bufferSize);
+ getConfigAttrib(configs[i], EGL_RED_SIZE, &config.redSize);
+ getConfigAttrib(configs[i], EGL_GREEN_SIZE, &config.greenSize);
+ getConfigAttrib(configs[i], EGL_BLUE_SIZE, &config.blueSize);
+ getConfigAttrib(configs[i], EGL_LUMINANCE_SIZE, &config.luminanceSize);
+ getConfigAttrib(configs[i], EGL_ALPHA_SIZE, &config.alphaSize);
+ getConfigAttrib(configs[i], EGL_ALPHA_MASK_SIZE, &config.alphaMaskSize);
+ getConfigAttrib(configs[i], EGL_BIND_TO_TEXTURE_RGB, &config.bindToTextureRGB);
+ getConfigAttrib(configs[i], EGL_BIND_TO_TEXTURE_RGBA, &config.bindToTextureRGBA);
+ getConfigAttrib(configs[i], EGL_COLOR_BUFFER_TYPE, &config.colorBufferType);
+ getConfigAttrib(configs[i], EGL_CONFIG_CAVEAT, &config.configCaveat);
+ getConfigAttrib(configs[i], EGL_CONFIG_ID, &config.configID);
+ getConfigAttrib(configs[i], EGL_CONFORMANT, &config.conformant);
+ getConfigAttrib(configs[i], EGL_DEPTH_SIZE, &config.depthSize);
+ getConfigAttrib(configs[i], EGL_LEVEL, &config.level);
+ getConfigAttrib(configs[i], EGL_MAX_PBUFFER_WIDTH, &config.maxPBufferWidth);
+ getConfigAttrib(configs[i], EGL_MAX_PBUFFER_HEIGHT, &config.maxPBufferHeight);
+ getConfigAttrib(configs[i], EGL_MAX_PBUFFER_PIXELS, &config.maxPBufferPixels);
+ getConfigAttrib(configs[i], EGL_MAX_SWAP_INTERVAL, &config.maxSwapInterval);
+ getConfigAttrib(configs[i], EGL_MIN_SWAP_INTERVAL, &config.minSwapInterval);
+ getConfigAttrib(configs[i], EGL_NATIVE_RENDERABLE, &config.nativeRenderable);
+ getConfigAttrib(configs[i], EGL_NATIVE_VISUAL_ID, &config.nativeVisualID);
+ getConfigAttrib(configs[i], EGL_NATIVE_VISUAL_TYPE, &config.nativeVisualType);
+ getConfigAttrib(configs[i], EGL_RENDERABLE_TYPE, &config.renderableType);
+ getConfigAttrib(configs[i], EGL_SAMPLE_BUFFERS, &config.sampleBuffers);
+ getConfigAttrib(configs[i], EGL_SAMPLES, &config.samples);
+ getConfigAttrib(configs[i], EGL_STENCIL_SIZE, &config.stencilSize);
+ getConfigAttrib(configs[i], EGL_SURFACE_TYPE, &config.surfaceType);
+ getConfigAttrib(configs[i], EGL_TRANSPARENT_TYPE, &config.transparentType);
+ getConfigAttrib(configs[i], EGL_TRANSPARENT_RED_VALUE, &config.transparentRedValue);
+ getConfigAttrib(configs[i], EGL_TRANSPARENT_GREEN_VALUE, &config.transparentGreenValue);
+ getConfigAttrib(configs[i], EGL_TRANSPARENT_BLUE_VALUE, &config.transparentBlueValue);
+
+ if (config.colorBufferType == EGL_RGB_BUFFER)
+ {
+ if (config.redSize == 8 && config.greenSize == 8 && config.blueSize == 8 &&
+ config.alphaSize == 8)
+ {
+ config.renderTargetFormat = GL_RGBA8;
+ }
+ else if (config.redSize == 8 && config.greenSize == 8 && config.blueSize == 8 &&
+ config.alphaSize == 0)
+ {
+ config.renderTargetFormat = GL_RGB8;
+ }
+ else if (config.redSize == 5 && config.greenSize == 6 && config.blueSize == 5 &&
+ config.alphaSize == 0)
+ {
+ config.renderTargetFormat = GL_RGB565;
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+
+ if (config.depthSize == 0 && config.stencilSize == 0)
+ {
+ config.depthStencilFormat = GL_ZERO;
+ }
+ else if (config.depthSize == 16 && config.stencilSize == 0)
+ {
+ config.depthStencilFormat = GL_DEPTH_COMPONENT16;
+ }
+ else if (config.depthSize == 24 && config.stencilSize == 0)
+ {
+ config.depthStencilFormat = GL_DEPTH_COMPONENT24;
+ }
+ else if (config.depthSize == 24 && config.stencilSize == 8)
+ {
+ config.depthStencilFormat = GL_DEPTH24_STENCIL8;
+ }
+ else if (config.depthSize == 0 && config.stencilSize == 8)
+ {
+ config.depthStencilFormat = GL_STENCIL_INDEX8;
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+
+ config.matchNativePixmap = EGL_NONE;
+ config.optimalOrientation = 0;
+
+ int internalId = configSet.add(config);
+ mConfigIds[internalId] = config.configID;
+ }
+
+ return configSet;
+}
+
+bool DisplayAndroid::testDeviceLost()
+{
+ return false;
+}
+
+egl::Error DisplayAndroid::restoreLostDevice()
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+bool DisplayAndroid::isValidNativeWindow(EGLNativeWindowType window) const
+{
+ return ANativeWindow_getFormat(window) >= 0;
+}
+
+egl::Error DisplayAndroid::getDevice(DeviceImpl **device)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DisplayAndroid::waitClient() const
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DisplayAndroid::waitNative(EGLint engine,
+ egl::Surface *drawSurface,
+ egl::Surface *readSurface) const
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DisplayAndroid::getDriverVersion(std::string *version) const
+{
+ VendorID vendor = GetVendorID(mFunctionsGL);
+
+ switch (vendor)
+ {
+ case VENDOR_ID_QUALCOMM:
+ *version = reinterpret_cast<const char *>(mFunctionsGL->getString(GL_VERSION));
+ return egl::Error(EGL_SUCCESS);
+ default:
+ *version = "";
+ return egl::Error(EGL_SUCCESS);
+ }
+}
+
+} // namespace rx
diff --git a/gfx/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.h b/gfx/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.h
new file mode 100755
index 000000000..0be9bb465
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.h
@@ -0,0 +1,78 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// DisplayAndroid.h: Android implementation of egl::Display
+
+#ifndef LIBANGLE_RENDERER_GL_EGL_ANDROID_DISPLAYANDROID_H_
+#define LIBANGLE_RENDERER_GL_EGL_ANDROID_DISPLAYANDROID_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "libANGLE/renderer/gl/egl/DisplayEGL.h"
+
+namespace rx
+{
+
+class DisplayAndroid : public DisplayEGL
+{
+ public:
+ DisplayAndroid();
+ ~DisplayAndroid() override;
+
+ egl::Error initialize(egl::Display *display) override;
+ void terminate() override;
+
+ SurfaceImpl *createWindowSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLNativeWindowType window,
+ const egl::AttributeMap &attribs) override;
+ SurfaceImpl *createPbufferSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ const egl::AttributeMap &attribs) override;
+ SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs) override;
+ SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ NativePixmapType nativePixmap,
+ const egl::AttributeMap &attribs) override;
+
+ ImageImpl *createImage(EGLenum target,
+ egl::ImageSibling *buffer,
+ const egl::AttributeMap &attribs) override;
+
+ egl::ConfigSet generateConfigs() override;
+
+ bool testDeviceLost() override;
+ egl::Error restoreLostDevice() override;
+
+ bool isValidNativeWindow(EGLNativeWindowType window) const override;
+
+ egl::Error getDevice(DeviceImpl **device) override;
+
+ egl::Error waitClient() const override;
+ egl::Error waitNative(EGLint engine,
+ egl::Surface *drawSurface,
+ egl::Surface *readSurface) const override;
+
+ egl::Error getDriverVersion(std::string *version) const override;
+
+ private:
+ template <typename T>
+ void getConfigAttrib(EGLConfig config, EGLint attribute, T *value) const;
+
+ std::vector<EGLint> mConfigAttribList;
+ std::map<EGLint, EGLint> mConfigIds;
+ EGLSurface mDummyPbuffer;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_GL_EGL_ANDROID_DISPLAYANDROID_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/egl/functionsegl_typedefs.h b/gfx/angle/src/libANGLE/renderer/gl/egl/functionsegl_typedefs.h
new file mode 100755
index 000000000..78f9009bf
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/functionsegl_typedefs.h
@@ -0,0 +1,131 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// functionsegl_typedefs.h: Typedefs of EGL functions.
+
+#ifndef LIBANGLE_RENDERER_GL_EGL_FUNCTIONSEGLTYPEDEFS_H_
+#define LIBANGLE_RENDERER_GL_EGL_FUNCTIONSEGLTYPEDEFS_H_
+
+#include <EGL/egl.h>
+
+namespace rx
+{
+// EGL 1.0
+typedef EGLBoolean (*PFNEGLCHOOSECONFIGPROC)(EGLDisplay dpy,
+ const EGLint *attrib_list,
+ EGLConfig *configs,
+ EGLint config_size,
+ EGLint *num_config);
+typedef EGLBoolean (*PFNEGLCOPYBUFFERSPROC)(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLNativePixmapType target);
+typedef EGLContext (*PFNEGLCREATECONTEXTPROC)(EGLDisplay dpy,
+ EGLConfig config,
+ EGLContext share_context,
+ const EGLint *attrib_list);
+typedef EGLSurface (*PFNEGLCREATEPBUFFERSURFACEPROC)(EGLDisplay dpy,
+ EGLConfig config,
+ const EGLint *attrib_list);
+typedef EGLSurface (*PFNEGLCREATEPIXMAPSURFACEPROC)(EGLDisplay dpy,
+ EGLConfig config,
+ EGLNativePixmapType pixmap,
+ const EGLint *attrib_list);
+typedef EGLSurface (*PFNEGLCREATEWINDOWSURFACEPROC)(EGLDisplay dpy,
+ EGLConfig config,
+ EGLNativeWindowType win,
+ const EGLint *attrib_list);
+typedef EGLBoolean (*PFNEGLDESTROYCONTEXTPROC)(EGLDisplay dpy, EGLContext ctx);
+typedef EGLBoolean (*PFNEGLDESTROYSURFACEPROC)(EGLDisplay dpy, EGLSurface surface);
+typedef EGLBoolean (*PFNEGLGETCONFIGATTRIBPROC)(EGLDisplay dpy,
+ EGLConfig config,
+ EGLint attribute,
+ EGLint *value);
+typedef EGLBoolean (*PFNEGLGETCONFIGSPROC)(EGLDisplay dpy,
+ EGLConfig *configs,
+ EGLint config_size,
+ EGLint *num_config);
+typedef EGLDisplay (*PFNEGLGETCURRENTDISPLAYPROC)(void);
+typedef EGLSurface (*PFNEGLGETCURRENTSURFACEPROC)(EGLint readdraw);
+typedef EGLDisplay (*PFNEGLGETDISPLAYPROC)(EGLNativeDisplayType display_id);
+typedef EGLint (*PFNEGLGETERRORPROC)(void);
+typedef __eglMustCastToProperFunctionPointerType (*PFNEGLGETPROCADDRESSPROC)(const char *procname);
+typedef EGLBoolean (*PFNEGLINITIALIZEPROC)(EGLDisplay dpy, EGLint *major, EGLint *minor);
+typedef EGLBoolean (*PFNEGLMAKECURRENTPROC)(EGLDisplay dpy,
+ EGLSurface draw,
+ EGLSurface read,
+ EGLContext ctx);
+typedef EGLBoolean (*PFNEGLQUERYCONTEXTPROC)(EGLDisplay dpy,
+ EGLContext ctx,
+ EGLint attribute,
+ EGLint *value);
+typedef const char *(*PFNEGLQUERYSTRINGPROC)(EGLDisplay dpy, EGLint name);
+typedef EGLBoolean (*PFNEGLQUERYSURFACEPROC)(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint attribute,
+ EGLint *value);
+typedef EGLBoolean (*PFNEGLSWAPBUFFERSPROC)(EGLDisplay dpy, EGLSurface surface);
+typedef EGLBoolean (*PFNEGLTERMINATEPROC)(EGLDisplay dpy);
+typedef EGLBoolean (*PFNEGLWAITGLPROC)(void);
+typedef EGLBoolean (*PFNEGLWAITNATIVEPROC)(EGLint engine);
+
+// EGL 1.1
+typedef EGLBoolean (*PFNEGLBINDTEXIMAGEPROC)(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+typedef EGLBoolean (*PFNEGLRELEASETEXIMAGEPROC)(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+typedef EGLBoolean (*PFNEGLSURFACEATTRIBPROC)(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint attribute,
+ EGLint value);
+typedef EGLBoolean (*PFNEGLSWAPINTERVALPROC)(EGLDisplay dpy, EGLint interval);
+
+// EGL 1.2
+typedef EGLBoolean (*PFNEGLBINDAPIPROC)(EGLenum api);
+typedef EGLenum (*PFNEGLQUERYAPIPROC)(void);
+typedef EGLSurface (*PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC)(EGLDisplay dpy,
+ EGLenum buftype,
+ EGLClientBuffer buffer,
+ EGLConfig config,
+ const EGLint *attrib_list);
+typedef EGLBoolean (*PFNEGLRELEASETHREADPROC)(void);
+typedef EGLBoolean (*PFNEGLWAITCLIENTPROC)(void);
+
+// EGL 1.3
+
+// EGL 1.4
+typedef EGLContext (*PFNEGLGETCURRENTCONTEXTPROC)(void);
+
+// EGL 1.5
+typedef EGLSync (*PFNEGLCREATESYNCPROC)(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list);
+typedef EGLBoolean (*PFNEGLDESTROYSYNCPROC)(EGLDisplay dpy, EGLSync sync);
+typedef EGLint (*PFNEGLCLIENTWAITSYNCPROC)(EGLDisplay dpy,
+ EGLSync sync,
+ EGLint flags,
+ EGLTime timeout);
+typedef EGLBoolean (*PFNEGLGETSYNCATTRIBPROC)(EGLDisplay dpy,
+ EGLSync sync,
+ EGLint attribute,
+ EGLAttrib *value);
+typedef EGLImage (*PFNEGLCREATEIMAGEPROC)(EGLDisplay dpy,
+ EGLContext ctx,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const EGLAttrib *attrib_list);
+typedef EGLBoolean (*PFNEGLDESTROYIMAGEPROC)(EGLDisplay dpy, EGLImage image);
+typedef EGLDisplay (*PFNEGLGETPLATFORMDISPLAYPROC)(EGLenum platform,
+ void *native_display,
+ const EGLAttrib *attrib_list);
+typedef EGLSurface (*PFNEGLCREATEPLATFORMWINDOWSURFACEPROC)(EGLDisplay dpy,
+ EGLConfig config,
+ void *native_window,
+ const EGLAttrib *attrib_list);
+typedef EGLSurface (*PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC)(EGLDisplay dpy,
+ EGLConfig config,
+ void *native_pixmap,
+ const EGLAttrib *attrib_list);
+typedef EGLBoolean (*PFNEGLWAITSYNCPROC)(EGLDisplay dpy, EGLSync sync, EGLint flags);
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_GL_EGL_FUNCTIONSEGLTYPEDEFS_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/egl/ozone/DisplayOzone.cpp b/gfx/angle/src/libANGLE/renderer/gl/egl/ozone/DisplayOzone.cpp
new file mode 100755
index 000000000..01549fcfa
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/ozone/DisplayOzone.cpp
@@ -0,0 +1,945 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// DisplayOzone.cpp: Ozone implementation of egl::Display
+
+#include "libANGLE/renderer/gl/egl/ozone/DisplayOzone.h"
+
+#include <fcntl.h>
+#include <poll.h>
+#include <iostream>
+#include <unistd.h>
+#include <sys/time.h>
+
+#include <EGL/eglext.h>
+
+#include <gbm.h>
+#include <drm_fourcc.h>
+
+#include "common/debug.h"
+#include "libANGLE/Config.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/renderer/gl/FramebufferGL.h"
+#include "libANGLE/renderer/gl/RendererGL.h"
+#include "libANGLE/renderer/gl/StateManagerGL.h"
+#include "libANGLE/renderer/gl/egl/FunctionsEGLDL.h"
+#include "libANGLE/renderer/gl/egl/ozone/SurfaceOzone.h"
+#include "platform/Platform.h"
+
+// ARM-specific extension needed to make Mali GPU behave - not in any
+// published header file.
+#ifndef EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM
+#define EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM 0x328A
+#endif
+
+#ifndef EGL_NO_CONFIG_MESA
+#define EGL_NO_CONFIG_MESA ((EGLConfig)0)
+#endif
+
+namespace
+{
+
+EGLint UnsignedToSigned(uint32_t u)
+{
+ return *reinterpret_cast<const EGLint *>(&u);
+}
+
+drmModeModeInfoPtr ChooseMode(drmModeConnectorPtr conn)
+{
+ drmModeModeInfoPtr mode = nullptr;
+ ASSERT(conn);
+ ASSERT(conn->connection == DRM_MODE_CONNECTED);
+ // use first preferred mode if any, else end up with last mode in list
+ for (int i = 0; i < conn->count_modes; ++i)
+ {
+ mode = conn->modes + i;
+ if (mode->type & DRM_MODE_TYPE_PREFERRED)
+ {
+ break;
+ }
+ }
+ return mode;
+}
+
+int ChooseCRTC(int fd, drmModeConnectorPtr conn)
+{
+ for (int i = 0; i < conn->count_encoders; ++i)
+ {
+ drmModeEncoderPtr enc = drmModeGetEncoder(fd, conn->encoders[i]);
+ unsigned long crtcs = enc->possible_crtcs;
+ drmModeFreeEncoder(enc);
+ if (crtcs)
+ {
+ return __builtin_ctzl(crtcs);
+ }
+ }
+ return -1;
+}
+} // namespace
+
+namespace rx
+{
+
+// TODO(fjhenigman) Implement swap control. Until then this is unused.
+SwapControlData::SwapControlData()
+ : targetSwapInterval(0), maxSwapInterval(-1), currentSwapInterval(-1)
+{
+}
+
+DisplayOzone::Buffer::Buffer(DisplayOzone *display,
+ uint32_t useFlags,
+ uint32_t gbmFormat,
+ uint32_t drmFormat,
+ uint32_t drmFormatFB,
+ int depthBits,
+ int stencilBits)
+ : mDisplay(display),
+ mNative(nullptr),
+ mWidth(0),
+ mHeight(0),
+ mDepthBits(depthBits),
+ mStencilBits(stencilBits),
+ mUseFlags(useFlags),
+ mGBMFormat(gbmFormat),
+ mDRMFormat(drmFormat),
+ mDRMFormatFB(drmFormatFB),
+ mBO(nullptr),
+ mDMABuf(-1),
+ mHasDRMFB(false),
+ mDRMFB(0),
+ mImage(EGL_NO_IMAGE_KHR),
+ mColorBuffer(0),
+ mDSBuffer(0),
+ mGLFB(0),
+ mTexture(0)
+{
+}
+
+DisplayOzone::Buffer::~Buffer()
+{
+ mDisplay->mFunctionsGL->deleteFramebuffers(1, &mGLFB);
+ reset();
+}
+
+void DisplayOzone::Buffer::reset()
+{
+ if (mHasDRMFB)
+ {
+ int fd = gbm_device_get_fd(mDisplay->mGBM);
+ drmModeRmFB(fd, mDRMFB);
+ mHasDRMFB = false;
+ }
+
+ FunctionsGL *gl = mDisplay->mFunctionsGL;
+ gl->deleteRenderbuffers(1, &mColorBuffer);
+ mColorBuffer = 0;
+ gl->deleteRenderbuffers(1, &mDSBuffer);
+ mDSBuffer = 0;
+
+ // Here we might destroy the GL framebuffer (mGLFB) but unlike every other resource in Buffer,
+ // it does not get destroyed (and recreated) because when it is the default framebuffer for
+ // an ANGLE surface then ANGLE expects it to have the same lifetime as that surface.
+
+ if (mImage != EGL_NO_IMAGE_KHR)
+ {
+ mDisplay->mEGL->destroyImageKHR(mImage);
+ mImage = EGL_NO_IMAGE_KHR;
+ }
+
+ if (mTexture)
+ {
+ gl->deleteTextures(1, &mTexture);
+ mTexture = 0;
+ }
+
+ if (mDMABuf >= 0)
+ {
+ close(mDMABuf);
+ mDMABuf = -1;
+ }
+
+ if (mBO)
+ {
+ gbm_bo_destroy(mBO);
+ mBO = nullptr;
+ }
+}
+
+bool DisplayOzone::Buffer::resize(int32_t width, int32_t height)
+{
+ if (mWidth == width && mHeight == height)
+ {
+ return true;
+ }
+
+ reset();
+
+ if (width <= 0 || height <= 0)
+ {
+ return true;
+ }
+
+ mBO = gbm_bo_create(mDisplay->mGBM, width, height, mGBMFormat, mUseFlags);
+ if (!mBO)
+ {
+ return false;
+ }
+
+ mDMABuf = gbm_bo_get_fd(mBO);
+ if (mDMABuf < 0)
+ {
+ return false;
+ }
+
+ // clang-format off
+ const EGLint attr[] =
+ {
+ EGL_WIDTH, width,
+ EGL_HEIGHT, height,
+ EGL_LINUX_DRM_FOURCC_EXT, UnsignedToSigned(mDRMFormat),
+ EGL_DMA_BUF_PLANE0_FD_EXT, mDMABuf,
+ EGL_DMA_BUF_PLANE0_PITCH_EXT, UnsignedToSigned(gbm_bo_get_stride(mBO)),
+ EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
+ EGL_NONE,
+ };
+ // clang-format on
+
+ mImage = mDisplay->mEGL->createImageKHR(EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, nullptr, attr);
+ if (mImage == EGL_NO_IMAGE_KHR)
+ {
+ return false;
+ }
+
+ FunctionsGL *gl = mDisplay->mFunctionsGL;
+ StateManagerGL *sm = mDisplay->getRenderer()->getStateManager();
+
+ gl->genRenderbuffers(1, &mColorBuffer);
+ sm->bindRenderbuffer(GL_RENDERBUFFER, mColorBuffer);
+ gl->eglImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, mImage);
+
+ sm->bindFramebuffer(GL_FRAMEBUFFER, mGLFB);
+ gl->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER,
+ mColorBuffer);
+
+ if (mDepthBits || mStencilBits)
+ {
+ gl->genRenderbuffers(1, &mDSBuffer);
+ sm->bindRenderbuffer(GL_RENDERBUFFER, mDSBuffer);
+ gl->renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height);
+ }
+
+ if (mDepthBits)
+ {
+ gl->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
+ mDSBuffer);
+ }
+
+ if (mStencilBits)
+ {
+ gl->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
+ mDSBuffer);
+ }
+
+ mWidth = width;
+ mHeight = height;
+ return true;
+}
+
+bool DisplayOzone::Buffer::initialize(const NativeWindow *native)
+{
+ mNative = native;
+ mDisplay->mFunctionsGL->genFramebuffers(1, &mGLFB);
+ return resize(native->width, native->height);
+}
+
+bool DisplayOzone::Buffer::initialize(int width, int height)
+{
+ mDisplay->mFunctionsGL->genFramebuffers(1, &mGLFB);
+ return resize(width, height);
+}
+
+void DisplayOzone::Buffer::bindTexImage()
+{
+ mDisplay->mFunctionsGL->eglImageTargetTexture2DOES(GL_TEXTURE_2D, mImage);
+}
+
+GLuint DisplayOzone::Buffer::getTexture()
+{
+ // TODO(fjhenigman) Try not to create a new texture every time. That already works on Intel
+ // and should work on Mali with proper fences.
+ FunctionsGL *gl = mDisplay->mFunctionsGL;
+ StateManagerGL *sm = mDisplay->getRenderer()->getStateManager();
+
+ gl->genTextures(1, &mTexture);
+ sm->bindTexture(GL_TEXTURE_2D, mTexture);
+ gl->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ gl->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ gl->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ gl->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ ASSERT(mImage != EGL_NO_IMAGE_KHR);
+ gl->eglImageTargetTexture2DOES(GL_TEXTURE_2D, mImage);
+ return mTexture;
+}
+
+uint32_t DisplayOzone::Buffer::getDRMFB()
+{
+ if (!mHasDRMFB)
+ {
+ int fd = gbm_device_get_fd(mDisplay->mGBM);
+ uint32_t handles[4] = {gbm_bo_get_handle(mBO).u32};
+ uint32_t pitches[4] = {gbm_bo_get_stride(mBO)};
+ uint32_t offsets[4] = {0};
+ if (drmModeAddFB2(fd, mWidth, mHeight, mDRMFormatFB, handles, pitches, offsets, &mDRMFB, 0))
+ {
+ std::cerr << "drmModeAddFB2 failed" << std::endl;
+ }
+ else
+ {
+ mHasDRMFB = true;
+ }
+ }
+
+ return mDRMFB;
+}
+
+FramebufferGL *DisplayOzone::Buffer::framebufferGL(const gl::FramebufferState &state)
+{
+ return new FramebufferGL(
+ mGLFB, state, mDisplay->mFunctionsGL, mDisplay->getRenderer()->getWorkarounds(),
+ mDisplay->getRenderer()->getBlitter(), mDisplay->getRenderer()->getStateManager());
+}
+
+void DisplayOzone::Buffer::present()
+{
+ if (mNative)
+ {
+ if (mNative->visible)
+ {
+ mDisplay->drawBuffer(this);
+ }
+ resize(mNative->width, mNative->height);
+ }
+}
+
+DisplayOzone::DisplayOzone()
+ : DisplayEGL(),
+ mSwapControl(SwapControl::ABSENT),
+ mMinSwapInterval(0),
+ mMaxSwapInterval(0),
+ mCurrentSwapInterval(-1),
+ mGBM(nullptr),
+ mConnector(nullptr),
+ mMode(nullptr),
+ mCRTC(nullptr),
+ mSetCRTC(true),
+ mWidth(0),
+ mHeight(0),
+ mScanning(nullptr),
+ mPending(nullptr),
+ mDrawing(nullptr),
+ mUnused(nullptr),
+ mProgram(0),
+ mVertexShader(0),
+ mFragmentShader(0),
+ mVertexBuffer(0),
+ mIndexBuffer(0),
+ mCenterUniform(0),
+ mWindowSizeUniform(0),
+ mBorderSizeUniform(0),
+ mDepthUniform(0)
+{
+}
+
+DisplayOzone::~DisplayOzone()
+{
+}
+
+egl::Error DisplayOzone::initialize(egl::Display *display)
+{
+ int fd;
+ char deviceName[30];
+ drmModeResPtr resources = nullptr;
+
+ for (int i = 0; i < 9; ++i)
+ {
+ snprintf(deviceName, sizeof(deviceName), "/dev/dri/card%d", i);
+ fd = open(deviceName, O_RDWR | O_CLOEXEC);
+ if (fd >= 0)
+ {
+ resources = drmModeGetResources(fd);
+ if (resources)
+ {
+ if (resources->count_connectors > 0)
+ {
+ break;
+ }
+ drmModeFreeResources(resources);
+ resources = nullptr;
+ }
+ close(fd);
+ }
+ }
+ if (!resources)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Could not open drm device.");
+ }
+
+ mGBM = gbm_create_device(fd);
+ if (!mGBM)
+ {
+ close(fd);
+ drmModeFreeResources(resources);
+ return egl::Error(EGL_NOT_INITIALIZED, "Could not create gbm device.");
+ }
+
+ mConnector = nullptr;
+ bool monitorConnected = false;
+ for (int i = 0; !mCRTC && i < resources->count_connectors; ++i)
+ {
+ drmModeFreeConnector(mConnector);
+ mConnector = drmModeGetConnector(fd, resources->connectors[i]);
+ if (!mConnector || mConnector->connection != DRM_MODE_CONNECTED)
+ {
+ continue;
+ }
+ monitorConnected = true;
+ mMode = ChooseMode(mConnector);
+ if (!mMode)
+ {
+ continue;
+ }
+ int n = ChooseCRTC(fd, mConnector);
+ if (n < 0)
+ {
+ continue;
+ }
+ mCRTC = drmModeGetCrtc(fd, resources->crtcs[n]);
+ }
+ drmModeFreeResources(resources);
+
+ if (mCRTC)
+ {
+ mWidth = mMode->hdisplay;
+ mHeight = mMode->vdisplay;
+ }
+ else if (!monitorConnected)
+ {
+ // Even though there is no monitor to show it, we still do
+ // everything the same as if there were one, so we need an
+ // arbitrary size for our buffers.
+ mWidth = 1280;
+ mHeight = 1024;
+ }
+ else
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Failed to choose mode/crtc.");
+ }
+
+ // ANGLE builds its executables with an RPATH so they pull in ANGLE's libGL and libEGL.
+ // Here we need to open the native libEGL. An absolute path would work, but then we
+ // couldn't use LD_LIBRARY_PATH which is often useful during development. Instead we take
+ // advantage of the fact that the system lib is available under multiple names (for example
+ // with a .1 suffix) while Angle only installs libEGL.so.
+ FunctionsEGLDL *egl = new FunctionsEGLDL();
+ mEGL = egl;
+ ANGLE_TRY(egl->initialize(display->getNativeDisplayId(), "libEGL.so.1"));
+
+ const char *necessaryExtensions[] = {
+ "EGL_KHR_image_base", "EGL_EXT_image_dma_buf_import", "EGL_KHR_surfaceless_context",
+ };
+ for (auto &ext : necessaryExtensions)
+ {
+ if (!mEGL->hasExtension(ext))
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "need %s", ext);
+ }
+ }
+
+ if (mEGL->hasExtension("EGL_MESA_configless_context"))
+ {
+ mConfig = EGL_NO_CONFIG_MESA;
+ }
+ else
+ {
+ // clang-format off
+ const EGLint attrib[] =
+ {
+ // We want RGBA8 and DEPTH24_STENCIL8
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_DEPTH_SIZE, 24,
+ EGL_STENCIL_SIZE, 8,
+ EGL_NONE,
+ };
+ // clang-format on
+ EGLint numConfig;
+ EGLConfig config[1];
+ if (!mEGL->chooseConfig(attrib, config, 1, &numConfig) || numConfig < 1)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Could not get EGL config.");
+ }
+ mConfig = config[0];
+ }
+
+ ANGLE_TRY(initializeContext(display->getAttributeMap()));
+
+ if (!mEGL->makeCurrent(EGL_NO_SURFACE, mContext))
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Could not make context current.");
+ }
+
+ mFunctionsGL = mEGL->makeFunctionsGL();
+ mFunctionsGL->initialize();
+
+ return DisplayGL::initialize(display);
+}
+
+void DisplayOzone::pageFlipHandler(int fd,
+ unsigned int sequence,
+ unsigned int tv_sec,
+ unsigned int tv_usec,
+ void *data)
+{
+ DisplayOzone *display = reinterpret_cast<DisplayOzone *>(data);
+ uint64_t tv = tv_sec;
+ display->pageFlipHandler(sequence, tv * 1000000 + tv_usec);
+}
+
+void DisplayOzone::pageFlipHandler(unsigned int sequence, uint64_t tv)
+{
+ ASSERT(mPending);
+ mUnused = mScanning;
+ mScanning = mPending;
+ mPending = nullptr;
+}
+
+void DisplayOzone::presentScreen()
+{
+ if (!mCRTC)
+ {
+ // no monitor
+ return;
+ }
+
+ // see if pending flip has finished, without blocking
+ int fd = gbm_device_get_fd(mGBM);
+ if (mPending)
+ {
+ pollfd pfd;
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+ if (poll(&pfd, 1, 0) < 0)
+ {
+ std::cerr << "poll failed: " << errno << " " << strerror(errno) << std::endl;
+ }
+ if (pfd.revents & POLLIN)
+ {
+ drmEventContext event;
+ event.version = DRM_EVENT_CONTEXT_VERSION;
+ event.page_flip_handler = pageFlipHandler;
+ drmHandleEvent(fd, &event);
+ }
+ }
+
+ // if pending flip has finished, schedule next one
+ if (!mPending && mDrawing)
+ {
+ flushGL();
+ if (mSetCRTC)
+ {
+ if (drmModeSetCrtc(fd, mCRTC->crtc_id, mDrawing->getDRMFB(), 0, 0,
+ &mConnector->connector_id, 1, mMode))
+ {
+ std::cerr << "set crtc failed: " << errno << " " << strerror(errno) << std::endl;
+ }
+ mSetCRTC = false;
+ }
+ if (drmModePageFlip(fd, mCRTC->crtc_id, mDrawing->getDRMFB(), DRM_MODE_PAGE_FLIP_EVENT,
+ this))
+ {
+ std::cerr << "page flip failed: " << errno << " " << strerror(errno) << std::endl;
+ }
+ mPending = mDrawing;
+ mDrawing = nullptr;
+ }
+}
+
+GLuint DisplayOzone::makeShader(GLuint type, const char *src)
+{
+ FunctionsGL *gl = mFunctionsGL;
+ GLuint shader = gl->createShader(type);
+ gl->shaderSource(shader, 1, &src, nullptr);
+ gl->compileShader(shader);
+
+ GLchar buf[999];
+ GLsizei len;
+ GLint compiled;
+ gl->getShaderInfoLog(shader, sizeof(buf), &len, buf);
+ gl->getShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+ if (compiled != GL_TRUE)
+ {
+ ANGLEPlatformCurrent()->logError("DisplayOzone shader compilation error:");
+ ANGLEPlatformCurrent()->logError(buf);
+ }
+
+ return shader;
+}
+
+void DisplayOzone::drawWithTexture(Buffer *buffer)
+{
+ FunctionsGL *gl = mFunctionsGL;
+ StateManagerGL *sm = getRenderer()->getStateManager();
+
+ if (!mProgram)
+ {
+ const GLchar *vertexSource =
+ "#version 100\n"
+ "attribute vec3 vertex;\n"
+ "uniform vec2 center;\n"
+ "uniform vec2 windowSize;\n"
+ "uniform vec2 borderSize;\n"
+ "uniform float depth;\n"
+ "varying vec3 texCoord;\n"
+ "void main()\n"
+ "{\n"
+ " vec2 pos = vertex.xy * (windowSize + borderSize * vertex.z);\n"
+ " gl_Position = vec4(center + pos, depth, 1);\n"
+ " texCoord = vec3(pos / windowSize * vec2(.5, -.5) + vec2(.5, .5), vertex.z);\n"
+ "}\n";
+
+ const GLchar *fragmentSource =
+ "#version 100\n"
+ "precision mediump float;\n"
+ "uniform sampler2D tex;\n"
+ "varying vec3 texCoord;\n"
+ "void main()\n"
+ "{\n"
+ " if (texCoord.z > 0.)\n"
+ " {\n"
+ " float c = abs((texCoord.z * 2.) - 1.);\n"
+ " gl_FragColor = vec4(c, c, c, 1);\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " gl_FragColor = texture2D(tex, texCoord.xy);\n"
+ " }\n"
+ "}\n";
+
+ mVertexShader = makeShader(GL_VERTEX_SHADER, vertexSource);
+ mFragmentShader = makeShader(GL_FRAGMENT_SHADER, fragmentSource);
+ mProgram = gl->createProgram();
+ gl->attachShader(mProgram, mVertexShader);
+ gl->attachShader(mProgram, mFragmentShader);
+ gl->bindAttribLocation(mProgram, 0, "vertex");
+ gl->linkProgram(mProgram);
+ GLint linked;
+ gl->getProgramiv(mProgram, GL_LINK_STATUS, &linked);
+ ASSERT(linked);
+ mCenterUniform = gl->getUniformLocation(mProgram, "center");
+ mWindowSizeUniform = gl->getUniformLocation(mProgram, "windowSize");
+ mBorderSizeUniform = gl->getUniformLocation(mProgram, "borderSize");
+ mDepthUniform = gl->getUniformLocation(mProgram, "depth");
+ GLint texUniform = gl->getUniformLocation(mProgram, "tex");
+ sm->useProgram(mProgram);
+ gl->uniform1i(texUniform, 0);
+
+ // clang-format off
+ const GLfloat vertices[] =
+ {
+ // window corners, and window border inside corners
+ 1, -1, 0,
+ -1, -1, 0,
+ 1, 1, 0,
+ -1, 1, 0,
+ // window border outside corners
+ 1, -1, 1,
+ -1, -1, 1,
+ 1, 1, 1,
+ -1, 1, 1,
+ };
+ // clang-format on
+ gl->genBuffers(1, &mVertexBuffer);
+ sm->bindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
+ gl->bufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
+
+ // window border triangle strip
+ const GLuint borderStrip[] = {5, 0, 4, 2, 6, 3, 7, 1, 5, 0};
+
+ gl->genBuffers(1, &mIndexBuffer);
+ sm->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
+ gl->bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(borderStrip), borderStrip, GL_STATIC_DRAW);
+ }
+ else
+ {
+ sm->useProgram(mProgram);
+ sm->bindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
+ sm->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
+ }
+
+ // convert from pixels to "-1 to 1" space
+ const NativeWindow *n = buffer->getNative();
+ double x = n->x * 2. / mWidth - 1;
+ double y = n->y * 2. / mHeight - 1;
+ double halfw = n->width * 1. / mWidth;
+ double halfh = n->height * 1. / mHeight;
+ double borderw = n->borderWidth * 2. / mWidth;
+ double borderh = n->borderHeight * 2. / mHeight;
+
+ gl->uniform2f(mCenterUniform, x + halfw, y + halfh);
+ gl->uniform2f(mWindowSizeUniform, halfw, halfh);
+ gl->uniform2f(mBorderSizeUniform, borderw, borderh);
+ gl->uniform1f(mDepthUniform, n->depth / 1e6);
+
+ sm->setBlendEnabled(false);
+ sm->setCullFaceEnabled(false);
+ sm->setStencilTestEnabled(false);
+ sm->setScissorTestEnabled(false);
+ sm->setDepthTestEnabled(true);
+ sm->setColorMask(true, true, true, true);
+ sm->setDepthMask(true);
+ sm->setDepthRange(0, 1);
+ sm->setDepthFunc(GL_LESS);
+ sm->setViewport(gl::Rectangle(0, 0, mWidth, mHeight));
+ sm->activeTexture(0);
+ GLuint tex = buffer->getTexture();
+ sm->bindTexture(GL_TEXTURE_2D, tex);
+ gl->vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
+ gl->enableVertexAttribArray(0);
+ sm->bindFramebuffer(GL_DRAW_FRAMEBUFFER, mDrawing->getGLFB());
+ gl->drawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ gl->drawElements(GL_TRIANGLE_STRIP, 10, GL_UNSIGNED_INT, 0);
+ sm->deleteTexture(tex);
+}
+
+void DisplayOzone::drawBuffer(Buffer *buffer)
+{
+ if (!mDrawing)
+ {
+ // get buffer on which to draw window
+ if (mUnused)
+ {
+ mDrawing = mUnused;
+ mUnused = nullptr;
+ }
+ else
+ {
+ mDrawing = new Buffer(this, GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT,
+ GBM_FORMAT_ARGB8888, DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888,
+ true, true); // XXX shouldn't need stencil
+ if (!mDrawing || !mDrawing->initialize(mWidth, mHeight))
+ {
+ return;
+ }
+ }
+
+ StateManagerGL *sm = getRenderer()->getStateManager();
+ sm->bindFramebuffer(GL_DRAW_FRAMEBUFFER, mDrawing->getGLFB());
+ sm->setClearColor(gl::ColorF(0, 0, 0, 1));
+ sm->setClearDepth(1);
+ sm->setScissorTestEnabled(false);
+ sm->setColorMask(true, true, true, true);
+ sm->setDepthMask(true);
+ mFunctionsGL->clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ }
+
+ drawWithTexture(buffer);
+ presentScreen();
+}
+
+void DisplayOzone::flushGL()
+{
+ mFunctionsGL->flush();
+ if (mEGL->hasExtension("EGL_KHR_fence_sync"))
+ {
+ const EGLint attrib[] = {EGL_SYNC_CONDITION_KHR,
+ EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM, EGL_NONE};
+ EGLSyncKHR fence = mEGL->createSyncKHR(EGL_SYNC_FENCE_KHR, attrib);
+ if (fence)
+ {
+ // TODO(fjhenigman) Figure out the right way to use fences on Mali GPU
+ // to maximize throughput and avoid hangs when a program is interrupted.
+ // This busy wait was an attempt to reduce hangs when interrupted by SIGINT,
+ // but we still get some.
+ for (;;)
+ {
+ EGLint r = mEGL->clientWaitSyncKHR(fence, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 0);
+ if (r != EGL_TIMEOUT_EXPIRED_KHR)
+ {
+ break;
+ }
+ usleep(99);
+ }
+ mEGL->destroySyncKHR(fence);
+ return;
+ }
+ }
+}
+
+void DisplayOzone::terminate()
+{
+ SafeDelete(mScanning);
+ SafeDelete(mPending);
+ SafeDelete(mDrawing);
+ SafeDelete(mUnused);
+
+ if (mProgram)
+ {
+ mFunctionsGL->deleteProgram(mProgram);
+ mFunctionsGL->deleteShader(mVertexShader);
+ mFunctionsGL->deleteShader(mFragmentShader);
+ mFunctionsGL->deleteBuffers(1, &mVertexBuffer);
+ mFunctionsGL->deleteBuffers(1, &mIndexBuffer);
+ mProgram = 0;
+ }
+
+ DisplayGL::terminate();
+
+ if (mContext)
+ {
+ // Mesa might crash if you terminate EGL with a context current
+ // then re-initialize EGL, so make our context not current.
+ mEGL->makeCurrent(EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ mEGL->destroyContext(mContext);
+ mContext = nullptr;
+ }
+
+ SafeDelete(mFunctionsGL);
+
+ if (mEGL)
+ {
+ mEGL->terminate();
+ SafeDelete(mEGL);
+ }
+
+ drmModeFreeCrtc(mCRTC);
+
+ if (mGBM)
+ {
+ int fd = gbm_device_get_fd(mGBM);
+ gbm_device_destroy(mGBM);
+ mGBM = nullptr;
+ close(fd);
+ }
+}
+
+SurfaceImpl *DisplayOzone::createWindowSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLNativeWindowType window,
+ const egl::AttributeMap &attribs)
+{
+ Buffer *buffer = new Buffer(this, GBM_BO_USE_RENDERING, GBM_FORMAT_ARGB8888,
+ DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888, true, true);
+ if (!buffer || !buffer->initialize(reinterpret_cast<const NativeWindow *>(window)))
+ {
+ return nullptr;
+ }
+ return new SurfaceOzone(state, getRenderer(), buffer);
+}
+
+SurfaceImpl *DisplayOzone::createPbufferSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ const egl::AttributeMap &attribs)
+{
+ EGLAttrib width = attribs.get(EGL_WIDTH, 0);
+ EGLAttrib height = attribs.get(EGL_HEIGHT, 0);
+ Buffer *buffer = new Buffer(this, GBM_BO_USE_RENDERING, GBM_FORMAT_ARGB8888,
+ DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888, true, true);
+ if (!buffer || !buffer->initialize(width, height))
+ {
+ return nullptr;
+ }
+ return new SurfaceOzone(state, getRenderer(), buffer);
+}
+
+SurfaceImpl *DisplayOzone::createPbufferFromClientBuffer(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs)
+{
+ UNIMPLEMENTED();
+ return nullptr;
+}
+
+SurfaceImpl *DisplayOzone::createPixmapSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ NativePixmapType nativePixmap,
+ const egl::AttributeMap &attribs)
+{
+ UNIMPLEMENTED();
+ return nullptr;
+}
+
+egl::Error DisplayOzone::getDevice(DeviceImpl **device)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_BAD_DISPLAY);
+}
+
+egl::ConfigSet DisplayOzone::generateConfigs()
+{
+ egl::ConfigSet configs;
+
+ egl::Config config;
+ config.redSize = 8;
+ config.greenSize = 8;
+ config.blueSize = 8;
+ config.alphaSize = 8;
+ config.depthSize = 24;
+ config.stencilSize = 8;
+ config.bindToTextureRGBA = EGL_TRUE;
+ config.renderableType = EGL_OPENGL_ES2_BIT;
+ config.surfaceType = EGL_WINDOW_BIT | EGL_PBUFFER_BIT;
+
+ configs.add(config);
+ return configs;
+}
+
+bool DisplayOzone::testDeviceLost()
+{
+ return false;
+}
+
+egl::Error DisplayOzone::restoreLostDevice()
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_BAD_DISPLAY);
+}
+
+bool DisplayOzone::isValidNativeWindow(EGLNativeWindowType window) const
+{
+ return true;
+}
+
+egl::Error DisplayOzone::getDriverVersion(std::string *version) const
+{
+ *version = "";
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DisplayOzone::waitClient() const
+{
+ // TODO(fjhenigman) Implement this.
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DisplayOzone::waitNative(EGLint engine,
+ egl::Surface *drawSurface,
+ egl::Surface *readSurface) const
+{
+ // TODO(fjhenigman) Implement this.
+ return egl::Error(EGL_SUCCESS);
+}
+
+void DisplayOzone::setSwapInterval(EGLSurface drawable, SwapControlData *data)
+{
+ ASSERT(data != nullptr);
+}
+
+} // namespace rx
diff --git a/gfx/angle/src/libANGLE/renderer/gl/egl/ozone/DisplayOzone.h b/gfx/angle/src/libANGLE/renderer/gl/egl/ozone/DisplayOzone.h
new file mode 100755
index 000000000..77c669314
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/ozone/DisplayOzone.h
@@ -0,0 +1,211 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// DisplayOzone.h: Ozone implementation of egl::Display
+
+#ifndef LIBANGLE_RENDERER_GL_EGL_OZONE_DISPLAYOZONE_H_
+#define LIBANGLE_RENDERER_GL_EGL_OZONE_DISPLAYOZONE_H_
+
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+
+#include <string>
+
+#include "libANGLE/renderer/gl/egl/DisplayEGL.h"
+
+struct gbm_device;
+struct gbm_bo;
+
+namespace gl
+{
+class FramebufferState;
+}
+
+namespace rx
+{
+
+class FramebufferGL;
+
+// TODO(fjhenigman) Implement swap control. The following struct will be used for that.
+// State-tracking data for the swap control to allow DisplayOzone to remember per
+// drawable information for swap control.
+struct SwapControlData final
+{
+ SwapControlData();
+
+ // Set by the drawable
+ int targetSwapInterval;
+
+ // DisplayOzone-side state-tracking
+ int maxSwapInterval;
+ int currentSwapInterval;
+};
+
+class DisplayOzone final : public DisplayEGL
+{
+ public:
+ struct NativeWindow
+ {
+ int32_t x;
+ int32_t y;
+ int32_t width;
+ int32_t height;
+ int32_t borderWidth;
+ int32_t borderHeight;
+ int32_t visible;
+ int32_t depth;
+ };
+
+ class Buffer final : angle::NonCopyable
+ {
+ public:
+ Buffer(DisplayOzone *display,
+ uint32_t useFlags,
+ uint32_t gbmFormat,
+ uint32_t drmFormat,
+ uint32_t drmFormatFB,
+ int depthBits,
+ int stencilBits);
+
+ ~Buffer();
+ bool initialize(const NativeWindow *window);
+ bool initialize(int32_t width, int32_t height);
+ void reset();
+ bool resize(int32_t width, int32_t height);
+ FramebufferGL *framebufferGL(const gl::FramebufferState &state);
+ void present();
+ uint32_t getDRMFB();
+ void bindTexImage();
+ GLuint getTexture();
+ int32_t getWidth() const { return mWidth; }
+ int32_t getHeight() const { return mHeight; }
+ GLuint getGLFB() const { return mGLFB; }
+ const NativeWindow *getNative() const { return mNative; }
+
+ private:
+ DisplayOzone *mDisplay;
+ const NativeWindow *mNative;
+ int mWidth;
+ int mHeight;
+ const int mDepthBits;
+ const int mStencilBits;
+ const uint32_t mUseFlags;
+ const uint32_t mGBMFormat;
+ const uint32_t mDRMFormat;
+ const uint32_t mDRMFormatFB;
+ gbm_bo *mBO;
+ int mDMABuf;
+ bool mHasDRMFB;
+ uint32_t mDRMFB;
+ EGLImageKHR mImage;
+ GLuint mColorBuffer;
+ GLuint mDSBuffer;
+ GLuint mGLFB;
+ GLuint mTexture;
+ };
+
+ DisplayOzone();
+ ~DisplayOzone() override;
+
+ egl::Error initialize(egl::Display *display) override;
+ void terminate() override;
+
+ SurfaceImpl *createWindowSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLNativeWindowType window,
+ const egl::AttributeMap &attribs) override;
+ SurfaceImpl *createPbufferSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ const egl::AttributeMap &attribs) override;
+ SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs) override;
+ SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ NativePixmapType nativePixmap,
+ const egl::AttributeMap &attribs) override;
+
+ egl::ConfigSet generateConfigs() override;
+
+ bool testDeviceLost() override;
+ egl::Error restoreLostDevice() override;
+
+ bool isValidNativeWindow(EGLNativeWindowType window) const override;
+
+ egl::Error getDevice(DeviceImpl **device) override;
+
+ egl::Error waitClient() const override;
+ egl::Error waitNative(EGLint engine,
+ egl::Surface *drawSurface,
+ egl::Surface *readSurface) const override;
+
+ // TODO(fjhenigman) Implement this.
+ // Swap interval can be set globally or per drawable.
+ // This function will make sure the drawable's swap interval is the
+ // one required so that the subsequent swapBuffers acts as expected.
+ void setSwapInterval(EGLSurface drawable, SwapControlData *data);
+
+ egl::Error getDriverVersion(std::string *version) const override;
+
+ private:
+ GLuint makeShader(GLuint type, const char *src);
+ void drawBuffer(Buffer *buffer);
+ void drawWithBlit(Buffer *buffer);
+ void drawWithTexture(Buffer *buffer);
+ void flushGL();
+ void presentScreen();
+ static void pageFlipHandler(int fd,
+ unsigned int sequence,
+ unsigned int tv_sec,
+ unsigned int tv_usec,
+ void *data);
+ void pageFlipHandler(unsigned int sequence, uint64_t tv);
+
+ // TODO(fjhenigman) Implement swap control. The following stuff will be used for that.
+ enum class SwapControl
+ {
+ ABSENT,
+ EXT,
+ MESA,
+ SGI,
+ };
+ SwapControl mSwapControl;
+ int mMinSwapInterval;
+ int mMaxSwapInterval;
+ int mCurrentSwapInterval;
+
+ gbm_device *mGBM;
+ drmModeConnectorPtr mConnector;
+ drmModeModeInfoPtr mMode;
+ drmModeCrtcPtr mCRTC;
+ bool mSetCRTC;
+
+ int32_t mWidth;
+ int32_t mHeight;
+
+ // Three scanout buffers cycle through four states. The state of a buffer
+ // is indicated by which of these pointers points to it.
+ // TODO(fjhenigman) It might be simpler/clearer to use a ring buffer.
+ Buffer *mScanning;
+ Buffer *mPending;
+ Buffer *mDrawing;
+ Buffer *mUnused;
+
+ GLuint mProgram;
+ GLuint mVertexShader;
+ GLuint mFragmentShader;
+ GLuint mVertexBuffer;
+ GLuint mIndexBuffer;
+ GLint mCenterUniform;
+ GLint mWindowSizeUniform;
+ GLint mBorderSizeUniform;
+ GLint mDepthUniform;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_GL_EGL_OZONE_DISPLAYOZONE_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/egl/ozone/SurfaceOzone.cpp b/gfx/angle/src/libANGLE/renderer/gl/egl/ozone/SurfaceOzone.cpp
new file mode 100755
index 000000000..614fed0fd
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/ozone/SurfaceOzone.cpp
@@ -0,0 +1,98 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// SurfaceOzone.cpp: Ozone implementation of egl::SurfaceGL
+
+#include "libANGLE/renderer/gl/egl/ozone/SurfaceOzone.h"
+
+#include "libANGLE/renderer/gl/FramebufferGL.h"
+#include "libANGLE/renderer/gl/egl/ozone/DisplayOzone.h"
+
+namespace rx
+{
+
+SurfaceOzone::SurfaceOzone(const egl::SurfaceState &state,
+ RendererGL *renderer,
+ DisplayOzone::Buffer *buffer)
+ : SurfaceGL(state, renderer), mBuffer(buffer)
+{
+}
+
+SurfaceOzone::~SurfaceOzone()
+{
+ delete mBuffer;
+}
+
+egl::Error SurfaceOzone::initialize()
+{
+ return egl::Error(EGL_SUCCESS);
+}
+
+FramebufferImpl *SurfaceOzone::createDefaultFramebuffer(const gl::FramebufferState &state)
+{
+ return mBuffer->framebufferGL(state);
+}
+
+egl::Error SurfaceOzone::makeCurrent()
+{
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error SurfaceOzone::swap()
+{
+ mBuffer->present();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error SurfaceOzone::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error SurfaceOzone::querySurfacePointerANGLE(EGLint attribute, void **value)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error SurfaceOzone::bindTexImage(gl::Texture *texture, EGLint buffer)
+{
+ mBuffer->bindTexImage();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error SurfaceOzone::releaseTexImage(EGLint buffer)
+{
+ return egl::Error(EGL_SUCCESS);
+}
+
+void SurfaceOzone::setSwapInterval(EGLint interval)
+{
+ mSwapControl.targetSwapInterval = interval;
+}
+
+EGLint SurfaceOzone::getWidth() const
+{
+ return mBuffer->getWidth();
+}
+
+EGLint SurfaceOzone::getHeight() const
+{
+ return mBuffer->getHeight();
+}
+
+EGLint SurfaceOzone::isPostSubBufferSupported() const
+{
+ UNIMPLEMENTED();
+ return EGL_FALSE;
+}
+
+EGLint SurfaceOzone::getSwapBehavior() const
+{
+ return EGL_BUFFER_PRESERVED;
+}
+} // namespace rx
diff --git a/gfx/angle/src/libANGLE/renderer/gl/egl/ozone/SurfaceOzone.h b/gfx/angle/src/libANGLE/renderer/gl/egl/ozone/SurfaceOzone.h
new file mode 100755
index 000000000..24b8ec8c9
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/ozone/SurfaceOzone.h
@@ -0,0 +1,52 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// SurfaceOzone.h: Ozone implementation of egl::SurfaceGL
+
+#ifndef LIBANGLE_RENDERER_GL_EGL_OZONE_SURFACEOZONE_H_
+#define LIBANGLE_RENDERER_GL_EGL_OZONE_SURFACEOZONE_H_
+
+#include "libANGLE/renderer/gl/SurfaceGL.h"
+#include "libANGLE/renderer/gl/egl/ozone/DisplayOzone.h"
+
+namespace rx
+{
+
+class SurfaceOzone : public SurfaceGL
+{
+ public:
+ SurfaceOzone(const egl::SurfaceState &state,
+ RendererGL *renderer,
+ DisplayOzone::Buffer *buffer);
+ ~SurfaceOzone() override;
+
+ FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override;
+
+ egl::Error initialize() override;
+ egl::Error makeCurrent() override;
+
+ egl::Error swap() override;
+ egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override;
+ egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override;
+ egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) override;
+ egl::Error releaseTexImage(EGLint buffer) override;
+ void setSwapInterval(EGLint interval) override;
+
+ EGLint getWidth() const override;
+ EGLint getHeight() const override;
+
+ EGLint isPostSubBufferSupported() const override;
+ EGLint getSwapBehavior() const override;
+
+ private:
+ DisplayOzone::Buffer *mBuffer;
+
+ // TODO(fjhenigman) Implement swap control. This will be used for that.
+ SwapControlData mSwapControl;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_GL_EGL_OZONE_SURFACEOZONE_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/formatutilsgl.cpp b/gfx/angle/src/libANGLE/renderer/gl/formatutilsgl.cpp
new file mode 100755
index 000000000..c5219b4b8
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/formatutilsgl.cpp
@@ -0,0 +1,553 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// formatutilsgl.cpp: Queries for GL image formats and their translations to native
+// GL formats.
+
+#include "libANGLE/renderer/gl/formatutilsgl.h"
+
+#include <limits>
+
+#include "common/string_utils.h"
+#include "libANGLE/formatutils.h"
+
+namespace rx
+{
+
+namespace nativegl
+{
+
+SupportRequirement::SupportRequirement()
+ : version(std::numeric_limits<GLuint>::max(), std::numeric_limits<GLuint>::max()),
+ versionExtensions(),
+ requiredExtensions()
+{
+}
+
+InternalFormat::InternalFormat()
+ : texture(),
+ filter(),
+ renderbuffer(),
+ framebufferAttachment()
+{
+}
+
+// supported = version || vertexExt
+static inline SupportRequirement VersionOrExts(GLuint major, GLuint minor, const std::string &versionExt)
+{
+ SupportRequirement requirement;
+ requirement.version.major = major;
+ requirement.version.minor = minor;
+ angle::SplitStringAlongWhitespace(versionExt, &requirement.versionExtensions);
+ return requirement;
+}
+
+// supported = (version || vertexExt) && requiredExt
+static inline SupportRequirement VersionOrExtsAndExts(GLuint major,
+ GLuint minor,
+ const std::string &versionExt,
+ const std::string &requiredExt)
+{
+ SupportRequirement requirement;
+ requirement.version.major = major;
+ requirement.version.minor = minor;
+ angle::SplitStringAlongWhitespace(versionExt, &requirement.versionExtensions);
+ angle::SplitStringAlongWhitespace(requiredExt, &requirement.requiredExtensions);
+ return requirement;
+}
+
+// supported = version
+static inline SupportRequirement VersionOnly(GLuint major, GLuint minor)
+{
+ SupportRequirement requirement;
+ requirement.version.major = major;
+ requirement.version.minor = minor;
+ return requirement;
+}
+
+// supported = ext
+static inline SupportRequirement ExtsOnly(const std::string &ext)
+{
+ SupportRequirement requirement;
+ requirement.version.major = 0;
+ requirement.version.minor = 0;
+ angle::SplitStringAlongWhitespace(ext, &requirement.requiredExtensions);
+ return requirement;
+}
+
+// supported = true
+static inline SupportRequirement AlwaysSupported()
+{
+ SupportRequirement requirement;
+ requirement.version.major = 0;
+ requirement.version.minor = 0;
+ return requirement;
+}
+
+// supported = false
+static inline SupportRequirement NeverSupported()
+{
+ SupportRequirement requirement;
+ requirement.version.major = std::numeric_limits<GLuint>::max();
+ requirement.version.minor = std::numeric_limits<GLuint>::max();
+ return requirement;
+}
+
+struct InternalFormatInfo
+{
+ InternalFormat glesInfo;
+ InternalFormat glInfo;
+};
+
+typedef std::pair<GLenum, InternalFormatInfo> InternalFormatInfoPair;
+typedef std::map<GLenum, InternalFormatInfo> InternalFormatInfoMap;
+
+// A helper function to insert data into the format map with fewer characters.
+static inline void InsertFormatMapping(InternalFormatInfoMap *map, GLenum internalFormat,
+ const SupportRequirement &desktopTexture, const SupportRequirement &desktopFilter, const SupportRequirement &desktopRender,
+ const SupportRequirement &esTexture, const SupportRequirement &esFilter, const SupportRequirement &esRender)
+{
+ InternalFormatInfo formatInfo;
+ formatInfo.glInfo.texture = desktopTexture;
+ formatInfo.glInfo.filter = desktopFilter;
+ formatInfo.glInfo.renderbuffer = desktopRender;
+ formatInfo.glInfo.framebufferAttachment = desktopRender;
+ formatInfo.glesInfo.texture = esTexture;
+ formatInfo.glesInfo.filter = esTexture;
+ formatInfo.glesInfo.renderbuffer = esFilter;
+ formatInfo.glesInfo.framebufferAttachment = esRender;
+ map->insert(std::make_pair(internalFormat, formatInfo));
+}
+
+static InternalFormatInfoMap BuildInternalFormatInfoMap()
+{
+ InternalFormatInfoMap map;
+
+ // clang-format off
+ // | Format | OpenGL texture support | Filter | OpenGL render support | OpenGL ES texture support | Filter | OpenGL ES render support |
+ InsertFormatMapping(&map, GL_R8, VersionOrExts(3, 0, "GL_ARB_texture_rg"), AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOrExts(3, 0, "GL_EXT_texture_rg"), AlwaysSupported(), VersionOrExts(3, 0, "GL_EXT_texture_rg") );
+ InsertFormatMapping(&map, GL_R8_SNORM, VersionOnly(3, 1), AlwaysSupported(), NeverSupported(), VersionOnly(3, 0), AlwaysSupported(), NeverSupported() );
+ InsertFormatMapping(&map, GL_RG8, VersionOrExts(3, 0, "GL_ARB_texture_rg"), AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOrExts(3, 0, "GL_EXT_texture_rg"), AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg") );
+ InsertFormatMapping(&map, GL_RG8_SNORM, VersionOnly(3, 1), AlwaysSupported(), NeverSupported(), VersionOnly(3, 0), AlwaysSupported(), NeverSupported() );
+ InsertFormatMapping(&map, GL_RGB8, AlwaysSupported(), AlwaysSupported(), AlwaysSupported(), VersionOrExts(3, 0, "GL_OES_rgb8_rgba8"), AlwaysSupported(), AlwaysSupported() );
+ InsertFormatMapping(&map, GL_RG8_SNORM, VersionOnly(3, 1), AlwaysSupported(), NeverSupported(), VersionOnly(3, 0), AlwaysSupported(), NeverSupported() );
+ InsertFormatMapping(&map, GL_RGB565, AlwaysSupported(), AlwaysSupported(), AlwaysSupported(), AlwaysSupported(), AlwaysSupported(), AlwaysSupported() );
+ InsertFormatMapping(&map, GL_RGBA4, AlwaysSupported(), AlwaysSupported(), AlwaysSupported(), AlwaysSupported(), AlwaysSupported(), AlwaysSupported() );
+ InsertFormatMapping(&map, GL_RGB5_A1, AlwaysSupported(), AlwaysSupported(), AlwaysSupported(), AlwaysSupported(), AlwaysSupported(), AlwaysSupported() );
+ InsertFormatMapping(&map, GL_RGBA8, AlwaysSupported(), AlwaysSupported(), AlwaysSupported(), VersionOrExts(3, 0, "GL_OES_rgb8_rgba8"), AlwaysSupported(), VersionOrExts(3, 0, "GL_OES_rgb8_rgba8") );
+ InsertFormatMapping(&map, GL_RGBA8_SNORM, VersionOnly(3, 1), AlwaysSupported(), NeverSupported(), VersionOnly(3, 0), AlwaysSupported(), NeverSupported() );
+ InsertFormatMapping(&map, GL_RGB10_A2, AlwaysSupported(), AlwaysSupported(), AlwaysSupported(), VersionOnly(3, 0), AlwaysSupported(), VersionOnly(3, 0) );
+ InsertFormatMapping(&map, GL_RGB10_A2UI, VersionOrExts(3, 3, "GL_ARB_texture_rgb10_a2ui"), NeverSupported(), AlwaysSupported(), VersionOnly(3, 0), NeverSupported(), AlwaysSupported() );
+ InsertFormatMapping(&map, GL_SRGB8, VersionOrExts(2, 1, "GL_EXT_texture_sRGB"), AlwaysSupported(), VersionOrExts(2, 1, "GL_EXT_texture_sRGB"), VersionOnly(3, 0), AlwaysSupported(), NeverSupported() );
+ InsertFormatMapping(&map, GL_SRGB8_ALPHA8, VersionOrExts(2, 1, "GL_EXT_texture_sRGB"), AlwaysSupported(), VersionOrExts(2, 1, "GL_EXT_texture_sRGB"), VersionOnly(3, 0), AlwaysSupported(), VersionOrExts(3, 0, "GL_EXT_sRGB") );
+ InsertFormatMapping(&map, GL_R8I, VersionOrExts(3, 0, "GL_ARB_texture_rg"), NeverSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), NeverSupported(), VersionOnly(3, 0) );
+ InsertFormatMapping(&map, GL_R8UI, VersionOrExts(3, 0, "GL_ARB_texture_rg"), NeverSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), NeverSupported(), VersionOnly(3, 0) );
+ InsertFormatMapping(&map, GL_R16I, VersionOrExts(3, 0, "GL_ARB_texture_rg"), NeverSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), NeverSupported(), VersionOnly(3, 0) );
+ InsertFormatMapping(&map, GL_R16UI, VersionOrExts(3, 0, "GL_ARB_texture_rg"), NeverSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), NeverSupported(), VersionOnly(3, 0) );
+ InsertFormatMapping(&map, GL_R32I, VersionOrExts(3, 0, "GL_ARB_texture_rg"), NeverSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), NeverSupported(), VersionOnly(3, 0) );
+ InsertFormatMapping(&map, GL_R32UI, VersionOrExts(3, 0, "GL_ARB_texture_rg"), NeverSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), NeverSupported(), VersionOnly(3, 0) );
+ InsertFormatMapping(&map, GL_RG8I, VersionOrExts(3, 0, "GL_ARB_texture_rg"), NeverSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), NeverSupported(), VersionOnly(3, 0) );
+ InsertFormatMapping(&map, GL_RG8UI, VersionOrExts(3, 0, "GL_ARB_texture_rg"), NeverSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), NeverSupported(), VersionOnly(3, 0) );
+ InsertFormatMapping(&map, GL_RG16I, VersionOrExts(3, 0, "GL_ARB_texture_rg"), NeverSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), NeverSupported(), VersionOnly(3, 0) );
+ InsertFormatMapping(&map, GL_RG16UI, VersionOrExts(3, 0, "GL_ARB_texture_rg"), NeverSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), NeverSupported(), VersionOnly(3, 0) );
+ InsertFormatMapping(&map, GL_RG32I, VersionOrExts(3, 0, "GL_ARB_texture_rg"), NeverSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), NeverSupported(), VersionOnly(3, 0) );
+ InsertFormatMapping(&map, GL_RG32UI, VersionOrExts(3, 0, "GL_ARB_texture_rg"), NeverSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), NeverSupported(), VersionOnly(3, 0) );
+ InsertFormatMapping(&map, GL_RGB8I, VersionOrExts(3, 0, "GL_EXT_texture_integer"), NeverSupported(), NeverSupported(), VersionOnly(3, 0), NeverSupported(), NeverSupported() );
+ InsertFormatMapping(&map, GL_RGB8UI, VersionOrExts(3, 0, "GL_EXT_texture_integer"), NeverSupported(), NeverSupported(), VersionOnly(3, 0), NeverSupported(), NeverSupported() );
+ InsertFormatMapping(&map, GL_RGB16I, VersionOrExts(3, 0, "GL_EXT_texture_integer"), NeverSupported(), NeverSupported(), VersionOnly(3, 0), NeverSupported(), NeverSupported() );
+ InsertFormatMapping(&map, GL_RGB16UI, VersionOrExts(3, 0, "GL_EXT_texture_integer"), NeverSupported(), NeverSupported(), VersionOnly(3, 0), NeverSupported(), NeverSupported() );
+ InsertFormatMapping(&map, GL_RGB32I, VersionOrExts(3, 0, "GL_EXT_texture_integer"), NeverSupported(), NeverSupported(), VersionOnly(3, 0), NeverSupported(), NeverSupported() );
+ InsertFormatMapping(&map, GL_RGB32UI, VersionOrExts(3, 0, "GL_EXT_texture_integer"), NeverSupported(), NeverSupported(), VersionOnly(3, 0), NeverSupported(), NeverSupported() );
+ InsertFormatMapping(&map, GL_RGBA8I, VersionOrExts(3, 0, "GL_EXT_texture_integer"), NeverSupported(), VersionOrExts(3, 0, "GL_EXT_texture_integer"), VersionOnly(3, 0), NeverSupported(), VersionOnly(3, 0) );
+ InsertFormatMapping(&map, GL_RGBA8UI, VersionOrExts(3, 0, "GL_EXT_texture_integer"), NeverSupported(), VersionOrExts(3, 0, "GL_EXT_texture_integer"), VersionOnly(3, 0), NeverSupported(), VersionOnly(3, 0) );
+ InsertFormatMapping(&map, GL_RGBA16I, VersionOrExts(3, 0, "GL_EXT_texture_integer"), NeverSupported(), VersionOrExts(3, 0, "GL_EXT_texture_integer"), VersionOnly(3, 0), NeverSupported(), VersionOnly(3, 0) );
+ InsertFormatMapping(&map, GL_RGBA16UI, VersionOrExts(3, 0, "GL_EXT_texture_integer"), NeverSupported(), VersionOrExts(3, 0, "GL_EXT_texture_integer"), VersionOnly(3, 0), NeverSupported(), VersionOnly(3, 0) );
+ InsertFormatMapping(&map, GL_RGBA32I, VersionOrExts(3, 0, "GL_EXT_texture_integer"), NeverSupported(), VersionOrExts(3, 0, "GL_EXT_texture_integer"), VersionOnly(3, 0), NeverSupported(), VersionOnly(3, 0) );
+ InsertFormatMapping(&map, GL_RGBA32UI, VersionOrExts(3, 0, "GL_EXT_texture_integer"), NeverSupported(), VersionOrExts(3, 0, "GL_EXT_texture_integer"), VersionOnly(3, 0), NeverSupported(), VersionOnly(3, 0) );
+
+ // Unsized formats
+ InsertFormatMapping(&map, GL_ALPHA, NeverSupported(), NeverSupported(), NeverSupported(), NeverSupported(), NeverSupported(), NeverSupported() );
+ InsertFormatMapping(&map, GL_LUMINANCE, NeverSupported(), NeverSupported(), NeverSupported(), NeverSupported(), NeverSupported(), NeverSupported() );
+ InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, NeverSupported(), NeverSupported(), NeverSupported(), NeverSupported(), NeverSupported(), NeverSupported() );
+ InsertFormatMapping(&map, GL_RED, VersionOrExts(3, 0, "GL_ARB_texture_rg"), AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOrExts(3, 0, "GL_EXT_texture_rg"), AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg") );
+ InsertFormatMapping(&map, GL_RG, VersionOrExts(3, 0, "GL_ARB_texture_rg"), AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOrExts(3, 0, "GL_EXT_texture_rg"), AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg") );
+ InsertFormatMapping(&map, GL_RGB, AlwaysSupported(), AlwaysSupported(), AlwaysSupported(), AlwaysSupported(), AlwaysSupported(), AlwaysSupported() );
+ InsertFormatMapping(&map, GL_RGBA, AlwaysSupported(), AlwaysSupported(), AlwaysSupported(), AlwaysSupported(), AlwaysSupported(), AlwaysSupported() );
+ InsertFormatMapping(&map, GL_RED_INTEGER, VersionOrExts(3, 0, "GL_ARB_texture_rg"), NeverSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), NeverSupported(), VersionOnly(3, 0) );
+ InsertFormatMapping(&map, GL_RG_INTEGER, VersionOrExts(3, 0, "GL_ARB_texture_rg"), NeverSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), NeverSupported(), VersionOnly(3, 0) );
+ InsertFormatMapping(&map, GL_RGB_INTEGER, VersionOrExts(3, 0, "GL_EXT_texture_integer"), NeverSupported(), NeverSupported(), VersionOnly(3, 0), NeverSupported(), NeverSupported() );
+ InsertFormatMapping(&map, GL_RGBA_INTEGER, VersionOrExts(3, 0, "GL_EXT_texture_integer"), NeverSupported(), VersionOrExts(3, 0, "GL_EXT_texture_integer"), VersionOnly(3, 0), NeverSupported(), VersionOnly(3, 0) );
+ InsertFormatMapping(&map, GL_SRGB, VersionOrExts(2, 1, "GL_EXT_texture_sRGB"), AlwaysSupported(), VersionOrExts(2, 1, "GL_EXT_texture_sRGB"), ExtsOnly("GL_EXT_sRGB"), AlwaysSupported(), NeverSupported() );
+ InsertFormatMapping(&map, GL_SRGB_ALPHA, VersionOrExts(2, 1, "GL_EXT_texture_sRGB"), AlwaysSupported(), VersionOrExts(2, 1, "GL_EXT_texture_sRGB"), ExtsOnly("GL_EXT_sRGB"), AlwaysSupported(), NeverSupported() );
+
+ // From GL_EXT_texture_format_BGRA8888
+ InsertFormatMapping(&map, GL_BGRA8_EXT, VersionOrExts(1, 2, "GL_EXT_bgra"), AlwaysSupported(), VersionOrExts(1, 2, "GL_EXT_bgra"), ExtsOnly("GL_EXT_texture_format_BGRA8888"), AlwaysSupported(), NeverSupported() );
+ InsertFormatMapping(&map, GL_BGRA_EXT, VersionOrExts(1, 2, "GL_EXT_bgra"), AlwaysSupported(), VersionOrExts(1, 2, "GL_EXT_bgra"), ExtsOnly("GL_EXT_texture_format_BGRA8888"), AlwaysSupported(), NeverSupported() );
+
+ // Floating point formats
+ // | Format | OpenGL texture support | Filter | OpenGL render support | OpenGL ES texture support | Filter | OpenGL ES render support |
+ InsertFormatMapping(&map, GL_R11F_G11F_B10F, VersionOrExts(3, 0, "GL_EXT_packed_float"), AlwaysSupported(), VersionOrExts(3, 0, "GL_EXT_packed_float GL_ARB_color_buffer_float"), VersionOnly(3, 0), AlwaysSupported(), ExtsOnly("GL_EXT_color_buffer_float") );
+ InsertFormatMapping(&map, GL_RGB9_E5, VersionOrExts(3, 0, "GL_EXT_texture_shared_exponent"), AlwaysSupported(), VersionOrExts(3, 0, "GL_EXT_texture_shared_exponent GL_ARB_color_buffer_float"), VersionOnly(3, 0), AlwaysSupported(), NeverSupported() );
+ InsertFormatMapping(&map, GL_R16F, VersionOrExts(3, 0, "GL_ARB_texture_rg ARB_texture_float"), AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg GL_ARB_texture_float GL_ARB_color_buffer_float"), VersionOrExts(3, 0, "GL_OES_texture_half_float GL_EXT_texture_rg"), VersionOrExts(3, 0, "GL_OES_texture_half_float_linear"), VersionOrExtsAndExts(3, 0, "GL_EXT_texture_rg", "GL_EXT_color_buffer_half_float"));
+ InsertFormatMapping(&map, GL_RG16F, VersionOrExts(3, 0, "GL_ARB_texture_rg ARB_texture_float"), AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg GL_ARB_texture_float GL_ARB_color_buffer_float"), VersionOrExts(3, 0, "GL_OES_texture_half_float GL_EXT_texture_rg"), VersionOrExts(3, 0, "GL_OES_texture_half_float_linear"), VersionOrExtsAndExts(3, 0, "GL_EXT_texture_rg", "GL_EXT_color_buffer_half_float"));
+ InsertFormatMapping(&map, GL_RGB16F, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_float GL_ARB_color_buffer_float"), VersionOrExts(3, 0, "GL_OES_texture_half_float"), VersionOrExts(3, 0, "GL_OES_texture_half_float_linear"), ExtsOnly("GL_EXT_color_buffer_half_float") );
+ InsertFormatMapping(&map, GL_RGBA16F, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_float GL_ARB_color_buffer_float"), VersionOrExts(3, 0, "GL_OES_texture_half_float"), VersionOrExts(3, 0, "GL_OES_texture_half_float_linear"), ExtsOnly("GL_EXT_color_buffer_half_float") );
+ InsertFormatMapping(&map, GL_R32F, VersionOrExts(3, 0, "GL_ARB_texture_rg GL_ARB_texture_float"), AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg GL_ARB_texture_float GL_ARB_color_buffer_float"), VersionOrExts(3, 0, "GL_OES_texture_float GL_EXT_texture_rg"), VersionOrExts(3, 0, "GL_OES_texture_float_linear"), ExtsOnly("GL_EXT_color_buffer_float") );
+ InsertFormatMapping(&map, GL_RG32F, VersionOrExts(3, 0, "GL_ARB_texture_rg GL_ARB_texture_float"), AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg GL_ARB_texture_float GL_ARB_color_buffer_float"), VersionOrExts(3, 0, "GL_OES_texture_float GL_EXT_texture_rg"), VersionOrExts(3, 0, "GL_OES_texture_float_linear"), ExtsOnly("GL_EXT_color_buffer_float") );
+ InsertFormatMapping(&map, GL_RGB32F, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_float GL_ARB_color_buffer_float"), VersionOrExts(3, 0, "GL_OES_texture_float"), VersionOrExts(3, 0, "GL_OES_texture_float_linear"), NeverSupported() );
+ InsertFormatMapping(&map, GL_RGBA32F, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_float GL_ARB_color_buffer_float"), VersionOrExts(3, 0, "GL_OES_texture_float"), VersionOrExts(3, 0, "GL_OES_texture_float_linear"), ExtsOnly("GL_EXT_color_buffer_float") );
+
+ // Depth stencil formats
+ // | Format | OpenGL texture support | Filter | OpenGL render support | OpenGL ES texture support | Filter | OpenGL ES render support |
+ InsertFormatMapping(&map, GL_DEPTH_COMPONENT16, VersionOnly(1, 5), VersionOrExts(1, 5, "GL_ARB_depth_texture"), VersionOnly(1, 5), VersionOnly(2, 0), VersionOrExts(3, 0, "GL_OES_depth_texture"), VersionOnly(2, 0) );
+ InsertFormatMapping(&map, GL_DEPTH_COMPONENT24, VersionOnly(1, 5), VersionOrExts(1, 5, "GL_ARB_depth_texture"), VersionOnly(1, 5), VersionOnly(2, 0), VersionOrExts(3, 0, "GL_OES_depth_texture"), VersionOnly(2, 0) );
+ InsertFormatMapping(&map, GL_DEPTH_COMPONENT32_OES, VersionOnly(1, 5), VersionOrExts(1, 5, "GL_ARB_depth_texture"), VersionOnly(1, 5), ExtsOnly("GL_OES_depth_texture"), AlwaysSupported(), ExtsOnly("GL_OES_depth32") );
+ InsertFormatMapping(&map, GL_DEPTH_COMPONENT32F, VersionOrExts(3, 0, "GL_ARB_depth_buffer_float"), AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_depth_buffer_float"), VersionOnly(3, 0), VersionOrExts(3, 0, "GL_OES_depth_texture"), VersionOnly(3, 0) );
+ InsertFormatMapping(&map, GL_STENCIL_INDEX8, VersionOrExts(3, 0, "GL_EXT_packed_depth_stencil"), NeverSupported(), VersionOrExts(3, 0, "GL_EXT_packed_depth_stencil"), VersionOnly(2, 0), NeverSupported(), VersionOnly(2, 0) );
+ InsertFormatMapping(&map, GL_DEPTH24_STENCIL8, VersionOrExts(3, 0, "GL_ARB_framebuffer_object"), VersionOrExts(3, 0, "GL_ARB_depth_texture"), VersionOrExts(3, 0, "GL_ARB_framebuffer_object"), VersionOrExts(3, 0, "GL_OES_depth_texture"), AlwaysSupported(), VersionOrExts(3, 0, "GL_OES_depth_texture GL_OES_packed_depth_stencil"));
+ InsertFormatMapping(&map, GL_DEPTH32F_STENCIL8, VersionOrExts(3, 0, "GL_ARB_depth_buffer_float"), AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_depth_buffer_float"), VersionOnly(3, 0), AlwaysSupported(), VersionOnly(3, 0) );
+ InsertFormatMapping(&map, GL_DEPTH_COMPONENT, VersionOnly(1, 5), VersionOrExts(1, 5, "GL_ARB_depth_texture"), VersionOnly(1, 5), VersionOnly(2, 0), VersionOrExts(3, 0, "GL_OES_depth_texture"), VersionOnly(2, 0) );
+ InsertFormatMapping(&map, GL_DEPTH_STENCIL, VersionOnly(1, 5), VersionOrExts(1, 5, "GL_ARB_depth_texture"), VersionOnly(1, 5), VersionOnly(2, 0), VersionOrExts(3, 0, "GL_OES_depth_texture"), VersionOnly(2, 0) );
+
+ // Luminance alpha formats
+ // | Format | OpenGL texture support | Filter | Render | OpenGL ES texture support | Filter | Render |
+ InsertFormatMapping(&map, GL_ALPHA8_EXT, AlwaysSupported(), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_storage"), AlwaysSupported(), NeverSupported());
+ InsertFormatMapping(&map, GL_LUMINANCE8_EXT, AlwaysSupported(), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_storage"), AlwaysSupported(), NeverSupported());
+ InsertFormatMapping(&map, GL_ALPHA32F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_storage"), AlwaysSupported(), NeverSupported());
+ InsertFormatMapping(&map, GL_LUMINANCE32F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_storage"), AlwaysSupported(), NeverSupported());
+ InsertFormatMapping(&map, GL_ALPHA16F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_storage"), AlwaysSupported(), NeverSupported());
+ InsertFormatMapping(&map, GL_LUMINANCE16F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_storage"), AlwaysSupported(), NeverSupported());
+ InsertFormatMapping(&map, GL_LUMINANCE8_ALPHA8_EXT, AlwaysSupported(), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_storage"), AlwaysSupported(), NeverSupported());
+ InsertFormatMapping(&map, GL_LUMINANCE_ALPHA32F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_storage"), AlwaysSupported(), NeverSupported());
+ InsertFormatMapping(&map, GL_LUMINANCE_ALPHA16F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_storage"), AlwaysSupported(), NeverSupported());
+
+ // Compressed formats, From ES 3.0.1 spec, table 3.16
+ InsertFormatMapping(&map, GL_COMPRESSED_R11_EAC, VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), AlwaysSupported(), NeverSupported(), VersionOnly(3, 0), AlwaysSupported(), NeverSupported());
+ InsertFormatMapping(&map, GL_COMPRESSED_SIGNED_R11_EAC, VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), AlwaysSupported(), NeverSupported(), VersionOnly(3, 0), AlwaysSupported(), NeverSupported());
+ InsertFormatMapping(&map, GL_COMPRESSED_RG11_EAC, VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), AlwaysSupported(), NeverSupported(), VersionOnly(3, 0), AlwaysSupported(), NeverSupported());
+ InsertFormatMapping(&map, GL_COMPRESSED_SIGNED_RG11_EAC, VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), AlwaysSupported(), NeverSupported(), VersionOnly(3, 0), AlwaysSupported(), NeverSupported());
+ InsertFormatMapping(&map, GL_COMPRESSED_RGB8_ETC2, VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), AlwaysSupported(), NeverSupported(), VersionOnly(3, 0), AlwaysSupported(), NeverSupported());
+ InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ETC2, VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), AlwaysSupported(), NeverSupported(), VersionOnly(3, 0), AlwaysSupported(), NeverSupported());
+ InsertFormatMapping(&map, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), AlwaysSupported(), NeverSupported(), VersionOnly(3, 0), AlwaysSupported(), NeverSupported());
+ InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), AlwaysSupported(), NeverSupported(), VersionOnly(3, 0), AlwaysSupported(), NeverSupported());
+ InsertFormatMapping(&map, GL_COMPRESSED_RGBA8_ETC2_EAC, VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), AlwaysSupported(), NeverSupported(), VersionOnly(3, 0), AlwaysSupported(), NeverSupported());
+ InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), AlwaysSupported(), NeverSupported(), VersionOnly(3, 0), AlwaysSupported(), NeverSupported());
+
+ // From GL_EXT_texture_compression_dxt1
+ // | Format | OpenGL texture support | Filter | Render | OpenGL ES texture support | Filter | Render |
+ InsertFormatMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, ExtsOnly("GL_EXT_texture_compression_s3tc"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_compression_dxt1"), AlwaysSupported(), NeverSupported());
+ InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, ExtsOnly("GL_EXT_texture_compression_s3tc"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_compression_dxt1"), AlwaysSupported(), NeverSupported());
+
+ // From GL_ANGLE_texture_compression_dxt3
+ InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, ExtsOnly("GL_EXT_texture_compression_s3tc"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_ANGLE_texture_compression_dxt3"), AlwaysSupported(), NeverSupported());
+
+ // From GL_ANGLE_texture_compression_dxt5
+ InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, ExtsOnly("GL_EXT_texture_compression_s3tc"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_ANGLE_texture_compression_dxt5"), AlwaysSupported(), NeverSupported());
+
+ // From GL_ETC1_RGB8_OES
+ InsertFormatMapping(&map, GL_ETC1_RGB8_OES, VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), AlwaysSupported(), NeverSupported(), VersionOrExts(3, 0, "GL_ETC1_RGB8_OES"), AlwaysSupported(), NeverSupported());
+
+ // clang-format on
+
+ return map;
+}
+
+static const InternalFormatInfoMap &GetInternalFormatMap()
+{
+ static const InternalFormatInfoMap formatMap = BuildInternalFormatInfoMap();
+ return formatMap;
+}
+
+const InternalFormat &GetInternalFormatInfo(GLenum internalFormat, StandardGL standard)
+{
+ const InternalFormatInfoMap &formatMap = GetInternalFormatMap();
+ InternalFormatInfoMap::const_iterator iter = formatMap.find(internalFormat);
+ if (iter != formatMap.end())
+ {
+ const InternalFormatInfo &info = iter->second;
+ switch (standard)
+ {
+ case STANDARD_GL_ES: return info.glesInfo;
+ case STANDARD_GL_DESKTOP: return info.glInfo;
+ default: UNREACHABLE(); break;
+ }
+ }
+
+ static const InternalFormat defaultInternalFormat;
+ return defaultInternalFormat;
+}
+
+static GLenum GetNativeInternalFormat(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum internalFormat,
+ GLenum sizedInternalFormat)
+{
+ GLenum result = internalFormat;
+
+ if (functions->standard == STANDARD_GL_DESKTOP)
+ {
+ // Use sized internal formats whenever possible to guarantee the requested precision.
+ // On Desktop GL, passing an internal format of GL_RGBA will generate a GL_RGBA8 texture
+ // even if the provided type is GL_FLOAT.
+ result = sizedInternalFormat;
+
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(sizedInternalFormat);
+
+ if (workarounds.avoid1BitAlphaTextureFormats && formatInfo.alphaBits == 1)
+ {
+ // Use an 8-bit format instead
+ result = GL_RGBA8;
+ }
+
+ if (workarounds.rgba4IsNotSupportedForColorRendering && sizedInternalFormat == GL_RGBA4)
+ {
+ // Use an 8-bit format instead
+ result = GL_RGBA8;
+ }
+
+ if (sizedInternalFormat == GL_RGB565 && !functions->isAtLeastGL(gl::Version(4, 1)) &&
+ !functions->hasGLExtension("GL_ARB_ES2_compatibility"))
+ {
+ // GL_RGB565 is required for basic ES2 functionality but was not added to desktop GL
+ // until 4.1.
+ // Work around this by using an 8-bit format instead.
+ result = GL_RGB8;
+ }
+
+ if (sizedInternalFormat == GL_BGRA8_EXT)
+ {
+ // GLES accepts GL_BGRA as an internal format but desktop GL only accepts it as a type.
+ // Update the internal format to GL_RGBA.
+ result = GL_RGBA8;
+ }
+
+ if ((functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0)
+ {
+ // Work around deprecated luminance alpha formats in the OpenGL core profile by backing
+ // them with R or RG textures.
+ if (formatInfo.format == GL_LUMINANCE || formatInfo.format == GL_ALPHA)
+ {
+ result = gl::GetSizedInternalFormat(GL_RED, formatInfo.type);
+ }
+
+ if (formatInfo.format == GL_LUMINANCE_ALPHA)
+ {
+ result = gl::GetSizedInternalFormat(GL_RG, formatInfo.type);
+ }
+ }
+ }
+
+ return result;
+}
+
+static GLenum GetNativeFormat(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum format)
+{
+ GLenum result = format;
+
+ if (functions->standard == STANDARD_GL_DESKTOP)
+ {
+ // The ES SRGB extensions require that the provided format is GL_SRGB or SRGB_ALPHA but
+ // the desktop GL extensions only accept GL_RGB or GL_RGBA. Convert them.
+ if (format == GL_SRGB)
+ {
+ result = GL_RGB;
+ }
+
+ if (format == GL_SRGB_ALPHA)
+ {
+ result = GL_RGBA;
+ }
+
+ if ((functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0)
+ {
+ // Work around deprecated luminance alpha formats in the OpenGL core profile by backing
+ // them with R or RG textures.
+ if (format == GL_LUMINANCE || format == GL_ALPHA)
+ {
+ result = GL_RED;
+ }
+
+ if (format == GL_LUMINANCE_ALPHA)
+ {
+ result = GL_RG;
+ }
+ }
+ }
+
+ return result;
+}
+
+static GLenum GetNativeCompressedFormat(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum format)
+{
+ GLenum result = format;
+
+ if (functions->standard == STANDARD_GL_DESKTOP)
+ {
+ if (format == GL_ETC1_RGB8_OES)
+ {
+ // GL_ETC1_RGB8_OES is not available in any desktop GL extension but the compression
+ // format is forwards compatible so just use the ETC2 format.
+ result = GL_COMPRESSED_RGB8_ETC2;
+ }
+ }
+
+ if (functions->isAtLeastGLES(gl::Version(3, 0)))
+ {
+ if (format == GL_ETC1_RGB8_OES)
+ {
+ // Pass GL_COMPRESSED_RGB8_ETC2 as the target format in ES3 and higher because it
+ // becomes a core format.
+ result = GL_COMPRESSED_RGB8_ETC2;
+ }
+ }
+
+ return result;
+}
+
+static GLenum GetNativeType(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum type)
+{
+ GLenum result = type;
+
+ if (functions->standard == STANDARD_GL_DESKTOP)
+ {
+ if (type == GL_HALF_FLOAT_OES)
+ {
+ // The enums differ for the OES half float extensions and desktop GL spec. Update it.
+ result = GL_HALF_FLOAT;
+ }
+ }
+
+ if (functions->isAtLeastGLES(gl::Version(3, 0)))
+ {
+ if (type == GL_HALF_FLOAT_OES)
+ {
+ // The enums differ for the OES half float extensions and ES 3 spec. Update it.
+ result = GL_HALF_FLOAT;
+ }
+ }
+
+ return result;
+}
+
+static GLenum GetNativeReadType(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum type)
+{
+ GLenum result = type;
+
+ if (functions->standard == STANDARD_GL_DESKTOP)
+ {
+ if (type == GL_HALF_FLOAT_OES)
+ {
+ // The enums differ for the OES half float extensions and desktop GL spec. Update it.
+ result = GL_HALF_FLOAT;
+ }
+ }
+
+ return result;
+}
+
+static GLenum GetNativeReadFormat(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum format)
+{
+ GLenum result = format;
+ return result;
+}
+
+TexImageFormat GetTexImageFormat(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum internalFormat,
+ GLenum format,
+ GLenum type)
+{
+ TexImageFormat result;
+ result.internalFormat = GetNativeInternalFormat(
+ functions, workarounds, internalFormat, gl::GetSizedInternalFormat(internalFormat, type));
+ result.format = GetNativeFormat(functions, workarounds, format);
+ result.type = GetNativeType(functions, workarounds, type);
+ return result;
+}
+
+TexSubImageFormat GetTexSubImageFormat(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum format,
+ GLenum type)
+{
+ TexSubImageFormat result;
+ result.format = GetNativeFormat(functions, workarounds, format);
+ result.type = GetNativeType(functions, workarounds, type);
+ return result;
+}
+
+CompressedTexImageFormat GetCompressedTexImageFormat(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum internalFormat)
+{
+ CompressedTexImageFormat result;
+ result.internalFormat = GetNativeCompressedFormat(functions, workarounds, internalFormat);
+ return result;
+}
+
+CompressedTexSubImageFormat GetCompressedSubTexImageFormat(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum format)
+{
+ CompressedTexSubImageFormat result;
+ result.format = GetNativeCompressedFormat(functions, workarounds, format);
+ return result;
+}
+
+CopyTexImageImageFormat GetCopyTexImageImageFormat(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum internalFormat,
+ GLenum framebufferType)
+{
+ CopyTexImageImageFormat result;
+ result.internalFormat =
+ GetNativeInternalFormat(functions, workarounds, internalFormat,
+ gl::GetSizedInternalFormat(internalFormat, framebufferType));
+ return result;
+}
+
+TexStorageFormat GetTexStorageFormat(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum internalFormat)
+{
+ TexStorageFormat result;
+ result.internalFormat =
+ GetNativeInternalFormat(functions, workarounds, internalFormat, internalFormat);
+ return result;
+}
+
+RenderbufferFormat GetRenderbufferFormat(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum internalFormat)
+{
+ RenderbufferFormat result;
+ result.internalFormat =
+ GetNativeInternalFormat(functions, workarounds, internalFormat, internalFormat);
+ return result;
+}
+ReadPixelsFormat GetReadPixelsFormat(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum format,
+ GLenum type)
+{
+ ReadPixelsFormat result;
+ result.format = GetNativeReadFormat(functions, workarounds, format);
+ result.type = GetNativeReadType(functions, workarounds, type);
+ return result;
+}
+}
+
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/formatutilsgl.h b/gfx/angle/src/libANGLE/renderer/gl/formatutilsgl.h
new file mode 100755
index 000000000..616f37af2
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/formatutilsgl.h
@@ -0,0 +1,129 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// formatutilsgl.h: Queries for GL image formats and their translations to native
+// GL formats.
+
+#ifndef LIBANGLE_RENDERER_GL_FORMATUTILSGL_H_
+#define LIBANGLE_RENDERER_GL_FORMATUTILSGL_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "angle_gl.h"
+#include "libANGLE/Version.h"
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+#include "libANGLE/renderer/gl/WorkaroundsGL.h"
+
+namespace rx
+{
+
+namespace nativegl
+{
+
+struct SupportRequirement
+{
+ SupportRequirement();
+
+ // Version that this format became supported without extensions
+ gl::Version version;
+
+ // Extensions that are required if the minimum version is not met
+ std::vector<std::string> versionExtensions;
+
+ // Extensions that are always required to support this format
+ std::vector<std::string> requiredExtensions;
+};
+
+struct InternalFormat
+{
+ InternalFormat();
+
+ SupportRequirement texture;
+ SupportRequirement filter;
+ SupportRequirement renderbuffer;
+ SupportRequirement framebufferAttachment;
+};
+const InternalFormat &GetInternalFormatInfo(GLenum internalFormat, StandardGL standard);
+
+struct TexImageFormat
+{
+ GLenum internalFormat;
+ GLenum format;
+ GLenum type;
+};
+TexImageFormat GetTexImageFormat(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum internalFormat,
+ GLenum format,
+ GLenum type);
+
+struct TexSubImageFormat
+{
+ GLenum format;
+ GLenum type;
+};
+TexSubImageFormat GetTexSubImageFormat(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum format,
+ GLenum type);
+
+struct CompressedTexImageFormat
+{
+ GLenum internalFormat;
+};
+CompressedTexImageFormat GetCompressedTexImageFormat(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum internalFormat);
+
+struct CompressedTexSubImageFormat
+{
+ GLenum format;
+};
+CompressedTexSubImageFormat GetCompressedSubTexImageFormat(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum format);
+
+struct CopyTexImageImageFormat
+{
+ GLenum internalFormat;
+};
+CopyTexImageImageFormat GetCopyTexImageImageFormat(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum internalFormat,
+ GLenum framebufferType);
+
+struct TexStorageFormat
+{
+ GLenum internalFormat;
+};
+TexStorageFormat GetTexStorageFormat(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum internalFormat);
+
+struct RenderbufferFormat
+{
+ GLenum internalFormat;
+};
+RenderbufferFormat GetRenderbufferFormat(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum internalFormat);
+
+struct ReadPixelsFormat
+{
+ GLenum format;
+ GLenum type;
+};
+ReadPixelsFormat GetReadPixelsFormat(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum format,
+ GLenum type);
+}
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_FORMATUTILSGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/functionsgl_enums.h b/gfx/angle/src/libANGLE/renderer/gl/functionsgl_enums.h
new file mode 100755
index 000000000..918a7a1e6
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/functionsgl_enums.h
@@ -0,0 +1,1375 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// functionsgl_enums.h: OpenGL enums for versions 1.0 through 4.5.
+
+#ifndef LIBANGLE_RENDERER_GL_FUNCTIONSGLENUMS_H_
+#define LIBANGLE_RENDERER_GL_FUNCTIONSGLENUMS_H_
+
+// 1.0
+#define GL_ALPHA 0x1906
+#define GL_ALWAYS 0x0207
+#define GL_AND 0x1501
+#define GL_AND_INVERTED 0x1504
+#define GL_AND_REVERSE 0x1502
+#define GL_BACK 0x0405
+#define GL_BACK_LEFT 0x0402
+#define GL_BACK_RIGHT 0x0403
+#define GL_BLEND 0x0BE2
+#define GL_BLEND_DST 0x0BE0
+#define GL_BLEND_SRC 0x0BE1
+#define GL_BLUE 0x1905
+#define GL_BYTE 0x1400
+#define GL_CCW 0x0901
+#define GL_CLEAR 0x1500
+#define GL_COLOR 0x1800
+#define GL_COLOR_BUFFER_BIT 0x00004000
+#define GL_COLOR_CLEAR_VALUE 0x0C22
+#define GL_COLOR_LOGIC_OP 0x0BF2
+#define GL_COLOR_WRITEMASK 0x0C23
+#define GL_COPY 0x1503
+#define GL_COPY_INVERTED 0x150C
+#define GL_CULL_FACE 0x0B44
+#define GL_CULL_FACE_MODE 0x0B45
+#define GL_CW 0x0900
+#define GL_DECR 0x1E03
+#define GL_DEPTH 0x1801
+#define GL_DEPTH_BUFFER_BIT 0x00000100
+#define GL_DEPTH_CLEAR_VALUE 0x0B73
+#define GL_DEPTH_COMPONENT 0x1902
+#define GL_DEPTH_FUNC 0x0B74
+#define GL_DEPTH_RANGE 0x0B70
+#define GL_DEPTH_TEST 0x0B71
+#define GL_DEPTH_WRITEMASK 0x0B72
+#define GL_DITHER 0x0BD0
+#define GL_DONT_CARE 0x1100
+#define GL_DOUBLE 0x140A
+#define GL_DOUBLEBUFFER 0x0C32
+#define GL_DRAW_BUFFER 0x0C01
+#define GL_DST_ALPHA 0x0304
+#define GL_DST_COLOR 0x0306
+#define GL_EQUAL 0x0202
+#define GL_EQUIV 0x1509
+#define GL_EXTENSIONS 0x1F03
+#define GL_FALSE 0
+#define GL_FASTEST 0x1101
+#define GL_FILL 0x1B02
+#define GL_FLOAT 0x1406
+#define GL_FRONT 0x0404
+#define GL_FRONT_AND_BACK 0x0408
+#define GL_FRONT_FACE 0x0B46
+#define GL_FRONT_LEFT 0x0400
+#define GL_FRONT_RIGHT 0x0401
+#define GL_GEQUAL 0x0206
+#define GL_GREATER 0x0204
+#define GL_GREEN 0x1904
+#define GL_INCR 0x1E02
+#define GL_INT 0x1404
+#define GL_INVALID_ENUM 0x0500
+#define GL_INVALID_OPERATION 0x0502
+#define GL_INVALID_VALUE 0x0501
+#define GL_INVERT 0x150A
+#define GL_KEEP 0x1E00
+#define GL_LEFT 0x0406
+#define GL_LEQUAL 0x0203
+#define GL_LESS 0x0201
+#define GL_LINE 0x1B01
+#define GL_LINEAR 0x2601
+#define GL_LINEAR_MIPMAP_LINEAR 0x2703
+#define GL_LINEAR_MIPMAP_NEAREST 0x2701
+#define GL_LINES 0x0001
+#define GL_LINE_LOOP 0x0002
+#define GL_LINE_SMOOTH 0x0B20
+#define GL_LINE_SMOOTH_HINT 0x0C52
+#define GL_LINE_STRIP 0x0003
+#define GL_LINE_WIDTH 0x0B21
+#define GL_LINE_WIDTH_GRANULARITY 0x0B23
+#define GL_LINE_WIDTH_RANGE 0x0B22
+#define GL_LOGIC_OP_MODE 0x0BF0
+#define GL_MAX_TEXTURE_SIZE 0x0D33
+#define GL_MAX_VIEWPORT_DIMS 0x0D3A
+#define GL_NAND 0x150E
+#define GL_NEAREST 0x2600
+#define GL_NEAREST_MIPMAP_LINEAR 0x2702
+#define GL_NEAREST_MIPMAP_NEAREST 0x2700
+#define GL_NEVER 0x0200
+#define GL_NICEST 0x1102
+#define GL_NONE 0
+#define GL_NOOP 0x1505
+#define GL_NOR 0x1508
+#define GL_NOTEQUAL 0x0205
+#define GL_NO_ERROR 0
+#define GL_ONE 1
+#define GL_ONE_MINUS_DST_ALPHA 0x0305
+#define GL_ONE_MINUS_DST_COLOR 0x0307
+#define GL_ONE_MINUS_SRC_ALPHA 0x0303
+#define GL_ONE_MINUS_SRC_COLOR 0x0301
+#define GL_OR 0x1507
+#define GL_OR_INVERTED 0x150D
+#define GL_OR_REVERSE 0x150B
+#define GL_OUT_OF_MEMORY 0x0505
+#define GL_PACK_ALIGNMENT 0x0D05
+#define GL_PACK_LSB_FIRST 0x0D01
+#define GL_PACK_ROW_LENGTH 0x0D02
+#define GL_PACK_SKIP_PIXELS 0x0D04
+#define GL_PACK_SKIP_ROWS 0x0D03
+#define GL_PACK_SWAP_BYTES 0x0D00
+#define GL_POINT 0x1B00
+#define GL_POINTS 0x0000
+#define GL_POINT_SIZE 0x0B11
+#define GL_POINT_SIZE_GRANULARITY 0x0B13
+#define GL_POINT_SIZE_RANGE 0x0B12
+#define GL_POLYGON_MODE 0x0B40
+#define GL_POLYGON_OFFSET_FACTOR 0x8038
+#define GL_POLYGON_OFFSET_FILL 0x8037
+#define GL_POLYGON_OFFSET_LINE 0x2A02
+#define GL_POLYGON_OFFSET_POINT 0x2A01
+#define GL_POLYGON_OFFSET_UNITS 0x2A00
+#define GL_POLYGON_SMOOTH 0x0B41
+#define GL_POLYGON_SMOOTH_HINT 0x0C53
+#define GL_PROXY_TEXTURE_1D 0x8063
+#define GL_PROXY_TEXTURE_2D 0x8064
+#define GL_QUADS 0x0007
+#define GL_R3_G3_B2 0x2A10
+#define GL_READ_BUFFER 0x0C02
+#define GL_RED 0x1903
+#define GL_RENDERER 0x1F01
+#define GL_REPEAT 0x2901
+#define GL_REPLACE 0x1E01
+#define GL_RGB 0x1907
+#define GL_RGB10 0x8052
+#define GL_RGB10_A2 0x8059
+#define GL_RGB12 0x8053
+#define GL_RGB16 0x8054
+#define GL_RGB4 0x804F
+#define GL_RGB5 0x8050
+#define GL_RGB5_A1 0x8057
+#define GL_RGB8 0x8051
+#define GL_RGBA 0x1908
+#define GL_RGBA12 0x805A
+#define GL_RGBA16 0x805B
+#define GL_RGBA2 0x8055
+#define GL_RGBA4 0x8056
+#define GL_RGBA8 0x8058
+#define GL_RIGHT 0x0407
+#define GL_SCISSOR_BOX 0x0C10
+#define GL_SCISSOR_TEST 0x0C11
+#define GL_SET 0x150F
+#define GL_SHORT 0x1402
+#define GL_SRC_ALPHA 0x0302
+#define GL_SRC_ALPHA_SATURATE 0x0308
+#define GL_SRC_COLOR 0x0300
+#define GL_STENCIL 0x1802
+#define GL_STENCIL_BUFFER_BIT 0x00000400
+#define GL_STENCIL_CLEAR_VALUE 0x0B91
+#define GL_STENCIL_FAIL 0x0B94
+#define GL_STENCIL_FUNC 0x0B92
+#define GL_STENCIL_INDEX 0x1901
+#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
+#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
+#define GL_STENCIL_REF 0x0B97
+#define GL_STENCIL_TEST 0x0B90
+#define GL_STENCIL_VALUE_MASK 0x0B93
+#define GL_STENCIL_WRITEMASK 0x0B98
+#define GL_STEREO 0x0C33
+#define GL_SUBPIXEL_BITS 0x0D50
+#define GL_TEXTURE 0x1702
+#define GL_TEXTURE_1D 0x0DE0
+#define GL_TEXTURE_2D 0x0DE1
+#define GL_TEXTURE_ALPHA_SIZE 0x805F
+#define GL_TEXTURE_BINDING_1D 0x8068
+#define GL_TEXTURE_BINDING_2D 0x8069
+#define GL_TEXTURE_BLUE_SIZE 0x805E
+#define GL_TEXTURE_BORDER_COLOR 0x1004
+#define GL_TEXTURE_GREEN_SIZE 0x805D
+#define GL_TEXTURE_HEIGHT 0x1001
+#define GL_TEXTURE_INTERNAL_FORMAT 0x1003
+#define GL_TEXTURE_MAG_FILTER 0x2800
+#define GL_TEXTURE_MIN_FILTER 0x2801
+#define GL_TEXTURE_RED_SIZE 0x805C
+#define GL_TEXTURE_WIDTH 0x1000
+#define GL_TEXTURE_WRAP_S 0x2802
+#define GL_TEXTURE_WRAP_T 0x2803
+#define GL_TRIANGLES 0x0004
+#define GL_TRIANGLE_FAN 0x0006
+#define GL_TRIANGLE_STRIP 0x0005
+#define GL_TRUE 1
+#define GL_UNPACK_ALIGNMENT 0x0CF5
+#define GL_UNPACK_LSB_FIRST 0x0CF1
+#define GL_UNPACK_ROW_LENGTH 0x0CF2
+#define GL_UNPACK_SKIP_PIXELS 0x0CF4
+#define GL_UNPACK_SKIP_ROWS 0x0CF3
+#define GL_UNPACK_SWAP_BYTES 0x0CF0
+#define GL_UNSIGNED_BYTE 0x1401
+#define GL_UNSIGNED_INT 0x1405
+#define GL_UNSIGNED_SHORT 0x1403
+#define GL_VENDOR 0x1F00
+#define GL_VERSION 0x1F02
+#define GL_VIEWPORT 0x0BA2
+#define GL_XOR 0x1506
+#define GL_ZERO 0
+
+// 1.2
+#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
+#define GL_BGR 0x80E0
+#define GL_BGRA 0x80E1
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_MAX_3D_TEXTURE_SIZE 0x8073
+#define GL_MAX_ELEMENTS_INDICES 0x80E9
+#define GL_MAX_ELEMENTS_VERTICES 0x80E8
+#define GL_PACK_IMAGE_HEIGHT 0x806C
+#define GL_PACK_SKIP_IMAGES 0x806B
+#define GL_PROXY_TEXTURE_3D 0x8070
+#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23
+#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22
+#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13
+#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12
+#define GL_TEXTURE_3D 0x806F
+#define GL_TEXTURE_BASE_LEVEL 0x813C
+#define GL_TEXTURE_BINDING_3D 0x806A
+#define GL_TEXTURE_DEPTH 0x8071
+#define GL_TEXTURE_MAX_LEVEL 0x813D
+#define GL_TEXTURE_MAX_LOD 0x813B
+#define GL_TEXTURE_MIN_LOD 0x813A
+#define GL_TEXTURE_WRAP_R 0x8072
+#define GL_UNPACK_IMAGE_HEIGHT 0x806E
+#define GL_UNPACK_SKIP_IMAGES 0x806D
+#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362
+#define GL_UNSIGNED_BYTE_3_3_2 0x8032
+#define GL_UNSIGNED_INT_10_10_10_2 0x8036
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#define GL_UNSIGNED_INT_8_8_8_8 0x8035
+#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
+#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
+
+// 1.2 Extensions
+#define GL_ALL_COMPLETED_NV 0x84F2
+#define GL_FENCE_STATUS_NV 0x84F3
+#define GL_FENCE_CONDITION_NV 0x84F4
+
+// 1.3
+#define GL_ACTIVE_TEXTURE 0x84E0
+#define GL_CLAMP_TO_BORDER 0x812D
+#define GL_COMPRESSED_RGB 0x84ED
+#define GL_COMPRESSED_RGBA 0x84EE
+#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
+#define GL_MULTISAMPLE 0x809D
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B
+#define GL_SAMPLES 0x80A9
+#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE 0x809F
+#define GL_SAMPLE_BUFFERS 0x80A8
+#define GL_SAMPLE_COVERAGE 0x80A0
+#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
+#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
+#define GL_TEXTURE0 0x84C0
+#define GL_TEXTURE1 0x84C1
+#define GL_TEXTURE10 0x84CA
+#define GL_TEXTURE11 0x84CB
+#define GL_TEXTURE12 0x84CC
+#define GL_TEXTURE13 0x84CD
+#define GL_TEXTURE14 0x84CE
+#define GL_TEXTURE15 0x84CF
+#define GL_TEXTURE16 0x84D0
+#define GL_TEXTURE17 0x84D1
+#define GL_TEXTURE18 0x84D2
+#define GL_TEXTURE19 0x84D3
+#define GL_TEXTURE2 0x84C2
+#define GL_TEXTURE20 0x84D4
+#define GL_TEXTURE21 0x84D5
+#define GL_TEXTURE22 0x84D6
+#define GL_TEXTURE23 0x84D7
+#define GL_TEXTURE24 0x84D8
+#define GL_TEXTURE25 0x84D9
+#define GL_TEXTURE26 0x84DA
+#define GL_TEXTURE27 0x84DB
+#define GL_TEXTURE28 0x84DC
+#define GL_TEXTURE29 0x84DD
+#define GL_TEXTURE3 0x84C3
+#define GL_TEXTURE30 0x84DE
+#define GL_TEXTURE31 0x84DF
+#define GL_TEXTURE4 0x84C4
+#define GL_TEXTURE5 0x84C5
+#define GL_TEXTURE6 0x84C6
+#define GL_TEXTURE7 0x84C7
+#define GL_TEXTURE8 0x84C8
+#define GL_TEXTURE9 0x84C9
+#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
+#define GL_TEXTURE_COMPRESSED 0x86A1
+#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0
+#define GL_TEXTURE_COMPRESSION_HINT 0x84EF
+#define GL_TEXTURE_CUBE_MAP 0x8513
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+
+// 1.5
+#define GL_BLEND_COLOR 0x8005
+#define GL_BLEND_DST_ALPHA 0x80CA
+#define GL_BLEND_DST_RGB 0x80C8
+#define GL_BLEND_EQUATION 0x8009
+#define GL_BLEND_SRC_ALPHA 0x80CB
+#define GL_BLEND_SRC_RGB 0x80C9
+#define GL_CONSTANT_ALPHA 0x8003
+#define GL_CONSTANT_COLOR 0x8001
+#define GL_DECR_WRAP 0x8508
+#define GL_DEPTH_COMPONENT16 0x81A5
+#define GL_DEPTH_COMPONENT24 0x81A6
+#define GL_DEPTH_COMPONENT32 0x81A7
+#define GL_FUNC_ADD 0x8006
+#define GL_FUNC_REVERSE_SUBTRACT 0x800B
+#define GL_FUNC_SUBTRACT 0x800A
+#define GL_INCR_WRAP 0x8507
+#define GL_MAX 0x8008
+#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
+#define GL_MIN 0x8007
+#define GL_MIRRORED_REPEAT 0x8370
+#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128
+#define GL_TEXTURE_COMPARE_FUNC 0x884D
+#define GL_TEXTURE_COMPARE_MODE 0x884C
+#define GL_TEXTURE_DEPTH_SIZE 0x884A
+#define GL_TEXTURE_LOD_BIAS 0x8501
+
+// 1.5
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_ARRAY_BUFFER_BINDING 0x8894
+#define GL_BUFFER_ACCESS 0x88BB
+#define GL_BUFFER_MAPPED 0x88BC
+#define GL_BUFFER_MAP_POINTER 0x88BD
+#define GL_BUFFER_SIZE 0x8764
+#define GL_BUFFER_USAGE 0x8765
+#define GL_CURRENT_QUERY 0x8865
+#define GL_DYNAMIC_COPY 0x88EA
+#define GL_DYNAMIC_DRAW 0x88E8
+#define GL_DYNAMIC_READ 0x88E9
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+#define GL_QUERY_COUNTER_BITS 0x8864
+#define GL_QUERY_RESULT 0x8866
+#define GL_QUERY_RESULT_AVAILABLE 0x8867
+#define GL_READ_ONLY 0x88B8
+#define GL_READ_WRITE 0x88BA
+#define GL_SAMPLES_PASSED 0x8914
+#define GL_SRC1_ALPHA 0x8589
+#define GL_STATIC_COPY 0x88E6
+#define GL_STATIC_DRAW 0x88E4
+#define GL_STATIC_READ 0x88E5
+#define GL_STREAM_COPY 0x88E2
+#define GL_STREAM_DRAW 0x88E0
+#define GL_STREAM_READ 0x88E1
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+#define GL_WRITE_ONLY 0x88B9
+
+// 2.0
+#define GL_ACTIVE_ATTRIBUTES 0x8B89
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
+#define GL_ACTIVE_UNIFORMS 0x8B86
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
+#define GL_ATTACHED_SHADERS 0x8B85
+#define GL_BLEND_EQUATION_ALPHA 0x883D
+#define GL_BLEND_EQUATION_RGB 0x8009
+#define GL_BOOL 0x8B56
+#define GL_BOOL_VEC2 0x8B57
+#define GL_BOOL_VEC3 0x8B58
+#define GL_BOOL_VEC4 0x8B59
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_CURRENT_PROGRAM 0x8B8D
+#define GL_CURRENT_VERTEX_ATTRIB 0x8626
+#define GL_DELETE_STATUS 0x8B80
+#define GL_DRAW_BUFFER0 0x8825
+#define GL_DRAW_BUFFER1 0x8826
+#define GL_DRAW_BUFFER10 0x882F
+#define GL_DRAW_BUFFER11 0x8830
+#define GL_DRAW_BUFFER12 0x8831
+#define GL_DRAW_BUFFER13 0x8832
+#define GL_DRAW_BUFFER14 0x8833
+#define GL_DRAW_BUFFER15 0x8834
+#define GL_DRAW_BUFFER2 0x8827
+#define GL_DRAW_BUFFER3 0x8828
+#define GL_DRAW_BUFFER4 0x8829
+#define GL_DRAW_BUFFER5 0x882A
+#define GL_DRAW_BUFFER6 0x882B
+#define GL_DRAW_BUFFER7 0x882C
+#define GL_DRAW_BUFFER8 0x882D
+#define GL_DRAW_BUFFER9 0x882E
+#define GL_FLOAT_MAT2 0x8B5A
+#define GL_FLOAT_MAT3 0x8B5B
+#define GL_FLOAT_MAT4 0x8B5C
+#define GL_FLOAT_VEC2 0x8B50
+#define GL_FLOAT_VEC3 0x8B51
+#define GL_FLOAT_VEC4 0x8B52
+#define GL_FRAGMENT_SHADER 0x8B30
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B
+#define GL_INFO_LOG_LENGTH 0x8B84
+#define GL_INT_VEC2 0x8B53
+#define GL_INT_VEC3 0x8B54
+#define GL_INT_VEC4 0x8B55
+#define GL_LINK_STATUS 0x8B82
+#define GL_LOWER_LEFT 0x8CA1
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#define GL_MAX_DRAW_BUFFERS 0x8824
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
+#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
+#define GL_MAX_VARYING_FLOATS 0x8B4B
+#define GL_MAX_VERTEX_ATTRIBS 0x8869
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A
+#define GL_POINT_SPRITE 0x8861
+#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0
+#define GL_SAMPLER_1D 0x8B5D
+#define GL_SAMPLER_1D_SHADOW 0x8B61
+#define GL_SAMPLER_2D 0x8B5E
+#define GL_SAMPLER_2D_SHADOW 0x8B62
+#define GL_SAMPLER_3D 0x8B5F
+#define GL_SAMPLER_CUBE 0x8B60
+#define GL_SHADER_SOURCE_LENGTH 0x8B88
+#define GL_SHADER_TYPE 0x8B4F
+#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
+#define GL_STENCIL_BACK_FAIL 0x8801
+#define GL_STENCIL_BACK_FUNC 0x8800
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
+#define GL_STENCIL_BACK_REF 0x8CA3
+#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
+#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
+#define GL_UPPER_LEFT 0x8CA2
+#define GL_VALIDATE_STATUS 0x8B83
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
+#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642
+#define GL_VERTEX_SHADER 0x8B31
+
+// 2.1
+#define GL_COMPRESSED_SRGB 0x8C48
+#define GL_COMPRESSED_SRGB_ALPHA 0x8C49
+#define GL_FLOAT_MAT2x3 0x8B65
+#define GL_FLOAT_MAT2x4 0x8B66
+#define GL_FLOAT_MAT3x2 0x8B67
+#define GL_FLOAT_MAT3x4 0x8B68
+#define GL_FLOAT_MAT4x2 0x8B69
+#define GL_FLOAT_MAT4x3 0x8B6A
+#define GL_PIXEL_PACK_BUFFER 0x88EB
+#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER 0x88EC
+#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
+#define GL_SRGB 0x8C40
+#define GL_SRGB8 0x8C41
+#define GL_SRGB8_ALPHA8 0x8C43
+#define GL_SRGB_ALPHA 0x8C42
+
+// 3.0
+#define GL_BGRA_INTEGER 0x8D9B
+#define GL_BGR_INTEGER 0x8D9A
+#define GL_BLUE_INTEGER 0x8D96
+#define GL_BUFFER_ACCESS_FLAGS 0x911F
+#define GL_BUFFER_MAP_LENGTH 0x9120
+#define GL_BUFFER_MAP_OFFSET 0x9121
+#define GL_CLAMP_READ_COLOR 0x891C
+#define GL_CLIP_DISTANCE0 0x3000
+#define GL_CLIP_DISTANCE1 0x3001
+#define GL_CLIP_DISTANCE2 0x3002
+#define GL_CLIP_DISTANCE3 0x3003
+#define GL_CLIP_DISTANCE4 0x3004
+#define GL_CLIP_DISTANCE5 0x3005
+#define GL_CLIP_DISTANCE6 0x3006
+#define GL_CLIP_DISTANCE7 0x3007
+#define GL_COLOR_ATTACHMENT0 0x8CE0
+#define GL_COLOR_ATTACHMENT1 0x8CE1
+#define GL_COLOR_ATTACHMENT10 0x8CEA
+#define GL_COLOR_ATTACHMENT11 0x8CEB
+#define GL_COLOR_ATTACHMENT12 0x8CEC
+#define GL_COLOR_ATTACHMENT13 0x8CED
+#define GL_COLOR_ATTACHMENT14 0x8CEE
+#define GL_COLOR_ATTACHMENT15 0x8CEF
+#define GL_COLOR_ATTACHMENT2 0x8CE2
+#define GL_COLOR_ATTACHMENT3 0x8CE3
+#define GL_COLOR_ATTACHMENT4 0x8CE4
+#define GL_COLOR_ATTACHMENT5 0x8CE5
+#define GL_COLOR_ATTACHMENT6 0x8CE6
+#define GL_COLOR_ATTACHMENT7 0x8CE7
+#define GL_COLOR_ATTACHMENT8 0x8CE8
+#define GL_COLOR_ATTACHMENT9 0x8CE9
+#define GL_COMPARE_REF_TO_TEXTURE 0x884E
+#define GL_COMPRESSED_RED 0x8225
+#define GL_COMPRESSED_RED_RGTC1 0x8DBB
+#define GL_COMPRESSED_RG 0x8226
+#define GL_COMPRESSED_RG_RGTC2 0x8DBD
+#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC
+#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE
+#define GL_CONTEXT_FLAGS 0x821E
+#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001
+#define GL_DEPTH24_STENCIL8 0x88F0
+#define GL_DEPTH32F_STENCIL8 0x8CAD
+#define GL_DEPTH_ATTACHMENT 0x8D00
+#define GL_DEPTH_COMPONENT32F 0x8CAC
+#define GL_DEPTH_STENCIL 0x84F9
+#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
+#define GL_DRAW_FRAMEBUFFER 0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_FIXED_ONLY 0x891D
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD
+#define GL_FRAMEBUFFER 0x8D40
+#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215
+#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211
+#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216
+#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212
+#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
+#define GL_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
+#define GL_FRAMEBUFFER_DEFAULT 0x8218
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
+#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
+#define GL_FRAMEBUFFER_SRGB 0x8DB9
+#define GL_FRAMEBUFFER_UNDEFINED 0x8219
+#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
+#define GL_GREEN_INTEGER 0x8D95
+#define GL_HALF_FLOAT 0x140B
+#define GL_INTERLEAVED_ATTRIBS 0x8C8C
+#define GL_INT_SAMPLER_1D 0x8DC9
+#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE
+#define GL_INT_SAMPLER_2D 0x8DCA
+#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF
+#define GL_INT_SAMPLER_3D 0x8DCB
+#define GL_INT_SAMPLER_CUBE 0x8DCC
+#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
+#define GL_MAJOR_VERSION 0x821B
+#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010
+#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
+#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004
+#define GL_MAP_READ_BIT 0x0001
+#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
+#define GL_MAP_WRITE_BIT 0x0002
+#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF
+#define GL_MAX_CLIP_DISTANCES 0x0D32
+#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF
+#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905
+#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
+#define GL_MAX_SAMPLES 0x8D57
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80
+#define GL_MAX_VARYING_COMPONENTS 0x8B4B
+#define GL_MINOR_VERSION 0x821C
+#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904
+#define GL_NUM_EXTENSIONS 0x821D
+#define GL_PRIMITIVES_GENERATED 0x8C87
+#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19
+#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B
+#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16
+#define GL_QUERY_BY_REGION_WAIT 0x8E15
+#define GL_QUERY_NO_WAIT 0x8E14
+#define GL_QUERY_WAIT 0x8E13
+#define GL_R11F_G11F_B10F 0x8C3A
+#define GL_R16 0x822A
+#define GL_R16F 0x822D
+#define GL_R16I 0x8233
+#define GL_R16UI 0x8234
+#define GL_R32F 0x822E
+#define GL_R32I 0x8235
+#define GL_R32UI 0x8236
+#define GL_R8 0x8229
+#define GL_R8I 0x8231
+#define GL_R8UI 0x8232
+#define GL_RASTERIZER_DISCARD 0x8C89
+#define GL_READ_FRAMEBUFFER 0x8CA8
+#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA
+#define GL_RED_INTEGER 0x8D94
+#define GL_RENDERBUFFER 0x8D41
+#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
+#define GL_RENDERBUFFER_BINDING 0x8CA7
+#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
+#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
+#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
+#define GL_RENDERBUFFER_HEIGHT 0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
+#define GL_RENDERBUFFER_RED_SIZE 0x8D50
+#define GL_RENDERBUFFER_SAMPLES 0x8CAB
+#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
+#define GL_RENDERBUFFER_WIDTH 0x8D42
+#define GL_RG 0x8227
+#define GL_RG16 0x822C
+#define GL_RG16F 0x822F
+#define GL_RG16I 0x8239
+#define GL_RG16UI 0x823A
+#define GL_RG32F 0x8230
+#define GL_RG32I 0x823B
+#define GL_RG32UI 0x823C
+#define GL_RG8 0x822B
+#define GL_RG8I 0x8237
+#define GL_RG8UI 0x8238
+#define GL_RGB16F 0x881B
+#define GL_RGB16I 0x8D89
+#define GL_RGB16UI 0x8D77
+#define GL_RGB32F 0x8815
+#define GL_RGB32I 0x8D83
+#define GL_RGB32UI 0x8D71
+#define GL_RGB8I 0x8D8F
+#define GL_RGB8UI 0x8D7D
+#define GL_RGB9_E5 0x8C3D
+#define GL_RGBA16F 0x881A
+#define GL_RGBA16I 0x8D88
+#define GL_RGBA16UI 0x8D76
+#define GL_RGBA32F 0x8814
+#define GL_RGBA32I 0x8D82
+#define GL_RGBA32UI 0x8D70
+#define GL_RGBA8I 0x8D8E
+#define GL_RGBA8UI 0x8D7C
+#define GL_RGBA_INTEGER 0x8D99
+#define GL_RGB_INTEGER 0x8D98
+#define GL_RG_INTEGER 0x8228
+#define GL_SAMPLER_1D_ARRAY 0x8DC0
+#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3
+#define GL_SAMPLER_2D_ARRAY 0x8DC1
+#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
+#define GL_SAMPLER_CUBE_SHADOW 0x8DC5
+#define GL_SEPARATE_ATTRIBS 0x8C8D
+#define GL_STENCIL_ATTACHMENT 0x8D20
+#define GL_STENCIL_INDEX1 0x8D46
+#define GL_STENCIL_INDEX16 0x8D49
+#define GL_STENCIL_INDEX4 0x8D47
+#define GL_STENCIL_INDEX8 0x8D48
+#define GL_TEXTURE_1D_ARRAY 0x8C18
+#define GL_TEXTURE_2D_ARRAY 0x8C1A
+#define GL_TEXTURE_ALPHA_TYPE 0x8C13
+#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C
+#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D
+#define GL_TEXTURE_BLUE_TYPE 0x8C12
+#define GL_TEXTURE_DEPTH_TYPE 0x8C16
+#define GL_TEXTURE_GREEN_TYPE 0x8C11
+#define GL_TEXTURE_RED_TYPE 0x8C10
+#define GL_TEXTURE_SHARED_SIZE 0x8C3F
+#define GL_TEXTURE_STENCIL_SIZE 0x88F1
+#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88
+#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76
+#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
+#define GL_UNSIGNED_INT_24_8 0x84FA
+#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E
+#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1
+#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6
+#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7
+#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4
+#define GL_UNSIGNED_INT_VEC2 0x8DC6
+#define GL_UNSIGNED_INT_VEC3 0x8DC7
+#define GL_UNSIGNED_INT_VEC4 0x8DC8
+#define GL_UNSIGNED_NORMALIZED 0x8C17
+#define GL_VERTEX_ARRAY_BINDING 0x85B5
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD
+
+// 3.1
+#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36
+#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35
+#define GL_COPY_READ_BUFFER 0x8F36
+#define GL_COPY_WRITE_BUFFER 0x8F37
+#define GL_INT_SAMPLER_2D_RECT 0x8DCD
+#define GL_INT_SAMPLER_BUFFER 0x8DD0
+#define GL_INVALID_INDEX 0xFFFFFFFFu
+#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33
+#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E
+#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31
+#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8
+#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B
+#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
+#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F
+#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B
+#define GL_PRIMITIVE_RESTART 0x8F9D
+#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E
+#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7
+#define GL_R16_SNORM 0x8F98
+#define GL_R8_SNORM 0x8F94
+#define GL_RG16_SNORM 0x8F99
+#define GL_RG8_SNORM 0x8F95
+#define GL_RGB16_SNORM 0x8F9A
+#define GL_RGB8_SNORM 0x8F96
+#define GL_RGBA16_SNORM 0x8F9B
+#define GL_RGBA8_SNORM 0x8F97
+#define GL_SAMPLER_2D_RECT 0x8B63
+#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64
+#define GL_SAMPLER_BUFFER 0x8DC2
+#define GL_SIGNED_NORMALIZED 0x8F9C
+#define GL_TEXTURE_BINDING_BUFFER 0x8C2C
+#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6
+#define GL_TEXTURE_BUFFER 0x8C2A
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D
+#define GL_TEXTURE_RECTANGLE 0x84F5
+#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43
+#define GL_UNIFORM_BLOCK_BINDING 0x8A3F
+#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40
+#define GL_UNIFORM_BLOCK_INDEX 0x8A3A
+#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44
+#define GL_UNIFORM_BUFFER 0x8A11
+#define GL_UNIFORM_BUFFER_BINDING 0x8A28
+#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34
+#define GL_UNIFORM_BUFFER_SIZE 0x8A2A
+#define GL_UNIFORM_BUFFER_START 0x8A29
+#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E
+#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D
+#define GL_UNIFORM_NAME_LENGTH 0x8A39
+#define GL_UNIFORM_OFFSET 0x8A3B
+#define GL_UNIFORM_SIZE 0x8A38
+#define GL_UNIFORM_TYPE 0x8A37
+#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8
+
+// 3.2
+#define GL_ALREADY_SIGNALED 0x911A
+#define GL_CONDITION_SATISFIED 0x911C
+#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
+#define GL_CONTEXT_PROFILE_MASK 0x9126
+#define GL_DEPTH_CLAMP 0x864F
+#define GL_FIRST_VERTEX_CONVENTION 0x8E4D
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8
+#define GL_GEOMETRY_INPUT_TYPE 0x8917
+#define GL_GEOMETRY_OUTPUT_TYPE 0x8918
+#define GL_GEOMETRY_SHADER 0x8DD9
+#define GL_GEOMETRY_VERTICES_OUT 0x8916
+#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109
+#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C
+#define GL_LAST_VERTEX_CONVENTION 0x8E4E
+#define GL_LINES_ADJACENCY 0x000A
+#define GL_LINE_STRIP_ADJACENCY 0x000B
+#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E
+#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F
+#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125
+#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123
+#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF
+#define GL_MAX_INTEGER_SAMPLES 0x9110
+#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59
+#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
+#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
+#define GL_OBJECT_TYPE 0x9112
+#define GL_PROGRAM_POINT_SIZE 0x8642
+#define GL_PROVOKING_VERTEX 0x8E4F
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103
+#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C
+#define GL_SAMPLER_2D_MULTISAMPLE 0x9108
+#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B
+#define GL_SAMPLE_MASK 0x8E51
+#define GL_SAMPLE_MASK_VALUE 0x8E52
+#define GL_SAMPLE_POSITION 0x8E50
+#define GL_SIGNALED 0x9119
+#define GL_SYNC_CONDITION 0x9113
+#define GL_SYNC_FENCE 0x9116
+#define GL_SYNC_FLAGS 0x9115
+#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
+#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
+#define GL_SYNC_STATUS 0x9114
+#define GL_TEXTURE_2D_MULTISAMPLE 0x9100
+#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105
+#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F
+#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107
+#define GL_TEXTURE_SAMPLES 0x9106
+#define GL_TIMEOUT_EXPIRED 0x911B
+#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
+#define GL_TRIANGLES_ADJACENCY 0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D
+#define GL_UNSIGNALED 0x9118
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D
+#define GL_WAIT_FAILED 0x911D
+
+// 3.3
+#define GL_ANY_SAMPLES_PASSED 0x8C2F
+#define GL_INT_2_10_10_10_REV 0x8D9F
+#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC
+#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB
+#define GL_ONE_MINUS_SRC1_COLOR 0x88FA
+#define GL_RGB10_A2UI 0x906F
+#define GL_SAMPLER_BINDING 0x8919
+#define GL_SRC1_COLOR 0x88F9
+#define GL_TEXTURE_SWIZZLE_A 0x8E45
+#define GL_TEXTURE_SWIZZLE_B 0x8E44
+#define GL_TEXTURE_SWIZZLE_G 0x8E43
+#define GL_TEXTURE_SWIZZLE_R 0x8E42
+#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
+#define GL_TIMESTAMP 0x8E28
+#define GL_TIME_ELAPSED 0x88BF
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE
+
+// 4.0
+#define GL_ACTIVE_SUBROUTINES 0x8DE5
+#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48
+#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6
+#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47
+#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49
+#define GL_COMPATIBLE_SUBROUTINES 0x8E4B
+#define GL_DOUBLE_MAT2 0x8F46
+#define GL_DOUBLE_MAT2x3 0x8F49
+#define GL_DOUBLE_MAT2x4 0x8F4A
+#define GL_DOUBLE_MAT3 0x8F47
+#define GL_DOUBLE_MAT3x2 0x8F4B
+#define GL_DOUBLE_MAT3x4 0x8F4C
+#define GL_DOUBLE_MAT4 0x8F48
+#define GL_DOUBLE_MAT4x2 0x8F4D
+#define GL_DOUBLE_MAT4x3 0x8F4E
+#define GL_DOUBLE_VEC2 0x8FFC
+#define GL_DOUBLE_VEC3 0x8FFD
+#define GL_DOUBLE_VEC4 0x8FFE
+#define GL_DRAW_INDIRECT_BUFFER 0x8F3F
+#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43
+#define GL_FRACTIONAL_EVEN 0x8E7C
+#define GL_FRACTIONAL_ODD 0x8E7B
+#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D
+#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E
+#define GL_ISOLINES 0x8E7A
+#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E
+#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F
+#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C
+#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A
+#define GL_MAX_PATCH_VERTICES 0x8E7D
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F
+#define GL_MAX_SUBROUTINES 0x8DE7
+#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8
+#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C
+#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83
+#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81
+#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85
+#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89
+#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F
+#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D
+#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86
+#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82
+#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A
+#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80
+#define GL_MAX_TESS_GEN_LEVEL 0x8E7E
+#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84
+#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70
+#define GL_MAX_VERTEX_STREAMS 0x8E71
+#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E
+#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37
+#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A
+#define GL_PATCHES 0x000E
+#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73
+#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74
+#define GL_PATCH_VERTICES 0x8E72
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B
+#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D
+#define GL_SAMPLE_SHADING 0x8C36
+#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75
+#define GL_TESS_CONTROL_SHADER 0x8E88
+#define GL_TESS_EVALUATION_SHADER 0x8E87
+#define GL_TESS_GEN_MODE 0x8E76
+#define GL_TESS_GEN_POINT_MODE 0x8E79
+#define GL_TESS_GEN_SPACING 0x8E77
+#define GL_TESS_GEN_VERTEX_ORDER 0x8E78
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A
+#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009
+#define GL_TRANSFORM_FEEDBACK 0x8E22
+#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25
+#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F
+
+// 4.1
+#define GL_ACTIVE_PROGRAM 0x8259
+#define GL_ALL_SHADER_BITS 0xFFFFFFFF
+#define GL_FIXED 0x140C
+#define GL_FRAGMENT_SHADER_BIT 0x00000002
+#define GL_GEOMETRY_SHADER_BIT 0x00000004
+#define GL_HIGH_FLOAT 0x8DF2
+#define GL_HIGH_INT 0x8DF5
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
+#define GL_LAYER_PROVOKING_VERTEX 0x825E
+#define GL_LOW_FLOAT 0x8DF0
+#define GL_LOW_INT 0x8DF3
+#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
+#define GL_MAX_VARYING_VECTORS 0x8DFC
+#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
+#define GL_MAX_VIEWPORTS 0x825B
+#define GL_MEDIUM_FLOAT 0x8DF1
+#define GL_MEDIUM_INT 0x8DF4
+#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
+#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
+#define GL_PROGRAM_BINARY_FORMATS 0x87FF
+#define GL_PROGRAM_BINARY_LENGTH 0x8741
+#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257
+#define GL_PROGRAM_PIPELINE_BINDING 0x825A
+#define GL_PROGRAM_SEPARABLE 0x8258
+#define GL_RGB565 0x8D62
+#define GL_SHADER_BINARY_FORMATS 0x8DF8
+#define GL_SHADER_COMPILER 0x8DFA
+#define GL_TESS_CONTROL_SHADER_BIT 0x00000008
+#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010
+#define GL_UNDEFINED_VERTEX 0x8260
+#define GL_VERTEX_SHADER_BIT 0x00000001
+#define GL_VIEWPORT_BOUNDS_RANGE 0x825D
+#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F
+#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C
+
+// 4.2
+#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9
+#define GL_ALL_BARRIER_BITS 0xFFFFFFFF
+#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000
+#define GL_ATOMIC_COUNTER_BUFFER 0x92C0
+#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5
+#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6
+#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1
+#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7
+#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3
+#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2
+#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200
+#define GL_COMMAND_BARRIER_BIT 0x00000040
+#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C
+#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E
+#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F
+#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D
+#define GL_COPY_READ_BUFFER_BINDING 0x8F36
+#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37
+#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002
+#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400
+#define GL_IMAGE_1D 0x904C
+#define GL_IMAGE_1D_ARRAY 0x9052
+#define GL_IMAGE_2D 0x904D
+#define GL_IMAGE_2D_ARRAY 0x9053
+#define GL_IMAGE_2D_MULTISAMPLE 0x9055
+#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056
+#define GL_IMAGE_2D_RECT 0x904F
+#define GL_IMAGE_3D 0x904E
+#define GL_IMAGE_BINDING_ACCESS 0x8F3E
+#define GL_IMAGE_BINDING_FORMAT 0x906E
+#define GL_IMAGE_BINDING_LAYER 0x8F3D
+#define GL_IMAGE_BINDING_LAYERED 0x8F3C
+#define GL_IMAGE_BINDING_LEVEL 0x8F3B
+#define GL_IMAGE_BINDING_NAME 0x8F3A
+#define GL_IMAGE_BUFFER 0x9051
+#define GL_IMAGE_CUBE 0x9050
+#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054
+#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9
+#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8
+#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7
+#define GL_INT_IMAGE_1D 0x9057
+#define GL_INT_IMAGE_1D_ARRAY 0x905D
+#define GL_INT_IMAGE_2D 0x9058
+#define GL_INT_IMAGE_2D_ARRAY 0x905E
+#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060
+#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061
+#define GL_INT_IMAGE_2D_RECT 0x905A
+#define GL_INT_IMAGE_3D 0x9059
+#define GL_INT_IMAGE_BUFFER 0x905C
+#define GL_INT_IMAGE_CUBE 0x905B
+#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F
+#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC
+#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8
+#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7
+#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1
+#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF
+#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39
+#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6
+#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0
+#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF
+#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD
+#define GL_MAX_IMAGE_SAMPLES 0x906D
+#define GL_MAX_IMAGE_UNITS 0x8F38
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD
+#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE
+#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC
+#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2
+#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC
+#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA
+#define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC
+#define GL_NUM_SAMPLE_COUNTS 0x9380
+#define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D
+#define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C
+#define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E
+#define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B
+#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080
+#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020
+#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008
+#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F
+#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100
+#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800
+#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23
+#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA
+#define GL_UNIFORM_BARRIER_BIT 0x00000004
+#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129
+#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128
+#define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A
+#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127
+#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB
+#define GL_UNSIGNED_INT_IMAGE_1D 0x9062
+#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068
+#define GL_UNSIGNED_INT_IMAGE_2D 0x9063
+#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C
+#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065
+#define GL_UNSIGNED_INT_IMAGE_3D 0x9064
+#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067
+#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066
+#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A
+#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001
+
+// 4.3
+#define GL_ACTIVE_RESOURCES 0x92F5
+#define GL_ACTIVE_VARIABLES 0x9305
+#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A
+#define GL_ARRAY_SIZE 0x92FB
+#define GL_ARRAY_STRIDE 0x92FE
+#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED
+#define GL_AUTO_GENERATE_MIPMAP 0x8295
+#define GL_BLOCK_INDEX 0x92FD
+#define GL_BUFFER 0x82E0
+#define GL_BUFFER_BINDING 0x9302
+#define GL_BUFFER_DATA_SIZE 0x9303
+#define GL_BUFFER_VARIABLE 0x92E5
+#define GL_CAVEAT_SUPPORT 0x82B8
+#define GL_CLEAR_BUFFER 0x82B4
+#define GL_COLOR_COMPONENTS 0x8283
+#define GL_COLOR_ENCODING 0x8296
+#define GL_COLOR_RENDERABLE 0x8286
+#define GL_COMPRESSED_R11_EAC 0x9270
+#define GL_COMPRESSED_RG11_EAC 0x9272
+#define GL_COMPRESSED_RGB8_ETC2 0x9274
+#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
+#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
+#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
+#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
+#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
+#define GL_COMPRESSED_SRGB8_ETC2 0x9275
+#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
+#define GL_COMPUTE_SHADER 0x91B9
+#define GL_COMPUTE_SHADER_BIT 0x00000020
+#define GL_COMPUTE_SUBROUTINE 0x92ED
+#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3
+#define GL_COMPUTE_TEXTURE 0x82A0
+#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267
+#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
+#define GL_DEBUG_CALLBACK_FUNCTION 0x8244
+#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245
+#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D
+#define GL_DEBUG_LOGGED_MESSAGES 0x9145
+#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243
+#define GL_DEBUG_OUTPUT 0x92E0
+#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
+#define GL_DEBUG_SEVERITY_HIGH 0x9146
+#define GL_DEBUG_SEVERITY_LOW 0x9148
+#define GL_DEBUG_SEVERITY_MEDIUM 0x9147
+#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B
+#define GL_DEBUG_SOURCE_API 0x8246
+#define GL_DEBUG_SOURCE_APPLICATION 0x824A
+#define GL_DEBUG_SOURCE_OTHER 0x824B
+#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248
+#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249
+#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247
+#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D
+#define GL_DEBUG_TYPE_ERROR 0x824C
+#define GL_DEBUG_TYPE_MARKER 0x8268
+#define GL_DEBUG_TYPE_OTHER 0x8251
+#define GL_DEBUG_TYPE_PERFORMANCE 0x8250
+#define GL_DEBUG_TYPE_POP_GROUP 0x826A
+#define GL_DEBUG_TYPE_PORTABILITY 0x824F
+#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269
+#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E
+#define GL_DEPTH_COMPONENTS 0x8284
+#define GL_DEPTH_RENDERABLE 0x8287
+#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA
+#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE
+#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF
+#define GL_FILTER 0x829A
+#define GL_FRAGMENT_SUBROUTINE 0x92EC
+#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2
+#define GL_FRAGMENT_TEXTURE 0x829F
+#define GL_FRAMEBUFFER_BLEND 0x828B
+#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314
+#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311
+#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312
+#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313
+#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310
+#define GL_FRAMEBUFFER_RENDERABLE 0x8289
+#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A
+#define GL_FULL_SUPPORT 0x82B7
+#define GL_GEOMETRY_SUBROUTINE 0x92EB
+#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1
+#define GL_GEOMETRY_TEXTURE 0x829E
+#define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291
+#define GL_GET_TEXTURE_IMAGE_TYPE 0x8292
+#define GL_IMAGE_CLASS_10_10_10_2 0x82C3
+#define GL_IMAGE_CLASS_11_11_10 0x82C2
+#define GL_IMAGE_CLASS_1_X_16 0x82BE
+#define GL_IMAGE_CLASS_1_X_32 0x82BB
+#define GL_IMAGE_CLASS_1_X_8 0x82C1
+#define GL_IMAGE_CLASS_2_X_16 0x82BD
+#define GL_IMAGE_CLASS_2_X_32 0x82BA
+#define GL_IMAGE_CLASS_2_X_8 0x82C0
+#define GL_IMAGE_CLASS_4_X_16 0x82BC
+#define GL_IMAGE_CLASS_4_X_32 0x82B9
+#define GL_IMAGE_CLASS_4_X_8 0x82BF
+#define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8
+#define GL_IMAGE_PIXEL_FORMAT 0x82A9
+#define GL_IMAGE_PIXEL_TYPE 0x82AA
+#define GL_IMAGE_TEXEL_SIZE 0x82A7
+#define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274
+#define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B
+#define GL_INTERNALFORMAT_BLUE_SIZE 0x8273
+#define GL_INTERNALFORMAT_BLUE_TYPE 0x827A
+#define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275
+#define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C
+#define GL_INTERNALFORMAT_GREEN_SIZE 0x8272
+#define GL_INTERNALFORMAT_GREEN_TYPE 0x8279
+#define GL_INTERNALFORMAT_PREFERRED 0x8270
+#define GL_INTERNALFORMAT_RED_SIZE 0x8271
+#define GL_INTERNALFORMAT_RED_TYPE 0x8278
+#define GL_INTERNALFORMAT_SHARED_SIZE 0x8277
+#define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276
+#define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D
+#define GL_INTERNALFORMAT_SUPPORTED 0x826F
+#define GL_IS_PER_PATCH 0x92E7
+#define GL_IS_ROW_MAJOR 0x9300
+#define GL_LOCATION 0x930E
+#define GL_LOCATION_INDEX 0x930F
+#define GL_MANUAL_GENERATE_MIPMAP 0x8294
+#define GL_MATRIX_STRIDE 0x92FF
+#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266
+#define GL_MAX_COMBINED_DIMENSIONS 0x8282
+#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39
+#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC
+#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265
+#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264
+#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD
+#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB
+#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262
+#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC
+#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB
+#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263
+#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE
+#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB
+#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF
+#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C
+#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144
+#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143
+#define GL_MAX_DEPTH 0x8280
+#define GL_MAX_ELEMENT_INDEX 0x8D6B
+#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA
+#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316
+#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317
+#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318
+#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315
+#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7
+#define GL_MAX_HEIGHT 0x827F
+#define GL_MAX_LABEL_LENGTH 0x82E8
+#define GL_MAX_LAYERS 0x8281
+#define GL_MAX_NAME_LENGTH 0x92F6
+#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7
+#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8
+#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE
+#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD
+#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8
+#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9
+#define GL_MAX_UNIFORM_LOCATIONS 0x826E
+#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA
+#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9
+#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6
+#define GL_MAX_WIDTH 0x827E
+#define GL_MIPMAP 0x8293
+#define GL_NAME_LENGTH 0x92F9
+#define GL_NUM_ACTIVE_VARIABLES 0x9304
+#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9
+#define GL_OFFSET 0x92FC
+#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69
+#define GL_PROGRAM 0x82E2
+#define GL_PROGRAM_INPUT 0x92E3
+#define GL_PROGRAM_OUTPUT 0x92E4
+#define GL_PROGRAM_PIPELINE 0x82E4
+#define GL_QUERY 0x82E3
+#define GL_READ_PIXELS 0x828C
+#define GL_READ_PIXELS_FORMAT 0x828D
+#define GL_READ_PIXELS_TYPE 0x828E
+#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B
+#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A
+#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309
+#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307
+#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308
+#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306
+#define GL_SAMPLER 0x82E6
+#define GL_SHADER 0x82E1
+#define GL_SHADER_IMAGE_ATOMIC 0x82A6
+#define GL_SHADER_IMAGE_LOAD 0x82A4
+#define GL_SHADER_IMAGE_STORE 0x82A5
+#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000
+#define GL_SHADER_STORAGE_BLOCK 0x92E6
+#define GL_SHADER_STORAGE_BUFFER 0x90D2
+#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3
+#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF
+#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5
+#define GL_SHADER_STORAGE_BUFFER_START 0x90D4
+#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC
+#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE
+#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD
+#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF
+#define GL_SRGB_READ 0x8297
+#define GL_SRGB_WRITE 0x8298
+#define GL_STENCIL_COMPONENTS 0x8285
+#define GL_STENCIL_RENDERABLE 0x8288
+#define GL_TESS_CONTROL_SUBROUTINE 0x92E9
+#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF
+#define GL_TESS_CONTROL_TEXTURE 0x829C
+#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA
+#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0
+#define GL_TESS_EVALUATION_TEXTURE 0x829D
+#define GL_TEXTURE_BUFFER_OFFSET 0x919D
+#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F
+#define GL_TEXTURE_BUFFER_SIZE 0x919E
+#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2
+#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3
+#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1
+#define GL_TEXTURE_GATHER 0x82A2
+#define GL_TEXTURE_GATHER_SHADOW 0x82A3
+#define GL_TEXTURE_IMAGE_FORMAT 0x828F
+#define GL_TEXTURE_IMAGE_TYPE 0x8290
+#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
+#define GL_TEXTURE_SHADOW 0x82A1
+#define GL_TEXTURE_VIEW 0x82B5
+#define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD
+#define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB
+#define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE
+#define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC
+#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C
+#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D
+#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4
+#define GL_TYPE 0x92FA
+#define GL_UNIFORM 0x92E1
+#define GL_UNIFORM_BLOCK 0x92E2
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC
+#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E
+#define GL_VERTEX_ATTRIB_BINDING 0x82D4
+#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5
+#define GL_VERTEX_BINDING_BUFFER 0x8F4F
+#define GL_VERTEX_BINDING_DIVISOR 0x82D6
+#define GL_VERTEX_BINDING_OFFSET 0x82D7
+#define GL_VERTEX_BINDING_STRIDE 0x82D8
+#define GL_VERTEX_SUBROUTINE 0x92E8
+#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE
+#define GL_VERTEX_TEXTURE 0x829B
+#define GL_VIEW_CLASS_128_BITS 0x82C4
+#define GL_VIEW_CLASS_16_BITS 0x82CA
+#define GL_VIEW_CLASS_24_BITS 0x82C9
+#define GL_VIEW_CLASS_32_BITS 0x82C8
+#define GL_VIEW_CLASS_48_BITS 0x82C7
+#define GL_VIEW_CLASS_64_BITS 0x82C6
+#define GL_VIEW_CLASS_8_BITS 0x82CB
+#define GL_VIEW_CLASS_96_BITS 0x82C5
+#define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3
+#define GL_VIEW_CLASS_BPTC_UNORM 0x82D2
+#define GL_VIEW_CLASS_RGTC1_RED 0x82D0
+#define GL_VIEW_CLASS_RGTC2_RG 0x82D1
+#define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC
+#define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD
+#define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE
+#define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF
+#define GL_VIEW_COMPATIBILITY_CLASS 0x82B6
+
+// 4.4
+#define GL_BUFFER_IMMUTABLE_STORAGE 0x821F
+#define GL_BUFFER_STORAGE_FLAGS 0x8220
+#define GL_CLEAR_TEXTURE 0x9365
+#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000
+#define GL_CLIENT_STORAGE_BIT 0x0200
+#define GL_DYNAMIC_STORAGE_BIT 0x0100
+#define GL_LOCATION_COMPONENT 0x934A
+#define GL_MAP_COHERENT_BIT 0x0080
+#define GL_MAP_PERSISTENT_BIT 0x0040
+#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5
+#define GL_MIRROR_CLAMP_TO_EDGE 0x8743
+#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221
+#define GL_QUERY_BUFFER 0x9192
+#define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000
+#define GL_QUERY_BUFFER_BINDING 0x9193
+#define GL_QUERY_RESULT_NO_WAIT 0x9194
+#define GL_TEXTURE_BUFFER_BINDING 0x8C2A
+#define GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B
+#define GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C
+
+// 4.5
+#define GL_CLIP_DEPTH_MODE 0x935D
+#define GL_CLIP_ORIGIN 0x935C
+#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004
+#define GL_CONTEXT_LOST 0x0507
+#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB
+#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC
+#define GL_GUILTY_CONTEXT_RESET 0x8253
+#define GL_INNOCENT_CONTEXT_RESET 0x8254
+#define GL_LOSE_CONTEXT_ON_RESET 0x8252
+#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES 0x82FA
+#define GL_MAX_CULL_DISTANCES 0x82F9
+#define GL_NEGATIVE_ONE_TO_ONE 0x935E
+#define GL_NO_RESET_NOTIFICATION 0x8261
+#define GL_QUERY_BY_REGION_NO_WAIT_INVERTED 0x8E1A
+#define GL_QUERY_BY_REGION_WAIT_INVERTED 0x8E19
+#define GL_QUERY_NO_WAIT_INVERTED 0x8E18
+#define GL_QUERY_TARGET 0x82EA
+#define GL_QUERY_WAIT_INVERTED 0x8E17
+#define GL_RESET_NOTIFICATION_STRATEGY 0x8256
+#define GL_TEXTURE_TARGET 0x1006
+#define GL_UNKNOWN_CONTEXT_RESET 0x8255
+#define GL_ZERO_TO_ONE 0x935F
+
+#endif // LIBANGLE_RENDERER_GL_FUNCTIONSGLENUMS_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/functionsgl_typedefs.h b/gfx/angle/src/libANGLE/renderer/gl/functionsgl_typedefs.h
new file mode 100755
index 000000000..daf7ff74e
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/functionsgl_typedefs.h
@@ -0,0 +1,758 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// functionsgl_typedefs.h: Typedefs of OpenGL types and functions for versions 1.0 through 4.5.
+
+#ifndef LIBANGLE_RENDERER_GL_FUNCTIONSGLTYPEDEFS_H_
+#define LIBANGLE_RENDERER_GL_FUNCTIONSGLTYPEDEFS_H_
+
+#include "common/platform.h"
+
+#include <KHR/khrplatform.h>
+#include <stdint.h>
+
+#ifndef INTERNAL_GL_APIENTRY
+# ifdef ANGLE_PLATFORM_WINDOWS
+# define INTERNAL_GL_APIENTRY __stdcall
+# else
+# define INTERNAL_GL_APIENTRY
+# endif
+#endif
+
+typedef void GLvoid;
+typedef char GLchar;
+typedef unsigned int GLenum;
+typedef unsigned char GLboolean;
+typedef unsigned int GLbitfield;
+typedef khronos_int8_t GLbyte;
+typedef short GLshort;
+typedef int GLint;
+typedef int GLsizei;
+typedef khronos_uint8_t GLubyte;
+typedef unsigned short GLushort;
+typedef unsigned int GLuint;
+typedef khronos_float_t GLfloat;
+typedef khronos_float_t GLclampf;
+typedef double GLdouble;
+typedef double GLclampd;
+typedef khronos_int32_t GLfixed;
+typedef khronos_intptr_t GLintptr;
+typedef khronos_ssize_t GLsizeiptr;
+typedef unsigned short GLhalf;
+typedef khronos_int64_t GLint64;
+typedef khronos_uint64_t GLuint64;
+typedef struct __GLsync *GLsync;
+
+namespace rx
+{
+typedef void (INTERNAL_GL_APIENTRY *GLDEBUGPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam);
+typedef void (INTERNAL_GL_APIENTRY *GLDEBUGPROCARB)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam);
+typedef void (INTERNAL_GL_APIENTRY *GLDEBUGPROCAMD)(GLuint id, GLenum category, GLenum severity, GLsizei length, const GLchar *message, void *userParam);
+
+// 1.0
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBLENDFUNCPROC)(GLenum, GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARPROC)(GLbitfield);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARCOLORPROC)(GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARDEPTHPROC)(GLdouble);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARSTENCILPROC)(GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCOLORMASKPROC)(GLboolean, GLboolean, GLboolean, GLboolean);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCULLFACEPROC)(GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDEPTHFUNCPROC)(GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDEPTHMASKPROC)(GLboolean);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDEPTHRANGEPROC)(GLdouble, GLdouble);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDISABLEPROC)(GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDRAWBUFFERPROC)(GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLENABLEPROC)(GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLFINISHPROC)();
+typedef void (INTERNAL_GL_APIENTRY *PFNGLFLUSHPROC)();
+typedef void (INTERNAL_GL_APIENTRY *PFNGLFRONTFACEPROC)(GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETBOOLEANVPROC)(GLenum, GLboolean *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETDOUBLEVPROC)(GLenum, GLdouble *);
+typedef GLenum (INTERNAL_GL_APIENTRY *PFNGLGETERRORPROC)();
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETFLOATVPROC)(GLenum, GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETINTEGERVPROC)(GLenum, GLint *);
+typedef const GLubyte * (INTERNAL_GL_APIENTRY *PFNGLGETSTRINGPROC)(GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETTEXIMAGEPROC)(GLenum, GLint, GLenum, GLenum, GLvoid *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETTEXLEVELPARAMETERFVPROC)(GLenum, GLint, GLenum, GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETTEXLEVELPARAMETERIVPROC)(GLenum, GLint, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETTEXPARAMETERFVPROC)(GLenum, GLenum, GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETTEXPARAMETERIVPROC)(GLenum, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLHINTPROC)(GLenum, GLenum);
+typedef GLboolean (INTERNAL_GL_APIENTRY *PFNGLISENABLEDPROC)(GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLLINEWIDTHPROC)(GLfloat);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLLOGICOPPROC)(GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPIXELSTOREFPROC)(GLenum, GLfloat);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPIXELSTOREIPROC)(GLenum, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPOINTSIZEPROC)(GLfloat);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPOLYGONMODEPROC)(GLenum, GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLREADBUFFERPROC)(GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLREADPIXELSPROC)(GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLSCISSORPROC)(GLint, GLint, GLsizei, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLSTENCILFUNCPROC)(GLenum, GLint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLSTENCILMASKPROC)(GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLSTENCILOPPROC)(GLenum, GLenum, GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXIMAGE1DPROC)(GLenum, GLint, GLint, GLsizei, GLint, GLenum, GLenum, const GLvoid *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXIMAGE2DPROC)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXPARAMETERFPROC)(GLenum, GLenum, GLfloat);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXPARAMETERFVPROC)(GLenum, GLenum, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXPARAMETERIPROC)(GLenum, GLenum, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXPARAMETERIVPROC)(GLenum, GLenum, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVIEWPORTPROC)(GLint, GLint, GLsizei, GLsizei);
+
+// 1.1
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBINDTEXTUREPROC)(GLenum, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCOPYTEXIMAGE1DPROC)(GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCOPYTEXIMAGE2DPROC)(GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCOPYTEXSUBIMAGE1DPROC)(GLenum, GLint, GLint, GLint, GLint, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCOPYTEXSUBIMAGE2DPROC)(GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDELETETEXTURESPROC)(GLsizei, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDRAWARRAYSPROC)(GLenum, GLint, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDRAWELEMENTSPROC)(GLenum, GLsizei, GLenum, const GLvoid *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGENTEXTURESPROC)(GLsizei, GLuint *);
+typedef GLboolean (INTERNAL_GL_APIENTRY *PFNGLISTEXTUREPROC)(GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPOLYGONOFFSETPROC)(GLfloat, GLfloat);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXSUBIMAGE1DPROC)(GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXSUBIMAGE2DPROC)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *);
+
+// 1.2
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBLENDCOLORPROC)(GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBLENDEQUATIONPROC)(GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCOPYTEXSUBIMAGE3DPROC)(GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDRAWRANGEELEMENTSPROC)(GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXIMAGE3DPROC)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXSUBIMAGE3DPROC)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *);
+
+// 1.2 Extensions
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDELETEFENCESNVPROC)(GLsizei, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGENFENCESNVPROC)(GLsizei, GLuint *);
+typedef GLboolean (INTERNAL_GL_APIENTRY *PFNGLISFENCENVPROC)(GLuint);
+typedef GLboolean (INTERNAL_GL_APIENTRY *PFNGLTESTFENCENVPROC)(GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETFENCEIVNVPROC)(GLuint, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLFINISHFENCENVPROC)(GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLSETFENCENVPROC)(GLuint, GLenum);
+
+// 1.3
+typedef void (INTERNAL_GL_APIENTRY *PFNGLACTIVETEXTUREPROC)(GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCOMPRESSEDTEXIMAGE1DPROC)(GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCOMPRESSEDTEXIMAGE2DPROC)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCOMPRESSEDTEXIMAGE3DPROC)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)(GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETCOMPRESSEDTEXIMAGEPROC)(GLenum, GLint, GLvoid *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLSAMPLECOVERAGEPROC)(GLfloat, GLboolean);
+
+// 1.4
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBLENDFUNCSEPARATEPROC)(GLenum, GLenum, GLenum, GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLMULTIDRAWARRAYSPROC)(GLenum, const GLint *, const GLsizei *, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLMULTIDRAWELEMENTSPROC)(GLenum, const GLsizei *, GLenum, const GLvoid *const*, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPOINTPARAMETERFPROC)(GLenum, GLfloat);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPOINTPARAMETERFVPROC)(GLenum, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPOINTPARAMETERIPROC)(GLenum, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPOINTPARAMETERIVPROC)(GLenum, const GLint *);
+
+// 1.5
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBEGINQUERYPROC)(GLenum, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBINDBUFFERPROC)(GLenum, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBUFFERDATAPROC)(GLenum, GLsizeiptr, const GLvoid *, GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBUFFERSUBDATAPROC)(GLenum, GLintptr, GLsizeiptr, const GLvoid *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDELETEBUFFERSPROC)(GLsizei, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDELETEQUERIESPROC)(GLsizei, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLENDQUERYPROC)(GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGENBUFFERSPROC)(GLsizei, GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGENQUERIESPROC)(GLsizei, GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETBUFFERPARAMETERIVPROC)(GLenum, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETBUFFERPOINTERVPROC)(GLenum, GLenum, GLvoid **);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETBUFFERSUBDATAPROC)(GLenum, GLintptr, GLsizeiptr, GLvoid *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETQUERYOBJECTIVPROC)(GLuint, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETQUERYOBJECTUIVPROC)(GLuint, GLenum, GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETQUERYIVPROC)(GLenum, GLenum, GLint *);
+typedef GLboolean (INTERNAL_GL_APIENTRY *PFNGLISBUFFERPROC)(GLuint);
+typedef GLboolean (INTERNAL_GL_APIENTRY *PFNGLISQUERYPROC)(GLuint);
+typedef void * (INTERNAL_GL_APIENTRY *PFNGLMAPBUFFERPROC)(GLenum, GLenum);
+typedef GLboolean (INTERNAL_GL_APIENTRY *PFNGLUNMAPBUFFERPROC)(GLenum);
+
+// 2.0
+typedef void (INTERNAL_GL_APIENTRY *PFNGLATTACHSHADERPROC)(GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBINDATTRIBLOCATIONPROC)(GLuint, GLuint, const GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBLENDEQUATIONSEPARATEPROC)(GLenum, GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCOMPILESHADERPROC)(GLuint);
+typedef GLuint (INTERNAL_GL_APIENTRY *PFNGLCREATEPROGRAMPROC)();
+typedef GLuint (INTERNAL_GL_APIENTRY *PFNGLCREATESHADERPROC)(GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDELETEPROGRAMPROC)(GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDELETESHADERPROC)(GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDETACHSHADERPROC)(GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDRAWBUFFERSPROC)(GLsizei, const GLenum *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETACTIVEATTRIBPROC)(GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETACTIVEUNIFORMPROC)(GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETATTACHEDSHADERSPROC)(GLuint, GLsizei, GLsizei *, GLuint *);
+typedef GLint (INTERNAL_GL_APIENTRY *PFNGLGETATTRIBLOCATIONPROC)(GLuint, const GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETPROGRAMINFOLOGPROC)(GLuint, GLsizei, GLsizei *, GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETPROGRAMIVPROC)(GLuint, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETSHADERINFOLOGPROC)(GLuint, GLsizei, GLsizei *, GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETSHADERSOURCEPROC)(GLuint, GLsizei, GLsizei *, GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETSHADERIVPROC)(GLuint, GLenum, GLint *);
+typedef GLint (INTERNAL_GL_APIENTRY *PFNGLGETUNIFORMLOCATIONPROC)(GLuint, const GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETUNIFORMFVPROC)(GLuint, GLint, GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETUNIFORMIVPROC)(GLuint, GLint, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETVERTEXATTRIBPOINTERVPROC)(GLuint, GLenum, GLvoid **);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint, GLenum, GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETVERTEXATTRIBFVPROC)(GLuint, GLenum, GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETVERTEXATTRIBIVPROC)(GLuint, GLenum, GLint *);
+typedef GLboolean (INTERNAL_GL_APIENTRY *PFNGLISPROGRAMPROC)(GLuint);
+typedef GLboolean (INTERNAL_GL_APIENTRY *PFNGLISSHADERPROC)(GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLLINKPROGRAMPROC)(GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLSHADERSOURCEPROC)(GLuint, GLsizei, const GLchar *const*, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLSTENCILFUNCSEPARATEPROC)(GLenum, GLenum, GLint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLSTENCILMASKSEPARATEPROC)(GLenum, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLSTENCILOPSEPARATEPROC)(GLenum, GLenum, GLenum, GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM1FPROC)(GLint, GLfloat);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM1FVPROC)(GLint, GLsizei, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM1IPROC)(GLint, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM1IVPROC)(GLint, GLsizei, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM2FPROC)(GLint, GLfloat, GLfloat);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM2FVPROC)(GLint, GLsizei, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM2IPROC)(GLint, GLint, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM2IVPROC)(GLint, GLsizei, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM3FPROC)(GLint, GLfloat, GLfloat, GLfloat);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM3FVPROC)(GLint, GLsizei, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM3IPROC)(GLint, GLint, GLint, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM3IVPROC)(GLint, GLsizei, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM4FPROC)(GLint, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM4FVPROC)(GLint, GLsizei, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM4IPROC)(GLint, GLint, GLint, GLint, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM4IVPROC)(GLint, GLsizei, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORMMATRIX2FVPROC)(GLint, GLsizei, GLboolean, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORMMATRIX3FVPROC)(GLint, GLsizei, GLboolean, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORMMATRIX4FVPROC)(GLint, GLsizei, GLboolean, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUSEPROGRAMPROC)(GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVALIDATEPROGRAMPROC)(GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB1DPROC)(GLuint, GLdouble);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB1DVPROC)(GLuint, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB1FPROC)(GLuint, GLfloat);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB1FVPROC)(GLuint, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB1SPROC)(GLuint, GLshort);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB1SVPROC)(GLuint, const GLshort *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB2DPROC)(GLuint, GLdouble, GLdouble);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB2DVPROC)(GLuint, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB2FPROC)(GLuint, GLfloat, GLfloat);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB2FVPROC)(GLuint, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB2SPROC)(GLuint, GLshort, GLshort);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB2SVPROC)(GLuint, const GLshort *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB3DPROC)(GLuint, GLdouble, GLdouble, GLdouble);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB3DVPROC)(GLuint, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB3FPROC)(GLuint, GLfloat, GLfloat, GLfloat);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB3FVPROC)(GLuint, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB3SPROC)(GLuint, GLshort, GLshort, GLshort);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB3SVPROC)(GLuint, const GLshort *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB4NBVPROC)(GLuint, const GLbyte *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB4NIVPROC)(GLuint, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB4NSVPROC)(GLuint, const GLshort *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB4NUBPROC)(GLuint, GLubyte, GLubyte, GLubyte, GLubyte);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB4NUBVPROC)(GLuint, const GLubyte *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB4NUIVPROC)(GLuint, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB4NUSVPROC)(GLuint, const GLushort *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB4BVPROC)(GLuint, const GLbyte *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB4DPROC)(GLuint, GLdouble, GLdouble, GLdouble, GLdouble);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB4DVPROC)(GLuint, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB4FPROC)(GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB4FVPROC)(GLuint, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB4IVPROC)(GLuint, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB4SPROC)(GLuint, GLshort, GLshort, GLshort, GLshort);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB4SVPROC)(GLuint, const GLshort *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB4UBVPROC)(GLuint, const GLubyte *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB4UIVPROC)(GLuint, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIB4USVPROC)(GLuint, const GLushort *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBPOINTERPROC)(GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *);
+
+// 2.1
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORMMATRIX2X3FVPROC)(GLint, GLsizei, GLboolean, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORMMATRIX2X4FVPROC)(GLint, GLsizei, GLboolean, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORMMATRIX3X2FVPROC)(GLint, GLsizei, GLboolean, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORMMATRIX3X4FVPROC)(GLint, GLsizei, GLboolean, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORMMATRIX4X2FVPROC)(GLint, GLsizei, GLboolean, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORMMATRIX4X3FVPROC)(GLint, GLsizei, GLboolean, const GLfloat *);
+
+// 3.0
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBEGINCONDITIONALRENDERPROC)(GLuint, GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBEGINTRANSFORMFEEDBACKPROC)(GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBINDBUFFERBASEPROC)(GLenum, GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBINDBUFFERRANGEPROC)(GLenum, GLuint, GLuint, GLintptr, GLsizeiptr);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBINDFRAGDATALOCATIONPROC)(GLuint, GLuint, const GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBINDFRAMEBUFFERPROC)(GLenum, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBINDRENDERBUFFERPROC)(GLenum, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBINDVERTEXARRAYPROC)(GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBLITFRAMEBUFFERPROC)(GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum);
+typedef GLenum (INTERNAL_GL_APIENTRY *PFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCLAMPCOLORPROC)(GLenum, GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARBUFFERFIPROC)(GLenum, GLint, GLfloat, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARBUFFERFVPROC)(GLenum, GLint, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARBUFFERIVPROC)(GLenum, GLint, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARBUFFERUIVPROC)(GLenum, GLint, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCOLORMASKIPROC)(GLuint, GLboolean, GLboolean, GLboolean, GLboolean);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDELETEFRAMEBUFFERSPROC)(GLsizei, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDELETERENDERBUFFERSPROC)(GLsizei, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDELETEVERTEXARRAYSPROC)(GLsizei, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDISABLEIPROC)(GLenum, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLENABLEIPROC)(GLenum, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLENDCONDITIONALRENDERPROC)();
+typedef void (INTERNAL_GL_APIENTRY *PFNGLENDTRANSFORMFEEDBACKPROC)();
+typedef void (INTERNAL_GL_APIENTRY *PFNGLFLUSHMAPPEDBUFFERRANGEPROC)(GLenum, GLintptr, GLsizeiptr);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLFRAMEBUFFERRENDERBUFFERPROC)(GLenum, GLenum, GLenum, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLFRAMEBUFFERTEXTURE1DPROC)(GLenum, GLenum, GLenum, GLuint, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLFRAMEBUFFERTEXTURE2DPROC)(GLenum, GLenum, GLenum, GLuint, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLFRAMEBUFFERTEXTURE3DPROC)(GLenum, GLenum, GLenum, GLuint, GLint, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLFRAMEBUFFERTEXTURELAYERPROC)(GLenum, GLenum, GLuint, GLint, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGENFRAMEBUFFERSPROC)(GLsizei, GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGENRENDERBUFFERSPROC)(GLsizei, GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGENVERTEXARRAYSPROC)(GLsizei, GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGENERATEMIPMAPPROC)(GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETBOOLEANI_VPROC)(GLenum, GLuint, GLboolean *);
+typedef GLint (INTERNAL_GL_APIENTRY *PFNGLGETFRAGDATALOCATIONPROC)(GLuint, const GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLenum, GLenum, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETINTEGERI_VPROC)(GLenum, GLuint, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETRENDERBUFFERPARAMETERIVPROC)(GLenum, GLenum, GLint *);
+typedef const GLubyte * (INTERNAL_GL_APIENTRY *PFNGLGETSTRINGIPROC)(GLenum, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETTEXPARAMETERIIVPROC)(GLenum, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETTEXPARAMETERIUIVPROC)(GLenum, GLenum, GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)(GLuint, GLuint, GLsizei, GLsizei *, GLsizei *, GLenum *, GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETUNIFORMUIVPROC)(GLuint, GLint, GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETVERTEXATTRIBIIVPROC)(GLuint, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETVERTEXATTRIBIUIVPROC)(GLuint, GLenum, GLuint *);
+typedef GLboolean (INTERNAL_GL_APIENTRY *PFNGLISENABLEDIPROC)(GLenum, GLuint);
+typedef GLboolean (INTERNAL_GL_APIENTRY *PFNGLISFRAMEBUFFERPROC)(GLuint);
+typedef GLboolean (INTERNAL_GL_APIENTRY *PFNGLISRENDERBUFFERPROC)(GLuint);
+typedef GLboolean (INTERNAL_GL_APIENTRY *PFNGLISVERTEXARRAYPROC)(GLuint);
+typedef void * (INTERNAL_GL_APIENTRY *PFNGLMAPBUFFERRANGEPROC)(GLenum, GLintptr, GLsizeiptr, GLbitfield);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLRENDERBUFFERSTORAGEPROC)(GLenum, GLenum, GLsizei, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLenum, GLsizei, GLenum, GLsizei, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXPARAMETERIIVPROC)(GLenum, GLenum, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXPARAMETERIUIVPROC)(GLenum, GLenum, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTRANSFORMFEEDBACKVARYINGSPROC)(GLuint, GLsizei, const GLchar *const*, GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM1UIPROC)(GLint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM1UIVPROC)(GLint, GLsizei, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM2UIPROC)(GLint, GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM2UIVPROC)(GLint, GLsizei, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM3UIPROC)(GLint, GLuint, GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM3UIVPROC)(GLint, GLsizei, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM4UIPROC)(GLint, GLuint, GLuint, GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM4UIVPROC)(GLint, GLsizei, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBI1IPROC)(GLuint, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBI1IVPROC)(GLuint, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBI1UIPROC)(GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBI1UIVPROC)(GLuint, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBI2IPROC)(GLuint, GLint, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBI2IVPROC)(GLuint, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBI2UIPROC)(GLuint, GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBI2UIVPROC)(GLuint, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBI3IPROC)(GLuint, GLint, GLint, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBI3IVPROC)(GLuint, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBI3UIPROC)(GLuint, GLuint, GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBI3UIVPROC)(GLuint, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBI4BVPROC)(GLuint, const GLbyte *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBI4IPROC)(GLuint, GLint, GLint, GLint, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBI4IVPROC)(GLuint, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBI4SVPROC)(GLuint, const GLshort *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBI4UBVPROC)(GLuint, const GLubyte *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBI4UIPROC)(GLuint, GLuint, GLuint, GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBI4UIVPROC)(GLuint, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBI4USVPROC)(GLuint, const GLushort *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBIPOINTERPROC)(GLuint, GLint, GLenum, GLsizei, const GLvoid *);
+
+// 3.1
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCOPYBUFFERSUBDATAPROC)(GLenum, GLenum, GLintptr, GLintptr, GLsizeiptr);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDRAWARRAYSINSTANCEDPROC)(GLenum, GLint, GLsizei, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDRAWELEMENTSINSTANCEDPROC)(GLenum, GLsizei, GLenum, const GLvoid *, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)(GLuint, GLuint, GLsizei, GLsizei *, GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETACTIVEUNIFORMBLOCKIVPROC)(GLuint, GLuint, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETACTIVEUNIFORMNAMEPROC)(GLuint, GLuint, GLsizei, GLsizei *, GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETACTIVEUNIFORMSIVPROC)(GLuint, GLsizei, const GLuint *, GLenum, GLint *);
+typedef GLuint (INTERNAL_GL_APIENTRY *PFNGLGETUNIFORMBLOCKINDEXPROC)(GLuint, const GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETUNIFORMINDICESPROC)(GLuint, GLsizei, const GLchar *const*, GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPRIMITIVERESTARTINDEXPROC)(GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXBUFFERPROC)(GLenum, GLenum, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORMBLOCKBINDINGPROC)(GLuint, GLuint, GLuint);
+
+// 3.2
+typedef GLenum (INTERNAL_GL_APIENTRY *PFNGLCLIENTWAITSYNCPROC)(GLsync, GLbitfield, GLuint64);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDELETESYNCPROC)(GLsync);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDRAWELEMENTSBASEVERTEXPROC)(GLenum, GLsizei, GLenum, const GLvoid *, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)(GLenum, GLsizei, GLenum, const GLvoid *, GLsizei, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)(GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *, GLint);
+typedef GLsync (INTERNAL_GL_APIENTRY *PFNGLFENCESYNCPROC)(GLenum, GLbitfield);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLFRAMEBUFFERTEXTUREPROC)(GLenum, GLenum, GLuint, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETBUFFERPARAMETERI64VPROC)(GLenum, GLenum, GLint64 *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETINTEGER64I_VPROC)(GLenum, GLuint, GLint64 *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETINTEGER64VPROC)(GLenum, GLint64 *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETMULTISAMPLEFVPROC)(GLenum, GLuint, GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETSYNCIVPROC)(GLsync, GLenum, GLsizei, GLsizei *, GLint *);
+typedef GLboolean (INTERNAL_GL_APIENTRY *PFNGLISSYNCPROC)(GLsync);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)(GLenum, const GLsizei *, GLenum, const GLvoid *const*, GLsizei, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROVOKINGVERTEXPROC)(GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLSAMPLEMASKIPROC)(GLuint, GLbitfield);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXIMAGE2DMULTISAMPLEPROC)(GLenum, GLsizei, GLint, GLsizei, GLsizei, GLboolean);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXIMAGE3DMULTISAMPLEPROC)(GLenum, GLsizei, GLint, GLsizei, GLsizei, GLsizei, GLboolean);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLWAITSYNCPROC)(GLsync, GLbitfield, GLuint64);
+
+// 3.3
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)(GLuint, GLuint, GLuint, const GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBINDSAMPLERPROC)(GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDELETESAMPLERSPROC)(GLsizei, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGENSAMPLERSPROC)(GLsizei, GLuint *);
+typedef GLint (INTERNAL_GL_APIENTRY *PFNGLGETFRAGDATAINDEXPROC)(GLuint, const GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETQUERYOBJECTI64VPROC)(GLuint, GLenum, GLint64 *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETQUERYOBJECTUI64VPROC)(GLuint, GLenum, GLuint64 *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETSAMPLERPARAMETERIIVPROC)(GLuint, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETSAMPLERPARAMETERIUIVPROC)(GLuint, GLenum, GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETSAMPLERPARAMETERFVPROC)(GLuint, GLenum, GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETSAMPLERPARAMETERIVPROC)(GLuint, GLenum, GLint *);
+typedef GLboolean (INTERNAL_GL_APIENTRY *PFNGLISSAMPLERPROC)(GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLQUERYCOUNTERPROC)(GLuint, GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLSAMPLERPARAMETERIIVPROC)(GLuint, GLenum, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLSAMPLERPARAMETERIUIVPROC)(GLuint, GLenum, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLSAMPLERPARAMETERFPROC)(GLuint, GLenum, GLfloat);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLSAMPLERPARAMETERFVPROC)(GLuint, GLenum, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLSAMPLERPARAMETERIPROC)(GLuint, GLenum, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLSAMPLERPARAMETERIVPROC)(GLuint, GLenum, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBDIVISORPROC)(GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBP1UIPROC)(GLuint, GLenum, GLboolean, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBP1UIVPROC)(GLuint, GLenum, GLboolean, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBP2UIPROC)(GLuint, GLenum, GLboolean, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBP2UIVPROC)(GLuint, GLenum, GLboolean, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBP3UIPROC)(GLuint, GLenum, GLboolean, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBP3UIVPROC)(GLuint, GLenum, GLboolean, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBP4UIPROC)(GLuint, GLenum, GLboolean, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBP4UIVPROC)(GLuint, GLenum, GLboolean, const GLuint *);
+
+// 4.0
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBEGINQUERYINDEXEDPROC)(GLenum, GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBINDTRANSFORMFEEDBACKPROC)(GLenum, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBLENDEQUATIONSEPARATEIPROC)(GLuint, GLenum, GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBLENDEQUATIONIPROC)(GLuint, GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBLENDFUNCSEPARATEIPROC)(GLuint, GLenum, GLenum, GLenum, GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBLENDFUNCIPROC)(GLuint, GLenum, GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDELETETRANSFORMFEEDBACKSPROC)(GLsizei, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDRAWARRAYSINDIRECTPROC)(GLenum, const void *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDRAWELEMENTSINDIRECTPROC)(GLenum, GLenum, const void *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDRAWTRANSFORMFEEDBACKPROC)(GLenum, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC)(GLenum, GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLENDQUERYINDEXEDPROC)(GLenum, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGENTRANSFORMFEEDBACKSPROC)(GLsizei, GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETACTIVESUBROUTINENAMEPROC)(GLuint, GLenum, GLuint, GLsizei, GLsizei *, GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC)(GLuint, GLenum, GLuint, GLsizei, GLsizei *, GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC)(GLuint, GLenum, GLuint, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETPROGRAMSTAGEIVPROC)(GLuint, GLenum, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETQUERYINDEXEDIVPROC)(GLenum, GLuint, GLenum, GLint *);
+typedef GLuint (INTERNAL_GL_APIENTRY *PFNGLGETSUBROUTINEINDEXPROC)(GLuint, GLenum, const GLchar *);
+typedef GLint (INTERNAL_GL_APIENTRY *PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC)(GLuint, GLenum, const GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETUNIFORMSUBROUTINEUIVPROC)(GLenum, GLint, GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETUNIFORMDVPROC)(GLuint, GLint, GLdouble *);
+typedef GLboolean (INTERNAL_GL_APIENTRY *PFNGLISTRANSFORMFEEDBACKPROC)(GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLMINSAMPLESHADINGPROC)(GLfloat);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPATCHPARAMETERFVPROC)(GLenum, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPATCHPARAMETERIPROC)(GLenum, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPAUSETRANSFORMFEEDBACKPROC)();
+typedef void (INTERNAL_GL_APIENTRY *PFNGLRESUMETRANSFORMFEEDBACKPROC)();
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM1DPROC)(GLint, GLdouble);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM1DVPROC)(GLint, GLsizei, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM2DPROC)(GLint, GLdouble, GLdouble);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM2DVPROC)(GLint, GLsizei, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM3DPROC)(GLint, GLdouble, GLdouble, GLdouble);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM3DVPROC)(GLint, GLsizei, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM4DPROC)(GLint, GLdouble, GLdouble, GLdouble, GLdouble);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORM4DVPROC)(GLint, GLsizei, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORMMATRIX2DVPROC)(GLint, GLsizei, GLboolean, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORMMATRIX2X3DVPROC)(GLint, GLsizei, GLboolean, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORMMATRIX2X4DVPROC)(GLint, GLsizei, GLboolean, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORMMATRIX3DVPROC)(GLint, GLsizei, GLboolean, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORMMATRIX3X2DVPROC)(GLint, GLsizei, GLboolean, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORMMATRIX3X4DVPROC)(GLint, GLsizei, GLboolean, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORMMATRIX4DVPROC)(GLint, GLsizei, GLboolean, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORMMATRIX4X2DVPROC)(GLint, GLsizei, GLboolean, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORMMATRIX4X3DVPROC)(GLint, GLsizei, GLboolean, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUNIFORMSUBROUTINESUIVPROC)(GLenum, GLsizei, const GLuint *);
+
+// 4.1
+typedef void (INTERNAL_GL_APIENTRY *PFNGLACTIVESHADERPROGRAMPROC)(GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBINDPROGRAMPIPELINEPROC)(GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARDEPTHFPROC)(GLfloat);
+typedef GLuint (INTERNAL_GL_APIENTRY *PFNGLCREATESHADERPROGRAMVPROC)(GLenum, GLsizei, const GLchar *const*);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDELETEPROGRAMPIPELINESPROC)(GLsizei, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDEPTHRANGEARRAYVPROC)(GLuint, GLsizei, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDEPTHRANGEINDEXEDPROC)(GLuint, GLdouble, GLdouble);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDEPTHRANGEFPROC)(GLfloat, GLfloat);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGENPROGRAMPIPELINESPROC)(GLsizei, GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETDOUBLEI_VPROC)(GLenum, GLuint, GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETFLOATI_VPROC)(GLenum, GLuint, GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETPROGRAMBINARYPROC)(GLuint, GLsizei, GLsizei *, GLenum *, void *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETPROGRAMPIPELINEINFOLOGPROC)(GLuint, GLsizei, GLsizei *, GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETPROGRAMPIPELINEIVPROC)(GLuint, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETSHADERPRECISIONFORMATPROC)(GLenum, GLenum, GLint *, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETVERTEXATTRIBLDVPROC)(GLuint, GLenum, GLdouble *);
+typedef GLboolean (INTERNAL_GL_APIENTRY *PFNGLISPROGRAMPIPELINEPROC)(GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMBINARYPROC)(GLuint, GLenum, const void *, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMPARAMETERIPROC)(GLuint, GLenum, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM1DPROC)(GLuint, GLint, GLdouble);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM1DVPROC)(GLuint, GLint, GLsizei, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM1FPROC)(GLuint, GLint, GLfloat);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM1FVPROC)(GLuint, GLint, GLsizei, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM1IPROC)(GLuint, GLint, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM1IVPROC)(GLuint, GLint, GLsizei, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM1UIPROC)(GLuint, GLint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM1UIVPROC)(GLuint, GLint, GLsizei, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM2DPROC)(GLuint, GLint, GLdouble, GLdouble);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM2DVPROC)(GLuint, GLint, GLsizei, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM2FPROC)(GLuint, GLint, GLfloat, GLfloat);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM2FVPROC)(GLuint, GLint, GLsizei, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM2IPROC)(GLuint, GLint, GLint, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM2IVPROC)(GLuint, GLint, GLsizei, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM2UIPROC)(GLuint, GLint, GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM2UIVPROC)(GLuint, GLint, GLsizei, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM3DPROC)(GLuint, GLint, GLdouble, GLdouble, GLdouble);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM3DVPROC)(GLuint, GLint, GLsizei, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM3FPROC)(GLuint, GLint, GLfloat, GLfloat, GLfloat);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM3FVPROC)(GLuint, GLint, GLsizei, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM3IPROC)(GLuint, GLint, GLint, GLint, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM3IVPROC)(GLuint, GLint, GLsizei, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM3UIPROC)(GLuint, GLint, GLuint, GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM3UIVPROC)(GLuint, GLint, GLsizei, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM4DPROC)(GLuint, GLint, GLdouble, GLdouble, GLdouble, GLdouble);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM4DVPROC)(GLuint, GLint, GLsizei, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM4FPROC)(GLuint, GLint, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM4FVPROC)(GLuint, GLint, GLsizei, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM4IPROC)(GLuint, GLint, GLint, GLint, GLint, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM4IVPROC)(GLuint, GLint, GLsizei, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM4UIPROC)(GLuint, GLint, GLuint, GLuint, GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORM4UIVPROC)(GLuint, GLint, GLsizei, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORMMATRIX2DVPROC)(GLuint, GLint, GLsizei, GLboolean, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORMMATRIX2FVPROC)(GLuint, GLint, GLsizei, GLboolean, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC)(GLuint, GLint, GLsizei, GLboolean, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC)(GLuint, GLint, GLsizei, GLboolean, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC)(GLuint, GLint, GLsizei, GLboolean, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC)(GLuint, GLint, GLsizei, GLboolean, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORMMATRIX3DVPROC)(GLuint, GLint, GLsizei, GLboolean, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORMMATRIX3FVPROC)(GLuint, GLint, GLsizei, GLboolean, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC)(GLuint, GLint, GLsizei, GLboolean, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC)(GLuint, GLint, GLsizei, GLboolean, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC)(GLuint, GLint, GLsizei, GLboolean, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC)(GLuint, GLint, GLsizei, GLboolean, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORMMATRIX4DVPROC)(GLuint, GLint, GLsizei, GLboolean, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORMMATRIX4FVPROC)(GLuint, GLint, GLsizei, GLboolean, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC)(GLuint, GLint, GLsizei, GLboolean, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC)(GLuint, GLint, GLsizei, GLboolean, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC)(GLuint, GLint, GLsizei, GLboolean, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC)(GLuint, GLint, GLsizei, GLboolean, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLRELEASESHADERCOMPILERPROC)();
+typedef void (INTERNAL_GL_APIENTRY *PFNGLSCISSORARRAYVPROC)(GLuint, GLsizei, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLSCISSORINDEXEDPROC)(GLuint, GLint, GLint, GLsizei, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLSCISSORINDEXEDVPROC)(GLuint, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLSHADERBINARYPROC)(GLsizei, const GLuint *, GLenum, const void *, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLUSEPROGRAMSTAGESPROC)(GLuint, GLbitfield, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVALIDATEPROGRAMPIPELINEPROC)(GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBL1DPROC)(GLuint, GLdouble);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBL1DVPROC)(GLuint, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBL2DPROC)(GLuint, GLdouble, GLdouble);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBL2DVPROC)(GLuint, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBL3DPROC)(GLuint, GLdouble, GLdouble, GLdouble);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBL3DVPROC)(GLuint, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBL4DPROC)(GLuint, GLdouble, GLdouble, GLdouble, GLdouble);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBL4DVPROC)(GLuint, const GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBLPOINTERPROC)(GLuint, GLint, GLenum, GLsizei, const void *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVIEWPORTARRAYVPROC)(GLuint, GLsizei, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVIEWPORTINDEXEDFPROC)(GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVIEWPORTINDEXEDFVPROC)(GLuint, const GLfloat *);
+
+// 4.2
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBINDIMAGETEXTUREPROC)(GLuint, GLuint, GLint, GLboolean, GLint, GLenum, GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC)(GLenum, GLint, GLsizei, GLsizei, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC)(GLenum, GLsizei, GLenum, const void *, GLsizei, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC)(GLenum, GLsizei, GLenum, const void *, GLsizei, GLint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC)(GLenum, GLuint, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC)(GLenum, GLuint, GLuint, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC)(GLuint, GLuint, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETINTERNALFORMATIVPROC)(GLenum, GLenum, GLenum, GLsizei, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLMEMORYBARRIERPROC)(GLbitfield);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXSTORAGE1DPROC)(GLenum, GLsizei, GLenum, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXSTORAGE2DPROC)(GLenum, GLsizei, GLenum, GLsizei, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXSTORAGE3DPROC)(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLsizei);
+
+// 4.3
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBINDVERTEXBUFFERPROC)(GLuint, GLuint, GLintptr, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARBUFFERDATAPROC)(GLenum, GLenum, GLenum, GLenum, const void *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARBUFFERSUBDATAPROC)(GLenum, GLenum, GLintptr, GLsizeiptr, GLenum, GLenum, const void *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCOPYIMAGESUBDATAPROC)(GLuint, GLenum, GLint, GLint, GLint, GLint, GLuint, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDEBUGMESSAGECALLBACKPROC)(GLDEBUGPROC, const void *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDEBUGMESSAGECONTROLPROC)(GLenum, GLenum, GLenum, GLsizei, const GLuint *, GLboolean);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDEBUGMESSAGEINSERTPROC)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDISPATCHCOMPUTEPROC)(GLuint, GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDISPATCHCOMPUTEINDIRECTPROC)(GLintptr);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLFRAMEBUFFERPARAMETERIPROC)(GLenum, GLenum, GLint);
+typedef GLuint (INTERNAL_GL_APIENTRY *PFNGLGETDEBUGMESSAGELOGPROC)(GLuint, GLsizei, GLenum *, GLenum *, GLuint *, GLenum *, GLsizei *, GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETFRAMEBUFFERPARAMETERIVPROC)(GLenum, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETINTERNALFORMATI64VPROC)(GLenum, GLenum, GLenum, GLsizei, GLint64 *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETPOINTERVPROC)(GLenum, void **);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETOBJECTLABELPROC)(GLenum, GLuint, GLsizei, GLsizei *, GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETOBJECTPTRLABELPROC)(const void *, GLsizei, GLsizei *, GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETPROGRAMINTERFACEIVPROC)(GLuint, GLenum, GLenum, GLint *);
+typedef GLuint (INTERNAL_GL_APIENTRY *PFNGLGETPROGRAMRESOURCEINDEXPROC)(GLuint, GLenum, const GLchar *);
+typedef GLint (INTERNAL_GL_APIENTRY *PFNGLGETPROGRAMRESOURCELOCATIONPROC)(GLuint, GLenum, const GLchar *);
+typedef GLint (INTERNAL_GL_APIENTRY *PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC)(GLuint, GLenum, const GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETPROGRAMRESOURCENAMEPROC)(GLuint, GLenum, GLuint, GLsizei, GLsizei *, GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETPROGRAMRESOURCEIVPROC)(GLuint, GLenum, GLuint, GLsizei, const GLenum *, GLsizei, GLsizei *, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLINVALIDATEBUFFERDATAPROC)(GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLINVALIDATEBUFFERSUBDATAPROC)(GLuint, GLintptr, GLsizeiptr);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLINVALIDATEFRAMEBUFFERPROC)(GLenum, GLsizei, const GLenum *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLINVALIDATESUBFRAMEBUFFERPROC)(GLenum, GLsizei, const GLenum *, GLint, GLint, GLsizei, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLINVALIDATETEXIMAGEPROC)(GLuint, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLINVALIDATETEXSUBIMAGEPROC)(GLuint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLMULTIDRAWARRAYSINDIRECTPROC)(GLenum, const void *, GLsizei, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLMULTIDRAWELEMENTSINDIRECTPROC)(GLenum, GLenum, const void *, GLsizei, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLOBJECTLABELPROC)(GLenum, GLuint, GLsizei, const GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLOBJECTPTRLABELPROC)(const void *, GLsizei, const GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPOPDEBUGGROUPPROC)();
+typedef void (INTERNAL_GL_APIENTRY *PFNGLPUSHDEBUGGROUPPROC)(GLenum, GLuint, GLsizei, const GLchar *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLSHADERSTORAGEBLOCKBINDINGPROC)(GLuint, GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXBUFFERRANGEPROC)(GLenum, GLenum, GLuint, GLintptr, GLsizeiptr);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXSTORAGE2DMULTISAMPLEPROC)(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLboolean);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXSTORAGE3DMULTISAMPLEPROC)(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLsizei, GLboolean);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXTUREVIEWPROC)(GLuint, GLenum, GLuint, GLenum, GLuint, GLuint, GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBBINDINGPROC)(GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBFORMATPROC)(GLuint, GLint, GLenum, GLboolean, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBIFORMATPROC)(GLuint, GLint, GLenum, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXATTRIBLFORMATPROC)(GLuint, GLint, GLenum, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXBINDINGDIVISORPROC)(GLuint, GLuint);
+
+// NV_framebuffer_mixed_samples
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCOVERAGEMODULATIONNVPROC)(GLenum);
+
+// 4.4
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBINDBUFFERSBASEPROC)(GLenum, GLuint, GLsizei, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBINDBUFFERSRANGEPROC)(GLenum, GLuint, GLsizei, const GLuint *, const GLintptr *, const GLsizeiptr *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBINDIMAGETEXTURESPROC)(GLuint, GLsizei, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBINDSAMPLERSPROC)(GLuint, GLsizei, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBINDTEXTURESPROC)(GLuint, GLsizei, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBINDVERTEXBUFFERSPROC)(GLuint, GLsizei, const GLuint *, const GLintptr *, const GLsizei *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBUFFERSTORAGEPROC)(GLenum, GLsizeiptr, const void *, GLbitfield);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARTEXIMAGEPROC)(GLuint, GLint, GLenum, GLenum, const void *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARTEXSUBIMAGEPROC)(GLuint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const void *);
+
+// 4.5
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBINDTEXTUREUNITPROC)(GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLBLITNAMEDFRAMEBUFFERPROC)(GLuint, GLuint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum);
+typedef GLenum (INTERNAL_GL_APIENTRY *PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC)(GLuint, GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARNAMEDBUFFERDATAPROC)(GLuint, GLenum, GLenum, GLenum, const void *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARNAMEDBUFFERSUBDATAPROC)(GLuint, GLenum, GLintptr, GLsizeiptr, GLenum, GLenum, const void *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARNAMEDFRAMEBUFFERFIPROC)(GLuint, GLenum, const GLfloat, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARNAMEDFRAMEBUFFERFVPROC)(GLuint, GLenum, GLint, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARNAMEDFRAMEBUFFERIVPROC)(GLuint, GLenum, GLint, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC)(GLuint, GLenum, GLint, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCLIPCONTROLPROC)(GLenum, GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC)(GLuint, GLint, GLint, GLsizei, GLenum, GLsizei, const void *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC)(GLuint, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const void *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC)(GLuint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const void *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCOPYNAMEDBUFFERSUBDATAPROC)(GLuint, GLuint, GLintptr, GLintptr, GLsizeiptr);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCOPYTEXTURESUBIMAGE1DPROC)(GLuint, GLint, GLint, GLint, GLint, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCOPYTEXTURESUBIMAGE2DPROC)(GLuint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCOPYTEXTURESUBIMAGE3DPROC)(GLuint, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCREATEBUFFERSPROC)(GLsizei, GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCREATEFRAMEBUFFERSPROC)(GLsizei, GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCREATEPROGRAMPIPELINESPROC)(GLsizei, GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCREATEQUERIESPROC)(GLenum, GLsizei, GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCREATERENDERBUFFERSPROC)(GLsizei, GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCREATESAMPLERSPROC)(GLsizei, GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCREATETEXTURESPROC)(GLenum, GLsizei, GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCREATETRANSFORMFEEDBACKSPROC)(GLsizei, GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLCREATEVERTEXARRAYSPROC)(GLsizei, GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLDISABLEVERTEXARRAYATTRIBPROC)(GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLENABLEVERTEXARRAYATTRIBPROC)(GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC)(GLuint, GLintptr, GLsizeiptr);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGENERATETEXTUREMIPMAPPROC)(GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC)(GLuint, GLint, GLsizei, void *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC)(GLuint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLsizei, void *);
+typedef GLenum (INTERNAL_GL_APIENTRY *PFNGLGETGRAPHICSRESETSTATUSPROC)();
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETNAMEDBUFFERPARAMETERI64VPROC)(GLuint, GLenum, GLint64 *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETNAMEDBUFFERPARAMETERIVPROC)(GLuint, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETNAMEDBUFFERPOINTERVPROC)(GLuint, GLenum, void **);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETNAMEDBUFFERSUBDATAPROC)(GLuint, GLintptr, GLsizeiptr, void *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLuint, GLenum, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC)(GLuint, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC)(GLuint, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETQUERYBUFFEROBJECTI64VPROC)(GLuint, GLuint, GLenum, GLintptr);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETQUERYBUFFEROBJECTIVPROC)(GLuint, GLuint, GLenum, GLintptr);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETQUERYBUFFEROBJECTUI64VPROC)(GLuint, GLuint, GLenum, GLintptr);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETQUERYBUFFEROBJECTUIVPROC)(GLuint, GLuint, GLenum, GLintptr);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETTEXTUREIMAGEPROC)(GLuint, GLint, GLenum, GLenum, GLsizei, void *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETTEXTURELEVELPARAMETERFVPROC)(GLuint, GLint, GLenum, GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETTEXTURELEVELPARAMETERIVPROC)(GLuint, GLint, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETTEXTUREPARAMETERIIVPROC)(GLuint, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETTEXTUREPARAMETERIUIVPROC)(GLuint, GLenum, GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETTEXTUREPARAMETERFVPROC)(GLuint, GLenum, GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETTEXTUREPARAMETERIVPROC)(GLuint, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETTEXTURESUBIMAGEPROC)(GLuint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, GLsizei, void *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETTRANSFORMFEEDBACKI64_VPROC)(GLuint, GLenum, GLuint, GLint64 *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETTRANSFORMFEEDBACKI_VPROC)(GLuint, GLenum, GLuint, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETTRANSFORMFEEDBACKIVPROC)(GLuint, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETVERTEXARRAYINDEXED64IVPROC)(GLuint, GLuint, GLenum, GLint64 *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETVERTEXARRAYINDEXEDIVPROC)(GLuint, GLuint, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETVERTEXARRAYIVPROC)(GLuint, GLenum, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETNCOMPRESSEDTEXIMAGEPROC)(GLenum, GLint, GLsizei, void *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETNTEXIMAGEPROC)(GLenum, GLint, GLenum, GLenum, GLsizei, void *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETNUNIFORMDVPROC)(GLuint, GLint, GLsizei, GLdouble *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETNUNIFORMFVPROC)(GLuint, GLint, GLsizei, GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETNUNIFORMIVPROC)(GLuint, GLint, GLsizei, GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETNUNIFORMUIVPROC)(GLuint, GLint, GLsizei, GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC)(GLuint, GLsizei, const GLenum *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC)(GLuint, GLsizei, const GLenum *, GLint, GLint, GLsizei, GLsizei);
+typedef void *(INTERNAL_GL_APIENTRY *PFNGLMAPNAMEDBUFFERPROC)(GLuint, GLenum);
+typedef void *(INTERNAL_GL_APIENTRY *PFNGLMAPNAMEDBUFFERRANGEPROC)(GLuint, GLintptr, GLsizeiptr, GLbitfield);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLMEMORYBARRIERBYREGIONPROC)(GLbitfield);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLNAMEDBUFFERDATAPROC)(GLuint, GLsizeiptr, const void *, GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLNAMEDBUFFERSTORAGEPROC)(GLuint, GLsizeiptr, const void *, GLbitfield);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLNAMEDBUFFERSUBDATAPROC)(GLuint, GLintptr, GLsizeiptr, const void *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC)(GLuint, GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC)(GLuint, GLsizei, const GLenum *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC)(GLuint, GLenum, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC)(GLuint, GLenum);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC)(GLuint, GLenum, GLenum, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLNAMEDFRAMEBUFFERTEXTUREPROC)(GLuint, GLenum, GLuint, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC)(GLuint, GLenum, GLuint, GLint, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLNAMEDRENDERBUFFERSTORAGEPROC)(GLuint, GLenum, GLsizei, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLuint, GLsizei, GLenum, GLsizei, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLREADNPIXELSPROC)(GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLsizei, void *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXTUREBARRIERPROC)();
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXTUREBUFFERPROC)(GLuint, GLenum, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXTUREBUFFERRANGEPROC)(GLuint, GLenum, GLuint, GLintptr, GLsizeiptr);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXTUREPARAMETERIIVPROC)(GLuint, GLenum, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXTUREPARAMETERIUIVPROC)(GLuint, GLenum, const GLuint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXTUREPARAMETERFPROC)(GLuint, GLenum, GLfloat);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXTUREPARAMETERFVPROC)(GLuint, GLenum, const GLfloat *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXTUREPARAMETERIPROC)(GLuint, GLenum, GLint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXTUREPARAMETERIVPROC)(GLuint, GLenum, const GLint *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXTURESTORAGE1DPROC)(GLuint, GLsizei, GLenum, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXTURESTORAGE2DPROC)(GLuint, GLsizei, GLenum, GLsizei, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC)(GLuint, GLsizei, GLenum, GLsizei, GLsizei, GLboolean);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXTURESTORAGE3DPROC)(GLuint, GLsizei, GLenum, GLsizei, GLsizei, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC)(GLuint, GLsizei, GLenum, GLsizei, GLsizei, GLsizei, GLboolean);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXTURESUBIMAGE1DPROC)(GLuint, GLint, GLint, GLsizei, GLenum, GLenum, const void *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXTURESUBIMAGE2DPROC)(GLuint, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const void *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXTURESUBIMAGE3DPROC)(GLuint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const void *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC)(GLuint, GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC)(GLuint, GLuint, GLuint, GLintptr, GLsizeiptr);
+typedef GLboolean (INTERNAL_GL_APIENTRY *PFNGLUNMAPNAMEDBUFFERPROC)(GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXARRAYATTRIBBINDINGPROC)(GLuint, GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXARRAYATTRIBFORMATPROC)(GLuint, GLuint, GLint, GLenum, GLboolean, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXARRAYATTRIBIFORMATPROC)(GLuint, GLuint, GLint, GLenum, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXARRAYATTRIBLFORMATPROC)(GLuint, GLuint, GLint, GLenum, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXARRAYBINDINGDIVISORPROC)(GLuint, GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXARRAYELEMENTBUFFERPROC)(GLuint, GLuint);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXARRAYVERTEXBUFFERPROC)(GLuint, GLuint, GLuint, GLintptr, GLsizei);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLVERTEXARRAYVERTEXBUFFERSPROC)(GLuint, GLuint, GLsizei, const GLuint *, const GLintptr *, const GLsizei *);
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_FUNCTIONSGLTYPEDEFS_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/glx/DisplayGLX.cpp b/gfx/angle/src/libANGLE/renderer/gl/glx/DisplayGLX.cpp
new file mode 100755
index 000000000..e98401d0a
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/glx/DisplayGLX.cpp
@@ -0,0 +1,981 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// DisplayGLX.cpp: GLX implementation of egl::Display
+
+#include "libANGLE/renderer/gl/glx/DisplayGLX.h"
+
+#include <EGL/eglext.h>
+#include <algorithm>
+#include <cstring>
+#include <fstream>
+
+#include "common/debug.h"
+#include "libANGLE/Config.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/renderer/gl/glx/PbufferSurfaceGLX.h"
+#include "libANGLE/renderer/gl/glx/WindowSurfaceGLX.h"
+#include "libANGLE/renderer/gl/RendererGL.h"
+#include "libANGLE/renderer/gl/renderergl_utils.h"
+#include "third_party/libXNVCtrl/NVCtrl.h"
+#include "third_party/libXNVCtrl/NVCtrlLib.h"
+
+namespace
+{
+
+// Scan /etc/ati/amdpcsdb.default for "ReleaseVersion".
+// Return empty string on failing.
+egl::Error GetAMDDriverVersion(std::string *version)
+{
+ *version = "";
+
+ const char kAMDDriverInfoFileName[] = "/etc/ati/amdpcsdb.default";
+ std::ifstream file(kAMDDriverInfoFileName);
+
+ if (!file)
+ {
+ return egl::Error(EGL_SUCCESS);
+ }
+
+ std::string line;
+ while (std::getline(file, line))
+ {
+ static const char kReleaseVersion[] = "ReleaseVersion=";
+ if (line.compare(0, std::strlen(kReleaseVersion), kReleaseVersion) != 0)
+ {
+ continue;
+ }
+
+ const size_t begin = line.find_first_of("0123456789");
+ if (begin == std::string::npos)
+ {
+ continue;
+ }
+
+ const size_t end = line.find_first_not_of("0123456789.", begin);
+ if (end == std::string::npos)
+ {
+ *version = line.substr(begin);
+ }
+ else
+ {
+ *version = line.substr(begin, end - begin);
+ }
+ return egl::Error(EGL_SUCCESS);
+ }
+ return egl::Error(EGL_SUCCESS);
+}
+
+} // anonymous namespace
+
+namespace rx
+{
+
+static int IgnoreX11Errors(Display *, XErrorEvent *)
+{
+ return 0;
+}
+
+SwapControlData::SwapControlData()
+ : targetSwapInterval(0),
+ maxSwapInterval(-1),
+ currentSwapInterval(-1)
+{
+}
+
+class FunctionsGLGLX : public FunctionsGL
+{
+ public:
+ FunctionsGLGLX(PFNGETPROCPROC getProc)
+ : mGetProc(getProc)
+ {
+ }
+
+ ~FunctionsGLGLX() override {}
+
+ private:
+ void *loadProcAddress(const std::string &function) override
+ {
+ return reinterpret_cast<void*>(mGetProc(function.c_str()));
+ }
+
+ PFNGETPROCPROC mGetProc;
+};
+
+DisplayGLX::DisplayGLX()
+ : DisplayGL(),
+ mFunctionsGL(nullptr),
+ mRequestedVisual(-1),
+ mContextConfig(nullptr),
+ mContext(nullptr),
+ mDummyPbuffer(0),
+ mUsesNewXDisplay(false),
+ mIsMesa(false),
+ mHasMultisample(false),
+ mHasARBCreateContext(false),
+ mHasARBCreateContextProfile(false),
+ mHasARBCreateContextRobustness(false),
+ mHasEXTCreateContextES2Profile(false),
+ mSwapControl(SwapControl::Absent),
+ mMinSwapInterval(0),
+ mMaxSwapInterval(0),
+ mCurrentSwapInterval(-1),
+ mXDisplay(nullptr),
+ mEGLDisplay(nullptr)
+{
+}
+
+DisplayGLX::~DisplayGLX()
+{
+}
+
+egl::Error DisplayGLX::initialize(egl::Display *display)
+{
+ mEGLDisplay = display;
+ mXDisplay = display->getNativeDisplayId();
+ const auto &attribMap = display->getAttributeMap();
+
+ // ANGLE_platform_angle allows the creation of a default display
+ // using EGL_DEFAULT_DISPLAY (= nullptr). In this case just open
+ // the display specified by the DISPLAY environment variable.
+ if (mXDisplay == EGL_DEFAULT_DISPLAY)
+ {
+ mUsesNewXDisplay = true;
+ mXDisplay = XOpenDisplay(NULL);
+ if (!mXDisplay)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Could not open the default X display.");
+ }
+ }
+
+ std::string glxInitError;
+ if (!mGLX.initialize(mXDisplay, DefaultScreen(mXDisplay), &glxInitError))
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, glxInitError.c_str());
+ }
+
+ mHasMultisample = mGLX.minorVersion > 3 || mGLX.hasExtension("GLX_ARB_multisample");
+ mHasARBCreateContext = mGLX.hasExtension("GLX_ARB_create_context");
+ mHasARBCreateContextProfile = mGLX.hasExtension("GLX_ARB_create_context_profile");
+ mHasARBCreateContextRobustness = mGLX.hasExtension("GLX_ARB_create_context_robustness");
+ mHasEXTCreateContextES2Profile = mGLX.hasExtension("GLX_EXT_create_context_es2_profile");
+
+ std::string clientVendor = mGLX.getClientString(GLX_VENDOR);
+ mIsMesa = clientVendor.find("Mesa") != std::string::npos;
+
+ // Choose the swap_control extension to use, if any.
+ // The EXT version is better as it allows glXSwapInterval to be called per
+ // window, while we'll potentially need to change the swap interval on each
+ // swap buffers when using the SGI or MESA versions.
+ if (mGLX.hasExtension("GLX_EXT_swap_control"))
+ {
+ mSwapControl = SwapControl::EXT;
+
+ // In GLX_EXT_swap_control querying these is done on a GLXWindow so we just
+ // set default values.
+ mMinSwapInterval = 0;
+ mMaxSwapInterval = 4;
+ }
+ else if (mGLX.hasExtension("GLX_MESA_swap_control"))
+ {
+ // If we have the Mesa or SGI extension, assume that you can at least set
+ // a swap interval of 0 or 1.
+ mSwapControl = SwapControl::Mesa;
+ mMinSwapInterval = 0;
+ mMinSwapInterval = 1;
+ }
+ else if (mGLX.hasExtension("GLX_SGI_swap_control"))
+ {
+ mSwapControl = SwapControl::SGI;
+ mMinSwapInterval = 0;
+ mMinSwapInterval = 1;
+ }
+ else
+ {
+ mSwapControl = SwapControl::Absent;
+ mMinSwapInterval = 1;
+ mMinSwapInterval = 1;
+ }
+
+ if (attribMap.contains(EGL_X11_VISUAL_ID_ANGLE))
+ {
+ mRequestedVisual = static_cast<EGLint>(attribMap.get(EGL_X11_VISUAL_ID_ANGLE, -1));
+
+ // There is no direct way to get the GLXFBConfig matching an X11 visual ID
+ // so we have to iterate over all the GLXFBConfigs to find the right one.
+ int nConfigs;
+ int attribList[] = {
+ None,
+ };
+ glx::FBConfig *allConfigs = mGLX.chooseFBConfig(attribList, &nConfigs);
+
+ for (int i = 0; i < nConfigs; ++i)
+ {
+ if (getGLXFBConfigAttrib(allConfigs[i], GLX_VISUAL_ID) == mRequestedVisual)
+ {
+ mContextConfig = allConfigs[i];
+ break;
+ }
+ }
+ XFree(allConfigs);
+
+ if (mContextConfig == nullptr)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Invalid visual ID requested.");
+ }
+ }
+ else
+ {
+ // When glXMakeCurrent is called, the context and the surface must be
+ // compatible which in glX-speak means that their config have the same
+ // color buffer type, are both RGBA or ColorIndex, and their buffers have
+ // the same depth, if they exist.
+ // Since our whole EGL implementation is backed by only one GL context, this
+ // context must be compatible with all the GLXFBConfig corresponding to the
+ // EGLconfigs that we will be exposing.
+ int nConfigs;
+ int attribList[] =
+ {
+ // We want RGBA8 and DEPTH24_STENCIL8
+ GLX_RED_SIZE, 8,
+ GLX_GREEN_SIZE, 8,
+ GLX_BLUE_SIZE, 8,
+ GLX_ALPHA_SIZE, 8,
+ GLX_DEPTH_SIZE, 24,
+ GLX_STENCIL_SIZE, 8,
+ // We want RGBA rendering (vs COLOR_INDEX) and doublebuffer
+ GLX_RENDER_TYPE, GLX_RGBA_BIT,
+ // Double buffer is not strictly required as a non-doublebuffer
+ // context can work with a doublebuffered surface, but it still
+ // flickers and all applications want doublebuffer anyway.
+ GLX_DOUBLEBUFFER, True,
+ // All of these must be supported for full EGL support
+ GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT | GLX_PBUFFER_BIT | GLX_PIXMAP_BIT,
+ // This makes sure the config have an associated visual Id
+ GLX_X_RENDERABLE, True,
+ GLX_CONFIG_CAVEAT, GLX_NONE,
+ None
+ };
+ glx::FBConfig *candidates = mGLX.chooseFBConfig(attribList, &nConfigs);
+ if (nConfigs == 0)
+ {
+ XFree(candidates);
+ return egl::Error(EGL_NOT_INITIALIZED, "Could not find a decent GLX FBConfig to create the context.");
+ }
+ mContextConfig = candidates[0];
+ XFree(candidates);
+ }
+
+ const auto &eglAttributes = display->getAttributeMap();
+ if (mHasARBCreateContext)
+ {
+ egl::Error error = initializeContext(mContextConfig, eglAttributes, &mContext);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ else
+ {
+ if (eglAttributes.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE,
+ EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE) ==
+ EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED,
+ "Cannot create an OpenGL ES platform on GLX without the "
+ "GLX_ARB_create_context extension.");
+ }
+
+ XVisualInfo visualTemplate;
+ visualTemplate.visualid = getGLXFBConfigAttrib(mContextConfig, GLX_VISUAL_ID);
+
+ int numVisuals = 0;
+ XVisualInfo *visuals =
+ XGetVisualInfo(mXDisplay, VisualIDMask, &visualTemplate, &numVisuals);
+ if (numVisuals <= 0)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED,
+ "Could not get the visual info from the fb config");
+ }
+ ASSERT(numVisuals == 1);
+
+ mContext = mGLX.createContext(&visuals[0], nullptr, true);
+ XFree(visuals);
+
+ if (!mContext)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Could not create GL context.");
+ }
+ }
+ ASSERT(mContext);
+
+ // FunctionsGL and DisplayGL need to make a few GL calls, for example to
+ // query the version of the context so we need to make the context current.
+ // glXMakeCurrent requires a GLXDrawable so we create a temporary Pbuffer
+ // (of size 1, 1) for the duration of these calls.
+ // Ideally we would want to unset the current context and destroy the pbuffer
+ // before going back to the application but this is TODO
+ // We could use a pbuffer of size (0, 0) but it fails on the Intel Mesa driver
+ // as commented on https://bugs.freedesktop.org/show_bug.cgi?id=38869 so we
+ // use (1, 1) instead.
+
+ int dummyPbufferAttribs[] =
+ {
+ GLX_PBUFFER_WIDTH, 1,
+ GLX_PBUFFER_HEIGHT, 1,
+ None,
+ };
+ mDummyPbuffer = mGLX.createPbuffer(mContextConfig, dummyPbufferAttribs);
+ if (!mDummyPbuffer)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Could not create the dummy pbuffer.");
+ }
+
+ if (!mGLX.makeCurrent(mDummyPbuffer, mContext))
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Could not make the dummy pbuffer current.");
+ }
+
+ mFunctionsGL = new FunctionsGLGLX(mGLX.getProc);
+ mFunctionsGL->initialize();
+
+ // TODO(cwallez, angleproject:1303) Disable the OpenGL ES backend on Linux NVIDIA and Intel as
+ // it has problems on our automated testing. An OpenGL ES backend might not trigger this test if
+ // there is no Desktop OpenGL support, but that's not the case in our automated testing.
+ VendorID vendor = GetVendorID(mFunctionsGL);
+ bool isOpenGLES =
+ eglAttributes.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE) ==
+ EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE;
+ if (isOpenGLES && (IsIntel(vendor) || IsNvidia(vendor)))
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Intel or NVIDIA OpenGL ES drivers are not supported.");
+ }
+
+ syncXCommands();
+
+ return DisplayGL::initialize(display);
+}
+
+void DisplayGLX::terminate()
+{
+ DisplayGL::terminate();
+
+ if (mDummyPbuffer)
+ {
+ mGLX.destroyPbuffer(mDummyPbuffer);
+ mDummyPbuffer = 0;
+ }
+
+ if (mContext)
+ {
+ mGLX.destroyContext(mContext);
+ mContext = nullptr;
+ }
+
+ mGLX.terminate();
+
+ SafeDelete(mFunctionsGL);
+}
+
+SurfaceImpl *DisplayGLX::createWindowSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLNativeWindowType window,
+ const egl::AttributeMap &attribs)
+{
+ ASSERT(configIdToGLXConfig.count(configuration->configID) > 0);
+ glx::FBConfig fbConfig = configIdToGLXConfig[configuration->configID];
+
+ return new WindowSurfaceGLX(state, mGLX, this, getRenderer(), window, mGLX.getDisplay(),
+ mContext, fbConfig);
+}
+
+SurfaceImpl *DisplayGLX::createPbufferSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ const egl::AttributeMap &attribs)
+{
+ ASSERT(configIdToGLXConfig.count(configuration->configID) > 0);
+ glx::FBConfig fbConfig = configIdToGLXConfig[configuration->configID];
+
+ EGLint width = static_cast<EGLint>(attribs.get(EGL_WIDTH, 0));
+ EGLint height = static_cast<EGLint>(attribs.get(EGL_HEIGHT, 0));
+ bool largest = (attribs.get(EGL_LARGEST_PBUFFER, EGL_FALSE) == EGL_TRUE);
+
+ return new PbufferSurfaceGLX(state, getRenderer(), width, height, largest, mGLX, mContext,
+ fbConfig);
+}
+
+SurfaceImpl *DisplayGLX::createPbufferFromClientBuffer(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs)
+{
+ UNIMPLEMENTED();
+ return nullptr;
+}
+
+SurfaceImpl *DisplayGLX::createPixmapSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ NativePixmapType nativePixmap,
+ const egl::AttributeMap &attribs)
+{
+ UNIMPLEMENTED();
+ return nullptr;
+}
+
+egl::Error DisplayGLX::getDevice(DeviceImpl **device)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_BAD_DISPLAY);
+}
+
+egl::Error DisplayGLX::initializeContext(glx::FBConfig config,
+ const egl::AttributeMap &eglAttributes,
+ glx::Context *context)
+{
+ int profileMask = 0;
+
+ EGLint requestedDisplayType = static_cast<EGLint>(
+ eglAttributes.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE));
+ if (requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
+ {
+ if (!mHasEXTCreateContextES2Profile)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED,
+ "Cannot create an OpenGL ES platform on GLX without the "
+ "GLX_EXT_create_context_es_profile extension.");
+ }
+
+ ASSERT(mHasARBCreateContextProfile);
+ profileMask |= GLX_CONTEXT_ES2_PROFILE_BIT_EXT;
+ }
+
+ // Create a context of the requested version, if any.
+ gl::Version requestedVersion(static_cast<EGLint>(eglAttributes.get(
+ EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, EGL_DONT_CARE)),
+ static_cast<EGLint>(eglAttributes.get(
+ EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, EGL_DONT_CARE)));
+ if (static_cast<EGLint>(requestedVersion.major) != EGL_DONT_CARE &&
+ static_cast<EGLint>(requestedVersion.minor) != EGL_DONT_CARE)
+ {
+ if (!(profileMask & GLX_CONTEXT_ES2_PROFILE_BIT_EXT) &&
+ requestedVersion >= gl::Version(3, 2))
+ {
+ profileMask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
+ }
+ return createContextAttribs(config, requestedVersion, profileMask, context);
+ }
+
+ // It is commonly assumed that glXCreateContextAttrib will create a context
+ // of the highest version possible but it is not specified in the spec and
+ // is not true on the Mesa drivers. On Mesa, Instead we try to create a
+ // context per GL version until we succeed, starting from newer version.
+ // On both Mesa and other drivers we try to create a desktop context and fall
+ // back to ES context.
+ // The code could be simpler if the Mesa code path was used for all drivers,
+ // however the cost of failing a context creation can be high (3 milliseconds
+ // for the NVIDIA driver). The good thing is that failed context creation only
+ // takes 0.1 milliseconds on Mesa.
+
+ struct ContextCreationInfo
+ {
+ EGLint displayType;
+ int profileFlag;
+ Optional<gl::Version> version;
+ };
+
+ // clang-format off
+ // For regular drivers we try to create a core, compatibility, then ES context.
+ // Without requiring any specific version (the Optional version is undefined).
+ const ContextCreationInfo contextsToTry[] = {
+ { EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, {} },
+ { EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, 0, {} },
+ { EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, {} },
+ };
+
+ // On Mesa we try to create a core context, except for versions below 3.2
+ // where it is not applicable. (and fallback to ES as well)
+ const ContextCreationInfo mesaContextsToTry[] = {
+ { EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, { gl::Version(4, 5) } },
+ { EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, { gl::Version(4, 4) } },
+ { EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, { gl::Version(4, 3) } },
+ { EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, { gl::Version(4, 2) } },
+ { EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, { gl::Version(4, 1) } },
+ { EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, { gl::Version(4, 0) } },
+ { EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, { gl::Version(3, 3) } },
+ { EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, { gl::Version(3, 2) } },
+ { EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, 0, { gl::Version(3, 1) } },
+ { EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, 0, { gl::Version(3, 0) } },
+ { EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, 0, { gl::Version(2, 0) } },
+ { EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, 0, { gl::Version(1, 5) } },
+ { EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, 0, { gl::Version(1, 4) } },
+ { EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, 0, { gl::Version(1, 3) } },
+ { EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, 0, { gl::Version(1, 2) } },
+ { EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, 0, { gl::Version(1, 1) } },
+ { EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, 0, { gl::Version(1, 0) } },
+ { EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, { gl::Version(3, 2) } },
+ { EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, { gl::Version(3, 1) } },
+ { EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, { gl::Version(3, 0) } },
+ { EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, { gl::Version(2, 0) } },
+ };
+ // clang-format on
+
+ const ContextCreationInfo *toTry = contextsToTry;
+ size_t toTryLength = ArraySize(contextsToTry);
+ if (mIsMesa)
+ {
+ toTry = mesaContextsToTry;
+ toTryLength = ArraySize(mesaContextsToTry);
+ }
+
+ // NOTE: below we return as soon as we're able to create a context so the
+ // "error" variable is EGL_SUCCESS when returned contrary to the common idiom
+ // of returning "error" when there is an actual error.
+ for (size_t i = 0; i < toTryLength; ++i)
+ {
+ const ContextCreationInfo &info = toTry[i];
+ if (requestedDisplayType != EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE &&
+ requestedDisplayType != info.displayType)
+ {
+ continue;
+ }
+
+ egl::Error error = createContextAttribs(config, info.version, info.profileFlag, context);
+ if (!error.isError())
+ {
+ return error;
+ }
+ }
+
+ return egl::Error(EGL_NOT_INITIALIZED, "Could not create a backing OpenGL context.");
+}
+
+egl::ConfigSet DisplayGLX::generateConfigs()
+{
+ egl::ConfigSet configs;
+ configIdToGLXConfig.clear();
+
+ const gl::Version &maxVersion = getMaxSupportedESVersion();
+ ASSERT(maxVersion >= gl::Version(2, 0));
+ bool supportsES3 = maxVersion >= gl::Version(3, 0);
+
+ int contextRedSize = getGLXFBConfigAttrib(mContextConfig, GLX_RED_SIZE);
+ int contextGreenSize = getGLXFBConfigAttrib(mContextConfig, GLX_GREEN_SIZE);
+ int contextBlueSize = getGLXFBConfigAttrib(mContextConfig, GLX_BLUE_SIZE);
+ int contextAlphaSize = getGLXFBConfigAttrib(mContextConfig, GLX_ALPHA_SIZE);
+
+ int contextDepthSize = getGLXFBConfigAttrib(mContextConfig, GLX_DEPTH_SIZE);
+ int contextStencilSize = getGLXFBConfigAttrib(mContextConfig, GLX_STENCIL_SIZE);
+
+ int contextSamples = mHasMultisample ? getGLXFBConfigAttrib(mContextConfig, GLX_SAMPLES) : 0;
+ int contextSampleBuffers =
+ mHasMultisample ? getGLXFBConfigAttrib(mContextConfig, GLX_SAMPLE_BUFFERS) : 0;
+
+ int contextAccumRedSize = getGLXFBConfigAttrib(mContextConfig, GLX_ACCUM_RED_SIZE);
+ int contextAccumGreenSize = getGLXFBConfigAttrib(mContextConfig, GLX_ACCUM_GREEN_SIZE);
+ int contextAccumBlueSize = getGLXFBConfigAttrib(mContextConfig, GLX_ACCUM_BLUE_SIZE);
+ int contextAccumAlphaSize = getGLXFBConfigAttrib(mContextConfig, GLX_ACCUM_ALPHA_SIZE);
+
+ int attribList[] =
+ {
+ GLX_RENDER_TYPE, GLX_RGBA_BIT,
+ GLX_X_RENDERABLE, True,
+ GLX_DOUBLEBUFFER, True,
+ None,
+ };
+
+ int glxConfigCount;
+ glx::FBConfig *glxConfigs = mGLX.chooseFBConfig(attribList, &glxConfigCount);
+
+ for (int i = 0; i < glxConfigCount; i++)
+ {
+ glx::FBConfig glxConfig = glxConfigs[i];
+ egl::Config config;
+
+ // Native stuff
+ config.nativeVisualID = getGLXFBConfigAttrib(glxConfig, GLX_VISUAL_ID);
+ config.nativeVisualType = getGLXFBConfigAttrib(glxConfig, GLX_X_VISUAL_TYPE);
+ config.nativeRenderable = EGL_TRUE;
+
+ // When a visual ID has been specified with EGL_ANGLE_x11_visual we should
+ // only return configs with this visual: it will maximize performance by avoid
+ // blits in the driver when showing the window on the screen.
+ if (mRequestedVisual != -1 && config.nativeVisualID != mRequestedVisual)
+ {
+ continue;
+ }
+
+ // Buffer sizes
+ config.redSize = getGLXFBConfigAttrib(glxConfig, GLX_RED_SIZE);
+ config.greenSize = getGLXFBConfigAttrib(glxConfig, GLX_GREEN_SIZE);
+ config.blueSize = getGLXFBConfigAttrib(glxConfig, GLX_BLUE_SIZE);
+ config.alphaSize = getGLXFBConfigAttrib(glxConfig, GLX_ALPHA_SIZE);
+ config.depthSize = getGLXFBConfigAttrib(glxConfig, GLX_DEPTH_SIZE);
+ config.stencilSize = getGLXFBConfigAttrib(glxConfig, GLX_STENCIL_SIZE);
+
+ // We require RGBA8 and the D24S8 (or no DS buffer)
+ if (config.redSize != contextRedSize || config.greenSize != contextGreenSize ||
+ config.blueSize != contextBlueSize || config.alphaSize != contextAlphaSize)
+ {
+ continue;
+ }
+ // The GLX spec says that it is ok for a whole buffer to not be present
+ // however the Mesa Intel driver (and probably on other Mesa drivers)
+ // fails to make current when the Depth stencil doesn't exactly match the
+ // configuration.
+ bool hasSameDepthStencil =
+ config.depthSize == contextDepthSize && config.stencilSize == contextStencilSize;
+ bool hasNoDepthStencil = config.depthSize == 0 && config.stencilSize == 0;
+ if (!hasSameDepthStencil && (mIsMesa || !hasNoDepthStencil))
+ {
+ continue;
+ }
+
+ config.colorBufferType = EGL_RGB_BUFFER;
+ config.luminanceSize = 0;
+ config.alphaMaskSize = 0;
+
+ config.bufferSize = config.redSize + config.greenSize + config.blueSize + config.alphaSize;
+
+ // Multisample and accumulation buffers
+ int samples = mHasMultisample ? getGLXFBConfigAttrib(glxConfig, GLX_SAMPLES) : 0;
+ int sampleBuffers =
+ mHasMultisample ? getGLXFBConfigAttrib(glxConfig, GLX_SAMPLE_BUFFERS) : 0;
+
+ int accumRedSize = getGLXFBConfigAttrib(glxConfig, GLX_ACCUM_RED_SIZE);
+ int accumGreenSize = getGLXFBConfigAttrib(glxConfig, GLX_ACCUM_GREEN_SIZE);
+ int accumBlueSize = getGLXFBConfigAttrib(glxConfig, GLX_ACCUM_BLUE_SIZE);
+ int accumAlphaSize = getGLXFBConfigAttrib(glxConfig, GLX_ACCUM_ALPHA_SIZE);
+
+ if (samples != contextSamples ||
+ sampleBuffers != contextSampleBuffers ||
+ accumRedSize != contextAccumRedSize ||
+ accumGreenSize != contextAccumGreenSize ||
+ accumBlueSize != contextAccumBlueSize ||
+ accumAlphaSize != contextAccumAlphaSize)
+ {
+ continue;
+ }
+
+ config.samples = samples;
+ config.sampleBuffers = sampleBuffers;
+
+ // Transparency
+ if (getGLXFBConfigAttrib(glxConfig, GLX_TRANSPARENT_TYPE) == GLX_TRANSPARENT_RGB)
+ {
+ config.transparentType = EGL_TRANSPARENT_RGB;
+ config.transparentRedValue = getGLXFBConfigAttrib(glxConfig, GLX_TRANSPARENT_RED_VALUE);
+ config.transparentGreenValue = getGLXFBConfigAttrib(glxConfig, GLX_TRANSPARENT_GREEN_VALUE);
+ config.transparentBlueValue = getGLXFBConfigAttrib(glxConfig, GLX_TRANSPARENT_BLUE_VALUE);
+ }
+ else
+ {
+ config.transparentType = EGL_NONE;
+ }
+
+ // Pbuffer
+ config.maxPBufferWidth = getGLXFBConfigAttrib(glxConfig, GLX_MAX_PBUFFER_WIDTH);
+ config.maxPBufferHeight = getGLXFBConfigAttrib(glxConfig, GLX_MAX_PBUFFER_HEIGHT);
+ config.maxPBufferPixels = getGLXFBConfigAttrib(glxConfig, GLX_MAX_PBUFFER_PIXELS);
+
+ // Caveat
+ config.configCaveat = EGL_NONE;
+
+ int caveat = getGLXFBConfigAttrib(glxConfig, GLX_CONFIG_CAVEAT);
+ if (caveat == GLX_SLOW_CONFIG)
+ {
+ config.configCaveat = EGL_SLOW_CONFIG;
+ }
+ else if (caveat == GLX_NON_CONFORMANT_CONFIG)
+ {
+ continue;
+ }
+
+ // Misc
+ config.level = getGLXFBConfigAttrib(glxConfig, GLX_LEVEL);
+
+ config.bindToTextureRGB = EGL_FALSE;
+ config.bindToTextureRGBA = EGL_FALSE;
+
+ int glxDrawable = getGLXFBConfigAttrib(glxConfig, GLX_DRAWABLE_TYPE);
+ config.surfaceType = 0 |
+ (glxDrawable & GLX_WINDOW_BIT ? EGL_WINDOW_BIT : 0) |
+ (glxDrawable & GLX_PBUFFER_BIT ? EGL_PBUFFER_BIT : 0) |
+ (glxDrawable & GLX_PIXMAP_BIT ? EGL_PIXMAP_BIT : 0);
+
+ config.minSwapInterval = mMinSwapInterval;
+ config.maxSwapInterval = mMaxSwapInterval;
+
+ // TODO(cwallez) wildly guessing these formats, another TODO says they should be removed anyway
+ config.renderTargetFormat = GL_RGBA8;
+ config.depthStencilFormat = GL_DEPTH24_STENCIL8;
+
+ config.conformant = EGL_OPENGL_ES2_BIT | (supportsES3 ? EGL_OPENGL_ES3_BIT_KHR : 0);
+ config.renderableType = config.conformant;
+
+ // TODO(cwallez) I have no idea what this is
+ config.matchNativePixmap = EGL_NONE;
+
+ int id = configs.add(config);
+ configIdToGLXConfig[id] = glxConfig;
+ }
+
+ XFree(glxConfigs);
+
+ return configs;
+}
+
+bool DisplayGLX::testDeviceLost()
+{
+ if (mHasARBCreateContextRobustness)
+ {
+ return getRenderer()->getResetStatus() != GL_NO_ERROR;
+ }
+
+ return false;
+}
+
+egl::Error DisplayGLX::restoreLostDevice()
+{
+ return egl::Error(EGL_BAD_DISPLAY);
+}
+
+bool DisplayGLX::isValidNativeWindow(EGLNativeWindowType window) const
+{
+ // There is no function in Xlib to check the validity of a Window directly.
+ // However a small number of functions used to obtain window information
+ // return a status code (0 meaning failure) and guarantee that they will
+ // fail if the window doesn't exist (the rational is that these function
+ // are used by window managers). Out of these function we use XQueryTree
+ // as it seems to be the simplest; a drawback is that it will allocate
+ // memory for the list of children, because we use a child window for
+ // WindowSurface.
+ Window root;
+ Window parent;
+ Window *children = nullptr;
+ unsigned nChildren;
+ int status = XQueryTree(mGLX.getDisplay(), window, &root, &parent, &children, &nChildren);
+ if (children)
+ {
+ XFree(children);
+ }
+ return status != 0;
+}
+
+std::string DisplayGLX::getVendorString() const
+{
+ // UNIMPLEMENTED();
+ return "";
+}
+
+egl::Error DisplayGLX::waitClient() const
+{
+ mGLX.waitGL();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DisplayGLX::getDriverVersion(std::string *version) const
+{
+ VendorID vendor = GetVendorID(mFunctionsGL);
+
+ switch (vendor)
+ {
+ case VENDOR_ID_NVIDIA:
+ return getNVIDIADriverVersion(version);
+ case VENDOR_ID_AMD:
+ return GetAMDDriverVersion(version);
+ default:
+ *version = "";
+ return egl::Error(EGL_SUCCESS);
+ }
+}
+
+egl::Error DisplayGLX::waitNative(EGLint engine,
+ egl::Surface *drawSurface,
+ egl::Surface *readSurface) const
+{
+ // eglWaitNative is used to notice the driver of changes in X11 for the current surface, such as
+ // changes of the window size. We use this event to update the child window of WindowSurfaceGLX
+ // to match its parent window's size.
+ // Handling eglWaitNative this way helps the application control when resize happens. This is
+ // important because drivers have a tendency to clobber the back buffer when the windows are
+ // resized. See http://crbug.com/326995
+ if (drawSurface != nullptr)
+ {
+ SurfaceGLX *glxDrawSurface = GetImplAs<SurfaceGLX>(drawSurface);
+ egl::Error error = glxDrawSurface->checkForResize();
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ if (readSurface != drawSurface && readSurface != nullptr)
+ {
+ SurfaceGLX *glxReadSurface = GetImplAs<SurfaceGLX>(readSurface);
+ egl::Error error = glxReadSurface->checkForResize();
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ // We still need to forward the resizing of the child window to the driver.
+ mGLX.waitX();
+ return egl::Error(EGL_SUCCESS);
+}
+
+void DisplayGLX::syncXCommands() const
+{
+ if (mUsesNewXDisplay)
+ {
+ XSync(mGLX.getDisplay(), False);
+ }
+}
+
+void DisplayGLX::setSwapInterval(glx::Drawable drawable, SwapControlData *data)
+{
+ ASSERT(data != nullptr);
+
+ // TODO(cwallez) error checking?
+ if (mSwapControl == SwapControl::EXT)
+ {
+ // Prefer the EXT extension, it gives per-drawable swap intervals, which will
+ // minimize the number of driver calls.
+ if (data->maxSwapInterval < 0)
+ {
+ unsigned int maxSwapInterval = 0;
+ mGLX.queryDrawable(drawable, GLX_MAX_SWAP_INTERVAL_EXT, &maxSwapInterval);
+ data->maxSwapInterval = static_cast<int>(maxSwapInterval);
+ }
+
+ // When the egl configs were generated we had to guess what the max swap interval
+ // was because we didn't have a window to query it one (and that this max could
+ // depend on the monitor). This means that the target interval might be higher
+ // than the max interval and needs to be clamped.
+ const int realInterval = std::min(data->targetSwapInterval, data->maxSwapInterval);
+ if (data->currentSwapInterval != realInterval)
+ {
+ mGLX.swapIntervalEXT(drawable, realInterval);
+ data->currentSwapInterval = realInterval;
+ }
+ }
+ else if (mCurrentSwapInterval != data->targetSwapInterval)
+ {
+ // With the Mesa or SGI extensions we can still do per-drawable swap control
+ // manually but it is more expensive in number of driver calls.
+ if (mSwapControl == SwapControl::Mesa)
+ {
+ mGLX.swapIntervalMESA(data->targetSwapInterval);
+ }
+ else if (mSwapControl == SwapControl::SGI)
+ {
+ mGLX.swapIntervalSGI(data->targetSwapInterval);
+ }
+ mCurrentSwapInterval = data->targetSwapInterval;
+ }
+}
+
+bool DisplayGLX::isValidWindowVisualId(unsigned long visualId) const
+{
+ return mRequestedVisual == -1 || static_cast<unsigned long>(mRequestedVisual) == visualId;
+}
+
+const FunctionsGL *DisplayGLX::getFunctionsGL() const
+{
+ return mFunctionsGL;
+}
+
+void DisplayGLX::generateExtensions(egl::DisplayExtensions *outExtensions) const
+{
+ outExtensions->createContextRobustness = mHasARBCreateContextRobustness;
+}
+
+void DisplayGLX::generateCaps(egl::Caps *outCaps) const
+{
+ outCaps->textureNPOT = true;
+}
+
+int DisplayGLX::getGLXFBConfigAttrib(glx::FBConfig config, int attrib) const
+{
+ int result;
+ mGLX.getFBConfigAttrib(config, attrib, &result);
+ return result;
+}
+
+egl::Error DisplayGLX::createContextAttribs(glx::FBConfig,
+ const Optional<gl::Version> &version,
+ int profileMask,
+ glx::Context *context) const
+{
+ std::vector<int> attribs;
+
+ if (mHasARBCreateContextRobustness)
+ {
+ attribs.push_back(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB);
+ attribs.push_back(GLX_LOSE_CONTEXT_ON_RESET_ARB);
+ }
+
+ if (version.valid())
+ {
+ attribs.push_back(GLX_CONTEXT_MAJOR_VERSION_ARB);
+ attribs.push_back(version.value().major);
+
+ attribs.push_back(GLX_CONTEXT_MINOR_VERSION_ARB);
+ attribs.push_back(version.value().minor);
+ }
+
+ if (profileMask != 0 && mHasARBCreateContextProfile)
+ {
+ attribs.push_back(GLX_CONTEXT_PROFILE_MASK_ARB);
+ attribs.push_back(profileMask);
+ }
+
+ attribs.push_back(None);
+
+ // When creating a context with glXCreateContextAttribsARB, a variety of X11 errors can
+ // be generated. To prevent these errors from crashing our process, we simply ignore
+ // them and only look if GLXContext was created.
+ // Process all events before setting the error handler to avoid desynchronizing XCB instances
+ // (the error handler is NOT per-display).
+ XSync(mXDisplay, False);
+ auto oldErrorHandler = XSetErrorHandler(IgnoreX11Errors);
+ *context = mGLX.createContextAttribsARB(mContextConfig, nullptr, True, attribs.data());
+ XSetErrorHandler(oldErrorHandler);
+
+ if (!*context)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Could not create GL context.");
+ }
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DisplayGLX::getNVIDIADriverVersion(std::string *version) const
+{
+ *version = "";
+
+ int eventBase = 0;
+ int errorBase = 0;
+ if (XNVCTRLQueryExtension(mXDisplay, &eventBase, &errorBase))
+ {
+ int screenCount = ScreenCount(mXDisplay);
+ for (int screen = 0; screen < screenCount; ++screen)
+ {
+ char *buffer = nullptr;
+ if (XNVCTRLIsNvScreen(mXDisplay, screen) &&
+ XNVCTRLQueryStringAttribute(mXDisplay, screen, 0,
+ NV_CTRL_STRING_NVIDIA_DRIVER_VERSION, &buffer))
+ {
+ *version = buffer;
+ XFree(buffer);
+ }
+ }
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/glx/DisplayGLX.h b/gfx/angle/src/libANGLE/renderer/gl/glx/DisplayGLX.h
new file mode 100755
index 000000000..7e870c2f3
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/glx/DisplayGLX.h
@@ -0,0 +1,151 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// DisplayGLX.h: GLX implementation of egl::Display
+
+#ifndef LIBANGLE_RENDERER_GL_GLX_DISPLAYGLX_H_
+#define LIBANGLE_RENDERER_GL_GLX_DISPLAYGLX_H_
+
+#include <string>
+#include <vector>
+
+#include "common/Optional.h"
+#include "libANGLE/renderer/gl/DisplayGL.h"
+#include "libANGLE/renderer/gl/glx/FunctionsGLX.h"
+
+namespace rx
+{
+
+class FunctionsGLX;
+
+// State-tracking data for the swap control to allow DisplayGLX to remember per
+// drawable information for swap control.
+struct SwapControlData
+{
+ SwapControlData();
+
+ // Set by the drawable
+ int targetSwapInterval;
+
+ // DisplayGLX-side state-tracking
+ int maxSwapInterval;
+ int currentSwapInterval;
+};
+
+class DisplayGLX : public DisplayGL
+{
+ public:
+ DisplayGLX();
+ ~DisplayGLX() override;
+
+ egl::Error initialize(egl::Display *display) override;
+ void terminate() override;
+
+ SurfaceImpl *createWindowSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLNativeWindowType window,
+ const egl::AttributeMap &attribs) override;
+ SurfaceImpl *createPbufferSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ const egl::AttributeMap &attribs) override;
+ SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs) override;
+ SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ NativePixmapType nativePixmap,
+ const egl::AttributeMap &attribs) override;
+
+ egl::ConfigSet generateConfigs() override;
+
+ bool testDeviceLost() override;
+ egl::Error restoreLostDevice() override;
+
+ bool isValidNativeWindow(EGLNativeWindowType window) const override;
+
+ egl::Error getDevice(DeviceImpl **device) override;
+
+ std::string getVendorString() const override;
+
+ egl::Error waitClient() const override;
+ egl::Error waitNative(EGLint engine,
+ egl::Surface *drawSurface,
+ egl::Surface *readSurface) const override;
+
+ egl::Error getDriverVersion(std::string *version) const override;
+
+ // Synchronizes with the X server, if the display has been opened by ANGLE.
+ // Calling this is required at the end of every functions that does buffered
+ // X calls (not for glX calls) otherwise there might be race conditions
+ // between the application's display and ANGLE's one.
+ void syncXCommands() const;
+
+ // Depending on the supported GLX extension, swap interval can be set
+ // globally or per drawable. This function will make sure the drawable's
+ // swap interval is the one required so that the subsequent swapBuffers
+ // acts as expected.
+ void setSwapInterval(glx::Drawable drawable, SwapControlData *data);
+
+ bool isValidWindowVisualId(unsigned long visualId) const;
+
+ private:
+ const FunctionsGL *getFunctionsGL() const override;
+
+ egl::Error initializeContext(glx::FBConfig config,
+ const egl::AttributeMap &eglAttributes,
+ glx::Context *context);
+
+ void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
+ void generateCaps(egl::Caps *outCaps) const override;
+
+ int getGLXFBConfigAttrib(glx::FBConfig config, int attrib) const;
+ egl::Error createContextAttribs(glx::FBConfig,
+ const Optional<gl::Version> &version,
+ int profileMask,
+ glx::Context *context) const;
+
+ egl::Error getNVIDIADriverVersion(std::string *version) const;
+
+ FunctionsGL *mFunctionsGL;
+
+ std::map<int, glx::FBConfig> configIdToGLXConfig;
+
+ EGLint mRequestedVisual;
+ glx::FBConfig mContextConfig;
+ glx::Context mContext;
+ // A pbuffer the context is current on during ANGLE initialization
+ glx::Pbuffer mDummyPbuffer;
+
+ bool mUsesNewXDisplay;
+ bool mIsMesa;
+ bool mHasMultisample;
+ bool mHasARBCreateContext;
+ bool mHasARBCreateContextProfile;
+ bool mHasARBCreateContextRobustness;
+ bool mHasEXTCreateContextES2Profile;
+
+ enum class SwapControl
+ {
+ Absent,
+ EXT,
+ Mesa,
+ SGI,
+ };
+ SwapControl mSwapControl;
+ int mMinSwapInterval;
+ int mMaxSwapInterval;
+ int mCurrentSwapInterval;
+
+ FunctionsGLX mGLX;
+ Display *mXDisplay;
+ egl::Display *mEGLDisplay;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_GLX_DISPLAYGLX_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/glx/FBConfigCompatibility.md b/gfx/angle/src/libANGLE/renderer/gl/glx/FBConfigCompatibility.md
new file mode 100755
index 000000000..2343ad086
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/glx/FBConfigCompatibility.md
@@ -0,0 +1,204 @@
+GLX Framebuffer Compatibility investigation
+===========================================
+
+In GLX and EGL, contexts are created with respect to a config that
+describes the type of surfaces they will be used to render to.
+Likewise surfaces are created with respect to a config and for
+a context to be able to render to a surface, both their configs
+must be compatible. Compatibility is losely described in both
+the GLX and EGL specs but the following is clear:
+ * In GLX the config's color buffer must have the same type, including
+RGBA vs. ColorIndex and the buffers must have the same depth, if they
+exist.
+ * In EGL the config's color buffer must have the same type and the
+buffers must have the same depth (not clear if it is only if they exist)
+
+Obviously the EGLconfig we will expose will have a one-to-one
+correspondance with GLXFBConfigs.
+
+Our EGL implementation uses a single OpenGL context to back all
+the EGLcontexts created by the application. Since our GL context
+and GLXContext are the same object but in two APIs, we will make
+the confusion and call the GLX context our backing context.
+
+The problem we have is that the the GLX context is created before
+the application can choose what type of context it wants to use,
+that means we have to expose EGLconfigs whose respective GLXFBConfigs
+are compatible with the GLXFBConfig of our GLX context; we also need
+to choose the GLXFBConfig of our GLX context so that it matches the
+most common needs of application.
+
+Choice of the GLX context GLXFBConfig
+-------------------------------------
+
+We decided that our GLX context's configuration must satisfy the following:
+ * Have a RGBA8 color buffer and D24S8 depth-stencil buffer which is what
+the vast majority of applications use.
+ * It must render in direct colors, i.e. not in a color indexed format.
+ * It must be double-buffered (see later)
+ * It must support rendering to all the types of GLX surfaces so that we can
+use it for all types of EGL surfaces
+ * It must have an associated visual ID so that we can use it with X, it seems
+like this would be strongly tied to it having the ```WINDOW_BIT``` set.
+ * We would like a conformant context.
+
+Study of compatible GLXFBConfigs
+--------------------------------
+
+When using the condition of compatibility defined in the GLX spec and filtering
+out the non-conformant GLXFBConfig we got the following list (see function
+```print_visual_attribs_short``` in [glxinfo's source code](http://cgit.freedesktop.org/mesa/demos/tree/src/xdemos/glxinfo.c)
+to understand how to read the table):
+
+```
+ visual x bf lv rg d st colorbuffer sr ax dp st accumbuffer ms cav
+ id dep cl sp sz l ci b ro r g b a F gb bf th cl r g b a ns b eat Result
+----------------------------------------------------------------------------
+0x02e 24 tc 0 32 0 r . . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None Fail
+0x0e4 32 tc 0 32 0 r . . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None BadMatch
+0x02c 24 tc 0 32 0 r y . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None Pass
+0x0e2 32 tc 0 32 0 r y . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None BadMatch
+0x089 24 dc 0 32 0 r . . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None Fail
+0x087 24 dc 0 32 0 r y . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None Pass
+0x026 24 tc 0 32 0 r . . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None Fail
+0x0dc 32 tc 0 32 0 r . . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None BadMatch
+0x024 24 tc 0 32 0 r y . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None Pass
+0x0da 32 tc 0 32 0 r y . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None BadMatch
+0x081 24 dc 0 32 0 r . . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None Fail
+0x07f 24 dc 0 32 0 r y . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None Pass
+```
+
+The last column shows the result of trying to render on a window using the config,
+with a GLX context using config 0x024. The first thing we see is that BadMatch is
+thrown by the X server when creating the subwindow for rendering. This was because
+we didn't set the border pixel of the subwindow *shake fist at X11* (see this [StackOverflow question](http://stackoverflow.com/questions/3645632/how-to-create-a-window-with-a-bit-depth-of-32)).
+The result updated with this fix give:
+
+```
+ visual x bf lv rg d st colorbuffer sr ax dp st accumbuffer ms cav
+ id dep cl sp sz l ci b ro r g b a F gb bf th cl r g b a ns b eat
+----------------------------------------------------------------------------
+0x02e 24 tc 0 32 0 r . . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None Fail
+0x0e4 32 tc 0 32 0 r . . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None Fail
+0x02c 24 tc 0 32 0 r y . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None Pass
+0x0e2 32 tc 0 32 0 r y . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None Pass
+0x089 24 dc 0 32 0 r . . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None Fail
+0x087 24 dc 0 32 0 r y . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None Pass
+0x026 24 tc 0 32 0 r . . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None Fail
+0x0dc 32 tc 0 32 0 r . . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None Fail
+0x024 24 tc 0 32 0 r y . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None Pass
+0x0da 32 tc 0 32 0 r y . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None Pass
+0x081 24 dc 0 32 0 r . . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None Fail
+0x07f 24 dc 0 32 0 r y . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None Pass
+```
+
+From this we see that our rendering test passed if and only if the config was double
+buffered like 0x024 which is our GLX context config. The compatible configs are then:
+
+```
+ visual x bf lv rg d st colorbuffer sr ax dp st accumbuffer ms cav
+ id dep cl sp sz l ci b ro r g b a F gb bf th cl r g b a ns b eat
+----------------------------------------------------------------------------
+0x02c 24 tc 0 32 0 r y . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None
+0x0e2 32 tc 0 32 0 r y . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None
+0x087 24 dc 0 32 0 r y . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None
+0x024 24 tc 0 32 0 r y . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None
+0x0da 32 tc 0 32 0 r y . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None
+0x07f 24 dc 0 32 0 r y . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None
+```
+
+We can see two dimensions, with our without a depth-stencil buffer and with TrueColor
+or DirectColor. The depth-stencil will be useful to expose to application.
+
+More on double buffering
+------------------------
+The tests above show that double-buffered contexts are not compatible with single-
+buffered surfaces; however other tests show that single-buffered contexts are
+compatible with both single and double-buffered surfaces. The problem is that in
+that case, we can see some flickering even with double-buffered surfaces. If we
+can find a trick to avoid that flicker, then we would be able to expose single
+and double-buffered surfaces at the EGL level. Not exposing them isn't too much
+of a problem though as the vast majority of application want double-buffering.
+
+AMD and extra buffers
+---------------------
+As can be seen above, NVIDIA does not expose conformant context with multisampled
+buffers or non RGBA16 accumulation buffers. The behavior is different on AMD that
+exposes them as conformant, which gives the following list after filtering as
+explained above:
+
+```
+ visual x bf lv rg d st colorbuffer sr ax dp st accumbuffer ms cav
+ id dep cl sp sz l ci b ro r g b a F gb bf th cl r g b a ns b eat
+----------------------------------------------------------------------------
+0x023 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 16 16 16 16 0 0 None
+0x027 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None
+0x02b 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 2 1 None
+0x02f 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 4 1 None
+0x03b 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 16 16 16 16 0 0 None
+0x03f 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None
+0x043 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 2 1 None
+0x047 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 4 1 None
+```
+
+ANGLE's context is created using 0x027 and experimentation shows it is only compatible
+with 0x03f which is the only other config lacking both an accumulation buffer and a
+multisample buffer. The GLX spec seems to hint it should still work ("should have the
+same size, if they exist") but it doesn't work in this case. Filtering the configs to
+have the same multisample and accumulation buffers gives the following:
+
+```
+ visual x bf lv rg d st colorbuffer sr ax dp st accumbuffer ms cav
+ id dep cl sp sz l ci b ro r g b a F gb bf th cl r g b a ns b eat
+----------------------------------------------------------------------------
+0x027 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None
+0x03f 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None
+```
+
+Mesa Intel driver
+-----------------
+In GLX, a criterium for context and surface compatibility is that buffers
+should have the same depth, if they exist at all in the surface. This means
+that it should be possible to make a context with a D24S8 depth-stencil
+buffer to a surface without a depth-stencil buffer. This doesn't work on the
+Mesa Intel driver. The list before the workaround was the following, with
+0x020 being the fbconfig chosen for the context:
+
+```
+ visual x bf lv rg d st colorbuffer sr ax dp st accumbuffer ms cav
+ id dep cl sp sz l ci b ro r g b a F gb bf th cl r g b a ns b eat
+----------------------------------------------------------------------------
+0x020 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None
+0x021 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None
+0x08f 32 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None
+0x0d0 24 tc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 0 0 None
+0x0e2 24 dc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 0 0 None
+0x0e9 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None
+```
+
+After the workaround that list becomes the following:
+
+```
+ visual x bf lv rg d st colorbuffer sr ax dp st accumbuffer ms cav
+ id dep cl sp sz l ci b ro r g b a F gb bf th cl r g b a ns b eat
+----------------------------------------------------------------------------
+0x020 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None
+0x021 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None
+0x08f 32 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None
+0x0e9 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None
+```
+
+Future investigation
+--------------------
+All the non-conformant configs have a multisampled buffer, so it could be interesting
+to see if we can use them to expose another EGL extension.
+
+Finally this document is written with respect to a small number of drivers, before
+using the GLX EGL implementation in the wild it would be good to test it on other
+drivers and hardware.
+
+The drivers tested were:
+
+ - the proprietary NVIDIA driver
+ - the proprietary AMD driver
+ - the open source Intel (Broadwell) Mesa driver
diff --git a/gfx/angle/src/libANGLE/renderer/gl/glx/FunctionsGLX.cpp b/gfx/angle/src/libANGLE/renderer/gl/glx/FunctionsGLX.cpp
new file mode 100755
index 000000000..4ec38dd81
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/glx/FunctionsGLX.cpp
@@ -0,0 +1,398 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FunctionsGLX.cpp: Implements the FunctionsGLX class.
+
+#define ANGLE_SKIP_GLX_DEFINES 1
+#include "libANGLE/renderer/gl/glx/FunctionsGLX.h"
+#undef ANGLE_SKIP_GLX_DEFINES
+
+// We can only include glx.h in files which do not include ANGLE's GLES
+// headers, to avoid doubly-defined GLenum macros, typedefs, etc.
+#include <GL/glx.h>
+
+#include <dlfcn.h>
+#include <algorithm>
+
+#include "common/string_utils.h"
+#include "libANGLE/renderer/gl/glx/functionsglx_typedefs.h"
+
+namespace rx
+{
+
+void* FunctionsGLX::sLibHandle = nullptr;
+
+template<typename T>
+static bool GetProc(PFNGETPROCPROC getProc, T *member, const char *name)
+{
+ *member = reinterpret_cast<T>(getProc(name));
+ return *member != nullptr;
+}
+
+struct FunctionsGLX::GLXFunctionTable
+{
+ GLXFunctionTable()
+ : createContextPtr(nullptr),
+ destroyContextPtr(nullptr),
+ makeCurrentPtr(nullptr),
+ swapBuffersPtr(nullptr),
+ queryExtensionPtr(nullptr),
+ queryVersionPtr(nullptr),
+ getCurrentContextPtr(nullptr),
+ getCurrentDrawablePtr(nullptr),
+ waitXPtr(nullptr),
+ waitGLPtr(nullptr),
+ getClientStringPtr(nullptr),
+ queryExtensionsStringPtr(nullptr),
+ getFBConfigsPtr(nullptr),
+ chooseFBConfigPtr(nullptr),
+ getFBConfigAttribPtr(nullptr),
+ getVisualFromFBConfigPtr(nullptr),
+ createWindowPtr(nullptr),
+ destroyWindowPtr(nullptr),
+ createPbufferPtr(nullptr),
+ destroyPbufferPtr(nullptr),
+ queryDrawablePtr(nullptr),
+ createContextAttribsARBPtr(nullptr),
+ swapIntervalEXTPtr(nullptr),
+ swapIntervalMESAPtr(nullptr),
+ swapIntervalSGIPtr(nullptr)
+ {
+ }
+
+ // GLX 1.0
+ PFNGLXCREATECONTEXTPROC createContextPtr;
+ PFNGLXDESTROYCONTEXTPROC destroyContextPtr;
+ PFNGLXMAKECURRENTPROC makeCurrentPtr;
+ PFNGLXSWAPBUFFERSPROC swapBuffersPtr;
+ PFNGLXQUERYEXTENSIONPROC queryExtensionPtr;
+ PFNGLXQUERYVERSIONPROC queryVersionPtr;
+ PFNGLXGETCURRENTCONTEXTPROC getCurrentContextPtr;
+ PFNGLXGETCURRENTDRAWABLEPROC getCurrentDrawablePtr;
+ PFNGLXWAITXPROC waitXPtr;
+ PFNGLXWAITGLPROC waitGLPtr;
+
+ // GLX 1.1
+ PFNGLXGETCLIENTSTRINGPROC getClientStringPtr;
+ PFNGLXQUERYEXTENSIONSSTRINGPROC queryExtensionsStringPtr;
+
+ //GLX 1.3
+ PFNGLXGETFBCONFIGSPROC getFBConfigsPtr;
+ PFNGLXCHOOSEFBCONFIGPROC chooseFBConfigPtr;
+ PFNGLXGETFBCONFIGATTRIBPROC getFBConfigAttribPtr;
+ PFNGLXGETVISUALFROMFBCONFIGPROC getVisualFromFBConfigPtr;
+ PFNGLXCREATEWINDOWPROC createWindowPtr;
+ PFNGLXDESTROYWINDOWPROC destroyWindowPtr;
+ PFNGLXCREATEPBUFFERPROC createPbufferPtr;
+ PFNGLXDESTROYPBUFFERPROC destroyPbufferPtr;
+ PFNGLXQUERYDRAWABLEPROC queryDrawablePtr;
+
+ // GLX_ARB_create_context
+ PFNGLXCREATECONTEXTATTRIBSARBPROC createContextAttribsARBPtr;
+
+ // GLX_EXT_swap_control
+ PFNGLXSWAPINTERVALEXTPROC swapIntervalEXTPtr;
+
+ // GLX_MESA_swap_control
+ PFNGLXSWAPINTERVALMESAPROC swapIntervalMESAPtr;
+
+ // GLX_SGI_swap_control
+ PFNGLXSWAPINTERVALSGIPROC swapIntervalSGIPtr;
+};
+
+FunctionsGLX::FunctionsGLX()
+ : majorVersion(0),
+ minorVersion(0),
+ mXDisplay(nullptr),
+ mXScreen(-1),
+ mFnPtrs(new GLXFunctionTable())
+{
+}
+
+FunctionsGLX::~FunctionsGLX()
+{
+ delete mFnPtrs;
+ terminate();
+}
+
+bool FunctionsGLX::initialize(Display *xDisplay, int screen, std::string *errorString)
+{
+ terminate();
+ mXDisplay = xDisplay;
+ mXScreen = screen;
+
+#if !defined(ANGLE_LINK_GLX)
+ // Some OpenGL implementations can't handle having this library
+ // handle closed while there's any X window still open against
+ // which a GLXWindow was ever created.
+ if (!sLibHandle)
+ {
+ sLibHandle = dlopen("libGL.so.1", RTLD_NOW);
+ if (!sLibHandle)
+ {
+ *errorString = std::string("Could not dlopen libGL.so.1: ") + dlerror();
+ return false;
+ }
+ }
+
+ getProc = reinterpret_cast<PFNGETPROCPROC>(dlsym(sLibHandle, "glXGetProcAddress"));
+ if (!getProc)
+ {
+ getProc = reinterpret_cast<PFNGETPROCPROC>(dlsym(sLibHandle, "glXGetProcAddressARB"));
+ }
+ if (!getProc)
+ {
+ *errorString = "Could not retrieve glXGetProcAddress";
+ return false;
+ }
+#else
+ getProc = reinterpret_cast<PFNGETPROCPROC>(glXGetProcAddress);
+#endif
+
+#define GET_PROC_OR_ERROR(MEMBER, NAME) \
+ if (!GetProc(getProc, MEMBER, #NAME)) \
+ { \
+ *errorString = "Could not load GLX entry point " #NAME; \
+ return false; \
+ }
+#if !defined(ANGLE_LINK_GLX)
+#define GET_FNPTR_OR_ERROR(MEMBER, NAME) GET_PROC_OR_ERROR(MEMBER, NAME)
+#else
+#define GET_FNPTR_OR_ERROR(MEMBER, NAME) *MEMBER = NAME;
+#endif
+
+ // GLX 1.0
+ GET_FNPTR_OR_ERROR(&mFnPtrs->createContextPtr, glXCreateContext);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->destroyContextPtr, glXDestroyContext);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->makeCurrentPtr, glXMakeCurrent);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->swapBuffersPtr, glXSwapBuffers);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->queryExtensionPtr, glXQueryExtension);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->queryVersionPtr, glXQueryVersion);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->getCurrentContextPtr, glXGetCurrentContext);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->getCurrentDrawablePtr, glXGetCurrentDrawable);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->waitXPtr, glXWaitX);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->waitGLPtr, glXWaitGL);
+
+ // GLX 1.1
+ GET_FNPTR_OR_ERROR(&mFnPtrs->getClientStringPtr, glXGetClientString);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->queryExtensionsStringPtr, glXQueryExtensionsString);
+
+ // Check we have a working GLX
+ {
+ int errorBase;
+ int eventBase;
+ if (!queryExtension(&errorBase, &eventBase))
+ {
+ *errorString = "GLX is not present.";
+ return false;
+ }
+ }
+
+ // Check we have a supported version of GLX
+ if (!queryVersion(&majorVersion, &minorVersion))
+ {
+ *errorString = "Could not query the GLX version.";
+ return false;
+ }
+ if (majorVersion != 1 || minorVersion < 3)
+ {
+ *errorString = "Unsupported GLX version (requires at least 1.3).";
+ return false;
+ }
+
+ const char *extensions = queryExtensionsString();
+ if (!extensions)
+ {
+ *errorString = "glXQueryExtensionsString returned NULL";
+ return false;
+ }
+ angle::SplitStringAlongWhitespace(extensions, &mExtensions);
+
+ // GLX 1.3
+ GET_FNPTR_OR_ERROR(&mFnPtrs->getFBConfigsPtr, glXGetFBConfigs);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->chooseFBConfigPtr, glXChooseFBConfig);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->getFBConfigAttribPtr, glXGetFBConfigAttrib);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->getVisualFromFBConfigPtr, glXGetVisualFromFBConfig);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->createWindowPtr, glXCreateWindow);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->destroyWindowPtr, glXDestroyWindow);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->createPbufferPtr, glXCreatePbuffer);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->destroyPbufferPtr, glXDestroyPbuffer);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->queryDrawablePtr, glXQueryDrawable);
+
+ // Extensions
+ if (hasExtension("GLX_ARB_create_context"))
+ {
+ GET_PROC_OR_ERROR(&mFnPtrs->createContextAttribsARBPtr, glXCreateContextAttribsARB);
+ }
+ if (hasExtension("GLX_EXT_swap_control"))
+ {
+ GET_PROC_OR_ERROR(&mFnPtrs->swapIntervalEXTPtr, glXSwapIntervalEXT);
+ }
+ if (hasExtension("GLX_MESA_swap_control"))
+ {
+ GET_PROC_OR_ERROR(&mFnPtrs->swapIntervalMESAPtr, glXSwapIntervalMESA);
+ }
+ if (hasExtension("GLX_SGI_swap_control"))
+ {
+ GET_PROC_OR_ERROR(&mFnPtrs->swapIntervalSGIPtr, glXSwapIntervalSGI);
+ }
+
+#undef GET_FNPTR_OR_ERROR
+#undef GET_PROC_OR_ERROR
+
+ *errorString = "";
+ return true;
+}
+
+void FunctionsGLX::terminate()
+{
+}
+
+bool FunctionsGLX::hasExtension(const char *extension) const
+{
+ return std::find(mExtensions.begin(), mExtensions.end(), extension) != mExtensions.end();
+}
+
+Display *FunctionsGLX::getDisplay() const
+{
+ return mXDisplay;
+}
+
+int FunctionsGLX::getScreen() const
+{
+ return mXScreen;
+}
+
+// GLX functions
+
+// GLX 1.0
+glx::Context FunctionsGLX::createContext(XVisualInfo *visual, glx::Context share, bool direct) const
+{
+ GLXContext shareCtx = reinterpret_cast<GLXContext>(share);
+ GLXContext context = mFnPtrs->createContextPtr(mXDisplay, visual, shareCtx, direct);
+ return reinterpret_cast<glx::Context>(context);
+}
+void FunctionsGLX::destroyContext(glx::Context context) const
+{
+ GLXContext ctx = reinterpret_cast<GLXContext>(context);
+ mFnPtrs->destroyContextPtr(mXDisplay, ctx);
+}
+Bool FunctionsGLX::makeCurrent(glx::Drawable drawable, glx::Context context) const
+{
+ GLXContext ctx = reinterpret_cast<GLXContext>(context);
+ return mFnPtrs->makeCurrentPtr(mXDisplay, drawable, ctx);
+}
+void FunctionsGLX::swapBuffers(glx::Drawable drawable) const
+{
+ mFnPtrs->swapBuffersPtr(mXDisplay, drawable);
+}
+Bool FunctionsGLX::queryExtension(int *errorBase, int *event) const
+{
+ return mFnPtrs->queryExtensionPtr(mXDisplay, errorBase, event);
+}
+Bool FunctionsGLX::queryVersion(int *major, int *minor) const
+{
+ return mFnPtrs->queryVersionPtr(mXDisplay, major, minor);
+}
+glx::Context FunctionsGLX::getCurrentContext() const
+{
+ GLXContext context = mFnPtrs->getCurrentContextPtr();
+ return reinterpret_cast<glx::Context>(context);
+}
+glx::Drawable FunctionsGLX::getCurrentDrawable() const
+{
+ GLXDrawable drawable = mFnPtrs->getCurrentDrawablePtr();
+ return reinterpret_cast<glx::Drawable>(drawable);
+}
+void FunctionsGLX::waitX() const
+{
+ mFnPtrs->waitXPtr();
+}
+void FunctionsGLX::waitGL() const
+{
+ mFnPtrs->waitGLPtr();
+}
+
+// GLX 1.1
+const char *FunctionsGLX::getClientString(int name) const
+{
+ return mFnPtrs->getClientStringPtr(mXDisplay, name);
+}
+
+const char *FunctionsGLX::queryExtensionsString() const
+{
+ return mFnPtrs->queryExtensionsStringPtr(mXDisplay, mXScreen);
+}
+
+// GLX 1.4
+glx::FBConfig *FunctionsGLX::getFBConfigs(int *nElements) const
+{
+ GLXFBConfig *configs = mFnPtrs->getFBConfigsPtr(mXDisplay, mXScreen, nElements);
+ return reinterpret_cast<glx::FBConfig*>(configs);
+}
+glx::FBConfig *FunctionsGLX::chooseFBConfig(const int *attribList, int *nElements) const
+{
+ GLXFBConfig *configs = mFnPtrs->chooseFBConfigPtr(mXDisplay, mXScreen, attribList, nElements);
+ return reinterpret_cast<glx::FBConfig*>(configs);
+}
+int FunctionsGLX::getFBConfigAttrib(glx::FBConfig config, int attribute, int *value) const
+{
+ GLXFBConfig cfg = reinterpret_cast<GLXFBConfig>(config);
+ return mFnPtrs->getFBConfigAttribPtr(mXDisplay, cfg, attribute, value);
+}
+XVisualInfo *FunctionsGLX::getVisualFromFBConfig(glx::FBConfig config) const
+{
+ GLXFBConfig cfg = reinterpret_cast<GLXFBConfig>(config);
+ return mFnPtrs->getVisualFromFBConfigPtr(mXDisplay, cfg);
+}
+GLXWindow FunctionsGLX::createWindow(glx::FBConfig config, Window window, const int *attribList) const
+{
+ GLXFBConfig cfg = reinterpret_cast<GLXFBConfig>(config);
+ return mFnPtrs->createWindowPtr(mXDisplay, cfg, window, attribList);
+}
+void FunctionsGLX::destroyWindow(glx::Window window) const
+{
+ mFnPtrs->destroyWindowPtr(mXDisplay, window);
+}
+glx::Pbuffer FunctionsGLX::createPbuffer(glx::FBConfig config, const int *attribList) const
+{
+ GLXFBConfig cfg = reinterpret_cast<GLXFBConfig>(config);
+ return mFnPtrs->createPbufferPtr(mXDisplay, cfg, attribList);
+}
+void FunctionsGLX::destroyPbuffer(glx::Pbuffer pbuffer) const
+{
+ mFnPtrs->destroyPbufferPtr(mXDisplay, pbuffer);
+}
+void FunctionsGLX::queryDrawable(glx::Drawable drawable, int attribute, unsigned int *value) const
+{
+ mFnPtrs->queryDrawablePtr(mXDisplay, drawable, attribute, value);
+}
+
+// GLX_ARB_create_context
+glx::Context FunctionsGLX::createContextAttribsARB(glx::FBConfig config, glx::Context shareContext, Bool direct, const int *attribList) const
+{
+ GLXContext shareCtx = reinterpret_cast<GLXContext>(shareContext);
+ GLXFBConfig cfg = reinterpret_cast<GLXFBConfig>(config);
+ GLXContext ctx = mFnPtrs->createContextAttribsARBPtr(mXDisplay, cfg, shareCtx, direct, attribList);
+ return reinterpret_cast<glx::Context>(ctx);
+}
+
+void FunctionsGLX::swapIntervalEXT(glx::Drawable drawable, int intervals) const
+{
+ mFnPtrs->swapIntervalEXTPtr(mXDisplay, drawable, intervals);
+}
+
+int FunctionsGLX::swapIntervalMESA(int intervals) const
+{
+ return mFnPtrs->swapIntervalMESAPtr(intervals);
+}
+
+int FunctionsGLX::swapIntervalSGI(int intervals) const
+{
+ return mFnPtrs->swapIntervalSGIPtr(intervals);
+}
+
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/glx/FunctionsGLX.h b/gfx/angle/src/libANGLE/renderer/gl/glx/FunctionsGLX.h
new file mode 100755
index 000000000..98c2fef46
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/glx/FunctionsGLX.h
@@ -0,0 +1,96 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FunctionsGLX.h: Defines the FunctionsGLX class to load functions and data from GLX
+
+#ifndef LIBANGLE_RENDERER_GL_GLX_FUNCTIONSGLX_H_
+#define LIBANGLE_RENDERER_GL_GLX_FUNCTIONSGLX_H_
+
+#include <string>
+#include <vector>
+
+#include "libANGLE/renderer/gl/glx/platform_glx.h"
+
+namespace rx
+{
+
+class FunctionsGLX
+{
+ public:
+ FunctionsGLX();
+ ~FunctionsGLX();
+
+ // Load data from GLX, can be called multiple times
+ bool initialize(Display *xDisplay, int screen, std::string *errorString);
+ void terminate();
+
+ bool hasExtension(const char *extension) const;
+ int majorVersion;
+ int minorVersion;
+
+ Display *getDisplay() const;
+ int getScreen() const;
+
+ PFNGETPROCPROC getProc;
+
+ // GLX 1.0
+ glx::Context createContext(XVisualInfo *visual, glx::Context share, bool direct) const;
+ void destroyContext(glx::Context context) const;
+ Bool makeCurrent(glx::Drawable drawable, glx::Context context) const;
+ void swapBuffers(glx::Drawable drawable) const;
+ Bool queryExtension(int *errorBase, int *event) const;
+ Bool queryVersion(int *major, int *minor) const;
+ glx::Context getCurrentContext() const;
+ glx::Drawable getCurrentDrawable() const;
+ void waitX() const;
+ void waitGL() const;
+
+ // GLX 1.1
+ const char *getClientString(int name) const;
+ const char *queryExtensionsString() const;
+
+ // GLX 1.3
+ glx::FBConfig *getFBConfigs(int *nElements) const;
+ glx::FBConfig *chooseFBConfig(const int *attribList, int *nElements) const;
+ int getFBConfigAttrib(glx::FBConfig config, int attribute, int *value) const;
+ XVisualInfo *getVisualFromFBConfig(glx::FBConfig config) const;
+ glx::Window createWindow(glx::FBConfig config, Window window, const int *attribList) const;
+ void destroyWindow(glx::Window window) const;
+ glx::Pbuffer createPbuffer(glx::FBConfig config, const int *attribList) const;
+ void destroyPbuffer(glx::Pbuffer pbuffer) const;
+ void queryDrawable(glx::Drawable drawable, int attribute, unsigned int *value) const;
+
+ // GLX_ARB_create_context
+ glx::Context createContextAttribsARB(glx::FBConfig config, glx::Context shareContext, Bool direct, const int *attribList) const;
+
+ // GLX_EXT_swap_control
+ void swapIntervalEXT(glx::Drawable drawable, int interval) const;
+
+ // GLX_MESA_swap_control
+ int swapIntervalMESA(int interval) const;
+
+ // GLX_SGI_swap_control
+ int swapIntervalSGI(int interval) const;
+
+ private:
+ // So as to isolate GLX from angle we do not include angleutils.h and cannot
+ // use angle::NonCopyable so we replicated it here instead.
+ FunctionsGLX(const FunctionsGLX&) = delete;
+ void operator=(const FunctionsGLX&) = delete;
+
+ struct GLXFunctionTable;
+
+ static void *sLibHandle;
+ Display *mXDisplay;
+ int mXScreen;
+
+ GLXFunctionTable *mFnPtrs;
+ std::vector<std::string> mExtensions;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_GLX_FUNCTIONSGLX_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/glx/PbufferSurfaceGLX.cpp b/gfx/angle/src/libANGLE/renderer/gl/glx/PbufferSurfaceGLX.cpp
new file mode 100755
index 000000000..a97021b40
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/glx/PbufferSurfaceGLX.cpp
@@ -0,0 +1,143 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// PbufferSurfaceGLX.cpp: GLX implementation of egl::Surface for PBuffers
+
+#include "libANGLE/renderer/gl/glx/PbufferSurfaceGLX.h"
+
+#include "common/debug.h"
+#include "libANGLE/renderer/gl/glx/DisplayGLX.h"
+#include "libANGLE/renderer/gl/glx/FunctionsGLX.h"
+
+namespace rx
+{
+
+PbufferSurfaceGLX::PbufferSurfaceGLX(const egl::SurfaceState &state,
+ RendererGL *renderer,
+ EGLint width,
+ EGLint height,
+ bool largest,
+ const FunctionsGLX &glx,
+ glx::Context context,
+ glx::FBConfig fbConfig)
+ : SurfaceGLX(state, renderer),
+ mWidth(width),
+ mHeight(height),
+ mLargest(largest),
+ mGLX(glx),
+ mContext(context),
+ mFBConfig(fbConfig),
+ mPbuffer(0)
+{
+}
+
+PbufferSurfaceGLX::~PbufferSurfaceGLX()
+{
+ if (mPbuffer)
+ {
+ mGLX.destroyPbuffer(mPbuffer);
+ }
+}
+
+egl::Error PbufferSurfaceGLX::initialize()
+{
+ // Avoid creating 0-sized PBuffers as it fails on the Intel Mesa driver
+ // as commented on https://bugs.freedesktop.org/show_bug.cgi?id=38869 so we
+ // use (w, 1) or (1, h) instead.
+ int width = std::max(1, static_cast<int>(mWidth));
+ int height = std::max(1, static_cast<int>(mHeight));
+
+ const int attribs[] =
+ {
+ GLX_PBUFFER_WIDTH, width,
+ GLX_PBUFFER_HEIGHT, height,
+ GLX_LARGEST_PBUFFER, mLargest,
+ None
+ };
+
+ mPbuffer = mGLX.createPbuffer(mFBConfig, attribs);
+ if (!mPbuffer)
+ {
+ return egl::Error(EGL_BAD_ALLOC, "Failed to create a native GLX pbuffer.");
+ }
+
+ if (mLargest)
+ {
+ mGLX.queryDrawable(mPbuffer, GLX_WIDTH, &mWidth);
+ mGLX.queryDrawable(mPbuffer, GLX_HEIGHT, &mHeight);
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error PbufferSurfaceGLX::makeCurrent()
+{
+ if (mGLX.makeCurrent(mPbuffer, mContext) != True)
+ {
+ return egl::Error(EGL_BAD_DISPLAY);
+ }
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error PbufferSurfaceGLX::swap()
+{
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error PbufferSurfaceGLX::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
+{
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error PbufferSurfaceGLX::querySurfacePointerANGLE(EGLint attribute, void **value)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error PbufferSurfaceGLX::bindTexImage(gl::Texture *texture, EGLint buffer)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error PbufferSurfaceGLX::releaseTexImage(EGLint buffer)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+void PbufferSurfaceGLX::setSwapInterval(EGLint interval)
+{
+}
+
+EGLint PbufferSurfaceGLX::getWidth() const
+{
+ return mWidth;
+}
+
+EGLint PbufferSurfaceGLX::getHeight() const
+{
+ return mHeight;
+}
+
+EGLint PbufferSurfaceGLX::isPostSubBufferSupported() const
+{
+ UNIMPLEMENTED();
+ return EGL_FALSE;
+}
+
+EGLint PbufferSurfaceGLX::getSwapBehavior() const
+{
+ return EGL_BUFFER_PRESERVED;
+}
+
+egl::Error PbufferSurfaceGLX::checkForResize()
+{
+ // The size of pbuffers never change
+ return egl::Error(EGL_SUCCESS);
+}
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/glx/PbufferSurfaceGLX.h b/gfx/angle/src/libANGLE/renderer/gl/glx/PbufferSurfaceGLX.h
new file mode 100755
index 000000000..d346634b2
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/glx/PbufferSurfaceGLX.h
@@ -0,0 +1,64 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// PBufferSurfaceGLX.h: GLX implementation of egl::Surface for PBuffers
+
+#ifndef LIBANGLE_RENDERER_GL_GLX_PBUFFERSURFACEGLX_H_
+#define LIBANGLE_RENDERER_GL_GLX_PBUFFERSURFACEGLX_H_
+
+#include "libANGLE/renderer/gl/glx/platform_glx.h"
+#include "libANGLE/renderer/gl/glx/SurfaceGLX.h"
+
+namespace rx
+{
+
+class FunctionsGLX;
+
+class PbufferSurfaceGLX : public SurfaceGLX
+{
+ public:
+ PbufferSurfaceGLX(const egl::SurfaceState &state,
+ RendererGL *renderer,
+ EGLint width,
+ EGLint height,
+ bool largest,
+ const FunctionsGLX &glx,
+ glx::Context context,
+ glx::FBConfig fbConfig);
+ ~PbufferSurfaceGLX() override;
+
+ egl::Error initialize() override;
+ egl::Error makeCurrent() override;
+
+ egl::Error swap() override;
+ egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override;
+ egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override;
+ egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) override;
+ egl::Error releaseTexImage(EGLint buffer) override;
+ void setSwapInterval(EGLint interval) override;
+
+ EGLint getWidth() const override;
+ EGLint getHeight() const override;
+
+ EGLint isPostSubBufferSupported() const override;
+ EGLint getSwapBehavior() const override;
+
+ egl::Error checkForResize() override;
+
+ private:
+ unsigned mWidth;
+ unsigned mHeight;
+ bool mLargest;
+
+ const FunctionsGLX &mGLX;
+ glx::Context mContext;
+ glx::FBConfig mFBConfig;
+ glx::Pbuffer mPbuffer;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_GLX_PBUFFERSURFACEGLX_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/glx/SurfaceGLX.h b/gfx/angle/src/libANGLE/renderer/gl/glx/SurfaceGLX.h
new file mode 100755
index 000000000..813516e80
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/glx/SurfaceGLX.h
@@ -0,0 +1,26 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// SurfaceGLX.h: common interface for GLX surfaces
+
+#ifndef LIBANGLE_RENDERER_GL_GLX_SURFACEGLX_H_
+#define LIBANGLE_RENDERER_GL_GLX_SURFACEGLX_H_
+
+#include "libANGLE/renderer/gl/SurfaceGL.h"
+
+namespace rx
+{
+
+class SurfaceGLX : public SurfaceGL
+{
+ public:
+ SurfaceGLX(const egl::SurfaceState &state, RendererGL *renderer) : SurfaceGL(state, renderer) {}
+
+ virtual egl::Error checkForResize() = 0;
+};
+}
+
+#endif // LIBANGLE_RENDERER_GL_GLX_SURFACEGLX_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/glx/WindowSurfaceGLX.cpp b/gfx/angle/src/libANGLE/renderer/gl/glx/WindowSurfaceGLX.cpp
new file mode 100755
index 000000000..21b1b316f
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/glx/WindowSurfaceGLX.cpp
@@ -0,0 +1,244 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// WindowSurfaceGLX.cpp: GLX implementation of egl::Surface for windows
+
+#include "libANGLE/renderer/gl/glx/WindowSurfaceGLX.h"
+
+#include "common/debug.h"
+
+#include "libANGLE/renderer/gl/glx/DisplayGLX.h"
+#include "libANGLE/renderer/gl/glx/FunctionsGLX.h"
+
+namespace rx
+{
+
+static int IgnoreX11Errors(Display *, XErrorEvent *)
+{
+ return 0;
+}
+
+WindowSurfaceGLX::WindowSurfaceGLX(const egl::SurfaceState &state,
+ const FunctionsGLX &glx,
+ DisplayGLX *glxDisplay,
+ RendererGL *renderer,
+ Window window,
+ Display *display,
+ glx::Context context,
+ glx::FBConfig fbConfig)
+ : SurfaceGLX(state, renderer),
+ mParent(window),
+ mWindow(0),
+ mDisplay(display),
+ mGLX(glx),
+ mGLXDisplay(glxDisplay),
+ mContext(context),
+ mFBConfig(fbConfig),
+ mGLXWindow(0)
+{
+}
+
+WindowSurfaceGLX::~WindowSurfaceGLX()
+{
+ if (mGLXWindow)
+ {
+ mGLX.destroyWindow(mGLXWindow);
+ }
+
+ if (mWindow)
+ {
+ // When destroying the window, it may happen that the window has already been
+ // destroyed by the application (this happens in Chromium). There is no way to
+ // atomically check that a window exists and to destroy it so instead we call
+ // XDestroyWindow, ignoring any errors.
+ auto oldErrorHandler = XSetErrorHandler(IgnoreX11Errors);
+ XDestroyWindow(mDisplay, mWindow);
+ XSync(mDisplay, False);
+ XSetErrorHandler(oldErrorHandler);
+ }
+
+ mGLXDisplay->syncXCommands();
+}
+
+egl::Error WindowSurfaceGLX::initialize()
+{
+ // Check that the window's visual ID is valid, as part of the AMGLE_x11_visual
+ // extension.
+ {
+ XWindowAttributes windowAttributes;
+ XGetWindowAttributes(mDisplay, mParent, &windowAttributes);
+ unsigned long visualId = windowAttributes.visual->visualid;
+
+ if (!mGLXDisplay->isValidWindowVisualId(visualId))
+ {
+ return egl::Error(EGL_BAD_MATCH,
+ "The visual of native_window doesn't match the visual given with "
+ "ANGLE_X11_VISUAL_ID");
+ }
+ }
+
+ // The visual of the X window, GLX window and GLX context must match,
+ // however we received a user-created window that can have any visual
+ // and wouldn't work with our GLX context. To work in all cases, we
+ // create a child window with the right visual that covers all of its
+ // parent.
+ XVisualInfo *visualInfo = mGLX.getVisualFromFBConfig(mFBConfig);
+ if (!visualInfo)
+ {
+ return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to get the XVisualInfo for the child window.");
+ }
+ Visual* visual = visualInfo->visual;
+
+ if (!getWindowDimensions(mParent, &mParentWidth, &mParentHeight))
+ {
+ return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to get the parent window's dimensions.");
+ }
+
+ // The depth, colormap and visual must match otherwise we get a X error
+ // so we specify the colormap attribute. Also we do not want the window
+ // to be taken into account for input so we specify the event and
+ // do-not-propagate masks to 0 (the defaults). Finally we specify the
+ // border pixel attribute so that we can use a different visual depth
+ // than our parent (seems like X uses that as a condition to render
+ // the subwindow in a different buffer)
+ XSetWindowAttributes attributes;
+ unsigned long attributeMask = CWColormap | CWBorderPixel;
+
+ Colormap colormap = XCreateColormap(mDisplay, mParent, visual, AllocNone);
+ if(!colormap)
+ {
+ XFree(visualInfo);
+ return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to create the Colormap for the child window.");
+ }
+ attributes.colormap = colormap;
+ attributes.border_pixel = 0;
+
+ //TODO(cwallez) set up our own error handler to see if the call failed
+ mWindow = XCreateWindow(mDisplay, mParent, 0, 0, mParentWidth, mParentHeight,
+ 0, visualInfo->depth, InputOutput, visual, attributeMask, &attributes);
+ mGLXWindow = mGLX.createWindow(mFBConfig, mWindow, nullptr);
+
+ XMapWindow(mDisplay, mWindow);
+ XFlush(mDisplay);
+
+ XFree(visualInfo);
+ XFreeColormap(mDisplay, colormap);
+
+ mGLXDisplay->syncXCommands();
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error WindowSurfaceGLX::makeCurrent()
+{
+ if (mGLX.makeCurrent(mGLXWindow, mContext) != True)
+ {
+ return egl::Error(EGL_BAD_DISPLAY);
+ }
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error WindowSurfaceGLX::swap()
+{
+ // We need to swap before resizing as some drivers clobber the back buffer
+ // when the window is resized.
+ mGLXDisplay->setSwapInterval(mGLXWindow, &mSwapControl);
+ mGLX.swapBuffers(mGLXWindow);
+
+ egl::Error error = checkForResize();
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error WindowSurfaceGLX::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error WindowSurfaceGLX::querySurfacePointerANGLE(EGLint attribute, void **value)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error WindowSurfaceGLX::bindTexImage(gl::Texture *texture, EGLint buffer)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error WindowSurfaceGLX::releaseTexImage(EGLint buffer)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+void WindowSurfaceGLX::setSwapInterval(EGLint interval)
+{
+ mSwapControl.targetSwapInterval = interval;
+}
+
+EGLint WindowSurfaceGLX::getWidth() const
+{
+ // The size of the window is always the same as the cached size of its parent.
+ return mParentWidth;
+}
+
+EGLint WindowSurfaceGLX::getHeight() const
+{
+ // The size of the window is always the same as the cached size of its parent.
+ return mParentHeight;
+}
+
+EGLint WindowSurfaceGLX::isPostSubBufferSupported() const
+{
+ UNIMPLEMENTED();
+ return EGL_FALSE;
+}
+
+EGLint WindowSurfaceGLX::getSwapBehavior() const
+{
+ return EGL_BUFFER_PRESERVED;
+}
+
+egl::Error WindowSurfaceGLX::checkForResize()
+{
+ // TODO(cwallez) set up our own error handler to see if the call failed
+ unsigned int newParentWidth, newParentHeight;
+ if (!getWindowDimensions(mParent, &newParentWidth, &newParentHeight))
+ {
+ return egl::Error(EGL_BAD_CURRENT_SURFACE,
+ "Failed to retrieve the size of the parent window.");
+ }
+
+ if (mParentWidth != newParentWidth || mParentHeight != newParentHeight)
+ {
+ mParentWidth = newParentWidth;
+ mParentHeight = newParentHeight;
+
+ mGLX.waitGL();
+ XResizeWindow(mDisplay, mWindow, mParentWidth, mParentHeight);
+ mGLX.waitX();
+ XSync(mDisplay, False);
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+bool WindowSurfaceGLX::getWindowDimensions(Window window, unsigned int *width, unsigned int *height) const
+{
+ Window root;
+ int x, y;
+ unsigned int border, depth;
+ return XGetGeometry(mDisplay, window, &root, &x, &y, width, height, &border, &depth) != 0;
+}
+
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/glx/WindowSurfaceGLX.h b/gfx/angle/src/libANGLE/renderer/gl/glx/WindowSurfaceGLX.h
new file mode 100755
index 000000000..0cdda96e6
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/glx/WindowSurfaceGLX.h
@@ -0,0 +1,73 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// WindowSurfaceGLX.h: GLX implementation of egl::Surface for windows
+
+#ifndef LIBANGLE_RENDERER_GL_GLX_WINDOWSURFACEGLX_H_
+#define LIBANGLE_RENDERER_GL_GLX_WINDOWSURFACEGLX_H_
+
+#include "libANGLE/renderer/gl/glx/DisplayGLX.h"
+#include "libANGLE/renderer/gl/glx/platform_glx.h"
+#include "libANGLE/renderer/gl/glx/SurfaceGLX.h"
+
+namespace rx
+{
+
+class DisplayGLX;
+class FunctionsGLX;
+
+class WindowSurfaceGLX : public SurfaceGLX
+{
+ public:
+ WindowSurfaceGLX(const egl::SurfaceState &state,
+ const FunctionsGLX &glx,
+ DisplayGLX *glxDisplay,
+ RendererGL *renderer,
+ Window window,
+ Display *display,
+ glx::Context context,
+ glx::FBConfig fbConfig);
+ ~WindowSurfaceGLX() override;
+
+ egl::Error initialize() override;
+ egl::Error makeCurrent() override;
+
+ egl::Error swap() override;
+ egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override;
+ egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override;
+ egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) override;
+ egl::Error releaseTexImage(EGLint buffer) override;
+ void setSwapInterval(EGLint interval) override;
+
+ EGLint getWidth() const override;
+ EGLint getHeight() const override;
+
+ EGLint isPostSubBufferSupported() const override;
+ EGLint getSwapBehavior() const override;
+
+ egl::Error checkForResize() override;
+
+ private:
+ bool getWindowDimensions(Window window, unsigned int *width, unsigned int *height) const;
+
+ Window mParent;
+ unsigned int mParentWidth, mParentHeight;
+ Window mWindow;
+ Display *mDisplay;
+
+ const FunctionsGLX &mGLX;
+ DisplayGLX *mGLXDisplay;
+
+ glx::Context mContext;
+ glx::FBConfig mFBConfig;
+ glx::Window mGLXWindow;
+
+ SwapControlData mSwapControl;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_GLX_WINDOWSURFACEGLX_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/glx/functionsglx_typedefs.h b/gfx/angle/src/libANGLE/renderer/gl/glx/functionsglx_typedefs.h
new file mode 100755
index 000000000..b0ba033c7
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/glx/functionsglx_typedefs.h
@@ -0,0 +1,52 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// functionsglx_typedefs.h: Typedefs of GLX functions.
+
+#ifndef LIBANGLE_RENDERER_GL_GLX_FUNCTIONSGLXTYPEDEFS_H_
+#define LIBANGLE_RENDERER_GL_GLX_FUNCTIONSGLXTYPEDEFS_H_
+
+#include "libANGLE/renderer/gl/glx/platform_glx.h"
+
+namespace rx
+{
+
+// Only the functions of GLX 1.2 and earlier need to be typdefed; the other
+// functions are already typedefed in glx.h
+
+// GLX 1.0
+typedef XVisualInfo *(*PFNGLXCHOOSEVISUALPROC) (Display *dpy, int screen, int *attribList);
+typedef GLXContext (*PFNGLXCREATECONTEXTPROC) (Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct);
+typedef void (*PFNGLXDESTROYCONTEXTPROC) (Display *dpy, GLXContext ctx);
+typedef Bool (*PFNGLXMAKECURRENTPROC) (Display *dpy, GLXDrawable drawable, GLXContext ctx);
+typedef void (*PFNGLXCOPYCONTEXTPROC) (Display *dpy, GLXContext src, GLXContext dst, unsigned long mask);
+typedef void (*PFNGLXSWAPBUFFERSPROC) (Display *dpy, GLXDrawable drawable);
+typedef GLXPixmap (*PFNGLXCREATEGLXPIXMAPPROC) (Display *dpy, XVisualInfo *visual, Pixmap pixmap);
+typedef void (*PFNGLXDESTROYGLXPIXMAPPROC) (Display *dpy, GLXPixmap pixmap);
+typedef Bool (*PFNGLXQUERYEXTENSIONPROC) (Display *dpy, int *errorb, int *event);
+typedef Bool (*PFNGLXQUERYVERSIONPROC) (Display *dpy, int *maj, int *min);
+typedef Bool (*PFNGLXISDIRECTPROC) (Display *dpy, GLXContext ctx);
+typedef int (*PFNGLXGETCONFIGPROC) (Display *dpy, XVisualInfo *visual, int attrib, int *value);
+typedef GLXContext (*PFNGLXGETCURRENTCONTEXTPROC) ();
+typedef GLXDrawable (*PFNGLXGETCURRENTDRAWABLEPROC) ();
+typedef GLXContext (*PFNGLXGETCURRENTCONTEXTPROC) ();
+typedef GLXDrawable (*PFNGLXGETCURRENTDRAWABLEPROC) ();
+typedef void (*PFNGLXWAITGLPROC) ();
+typedef void (*PFNGLXWAITXPROC) ();
+typedef void (*PFNGLXUSEXFONT) (Font font, int first, int count, int list);
+
+// GLX 1.1
+typedef const char *(*PFNGLXQUERYEXTENSIONSSTRINGPROC) (Display *dpy, int screen);
+typedef const char *(*PFNGLXQUERYSERVERSTRINGPROC) (Display *dpy, int screen, int name);
+typedef const char *(*PFNGLXGETCLIENTSTRINGPROC) (Display *dpy, int name);
+
+
+// GLX 1.2
+typedef Display *(*PFNGLXGETCURRENTDISPLAYPROC) ();
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_GLX_FUNCTIONSGLXTYPEDEFS_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/glx/platform_glx.h b/gfx/angle/src/libANGLE/renderer/gl/glx/platform_glx.h
new file mode 100755
index 000000000..3ffb609d5
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/glx/platform_glx.h
@@ -0,0 +1,190 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// platform_glx.h: Includes specific to GLX.
+
+#ifndef LIBANGLE_RENDERER_GL_GLX_PLATFORMGLX_H_
+#define LIBANGLE_RENDERER_GL_GLX_PLATFORMGLX_H_
+
+#if !defined(ANGLE_SKIP_GLX_DEFINES)
+// GLX 1.0
+#define GLX_USE_GL 1
+#define GLX_BUFFER_SIZE 2
+#define GLX_LEVEL 3
+#define GLX_RGBA 4
+#define GLX_DOUBLEBUFFER 5
+#define GLX_STEREO 6
+#define GLX_AUX_BUFFERS 7
+#define GLX_RED_SIZE 8
+#define GLX_GREEN_SIZE 9
+#define GLX_BLUE_SIZE 10
+#define GLX_ALPHA_SIZE 11
+#define GLX_DEPTH_SIZE 12
+#define GLX_STENCIL_SIZE 13
+#define GLX_ACCUM_RED_SIZE 14
+#define GLX_ACCUM_GREEN_SIZE 15
+#define GLX_ACCUM_BLUE_SIZE 16
+#define GLX_ACCUM_ALPHA_SIZE 17
+
+#define GLX_BAD_SCREEN 1
+#define GLX_BAD_ATTRIBUTE 2
+#define GLX_NO_EXTENSION 3
+#define GLX_BAD_VISUAL 4
+#define GLX_BAD_CONTEXT 5
+#define GLX_BAD_VALUE 6
+#define GLX_BAD_ENUM 7
+
+// GLX 1.1
+#define GLX_VENDOR 1
+#define GLX_VERSION 2
+#define GLX_EXTENSIONS 3
+
+// GLX 1.3
+#define GLX_CONFIG_CAVEAT 0x20
+#define GLX_DONT_CARE 0xFFFFFFFF
+#define GLX_X_VISUAL_TYPE 0x22
+#define GLX_TRANSPARENT_TYPE 0x23
+#define GLX_TRANSPARENT_INDEX_VALUE 0x24
+#define GLX_TRANSPARENT_RED_VALUE 0x25
+#define GLX_TRANSPARENT_GREEN_VALUE 0x26
+#define GLX_TRANSPARENT_BLUE_VALUE 0x27
+#define GLX_TRANSPARENT_ALPHA_VALUE 0x28
+#define GLX_WINDOW_BIT 0x00000001
+#define GLX_PIXMAP_BIT 0x00000002
+#define GLX_PBUFFER_BIT 0x00000004
+#define GLX_AUX_BUFFERS_BIT 0x00000010
+#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001
+#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002
+#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004
+#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008
+#define GLX_DEPTH_BUFFER_BIT 0x00000020
+#define GLX_STENCIL_BUFFER_BIT 0x00000040
+#define GLX_ACCUM_BUFFER_BIT 0x00000080
+#define GLX_NONE 0x8000
+#define GLX_SLOW_CONFIG 0x8001
+#define GLX_TRUE_COLOR 0x8002
+#define GLX_DIRECT_COLOR 0x8003
+#define GLX_PSEUDO_COLOR 0x8004
+#define GLX_STATIC_COLOR 0x8005
+#define GLX_GRAY_SCALE 0x8006
+#define GLX_STATIC_GRAY 0x8007
+#define GLX_TRANSPARENT_RGB 0x8008
+#define GLX_TRANSPARENT_INDEX 0x8009
+#define GLX_VISUAL_ID 0x800B
+#define GLX_SCREEN 0x800C
+#define GLX_NON_CONFORMANT_CONFIG 0x800D
+#define GLX_DRAWABLE_TYPE 0x8010
+#define GLX_RENDER_TYPE 0x8011
+#define GLX_X_RENDERABLE 0x8012
+#define GLX_FBCONFIG_ID 0x8013
+#define GLX_RGBA_TYPE 0x8014
+#define GLX_COLOR_INDEX_TYPE 0x8015
+#define GLX_MAX_PBUFFER_WIDTH 0x8016
+#define GLX_MAX_PBUFFER_HEIGHT 0x8017
+#define GLX_MAX_PBUFFER_PIXELS 0x8018
+#define GLX_PRESERVED_CONTENTS 0x801B
+#define GLX_LARGEST_PBUFFER 0x801C
+#define GLX_WIDTH 0x801D
+#define GLX_HEIGHT 0x801E
+#define GLX_EVENT_MASK 0x801F
+#define GLX_DAMAGED 0x8020
+#define GLX_SAVED 0x8021
+#define GLX_WINDOW 0x8022
+#define GLX_PBUFFER 0x8023
+#define GLX_PBUFFER_HEIGHT 0x8040
+#define GLX_PBUFFER_WIDTH 0x8041
+#define GLX_RGBA_BIT 0x00000001
+#define GLX_COLOR_INDEX_BIT 0x00000002
+#define GLX_PBUFFER_CLOBBER_MASK 0x08000000
+
+// GLX 1.4
+#define GLX_SAMPLE_BUFFERS 0x186a0
+#define GLX_SAMPLES 0x186a1
+
+// GLX_ARB_create_context
+#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001
+#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
+#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
+#define GLX_CONTEXT_FLAGS_ARB 0x2094
+
+// GLX_ARB_create_context_profile
+#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
+
+// GLX_ARB_create_context_robustness
+#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
+#define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252
+#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define GLX_NO_RESET_NOTIFICATION_ARB 0x8261
+
+// GLX_EXT_create_context_es2_profile
+#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
+
+// GLX_EXT_texture_from_pixmap
+#define GLX_TEXTURE_1D_BIT_EXT 0x00000001
+#define GLX_TEXTURE_2D_BIT_EXT 0x00000002
+#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004
+#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0
+#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1
+#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2
+#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3
+#define GLX_Y_INVERTED_EXT 0x20D4
+#define GLX_TEXTURE_FORMAT_EXT 0x20D5
+#define GLX_TEXTURE_TARGET_EXT 0x20D6
+#define GLX_MIPMAP_TEXTURE_EXT 0x20D7
+#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8
+#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9
+#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA
+#define GLX_TEXTURE_1D_EXT 0x20DB
+#define GLX_TEXTURE_2D_EXT 0x20DC
+#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD
+#define GLX_FRONT_LEFT_EXT 0x20DE
+#define GLX_FRONT_RIGHT_EXT 0x20DF
+#define GLX_BACK_LEFT_EXT 0x20E0
+#define GLX_BACK_RIGHT_EXT 0x20E1
+#define GLX_FRONT_EXT 0x20DE
+#define GLX_BACK_EXT 0x20E0
+#define GLX_AUX0_EXT 0x20E2
+#define GLX_AUX1_EXT 0x20E3
+#define GLX_AUX2_EXT 0x20E4
+#define GLX_AUX3_EXT 0x20E5
+#define GLX_AUX4_EXT 0x20E6
+#define GLX_AUX5_EXT 0x20E7
+#define GLX_AUX6_EXT 0x20E8
+#define GLX_AUX7_EXT 0x20E9
+#define GLX_AUX8_EXT 0x20EA
+#define GLX_AUX9_EXT 0x20EB
+
+// GLX_EXT_swap_control
+#define GLX_SWAP_INTERVAL_EXT 0x20F1
+#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2
+#endif // !defined(ANGLE_SKIP_GLX_DEFINES)
+
+// GLX typedefs depend on the X headers
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+#include <X11/Xutil.h>
+
+// GLX typedefs
+namespace glx
+{
+
+typedef void *Context;
+typedef void *FBConfig;
+typedef XID FBConfigID;
+typedef XID ContextID;
+typedef XID Window;
+typedef XID Pbuffer;
+typedef XID Pixmap;
+typedef XID Drawable;
+
+}
+
+typedef void* (*PFNGETPROCPROC) (const char *name);
+
+#endif // LIBANGLE_RENDERER_GL_GLX_PLATFORMGLX_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/renderergl_utils.cpp b/gfx/angle/src/libANGLE/renderer/gl/renderergl_utils.cpp
new file mode 100755
index 000000000..504a787f8
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/renderergl_utils.cpp
@@ -0,0 +1,1045 @@
+//
+// Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// renderergl_utils.cpp: Conversion functions and other utility routines
+// specific to the OpenGL renderer.
+
+#include "libANGLE/renderer/gl/renderergl_utils.h"
+
+#include <limits>
+
+#include "common/mathutil.h"
+#include "libANGLE/Buffer.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+#include "libANGLE/renderer/gl/WorkaroundsGL.h"
+#include "libANGLE/renderer/gl/formatutilsgl.h"
+
+#include <algorithm>
+#include <sstream>
+
+using angle::CheckedNumeric;
+
+namespace rx
+{
+VendorID GetVendorID(const FunctionsGL *functions)
+{
+ std::string nativeVendorString(reinterpret_cast<const char *>(functions->getString(GL_VENDOR)));
+ if (nativeVendorString.find("Intel") != std::string::npos)
+ {
+ return VENDOR_ID_INTEL;
+ }
+ else if (nativeVendorString.find("NVIDIA") != std::string::npos)
+ {
+ return VENDOR_ID_NVIDIA;
+ }
+ else if (nativeVendorString.find("ATI") != std::string::npos ||
+ nativeVendorString.find("AMD") != std::string::npos)
+ {
+ return VENDOR_ID_AMD;
+ }
+ else if (nativeVendorString.find("Qualcomm") != std::string::npos)
+ {
+ return VENDOR_ID_QUALCOMM;
+ }
+ else
+ {
+ return VENDOR_ID_UNKNOWN;
+ }
+}
+
+namespace nativegl_gl
+{
+
+static bool MeetsRequirements(const FunctionsGL *functions, const nativegl::SupportRequirement &requirements)
+{
+ for (const std::string &extension : requirements.requiredExtensions)
+ {
+ if (!functions->hasExtension(extension))
+ {
+ return false;
+ }
+ }
+
+ if (functions->version >= requirements.version)
+ {
+ return true;
+ }
+ else if (!requirements.versionExtensions.empty())
+ {
+ for (const std::string &extension : requirements.versionExtensions)
+ {
+ if (!functions->hasExtension(extension))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+static gl::TextureCaps GenerateTextureFormatCaps(const FunctionsGL *functions, GLenum internalFormat)
+{
+ gl::TextureCaps textureCaps;
+
+ const nativegl::InternalFormat &formatInfo = nativegl::GetInternalFormatInfo(internalFormat, functions->standard);
+ textureCaps.texturable = MeetsRequirements(functions, formatInfo.texture);
+ textureCaps.filterable = textureCaps.texturable && MeetsRequirements(functions, formatInfo.filter);
+ textureCaps.renderable = MeetsRequirements(functions, formatInfo.framebufferAttachment);
+
+ // glGetInternalformativ is not available until version 4.2 but may be available through the 3.0
+ // extension GL_ARB_internalformat_query
+ if (textureCaps.renderable && functions->getInternalformativ)
+ {
+ GLint numSamples = 0;
+ functions->getInternalformativ(GL_RENDERBUFFER, internalFormat, GL_NUM_SAMPLE_COUNTS, 1, &numSamples);
+
+ if (numSamples > 0)
+ {
+ std::vector<GLint> samples(numSamples);
+ functions->getInternalformativ(GL_RENDERBUFFER, internalFormat, GL_SAMPLES,
+ static_cast<GLsizei>(samples.size()), &samples[0]);
+ for (size_t sampleIndex = 0; sampleIndex < samples.size(); sampleIndex++)
+ {
+ textureCaps.sampleCounts.insert(samples[sampleIndex]);
+ }
+ }
+ }
+
+ return textureCaps;
+}
+
+static GLint QuerySingleGLInt(const FunctionsGL *functions, GLenum name)
+{
+ GLint result = 0;
+ functions->getIntegerv(name, &result);
+ return result;
+}
+
+static GLint QuerySingleIndexGLInt(const FunctionsGL *functions, GLenum name, GLuint index)
+{
+ GLint result;
+ functions->getIntegeri_v(name, index, &result);
+ return result;
+}
+
+static GLint QueryGLIntRange(const FunctionsGL *functions, GLenum name, size_t index)
+{
+ GLint result[2] = {};
+ functions->getIntegerv(name, result);
+ return result[index];
+}
+
+static GLint64 QuerySingleGLInt64(const FunctionsGL *functions, GLenum name)
+{
+ GLint64 result = 0;
+ functions->getInteger64v(name, &result);
+ return result;
+}
+
+static GLfloat QuerySingleGLFloat(const FunctionsGL *functions, GLenum name)
+{
+ GLfloat result = 0.0f;
+ functions->getFloatv(name, &result);
+ return result;
+}
+
+static GLfloat QueryGLFloatRange(const FunctionsGL *functions, GLenum name, size_t index)
+{
+ GLfloat result[2] = {};
+ functions->getFloatv(name, result);
+ return result[index];
+}
+
+static gl::TypePrecision QueryTypePrecision(const FunctionsGL *functions, GLenum shaderType, GLenum precisionType)
+{
+ gl::TypePrecision precision;
+ functions->getShaderPrecisionFormat(shaderType, precisionType, precision.range, &precision.precision);
+ return precision;
+}
+
+static GLint QueryQueryValue(const FunctionsGL *functions, GLenum target, GLenum name)
+{
+ GLint result;
+ functions->getQueryiv(target, name, &result);
+ return result;
+}
+
+static void LimitVersion(gl::Version *curVersion, const gl::Version &maxVersion)
+{
+ if (*curVersion >= maxVersion)
+ {
+ *curVersion = maxVersion;
+ }
+}
+
+void GenerateCaps(const FunctionsGL *functions, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap,
+ gl::Extensions *extensions, gl::Version *maxSupportedESVersion)
+{
+ // Texture format support checks
+ const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
+ for (GLenum internalFormat : allFormats)
+ {
+ gl::TextureCaps textureCaps = GenerateTextureFormatCaps(functions, internalFormat);
+ textureCapsMap->insert(internalFormat, textureCaps);
+
+ if (gl::GetInternalFormatInfo(internalFormat).compressed)
+ {
+ caps->compressedTextureFormats.push_back(internalFormat);
+ }
+ }
+
+ // Start by assuming ES3.1 support and work down
+ *maxSupportedESVersion = gl::Version(3, 1);
+
+ // Table 6.28, implementation dependent values
+ if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->hasGLExtension("GL_ARB_ES3_compatibility") ||
+ functions->isAtLeastGLES(gl::Version(3, 0)))
+ {
+ caps->maxElementIndex = QuerySingleGLInt64(functions, GL_MAX_ELEMENT_INDEX);
+ }
+ else
+ {
+ // Doesn't affect ES3 support, can use a pre-defined limit
+ caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());
+ }
+
+ if (functions->isAtLeastGL(gl::Version(1, 2)) ||
+ functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_OES_texture_3D"))
+ {
+ caps->max3DTextureSize = QuerySingleGLInt(functions, GL_MAX_3D_TEXTURE_SIZE);
+ }
+ else
+ {
+ // Can't support ES3 without 3D textures
+ LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
+ }
+
+ caps->max2DTextureSize = QuerySingleGLInt(functions, GL_MAX_TEXTURE_SIZE); // GL 1.0 / ES 2.0
+ caps->maxCubeMapTextureSize = QuerySingleGLInt(functions, GL_MAX_CUBE_MAP_TEXTURE_SIZE); // GL 1.3 / ES 2.0
+
+ if (functions->isAtLeastGL(gl::Version(3, 0)) || functions->hasGLExtension("GL_EXT_texture_array") ||
+ functions->isAtLeastGLES(gl::Version(3, 0)))
+ {
+ caps->maxArrayTextureLayers = QuerySingleGLInt(functions, GL_MAX_ARRAY_TEXTURE_LAYERS);
+ }
+ else
+ {
+ // Can't support ES3 without array textures
+ LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
+ }
+
+ if (functions->isAtLeastGL(gl::Version(1, 5)) || functions->hasGLExtension("GL_EXT_texture_lod_bias") ||
+ functions->isAtLeastGLES(gl::Version(3, 0)))
+ {
+ caps->maxLODBias = QuerySingleGLFloat(functions, GL_MAX_TEXTURE_LOD_BIAS);
+ }
+ else
+ {
+ LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
+ }
+
+ if (functions->isAtLeastGL(gl::Version(3, 0)) || functions->hasGLExtension("GL_EXT_framebuffer_object") ||
+ functions->isAtLeastGLES(gl::Version(2, 0)))
+ {
+ caps->maxRenderbufferSize = QuerySingleGLInt(functions, GL_MAX_RENDERBUFFER_SIZE);
+ caps->maxColorAttachments = QuerySingleGLInt(functions, GL_MAX_COLOR_ATTACHMENTS);
+ }
+ else
+ {
+ // Can't support ES2 without framebuffers and renderbuffers
+ LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
+ }
+
+ if (functions->isAtLeastGL(gl::Version(2, 0)) || functions->hasGLExtension("ARB_draw_buffers") ||
+ functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_EXT_draw_buffers"))
+ {
+ caps->maxDrawBuffers = QuerySingleGLInt(functions, GL_MAX_DRAW_BUFFERS);
+ }
+ else
+ {
+ // Framebuffer is required to have at least one drawbuffer even if the extension is not
+ // supported
+ caps->maxDrawBuffers = 1;
+ LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
+ }
+
+ caps->maxViewportWidth = QueryGLIntRange(functions, GL_MAX_VIEWPORT_DIMS, 0); // GL 1.0 / ES 2.0
+ caps->maxViewportHeight = QueryGLIntRange(functions, GL_MAX_VIEWPORT_DIMS, 1); // GL 1.0 / ES 2.0
+
+ if (functions->standard == STANDARD_GL_DESKTOP &&
+ (functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0)
+ {
+ // Desktop GL core profile deprecated the GL_ALIASED_POINT_SIZE_RANGE query. Use
+ // GL_POINT_SIZE_RANGE instead.
+ caps->minAliasedPointSize = QueryGLFloatRange(functions, GL_POINT_SIZE_RANGE, 0);
+ caps->maxAliasedPointSize = QueryGLFloatRange(functions, GL_POINT_SIZE_RANGE, 1);
+ }
+ else
+ {
+ caps->minAliasedPointSize = QueryGLFloatRange(functions, GL_ALIASED_POINT_SIZE_RANGE, 0);
+ caps->maxAliasedPointSize = QueryGLFloatRange(functions, GL_ALIASED_POINT_SIZE_RANGE, 1);
+ }
+
+ caps->minAliasedLineWidth = QueryGLFloatRange(functions, GL_ALIASED_LINE_WIDTH_RANGE, 0); // GL 1.2 / ES 2.0
+ caps->maxAliasedLineWidth = QueryGLFloatRange(functions, GL_ALIASED_LINE_WIDTH_RANGE, 1); // GL 1.2 / ES 2.0
+
+ // Table 6.29, implementation dependent values (cont.)
+ if (functions->isAtLeastGL(gl::Version(1, 2)) ||
+ functions->isAtLeastGLES(gl::Version(3, 0)))
+ {
+ caps->maxElementsIndices = QuerySingleGLInt(functions, GL_MAX_ELEMENTS_INDICES);
+ caps->maxElementsVertices = QuerySingleGLInt(functions, GL_MAX_ELEMENTS_VERTICES);
+ }
+ else
+ {
+ // Doesn't impact supported version
+ }
+
+ if (functions->isAtLeastGL(gl::Version(4, 1)) ||
+ functions->hasGLExtension("GL_ARB_get_program_binary") ||
+ functions->isAtLeastGLES(gl::Version(3, 0)) ||
+ functions->hasGLExtension("GL_OES_get_program_binary"))
+ {
+ // Able to support the GL_PROGRAM_BINARY_ANGLE format as long as another program binary
+ // format is available.
+ GLint numBinaryFormats = QuerySingleGLInt(functions, GL_NUM_PROGRAM_BINARY_FORMATS_OES);
+ if (numBinaryFormats > 0)
+ {
+ caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE);
+ }
+ }
+ else
+ {
+ // Doesn't impact supported version
+ }
+
+ // glGetShaderPrecisionFormat is not available until desktop GL version 4.1 or GL_ARB_ES2_compatibility exists
+ if (functions->isAtLeastGL(gl::Version(4, 1)) || functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
+ functions->isAtLeastGLES(gl::Version(2, 0)))
+ {
+ caps->vertexHighpFloat = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_HIGH_FLOAT);
+ caps->vertexMediumpFloat = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_MEDIUM_FLOAT);
+ caps->vertexLowpFloat = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_LOW_FLOAT);
+ caps->fragmentHighpFloat = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_HIGH_FLOAT);
+ caps->fragmentMediumpFloat = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT);
+ caps->fragmentLowpFloat = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_LOW_FLOAT);
+ caps->vertexHighpInt = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_HIGH_INT);
+ caps->vertexMediumpInt = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_MEDIUM_INT);
+ caps->vertexLowpInt = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_LOW_INT);
+ caps->fragmentHighpInt = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_HIGH_INT);
+ caps->fragmentMediumpInt = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_MEDIUM_INT);
+ caps->fragmentLowpInt = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_LOW_INT);
+ }
+ else
+ {
+ // Doesn't impact supported version, set some default values
+ caps->vertexHighpFloat.setIEEEFloat();
+ caps->vertexMediumpFloat.setIEEEFloat();
+ caps->vertexLowpFloat.setIEEEFloat();
+ caps->fragmentHighpFloat.setIEEEFloat();
+ caps->fragmentMediumpFloat.setIEEEFloat();
+ caps->fragmentLowpFloat.setIEEEFloat();
+ caps->vertexHighpInt.setTwosComplementInt(32);
+ caps->vertexMediumpInt.setTwosComplementInt(32);
+ caps->vertexLowpInt.setTwosComplementInt(32);
+ caps->fragmentHighpInt.setTwosComplementInt(32);
+ caps->fragmentMediumpInt.setTwosComplementInt(32);
+ caps->fragmentLowpInt.setTwosComplementInt(32);
+ }
+
+ if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->hasGLExtension("GL_ARB_sync") ||
+ functions->isAtLeastGLES(gl::Version(3, 0)))
+ {
+ caps->maxServerWaitTimeout = QuerySingleGLInt64(functions, GL_MAX_SERVER_WAIT_TIMEOUT);
+ }
+ else
+ {
+ LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
+ }
+
+ // Table 6.31, implementation dependent vertex shader limits
+ if (functions->isAtLeastGL(gl::Version(2, 0)) ||
+ functions->isAtLeastGLES(gl::Version(2, 0)))
+ {
+ caps->maxVertexAttributes = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIBS);
+ caps->maxVertexUniformComponents = QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_COMPONENTS);
+ caps->maxVertexTextureImageUnits = QuerySingleGLInt(functions, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
+ }
+ else
+ {
+ // Can't support ES2 version without these caps
+ LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
+ }
+
+ if (functions->isAtLeastGL(gl::Version(4, 1)) || functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
+ functions->isAtLeastGLES(gl::Version(2, 0)))
+ {
+ caps->maxVertexUniformVectors = QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_VECTORS);
+ }
+ else
+ {
+ // Doesn't limit ES version, GL_MAX_VERTEX_UNIFORM_COMPONENTS / 4 is acceptable.
+ caps->maxVertexUniformVectors = caps->maxVertexUniformComponents / 4;
+ }
+
+ if (functions->isAtLeastGL(gl::Version(3, 1)) || functions->hasGLExtension("GL_ARB_uniform_buffer_object") ||
+ functions->isAtLeastGLES(gl::Version(3, 0)))
+ {
+ caps->maxVertexUniformBlocks = QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_BLOCKS);
+ }
+ else
+ {
+ // Can't support ES3 without uniform blocks
+ LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
+ }
+
+ if (functions->isAtLeastGL(gl::Version(3, 2)) ||
+ functions->isAtLeastGLES(gl::Version(3, 0)))
+ {
+ caps->maxVertexOutputComponents = QuerySingleGLInt(functions, GL_MAX_VERTEX_OUTPUT_COMPONENTS);
+ }
+ else
+ {
+ // There doesn't seem, to be a desktop extension to add this cap, maybe it could be given a safe limit
+ // instead of limiting the supported ES version.
+ LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
+ }
+
+ // Table 6.32, implementation dependent fragment shader limits
+ if (functions->isAtLeastGL(gl::Version(2, 0)) ||
+ functions->isAtLeastGLES(gl::Version(2, 0)))
+ {
+ caps->maxFragmentUniformComponents = QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS);
+ caps->maxTextureImageUnits = QuerySingleGLInt(functions, GL_MAX_TEXTURE_IMAGE_UNITS);
+ }
+ else
+ {
+ // Can't support ES2 version without these caps
+ LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
+ }
+
+ if (functions->isAtLeastGL(gl::Version(4, 1)) || functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
+ functions->isAtLeastGLES(gl::Version(2, 0)))
+ {
+ caps->maxFragmentUniformVectors = QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_VECTORS);
+ }
+ else
+ {
+ // Doesn't limit ES version, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS / 4 is acceptable.
+ caps->maxFragmentUniformVectors = caps->maxFragmentUniformComponents / 4;
+ }
+
+ if (functions->isAtLeastGL(gl::Version(3, 1)) || functions->hasGLExtension("GL_ARB_uniform_buffer_object") ||
+ functions->isAtLeastGLES(gl::Version(3, 0)))
+ {
+ caps->maxFragmentUniformBlocks = QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_BLOCKS);
+ }
+ else
+ {
+ // Can't support ES3 without uniform blocks
+ LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
+ }
+
+ if (functions->isAtLeastGL(gl::Version(3, 2)) ||
+ functions->isAtLeastGLES(gl::Version(3, 0)))
+ {
+ caps->maxFragmentInputComponents = QuerySingleGLInt(functions, GL_MAX_FRAGMENT_INPUT_COMPONENTS);
+ }
+ else
+ {
+ // There doesn't seem, to be a desktop extension to add this cap, maybe it could be given a safe limit
+ // instead of limiting the supported ES version.
+ LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
+ }
+
+ if (functions->isAtLeastGL(gl::Version(3, 0)) ||
+ functions->isAtLeastGLES(gl::Version(3, 0)))
+ {
+ caps->minProgramTexelOffset = QuerySingleGLInt(functions, GL_MIN_PROGRAM_TEXEL_OFFSET);
+ caps->maxProgramTexelOffset = QuerySingleGLInt(functions, GL_MAX_PROGRAM_TEXEL_OFFSET);
+ }
+ else
+ {
+ // Can't support ES3 without texel offset, could possibly be emulated in the shader
+ LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
+ }
+
+ // Table 6.33, implementation dependent aggregate shader limits
+ if (functions->isAtLeastGL(gl::Version(3, 1)) || functions->hasGLExtension("GL_ARB_uniform_buffer_object") ||
+ functions->isAtLeastGLES(gl::Version(3, 0)))
+ {
+ caps->maxUniformBufferBindings = QuerySingleGLInt(functions, GL_MAX_UNIFORM_BUFFER_BINDINGS);
+ caps->maxUniformBlockSize = QuerySingleGLInt64(functions, GL_MAX_UNIFORM_BLOCK_SIZE);
+ caps->uniformBufferOffsetAlignment = QuerySingleGLInt(functions, GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT);
+ caps->maxCombinedUniformBlocks = caps->maxVertexUniformBlocks + caps->maxFragmentInputComponents;
+ caps->maxCombinedVertexUniformComponents = QuerySingleGLInt64(functions, GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS);
+ caps->maxCombinedFragmentUniformComponents = QuerySingleGLInt64(functions, GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS);
+ }
+ else
+ {
+ // Can't support ES3 without uniform blocks
+ LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
+ }
+
+ if (functions->isAtLeastGL(gl::Version(3, 0)) ||
+ functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
+ functions->isAtLeastGLES(gl::Version(2, 0)))
+ {
+ caps->maxVaryingComponents = QuerySingleGLInt(functions, GL_MAX_VARYING_COMPONENTS);
+ }
+ else if (functions->isAtLeastGL(gl::Version(2, 0)))
+ {
+ caps->maxVaryingComponents = QuerySingleGLInt(functions, GL_MAX_VARYING_FLOATS);
+ LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
+ }
+ else
+ {
+ LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
+ }
+
+ if (functions->isAtLeastGL(gl::Version(4, 1)) || functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
+ functions->isAtLeastGLES(gl::Version(2, 0)))
+ {
+ caps->maxVaryingVectors = QuerySingleGLInt(functions, GL_MAX_VARYING_VECTORS);
+ }
+ else
+ {
+ // Doesn't limit ES version, GL_MAX_VARYING_COMPONENTS / 4 is acceptable.
+ caps->maxVaryingVectors = caps->maxVaryingComponents / 4;
+ }
+
+ // Determine the max combined texture image units by adding the vertex and fragment limits. If
+ // the real cap is queried, it would contain the limits for shader types that are not available to ES.
+ caps->maxCombinedTextureImageUnits = caps->maxVertexTextureImageUnits + caps->maxTextureImageUnits;
+
+ // Table 6.34, implementation dependent transform feedback limits
+ if (functions->isAtLeastGL(gl::Version(4, 0)) ||
+ functions->hasGLExtension("GL_ARB_transform_feedback2") ||
+ functions->isAtLeastGLES(gl::Version(3, 0)))
+ {
+ caps->maxTransformFeedbackInterleavedComponents = QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
+ caps->maxTransformFeedbackSeparateAttributes = QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS);
+ caps->maxTransformFeedbackSeparateComponents = QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS);
+ }
+ else
+ {
+ // Can't support ES3 without transform feedback
+ LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
+ }
+
+ // Table 6.35, Framebuffer Dependent Values
+ if (functions->isAtLeastGL(gl::Version(3, 0)) || functions->hasGLExtension("GL_EXT_framebuffer_multisample") ||
+ functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_EXT_multisampled_render_to_texture"))
+ {
+ caps->maxSamples = QuerySingleGLInt(functions, GL_MAX_SAMPLES);
+ }
+ else
+ {
+ LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
+ }
+
+ // Check if index constant sampler array indexing is supported
+ if (!functions->isAtLeastGL(gl::Version(4, 0)) &&
+ !functions->isAtLeastGLES(gl::Version(2, 0)) &&
+ !functions->hasExtension("GL_ARB_gpu_shader5"))
+ {
+ // This should also be required for ES2 but there are some driver support index constant
+ // sampler array indexing without meeting the requirements above. Don't limit their ES
+ // version as it would break WebGL for some users.
+ LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
+ }
+
+ // Check if sampler objects are supported
+ if (!functions->isAtLeastGL(gl::Version(3, 3)) &&
+ !functions->hasGLExtension("GL_ARB_sampler_objects") &&
+ !functions->isAtLeastGLES(gl::Version(3, 0)))
+ {
+ // Can't support ES3 without sampler objects
+ LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
+ }
+
+ // Can't support ES3 without texture swizzling
+ if (!functions->isAtLeastGL(gl::Version(3, 3)) &&
+ !functions->hasGLExtension("GL_ARB_texture_swizzle") &&
+ !functions->hasGLExtension("GL_EXT_texture_swizzle") &&
+ !functions->isAtLeastGLES(gl::Version(3, 0)))
+ {
+ LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
+
+ // Texture swizzling is required to work around the luminance texture format not being
+ // present in the core profile
+ if (functions->profile & GL_CONTEXT_CORE_PROFILE_BIT)
+ {
+ LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
+ }
+ }
+
+ // Can't support ES3 without the GLSL packing builtins. We have a workaround for all
+ // desktop OpenGL versions starting from 3.3 with the bit packing extension.
+ if (!functions->isAtLeastGL(gl::Version(4, 2)) &&
+ !(functions->isAtLeastGL(gl::Version(3, 2)) &&
+ functions->hasGLExtension("GL_ARB_shader_bit_encoding")) &&
+ !functions->hasGLExtension("GL_ARB_shading_language_packing") &&
+ !functions->isAtLeastGLES(gl::Version(3, 0)))
+ {
+ LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
+ }
+
+ // ES3 needs to support explicit layout location qualifiers, while it might be possible to
+ // fake them in our side, we currently don't support that.
+ if (!functions->isAtLeastGL(gl::Version(3, 3)) &&
+ !functions->hasGLExtension("GL_ARB_explicit_attrib_location") &&
+ !functions->isAtLeastGLES(gl::Version(3, 0)))
+ {
+ LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
+ }
+
+ if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
+ functions->hasGLExtension("GL_ARB_texture_multisample"))
+ {
+ caps->maxFramebufferWidth = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_WIDTH);
+ caps->maxFramebufferHeight = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_HEIGHT);
+ caps->maxFramebufferSamples = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_SAMPLES);
+ }
+ else
+ {
+ LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
+ }
+
+ if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
+ functions->hasGLExtension("GL_ARB_texture_multisample"))
+ {
+ caps->maxSampleMaskWords = QuerySingleGLInt(functions, GL_MAX_SAMPLE_MASK_WORDS);
+ caps->maxColorTextureSamples = QuerySingleGLInt(functions, GL_MAX_COLOR_TEXTURE_SAMPLES);
+ caps->maxDepthTextureSamples = QuerySingleGLInt(functions, GL_MAX_DEPTH_TEXTURE_SAMPLES);
+ caps->maxIntegerSamples = QuerySingleGLInt(functions, GL_MAX_INTEGER_SAMPLES);
+ }
+ else
+ {
+ LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
+ }
+
+ if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
+ functions->hasGLExtension("GL_ARB_vertex_attrib_binding"))
+ {
+ caps->maxVertexAttribRelativeOffset =
+ QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET);
+ caps->maxVertexAttribBindings = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIB_BINDINGS);
+ caps->maxVertexAttribStride = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIB_STRIDE);
+ }
+ else
+ {
+ LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
+ }
+
+ if (functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
+ functions->hasGLExtension("GL_ARB_shader_storage_buffer_object"))
+ {
+ caps->maxCombinedShaderOutputResources =
+ QuerySingleGLInt(functions, GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES);
+ caps->maxFragmentShaderStorageBlocks =
+ QuerySingleGLInt(functions, GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS);
+ caps->maxVertexShaderStorageBlocks =
+ QuerySingleGLInt(functions, GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS);
+ caps->maxShaderStorageBufferBindings =
+ QuerySingleGLInt(functions, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
+ caps->maxShaderStorageBlockSize =
+ QuerySingleGLInt64(functions, GL_MAX_SHADER_STORAGE_BLOCK_SIZE);
+ caps->maxCombinedShaderStorageBlocks =
+ QuerySingleGLInt(functions, GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS);
+ caps->shaderStorageBufferOffsetAlignment =
+ QuerySingleGLInt(functions, GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT);
+ }
+ else
+ {
+ LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
+ }
+
+ if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
+ functions->hasGLExtension("GL_ARB_compute_shader"))
+ {
+ for (GLuint index = 0u; index < 3u; ++index)
+ {
+ caps->maxComputeWorkGroupCount[index] =
+ QuerySingleIndexGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_COUNT, index);
+
+ caps->maxComputeWorkGroupSize[index] =
+ QuerySingleIndexGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_SIZE, index);
+ }
+ caps->maxComputeWorkGroupInvocations =
+ QuerySingleGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS);
+ caps->maxComputeUniformBlocks = QuerySingleGLInt(functions, GL_MAX_COMPUTE_UNIFORM_BLOCKS);
+ caps->maxComputeTextureImageUnits =
+ QuerySingleGLInt(functions, GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS);
+ caps->maxComputeSharedMemorySize =
+ QuerySingleGLInt(functions, GL_MAX_COMPUTE_SHARED_MEMORY_SIZE);
+ caps->maxComputeUniformComponents =
+ QuerySingleGLInt(functions, GL_MAX_COMPUTE_UNIFORM_COMPONENTS);
+ caps->maxComputeAtomicCounterBuffers =
+ QuerySingleGLInt(functions, GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS);
+ caps->maxComputeAtomicCounters =
+ QuerySingleGLInt(functions, GL_MAX_COMPUTE_ATOMIC_COUNTERS);
+ caps->maxComputeImageUniforms = QuerySingleGLInt(functions, GL_MAX_COMPUTE_IMAGE_UNIFORMS);
+ caps->maxCombinedComputeUniformComponents =
+ QuerySingleGLInt(functions, GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS);
+ caps->maxComputeShaderStorageBlocks =
+ QuerySingleGLInt(functions, GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS);
+ }
+ else
+ {
+ LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
+ }
+
+ if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
+ functions->hasGLExtension("GL_ARB_explicit_uniform_location"))
+ {
+ caps->maxUniformLocations = QuerySingleGLInt(functions, GL_MAX_UNIFORM_LOCATIONS);
+ }
+ else
+ {
+ LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
+ }
+
+ if (functions->isAtLeastGL(gl::Version(4, 0)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
+ functions->hasGLExtension("GL_ARB_texture_gather"))
+ {
+ caps->minProgramTextureGatherOffset =
+ QuerySingleGLInt(functions, GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET);
+ caps->maxProgramTextureGatherOffset =
+ QuerySingleGLInt(functions, GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET);
+ }
+ else
+ {
+ LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
+ }
+
+ if (functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
+ functions->hasGLExtension("GL_ARB_shader_image_load_store"))
+ {
+ caps->maxVertexImageUniforms = QuerySingleGLInt(functions, GL_MAX_VERTEX_IMAGE_UNIFORMS);
+ caps->maxFragmentImageUniforms =
+ QuerySingleGLInt(functions, GL_MAX_FRAGMENT_IMAGE_UNIFORMS);
+ caps->maxImageUnits = QuerySingleGLInt(functions, GL_MAX_IMAGE_UNITS);
+ caps->maxCombinedImageUniforms =
+ QuerySingleGLInt(functions, GL_MAX_COMBINED_IMAGE_UNIFORMS);
+ }
+ else
+ {
+ LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
+ }
+
+ if (functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
+ functions->hasGLExtension("GL_ARB_shader_atomic_counters"))
+ {
+ caps->maxVertexAtomicCounterBuffers =
+ QuerySingleGLInt(functions, GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS);
+ caps->maxVertexAtomicCounters = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATOMIC_COUNTERS);
+ caps->maxFragmentAtomicCounterBuffers =
+ QuerySingleGLInt(functions, GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS);
+ caps->maxFragmentAtomicCounters =
+ QuerySingleGLInt(functions, GL_MAX_FRAGMENT_ATOMIC_COUNTERS);
+ caps->maxAtomicCounterBufferBindings =
+ QuerySingleGLInt(functions, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS);
+ caps->maxAtomicCounterBufferSize =
+ QuerySingleGLInt(functions, GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE);
+ caps->maxCombinedAtomicCounterBuffers =
+ QuerySingleGLInt(functions, GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS);
+ caps->maxCombinedAtomicCounters =
+ QuerySingleGLInt(functions, GL_MAX_COMBINED_ATOMIC_COUNTERS);
+ }
+ else
+ {
+ LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
+ }
+
+ // TODO(geofflang): The gl-uniform-arrays WebGL conformance test struggles to complete on time
+ // if the max uniform vectors is too large. Artificially limit the maximum until the test is
+ // updated.
+ caps->maxVertexUniformVectors = std::min(1024u, caps->maxVertexUniformVectors);
+ caps->maxVertexUniformComponents =
+ std::min(caps->maxVertexUniformVectors * 4, caps->maxVertexUniformComponents);
+ caps->maxFragmentUniformVectors = std::min(1024u, caps->maxFragmentUniformVectors);
+ caps->maxFragmentUniformComponents =
+ std::min(caps->maxFragmentUniformVectors * 4, caps->maxFragmentUniformComponents);
+
+ // If it is not possible to support reading buffer data back, a shadow copy of the buffers must
+ // be held. This disallows writing to buffers indirectly through transform feedback, thus
+ // disallowing ES3.
+ if (!CanMapBufferForRead(functions))
+ {
+ LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
+ }
+
+ // Extension support
+ extensions->setTextureExtensionSupport(*textureCapsMap);
+ extensions->elementIndexUint = functions->standard == STANDARD_GL_DESKTOP ||
+ functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_OES_element_index_uint");
+ extensions->getProgramBinary = caps->programBinaryFormats.size() > 0;
+ extensions->readFormatBGRA = functions->isAtLeastGL(gl::Version(1, 2)) || functions->hasGLExtension("GL_EXT_bgra") ||
+ functions->hasGLESExtension("GL_EXT_read_format_bgra");
+ extensions->mapBuffer = functions->isAtLeastGL(gl::Version(1, 5)) ||
+ functions->hasGLESExtension("GL_OES_mapbuffer");
+ extensions->mapBufferRange = functions->isAtLeastGL(gl::Version(3, 0)) || functions->hasGLExtension("GL_ARB_map_buffer_range") ||
+ functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_EXT_map_buffer_range");
+ extensions->textureNPOT = functions->standard == STANDARD_GL_DESKTOP ||
+ functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_OES_texture_npot");
+ extensions->drawBuffers = functions->isAtLeastGL(gl::Version(2, 0)) || functions->hasGLExtension("ARB_draw_buffers") ||
+ functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_EXT_draw_buffers");
+ extensions->textureStorage = true;
+ extensions->textureFilterAnisotropic = functions->hasGLExtension("GL_EXT_texture_filter_anisotropic") || functions->hasGLESExtension("GL_EXT_texture_filter_anisotropic");
+ extensions->occlusionQueryBoolean =
+ functions->isAtLeastGL(gl::Version(1, 5)) ||
+ functions->hasGLExtension("GL_ARB_occlusion_query2") ||
+ functions->isAtLeastGLES(gl::Version(3, 0)) ||
+ functions->hasGLESExtension("GL_EXT_occlusion_query_boolean");
+ extensions->maxTextureAnisotropy = extensions->textureFilterAnisotropic ? QuerySingleGLFloat(functions, GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT) : 0.0f;
+ extensions->fence = functions->hasGLExtension("GL_NV_fence") || functions->hasGLESExtension("GL_NV_fence");
+ extensions->blendMinMax = functions->isAtLeastGL(gl::Version(1, 5)) || functions->hasGLExtension("GL_EXT_blend_minmax") ||
+ functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_EXT_blend_minmax");
+ extensions->framebufferBlit = (functions->blitFramebuffer != nullptr);
+ extensions->framebufferMultisample = caps->maxSamples > 0;
+ extensions->standardDerivatives = functions->isAtLeastGL(gl::Version(2, 0)) || functions->hasGLExtension("GL_ARB_fragment_shader") ||
+ functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_OES_standard_derivatives");
+ extensions->shaderTextureLOD = functions->isAtLeastGL(gl::Version(3, 0)) || functions->hasGLExtension("GL_ARB_shader_texture_lod") ||
+ functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_EXT_shader_texture_lod");
+ extensions->fragDepth = functions->standard == STANDARD_GL_DESKTOP ||
+ functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_EXT_frag_depth");
+ extensions->fboRenderMipmap = functions->isAtLeastGL(gl::Version(3, 0)) || functions->hasGLExtension("GL_EXT_framebuffer_object") ||
+ functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_OES_fbo_render_mipmap");
+ extensions->instancedArrays = functions->isAtLeastGL(gl::Version(3, 1)) ||
+ (functions->hasGLExtension("GL_ARB_instanced_arrays") &&
+ (functions->hasGLExtension("GL_ARB_draw_instanced") ||
+ functions->hasGLExtension("GL_EXT_draw_instanced"))) ||
+ functions->isAtLeastGLES(gl::Version(3, 0)) ||
+ functions->hasGLESExtension("GL_EXT_instanced_arrays");
+ extensions->unpackSubimage = functions->standard == STANDARD_GL_DESKTOP ||
+ functions->isAtLeastGLES(gl::Version(3, 0)) ||
+ functions->hasGLESExtension("GL_EXT_unpack_subimage");
+ extensions->packSubimage = functions->standard == STANDARD_GL_DESKTOP ||
+ functions->isAtLeastGLES(gl::Version(3, 0)) ||
+ functions->hasGLESExtension("GL_NV_pack_subimage");
+ extensions->debugMarker =
+ functions->isAtLeastGL(gl::Version(4, 3)) || functions->hasGLExtension("GL_KHR_debug") ||
+ functions->isAtLeastGLES(gl::Version(3, 2)) || functions->hasGLESExtension("GL_KHR_debug");
+ if (functions->isAtLeastGL(gl::Version(3, 3)) ||
+ functions->hasGLExtension("GL_ARB_timer_query") ||
+ functions->hasGLESExtension("GL_EXT_disjoint_timer_query"))
+ {
+ extensions->disjointTimerQuery = true;
+ extensions->queryCounterBitsTimeElapsed =
+ QueryQueryValue(functions, GL_TIME_ELAPSED, GL_QUERY_COUNTER_BITS);
+ extensions->queryCounterBitsTimestamp =
+ QueryQueryValue(functions, GL_TIMESTAMP, GL_QUERY_COUNTER_BITS);
+ }
+
+ // the EXT_multisample_compatibility is written against ES3.1 but can apply
+ // to earlier versions so therefore we're only checking for the extension string
+ // and not the specific GLES version.
+ extensions->multisampleCompatibility = functions->isAtLeastGL(gl::Version(1, 3)) ||
+ functions->hasGLESExtension("GL_EXT_multisample_compatibility");
+
+ extensions->framebufferMixedSamples =
+ functions->hasGLExtension("GL_NV_framebuffer_mixed_samples") ||
+ functions->hasGLESExtension("GL_NV_framebuffer_mixed_samples");
+
+ extensions->robustness = functions->isAtLeastGL(gl::Version(4, 5)) ||
+ functions->hasGLExtension("GL_KHR_robustness") ||
+ functions->hasGLExtension("GL_ARB_robustness") ||
+ functions->isAtLeastGLES(gl::Version(3, 2)) ||
+ functions->hasGLESExtension("GL_KHR_robustness") ||
+ functions->hasGLESExtension("GL_EXT_robustness");
+
+ // NV_path_rendering
+ // We also need interface query which is available in
+ // >= 4.3 core or ARB_interface_query or >= GLES 3.1
+ const bool canEnableGLPathRendering =
+ functions->hasGLExtension("GL_NV_path_rendering") &&
+ (functions->hasGLExtension("GL_ARB_program_interface_query") ||
+ functions->isAtLeastGL(gl::Version(4, 3)));
+
+ const bool canEnableESPathRendering =
+ functions->hasGLESExtension("GL_NV_path_rendering") &&
+ functions->isAtLeastGLES(gl::Version(3, 1));
+
+ extensions->pathRendering = canEnableGLPathRendering || canEnableESPathRendering;
+
+ extensions->textureSRGBDecode = functions->hasGLExtension("GL_EXT_texture_sRGB_decode") ||
+ functions->hasGLESExtension("GL_EXT_texture_sRGB_decode");
+
+#if defined(ANGLE_PLATFORM_APPLE)
+ VendorID vendor = GetVendorID(functions);
+ if ((IsAMD(vendor) || IsIntel(vendor)) && *maxSupportedESVersion >= gl::Version(3, 0))
+ {
+ // Apple Intel/AMD drivers do not correctly use the TEXTURE_SRGB_DECODE property of sampler
+ // states. Disable this extension when we would advertise any ES version that has samplers.
+ extensions->textureSRGBDecode = false;
+ }
+#endif
+
+ extensions->sRGBWriteControl = functions->isAtLeastGL(gl::Version(3, 0)) ||
+ functions->hasGLExtension("GL_EXT_framebuffer_sRGB") ||
+ functions->hasGLExtension("GL_ARB_framebuffer_sRGB") ||
+ functions->hasGLESExtension("GL_EXT_sRGB_write_control");
+
+#if defined(ANGLE_PLATFORM_ANDROID)
+ // SRGB blending does not appear to work correctly on the Nexus 5. Writing to an SRGB
+ // framebuffer with GL_FRAMEBUFFER_SRGB enabled and then reading back returns the same value.
+ // Disabling GL_FRAMEBUFFER_SRGB will then convert in the wrong direction.
+ extensions->sRGBWriteControl = false;
+#endif
+}
+
+void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workarounds)
+{
+ VendorID vendor = GetVendorID(functions);
+
+ workarounds->dontRemoveInvariantForFragmentInput =
+ functions->standard == STANDARD_GL_DESKTOP && IsAMD(vendor);
+
+ // Don't use 1-bit alpha formats on desktop GL with AMD or Intel drivers.
+ workarounds->avoid1BitAlphaTextureFormats =
+ functions->standard == STANDARD_GL_DESKTOP && (IsAMD(vendor) || IsIntel(vendor));
+
+ workarounds->rgba4IsNotSupportedForColorRendering =
+ functions->standard == STANDARD_GL_DESKTOP && IsIntel(vendor);
+
+ workarounds->emulateAbsIntFunction = IsIntel(vendor);
+
+ workarounds->addAndTrueToLoopCondition = IsIntel(vendor);
+
+ workarounds->emulateIsnanFloat = IsIntel(vendor);
+
+ workarounds->doesSRGBClearsOnLinearFramebufferAttachments =
+ functions->standard == STANDARD_GL_DESKTOP && (IsIntel(vendor) || IsAMD(vendor));
+
+#if defined(ANGLE_PLATFORM_APPLE)
+ workarounds->doWhileGLSLCausesGPUHang = true;
+ workarounds->useUnusedBlocksWithStandardOrSharedLayout = true;
+#endif
+
+ workarounds->finishDoesNotCauseQueriesToBeAvailable =
+ functions->standard == STANDARD_GL_DESKTOP && IsNvidia(vendor);
+
+ // TODO(cwallez): Disable this workaround for MacOSX versions 10.9 or later.
+ workarounds->alwaysCallUseProgramAfterLink = true;
+
+ workarounds->unpackOverlappingRowsSeparatelyUnpackBuffer = IsNvidia(vendor);
+ workarounds->packOverlappingRowsSeparatelyPackBuffer = IsNvidia(vendor);
+
+ workarounds->initializeCurrentVertexAttributes = IsNvidia(vendor);
+
+#if defined(ANGLE_PLATFORM_APPLE)
+ workarounds->unpackLastRowSeparatelyForPaddingInclusion = true;
+ workarounds->packLastRowSeparatelyForPaddingInclusion = true;
+#else
+ workarounds->unpackLastRowSeparatelyForPaddingInclusion = IsNvidia(vendor);
+ workarounds->packLastRowSeparatelyForPaddingInclusion = IsNvidia(vendor);
+#endif
+
+ workarounds->removeInvariantAndCentroidForESSL3 = functions->isAtMostGL(gl::Version(4, 1));
+}
+
+}
+
+bool CanMapBufferForRead(const FunctionsGL *functions)
+{
+ return (functions->mapBufferRange != nullptr) ||
+ (functions->mapBuffer != nullptr && functions->standard == STANDARD_GL_DESKTOP);
+}
+
+uint8_t *MapBufferRangeWithFallback(const FunctionsGL *functions,
+ GLenum target,
+ size_t offset,
+ size_t length,
+ GLbitfield access)
+{
+ if (functions->mapBufferRange != nullptr)
+ {
+ return reinterpret_cast<uint8_t *>(
+ functions->mapBufferRange(target, offset, length, access));
+ }
+ else if (functions->mapBuffer != nullptr &&
+ (functions->standard == STANDARD_GL_DESKTOP || access == GL_MAP_WRITE_BIT))
+ {
+ // Only the read and write bits are supported
+ ASSERT((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) != 0);
+
+ GLenum accessEnum = 0;
+ if (access == (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT))
+ {
+ accessEnum = GL_READ_WRITE;
+ }
+ else if (access == GL_MAP_READ_BIT)
+ {
+ accessEnum = GL_READ_ONLY;
+ }
+ else if (access == GL_MAP_WRITE_BIT)
+ {
+ accessEnum = GL_WRITE_ONLY;
+ }
+ else
+ {
+ UNREACHABLE();
+ return nullptr;
+ }
+
+ return reinterpret_cast<uint8_t *>(functions->mapBuffer(target, accessEnum)) + offset;
+ }
+ else
+ {
+ // No options available
+ UNREACHABLE();
+ return nullptr;
+ }
+}
+
+gl::ErrorOrResult<bool> ShouldApplyLastRowPaddingWorkaround(const gl::Extents &size,
+ const gl::PixelStoreStateBase &state,
+ GLenum format,
+ GLenum type,
+ bool is3D,
+ const void *pixels)
+{
+ if (state.pixelBuffer.get() == nullptr)
+ {
+ return false;
+ }
+
+ // We are using an pack or unpack buffer, compute what the driver thinks is going to be the
+ // last byte read or written. If it is past the end of the buffer, we will need to use the
+ // workaround otherwise the driver will generate INVALID_OPERATION and not do the operation.
+ CheckedNumeric<size_t> checkedEndByte;
+ CheckedNumeric<size_t> pixelBytes;
+ size_t rowPitch;
+
+ const gl::InternalFormat &glFormat =
+ gl::GetInternalFormatInfo(gl::GetSizedInternalFormat(format, type));
+ ANGLE_TRY_RESULT(glFormat.computePackUnpackEndByte(size, state, is3D), checkedEndByte);
+ ANGLE_TRY_RESULT(glFormat.computeRowPitch(size.width, state.alignment, state.rowLength),
+ rowPitch);
+ pixelBytes = glFormat.pixelBytes;
+
+ checkedEndByte += reinterpret_cast<intptr_t>(pixels);
+
+ // At this point checkedEndByte is the actual last byte read.
+ // The driver adds an extra row padding (if any), mimic it.
+ ANGLE_TRY_CHECKED_MATH(pixelBytes);
+ if (pixelBytes.ValueOrDie() * size.width < rowPitch)
+ {
+ checkedEndByte += rowPitch - pixelBytes * size.width;
+ }
+
+ ANGLE_TRY_CHECKED_MATH(checkedEndByte);
+
+ return checkedEndByte.ValueOrDie() > static_cast<size_t>(state.pixelBuffer->getSize());
+}
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/renderergl_utils.h b/gfx/angle/src/libANGLE/renderer/gl/renderergl_utils.h
new file mode 100755
index 000000000..1e9338fb5
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/renderergl_utils.h
@@ -0,0 +1,61 @@
+//
+// Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// renderergl_utils.h: Conversion functions and other utility routines
+// specific to the OpenGL renderer.
+
+#ifndef LIBANGLE_RENDERER_GL_RENDERERGLUTILS_H_
+#define LIBANGLE_RENDERER_GL_RENDERERGLUTILS_H_
+
+#include "libANGLE/angletypes.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/renderer/driver_utils.h"
+#include "libANGLE/renderer/gl/functionsgl_typedefs.h"
+
+#include <string>
+#include <vector>
+
+namespace gl
+{
+struct Caps;
+class TextureCapsMap;
+struct Extensions;
+struct Version;
+}
+
+namespace rx
+{
+class FunctionsGL;
+struct WorkaroundsGL;
+
+VendorID GetVendorID(const FunctionsGL *functions);
+std::string GetDriverVersion(const FunctionsGL *functions);
+
+namespace nativegl_gl
+{
+
+void GenerateCaps(const FunctionsGL *functions, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap,
+ gl::Extensions *extensions, gl::Version *maxSupportedESVersion);
+
+void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workarounds);
+}
+
+bool CanMapBufferForRead(const FunctionsGL *functions);
+uint8_t *MapBufferRangeWithFallback(const FunctionsGL *functions,
+ GLenum target,
+ size_t offset,
+ size_t length,
+ GLbitfield access);
+
+gl::ErrorOrResult<bool> ShouldApplyLastRowPaddingWorkaround(const gl::Extents &size,
+ const gl::PixelStoreStateBase &state,
+ GLenum format,
+ GLenum type,
+ bool is3D,
+ const void *pixels);
+}
+
+#endif // LIBANGLE_RENDERER_GL_RENDERERGLUTILS_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/wgl/D3DTextureSurfaceWGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/wgl/D3DTextureSurfaceWGL.cpp
new file mode 100644
index 000000000..f19e8fdf3
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/wgl/D3DTextureSurfaceWGL.cpp
@@ -0,0 +1,384 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// D3DTextureSurfaceWGL.cpp: WGL implementation of egl::Surface for D3D texture interop.
+
+#include "libANGLE/renderer/gl/wgl/D3DTextureSurfaceWGL.h"
+
+#include "libANGLE/renderer/gl/FramebufferGL.h"
+#include "libANGLE/renderer/gl/TextureGL.h"
+#include "libANGLE/renderer/gl/RendererGL.h"
+#include "libANGLE/renderer/gl/StateManagerGL.h"
+#include "libANGLE/renderer/gl/wgl/DisplayWGL.h"
+#include "libANGLE/renderer/gl/wgl/FunctionsWGL.h"
+
+namespace rx
+{
+
+namespace
+{
+
+egl::Error GetD3DTextureInfo(EGLClientBuffer clientBuffer,
+ size_t *width,
+ size_t *height,
+ IUnknown **object,
+ IUnknown **device)
+{
+ IUnknown *buffer = static_cast<IUnknown *>(clientBuffer);
+
+ IDirect3DTexture9 *texture9 = nullptr;
+ ID3D11Texture2D *texture11 = nullptr;
+ if (SUCCEEDED(buffer->QueryInterface<ID3D11Texture2D>(&texture11)))
+ {
+ D3D11_TEXTURE2D_DESC textureDesc;
+ texture11->GetDesc(&textureDesc);
+
+ // From table egl.restrictions in EGL_ANGLE_d3d_texture_client_buffer.
+ switch (textureDesc.Format)
+ {
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ break;
+
+ default:
+ SafeRelease(texture11);
+ return egl::Error(EGL_BAD_PARAMETER, "Unknown client buffer texture format: %u.",
+ textureDesc.Format);
+ }
+
+ ID3D11Device *d3d11Device = nullptr;
+ texture11->GetDevice(&d3d11Device);
+ if (d3d11Device == nullptr)
+ {
+ SafeRelease(texture11);
+ return egl::Error(EGL_BAD_PARAMETER,
+ "Could not query the D3D11 device from the client buffer.");
+ }
+
+ if (width)
+ {
+ *width = textureDesc.Width;
+ }
+ if (height)
+ {
+ *height = textureDesc.Height;
+ }
+
+ if (device)
+ {
+ *device = d3d11Device;
+ }
+ else
+ {
+ SafeRelease(d3d11Device);
+ }
+
+ if (object)
+ {
+ *object = texture11;
+ }
+ else
+ {
+ SafeRelease(texture11);
+ }
+
+ return egl::Error(EGL_SUCCESS);
+ }
+ else if (SUCCEEDED(buffer->QueryInterface<IDirect3DTexture9>(&texture9)))
+ {
+ D3DSURFACE_DESC surfaceDesc;
+ if (FAILED(texture9->GetLevelDesc(0, &surfaceDesc)))
+ {
+ SafeRelease(texture9);
+ return egl::Error(EGL_BAD_PARAMETER,
+ "Could not query description of the D3D9 surface.");
+ }
+
+ // From table egl.restrictions in EGL_ANGLE_d3d_texture_client_buffer.
+ switch (surfaceDesc.Format)
+ {
+ case D3DFMT_R8G8B8:
+ case D3DFMT_A8R8G8B8:
+ case D3DFMT_A16B16G16R16F:
+ case D3DFMT_A32B32G32R32F:
+ break;
+
+ default:
+ SafeRelease(texture9);
+ return egl::Error(EGL_BAD_PARAMETER, "Unknown client buffer texture format: %u.",
+ surfaceDesc.Format);
+ }
+
+ if (width)
+ {
+ *width = surfaceDesc.Width;
+ }
+ if (height)
+ {
+ *height = surfaceDesc.Height;
+ }
+
+ IDirect3DDevice9 *d3d9Device = nullptr;
+ HRESULT result = texture9->GetDevice(&d3d9Device);
+ if (FAILED(result))
+ {
+ SafeRelease(texture9);
+ return egl::Error(EGL_BAD_PARAMETER,
+ "Could not query the D3D9 device from the client buffer.");
+ }
+
+ if (device)
+ {
+ *device = d3d9Device;
+ }
+ else
+ {
+ SafeRelease(d3d9Device);
+ }
+
+ if (object)
+ {
+ *object = texture9;
+ }
+ else
+ {
+ SafeRelease(texture9);
+ }
+
+ return egl::Error(EGL_SUCCESS);
+ }
+ else
+ {
+ return egl::Error(EGL_BAD_PARAMETER,
+ "Provided buffer is not a IDirect3DTexture9 or ID3D11Texture2D.");
+ }
+}
+
+} // anonymous namespace
+
+D3DTextureSurfaceWGL::D3DTextureSurfaceWGL(const egl::SurfaceState &state,
+ RendererGL *renderer,
+ EGLClientBuffer clientBuffer,
+ DisplayWGL *display,
+ HGLRC wglContext,
+ HDC deviceContext,
+ const FunctionsGL *functionsGL,
+ const FunctionsWGL *functionsWGL)
+ : SurfaceGL(state, renderer),
+ mClientBuffer(clientBuffer),
+ mRenderer(renderer),
+ mDisplay(display),
+ mStateManager(renderer->getStateManager()),
+ mWorkarounds(renderer->getWorkarounds()),
+ mFunctionsGL(functionsGL),
+ mFunctionsWGL(functionsWGL),
+ mWGLContext(wglContext),
+ mDeviceContext(deviceContext),
+ mWidth(0),
+ mHeight(0),
+ mDeviceHandle(nullptr),
+ mObject(nullptr),
+ mBoundObjectTextureHandle(nullptr),
+ mBoundObjectRenderbufferHandle(nullptr),
+ mRenderbufferID(0),
+ mFramebufferID(0)
+{
+}
+
+D3DTextureSurfaceWGL::~D3DTextureSurfaceWGL()
+{
+ ASSERT(mBoundObjectTextureHandle == nullptr);
+
+ SafeRelease(mObject);
+
+ if (mDeviceHandle)
+ {
+ if (mBoundObjectRenderbufferHandle)
+ {
+ mFunctionsWGL->dxUnregisterObjectNV(mDeviceHandle, mBoundObjectRenderbufferHandle);
+ mBoundObjectRenderbufferHandle = nullptr;
+ }
+ mStateManager->deleteRenderbuffer(mRenderbufferID);
+
+ if (mBoundObjectTextureHandle)
+ {
+ mFunctionsWGL->dxUnregisterObjectNV(mDeviceHandle, mBoundObjectTextureHandle);
+ mBoundObjectTextureHandle = nullptr;
+ }
+
+ // GL framebuffer is deleted by the default framebuffer object
+ mFramebufferID = 0;
+
+ mDisplay->releaseD3DDevice(mDeviceHandle);
+ mDeviceHandle = nullptr;
+ }
+}
+
+egl::Error D3DTextureSurfaceWGL::ValidateD3DTextureClientBuffer(EGLClientBuffer clientBuffer)
+{
+ return GetD3DTextureInfo(clientBuffer, nullptr, nullptr, nullptr, nullptr);
+}
+
+egl::Error D3DTextureSurfaceWGL::initialize()
+{
+ IUnknown *device = nullptr;
+ ANGLE_TRY(GetD3DTextureInfo(mClientBuffer, &mWidth, &mHeight, &mObject, &device));
+
+ ASSERT(device != nullptr);
+ egl::Error error = mDisplay->registerD3DDevice(device, &mDeviceHandle);
+ SafeRelease(device);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ mFunctionsGL->genRenderbuffers(1, &mRenderbufferID);
+ mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mRenderbufferID);
+ mBoundObjectRenderbufferHandle = mFunctionsWGL->dxRegisterObjectNV(
+ mDeviceHandle, mObject, mRenderbufferID, GL_RENDERBUFFER, WGL_ACCESS_READ_WRITE_NV);
+ if (mBoundObjectRenderbufferHandle == nullptr)
+ {
+ return egl::Error(EGL_BAD_ALLOC, "Failed to register D3D object, error: 0x%08x.",
+ HRESULT_CODE(GetLastError()));
+ }
+
+ mFunctionsGL->genFramebuffers(1, &mFramebufferID);
+ mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
+ mFunctionsGL->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
+ mRenderbufferID);
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error D3DTextureSurfaceWGL::makeCurrent()
+{
+ if (!mFunctionsWGL->makeCurrent(mDeviceContext, mWGLContext))
+ {
+ // TODO(geofflang): What error type here?
+ return egl::Error(EGL_CONTEXT_LOST, "Failed to make the WGL context current.");
+ }
+
+ if (!mFunctionsWGL->dxLockObjectsNV(mDeviceHandle, 1, &mBoundObjectRenderbufferHandle))
+ {
+ DWORD error = GetLastError();
+ return egl::Error(EGL_BAD_ALLOC, "Failed to lock object, error: 0x%08x.",
+ HRESULT_CODE(error));
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error D3DTextureSurfaceWGL::unMakeCurrent()
+{
+ if (!mFunctionsWGL->dxUnlockObjectsNV(mDeviceHandle, 1, &mBoundObjectRenderbufferHandle))
+ {
+ DWORD error = GetLastError();
+ return egl::Error(EGL_BAD_ALLOC, "Failed to unlock object, error: 0x%08x.",
+ HRESULT_CODE(error));
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error D3DTextureSurfaceWGL::swap()
+{
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error D3DTextureSurfaceWGL::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error D3DTextureSurfaceWGL::querySurfacePointerANGLE(EGLint attribute, void **value)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error D3DTextureSurfaceWGL::bindTexImage(gl::Texture *texture, EGLint buffer)
+{
+ ASSERT(mBoundObjectTextureHandle == nullptr);
+
+ const TextureGL *textureGL = GetImplAs<TextureGL>(texture);
+ GLuint textureID = textureGL->getTextureID();
+
+ mBoundObjectTextureHandle = mFunctionsWGL->dxRegisterObjectNV(
+ mDeviceHandle, mObject, textureID, GL_TEXTURE_2D, WGL_ACCESS_READ_WRITE_NV);
+ if (mBoundObjectTextureHandle == nullptr)
+ {
+ DWORD error = GetLastError();
+ return egl::Error(EGL_BAD_ALLOC, "Failed to register D3D object, error: 0x%08x.",
+ HRESULT_CODE(error));
+ }
+
+ if (!mFunctionsWGL->dxLockObjectsNV(mDeviceHandle, 1, &mBoundObjectTextureHandle))
+ {
+ DWORD error = GetLastError();
+ return egl::Error(EGL_BAD_ALLOC, "Failed to lock object, error: 0x%08x.",
+ HRESULT_CODE(error));
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error D3DTextureSurfaceWGL::releaseTexImage(EGLint buffer)
+{
+ ASSERT(mBoundObjectTextureHandle != nullptr);
+ if (!mFunctionsWGL->dxUnlockObjectsNV(mDeviceHandle, 1, &mBoundObjectTextureHandle))
+ {
+ DWORD error = GetLastError();
+ return egl::Error(EGL_BAD_ALLOC, "Failed to unlock object, error: 0x%08x.",
+ HRESULT_CODE(error));
+ }
+
+ if (!mFunctionsWGL->dxUnregisterObjectNV(mDeviceHandle, mBoundObjectTextureHandle))
+ {
+ DWORD error = GetLastError();
+ return egl::Error(EGL_BAD_ALLOC, "Failed to unregister D3D object, error: 0x%08x.",
+ HRESULT_CODE(error));
+ }
+ mBoundObjectTextureHandle = nullptr;
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+void D3DTextureSurfaceWGL::setSwapInterval(EGLint interval)
+{
+ UNIMPLEMENTED();
+}
+
+EGLint D3DTextureSurfaceWGL::getWidth() const
+{
+ return static_cast<EGLint>(mWidth);
+}
+
+EGLint D3DTextureSurfaceWGL::getHeight() const
+{
+ return static_cast<EGLint>(mHeight);
+}
+
+EGLint D3DTextureSurfaceWGL::isPostSubBufferSupported() const
+{
+ return EGL_FALSE;
+}
+
+EGLint D3DTextureSurfaceWGL::getSwapBehavior() const
+{
+ return EGL_BUFFER_PRESERVED;
+}
+
+FramebufferImpl *D3DTextureSurfaceWGL::createDefaultFramebuffer(const gl::FramebufferState &data)
+{
+ return new FramebufferGL(mFramebufferID, data, mFunctionsGL, mWorkarounds,
+ mRenderer->getBlitter(), mStateManager);
+}
+} // namespace rx
diff --git a/gfx/angle/src/libANGLE/renderer/gl/wgl/D3DTextureSurfaceWGL.h b/gfx/angle/src/libANGLE/renderer/gl/wgl/D3DTextureSurfaceWGL.h
new file mode 100644
index 000000000..8fb1d4003
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/wgl/D3DTextureSurfaceWGL.h
@@ -0,0 +1,86 @@
+
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// D3DTextureSurfaceWGL.h: WGL implementation of egl::Surface for D3D texture interop.
+
+#ifndef LIBANGLE_RENDERER_GL_WGL_D3DTEXTIRESURFACEWGL_H_
+#define LIBANGLE_RENDERER_GL_WGL_D3DTEXTIRESURFACEWGL_H_
+
+#include "libANGLE/renderer/gl/SurfaceGL.h"
+
+#include <GL/wglext.h>
+
+namespace rx
+{
+
+class FunctionsGL;
+class FunctionsWGL;
+class DisplayWGL;
+class StateManagerGL;
+struct WorkaroundsGL;
+
+class D3DTextureSurfaceWGL : public SurfaceGL
+{
+ public:
+ D3DTextureSurfaceWGL(const egl::SurfaceState &state,
+ RendererGL *renderer,
+ EGLClientBuffer clientBuffer,
+ DisplayWGL *display,
+ HGLRC wglContext,
+ HDC deviceContext,
+ const FunctionsGL *functionsGL,
+ const FunctionsWGL *functionsWGL);
+ ~D3DTextureSurfaceWGL() override;
+
+ static egl::Error ValidateD3DTextureClientBuffer(EGLClientBuffer clientBuffer);
+
+ egl::Error initialize() override;
+ egl::Error makeCurrent() override;
+ egl::Error unMakeCurrent() override;
+
+ egl::Error swap() override;
+ egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override;
+ egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override;
+ egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) override;
+ egl::Error releaseTexImage(EGLint buffer) override;
+ void setSwapInterval(EGLint interval) override;
+
+ EGLint getWidth() const override;
+ EGLint getHeight() const override;
+
+ EGLint isPostSubBufferSupported() const override;
+ EGLint getSwapBehavior() const override;
+
+ FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &data) override;
+
+ private:
+ EGLClientBuffer mClientBuffer;
+
+ RendererGL *mRenderer;
+
+ DisplayWGL *mDisplay;
+ StateManagerGL *mStateManager;
+ const WorkaroundsGL &mWorkarounds;
+ const FunctionsGL *mFunctionsGL;
+ const FunctionsWGL *mFunctionsWGL;
+
+ HGLRC mWGLContext;
+ HDC mDeviceContext;
+
+ size_t mWidth;
+ size_t mHeight;
+
+ HANDLE mDeviceHandle;
+ IUnknown *mObject;
+ HANDLE mBoundObjectTextureHandle;
+ HANDLE mBoundObjectRenderbufferHandle;
+
+ GLuint mRenderbufferID;
+ GLuint mFramebufferID;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_GL_WGL_D3DTEXTIRESURFACEWGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.cpp
new file mode 100755
index 000000000..7c5214e82
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.cpp
@@ -0,0 +1,553 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// DXGISwapChainWindowSurfaceWGL.cpp: WGL implementation of egl::Surface for windows using a DXGI
+// swapchain.
+
+#include "libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.h"
+
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/gl/FramebufferGL.h"
+#include "libANGLE/renderer/gl/TextureGL.h"
+#include "libANGLE/renderer/gl/RendererGL.h"
+#include "libANGLE/renderer/gl/StateManagerGL.h"
+#include "libANGLE/renderer/gl/wgl/DisplayWGL.h"
+#include "libANGLE/renderer/gl/wgl/FunctionsWGL.h"
+
+#include <EGL/eglext.h>
+
+namespace rx
+{
+
+DXGISwapChainWindowSurfaceWGL::DXGISwapChainWindowSurfaceWGL(const egl::SurfaceState &state,
+ RendererGL *renderer,
+ EGLNativeWindowType window,
+ ID3D11Device *device,
+ HANDLE deviceHandle,
+ HGLRC wglContext,
+ HDC deviceContext,
+ const FunctionsGL *functionsGL,
+ const FunctionsWGL *functionsWGL,
+ EGLint orientation)
+ : SurfaceGL(state, renderer),
+ mWindow(window),
+ mStateManager(renderer->getStateManager()),
+ mWorkarounds(renderer->getWorkarounds()),
+ mRenderer(renderer),
+ mFunctionsGL(functionsGL),
+ mFunctionsWGL(functionsWGL),
+ mDevice(device),
+ mDeviceHandle(deviceHandle),
+ mWGLDevice(deviceContext),
+ mWGLContext(wglContext),
+ mSwapChainFormat(DXGI_FORMAT_UNKNOWN),
+ mSwapChainFlags(0),
+ mDepthBufferFormat(GL_NONE),
+ mFirstSwap(true),
+ mSwapChain(nullptr),
+ mSwapChain1(nullptr),
+ mColorRenderbufferID(0),
+ mRenderbufferBufferHandle(nullptr),
+ mDepthRenderbufferID(0),
+ mFramebufferID(0),
+ mTextureID(0),
+ mTextureHandle(nullptr),
+ mWidth(0),
+ mHeight(0),
+ mSwapInterval(1),
+ mOrientation(orientation)
+{
+}
+
+DXGISwapChainWindowSurfaceWGL::~DXGISwapChainWindowSurfaceWGL()
+{
+ if (mRenderbufferBufferHandle != nullptr)
+ {
+ mFunctionsWGL->dxUnlockObjectsNV(mDeviceHandle, 1, &mRenderbufferBufferHandle);
+ mFunctionsWGL->dxUnregisterObjectNV(mDeviceHandle, mRenderbufferBufferHandle);
+ }
+
+ if (mColorRenderbufferID != 0)
+ {
+ mStateManager->deleteRenderbuffer(mColorRenderbufferID);
+ mColorRenderbufferID = 0;
+ }
+
+ if (mDepthRenderbufferID != 0)
+ {
+ mStateManager->deleteRenderbuffer(mDepthRenderbufferID);
+ mDepthRenderbufferID = 0;
+ }
+
+ SafeRelease(mSwapChain);
+ SafeRelease(mSwapChain1);
+}
+
+egl::Error DXGISwapChainWindowSurfaceWGL::initialize()
+{
+ if (mOrientation != EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE)
+ {
+ // TODO(geofflang): Support the orientation extensions fully. Currently only inverting Y is
+ // supported. To support all orientations, an intermediate framebuffer will be needed with
+ // a blit before swap.
+ return egl::Error(EGL_BAD_ATTRIBUTE,
+ "DXGISwapChainWindowSurfaceWGL requires an orientation of "
+ "EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE.");
+ }
+
+ RECT rect;
+ if (!GetClientRect(mWindow, &rect))
+ {
+ return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to query the window size.");
+ }
+ mWidth = rect.right - rect.left;
+ mHeight = rect.bottom - rect.top;
+
+ mSwapChainFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
+ mSwapChainFlags = 0;
+ mDepthBufferFormat = GL_DEPTH24_STENCIL8;
+
+ mFunctionsGL->genFramebuffers(1, &mFramebufferID);
+ mFunctionsGL->genRenderbuffers(1, &mColorRenderbufferID);
+ mFunctionsGL->genRenderbuffers(1, &mDepthRenderbufferID);
+
+ return createSwapChain();
+}
+
+egl::Error DXGISwapChainWindowSurfaceWGL::makeCurrent()
+{
+ if (!mFunctionsWGL->makeCurrent(mWGLDevice, mWGLContext))
+ {
+ // TODO: What error type here?
+ return egl::Error(EGL_CONTEXT_LOST, "Failed to make the WGL context current.");
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DXGISwapChainWindowSurfaceWGL::swap()
+{
+ mFunctionsGL->flush();
+
+ egl::Error error = setObjectsLocked(false);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ HRESULT result = mSwapChain->Present(mSwapInterval, 0);
+ mFirstSwap = false;
+
+ error = setObjectsLocked(true);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (FAILED(result))
+ {
+ return egl::Error(EGL_BAD_ALLOC, "Failed to present swap chain, result: 0x%X", result);
+ }
+
+ return checkForResize();
+}
+
+egl::Error DXGISwapChainWindowSurfaceWGL::postSubBuffer(EGLint x,
+ EGLint y,
+ EGLint width,
+ EGLint height)
+{
+ ASSERT(mSwapChain1 != nullptr);
+
+ mFunctionsGL->flush();
+
+ egl::Error error = setObjectsLocked(false);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ HRESULT result = S_OK;
+ if (mFirstSwap)
+ {
+ result = mSwapChain1->Present(mSwapInterval, 0);
+ mFirstSwap = false;
+ }
+ else
+ {
+ RECT rect = {static_cast<LONG>(x), static_cast<LONG>(mHeight - y - height),
+ static_cast<LONG>(x + width), static_cast<LONG>(mHeight - y)};
+ DXGI_PRESENT_PARAMETERS params = {1, &rect, nullptr, nullptr};
+ result = mSwapChain1->Present1(mSwapInterval, 0, &params);
+ }
+
+ error = setObjectsLocked(true);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (FAILED(result))
+ {
+ return egl::Error(EGL_BAD_ALLOC, "Failed to present swap chain, result: 0x%X", result);
+ }
+
+ return checkForResize();
+}
+
+egl::Error DXGISwapChainWindowSurfaceWGL::querySurfacePointerANGLE(EGLint attribute, void **value)
+{
+ UNREACHABLE();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DXGISwapChainWindowSurfaceWGL::bindTexImage(gl::Texture *texture, EGLint buffer)
+{
+ ASSERT(mTextureHandle == nullptr);
+
+ const TextureGL *textureGL = GetImplAs<TextureGL>(texture);
+ GLuint textureID = textureGL->getTextureID();
+
+ ID3D11Texture2D *colorBuffer = nullptr;
+ HRESULT result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D),
+ reinterpret_cast<void **>(&colorBuffer));
+ if (FAILED(result))
+ {
+ return egl::Error(EGL_BAD_ALLOC, "Failed to query texture from swap chain, result: 0x%X",
+ result);
+ }
+
+ mTextureHandle = mFunctionsWGL->dxRegisterObjectNV(mDeviceHandle, colorBuffer, textureID,
+ GL_TEXTURE_2D, WGL_ACCESS_READ_WRITE_NV);
+ SafeRelease(colorBuffer);
+ if (mTextureHandle == nullptr)
+ {
+ return egl::Error(EGL_BAD_ALLOC, "Failed to register D3D object, error: 0x%08x.",
+ HRESULT_CODE(GetLastError()));
+ }
+
+ if (!mFunctionsWGL->dxLockObjectsNV(mDeviceHandle, 1, &mTextureHandle))
+ {
+ mFunctionsWGL->dxUnregisterObjectNV(mDeviceHandle, mTextureHandle);
+ mTextureHandle = nullptr;
+
+ return egl::Error(EGL_BAD_ALLOC, "Failed to lock D3D object, error: 0x%08x.",
+ HRESULT_CODE(GetLastError()));
+ }
+
+ mTextureID = textureID;
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DXGISwapChainWindowSurfaceWGL::releaseTexImage(EGLint buffer)
+{
+ ASSERT(mTextureHandle != nullptr);
+
+ if (!mFunctionsWGL->dxUnlockObjectsNV(mDeviceHandle, 1, &mTextureHandle))
+ {
+ return egl::Error(EGL_BAD_ALLOC, "Failed to unlock D3D object, error: 0x%08x.",
+ HRESULT_CODE(GetLastError()));
+ }
+
+ if (!mFunctionsWGL->dxUnregisterObjectNV(mDeviceHandle, mTextureHandle))
+ {
+ return egl::Error(EGL_BAD_ALLOC, "Failed to unregister D3D object, error: 0x%08x.",
+ HRESULT_CODE(GetLastError()));
+ }
+
+ mTextureID = 0;
+ mTextureHandle = nullptr;
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+void DXGISwapChainWindowSurfaceWGL::setSwapInterval(EGLint interval)
+{
+ mSwapInterval = interval;
+}
+
+EGLint DXGISwapChainWindowSurfaceWGL::getWidth() const
+{
+ return static_cast<EGLint>(mWidth);
+}
+
+EGLint DXGISwapChainWindowSurfaceWGL::getHeight() const
+{
+ return static_cast<EGLint>(mHeight);
+}
+
+EGLint DXGISwapChainWindowSurfaceWGL::isPostSubBufferSupported() const
+{
+ return mSwapChain1 != nullptr;
+}
+
+EGLint DXGISwapChainWindowSurfaceWGL::getSwapBehavior() const
+{
+ return EGL_BUFFER_DESTROYED;
+}
+
+FramebufferImpl *DXGISwapChainWindowSurfaceWGL::createDefaultFramebuffer(
+ const gl::FramebufferState &data)
+{
+ return new FramebufferGL(mFramebufferID, data, mFunctionsGL, mWorkarounds,
+ mRenderer->getBlitter(), mStateManager);
+}
+
+egl::Error DXGISwapChainWindowSurfaceWGL::setObjectsLocked(bool locked)
+{
+ if (mRenderbufferBufferHandle == nullptr)
+ {
+ ASSERT(mTextureHandle == nullptr);
+ return egl::Error(EGL_SUCCESS);
+ }
+
+ HANDLE resources[] = {
+ mRenderbufferBufferHandle, mTextureHandle,
+ };
+ GLint count = (mTextureHandle != nullptr) ? 2 : 1;
+
+ if (locked)
+ {
+ if (!mFunctionsWGL->dxLockObjectsNV(mDeviceHandle, count, resources))
+ {
+ return egl::Error(EGL_BAD_ALLOC, "Failed to lock object, error: 0x%08x.",
+ HRESULT_CODE(GetLastError()));
+ }
+ }
+ else
+ {
+ if (!mFunctionsWGL->dxUnlockObjectsNV(mDeviceHandle, count, resources))
+ {
+ return egl::Error(EGL_BAD_ALLOC, "Failed to lock object, error: 0x%08x.",
+ HRESULT_CODE(GetLastError()));
+ }
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DXGISwapChainWindowSurfaceWGL::checkForResize()
+{
+ RECT rect;
+ if (!GetClientRect(mWindow, &rect))
+ {
+ return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to query the window size.");
+ }
+
+ size_t newWidth = rect.right - rect.left;
+ size_t newHeight = rect.bottom - rect.top;
+ if (newWidth != mWidth || newHeight != mHeight)
+ {
+ mWidth = newWidth;
+ mHeight = newHeight;
+
+ // TODO(geofflang): Handle resize by resizing the swap chain instead of re-creating it.
+ egl::Error error = createSwapChain();
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+static IDXGIFactory *GetDXGIFactoryFromDevice(ID3D11Device *device)
+{
+ IDXGIDevice *dxgiDevice = nullptr;
+ HRESULT result =
+ device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void **>(&dxgiDevice));
+ if (FAILED(result))
+ {
+ return nullptr;
+ }
+
+ IDXGIAdapter *dxgiAdapter = nullptr;
+ result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void **>(&dxgiAdapter));
+ SafeRelease(dxgiDevice);
+ if (FAILED(result))
+ {
+ return nullptr;
+ }
+
+ IDXGIFactory *dxgiFactory = nullptr;
+ result =
+ dxgiAdapter->GetParent(__uuidof(IDXGIFactory), reinterpret_cast<void **>(&dxgiFactory));
+ SafeRelease(dxgiAdapter);
+ if (FAILED(result))
+ {
+ return nullptr;
+ }
+
+ return dxgiFactory;
+}
+
+egl::Error DXGISwapChainWindowSurfaceWGL::createSwapChain()
+{
+ egl::Error error = setObjectsLocked(false);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (mRenderbufferBufferHandle)
+ {
+ mFunctionsWGL->dxUnregisterObjectNV(mDeviceHandle, mRenderbufferBufferHandle);
+ mRenderbufferBufferHandle = nullptr;
+ }
+
+ // If this surface is bound to a texture, unregister it.
+ bool hadBoundSurface = (mTextureHandle != nullptr);
+ if (hadBoundSurface)
+ {
+ mFunctionsWGL->dxUnregisterObjectNV(mDeviceHandle, mTextureHandle);
+ mTextureHandle = nullptr;
+ }
+
+ IDXGIFactory *dxgiFactory = GetDXGIFactoryFromDevice(mDevice);
+ if (dxgiFactory == nullptr)
+ {
+ return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to query the DXGIFactory.");
+ }
+
+ IDXGIFactory2 *dxgiFactory2 = nullptr;
+ HRESULT result = dxgiFactory->QueryInterface(__uuidof(IDXGIFactory2),
+ reinterpret_cast<void **>(&dxgiFactory2));
+ if (SUCCEEDED(result))
+ {
+ ASSERT(dxgiFactory2 != nullptr);
+
+ DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
+ swapChainDesc.BufferCount = 1;
+ swapChainDesc.Format = mSwapChainFormat;
+ swapChainDesc.Width = static_cast<UINT>(mWidth);
+ swapChainDesc.Height = static_cast<UINT>(mHeight);
+ swapChainDesc.Format = mSwapChainFormat;
+ swapChainDesc.Stereo = FALSE;
+ swapChainDesc.SampleDesc.Count = 1;
+ swapChainDesc.SampleDesc.Quality = 0;
+ swapChainDesc.BufferUsage =
+ DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_BACK_BUFFER;
+ swapChainDesc.BufferCount = 1;
+ swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL;
+ swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
+ swapChainDesc.Flags = mSwapChainFlags;
+
+ result = dxgiFactory2->CreateSwapChainForHwnd(mDevice, mWindow, &swapChainDesc, nullptr,
+ nullptr, &mSwapChain1);
+ SafeRelease(dxgiFactory2);
+ SafeRelease(dxgiFactory);
+ if (FAILED(result))
+ {
+ return egl::Error(EGL_BAD_ALLOC, "Failed to create swap chain for window, result: 0x%X",
+ result);
+ }
+
+ mSwapChain = mSwapChain1;
+ mSwapChain->AddRef();
+ }
+ else
+ {
+ DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
+ swapChainDesc.BufferCount = 1;
+ swapChainDesc.BufferDesc.Format = mSwapChainFormat;
+ swapChainDesc.BufferDesc.Width = static_cast<UINT>(mWidth);
+ swapChainDesc.BufferDesc.Height = static_cast<UINT>(mHeight);
+ swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
+ swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
+ swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
+ swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
+ swapChainDesc.BufferUsage =
+ DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_BACK_BUFFER;
+ swapChainDesc.Flags = mSwapChainFlags;
+ swapChainDesc.OutputWindow = mWindow;
+ swapChainDesc.SampleDesc.Count = 1;
+ swapChainDesc.SampleDesc.Quality = 0;
+ swapChainDesc.Windowed = TRUE;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
+
+ result = dxgiFactory->CreateSwapChain(mDevice, &swapChainDesc, &mSwapChain);
+ SafeRelease(dxgiFactory);
+ if (FAILED(result))
+ {
+ return egl::Error(EGL_BAD_ALLOC, "Failed to create swap chain for window, result: 0x%X",
+ result);
+ }
+ }
+
+ ID3D11Texture2D *colorBuffer = nullptr;
+ result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D),
+ reinterpret_cast<void **>(&colorBuffer));
+ if (FAILED(result))
+ {
+ return egl::Error(EGL_BAD_ALLOC, "Failed to query texture from swap chain, result: 0x%X",
+ result);
+ }
+
+ mFunctionsGL->genRenderbuffers(1, &mColorRenderbufferID);
+ mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mColorRenderbufferID);
+ mRenderbufferBufferHandle =
+ mFunctionsWGL->dxRegisterObjectNV(mDeviceHandle, colorBuffer, mColorRenderbufferID,
+ GL_RENDERBUFFER, WGL_ACCESS_READ_WRITE_NV);
+ SafeRelease(colorBuffer);
+ if (mRenderbufferBufferHandle == nullptr)
+ {
+ return egl::Error(EGL_BAD_ALLOC, "Failed to register D3D object, error: 0x%X.",
+ HRESULT_CODE(GetLastError()));
+ }
+
+ // Rebind the surface to the texture if needed.
+ if (hadBoundSurface)
+ {
+ mTextureHandle = mFunctionsWGL->dxRegisterObjectNV(mDeviceHandle, colorBuffer, mTextureID,
+ GL_TEXTURE_2D, WGL_ACCESS_READ_WRITE_NV);
+ if (mTextureHandle == nullptr)
+ {
+ return egl::Error(EGL_BAD_ALLOC, "Failed to register D3D object, error: 0x%X.",
+ HRESULT_CODE(GetLastError()));
+ }
+ }
+
+ error = setObjectsLocked(true);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ASSERT(mFramebufferID != 0);
+ mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
+ mFunctionsGL->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
+ mColorRenderbufferID);
+
+ if (mDepthBufferFormat != GL_NONE)
+ {
+ ASSERT(mDepthRenderbufferID != 0);
+ mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mDepthRenderbufferID);
+ mFunctionsGL->renderbufferStorage(GL_RENDERBUFFER, mDepthBufferFormat,
+ static_cast<GLsizei>(mWidth),
+ static_cast<GLsizei>(mHeight));
+
+ const gl::InternalFormat &depthStencilFormatInfo =
+ gl::GetInternalFormatInfo(mDepthBufferFormat);
+ if (depthStencilFormatInfo.depthBits > 0)
+ {
+ mFunctionsGL->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER, mDepthRenderbufferID);
+ }
+ if (depthStencilFormatInfo.stencilBits > 0)
+ {
+ mFunctionsGL->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, mDepthRenderbufferID);
+ }
+ }
+
+ mFirstSwap = true;
+
+ return egl::Error(EGL_SUCCESS);
+}
+} // namespace rx
diff --git a/gfx/angle/src/libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.h b/gfx/angle/src/libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.h
new file mode 100755
index 000000000..f516239c9
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.h
@@ -0,0 +1,106 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// DXGISwapChainWindowSurfaceWGL.h: WGL implementation of egl::Surface for windows using a DXGI
+// swapchain.
+
+#ifndef LIBANGLE_RENDERER_GL_WGL_DXGISWAPCHAINSURFACEWGL_H_
+#define LIBANGLE_RENDERER_GL_WGL_DXGISWAPCHAINSURFACEWGL_H_
+
+#include "libANGLE/renderer/gl/SurfaceGL.h"
+
+#include <GL/wglext.h>
+
+namespace rx
+{
+
+class FunctionsGL;
+class FunctionsWGL;
+class DisplayWGL;
+class StateManagerGL;
+struct WorkaroundsGL;
+
+class DXGISwapChainWindowSurfaceWGL : public SurfaceGL
+{
+ public:
+ DXGISwapChainWindowSurfaceWGL(const egl::SurfaceState &state,
+ RendererGL *renderer,
+ EGLNativeWindowType window,
+ ID3D11Device *device,
+ HANDLE deviceHandle,
+ HGLRC wglContext,
+ HDC deviceContext,
+ const FunctionsGL *functionsGL,
+ const FunctionsWGL *functionsWGL,
+ EGLint orientation);
+ ~DXGISwapChainWindowSurfaceWGL() override;
+
+ egl::Error initialize() override;
+ egl::Error makeCurrent() override;
+
+ egl::Error swap() override;
+ egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override;
+ egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override;
+ egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) override;
+ egl::Error releaseTexImage(EGLint buffer) override;
+ void setSwapInterval(EGLint interval) override;
+
+ EGLint getWidth() const override;
+ EGLint getHeight() const override;
+
+ EGLint isPostSubBufferSupported() const override;
+ EGLint getSwapBehavior() const override;
+
+ FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &data) override;
+
+ private:
+ egl::Error setObjectsLocked(bool locked);
+ egl::Error checkForResize();
+
+ egl::Error createSwapChain();
+
+ EGLNativeWindowType mWindow;
+
+ StateManagerGL *mStateManager;
+ const WorkaroundsGL &mWorkarounds;
+ RendererGL *mRenderer;
+ const FunctionsGL *mFunctionsGL;
+ const FunctionsWGL *mFunctionsWGL;
+
+ ID3D11Device *mDevice;
+ HANDLE mDeviceHandle;
+
+ HDC mWGLDevice;
+ HGLRC mWGLContext;
+
+ DXGI_FORMAT mSwapChainFormat;
+ UINT mSwapChainFlags;
+ GLenum mDepthBufferFormat;
+
+ bool mFirstSwap;
+ IDXGISwapChain *mSwapChain;
+ IDXGISwapChain1 *mSwapChain1;
+
+ GLuint mColorRenderbufferID;
+ HANDLE mRenderbufferBufferHandle;
+
+ GLuint mDepthRenderbufferID;
+
+ GLuint mFramebufferID;
+
+ GLuint mTextureID;
+ HANDLE mTextureHandle;
+
+ size_t mWidth;
+ size_t mHeight;
+
+ EGLint mSwapInterval;
+
+ EGLint mOrientation;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_GL_WGL_DXGISWAPCHAINSURFACEWGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/wgl/DisplayWGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/wgl/DisplayWGL.cpp
new file mode 100755
index 000000000..188321115
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/wgl/DisplayWGL.cpp
@@ -0,0 +1,741 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// DisplayWGL.h: WGL implementation of egl::Display
+
+#include "libANGLE/renderer/gl/wgl/DisplayWGL.h"
+
+#include "common/debug.h"
+#include "libANGLE/Config.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/renderer/gl/RendererGL.h"
+#include "libANGLE/renderer/gl/renderergl_utils.h"
+#include "libANGLE/renderer/gl/wgl/D3DTextureSurfaceWGL.h"
+#include "libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.h"
+#include "libANGLE/renderer/gl/wgl/FunctionsWGL.h"
+#include "libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.h"
+#include "libANGLE/renderer/gl/wgl/WindowSurfaceWGL.h"
+#include "libANGLE/renderer/gl/wgl/wgl_utils.h"
+
+#include "platform/Platform.h"
+
+#include <EGL/eglext.h>
+#include <string>
+#include <sstream>
+
+namespace rx
+{
+
+class FunctionsGLWindows : public FunctionsGL
+{
+ public:
+ FunctionsGLWindows(HMODULE openGLModule, PFNWGLGETPROCADDRESSPROC getProcAddressWGL)
+ : mOpenGLModule(openGLModule),
+ mGetProcAddressWGL(getProcAddressWGL)
+ {
+ ASSERT(mOpenGLModule);
+ ASSERT(mGetProcAddressWGL);
+ }
+
+ ~FunctionsGLWindows() override {}
+
+ private:
+ void *loadProcAddress(const std::string &function) override
+ {
+ void *proc = reinterpret_cast<void*>(mGetProcAddressWGL(function.c_str()));
+ if (!proc)
+ {
+ proc = reinterpret_cast<void*>(GetProcAddress(mOpenGLModule, function.c_str()));
+ }
+ return proc;
+ }
+
+ HMODULE mOpenGLModule;
+ PFNWGLGETPROCADDRESSPROC mGetProcAddressWGL;
+};
+
+DisplayWGL::DisplayWGL()
+ : DisplayGL(),
+ mOpenGLModule(nullptr),
+ mFunctionsWGL(nullptr),
+ mFunctionsGL(nullptr),
+ mHasRobustness(false),
+ mWindowClass(0),
+ mWindow(nullptr),
+ mDeviceContext(nullptr),
+ mPixelFormat(0),
+ mWGLContext(nullptr),
+ mUseDXGISwapChains(false),
+ mDxgiModule(nullptr),
+ mD3d11Module(nullptr),
+ mD3D11DeviceHandle(nullptr),
+ mD3D11Device(nullptr),
+ mDisplay(nullptr)
+{
+}
+
+DisplayWGL::~DisplayWGL()
+{
+}
+
+egl::Error DisplayWGL::initialize(egl::Display *display)
+{
+ mDisplay = display;
+
+ mOpenGLModule = LoadLibraryA("opengl32.dll");
+ if (!mOpenGLModule)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Failed to load OpenGL library.");
+ }
+
+ mFunctionsWGL = new FunctionsWGL();
+ mFunctionsWGL->initialize(mOpenGLModule, nullptr);
+
+ // WGL can't grab extensions until it creates a context because it needs to load the driver's DLLs first.
+ // Create a dummy context to load the driver and determine which GL versions are available.
+
+ // Work around compile error from not defining "UNICODE" while Chromium does
+ const LPSTR idcArrow = MAKEINTRESOURCEA(32512);
+
+ std::string className = FormatString("ANGLE DisplayWGL 0x%0.8p Intermediate Window Class", mDisplay);
+
+ WNDCLASSA intermediateClassDesc = { 0 };
+ intermediateClassDesc.style = CS_OWNDC;
+ intermediateClassDesc.lpfnWndProc = DefWindowProc;
+ intermediateClassDesc.cbClsExtra = 0;
+ intermediateClassDesc.cbWndExtra = 0;
+ intermediateClassDesc.hInstance = GetModuleHandle(nullptr);
+ intermediateClassDesc.hIcon = nullptr;
+ intermediateClassDesc.hCursor = LoadCursorA(nullptr, idcArrow);
+ intermediateClassDesc.hbrBackground = 0;
+ intermediateClassDesc.lpszMenuName = nullptr;
+ intermediateClassDesc.lpszClassName = className.c_str();
+ mWindowClass = RegisterClassA(&intermediateClassDesc);
+ if (!mWindowClass)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Failed to register intermediate OpenGL window class.");
+ }
+
+ HWND dummyWindow = CreateWindowExA(0,
+ reinterpret_cast<const char *>(mWindowClass),
+ "ANGLE Dummy Window",
+ WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr);
+ if (!dummyWindow)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Failed to create dummy OpenGL window.");
+ }
+
+ HDC dummyDeviceContext = GetDC(dummyWindow);
+ if (!dummyDeviceContext)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Failed to get the device context of the dummy OpenGL window.");
+ }
+
+ const PIXELFORMATDESCRIPTOR pixelFormatDescriptor = wgl::GetDefaultPixelFormatDescriptor();
+
+ int dummyPixelFormat = ChoosePixelFormat(dummyDeviceContext, &pixelFormatDescriptor);
+ if (dummyPixelFormat == 0)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Could not find a compatible pixel format for the dummy OpenGL window.");
+ }
+
+ if (!SetPixelFormat(dummyDeviceContext, dummyPixelFormat, &pixelFormatDescriptor))
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Failed to set the pixel format on the intermediate OpenGL window.");
+ }
+
+ HGLRC dummyWGLContext = mFunctionsWGL->createContext(dummyDeviceContext);
+ if (!dummyDeviceContext)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Failed to create a WGL context for the dummy OpenGL window.");
+ }
+
+ if (!mFunctionsWGL->makeCurrent(dummyDeviceContext, dummyWGLContext))
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Failed to make the dummy WGL context current.");
+ }
+
+ // Grab the GL version from this context and use it as the maximum version available.
+ typedef const GLubyte* (GL_APIENTRYP PFNGLGETSTRINGPROC) (GLenum name);
+ PFNGLGETSTRINGPROC getString = reinterpret_cast<PFNGLGETSTRINGPROC>(GetProcAddress(mOpenGLModule, "glGetString"));
+ if (!getString)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Failed to get glGetString pointer.");
+ }
+
+ // Reinitialize the wgl functions to grab the extensions
+ mFunctionsWGL->initialize(mOpenGLModule, dummyDeviceContext);
+
+ bool hasWGLCreateContextRobustness =
+ mFunctionsWGL->hasExtension("WGL_ARB_create_context_robustness");
+
+ // Destroy the dummy window and context
+ mFunctionsWGL->makeCurrent(dummyDeviceContext, nullptr);
+ mFunctionsWGL->deleteContext(dummyWGLContext);
+ ReleaseDC(dummyWindow, dummyDeviceContext);
+ DestroyWindow(dummyWindow);
+
+ const egl::AttributeMap &displayAttributes = display->getAttributeMap();
+ EGLint requestedDisplayType = static_cast<EGLint>(displayAttributes.get(
+ EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE));
+ if (requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE &&
+ !mFunctionsWGL->hasExtension("WGL_EXT_create_context_es2_profile") &&
+ !mFunctionsWGL->hasExtension("WGL_EXT_create_context_es_profile"))
+ {
+ return egl::Error(EGL_NOT_INITIALIZED,
+ "Cannot create an OpenGL ES platform on Windows without "
+ "the WGL_EXT_create_context_es(2)_profile extension.");
+ }
+
+ // Create the real intermediate context and windows
+ mWindow = CreateWindowExA(0,
+ reinterpret_cast<const char *>(mWindowClass),
+ "ANGLE Intermediate Window",
+ WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr);
+ if (!mWindow)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Failed to create intermediate OpenGL window.");
+ }
+
+ mDeviceContext = GetDC(mWindow);
+ if (!mDeviceContext)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Failed to get the device context of the intermediate OpenGL window.");
+ }
+
+ if (mFunctionsWGL->choosePixelFormatARB)
+ {
+ std::vector<int> attribs = wgl::GetDefaultPixelFormatAttributes(false);
+
+ UINT matchingFormats = 0;
+ mFunctionsWGL->choosePixelFormatARB(mDeviceContext, &attribs[0], nullptr, 1u, &mPixelFormat,
+ &matchingFormats);
+ }
+
+ if (mPixelFormat == 0)
+ {
+ mPixelFormat = ChoosePixelFormat(mDeviceContext, &pixelFormatDescriptor);
+ }
+
+ if (mPixelFormat == 0)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Could not find a compatible pixel format for the intermediate OpenGL window.");
+ }
+
+ if (!SetPixelFormat(mDeviceContext, mPixelFormat, &pixelFormatDescriptor))
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Failed to set the pixel format on the intermediate OpenGL window.");
+ }
+
+ if (mFunctionsWGL->createContextAttribsARB)
+ {
+ int flags = 0;
+ // TODO: allow debug contexts
+ // TODO: handle robustness
+
+ int mask = 0;
+
+ if (requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
+ {
+ mask |= WGL_CONTEXT_ES_PROFILE_BIT_EXT;
+ }
+ else
+ {
+ // Request core profile
+ mask |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
+ }
+
+ std::vector<int> contextCreationAttributes;
+
+ if (hasWGLCreateContextRobustness)
+ {
+ contextCreationAttributes.push_back(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB);
+ contextCreationAttributes.push_back(WGL_LOSE_CONTEXT_ON_RESET_ARB);
+ }
+
+ // Don't request a specific version unless the user wants one. WGL will return the highest version
+ // that the driver supports if no version is requested.
+ EGLint requestedMajorVersion = static_cast<EGLint>(
+ displayAttributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, EGL_DONT_CARE));
+ EGLint requestedMinorVersion = static_cast<EGLint>(
+ displayAttributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, EGL_DONT_CARE));
+ if (requestedMajorVersion != EGL_DONT_CARE && requestedMinorVersion != EGL_DONT_CARE)
+ {
+ contextCreationAttributes.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB);
+ contextCreationAttributes.push_back(requestedMajorVersion);
+
+ contextCreationAttributes.push_back(WGL_CONTEXT_MINOR_VERSION_ARB);
+ contextCreationAttributes.push_back(requestedMinorVersion);
+ }
+ else
+ {
+ // the ES profile will give us ES version 1.1 unless a higher version is requested.
+ // Requesting version 2.0 will give us the highest compatible version available (2.0,
+ // 3.0, 3.1, etc).
+ if (requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
+ {
+ contextCreationAttributes.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB);
+ contextCreationAttributes.push_back(2);
+
+ contextCreationAttributes.push_back(WGL_CONTEXT_MINOR_VERSION_ARB);
+ contextCreationAttributes.push_back(0);
+ }
+ }
+
+ // Set the flag attributes
+ if (flags != 0)
+ {
+ contextCreationAttributes.push_back(WGL_CONTEXT_FLAGS_ARB);
+ contextCreationAttributes.push_back(flags);
+ }
+
+ // Set the mask attribute
+ if (mask != 0)
+ {
+ contextCreationAttributes.push_back(WGL_CONTEXT_PROFILE_MASK_ARB);
+ contextCreationAttributes.push_back(mask);
+ }
+
+ // Signal the end of the attributes
+ contextCreationAttributes.push_back(0);
+ contextCreationAttributes.push_back(0);
+
+ mWGLContext = mFunctionsWGL->createContextAttribsARB(mDeviceContext, NULL, &contextCreationAttributes[0]);
+ }
+
+ // If wglCreateContextAttribsARB is unavailable or failed, try the standard wglCreateContext
+ if (!mWGLContext)
+ {
+ // Don't have control over GL versions
+ mWGLContext = mFunctionsWGL->createContext(mDeviceContext);
+ }
+
+ if (!mWGLContext)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Failed to create a WGL context for the intermediate OpenGL window.");
+ }
+
+ if (!mFunctionsWGL->makeCurrent(mDeviceContext, mWGLContext))
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Failed to make the intermediate WGL context current.");
+ }
+
+ mFunctionsGL = new FunctionsGLWindows(mOpenGLModule, mFunctionsWGL->getProcAddress);
+ mFunctionsGL->initialize();
+
+ mHasRobustness = mFunctionsGL->getGraphicsResetStatus != nullptr;
+ if (hasWGLCreateContextRobustness != mHasRobustness)
+ {
+ ANGLEPlatformCurrent()->logWarning(
+ "WGL_ARB_create_context_robustness exists but unable to OpenGL context with "
+ "robustness.");
+ }
+
+ // Intel OpenGL ES drivers are not currently supported due to bugs in the driver and ANGLE
+ VendorID vendor = GetVendorID(mFunctionsGL);
+ if (requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE && IsIntel(vendor))
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Intel OpenGL ES drivers are not supported.");
+ }
+
+ // Create DXGI swap chains for windows that come from other processes. Windows is unable to
+ // SetPixelFormat on windows from other processes when a sandbox is enabled.
+ HDC nativeDisplay = display->getNativeDisplayId();
+ HWND nativeWindow = WindowFromDC(nativeDisplay);
+ if (nativeWindow != nullptr)
+ {
+ DWORD currentProcessId = GetCurrentProcessId();
+ DWORD windowProcessId;
+ GetWindowThreadProcessId(nativeWindow, &windowProcessId);
+
+ // AMD drivers advertise the WGL_NV_DX_interop and WGL_NV_DX_interop2 extensions but fail
+ mUseDXGISwapChains = !IsAMD(vendor) && (currentProcessId != windowProcessId);
+ }
+ else
+ {
+ mUseDXGISwapChains = false;
+ }
+
+ if (mUseDXGISwapChains)
+ {
+ egl::Error error = initializeD3DDevice();
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ return DisplayGL::initialize(display);
+}
+
+void DisplayWGL::terminate()
+{
+ DisplayGL::terminate();
+
+ releaseD3DDevice(mD3D11DeviceHandle);
+
+ mFunctionsWGL->makeCurrent(mDeviceContext, NULL);
+ mFunctionsWGL->deleteContext(mWGLContext);
+ mWGLContext = NULL;
+
+ ReleaseDC(mWindow, mDeviceContext);
+ mDeviceContext = NULL;
+
+ DestroyWindow(mWindow);
+ mWindow = NULL;
+
+ UnregisterClassA(reinterpret_cast<const char*>(mWindowClass), NULL);
+ mWindowClass = NULL;
+
+ SafeDelete(mFunctionsWGL);
+ SafeDelete(mFunctionsGL);
+
+ FreeLibrary(mOpenGLModule);
+ mOpenGLModule = nullptr;
+
+ SafeRelease(mD3D11Device);
+
+ if (mDxgiModule)
+ {
+ FreeLibrary(mDxgiModule);
+ mDxgiModule = nullptr;
+ }
+
+ if (mD3d11Module)
+ {
+ FreeLibrary(mD3d11Module);
+ mD3d11Module = nullptr;
+ }
+
+ ASSERT(mRegisteredD3DDevices.empty());
+}
+
+SurfaceImpl *DisplayWGL::createWindowSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLNativeWindowType window,
+ const egl::AttributeMap &attribs)
+{
+ EGLint orientation = static_cast<EGLint>(attribs.get(EGL_SURFACE_ORIENTATION_ANGLE, 0));
+ if (mUseDXGISwapChains)
+ {
+ return new DXGISwapChainWindowSurfaceWGL(state, getRenderer(), window, mD3D11Device,
+ mD3D11DeviceHandle, mWGLContext, mDeviceContext,
+ mFunctionsGL, mFunctionsWGL, orientation);
+ }
+ else
+ {
+ return new WindowSurfaceWGL(state, getRenderer(), window, mPixelFormat, mWGLContext,
+ mFunctionsWGL, orientation);
+ }
+}
+
+SurfaceImpl *DisplayWGL::createPbufferSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ const egl::AttributeMap &attribs)
+{
+ EGLint width = static_cast<EGLint>(attribs.get(EGL_WIDTH, 0));
+ EGLint height = static_cast<EGLint>(attribs.get(EGL_HEIGHT, 0));
+ bool largest = (attribs.get(EGL_LARGEST_PBUFFER, EGL_FALSE) == EGL_TRUE);
+ EGLenum textureFormat = static_cast<EGLenum>(attribs.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE));
+ EGLenum textureTarget = static_cast<EGLenum>(attribs.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE));
+
+ return new PbufferSurfaceWGL(state, getRenderer(), width, height, textureFormat, textureTarget,
+ largest, mPixelFormat, mDeviceContext, mWGLContext, mFunctionsWGL);
+}
+
+SurfaceImpl *DisplayWGL::createPbufferFromClientBuffer(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs)
+{
+ ASSERT(buftype == EGL_D3D_TEXTURE_ANGLE);
+ return new D3DTextureSurfaceWGL(state, getRenderer(), clientBuffer, this, mWGLContext,
+ mDeviceContext, mFunctionsGL, mFunctionsWGL);
+}
+
+SurfaceImpl *DisplayWGL::createPixmapSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ NativePixmapType nativePixmap,
+ const egl::AttributeMap &attribs)
+{
+ UNIMPLEMENTED();
+ return nullptr;
+}
+
+egl::Error DisplayWGL::getDevice(DeviceImpl **device)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_BAD_DISPLAY);
+}
+
+egl::ConfigSet DisplayWGL::generateConfigs()
+{
+ egl::ConfigSet configs;
+
+ int minSwapInterval = 1;
+ int maxSwapInterval = 1;
+ if (mFunctionsWGL->swapIntervalEXT)
+ {
+ // No defined maximum swap interval in WGL_EXT_swap_control, use a reasonable number
+ minSwapInterval = 0;
+ maxSwapInterval = 8;
+ }
+
+ const gl::Version &maxVersion = getMaxSupportedESVersion();
+ ASSERT(maxVersion >= gl::Version(2, 0));
+ bool supportsES3 = maxVersion >= gl::Version(3, 0);
+
+ PIXELFORMATDESCRIPTOR pixelFormatDescriptor;
+ DescribePixelFormat(mDeviceContext, mPixelFormat, sizeof(pixelFormatDescriptor), &pixelFormatDescriptor);
+
+ auto getAttrib = [this](int attrib)
+ {
+ return wgl::QueryWGLFormatAttrib(mDeviceContext, mPixelFormat, attrib, mFunctionsWGL);
+ };
+
+ const EGLint optimalSurfaceOrientation =
+ mUseDXGISwapChains ? EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE : 0;
+
+ egl::Config config;
+ config.renderTargetFormat = GL_RGBA8; // TODO: use the bit counts to determine the format
+ config.depthStencilFormat = GL_DEPTH24_STENCIL8; // TODO: use the bit counts to determine the format
+ config.bufferSize = pixelFormatDescriptor.cColorBits;
+ config.redSize = pixelFormatDescriptor.cRedBits;
+ config.greenSize = pixelFormatDescriptor.cGreenBits;
+ config.blueSize = pixelFormatDescriptor.cBlueBits;
+ config.luminanceSize = 0;
+ config.alphaSize = pixelFormatDescriptor.cAlphaBits;
+ config.alphaMaskSize = 0;
+ config.bindToTextureRGB = (getAttrib(WGL_BIND_TO_TEXTURE_RGB_ARB) == TRUE);
+ config.bindToTextureRGBA = (getAttrib(WGL_BIND_TO_TEXTURE_RGBA_ARB) == TRUE);
+ config.colorBufferType = EGL_RGB_BUFFER;
+ config.configCaveat = EGL_NONE;
+ config.conformant = EGL_OPENGL_ES2_BIT | (supportsES3 ? EGL_OPENGL_ES3_BIT_KHR : 0);
+ config.depthSize = pixelFormatDescriptor.cDepthBits;
+ config.level = 0;
+ config.matchNativePixmap = EGL_NONE;
+ config.maxPBufferWidth = getAttrib(WGL_MAX_PBUFFER_WIDTH_ARB);
+ config.maxPBufferHeight = getAttrib(WGL_MAX_PBUFFER_HEIGHT_ARB);
+ config.maxPBufferPixels = getAttrib(WGL_MAX_PBUFFER_PIXELS_ARB);
+ config.maxSwapInterval = maxSwapInterval;
+ config.minSwapInterval = minSwapInterval;
+ config.nativeRenderable = EGL_TRUE; // Direct rendering
+ config.nativeVisualID = 0;
+ config.nativeVisualType = EGL_NONE;
+ config.renderableType = EGL_OPENGL_ES2_BIT | (supportsES3 ? EGL_OPENGL_ES3_BIT_KHR : 0);
+ config.sampleBuffers = 0; // FIXME: enumerate multi-sampling
+ config.samples = 0;
+ config.stencilSize = pixelFormatDescriptor.cStencilBits;
+ config.surfaceType =
+ ((pixelFormatDescriptor.dwFlags & PFD_DRAW_TO_WINDOW) ? EGL_WINDOW_BIT : 0) |
+ ((getAttrib(WGL_DRAW_TO_PBUFFER_ARB) == TRUE) ? EGL_PBUFFER_BIT : 0) |
+ ((getAttrib(WGL_SWAP_METHOD_ARB) == WGL_SWAP_COPY_ARB) ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT
+ : 0);
+ config.optimalOrientation = optimalSurfaceOrientation;
+
+ config.transparentType = EGL_NONE;
+ config.transparentRedValue = 0;
+ config.transparentGreenValue = 0;
+ config.transparentBlueValue = 0;
+
+ configs.add(config);
+
+ return configs;
+}
+
+bool DisplayWGL::testDeviceLost()
+{
+ if (mHasRobustness)
+ {
+ return getRenderer()->getResetStatus() != GL_NO_ERROR;
+ }
+
+ return false;
+}
+
+egl::Error DisplayWGL::restoreLostDevice()
+{
+ return egl::Error(EGL_BAD_DISPLAY);
+}
+
+bool DisplayWGL::isValidNativeWindow(EGLNativeWindowType window) const
+{
+ return (IsWindow(window) == TRUE);
+}
+
+egl::Error DisplayWGL::validateClientBuffer(const egl::Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs) const
+{
+ switch (buftype)
+ {
+ case EGL_D3D_TEXTURE_ANGLE:
+ return D3DTextureSurfaceWGL::ValidateD3DTextureClientBuffer(clientBuffer);
+
+ default:
+ return DisplayGL::validateClientBuffer(configuration, buftype, clientBuffer, attribs);
+ }
+}
+
+std::string DisplayWGL::getVendorString() const
+{
+ //UNIMPLEMENTED();
+ return "";
+}
+
+const FunctionsGL *DisplayWGL::getFunctionsGL() const
+{
+ return mFunctionsGL;
+}
+
+egl::Error DisplayWGL::initializeD3DDevice()
+{
+ if (mD3D11Device != nullptr)
+ {
+ return egl::Error(EGL_SUCCESS);
+ }
+
+ mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
+ if (!mDxgiModule)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Failed to load DXGI library.");
+ }
+
+ mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
+ if (!mD3d11Module)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Failed to load d3d11 library.");
+ }
+
+ PFN_D3D11_CREATE_DEVICE d3d11CreateDevice = nullptr;
+ d3d11CreateDevice = reinterpret_cast<PFN_D3D11_CREATE_DEVICE>(
+ GetProcAddress(mD3d11Module, "D3D11CreateDevice"));
+ if (d3d11CreateDevice == nullptr)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Could not retrieve D3D11CreateDevice address.");
+ }
+
+ HRESULT result = d3d11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, 0,
+ D3D11_SDK_VERSION, &mD3D11Device, nullptr, nullptr);
+ if (FAILED(result))
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Could not create D3D11 device, error: 0x%X",
+ result);
+ }
+
+ egl::Error error = registerD3DDevice(mD3D11Device, &mD3D11DeviceHandle);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+void DisplayWGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
+{
+ // Only enable the surface orientation and post sub buffer for DXGI swap chain surfaces, they
+ // prefer to swap with inverted Y.
+ outExtensions->postSubBuffer = mUseDXGISwapChains;
+ outExtensions->surfaceOrientation = mUseDXGISwapChains;
+
+ outExtensions->createContextRobustness = mHasRobustness;
+
+ outExtensions->d3dTextureClientBuffer = mFunctionsWGL->hasExtension("WGL_NV_DX_interop2");
+}
+
+void DisplayWGL::generateCaps(egl::Caps *outCaps) const
+{
+ outCaps->textureNPOT = true;
+}
+
+egl::Error DisplayWGL::waitClient() const
+{
+ // Unimplemented as this is not needed for WGL
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DisplayWGL::waitNative(EGLint engine,
+ egl::Surface *drawSurface,
+ egl::Surface *readSurface) const
+{
+ // Unimplemented as this is not needed for WGL
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DisplayWGL::getDriverVersion(std::string *version) const
+{
+ *version = "";
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DisplayWGL::registerD3DDevice(IUnknown *device, HANDLE *outHandle)
+{
+ ASSERT(device != nullptr);
+ ASSERT(outHandle != nullptr);
+
+ auto iter = mRegisteredD3DDevices.find(device);
+ if (iter != mRegisteredD3DDevices.end())
+ {
+ iter->second.refCount++;
+ *outHandle = iter->second.handle;
+ return egl::Error(EGL_SUCCESS);
+ }
+
+ HANDLE handle = mFunctionsWGL->dxOpenDeviceNV(device);
+ if (!handle)
+ {
+ return egl::Error(EGL_BAD_PARAMETER, "Failed to open D3D device.");
+ }
+
+ device->AddRef();
+
+ D3DObjectHandle newDeviceInfo;
+ newDeviceInfo.handle = handle;
+ newDeviceInfo.refCount = 1;
+ mRegisteredD3DDevices[device] = newDeviceInfo;
+
+ *outHandle = handle;
+ return egl::Error(EGL_SUCCESS);
+}
+
+void DisplayWGL::releaseD3DDevice(HANDLE deviceHandle)
+{
+ for (auto iter = mRegisteredD3DDevices.begin(); iter != mRegisteredD3DDevices.end(); iter++)
+ {
+ if (iter->second.handle == deviceHandle)
+ {
+ iter->second.refCount--;
+ if (iter->second.refCount == 0)
+ {
+ mFunctionsWGL->dxCloseDeviceNV(iter->second.handle);
+ iter->first->Release();
+ mRegisteredD3DDevices.erase(iter);
+ break;
+ }
+ }
+ }
+}
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/wgl/DisplayWGL.h b/gfx/angle/src/libANGLE/renderer/gl/wgl/DisplayWGL.h
new file mode 100755
index 000000000..509ea9b39
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/wgl/DisplayWGL.h
@@ -0,0 +1,112 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// DisplayWGL.h: WGL implementation of egl::Display
+
+#ifndef LIBANGLE_RENDERER_GL_WGL_DISPLAYWGL_H_
+#define LIBANGLE_RENDERER_GL_WGL_DISPLAYWGL_H_
+
+#include "libANGLE/renderer/gl/DisplayGL.h"
+
+#include <GL/wglext.h>
+
+namespace rx
+{
+
+class FunctionsWGL;
+
+class DisplayWGL : public DisplayGL
+{
+ public:
+ DisplayWGL();
+ ~DisplayWGL() override;
+
+ egl::Error initialize(egl::Display *display) override;
+ void terminate() override;
+
+ // Surface creation
+ SurfaceImpl *createWindowSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLNativeWindowType window,
+ const egl::AttributeMap &attribs) override;
+ SurfaceImpl *createPbufferSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ const egl::AttributeMap &attribs) override;
+ SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs) override;
+ SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ NativePixmapType nativePixmap,
+ const egl::AttributeMap &attribs) override;
+
+ egl::ConfigSet generateConfigs() override;
+
+ bool testDeviceLost() override;
+ egl::Error restoreLostDevice() override;
+
+ bool isValidNativeWindow(EGLNativeWindowType window) const override;
+ egl::Error validateClientBuffer(const egl::Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs) const override;
+
+ egl::Error getDevice(DeviceImpl **device) override;
+
+ std::string getVendorString() const override;
+
+ egl::Error waitClient() const override;
+ egl::Error waitNative(EGLint engine,
+ egl::Surface *drawSurface,
+ egl::Surface *readSurface) const override;
+
+ egl::Error getDriverVersion(std::string *version) const override;
+
+ egl::Error registerD3DDevice(IUnknown *device, HANDLE *outHandle);
+ void releaseD3DDevice(HANDLE handle);
+
+ private:
+ const FunctionsGL *getFunctionsGL() const override;
+
+ egl::Error initializeD3DDevice();
+
+ void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
+ void generateCaps(egl::Caps *outCaps) const override;
+
+ HMODULE mOpenGLModule;
+
+ FunctionsWGL *mFunctionsWGL;
+ FunctionsGL *mFunctionsGL;
+
+ bool mHasRobustness;
+
+ ATOM mWindowClass;
+ HWND mWindow;
+ HDC mDeviceContext;
+ int mPixelFormat;
+ HGLRC mWGLContext;
+
+ bool mUseDXGISwapChains;
+ HMODULE mDxgiModule;
+ HMODULE mD3d11Module;
+ HANDLE mD3D11DeviceHandle;
+ ID3D11Device *mD3D11Device;
+
+ struct D3DObjectHandle
+ {
+ HANDLE handle;
+ size_t refCount;
+ };
+ std::map<IUnknown *, D3DObjectHandle> mRegisteredD3DDevices;
+
+ egl::Display *mDisplay;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_WGL_DISPLAYWGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/wgl/FunctionsWGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/wgl/FunctionsWGL.cpp
new file mode 100755
index 000000000..2cfe6e9eb
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/wgl/FunctionsWGL.cpp
@@ -0,0 +1,181 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FunctionsWGL.h: Implements the FuntionsWGL class.
+
+#include "libANGLE/renderer/gl/wgl/FunctionsWGL.h"
+
+#include <algorithm>
+
+#include "common/string_utils.h"
+
+namespace rx
+{
+
+template <typename T>
+static void GetWGLProcAddress(HMODULE glModule, PFNWGLGETPROCADDRESSPROC getProcAddressWGL,
+ const std::string &procName, T *outProcAddress)
+{
+ T proc = nullptr;
+ if (getProcAddressWGL)
+ {
+ proc = reinterpret_cast<T>(getProcAddressWGL(procName.c_str()));
+ }
+
+ if (!proc)
+ {
+ proc = reinterpret_cast<T>(GetProcAddress(glModule, procName.c_str()));
+ }
+
+ *outProcAddress = proc;
+}
+
+template <typename T>
+static void GetWGLExtensionProcAddress(HMODULE glModule,
+ PFNWGLGETPROCADDRESSPROC getProcAddressWGL,
+ const std::vector<std::string> &extensions,
+ const std::string &extensionName,
+ const std::string &procName,
+ T *outProcAddress)
+{
+ T proc = nullptr;
+ if (std::find(extensions.begin(), extensions.end(), extensionName) != extensions.end())
+ {
+ GetWGLProcAddress(glModule, getProcAddressWGL, procName, &proc);
+ }
+
+ *outProcAddress = proc;
+}
+
+FunctionsWGL::FunctionsWGL()
+ : copyContext(nullptr),
+ createContext(nullptr),
+ createLayerContext(nullptr),
+ deleteContext(nullptr),
+ getCurrentContext(nullptr),
+ getCurrentDC(nullptr),
+ getProcAddress(nullptr),
+ makeCurrent(nullptr),
+ shareLists(nullptr),
+ useFontBitmapsA(nullptr),
+ useFontBitmapsW(nullptr),
+ swapBuffers(nullptr),
+ useFontOutlinesA(nullptr),
+ useFontOutlinesW(nullptr),
+ describeLayerPlane(nullptr),
+ setLayerPaletteEntries(nullptr),
+ getLayerPaletteEntries(nullptr),
+ realizeLayerPalette(nullptr),
+ swapLayerBuffers(nullptr),
+ swapMultipleBuffers(nullptr),
+ getExtensionStringEXT(nullptr),
+ getExtensionStringARB(nullptr),
+ createContextAttribsARB(nullptr),
+ getPixelFormatAttribivARB(nullptr),
+ getPixelFormatAttribfvARB(nullptr),
+ choosePixelFormatARB(nullptr),
+ swapIntervalEXT(nullptr),
+ createPbufferARB(nullptr),
+ getPbufferDCARB(nullptr),
+ releasePbufferDCARB(nullptr),
+ destroyPbufferARB(nullptr),
+ queryPbufferARB(nullptr),
+ bindTexImageARB(nullptr),
+ releaseTexImageARB(nullptr),
+ setPbufferAttribARB(nullptr),
+ dxSetResourceShareHandleNV(nullptr),
+ dxOpenDeviceNV(nullptr),
+ dxCloseDeviceNV(nullptr),
+ dxRegisterObjectNV(nullptr),
+ dxUnregisterObjectNV(nullptr),
+ dxObjectAccessNV(nullptr),
+ dxLockObjectsNV(nullptr),
+ dxUnlockObjectsNV(nullptr)
+{
+}
+
+void FunctionsWGL::initialize(HMODULE glModule, HDC context)
+{
+ // First grab the wglGetProcAddress function from the gl module
+ GetWGLProcAddress(glModule, nullptr, "wglGetProcAddress", &getProcAddress);
+
+ // Load the core wgl functions
+ GetWGLProcAddress(glModule, getProcAddress, "wglCopyContext", &copyContext);
+ GetWGLProcAddress(glModule, getProcAddress, "wglCreateContext", &createContext);
+ GetWGLProcAddress(glModule, getProcAddress, "wglCreateLayerContext", &createLayerContext);
+ GetWGLProcAddress(glModule, getProcAddress, "wglDeleteContext", &deleteContext);
+ GetWGLProcAddress(glModule, getProcAddress, "wglGetCurrentContext", &getCurrentContext);
+ GetWGLProcAddress(glModule, getProcAddress, "wglGetCurrentDC", &getCurrentDC);
+ GetWGLProcAddress(glModule, getProcAddress, "wglMakeCurrent", &makeCurrent);
+ GetWGLProcAddress(glModule, getProcAddress, "wglShareLists", &shareLists);
+ GetWGLProcAddress(glModule, getProcAddress, "wglUseFontBitmapsA", &useFontBitmapsA);
+ GetWGLProcAddress(glModule, getProcAddress, "wglUseFontBitmapsW", &useFontBitmapsW);
+ swapBuffers = SwapBuffers; // SwapBuffers is statically linked from GDI
+ GetWGLProcAddress(glModule, getProcAddress, "wglUseFontOutlinesA", &useFontOutlinesA);
+ GetWGLProcAddress(glModule, getProcAddress, "wglUseFontOutlinesW", &useFontOutlinesW);
+ GetWGLProcAddress(glModule, getProcAddress, "wglDescribeLayerPlane", &describeLayerPlane);
+ GetWGLProcAddress(glModule, getProcAddress, "wglSetLayerPaletteEntries", &setLayerPaletteEntries);
+ GetWGLProcAddress(glModule, getProcAddress, "wglGetLayerPaletteEntries", &getLayerPaletteEntries);
+ GetWGLProcAddress(glModule, getProcAddress, "wglRealizeLayerPalette", &realizeLayerPalette);
+ GetWGLProcAddress(glModule, getProcAddress, "wglSwapLayerBuffers", &swapLayerBuffers);
+ GetWGLProcAddress(glModule, getProcAddress, "wglSwapMultipleBuffers", &swapMultipleBuffers);
+
+ // Load extension string getter functions
+ GetWGLProcAddress(glModule, getProcAddress, "wglGetExtensionsStringEXT", &getExtensionStringEXT);
+ GetWGLProcAddress(glModule, getProcAddress, "wglGetExtensionsStringARB", &getExtensionStringARB);
+
+ std::string extensionString = "";
+ if (getExtensionStringEXT)
+ {
+ extensionString = getExtensionStringEXT();
+ }
+ else if (getExtensionStringARB && context)
+ {
+ extensionString = getExtensionStringARB(context);
+ }
+ angle::SplitStringAlongWhitespace(extensionString, &extensions);
+
+ // Load the wgl extension functions by checking if the context supports the extension first
+
+ // WGL_ARB_create_context
+ GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_ARB_create_context", "wglCreateContextAttribsARB", &createContextAttribsARB);
+
+ // WGL_ARB_pixel_format
+ GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_ARB_pixel_format", "wglGetPixelFormatAttribivARB", &getPixelFormatAttribivARB);
+ GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_ARB_pixel_format", "wglGetPixelFormatAttribfvARB", &getPixelFormatAttribfvARB);
+ GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_ARB_pixel_format", "wglChoosePixelFormatARB", &choosePixelFormatARB);
+
+ // WGL_EXT_swap_control
+ GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_EXT_swap_control", "wglSwapIntervalEXT", &swapIntervalEXT);
+
+ // WGL_ARB_pbuffer
+ GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_ARB_pbuffer", "wglCreatePbufferARB", &createPbufferARB);
+ GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_ARB_pbuffer", "wglGetPbufferDCARB", &getPbufferDCARB);
+ GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_ARB_pbuffer", "wglReleasePbufferDCARB", &releasePbufferDCARB);
+ GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_ARB_pbuffer", "wglDestroyPbufferARB", &destroyPbufferARB);
+ GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_ARB_pbuffer", "wglQueryPbufferARB", &queryPbufferARB);
+
+ // WGL_ARB_render_texture
+ GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_ARB_render_texture", "wglBindTexImageARB", &bindTexImageARB);
+ GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_ARB_render_texture", "wglReleaseTexImageARB", &releaseTexImageARB);
+ GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_ARB_render_texture", "wglSetPbufferAttribARB", &setPbufferAttribARB);
+
+ // WGL_NV_DX_interop
+ GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_NV_DX_interop", "wglDXSetResourceShareHandleNV", &dxSetResourceShareHandleNV);
+ GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_NV_DX_interop", "wglDXOpenDeviceNV", &dxOpenDeviceNV);
+ GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_NV_DX_interop", "wglDXCloseDeviceNV", &dxCloseDeviceNV);
+ GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_NV_DX_interop", "wglDXRegisterObjectNV", &dxRegisterObjectNV);
+ GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_NV_DX_interop", "wglDXUnregisterObjectNV", &dxUnregisterObjectNV);
+ GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_NV_DX_interop", "wglDXObjectAccessNV", &dxObjectAccessNV);
+ GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_NV_DX_interop", "wglDXLockObjectsNV", &dxLockObjectsNV);
+ GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_NV_DX_interop", "wglDXUnlockObjectsNV", &dxUnlockObjectsNV);
+}
+
+bool FunctionsWGL::hasExtension(const std::string &ext) const
+{
+ return std::find(extensions.begin(), extensions.end(), ext) != extensions.end();
+}
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/wgl/FunctionsWGL.h b/gfx/angle/src/libANGLE/renderer/gl/wgl/FunctionsWGL.h
new file mode 100755
index 000000000..30cf9ebc0
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/wgl/FunctionsWGL.h
@@ -0,0 +1,94 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FunctionsWGL.h: Defines the FuntionsWGL class to contain loaded WGL functions
+
+#ifndef LIBANGLE_RENDERER_GL_WGL_FUNCTIONS_WGL
+#define LIBANGLE_RENDERER_GL_WGL_FUNCTIONS_WGL
+
+#include "common/angleutils.h"
+#include "libANGLE/renderer/gl/wgl/functionswgl_typedefs.h"
+
+namespace rx
+{
+
+class FunctionsWGL : angle::NonCopyable
+{
+ public:
+ FunctionsWGL();
+
+ // Loads all available wgl functions, may be called multiple times
+ void initialize(HMODULE glModule, HDC context);
+
+ // Extension information
+ std::vector<std::string> extensions;
+ bool hasExtension(const std::string &ext) const;
+
+ // Base WGL functions
+ PFNWGLCOPYCONTEXTPROC copyContext;
+ PFNWGLCREATECONTEXTPROC createContext;
+ PFNWGLCREATELAYERCONTEXTPROC createLayerContext;
+ PFNWGLDELETECONTEXTPROC deleteContext;
+ PFNWGLGETCURRENTCONTEXTPROC getCurrentContext;
+ PFNWGLGETCURRENTDCPROC getCurrentDC;
+ PFNWGLGETPROCADDRESSPROC getProcAddress;
+ PFNWGLMAKECURRENTPROC makeCurrent;
+ PFNWGLSHARELISTSPROC shareLists;
+ PFNWGLUSEFONTBITMAPSAPROC useFontBitmapsA;
+ PFNWGLUSEFONTBITMAPSWPROC useFontBitmapsW;
+ PFNSWAPBUFFERSPROC swapBuffers;
+ PFNWGLUSEFONTOUTLINESAPROC useFontOutlinesA;
+ PFNWGLUSEFONTOUTLINESWPROC useFontOutlinesW;
+ PFNWGLDESCRIBELAYERPLANEPROC describeLayerPlane;
+ PFNWGLSETLAYERPALETTEENTRIESPROC setLayerPaletteEntries;
+ PFNWGLGETLAYERPALETTEENTRIESPROC getLayerPaletteEntries;
+ PFNWGLREALIZELAYERPALETTEPROC realizeLayerPalette;
+ PFNWGLSWAPLAYERBUFFERSPROC swapLayerBuffers;
+ PFNWGLSWAPMULTIPLEBUFFERSPROC swapMultipleBuffers;
+
+ // WGL_EXT_extensions_string
+ PFNWGLGETEXTENSIONSSTRINGEXTPROC getExtensionStringEXT;
+
+ // WGL_ARB_extensions_string
+ PFNWGLGETEXTENSIONSSTRINGARBPROC getExtensionStringARB;
+
+ // WGL_ARB_create_context
+ PFNWGLCREATECONTEXTATTRIBSARBPROC createContextAttribsARB;
+
+ // WGL_ARB_pixel_format
+ PFNWGLGETPIXELFORMATATTRIBIVARBPROC getPixelFormatAttribivARB;
+ PFNWGLGETPIXELFORMATATTRIBFVARBPROC getPixelFormatAttribfvARB;
+ PFNWGLCHOOSEPIXELFORMATARBPROC choosePixelFormatARB;
+
+ // WGL_EXT_swap_control
+ PFNWGLSWAPINTERVALEXTPROC swapIntervalEXT;
+
+ // WGL_ARB_pbuffer
+ PFNWGLCREATEPBUFFERARBPROC createPbufferARB;
+ PFNWGLGETPBUFFERDCARBPROC getPbufferDCARB;
+ PFNWGLRELEASEPBUFFERDCARBPROC releasePbufferDCARB;
+ PFNWGLDESTROYPBUFFERARBPROC destroyPbufferARB;
+ PFNWGLQUERYPBUFFERARBPROC queryPbufferARB;
+
+ // WGL_ARB_render_texture
+ PFNWGLBINDTEXIMAGEARBPROC bindTexImageARB;
+ PFNWGLRELEASETEXIMAGEARBPROC releaseTexImageARB;
+ PFNWGLSETPBUFFERATTRIBARBPROC setPbufferAttribARB;
+
+ // WGL_NV_DX_interop
+ PFNWGLDXSETRESOURCESHAREHANDLENVPROC dxSetResourceShareHandleNV;
+ PFNWGLDXOPENDEVICENVPROC dxOpenDeviceNV;
+ PFNWGLDXCLOSEDEVICENVPROC dxCloseDeviceNV;
+ PFNWGLDXREGISTEROBJECTNVPROC dxRegisterObjectNV;
+ PFNWGLDXUNREGISTEROBJECTNVPROC dxUnregisterObjectNV;
+ PFNWGLDXOBJECTACCESSNVPROC dxObjectAccessNV;
+ PFNWGLDXLOCKOBJECTSNVPROC dxLockObjectsNV;
+ PFNWGLDXUNLOCKOBJECTSNVPROC dxUnlockObjectsNV;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_WGL_FUNCTIONS_WGL
diff --git a/gfx/angle/src/libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.cpp
new file mode 100755
index 000000000..f2c503616
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.cpp
@@ -0,0 +1,196 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// SurfaceWGL.cpp: WGL implementation of egl::Surface
+
+#include "libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.h"
+
+#include "common/debug.h"
+#include "libANGLE/renderer/gl/RendererGL.h"
+#include "libANGLE/renderer/gl/wgl/FunctionsWGL.h"
+#include "libANGLE/renderer/gl/wgl/wgl_utils.h"
+
+namespace rx
+{
+
+PbufferSurfaceWGL::PbufferSurfaceWGL(const egl::SurfaceState &state,
+ RendererGL *renderer,
+ EGLint width,
+ EGLint height,
+ EGLenum textureFormat,
+ EGLenum textureTarget,
+ bool largest,
+ int pixelFormat,
+ HDC deviceContext,
+ HGLRC wglContext,
+ const FunctionsWGL *functions)
+ : SurfaceGL(state, renderer),
+ mWidth(width),
+ mHeight(height),
+ mLargest(largest),
+ mTextureFormat(textureFormat),
+ mTextureTarget(textureTarget),
+ mPixelFormat(pixelFormat),
+ mShareWGLContext(wglContext),
+ mParentDeviceContext(deviceContext),
+ mPbuffer(nullptr),
+ mPbufferDeviceContext(nullptr),
+ mFunctionsWGL(functions)
+{
+}
+
+PbufferSurfaceWGL::~PbufferSurfaceWGL()
+{
+ mFunctionsWGL->releasePbufferDCARB(mPbuffer, mPbufferDeviceContext);
+ mPbufferDeviceContext = nullptr;
+
+ mFunctionsWGL->destroyPbufferARB(mPbuffer);
+ mPbuffer = nullptr;
+}
+
+static int GetWGLTextureType(EGLenum eglTextureType)
+{
+ switch (eglTextureType)
+ {
+ case EGL_NO_TEXTURE: return WGL_NO_TEXTURE_ARB;
+ case EGL_TEXTURE_RGB: return WGL_TEXTURE_RGB_ARB;
+ case EGL_TEXTURE_RGBA: return WGL_TEXTURE_RGBA_ARB;
+ default: UNREACHABLE(); return 0;
+ }
+}
+
+static int GetWGLTextureTarget(EGLenum eglTextureTarget)
+{
+ switch (eglTextureTarget)
+ {
+ case EGL_NO_TEXTURE: return WGL_NO_TEXTURE_ARB;
+ case EGL_TEXTURE_2D: return WGL_TEXTURE_2D_ARB;
+ default: UNREACHABLE(); return 0;
+ }
+}
+
+egl::Error PbufferSurfaceWGL::initialize()
+{
+ const int pbufferCreationAttributes[] =
+ {
+ WGL_PBUFFER_LARGEST_ARB, mLargest ? 1 : 0,
+ WGL_TEXTURE_FORMAT_ARB, GetWGLTextureType(mTextureFormat),
+ WGL_TEXTURE_TARGET_ARB, GetWGLTextureTarget(mTextureTarget),
+ 0, 0,
+ };
+
+ mPbuffer = mFunctionsWGL->createPbufferARB(mParentDeviceContext, mPixelFormat, mWidth, mHeight,
+ pbufferCreationAttributes);
+ if (mPbuffer == nullptr)
+ {
+ DWORD error = GetLastError();
+ return egl::Error(EGL_BAD_ALLOC, "Failed to create a native WGL pbuffer, error: 0x%08x.", HRESULT_CODE(error));
+ }
+
+ // The returned pbuffer may not be as large as requested, update the size members.
+ if (mFunctionsWGL->queryPbufferARB(mPbuffer, WGL_PBUFFER_WIDTH_ARB, &mWidth) != TRUE ||
+ mFunctionsWGL->queryPbufferARB(mPbuffer, WGL_PBUFFER_HEIGHT_ARB, &mHeight) != TRUE)
+ {
+ DWORD error = GetLastError();
+ return egl::Error(EGL_BAD_ALLOC, "Failed to query the WGL pbuffer's dimensions, error: 0x%08x.", HRESULT_CODE(error));
+ }
+
+ mPbufferDeviceContext = mFunctionsWGL->getPbufferDCARB(mPbuffer);
+ if (mPbufferDeviceContext == nullptr)
+ {
+ mFunctionsWGL->destroyPbufferARB(mPbuffer);
+ mPbuffer = nullptr;
+
+ DWORD error = GetLastError();
+ return egl::Error(EGL_BAD_ALLOC, "Failed to get the WGL pbuffer handle, error: 0x%08x.", HRESULT_CODE(error));
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error PbufferSurfaceWGL::makeCurrent()
+{
+ if (!mFunctionsWGL->makeCurrent(mPbufferDeviceContext, mShareWGLContext))
+ {
+ // TODO: What error type here?
+ return egl::Error(EGL_CONTEXT_LOST, "Failed to make the WGL context current.");
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error PbufferSurfaceWGL::swap()
+{
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error PbufferSurfaceWGL::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
+{
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error PbufferSurfaceWGL::querySurfacePointerANGLE(EGLint attribute, void **value)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+static int GetWGLBufferBindTarget(EGLint buffer)
+{
+ switch (buffer)
+ {
+ case EGL_BACK_BUFFER: return WGL_BACK_LEFT_ARB;
+ default: UNREACHABLE(); return 0;
+ }
+}
+
+egl::Error PbufferSurfaceWGL::bindTexImage(gl::Texture *texture, EGLint buffer)
+{
+ if (!mFunctionsWGL->bindTexImageARB(mPbuffer, GetWGLBufferBindTarget(buffer)))
+ {
+ DWORD error = GetLastError();
+ return egl::Error(EGL_BAD_SURFACE, "Failed to bind native wgl pbuffer, error: 0x%08x.", HRESULT_CODE(error));
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error PbufferSurfaceWGL::releaseTexImage(EGLint buffer)
+{
+ if (!mFunctionsWGL->releaseTexImageARB(mPbuffer, GetWGLBufferBindTarget(buffer)))
+ {
+ DWORD error = GetLastError();
+ return egl::Error(EGL_BAD_SURFACE, "Failed to unbind native wgl pbuffer, error: 0x%08x.", HRESULT_CODE(error));
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+void PbufferSurfaceWGL::setSwapInterval(EGLint interval)
+{
+}
+
+EGLint PbufferSurfaceWGL::getWidth() const
+{
+ return mWidth;
+}
+
+EGLint PbufferSurfaceWGL::getHeight() const
+{
+ return mHeight;
+}
+
+EGLint PbufferSurfaceWGL::isPostSubBufferSupported() const
+{
+ return EGL_FALSE;
+}
+
+EGLint PbufferSurfaceWGL::getSwapBehavior() const
+{
+ return EGL_BUFFER_PRESERVED;
+}
+
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.h b/gfx/angle/src/libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.h
new file mode 100755
index 000000000..56235293a
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.h
@@ -0,0 +1,74 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// PBufferSurfaceWGL.h: WGL implementation of egl::Surface for PBuffers
+
+#ifndef LIBANGLE_RENDERER_GL_WGL_PBUFFERSURFACEWGL_H_
+#define LIBANGLE_RENDERER_GL_WGL_PBUFFERSURFACEWGL_H_
+
+#include "libANGLE/renderer/gl/SurfaceGL.h"
+
+#include <GL/wglext.h>
+
+namespace rx
+{
+
+class FunctionsWGL;
+
+class PbufferSurfaceWGL : public SurfaceGL
+{
+ public:
+ PbufferSurfaceWGL(const egl::SurfaceState &state,
+ RendererGL *renderer,
+ EGLint width,
+ EGLint height,
+ EGLenum textureFormat,
+ EGLenum textureTarget,
+ bool largest,
+ int pixelFormat,
+ HDC deviceContext,
+ HGLRC wglContext,
+ const FunctionsWGL *functions);
+ ~PbufferSurfaceWGL() override;
+
+ egl::Error initialize() override;
+ egl::Error makeCurrent() override;
+
+ egl::Error swap() override;
+ egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override;
+ egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override;
+ egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) override;
+ egl::Error releaseTexImage(EGLint buffer) override;
+ void setSwapInterval(EGLint interval) override;
+
+ EGLint getWidth() const override;
+ EGLint getHeight() const override;
+
+ EGLint isPostSubBufferSupported() const override;
+ EGLint getSwapBehavior() const override;
+
+ private:
+ EGLint mWidth;
+ EGLint mHeight;
+ bool mLargest;
+ EGLenum mTextureFormat;
+ EGLenum mTextureTarget;
+
+ int mPixelFormat;
+
+ HGLRC mShareWGLContext;
+
+ HDC mParentDeviceContext;
+
+ HPBUFFERARB mPbuffer;
+ HDC mPbufferDeviceContext;
+
+ const FunctionsWGL *mFunctionsWGL;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_WGL_PBUFFERSURFACEWGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/wgl/WindowSurfaceWGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/wgl/WindowSurfaceWGL.cpp
new file mode 100755
index 000000000..f22943acb
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/wgl/WindowSurfaceWGL.cpp
@@ -0,0 +1,178 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// WindowSurfaceWGL.cpp: WGL implementation of egl::Surface for windows
+
+#include "libANGLE/renderer/gl/wgl/WindowSurfaceWGL.h"
+
+#include "common/debug.h"
+#include "libANGLE/renderer/gl/RendererGL.h"
+#include "libANGLE/renderer/gl/wgl/FunctionsWGL.h"
+#include "libANGLE/renderer/gl/wgl/wgl_utils.h"
+
+namespace rx
+{
+
+WindowSurfaceWGL::WindowSurfaceWGL(const egl::SurfaceState &state,
+ RendererGL *renderer,
+ EGLNativeWindowType window,
+ int pixelFormat,
+ HGLRC wglContext,
+ const FunctionsWGL *functions,
+ EGLint orientation)
+ : SurfaceGL(state, renderer),
+ mPixelFormat(pixelFormat),
+ mWGLContext(wglContext),
+ mWindow(window),
+ mDeviceContext(nullptr),
+ mFunctionsWGL(functions),
+ mSwapBehavior(0)
+{
+ // EGL_ANGLE_surface_orientation is not supported for regular WGL window surfaces
+ ASSERT(orientation == 0);
+}
+
+WindowSurfaceWGL::~WindowSurfaceWGL()
+{
+ ReleaseDC(mWindow, mDeviceContext);
+ mDeviceContext = nullptr;
+}
+
+egl::Error WindowSurfaceWGL::initialize()
+{
+ mDeviceContext = GetDC(mWindow);
+ if (!mDeviceContext)
+ {
+ return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to get the device context from the native window, "
+ "error: 0x%X.", GetLastError());
+ }
+
+ // Require that the pixel format for this window has not been set yet or is equal to the Display's pixel format.
+ int windowPixelFormat = GetPixelFormat(mDeviceContext);
+ if (windowPixelFormat == 0)
+ {
+ PIXELFORMATDESCRIPTOR pixelFormatDescriptor = { 0 };
+ if (!DescribePixelFormat(mDeviceContext, mPixelFormat, sizeof(pixelFormatDescriptor), &pixelFormatDescriptor))
+ {
+ return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to DescribePixelFormat, error: 0x%X.", GetLastError());
+ }
+
+ if (!SetPixelFormat(mDeviceContext, mPixelFormat, &pixelFormatDescriptor))
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Failed to set the pixel format on the device context, "
+ "error: 0x%X.", GetLastError());
+ }
+ }
+ else if (windowPixelFormat != mPixelFormat)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Pixel format of the NativeWindow and NativeDisplayType must match.");
+ }
+
+ // Check for the swap behavior of this pixel format
+ switch (
+ wgl::QueryWGLFormatAttrib(mDeviceContext, mPixelFormat, WGL_SWAP_METHOD_ARB, mFunctionsWGL))
+ {
+ case WGL_SWAP_COPY_ARB:
+ mSwapBehavior = EGL_BUFFER_PRESERVED;
+ break;
+
+ case WGL_SWAP_EXCHANGE_ARB:
+ case WGL_SWAP_UNDEFINED_ARB:
+ default:
+ mSwapBehavior = EGL_BUFFER_DESTROYED;
+ break;
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error WindowSurfaceWGL::makeCurrent()
+{
+ if (!mFunctionsWGL->makeCurrent(mDeviceContext, mWGLContext))
+ {
+ // TODO: What error type here?
+ return egl::Error(EGL_CONTEXT_LOST, "Failed to make the WGL context current.");
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error WindowSurfaceWGL::swap()
+{
+ if (!mFunctionsWGL->swapBuffers(mDeviceContext))
+ {
+ // TODO: What error type here?
+ return egl::Error(EGL_CONTEXT_LOST, "Failed to swap buffers on the child window.");
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error WindowSurfaceWGL::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error WindowSurfaceWGL::querySurfacePointerANGLE(EGLint attribute, void **value)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error WindowSurfaceWGL::bindTexImage(gl::Texture *texture, EGLint buffer)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error WindowSurfaceWGL::releaseTexImage(EGLint buffer)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_SUCCESS);
+}
+
+void WindowSurfaceWGL::setSwapInterval(EGLint interval)
+{
+ if (mFunctionsWGL->swapIntervalEXT)
+ {
+ mFunctionsWGL->swapIntervalEXT(interval);
+ }
+}
+
+EGLint WindowSurfaceWGL::getWidth() const
+{
+ RECT rect;
+ if (!GetClientRect(mWindow, &rect))
+ {
+ return 0;
+ }
+ return rect.right - rect.left;
+}
+
+EGLint WindowSurfaceWGL::getHeight() const
+{
+ RECT rect;
+ if (!GetClientRect(mWindow, &rect))
+ {
+ return 0;
+ }
+ return rect.bottom - rect.top;
+}
+
+EGLint WindowSurfaceWGL::isPostSubBufferSupported() const
+{
+ // PostSubBuffer extension not exposed on WGL.
+ UNIMPLEMENTED();
+ return EGL_FALSE;
+}
+
+EGLint WindowSurfaceWGL::getSwapBehavior() const
+{
+ return mSwapBehavior;
+}
+
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/wgl/WindowSurfaceWGL.h b/gfx/angle/src/libANGLE/renderer/gl/wgl/WindowSurfaceWGL.h
new file mode 100755
index 000000000..eb95e4dc2
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/wgl/WindowSurfaceWGL.h
@@ -0,0 +1,64 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// WindowSurfaceWGL.h: WGL implementation of egl::Surface for windows
+
+#ifndef LIBANGLE_RENDERER_GL_WGL_WINDOWSURFACEWGL_H_
+#define LIBANGLE_RENDERER_GL_WGL_WINDOWSURFACEWGL_H_
+
+#include "libANGLE/renderer/gl/SurfaceGL.h"
+
+#include <GL/wglext.h>
+
+namespace rx
+{
+
+class FunctionsWGL;
+
+class WindowSurfaceWGL : public SurfaceGL
+{
+ public:
+ WindowSurfaceWGL(const egl::SurfaceState &state,
+ RendererGL *renderer,
+ EGLNativeWindowType window,
+ int pixelFormat,
+ HGLRC wglContext,
+ const FunctionsWGL *functions,
+ EGLint orientation);
+ ~WindowSurfaceWGL() override;
+
+ egl::Error initialize() override;
+ egl::Error makeCurrent() override;
+
+ egl::Error swap() override;
+ egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override;
+ egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override;
+ egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) override;
+ egl::Error releaseTexImage(EGLint buffer) override;
+ void setSwapInterval(EGLint interval) override;
+
+ EGLint getWidth() const override;
+ EGLint getHeight() const override;
+
+ EGLint isPostSubBufferSupported() const override;
+ EGLint getSwapBehavior() const override;
+
+ private:
+ int mPixelFormat;
+
+ HGLRC mWGLContext;
+
+ HWND mWindow;
+ HDC mDeviceContext;
+
+ const FunctionsWGL *mFunctionsWGL;
+
+ EGLint mSwapBehavior;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_WGL_WINDOWSURFACEWGL_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/wgl/functionswgl_typedefs.h b/gfx/angle/src/libANGLE/renderer/gl/wgl/functionswgl_typedefs.h
new file mode 100755
index 000000000..c4b79ee02
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/wgl/functionswgl_typedefs.h
@@ -0,0 +1,43 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// functionswgl_typedefs.h: Typedefs of WGL functions.
+
+#ifndef LIBANGLE_RENDERER_GL_WGL_FUNCTIONSWGLTYPEDEFS_H_
+#define LIBANGLE_RENDERER_GL_WGL_FUNCTIONSWGLTYPEDEFS_H_
+
+#include "common/platform.h"
+
+#include <angle_gl.h>
+#include <GL/wglext.h>
+
+namespace rx
+{
+
+typedef BOOL(WINAPI *PFNWGLCOPYCONTEXTPROC)(HGLRC, HGLRC, UINT);
+typedef HGLRC(WINAPI *PFNWGLCREATECONTEXTPROC)(HDC);
+typedef HGLRC(WINAPI *PFNWGLCREATELAYERCONTEXTPROC)(HDC, int);
+typedef BOOL(WINAPI *PFNWGLDELETECONTEXTPROC)(HGLRC);
+typedef HGLRC(WINAPI *PFNWGLGETCURRENTCONTEXTPROC)(VOID);
+typedef HDC(WINAPI *PFNWGLGETCURRENTDCPROC)(VOID);
+typedef PROC(WINAPI *PFNWGLGETPROCADDRESSPROC)(LPCSTR);
+typedef BOOL(WINAPI *PFNWGLMAKECURRENTPROC)(HDC, HGLRC);
+typedef BOOL(WINAPI *PFNWGLSHARELISTSPROC)(HGLRC, HGLRC);
+typedef BOOL(WINAPI *PFNWGLUSEFONTBITMAPSAPROC)(HDC, DWORD, DWORD, DWORD);
+typedef BOOL(WINAPI *PFNWGLUSEFONTBITMAPSWPROC)(HDC, DWORD, DWORD, DWORD);
+typedef BOOL(WINAPI *PFNSWAPBUFFERSPROC)(HDC);
+typedef BOOL(WINAPI *PFNWGLUSEFONTOUTLINESAPROC)(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT);
+typedef BOOL(WINAPI *PFNWGLUSEFONTOUTLINESWPROC)(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT);
+typedef BOOL(WINAPI *PFNWGLDESCRIBELAYERPLANEPROC)(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR);
+typedef int(WINAPI *PFNWGLSETLAYERPALETTEENTRIESPROC)(HDC, int, int, int, CONST COLORREF *);
+typedef int(WINAPI *PFNWGLGETLAYERPALETTEENTRIESPROC)(HDC, int, int, int, COLORREF *);
+typedef BOOL(WINAPI *PFNWGLREALIZELAYERPALETTEPROC)(HDC, int, BOOL);
+typedef BOOL(WINAPI *PFNWGLSWAPLAYERBUFFERSPROC)(HDC, UINT);
+typedef DWORD(WINAPI *PFNWGLSWAPMULTIPLEBUFFERSPROC)(UINT, CONST WGLSWAP *);
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_WGL_FUNCTIONSWGLTYPEDEFS_H_
diff --git a/gfx/angle/src/libANGLE/renderer/gl/wgl/wgl_utils.cpp b/gfx/angle/src/libANGLE/renderer/gl/wgl/wgl_utils.cpp
new file mode 100755
index 000000000..641c3fbc4
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/wgl/wgl_utils.cpp
@@ -0,0 +1,85 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// wgl_utils.cpp: Utility routines specific to the WGL->EGL implementation.
+
+#include "libANGLE/renderer/gl/wgl/wgl_utils.h"
+
+#include "libANGLE/renderer/gl/wgl/FunctionsWGL.h"
+
+namespace rx
+{
+
+namespace wgl
+{
+
+PIXELFORMATDESCRIPTOR GetDefaultPixelFormatDescriptor()
+{
+ PIXELFORMATDESCRIPTOR pixelFormatDescriptor = { 0 };
+ pixelFormatDescriptor.nSize = sizeof(pixelFormatDescriptor);
+ pixelFormatDescriptor.nVersion = 1;
+ pixelFormatDescriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_GENERIC_ACCELERATED | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
+ pixelFormatDescriptor.iPixelType = PFD_TYPE_RGBA;
+ pixelFormatDescriptor.cColorBits = 24;
+ pixelFormatDescriptor.cAlphaBits = 8;
+ pixelFormatDescriptor.cDepthBits = 24;
+ pixelFormatDescriptor.cStencilBits = 8;
+ pixelFormatDescriptor.iLayerType = PFD_MAIN_PLANE;
+
+ return pixelFormatDescriptor;
+}
+
+std::vector<int> GetDefaultPixelFormatAttributes(bool preservedSwap)
+{
+ std::vector<int> attribs;
+ attribs.push_back(WGL_DRAW_TO_WINDOW_ARB);
+ attribs.push_back(TRUE);
+
+ attribs.push_back(WGL_ACCELERATION_ARB);
+ attribs.push_back(WGL_FULL_ACCELERATION_ARB);
+
+ attribs.push_back(WGL_SUPPORT_OPENGL_ARB);
+ attribs.push_back(TRUE);
+
+ attribs.push_back(WGL_DOUBLE_BUFFER_ARB);
+ attribs.push_back(TRUE);
+
+ attribs.push_back(WGL_PIXEL_TYPE_ARB);
+ attribs.push_back(WGL_TYPE_RGBA_ARB);
+
+ attribs.push_back(WGL_COLOR_BITS_ARB);
+ attribs.push_back(24);
+
+ attribs.push_back(WGL_ALPHA_BITS_ARB);
+ attribs.push_back(8);
+
+ attribs.push_back(WGL_DEPTH_BITS_ARB);
+ attribs.push_back(24);
+
+ attribs.push_back(WGL_STENCIL_BITS_ARB);
+ attribs.push_back(8);
+
+ attribs.push_back(WGL_SWAP_METHOD_ARB);
+ attribs.push_back(preservedSwap ? WGL_SWAP_COPY_ARB : WGL_SWAP_UNDEFINED_ARB);
+
+ attribs.push_back(0);
+
+ return attribs;
+}
+
+int QueryWGLFormatAttrib(HDC dc, int format, int attribName, const FunctionsWGL *functions)
+{
+ int result = 0;
+ if (functions->getPixelFormatAttribivARB == nullptr ||
+ !functions->getPixelFormatAttribivARB(dc, format, 0, 1, &attribName, &result))
+ {
+ return 0;
+ }
+ return result;
+}
+}
+
+}
diff --git a/gfx/angle/src/libANGLE/renderer/gl/wgl/wgl_utils.h b/gfx/angle/src/libANGLE/renderer/gl/wgl/wgl_utils.h
new file mode 100755
index 000000000..d4914b5d3
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/wgl/wgl_utils.h
@@ -0,0 +1,32 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// wgl_utils.h: Utility routines specific to the WGL->EGL implementation.
+
+#ifndef LIBANGLE_RENDERER_GL_WGL_WGLUTILS_H_
+#define LIBANGLE_RENDERER_GL_WGL_WGLUTILS_H_
+
+#include <vector>
+
+#include "common/platform.h"
+
+namespace rx
+{
+
+class FunctionsWGL;
+
+namespace wgl
+{
+
+PIXELFORMATDESCRIPTOR GetDefaultPixelFormatDescriptor();
+std::vector<int> GetDefaultPixelFormatAttributes(bool preservedSwap);
+
+int QueryWGLFormatAttrib(HDC dc, int format, int attribName, const FunctionsWGL *functions);
+}
+
+}
+
+#endif // LIBANGLE_RENDERER_GL_WGL_WGLUTILS_H_