summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorbacker@chromium.org <backer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-28 19:24:49 +0000
committerbacker@chromium.org <backer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-28 19:24:49 +0000
commit5ae0b28229648b8b5d26624a45f3fffca4e545fd (patch)
treea97b457285d90a49521a360e7cad015fbd7e2474 /ui
parent2f4aec1e3e10cac458f44747d650c2336e220554 (diff)
downloadchromium_src-5ae0b28229648b8b5d26624a45f3fffca4e545fd.zip
chromium_src-5ae0b28229648b8b5d26624a45f3fffca4e545fd.tar.gz
chromium_src-5ae0b28229648b8b5d26624a45f3fffca4e545fd.tar.bz2
Refactor: Move app/gfx/gl ==> ui/gfx/gl
This is the final patch in the sequence. Note that gl.gyp is introduced because dependency checking on the Mac is done on a per file (rather than per target) basis. BUG=none TEST=trybots Review URL: http://codereview.chromium.org/6722026 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79599 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/gfx/compositor/compositor.gyp2
-rw-r--r--ui/gfx/compositor/compositor_gl.cc6
-rw-r--r--ui/gfx/gl/generate_bindings.py638
-rw-r--r--ui/gfx/gl/gl.gyp160
-rw-r--r--ui/gfx/gl/gl_bindings.h98
-rw-r--r--ui/gfx/gl/gl_bindings_skia.cc511
-rw-r--r--ui/gfx/gl/gl_bindings_skia.h21
-rw-r--r--ui/gfx/gl/gl_context.cc58
-rw-r--r--ui/gfx/gl/gl_context.h82
-rw-r--r--ui/gfx/gl/gl_context_egl.cc428
-rw-r--r--ui/gfx/gl/gl_context_egl.h119
-rw-r--r--ui/gfx/gl/gl_context_linux.cc830
-rw-r--r--ui/gfx/gl/gl_context_mac.cc209
-rw-r--r--ui/gfx/gl/gl_context_osmesa.cc131
-rw-r--r--ui/gfx/gl/gl_context_osmesa.h54
-rw-r--r--ui/gfx/gl/gl_context_stub.cc39
-rw-r--r--ui/gfx/gl/gl_context_stub.h39
-rw-r--r--ui/gfx/gl/gl_context_win.cc743
-rw-r--r--ui/gfx/gl/gl_implementation.cc147
-rw-r--r--ui/gfx/gl/gl_implementation.h74
-rw-r--r--ui/gfx/gl/gl_implementation_linux.cc160
-rw-r--r--ui/gfx/gl/gl_implementation_mac.cc92
-rw-r--r--ui/gfx/gl/gl_implementation_win.cc168
-rw-r--r--ui/gfx/gl/gl_interface.cc20
-rw-r--r--ui/gfx/gl/gl_interface.h436
-rw-r--r--ui/gfx/surface/accelerated_surface_mac.cc4
-rw-r--r--ui/gfx/surface/accelerated_surface_mac.h2
-rw-r--r--ui/gfx/surface/surface.gyp2
-rw-r--r--ui/ui_gfx.gypi2
29 files changed, 5265 insertions, 10 deletions
diff --git a/ui/gfx/compositor/compositor.gyp b/ui/gfx/compositor/compositor.gyp
index d003694..f739b93 100644
--- a/ui/gfx/compositor/compositor.gyp
+++ b/ui/gfx/compositor/compositor.gyp
@@ -10,7 +10,7 @@
'msvs_guid': '21CEE0E3-6F4E-4F01-B8C9-F7751CC21AA9',
'dependencies': [
'<(DEPTH)/base/base.gyp:base',
- '<(DEPTH)/app/app.gyp:app_base',
+ '<(DEPTH)/ui/gfx/gl/gl.gyp:gl',
'<(DEPTH)/ui/ui.gyp:ui_gfx',
],
'sources': [
diff --git a/ui/gfx/compositor/compositor_gl.cc b/ui/gfx/compositor/compositor_gl.cc
index 6fa426a..f152ffc 100644
--- a/ui/gfx/compositor/compositor_gl.cc
+++ b/ui/gfx/compositor/compositor_gl.cc
@@ -4,14 +4,14 @@
#include "ui/gfx/compositor/compositor.h"
-#include "app/gfx/gl/gl_context.h"
-#include "app/gfx/gl/gl_bindings.h"
-#include "app/gfx/gl/gl_implementation.h"
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "ui/gfx/transform.h"
+#include "ui/gfx/gl/gl_context.h"
+#include "ui/gfx/gl/gl_bindings.h"
+#include "ui/gfx/gl/gl_implementation.h"
namespace ui {
diff --git a/ui/gfx/gl/generate_bindings.py b/ui/gfx/gl/generate_bindings.py
new file mode 100644
index 0000000..41038cc
--- /dev/null
+++ b/ui/gfx/gl/generate_bindings.py
@@ -0,0 +1,638 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2011 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""code generator for GL/GLES extension wrangler."""
+
+import os
+import re
+import sys
+
+GL_FUNCTIONS = [
+['void', ['glActiveTexture'], 'GLenum texture'],
+['void', ['glAttachShader'], 'GLuint program, GLuint shader'],
+['void', ['glBindAttribLocation'],
+ 'GLuint program, GLuint index, const char* name'],
+['void', ['glBindBuffer'], 'GLenum target, GLuint buffer'],
+['void', ['glBindFramebufferEXT', 'glBindFramebuffer'],
+ 'GLenum target, GLuint framebuffer'],
+['void', ['glBindRenderbufferEXT', 'glBindRenderbuffer'],
+ 'GLenum target, GLuint renderbuffer'],
+['void', ['glBindTexture'], 'GLenum target, GLuint texture'],
+['void', ['glBlendColor'],
+ 'GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha'],
+['void', ['glBlendEquation'], ' GLenum mode '],
+['void', ['glBlendEquationSeparate'], 'GLenum modeRGB, GLenum modeAlpha'],
+['void', ['glBlendFunc'], 'GLenum sfactor, GLenum dfactor'],
+['void', ['glBlendFuncSeparate'],
+ 'GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha'],
+['void', ['glBlitFramebufferEXT', 'BlitFramebuffer'],
+ 'GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, '
+ 'GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, '
+ 'GLbitfield mask, GLenum filter'],
+['void', ['glBlitFramebufferANGLE', 'BlitFramebuffer'],
+ 'GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, '
+ 'GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, '
+ 'GLbitfield mask, GLenum filter'],
+['void', ['glBufferData'],
+ 'GLenum target, GLsizei size, const void* data, GLenum usage'],
+['void', ['glBufferSubData'],
+ 'GLenum target, GLint offset, GLsizei size, const void* data'],
+['GLenum', ['glCheckFramebufferStatusEXT',
+ 'glCheckFramebufferStatus'], 'GLenum target'],
+['void', ['glClear'], 'GLbitfield mask'],
+['void', ['glClearColor'],
+ 'GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha'],
+['void', ['glClearDepth'], 'GLclampd depth'],
+['void', ['glClearDepthf'], 'GLclampf depth'],
+['void', ['glClearStencil'], 'GLint s'],
+['void', ['glColorMask'],
+ 'GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha'],
+['void', ['glCompileShader'], 'GLuint shader'],
+['void', ['glCompressedTexImage2D'],
+ 'GLenum target, GLint level, GLenum internalformat, GLsizei width, '
+ 'GLsizei height, GLint border, GLsizei imageSize, const void* data'],
+['void', ['glCompressedTexSubImage2D'],
+ 'GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, '
+ 'GLsizei height, GLenum format, GLsizei imageSize, const void* data'],
+['void', ['glCopyTexImage2D'],
+ 'GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, '
+ 'GLsizei width, GLsizei height, GLint border'],
+['void', ['glCopyTexSubImage2D'], 'GLenum target, GLint level, GLint xoffset, '
+ 'GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height'],
+['GLuint', ['glCreateProgram'], 'void'],
+['GLuint', ['glCreateShader'], 'GLenum type'],
+['void', ['glCullFace'], 'GLenum mode'],
+['void', ['glDeleteBuffersARB', 'glDeleteBuffers'],
+ 'GLsizei n, const GLuint* buffers'],
+['void', ['glDeleteFramebuffersEXT', 'glDeleteFramebuffers'],
+ 'GLsizei n, const GLuint* framebuffers'],
+['void', ['glDeleteProgram'], 'GLuint program'],
+['void', ['glDeleteRenderbuffersEXT', 'glDeleteRenderbuffers'],
+ 'GLsizei n, const GLuint* renderbuffers'],
+['void', ['glDeleteShader'], 'GLuint shader'],
+['void', ['glDeleteTextures'], 'GLsizei n, const GLuint* textures'],
+['void', ['glDepthFunc'], 'GLenum func'],
+['void', ['glDepthMask'], 'GLboolean flag'],
+['void', ['glDepthRange'], 'GLclampd zNear, GLclampd zFar'],
+['void', ['glDepthRangef'], 'GLclampf zNear, GLclampf zFar'],
+['void', ['glDetachShader'], 'GLuint program, GLuint shader'],
+['void', ['glDisable'], 'GLenum cap'],
+['void', ['glDisableVertexAttribArray'], 'GLuint index'],
+['void', ['glDrawArrays'], 'GLenum mode, GLint first, GLsizei count'],
+['void', ['glDrawElements'],
+ 'GLenum mode, GLsizei count, GLenum type, const void* indices'],
+['void', ['glEnable'], 'GLenum cap'],
+['void', ['glEnableVertexAttribArray'], 'GLuint index'],
+['void', ['glFinish'], 'void'],
+['void', ['glFlush'], 'void'],
+['void', ['glFramebufferRenderbufferEXT', 'glFramebufferRenderbuffer'],
+ 'GLenum target, GLenum attachment, GLenum renderbuffertarget, '
+ 'GLuint renderbuffer'],
+['void', ['glFramebufferTexture2DEXT', 'glFramebufferTexture2D'],
+ 'GLenum target, GLenum attachment, GLenum textarget, GLuint texture, '
+ 'GLint level'],
+['void', ['glFrontFace'], 'GLenum mode'],
+['void', ['glGenBuffersARB', 'glGenBuffers'], 'GLsizei n, GLuint* buffers'],
+['void', ['glGenerateMipmapEXT', 'glGenerateMipmap'], 'GLenum target'],
+['void', ['glGenFramebuffersEXT', 'glGenFramebuffers'],
+ 'GLsizei n, GLuint* framebuffers'],
+['void', ['glGenRenderbuffersEXT', 'glGenRenderbuffers'],
+ 'GLsizei n, GLuint* renderbuffers'],
+['void', ['glGenTextures'], 'GLsizei n, GLuint* textures'],
+['void', ['glGetActiveAttrib'],
+ 'GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, '
+ 'GLint* size, GLenum* type, char* name'],
+['void', ['glGetActiveUniform'],
+ 'GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, '
+ 'GLint* size, GLenum* type, char* name'],
+['void', ['glGetAttachedShaders'],
+ 'GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders'],
+['GLint', ['glGetAttribLocation'], 'GLuint program, const char* name'],
+['void', ['glGetBooleanv'], 'GLenum pname, GLboolean* params'],
+['void', ['glGetBufferParameteriv'],
+ 'GLenum target, GLenum pname, GLint* params'],
+['GLenum', ['glGetError'], 'void'],
+['void', ['glGetFloatv'], 'GLenum pname, GLfloat* params'],
+['void', ['glGetFramebufferAttachmentParameterivEXT',
+ 'glGetFramebufferAttachmentParameteriv'], 'GLenum target, '
+ 'GLenum attachment, GLenum pname, GLint* params'],
+['void', ['glGetIntegerv'], 'GLenum pname, GLint* params'],
+['void', ['glGetProgramiv'], 'GLuint program, GLenum pname, GLint* params'],
+['void', ['glGetProgramInfoLog'],
+ 'GLuint program, GLsizei bufsize, GLsizei* length, char* infolog'],
+['void', ['glGetRenderbufferParameterivEXT', 'glGetRenderbufferParameteriv'],
+ 'GLenum target, GLenum pname, GLint* params'],
+['void', ['glGetShaderiv'], 'GLuint shader, GLenum pname, GLint* params'],
+['void', ['glGetShaderInfoLog'],
+ 'GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog'],
+['void', ['glGetShaderPrecisionFormat'],
+ 'GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision'],
+['void', ['glGetShaderSource'],
+ 'GLuint shader, GLsizei bufsize, GLsizei* length, char* source'],
+['const GLubyte*', ['glGetString'], 'GLenum name'],
+['void', ['glGetTexLevelParameterfv'],
+ 'GLenum target, GLint level, GLenum pname, GLfloat* params'],
+['void', ['glGetTexLevelParameteriv'],
+ 'GLenum target, GLint level, GLenum pname, GLint* params'],
+['void', ['glGetTexParameterfv'],
+ 'GLenum target, GLenum pname, GLfloat* params'],
+['void', ['glGetTexParameteriv'], 'GLenum target, GLenum pname, GLint* params'],
+['void', ['glGetUniformfv'], 'GLuint program, GLint location, GLfloat* params'],
+['void', ['glGetUniformiv'], 'GLuint program, GLint location, GLint* params'],
+['GLint', ['glGetUniformLocation'], 'GLuint program, const char* name'],
+['void', ['glGetVertexAttribfv'],
+ 'GLuint index, GLenum pname, GLfloat* params'],
+['void', ['glGetVertexAttribiv'], 'GLuint index, GLenum pname, GLint* params'],
+['void', ['glGetVertexAttribPointerv'],
+ 'GLuint index, GLenum pname, void** pointer'],
+['void', ['glHint'], 'GLenum target, GLenum mode'],
+['GLboolean', ['glIsBuffer'], 'GLuint buffer'],
+['GLboolean', ['glIsEnabled'], 'GLenum cap'],
+['GLboolean', ['glIsFramebufferEXT', 'glIsFramebuffer'],
+ 'GLuint framebuffer'],
+['GLboolean', ['glIsProgram'], 'GLuint program'],
+['GLboolean', ['glIsRenderbufferEXT', 'glIsRenderbuffer'],
+ 'GLuint renderbuffer'],
+['GLboolean', ['glIsShader'], 'GLuint shader'],
+['GLboolean', ['glIsTexture'], 'GLuint texture'],
+['void', ['glLineWidth'], 'GLfloat width'],
+['void', ['glLinkProgram'], 'GLuint program'],
+['void*', ['glMapBuffer'], 'GLenum target, GLenum access'],
+['void', ['glPixelStorei'], 'GLenum pname, GLint param'],
+['void', ['glPolygonOffset'], 'GLfloat factor, GLfloat units'],
+['void', ['glReadPixels'],
+ 'GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, '
+ 'GLenum type, void* pixels'],
+['void', ['glReleaseShaderCompiler'], 'void'],
+['void', ['glRenderbufferStorageMultisampleEXT',
+ 'glRenderbufferStorageMultisample'],
+ 'GLenum target, GLsizei samples, GLenum internalformat, '
+ 'GLsizei width, GLsizei height'],
+['void', ['glRenderbufferStorageMultisampleANGLE',
+ 'glRenderbufferStorageMultisample'],
+ 'GLenum target, GLsizei samples, GLenum internalformat, '
+ 'GLsizei width, GLsizei height'],
+['void', ['glRenderbufferStorageEXT', 'glRenderbufferStorage'],
+ 'GLenum target, GLenum internalformat, GLsizei width, GLsizei height'],
+['void', ['glSampleCoverage'], 'GLclampf value, GLboolean invert'],
+['void', ['glScissor'], 'GLint x, GLint y, GLsizei width, GLsizei height'],
+['void', ['glShaderBinary'],
+ 'GLsizei n, const GLuint* shaders, GLenum binaryformat, '
+ 'const void* binary, GLsizei length'],
+['void', ['glShaderSource'],
+ 'GLuint shader, GLsizei count, const char** str, const GLint* length'],
+['void', ['glStencilFunc'], 'GLenum func, GLint ref, GLuint mask'],
+['void', ['glStencilFuncSeparate'],
+ 'GLenum face, GLenum func, GLint ref, GLuint mask'],
+['void', ['glStencilMask'], 'GLuint mask'],
+['void', ['glStencilMaskSeparate'], 'GLenum face, GLuint mask'],
+['void', ['glStencilOp'], 'GLenum fail, GLenum zfail, GLenum zpass'],
+['void', ['glStencilOpSeparate'],
+ 'GLenum face, GLenum fail, GLenum zfail, GLenum zpass'],
+['void', ['glTexImage2D'],
+ 'GLenum target, GLint level, GLint internalformat, GLsizei width, '
+ 'GLsizei height, GLint border, GLenum format, GLenum type, '
+ 'const void* pixels'],
+['void', ['glTexParameterf'], 'GLenum target, GLenum pname, GLfloat param'],
+['void', ['glTexParameterfv'],
+ 'GLenum target, GLenum pname, const GLfloat* params'],
+['void', ['glTexParameteri'], 'GLenum target, GLenum pname, GLint param'],
+['void', ['glTexParameteriv'],
+ 'GLenum target, GLenum pname, const GLint* params'],
+['void', ['glTexSubImage2D'],
+ 'GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, '
+ 'GLsizei height, GLenum format, GLenum type, const void* pixels'],
+['void', ['glUniform1f'], 'GLint location, GLfloat x'],
+['void', ['glUniform1fv'], 'GLint location, GLsizei count, const GLfloat* v'],
+['void', ['glUniform1i'], 'GLint location, GLint x'],
+['void', ['glUniform1iv'], 'GLint location, GLsizei count, const GLint* v'],
+['void', ['glUniform2f'], 'GLint location, GLfloat x, GLfloat y'],
+['void', ['glUniform2fv'], 'GLint location, GLsizei count, const GLfloat* v'],
+['void', ['glUniform2i'], 'GLint location, GLint x, GLint y'],
+['void', ['glUniform2iv'], 'GLint location, GLsizei count, const GLint* v'],
+['void', ['glUniform3f'], 'GLint location, GLfloat x, GLfloat y, GLfloat z'],
+['void', ['glUniform3fv'], 'GLint location, GLsizei count, const GLfloat* v'],
+['void', ['glUniform3i'], 'GLint location, GLint x, GLint y, GLint z'],
+['void', ['glUniform3iv'], 'GLint location, GLsizei count, const GLint* v'],
+['void', ['glUniform4f'],
+ 'GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w'],
+['void', ['glUniform4fv'], 'GLint location, GLsizei count, const GLfloat* v'],
+['void', ['glUniform4i'], 'GLint location, GLint x, GLint y, GLint z, GLint w'],
+['void', ['glUniform4iv'], 'GLint location, GLsizei count, const GLint* v'],
+['void', ['glUniformMatrix2fv'],
+ 'GLint location, GLsizei count, GLboolean transpose, const GLfloat* value'],
+['void', ['glUniformMatrix3fv'],
+ 'GLint location, GLsizei count, GLboolean transpose, const GLfloat* value'],
+['void', ['glUniformMatrix4fv'],
+ 'GLint location, GLsizei count, GLboolean transpose, const GLfloat* value'],
+['GLboolean', ['glUnmapBuffer'], 'GLenum target'],
+['void', ['glUseProgram'], 'GLuint program'],
+['void', ['glValidateProgram'], 'GLuint program'],
+['void', ['glVertexAttrib1f'], 'GLuint indx, GLfloat x'],
+['void', ['glVertexAttrib1fv'], 'GLuint indx, const GLfloat* values'],
+['void', ['glVertexAttrib2f'], 'GLuint indx, GLfloat x, GLfloat y'],
+['void', ['glVertexAttrib2fv'], 'GLuint indx, const GLfloat* values'],
+['void', ['glVertexAttrib3f'], 'GLuint indx, GLfloat x, GLfloat y, GLfloat z'],
+['void', ['glVertexAttrib3fv'], 'GLuint indx, const GLfloat* values'],
+['void', ['glVertexAttrib4f'],
+ 'GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w'],
+['void', ['glVertexAttrib4fv'], 'GLuint indx, const GLfloat* values'],
+['void', ['glVertexAttribPointer'],
+ 'GLuint indx, GLint size, GLenum type, GLboolean normalized, '
+ 'GLsizei stride, const void* ptr'],
+['void', ['glViewport'], 'GLint x, GLint y, GLsizei width, GLsizei height'],
+['void', ['glGenFencesNV'], 'GLsizei n, GLuint* fences'],
+['void', ['glDeleteFencesNV'], 'GLsizei n, const GLuint* fences'],
+['void', ['glSetFenceNV'], 'GLuint fence, GLenum condition'],
+['GLboolean', ['glTestFenceNV'], 'GLuint fence'],
+['void', ['glFinishFenceNV'], 'GLuint fence'],
+['GLboolean', ['glIsFenceNV'], 'GLuint fence'],
+['void', ['glGetFenceivNV'], 'GLuint fence, GLenum pname, GLint* params']
+]
+
+OSMESA_FUNCTIONS = [
+['OSMesaContext', ['OSMesaCreateContext'],
+ 'GLenum format, OSMesaContext sharelist'],
+['OSMesaContext', ['OSMesaCreateContextExt'],
+ 'GLenum format, GLint depthBits, GLint stencilBits, GLint accumBits, '
+ 'OSMesaContext sharelist'],
+['void', ['OSMesaDestroyContext'], 'OSMesaContext ctx'],
+['GLboolean', ['OSMesaMakeCurrent'],
+ 'OSMesaContext ctx, void* buffer, GLenum type, GLsizei width, '
+ 'GLsizei height'],
+['OSMesaContext', ['OSMesaGetCurrentContext'], 'void'],
+['void', ['OSMesaPixelStore'], 'GLint pname, GLint value'],
+['void', ['OSMesaGetIntegerv'], 'GLint pname, GLint* value'],
+['GLboolean', ['OSMesaGetDepthBuffer'],
+ 'OSMesaContext c, GLint* width, GLint* height, GLint* bytesPerValue, '
+ 'void** buffer'],
+['GLboolean', ['OSMesaGetColorBuffer'],
+ 'OSMesaContext c, GLint* width, GLint* height, GLint* format, '
+ 'void** buffer'],
+['OSMESAproc', ['OSMesaGetProcAddress'], 'const char* funcName'],
+['void', ['OSMesaColorClamp'], 'GLboolean enable'],
+]
+
+EGL_FUNCTIONS = [
+['EGLint', ['eglGetError'], 'void'],
+['EGLDisplay', ['eglGetDisplay'], 'EGLNativeDisplayType display_id'],
+['EGLBoolean', ['eglInitialize'],
+ 'EGLDisplay dpy, EGLint* major, EGLint* minor'],
+['EGLBoolean', ['eglTerminate'], 'EGLDisplay dpy'],
+['const char*', ['eglQueryString'], 'EGLDisplay dpy, EGLint name'],
+['EGLBoolean', ['eglGetConfigs'],
+ 'EGLDisplay dpy, EGLConfig* configs, EGLint config_size, '
+ 'EGLint* num_config'],
+['EGLBoolean', ['eglChooseConfig'],
+ 'EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, '
+ 'EGLint config_size, EGLint* num_config'],
+['EGLBoolean', ['eglGetConfigAttrib'],
+ 'EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value'],
+['EGLSurface', ['eglCreateWindowSurface'],
+ 'EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, '
+ 'const EGLint* attrib_list'],
+['EGLSurface', ['eglCreatePbufferSurface'],
+ 'EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list'],
+['EGLSurface', ['eglCreatePixmapSurface'],
+ 'EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, '
+ 'const EGLint* attrib_list'],
+['EGLBoolean', ['eglDestroySurface'], 'EGLDisplay dpy, EGLSurface surface'],
+['EGLBoolean', ['eglQuerySurface'],
+ 'EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint* value'],
+['EGLBoolean', ['eglBindAPI'], 'EGLenum api'],
+['EGLenum', ['eglQueryAPI'], 'void'],
+['EGLBoolean', ['eglWaitClient'], 'void'],
+['EGLBoolean', ['eglReleaseThread'], 'void'],
+['EGLSurface', ['eglCreatePbufferFromClientBuffer'],
+ 'EGLDisplay dpy, EGLenum buftype, void* buffer, EGLConfig config, '
+ 'const EGLint* attrib_list'],
+['EGLBoolean', ['eglSurfaceAttrib'],
+ 'EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value'],
+['EGLBoolean', ['eglBindTexImage'],
+ 'EGLDisplay dpy, EGLSurface surface, EGLint buffer'],
+['EGLBoolean', ['eglReleaseTexImage'],
+ 'EGLDisplay dpy, EGLSurface surface, EGLint buffer'],
+['EGLBoolean', ['eglSwapInterval'], 'EGLDisplay dpy, EGLint interval'],
+['EGLContext', ['eglCreateContext'],
+ 'EGLDisplay dpy, EGLConfig config, EGLContext share_context, '
+ 'const EGLint* attrib_list'],
+['EGLBoolean', ['eglDestroyContext'], 'EGLDisplay dpy, EGLContext ctx'],
+['EGLBoolean', ['eglMakeCurrent'],
+ 'EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx'],
+['EGLContext', ['eglGetCurrentContext'], 'void'],
+['EGLSurface', ['eglGetCurrentSurface'], 'EGLint readdraw'],
+['EGLDisplay', ['eglGetCurrentDisplay'], 'void'],
+['EGLBoolean', ['eglQueryContext'],
+ 'EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint* value'],
+['EGLBoolean', ['eglWaitGL'], 'void'],
+['EGLBoolean', ['eglWaitNative'], 'EGLint engine'],
+['EGLBoolean', ['eglSwapBuffers'], 'EGLDisplay dpy, EGLSurface surface'],
+['EGLBoolean', ['eglCopyBuffers'],
+ 'EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target'],
+['__eglMustCastToProperFunctionPointerType', ['eglGetProcAddress'],
+ 'const char* procname'],
+]
+
+WGL_FUNCTIONS = [
+['HGLRC', ['wglCreateContext'], 'HDC hdc'],
+['HGLRC', ['wglCreateLayerContext'], 'HDC hdc, int iLayerPlane'],
+['BOOL', ['wglCopyContext'], 'HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask'],
+['BOOL', ['wglDeleteContext'], 'HGLRC hglrc'],
+['HGLRC', ['wglGetCurrentContext'], ''],
+['HDC', ['wglGetCurrentDC'], ''],
+['BOOL', ['wglMakeCurrent'], 'HDC hdc, HGLRC hglrc'],
+['BOOL', ['wglShareLists'], 'HGLRC hglrc1, HGLRC hglrc2'],
+['BOOL', ['wglSwapIntervalEXT'], 'int interval'],
+['BOOL', ['wglSwapLayerBuffers'], 'HDC hdc, UINT fuPlanes'],
+['const char*', ['wglGetExtensionsStringARB', 'wglGetExtensionsStringEXT'],
+ 'HDC hDC'],
+['BOOL', ['wglChoosePixelFormatARB'],
+ 'HDC dc, const int* int_attrib_list, const float* float_attrib_list, '
+ 'UINT max_formats, int* formats, UINT* num_formats'],
+['HPBUFFERARB', ['wglCreatePbufferARB'],
+ 'HDC hDC, int iPixelFormat, int iWidth, int iHeight, '
+ 'const int* piAttribList'],
+['HDC', ['wglGetPbufferDCARB'], 'HPBUFFERARB hPbuffer'],
+['int', ['wglReleasePbufferDCARB'], 'HPBUFFERARB hPbuffer, HDC hDC'],
+['BOOL', ['wglDestroyPbufferARB'], 'HPBUFFERARB hPbuffer'],
+['BOOL', ['wglQueryPbufferARB'],
+ 'HPBUFFERARB hPbuffer, int iAttribute, int* piValue'],
+]
+
+GLX_FUNCTIONS = [
+['XVisualInfo*', ['glXChooseVisual'],
+ 'Display* dpy, int screen, int* attribList'],
+['GLXContext', ['glXCreateContext'],
+ 'Display* dpy, XVisualInfo* vis, GLXContext shareList, int direct'],
+['void', ['glXDestroyContext'], 'Display* dpy, GLXContext ctx'],
+['int', ['glXMakeCurrent'],
+ 'Display* dpy, GLXDrawable drawable, GLXContext ctx'],
+['void', ['glXCopyContext'],
+ 'Display* dpy, GLXContext src, GLXContext dst, unsigned long mask'],
+['void', ['glXSwapBuffers'], 'Display* dpy, GLXDrawable drawable'],
+['GLXPixmap', ['glXCreateGLXPixmap'],
+ 'Display* dpy, XVisualInfo* visual, Pixmap pixmap'],
+['void', ['glXDestroyGLXPixmap'], 'Display* dpy, GLXPixmap pixmap'],
+['int', ['glXQueryExtension'], 'Display* dpy, int* errorb, int* event'],
+['int', ['glXQueryVersion'], 'Display* dpy, int* maj, int* min'],
+['int', ['glXIsDirect'], 'Display* dpy, GLXContext ctx'],
+['int', ['glXGetConfig'],
+ 'Display* dpy, XVisualInfo* visual, int attrib, int* value'],
+['GLXContext', ['glXGetCurrentContext'], 'void'],
+['GLXDrawable', ['glXGetCurrentDrawable'], 'void'],
+['void', ['glXWaitGL'], 'void'],
+['void', ['glXWaitX'], 'void'],
+['void', ['glXUseXFont'], 'Font font, int first, int count, int list'],
+['const char*', ['glXQueryExtensionsString'], 'Display* dpy, int screen'],
+['const char*', ['glXQueryServerString'], 'Display* dpy, int screen, int name'],
+['const char*', ['glXGetClientString'], 'Display* dpy, int name'],
+['Display*', ['glXGetCurrentDisplay'], 'void'],
+['GLXFBConfig*', ['glXChooseFBConfig'],
+ 'Display* dpy, int screen, const int* attribList, int* nitems'],
+['int', ['glXGetFBConfigAttrib'],
+ 'Display* dpy, GLXFBConfig config, int attribute, int* value'],
+['GLXFBConfig*', ['glXGetFBConfigs'],
+ 'Display* dpy, int screen, int* nelements'],
+['XVisualInfo*', ['glXGetVisualFromFBConfig'],
+ 'Display* dpy, GLXFBConfig config'],
+['GLXWindow', ['glXCreateWindow'],
+ 'Display* dpy, GLXFBConfig config, Window win, const int* attribList'],
+['void', ['glXDestroyWindow'], 'Display* dpy, GLXWindow window'],
+['GLXPixmap', ['glXCreatePixmap'],
+ 'Display* dpy, GLXFBConfig config, Pixmap pixmap, const int* attribList'],
+['void', ['glXDestroyPixmap'], 'Display* dpy, GLXPixmap pixmap'],
+['GLXPbuffer', ['glXCreatePbuffer'],
+ 'Display* dpy, GLXFBConfig config, const int* attribList'],
+['void', ['glXDestroyPbuffer'], 'Display* dpy, GLXPbuffer pbuf'],
+['void', ['glXQueryDrawable'],
+ 'Display* dpy, GLXDrawable draw, int attribute, unsigned int* value'],
+['GLXContext', ['glXCreateNewContext'],
+ 'Display* dpy, GLXFBConfig config, int renderType, '
+ 'GLXContext shareList, int direct'],
+['int', ['glXMakeContextCurrent'],
+ 'Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx'],
+['GLXDrawable', ['glXGetCurrentReadDrawable'], 'void'],
+['int', ['glXQueryContext'],
+ 'Display* dpy, GLXContext ctx, int attribute, int* value'],
+['void', ['glXSelectEvent'],
+ 'Display* dpy, GLXDrawable drawable, unsigned long mask'],
+['void', ['glXGetSelectedEvent'],
+ 'Display* dpy, GLXDrawable drawable, unsigned long* mask'],
+['void', ['glXSwapIntervalEXT'],
+ 'Display* dpy, GLXDrawable drawable, int interval'],
+]
+
+FUNCTION_SETS = [
+ [GL_FUNCTIONS, 'gl'],
+ [OSMESA_FUNCTIONS, 'osmesa'],
+ [EGL_FUNCTIONS, 'egl'],
+ [WGL_FUNCTIONS, 'wgl'],
+ [GLX_FUNCTIONS, 'glx'],
+]
+
+def GenerateHeader(file, functions, set_name):
+ """Generates gl_binding_autogen_x.h"""
+
+ # Write file header.
+ file.write('// Copyright (c) 2011 The Chromium Authors. All rights reserved.\n')
+ file.write('// Use of this source code is governed by a BSD-style license that can be\n')
+ file.write('// found in the LICENSE file.\n')
+ file.write('\n')
+ file.write('// This file is automatically generated.\n')
+ file.write('\n')
+ file.write('#ifndef UI_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' % set_name.upper())
+ file.write('#define UI_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' % set_name.upper())
+
+ # Write prototype for initialization function.
+ file.write('\n')
+ file.write('namespace gfx {\n')
+ file.write('\n')
+ file.write('void InitializeGLBindings%s();\n' % set_name.upper())
+ file.write('void InitializeDebugGLBindings%s();\n' % set_name.upper())
+
+ # Write typedefs for function pointer types. Always use the GL name for the
+ # typedef.
+ file.write('\n')
+ for [return_type, names, arguments] in functions:
+ file.write('typedef %s (GL_BINDING_CALL *%sProc)(%s);\n' %
+ (return_type, names[0], arguments))
+
+ # Write declarations for function pointers. Always use the GL name for the
+ # declaration.
+ file.write('\n')
+ for [return_type, names, arguments] in functions:
+ file.write('extern %sProc g_%s;\n' % (names[0], names[0]))
+ file.write('\n')
+ file.write( '} // namespace gfx\n')
+
+ # Write macros to invoke function pointers. Always use the GL name for the
+ # macro.
+ file.write('\n')
+ for [return_type, names, arguments] in functions:
+ file.write('#define %s ::gfx::g_%s\n' %
+ (names[0], names[0]))
+
+ file.write('\n')
+ file.write('#endif // UI_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' %
+ set_name.upper())
+
+
+def GenerateSource(file, functions, set_name):
+ """Generates gl_binding_autogen_x.cc"""
+
+ # Write file header.
+ file.write('// Copyright (c) 2011 The Chromium Authors. All rights reserved.\n')
+ file.write('// Use of this source code is governed by a BSD-style license that can be\n')
+ file.write('// found in the LICENSE file.\n')
+ file.write('\n')
+ file.write('// This file is automatically generated.\n')
+ file.write('\n')
+ file.write('#include "ui/gfx/gl/gl_bindings.h"\n')
+ file.write('#include "ui/gfx/gl/gl_implementation.h"\n')
+
+ # Write definitions of function pointers.
+ file.write('\n')
+ file.write('namespace gfx {\n')
+ file.write('\n')
+ for [return_type, names, arguments] in functions:
+ file.write('%sProc g_%s;\n' % (names[0], names[0]))
+
+ file.write('\n')
+ for [return_type, names, arguments] in functions:
+ file.write('static %sProc g_debug_%s;\n' % (names[0], names[0]))
+
+ # Write function to initialize the function pointers.
+ file.write('\n')
+ file.write('void InitializeGLBindings%s() {\n' % set_name.upper())
+ for [return_type, names, arguments] in functions:
+ for name in names:
+ file.write(' if (!g_%s)\n' % names[0])
+ file.write(
+ ' g_%s = reinterpret_cast<%sProc>(GetGLProcAddress("%s"));\n' %
+ (names[0], names[0], name))
+ file.write('}\n')
+ file.write('\n')
+
+ # Write logging wrappers for each function.
+ file.write('extern "C" {\n')
+ for [return_type, names, arguments] in functions:
+ file.write('\n')
+ file.write('static %s GL_BINDING_CALL Debug_%s(%s) {\n' %
+ (return_type, names[0], arguments))
+ argument_names = re.sub(r'(const )?[a-zA-Z0-9]+\** ([a-zA-Z0-9]+)', r'\2',
+ arguments)
+ argument_names = re.sub(r'(const )?[a-zA-Z0-9]+\** ([a-zA-Z0-9]+)', r'\2',
+ argument_names)
+ log_argument_names = argument_names.replace(',', ' << ", " <<');
+ if argument_names == 'void' or argument_names == '':
+ argument_names = ''
+ log_argument_names = ''
+ else:
+ log_argument_names = " << " + log_argument_names
+ function_name = names[0]
+ if return_type == 'void':
+ file.write(' GL_SERVICE_LOG("%s" << "(" %s << ")");\n' %
+ (function_name, log_argument_names))
+ file.write(' g_debug_%s(%s);\n' %
+ (function_name, argument_names))
+ else:
+ file.write(' GL_SERVICE_LOG("%s" << "(" %s << ")");\n' %
+ (function_name, log_argument_names))
+ file.write(' %s result = g_debug_%s(%s);\n' %
+ (return_type, function_name, argument_names))
+ file.write(' GL_SERVICE_LOG("GL_RESULT: " << result);\n');
+ file.write(' return result;\n')
+ file.write('}\n')
+ file.write('} // extern "C"\n')
+
+ # Write function to initialize the function pointers.
+ file.write('\n')
+ file.write('void InitializeDebugGLBindings%s() {\n' % set_name.upper())
+ for [return_type, names, arguments] in functions:
+ for name in names:
+ file.write(' if (!g_debug_%s) {\n' % names[0])
+ file.write(' g_debug_%s = g_%s;\n' % (names[0], names[0]))
+ file.write(' g_%s = Debug_%s;\n' % (names[0], names[0]))
+ file.write(' }\n')
+ file.write('}\n')
+ file.write('\n')
+
+ file.write( '} // namespace gfx\n')
+
+
+def GenerateMockSource(file, functions):
+ """Generates functions that invoke a mock GLInterface"""
+
+ file.write('// Copyright (c) 2011 The Chromium Authors. All rights reserved.\n')
+ file.write('// Use of this source code is governed by a BSD-style license that can be\n')
+ file.write('// found in the LICENSE file.\n')
+ file.write('\n')
+ file.write('// This file is automatically generated.\n')
+ file.write('\n')
+ file.write('#include <string.h>\n')
+ file.write('\n')
+ file.write('#include "ui/gfx/gl/gl_interface.h"\n')
+
+ file.write('\n')
+ file.write('namespace gfx {\n')
+
+ # Write function that trampoline into the GLInterface.
+ for [return_type, names, arguments] in functions:
+ file.write('\n')
+ file.write('%s GL_BINDING_CALL Mock_%s(%s) {\n' %
+ (return_type, names[0], arguments))
+ argument_names = re.sub(r'(const )?[a-zA-Z0-9]+\** ([a-zA-Z0-9]+)', r'\2',
+ arguments)
+ if argument_names == 'void':
+ argument_names = ''
+ function_name = names[0][2:]
+ if return_type == 'void':
+ file.write(' GLInterface::GetGLInterface()->%s(%s);\n' %
+ (function_name, argument_names))
+ else:
+ file.write(' return GLInterface::GetGLInterface()->%s(%s);\n' %
+ (function_name, argument_names))
+ file.write('}\n')
+
+ # Write a function to lookup a mock GL function based on its name.
+ file.write('\n')
+ file.write('void* GL_BINDING_CALL GetMockGLProcAddress(const char* name) {\n')
+ for [return_type, names, arguments] in functions:
+ file.write(' if (strcmp(name, "%s") == 0)\n' % names[0])
+ file.write(' return reinterpret_cast<void*>(Mock_%s);\n' % names[0])
+ file.write(' return NULL;\n')
+ file.write('}\n');
+
+ file.write('\n')
+ file.write('} // namespace gfx\n')
+
+
+def main(argv):
+ """This is the main function."""
+
+ if len(argv) >= 1:
+ dir = argv[0]
+ else:
+ dir = '.'
+
+ for [functions, set_name] in FUNCTION_SETS:
+ header_file = open(
+ os.path.join(dir, 'gl_bindings_autogen_%s.h' % set_name), 'wb')
+ GenerateHeader(header_file, functions, set_name)
+ header_file.close()
+
+ source_file = open(
+ os.path.join(dir, 'gl_bindings_autogen_%s.cc' % set_name), 'wb')
+ GenerateSource(source_file, functions, set_name)
+ source_file.close()
+
+ source_file = open(os.path.join(dir, 'gl_bindings_autogen_mock.cc'), 'wb')
+ GenerateMockSource(source_file, GL_FUNCTIONS)
+ source_file.close()
+
+
+if __name__ == '__main__':
+ main(sys.argv[1:])
diff --git a/ui/gfx/gl/gl.gyp b/ui/gfx/gl/gl.gyp
new file mode 100644
index 0000000..f64804b
--- /dev/null
+++ b/ui/gfx/gl/gl.gyp
@@ -0,0 +1,160 @@
+# Copyright (c) 2011 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'target_defaults': {
+ 'sources/': [
+ ['exclude', '/(cocoa|gtk|win)/'],
+ ['exclude', '_(cocoa|gtk|linux|mac|posix|win|x)\\.(cc|mm?)$'],
+ ['exclude', '/(gtk|win|x11)_[^/]*\\.cc$'],
+ ],
+ 'conditions': [
+ ['OS=="linux" or OS=="freebsd" or OS=="openbsd"', {'sources/': [
+ ['include', '/gtk/'],
+ ['include', '_(gtk|linux|posix|skia|x)\\.cc$'],
+ ['include', '/(gtk|x11)_[^/]*\\.cc$'],
+ ]}],
+ ['OS=="mac"', {'sources/': [
+ ['include', '/cocoa/'],
+ ['include', '_(cocoa|mac|posix)\\.(cc|mm?)$'],
+ ]}, { # else: OS != "mac"
+ 'sources/': [
+ ['exclude', '\\.mm?$'],
+ ],
+ }],
+ ['OS=="win"',
+ {'sources/': [
+ ['include', '_(win)\\.cc$'],
+ ['include', '/win/'],
+ ['include', '/win_[^/]*\\.cc$'],
+ ]}],
+ ],
+ },
+ 'targets': [
+ {
+ 'target_name': 'gl',
+ 'type': '<(library)',
+ 'dependencies': [
+ '<(DEPTH)/app/app.gyp:app_base',
+ '<(DEPTH)/base/base.gyp:base',
+ '<(DEPTH)/skia/skia.gyp:skia',
+ '<(DEPTH)/ui/ui.gyp:ui_gfx',
+ ],
+ 'variables': {
+ 'gl_binding_output_dir': '<(SHARED_INTERMEDIATE_DIR)/ui/gfx/gl',
+ },
+ 'include_dirs': [
+ '<(DEPTH)/third_party/mesa/MesaLib/include',
+ '<(gl_binding_output_dir)',
+ ],
+ 'direct_dependent_settings': {
+ 'include_dirs': [
+ '<(DEPTH)/third_party/mesa/MesaLib/include',
+ '<(gl_binding_output_dir)',
+ ],
+ },
+ 'sources': [
+ 'gl_bindings.gypi',
+ 'gl_bindings.h',
+ 'gl_bindings_skia.cc',
+ 'gl_bindings_skia.h',
+ 'gl_context.cc',
+ 'gl_context.h',
+ 'gl_context_linux.cc',
+ 'gl_context_mac.cc',
+ 'gl_context_osmesa.cc',
+ 'gl_context_osmesa.h',
+ 'gl_context_stub.cc',
+ 'gl_context_stub.h',
+ 'gl_context_win.cc',
+ 'gl_implementation.cc',
+ 'gl_implementation.h',
+ 'gl_implementation_linux.cc',
+ 'gl_implementation_mac.cc',
+ 'gl_implementation_win.cc',
+ 'gl_interface.cc',
+ 'gl_interface.h',
+ 'gl_switches.cc',
+ 'gl_switches.h',
+ '<(gl_binding_output_dir)/gl_bindings_autogen_gl.cc',
+ '<(gl_binding_output_dir)/gl_bindings_autogen_gl.h',
+ '<(gl_binding_output_dir)/gl_bindings_autogen_mock.cc',
+ '<(gl_binding_output_dir)/gl_bindings_autogen_osmesa.cc',
+ '<(gl_binding_output_dir)/gl_bindings_autogen_osmesa.h',
+ ],
+ # hard_dependency is necessary for this target because it has actions
+ # that generate header files included by dependent targets. The header
+ # files must be generated before the dependents are compiled. The usual
+ # semantics are to allow the two targets to build concurrently.
+ 'hard_dependency': 1,
+ 'actions': [
+ {
+ 'action_name': 'generate_gl_bindings',
+ 'inputs': [
+ 'generate_bindings.py',
+ ],
+ 'outputs': [
+ '<(gl_binding_output_dir)/gl_bindings_autogen_egl.cc',
+ '<(gl_binding_output_dir)/gl_bindings_autogen_egl.h',
+ '<(gl_binding_output_dir)/gl_bindings_autogen_gl.cc',
+ '<(gl_binding_output_dir)/gl_bindings_autogen_gl.h',
+ '<(gl_binding_output_dir)/gl_bindings_autogen_glx.cc',
+ '<(gl_binding_output_dir)/gl_bindings_autogen_glx.h',
+ '<(gl_binding_output_dir)/gl_bindings_autogen_mock.cc',
+ '<(gl_binding_output_dir)/gl_bindings_autogen_osmesa.cc',
+ '<(gl_binding_output_dir)/gl_bindings_autogen_osmesa.h',
+ '<(gl_binding_output_dir)/gl_bindings_autogen_wgl.cc',
+ '<(gl_binding_output_dir)/gl_bindings_autogen_wgl.h',
+ ],
+ 'action': [
+ 'python',
+ 'generate_bindings.py',
+ '<(gl_binding_output_dir)',
+ ],
+ },
+ ],
+ 'conditions': [
+ ['OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
+ 'sources': [
+ 'gl_context_egl.cc',
+ 'gl_context_egl.h',
+ '<(gl_binding_output_dir)/gl_bindings_autogen_egl.cc',
+ '<(gl_binding_output_dir)/gl_bindings_autogen_egl.h',
+ '<(gl_binding_output_dir)/gl_bindings_autogen_glx.cc',
+ '<(gl_binding_output_dir)/gl_bindings_autogen_glx.h',
+ ],
+ 'include_dirs': [
+ # We don't use angle, but pull the EGL/GLES headers from there.
+ '<(DEPTH)/third_party/angle/include',
+ ],
+ 'all_dependent_settings': {
+ 'defines': [
+ 'GL_GLEXT_PROTOTYPES',
+ ],
+ },
+ }],
+ ['OS=="mac"', {
+ 'link_settings': {
+ 'libraries': [
+ '$(SDKROOT)/System/Library/Frameworks/OpenGL.framework',
+ ],
+ },
+ }],
+ ['OS=="win"', {
+ 'sources': [
+ 'gl_context_egl.cc',
+ 'gl_context_egl.h',
+ '<(gl_binding_output_dir)/gl_bindings_autogen_egl.cc',
+ '<(gl_binding_output_dir)/gl_bindings_autogen_egl.h',
+ '<(gl_binding_output_dir)/gl_bindings_autogen_wgl.cc',
+ '<(gl_binding_output_dir)/gl_bindings_autogen_wgl.h',
+ ],
+ 'include_dirs': [
+ '<(DEPTH)/third_party/angle/include',
+ ],
+ }],
+ ],
+ },
+ ],
+} \ No newline at end of file
diff --git a/ui/gfx/gl/gl_bindings.h b/ui/gfx/gl/gl_bindings.h
new file mode 100644
index 0000000..8c16a97
--- /dev/null
+++ b/ui/gfx/gl/gl_bindings.h
@@ -0,0 +1,98 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Includes the platform independent and platform dependent GL headers.
+// Only include this in cc files. It pulls in system headers, including
+// the X11 headers on linux, which define all kinds of macros that are
+// liable to cause conflicts.
+
+#ifndef UI_GFX_GL_GL_BINDINGS_H_
+#define UI_GFX_GL_GL_BINDINGS_H_
+#pragma once
+
+#include <GL/gl.h>
+#include <GL/glext.h>
+
+#include "build/build_config.h"
+#if defined(OS_WIN)
+#include "base/logging.h"
+#endif
+
+// The standard OpenGL native extension headers are also included.
+#if defined(OS_WIN)
+#include <GL/wglext.h>
+#elif defined(OS_LINUX)
+#include <GL/glx.h>
+#include <GL/glxext.h>
+
+// Undefine some macros defined by X headers. This is why this file should only
+// be included in .cc files.
+#undef Bool
+#undef None
+#undef Status
+
+#elif defined(OS_MACOSX)
+#include <OpenGL/OpenGL.h>
+#endif
+
+#if defined(OS_WIN)
+#define GL_BINDING_CALL WINAPI
+#else
+#define GL_BINDING_CALL
+#endif
+
+#if defined(OS_WIN)
+#define GL_SERVICE_LOG(args) DLOG(INFO) << args;
+#else
+#define GL_SERVICE_LOG(args)
+#endif
+
+// Forward declare OSMesa types.
+typedef struct osmesa_context *OSMesaContext;
+typedef void (*OSMESAproc)();
+
+#if defined(OS_WIN) || defined(OS_LINUX)
+
+// Forward declare EGL types.
+typedef unsigned int EGLBoolean;
+typedef unsigned int EGLenum;
+typedef int EGLint;
+typedef void *EGLConfig;
+typedef void *EGLContext;
+typedef void *EGLDisplay;
+typedef void *EGLSurface;
+typedef void *EGLClientBuffer;
+typedef void (*__eglMustCastToProperFunctionPointerType)(void);
+
+#if defined(OS_WIN)
+typedef HDC EGLNativeDisplayType;
+typedef HBITMAP EGLNativePixmapType;
+typedef HWND EGLNativeWindowType;
+#else
+typedef Display *EGLNativeDisplayType;
+typedef Pixmap EGLNativePixmapType;
+typedef Window EGLNativeWindowType;
+#endif
+
+#endif // OS_WIN || OS_LINUX
+
+#include "gl_bindings_autogen_gl.h"
+#include "gl_bindings_autogen_osmesa.h"
+
+#if defined(OS_WIN)
+#include "gl_bindings_autogen_egl.h"
+#include "gl_bindings_autogen_wgl.h"
+#elif defined(OS_LINUX)
+#include "gl_bindings_autogen_egl.h"
+#include "gl_bindings_autogen_glx.h"
+#endif
+
+namespace gfx {
+
+// Find an entry point to the mock GL implementation.
+void* GL_BINDING_CALL GetMockGLProcAddress(const char* name);
+
+} // namespace gfx
+
+#endif // UI_GFX_GL_GL_BINDINGS_H_
diff --git a/ui/gfx/gl/gl_bindings_skia.cc b/ui/gfx/gl/gl_bindings_skia.cc
new file mode 100644
index 0000000..4f861aa
--- /dev/null
+++ b/ui/gfx/gl/gl_bindings_skia.cc
@@ -0,0 +1,511 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+#include "ui/gfx/gl/gl_bindings_skia.h"
+
+#include "base/logging.h"
+#include "ui/gfx/gl/gl_bindings.h"
+#include "ui/gfx/gl/gl_implementation.h"
+
+// Skia is built against the headers in gpu\GLES. These functions
+// are exported without any call-type modifiers.
+#define GR_GL_FUNCTION_TYPE
+
+#include "third_party/skia/gpu/include/GrGLInterface.h"
+
+namespace {
+
+extern "C" {
+
+// The following stub functions are required because the glXXX routines exported
+// via gl_bindings.h use call-type GL_BINDING_CALL, which on Windows is stdcall.
+// Skia has been built against the GLES headers, so the interfaces in
+// GrGLInterface are __cdecl.
+
+GLvoid StubGLActiveTexture(GLenum texture) {
+ glActiveTexture(texture);
+}
+
+GLvoid StubGLAttachShader(GLuint program, GLuint shader) {
+ glAttachShader(program, shader);
+}
+
+GLvoid StubGLBindAttribLocation(GLuint program, GLuint index,
+ const char* name) {
+ glBindAttribLocation(program, index, name);
+}
+
+GLvoid StubGLBindBuffer(GLenum target, GLuint buffer) {
+ glBindBuffer(target, buffer);
+}
+
+GLvoid StubGLBindFramebuffer(GLenum target, GLuint framebuffer) {
+ glBindFramebufferEXT(target, framebuffer);
+}
+
+GLvoid StubGLBindRenderbuffer(GLenum target, GLuint renderbuffer) {
+ glBindRenderbufferEXT(target, renderbuffer);
+}
+
+GLvoid StubGLBindTexture(GLenum target, GLuint texture) {
+ glBindTexture(target, texture);
+}
+
+GLvoid StubGLBlendColor(GLclampf red, GLclampf green, GLclampf blue,
+ GLclampf alpha) {
+ glBlendColor(red, green, blue, alpha);
+}
+
+GLvoid StubGLBlendFunc(GLenum sfactor, GLenum dfactor) {
+ glBlendFunc(sfactor, dfactor);
+}
+
+GLvoid StubGLBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter) {
+ glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
+ mask, filter);
+}
+
+GLvoid StubGLBufferData(GLenum target, GLsizei size, const void* data,
+ GLenum usage) {
+ glBufferData(target, size, data, usage);
+}
+
+GLvoid StubGLBufferSubData(GLenum target, GLint offset, GLsizei size,
+ const void* data) {
+ glBufferSubData(target, offset, size, data);
+}
+
+GLenum StubGLCheckFramebufferStatus(GLenum target) {
+ return glCheckFramebufferStatusEXT(target);
+}
+
+GLvoid StubGLClear(GLbitfield mask) {
+ glClear(mask);
+}
+
+GLvoid StubGLClearColor(GLclampf red, GLclampf green, GLclampf blue,
+ GLclampf alpha) {
+ glClearColor(red, green, blue, alpha);
+}
+
+GLvoid StubGLClearStencil(GLint s) {
+ glClearStencil(s);
+}
+
+GLvoid StubGLColorMask(GLboolean red, GLboolean green, GLboolean blue,
+ GLboolean alpha) {
+ glColorMask(red, green, blue, alpha);
+}
+
+GLvoid StubGLCompileShader(GLuint shader) {
+ glCompileShader(shader);
+}
+
+GLvoid StubGLCompressedTexImage2D(GLenum target, GLint level,
+ GLenum internalformat, GLsizei width,
+ GLsizei height, GLint border,
+ GLsizei imageSize, const void* data) {
+ glCompressedTexImage2D(target, level, internalformat, width, height, border,
+ imageSize, data);
+}
+
+GLuint StubGLCreateProgram(void) {
+ return glCreateProgram();
+}
+
+GLuint StubGLCreateShader(GLenum type) {
+ return glCreateShader(type);
+}
+
+GLvoid StubGLCullFace(GLenum mode) {
+ glCullFace(mode);
+}
+
+GLvoid StubGLDeleteBuffers(GLsizei n, const GLuint* buffers) {
+ glDeleteBuffersARB(n, buffers);
+}
+
+GLvoid StubGLDeleteFramebuffers(GLsizei n, const GLuint* framebuffers) {
+ glDeleteFramebuffersEXT(n, framebuffers);
+}
+
+GLvoid StubGLDeleteProgram(GLuint program) {
+ glDeleteProgram(program);
+}
+
+GLvoid StubGLDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) {
+ glDeleteRenderbuffersEXT(n, renderbuffers);
+}
+
+GLvoid StubGLDeleteShader(GLuint shader) {
+ glDeleteShader(shader);
+}
+
+GLvoid StubGLDeleteTextures(GLsizei n, const GLuint* textures) {
+ glDeleteTextures(n, textures);
+}
+
+GLvoid StubGLDepthMask(GLboolean flag) {
+ glDepthMask(flag);
+}
+
+GLvoid StubGLDisable(GLenum cap) {
+ glDisable(cap);
+}
+
+GLvoid StubGLDisableVertexAttribArray(GLuint index) {
+ glDisableVertexAttribArray(index);
+}
+
+GLvoid StubGLDrawArrays(GLenum mode, GLint first, GLsizei count) {
+ glDrawArrays(mode, first, count);
+}
+
+GLvoid StubGLDrawElements(GLenum mode, GLsizei count, GLenum type,
+ const void* indices) {
+ glDrawElements(mode, count, type, indices);
+}
+
+GLvoid StubGLEnable(GLenum cap) {
+ glEnable(cap);
+}
+
+GLvoid StubGLEnableVertexAttribArray(GLuint index) {
+ glEnableVertexAttribArray(index);
+}
+
+GLvoid StubGLFramebufferRenderbuffer(GLenum target, GLenum attachment,
+ GLenum renderbuffertarget,
+ GLuint renderbuffer) {
+ glFramebufferRenderbufferEXT(target, attachment, renderbuffertarget,
+ renderbuffer);
+}
+
+GLvoid StubGLFramebufferTexture2D(GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture,
+ GLint level) {
+ glFramebufferTexture2DEXT(target, attachment, textarget, texture, level);
+}
+
+GLvoid StubGLFrontFace(GLenum mode) {
+ glFrontFace(mode);
+}
+
+GLvoid StubGLGenBuffers(GLsizei n, GLuint* buffers) {
+ glGenBuffersARB(n, buffers);
+}
+
+GLvoid StubGLGenFramebuffers(GLsizei n, GLuint* framebuffers) {
+ glGenFramebuffersEXT(n, framebuffers);
+}
+
+GLvoid StubGLGenRenderbuffers(GLsizei n, GLuint* renderbuffers) {
+ glGenRenderbuffersEXT(n, renderbuffers);
+}
+
+GLvoid StubGLGenTextures(GLsizei n, GLuint* textures) {
+ glGenTextures(n, textures);
+}
+
+GLvoid StubGLGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) {
+ glGetBufferParameteriv(target, pname, params);
+}
+
+GLenum StubGLGetError() {
+ return glGetError();
+}
+
+GLvoid StubGLGetIntegerv(GLenum pname, GLint* params) {
+ glGetIntegerv(pname, params);
+}
+
+GLvoid StubGLGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length,
+ char* infolog) {
+ glGetProgramInfoLog(program, bufsize, length, infolog);
+}
+
+GLvoid StubGLGetProgramiv(GLuint program, GLenum pname, GLint* params) {
+ glGetProgramiv(program, pname, params);
+}
+
+GLvoid StubGLGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length,
+ char* infolog) {
+ glGetShaderInfoLog(shader, bufsize, length, infolog);
+}
+
+GLvoid StubGLGetShaderiv(GLuint shader, GLenum pname, GLint* params) {
+ glGetShaderiv(shader, pname, params);
+}
+
+const GLubyte* StubGLGetString(GLenum name) {
+ return glGetString(name);
+}
+
+GLint StubGLGetUniformLocation(GLuint program, const char* name) {
+ return glGetUniformLocation(program, name);
+}
+
+GLvoid StubGLLineWidth(GLfloat width) {
+ glLineWidth(width);
+}
+
+GLvoid StubGLLinkProgram(GLuint program) {
+ glLinkProgram(program);
+}
+
+void* StubGLMapBuffer(GLenum target, GLenum access) {
+ return glMapBuffer(target, access);
+}
+
+GLvoid StubGLPixelStorei(GLenum pname, GLint param) {
+ glPixelStorei(pname, param);
+}
+
+GLvoid StubGLReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, void* pixels) {
+ glReadPixels(x, y, width, height, format, type, pixels);
+}
+
+GLvoid StubGLRenderBufferStorage(GLenum target, GLenum internalformat,
+ GLsizei width, GLsizei height) {
+ glRenderbufferStorageEXT(target, internalformat, width, height);
+}
+
+GLvoid StubGLRenderbufferStorageMultisample(GLenum target, GLsizei samples,
+ GLenum internalformat,
+ GLsizei width, GLsizei height) {
+ glRenderbufferStorageMultisampleEXT(target, samples, internalformat, width,
+ height);
+}
+
+GLvoid StubGLScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
+ glScissor(x, y, width, height);
+}
+
+GLvoid StubGLShaderSource(GLuint shader, GLsizei count, const char** str,
+ const GLint* length) {
+ glShaderSource(shader, count, str, length);
+}
+
+GLvoid StubGLStencilFunc(GLenum func, GLint ref, GLuint mask) {
+ glStencilFunc(func, ref, mask);
+}
+
+GLvoid StubGLStencilFuncSeparate(GLenum face, GLenum func, GLint ref,
+ GLuint mask) {
+ glStencilFuncSeparate(face, func, ref, mask);
+}
+
+GLvoid StubGLStencilMask(GLuint mask) {
+ glStencilMask(mask);
+}
+
+GLvoid StubGLStencilMaskSeparate(GLenum face, GLuint mask) {
+ glStencilMaskSeparate(face, mask);
+}
+
+GLvoid StubGLStencilOp(GLenum fail, GLenum zfail, GLenum zpass) {
+ glStencilOp(fail, zfail, zpass);
+}
+
+GLvoid StubGLStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail,
+ GLenum zpass) {
+ glStencilOpSeparate(face, fail, zfail, zpass);
+}
+
+GLvoid StubGLTexImage2D(GLenum target, GLint level, GLint internalformat,
+ GLsizei width, GLsizei height, GLint border,
+ GLenum format, GLenum type, const void* pixels) {
+ glTexImage2D(target, level, internalformat, width, height, border, format,
+ type, pixels);
+}
+
+GLvoid StubGLTexParameteri(GLenum target, GLenum pname, GLint param) {
+ glTexParameteri(target, pname, param);
+}
+
+GLvoid StubGLTexSubImage2D(GLenum target, GLint level, GLint xoffset,
+ GLint yoffset, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, const void* pixels) {
+ glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type,
+ pixels);
+}
+
+GLvoid StubGLUniform1fv(GLint location, GLsizei count, const GLfloat* v) {
+ glUniform1fv(location, count, v);
+}
+
+GLvoid StubGLUniform1i(GLint location, GLint x) {
+ glUniform1i(location, x);
+}
+
+GLvoid StubGLUniform4fv(GLint location, GLsizei count, const GLfloat* v) {
+ glUniform4fv(location, count, v);
+}
+
+GLvoid StubGLUniformMatrix3fv(GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat* value) {
+ glUniformMatrix3fv(location, count, transpose, value);
+}
+
+GLboolean StubGLUnmapBuffer(GLenum target) {
+ return glUnmapBuffer(target);
+}
+
+GLvoid StubGLUseProgram(GLuint program) {
+ glUseProgram(program);
+}
+
+GLvoid StubGLVertexAttrib4fv(GLuint indx, const GLfloat* values) {
+ glVertexAttrib4fv(indx, values);
+}
+
+GLvoid StubGLVertexAttribPointer(GLuint indx, GLint size, GLenum type,
+ GLboolean normalized, GLsizei stride,
+ const void* ptr) {
+ glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
+}
+
+GLvoid StubGLViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
+ glViewport(x, y, width, height);
+}
+
+} // extern "C"
+
+// Populate |gl_interface| with pointers to the GL implementation used by
+// Chrome.
+void InitializeGrGLInterface(GrGLInterface* gl_interface) {
+
+ // Propagate the type of GL bindings exported back to skia.
+ switch (gfx::GetGLImplementation()) {
+ case gfx::kGLImplementationNone:
+ NOTREACHED();
+ break;
+ case gfx::kGLImplementationDesktopGL:
+ gl_interface->fBindingsExported = kDesktop_GrGLBinding;
+ break;
+ case gfx::kGLImplementationOSMesaGL:
+ gl_interface->fBindingsExported = kDesktop_GrGLBinding;
+ break;
+ case gfx::kGLImplementationEGLGLES2:
+ gl_interface->fBindingsExported = kES2_GrGLBinding;
+ break;
+ case gfx::kGLImplementationMockGL:
+ NOTREACHED();
+ break;
+ }
+
+ gl_interface->fClientActiveTexture = NULL;
+ gl_interface->fColor4ub = NULL;
+ gl_interface->fColorPointer = NULL;
+ gl_interface->fDisableClientState = NULL;
+ gl_interface->fEnableClientState = NULL;
+ gl_interface->fLoadMatrixf = NULL;
+ gl_interface->fMatrixMode = NULL;
+ gl_interface->fPointSize = NULL;
+ gl_interface->fShadeModel = NULL;
+ gl_interface->fTexCoordPointer = NULL;
+ gl_interface->fTexEnvi = NULL;
+ gl_interface->fVertexPointer = NULL;
+
+ gl_interface->fResolveMultisampleFramebuffer = NULL;
+ gl_interface->fActiveTexture = StubGLActiveTexture;
+ gl_interface->fAttachShader = StubGLAttachShader;
+ gl_interface->fBindAttribLocation = StubGLBindAttribLocation;
+ gl_interface->fBindBuffer = StubGLBindBuffer;
+ gl_interface->fBindTexture = StubGLBindTexture;
+ gl_interface->fBlendColor = StubGLBlendColor;
+ gl_interface->fBlendFunc = StubGLBlendFunc;
+ gl_interface->fBufferData = StubGLBufferData;
+ gl_interface->fBufferSubData = StubGLBufferSubData;
+ gl_interface->fClear = StubGLClear;
+ gl_interface->fClearColor = StubGLClearColor;
+ gl_interface->fClearStencil = StubGLClearStencil;
+ gl_interface->fColorMask = StubGLColorMask;
+ gl_interface->fCompileShader = StubGLCompileShader;
+ gl_interface->fCompressedTexImage2D = StubGLCompressedTexImage2D;
+ gl_interface->fCreateProgram = StubGLCreateProgram;
+ gl_interface->fCreateShader = StubGLCreateShader;
+ gl_interface->fCullFace = StubGLCullFace;
+ gl_interface->fDeleteBuffers = StubGLDeleteBuffers;
+ gl_interface->fDeleteProgram = StubGLDeleteProgram;
+ gl_interface->fDeleteShader = StubGLDeleteShader;
+ gl_interface->fDeleteTextures = StubGLDeleteTextures;
+ gl_interface->fDepthMask = StubGLDepthMask;
+ gl_interface->fDisable = StubGLDisable;
+ gl_interface->fDisableVertexAttribArray = StubGLDisableVertexAttribArray;
+ gl_interface->fDrawArrays = StubGLDrawArrays;
+ gl_interface->fDrawElements = StubGLDrawElements;
+ gl_interface->fEnable = StubGLEnable;
+ gl_interface->fEnableVertexAttribArray = StubGLEnableVertexAttribArray;
+ gl_interface->fFrontFace = StubGLFrontFace;
+ gl_interface->fGenBuffers = StubGLGenBuffers;
+ gl_interface->fGenTextures = StubGLGenTextures;
+ gl_interface->fGetBufferParameteriv = StubGLGetBufferParameteriv;
+ gl_interface->fGetError = StubGLGetError;
+ gl_interface->fGetIntegerv = StubGLGetIntegerv;
+ gl_interface->fGetProgramInfoLog = StubGLGetProgramInfoLog;
+ gl_interface->fGetProgramiv = StubGLGetProgramiv;
+ gl_interface->fGetShaderInfoLog = StubGLGetShaderInfoLog;
+ gl_interface->fGetShaderiv = StubGLGetShaderiv;
+ gl_interface->fGetString = StubGLGetString;
+ gl_interface->fGetUniformLocation = StubGLGetUniformLocation;
+ gl_interface->fLineWidth = StubGLLineWidth;
+ gl_interface->fLinkProgram = StubGLLinkProgram;
+ gl_interface->fPixelStorei = StubGLPixelStorei;
+ gl_interface->fReadPixels = StubGLReadPixels;
+ gl_interface->fScissor = StubGLScissor;
+ gl_interface->fShaderSource = StubGLShaderSource;
+ gl_interface->fStencilFunc = StubGLStencilFunc;
+ gl_interface->fStencilFuncSeparate = StubGLStencilFuncSeparate;
+ gl_interface->fStencilMask = StubGLStencilMask;
+ gl_interface->fStencilMaskSeparate = StubGLStencilMaskSeparate;
+ gl_interface->fStencilOp = StubGLStencilOp;
+ gl_interface->fStencilOpSeparate = StubGLStencilOpSeparate;
+ gl_interface->fTexImage2D = StubGLTexImage2D;
+ gl_interface->fTexParameteri = StubGLTexParameteri;
+ gl_interface->fTexSubImage2D = StubGLTexSubImage2D;
+ gl_interface->fUniform1fv = StubGLUniform1fv;
+ gl_interface->fUniform1i = StubGLUniform1i;
+ gl_interface->fUniform4fv = StubGLUniform4fv;
+ gl_interface->fUniformMatrix3fv = StubGLUniformMatrix3fv;
+ gl_interface->fUseProgram = StubGLUseProgram;
+ gl_interface->fVertexAttrib4fv = StubGLVertexAttrib4fv;
+ gl_interface->fVertexAttribPointer = StubGLVertexAttribPointer;
+ gl_interface->fViewport = StubGLViewport;
+ gl_interface->fBindFramebuffer = StubGLBindFramebuffer;
+ gl_interface->fBindRenderbuffer = StubGLBindRenderbuffer;
+ gl_interface->fCheckFramebufferStatus = StubGLCheckFramebufferStatus;
+ gl_interface->fDeleteFramebuffers = StubGLDeleteFramebuffers;
+ gl_interface->fDeleteRenderbuffers = StubGLDeleteRenderbuffers;
+ gl_interface->fFramebufferRenderbuffer = StubGLFramebufferRenderbuffer;
+ gl_interface->fFramebufferTexture2D = StubGLFramebufferTexture2D;
+ gl_interface->fGenFramebuffers = StubGLGenFramebuffers;
+ gl_interface->fGenRenderbuffers = StubGLGenRenderbuffers;
+ gl_interface->fRenderbufferStorage = StubGLRenderBufferStorage;
+ gl_interface->fRenderbufferStorageMultisample =
+ StubGLRenderbufferStorageMultisample;
+ gl_interface->fBlitFramebuffer = StubGLBlitFramebuffer;
+ gl_interface->fMapBuffer = StubGLMapBuffer;
+ gl_interface->fUnmapBuffer = StubGLUnmapBuffer;
+}
+
+} // namespace
+
+namespace gfx {
+
+void BindSkiaToHostGL() {
+ static GrGLInterface host_gl_interface;
+ static bool host_StubGL_initialized = false;
+ if (!host_StubGL_initialized) {
+ InitializeGrGLInterface(&host_gl_interface);
+ GrGLSetGLInterface(&host_gl_interface);
+ host_StubGL_initialized = true;
+ }
+}
+
+} // namespace gfx
diff --git a/ui/gfx/gl/gl_bindings_skia.h b/ui/gfx/gl/gl_bindings_skia.h
new file mode 100644
index 0000000..4433c73
--- /dev/null
+++ b/ui/gfx/gl/gl_bindings_skia.h
@@ -0,0 +1,21 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_GFX_GL_GL_BINDINGS_SKIA_H_
+#define UI_GFX_GL_GL_BINDINGS_SKIA_H_
+#pragma once
+
+namespace gfx {
+
+// The GPU back-end for skia normally makes direct calls to GLES2\gl. Call
+// this routine to bind the skia GL implementation to that exported by the
+// ui/gfx/gl entry points.
+// Note: This override is required to allow the skia gl calls to be correctly
+// routed around the command buffers during execution of the DumpRenderTree
+// layout tests.
+void BindSkiaToHostGL();
+
+}
+
+#endif // UI_GFX_GL_GL_BINDINGS_SKIA_H_
diff --git a/ui/gfx/gl/gl_context.cc b/ui/gfx/gl/gl_context.cc
new file mode 100644
index 0000000..769f28c
--- /dev/null
+++ b/ui/gfx/gl/gl_context.cc
@@ -0,0 +1,58 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+
+#include "base/command_line.h"
+#include "base/logging.h"
+#include "ui/gfx/gl/gl_context.h"
+#include "ui/gfx/gl/gl_bindings.h"
+#include "ui/gfx/gl/gl_implementation.h"
+#include "ui/gfx/gl/gl_switches.h"
+
+namespace gfx {
+
+unsigned int GLContext::GetBackingFrameBufferObject() {
+ return 0;
+}
+
+std::string GLContext::GetExtensions() {
+ DCHECK(IsCurrent());
+ const char* ext = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
+ return std::string(ext ? ext : "");
+}
+
+bool GLContext::HasExtension(const char* name) {
+ std::string extensions = GetExtensions();
+ extensions += " ";
+
+ std::string delimited_name(name);
+ delimited_name += " ";
+
+ return extensions.find(delimited_name) != std::string::npos;
+}
+
+bool GLContext::InitializeCommon() {
+ if (!MakeCurrent()) {
+ LOG(ERROR) << "MakeCurrent failed.";
+ return false;
+ }
+
+ if (!IsOffscreen()) {
+ if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync))
+ SetSwapInterval(0);
+ else
+ SetSwapInterval(1);
+ }
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ if (glGetError() != GL_NO_ERROR) {
+ LOG(ERROR) << "glClear failed.";
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace gfx
diff --git a/ui/gfx/gl/gl_context.h b/ui/gfx/gl/gl_context.h
new file mode 100644
index 0000000..67bba0b
--- /dev/null
+++ b/ui/gfx/gl/gl_context.h
@@ -0,0 +1,82 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_GFX_GL_GL_CONTEXT_H_
+#define UI_GFX_GL_GL_CONTEXT_H_
+#pragma once
+
+#include <string>
+
+#include "build/build_config.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/gfx/size.h"
+
+namespace gfx {
+
+// Encapsulates an OpenGL context, hiding platform specific management.
+class GLContext {
+ public:
+ GLContext() {}
+ virtual ~GLContext() {}
+
+ // Destroys the GL context.
+ virtual void Destroy() = 0;
+
+ // Makes the GL context current on the current thread.
+ virtual bool MakeCurrent() = 0;
+
+ // Returns true if this context is current.
+ virtual bool IsCurrent() = 0;
+
+ // Returns true if this context is offscreen.
+ virtual bool IsOffscreen() = 0;
+
+ // Swaps front and back buffers. This has no effect for off-screen
+ // contexts.
+ virtual bool SwapBuffers() = 0;
+
+ // Get the size of the back buffer.
+ virtual gfx::Size GetSize() = 0;
+
+ // Get the underlying platform specific GL context "handle".
+ virtual void* GetHandle() = 0;
+
+ // Set swap interval. This context must be current.
+ virtual void SetSwapInterval(int interval) = 0;
+
+ // Returns the internal frame buffer object name if the context is backed by
+ // FBO. Otherwise returns 0.
+ virtual unsigned int GetBackingFrameBufferObject();
+
+ // Returns space separated list of extensions. The context must be current.
+ virtual std::string GetExtensions();
+
+ // Returns whether the current context supports the named extension. The
+ // context must be current.
+ bool HasExtension(const char* name);
+
+ static bool InitializeOneOff();
+
+#if !defined(OS_MACOSX)
+ // Create a GL context that renders directly to a view.
+ static GLContext* CreateViewGLContext(gfx::PluginWindowHandle window,
+ bool multisampled);
+#endif
+
+ // Create a GL context used for offscreen rendering. It is initially backed by
+ // a 1x1 pbuffer. Use it to create an FBO to do useful rendering.
+ // |share_context|, if non-NULL, is a context which the internally created
+ // OpenGL context shares textures and other resources.
+ static GLContext* CreateOffscreenGLContext(GLContext* shared_context);
+
+ protected:
+ bool InitializeCommon();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(GLContext);
+};
+
+} // namespace gfx
+
+#endif // UI_GFX_GL_GL_CONTEXT_H_
diff --git a/ui/gfx/gl/gl_context_egl.cc b/ui/gfx/gl/gl_context_egl.cc
new file mode 100644
index 0000000..2b1565f
--- /dev/null
+++ b/ui/gfx/gl/gl_context_egl.cc
@@ -0,0 +1,428 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+#include "build/build_config.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "third_party/angle/include/EGL/egl.h"
+#include "ui/gfx/gl/gl_context_egl.h"
+
+// This header must come after the above third-party include, as
+// it brings in #defines that cause conflicts.
+#include "ui/gfx/gl/gl_bindings.h"
+
+#if defined(OS_LINUX)
+extern "C" {
+#include <X11/Xlib.h>
+}
+#define EGL_HAS_PBUFFERS 1
+#endif
+
+namespace gfx {
+
+namespace {
+
+// The EGL configuration to use.
+EGLDisplay g_display;
+EGLConfig g_config;
+
+// Returns the last EGL error as a string.
+const char* GetLastEGLErrorString() {
+ EGLint error = eglGetError();
+ switch (error) {
+ case EGL_SUCCESS:
+ return "EGL_SUCCESS";
+ case EGL_BAD_ACCESS:
+ return "EGL_BAD_ACCESS";
+ case EGL_BAD_ALLOC:
+ return "EGL_BAD_ALLOC";
+ case EGL_BAD_ATTRIBUTE:
+ return "EGL_BAD_ATTRIBUTE";
+ case EGL_BAD_CONTEXT:
+ return "EGL_BAD_CONTEXT";
+ case EGL_BAD_CONFIG:
+ return "EGL_BAD_CONFIG";
+ case EGL_BAD_CURRENT_SURFACE:
+ return "EGL_BAD_CURRENT_SURFACE";
+ case EGL_BAD_DISPLAY:
+ return "EGL_BAD_DISPLAY";
+ case EGL_BAD_SURFACE:
+ return "EGL_BAD_SURFACE";
+ case EGL_BAD_MATCH:
+ return "EGL_BAD_MATCH";
+ case EGL_BAD_PARAMETER:
+ return "EGL_BAD_PARAMETER";
+ case EGL_BAD_NATIVE_PIXMAP:
+ return "EGL_BAD_NATIVE_PIXMAP";
+ case EGL_BAD_NATIVE_WINDOW:
+ return "EGL_BAD_NATIVE_WINDOW";
+ default:
+ return "UNKNOWN";
+ }
+}
+} // namespace anonymous
+
+SharedEGLSurface::SharedEGLSurface(EGLSurface surface) : surface_(surface) {
+}
+
+SharedEGLSurface::~SharedEGLSurface() {
+ if (surface_) {
+ if (!eglDestroySurface(g_display, surface_)) {
+ LOG(ERROR) << "eglDestroySurface failed with error "
+ << GetLastEGLErrorString();
+ }
+ }
+}
+
+EGLSurface SharedEGLSurface::egl_surface() const {
+ return surface_;
+}
+
+bool BaseEGLContext::InitializeOneOff() {
+ static bool initialized = false;
+ if (initialized)
+ return true;
+
+#ifdef OS_LINUX
+ EGLNativeDisplayType native_display = XOpenDisplay(NULL);
+#else
+ EGLNativeDisplayType native_display = EGL_DEFAULT_DISPLAY;
+#endif
+ g_display = eglGetDisplay(native_display);
+ if (!g_display) {
+ LOG(ERROR) << "eglGetDisplay failed with error " << GetLastEGLErrorString();
+ return false;
+ }
+
+ if (!eglInitialize(g_display, NULL, NULL)) {
+ LOG(ERROR) << "eglInitialize failed with error " << GetLastEGLErrorString();
+ return false;
+ }
+
+ // Choose an EGL configuration.
+ static const EGLint kConfigAttribs[] = {
+ EGL_BUFFER_SIZE, 32,
+ EGL_ALPHA_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_RED_SIZE, 8,
+ EGL_DEPTH_SIZE, 16,
+ EGL_STENCIL_SIZE, 8,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+#ifdef EGL_HAS_PBUFFERS
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
+#else
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+#endif
+ EGL_NONE
+ };
+
+ EGLint num_configs;
+ if (!eglChooseConfig(g_display,
+ kConfigAttribs,
+ NULL,
+ 0,
+ &num_configs)) {
+ LOG(ERROR) << "eglChooseConfig failed failed with error "
+ << GetLastEGLErrorString();
+ return false;
+ }
+
+ if (num_configs == 0) {
+ LOG(ERROR) << "No suitable EGL configs found.";
+ return false;
+ }
+
+ scoped_array<EGLConfig> configs(new EGLConfig[num_configs]);
+ if (!eglChooseConfig(g_display,
+ kConfigAttribs,
+ configs.get(),
+ num_configs,
+ &num_configs)) {
+ LOG(ERROR) << "eglChooseConfig failed with error "
+ << GetLastEGLErrorString();
+ return false;
+ }
+
+ g_config = configs[0];
+
+ initialized = true;
+ return true;
+}
+
+EGLDisplay BaseEGLContext::GetDisplay() {
+ return g_display;
+}
+
+std::string BaseEGLContext::GetExtensions() {
+ const char* extensions = eglQueryString(g_display, EGL_EXTENSIONS);
+ if (!extensions)
+ return GLContext::GetExtensions();
+
+ return GLContext::GetExtensions() + " " + extensions;
+}
+
+NativeViewEGLContext::NativeViewEGLContext(void* window)
+ : window_(window),
+ context_(NULL)
+{
+}
+
+NativeViewEGLContext::~NativeViewEGLContext() {
+}
+
+bool NativeViewEGLContext::Initialize() {
+ DCHECK(!context_);
+
+ // Create a surface for the native window.
+ EGLNativeWindowType native_window =
+ reinterpret_cast<EGLNativeWindowType>(window_);
+ surface_ = new SharedEGLSurface(eglCreateWindowSurface(g_display,
+ g_config,
+ native_window,
+ NULL));
+
+ if (!surface_->egl_surface()) {
+ LOG(ERROR) << "eglCreateWindowSurface failed with error "
+ << GetLastEGLErrorString();
+ Destroy();
+ return false;
+ }
+
+ static const EGLint kContextAttributes[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+
+ context_ = eglCreateContext(g_display, g_config, NULL, kContextAttributes);
+ if (!context_) {
+ LOG(ERROR) << "eglCreateContext failed with error "
+ << GetLastEGLErrorString();
+ Destroy();
+ return false;
+ }
+
+ if (!MakeCurrent()) {
+ LOG(ERROR) << "MakeCurrent failed.";
+ Destroy();
+ return false;
+ }
+
+ if (!InitializeCommon()) {
+ LOG(ERROR) << "GLContext::InitializeCommon failed.";
+ Destroy();
+ return false;
+ }
+
+ return true;
+}
+
+void NativeViewEGLContext::Destroy() {
+ if (context_) {
+ if (!eglDestroyContext(g_display, context_)) {
+ LOG(ERROR) << "eglDestroyContext failed with error "
+ << GetLastEGLErrorString();
+ }
+
+ context_ = NULL;
+ }
+
+ surface_ = NULL;
+}
+
+bool NativeViewEGLContext::MakeCurrent() {
+ DCHECK(context_);
+ if (!eglMakeCurrent(g_display,
+ surface_->egl_surface(),
+ surface_->egl_surface(),
+ context_)) {
+ VLOG(1) << "eglMakeCurrent failed with error "
+ << GetLastEGLErrorString();
+ return false;
+ }
+
+ return true;
+}
+
+bool NativeViewEGLContext::IsCurrent() {
+ DCHECK(context_);
+ return context_ == eglGetCurrentContext();
+}
+
+bool NativeViewEGLContext::IsOffscreen() {
+ return false;
+}
+
+bool NativeViewEGLContext::SwapBuffers() {
+ if (!eglSwapBuffers(g_display, surface_->egl_surface())) {
+ VLOG(1) << "eglSwapBuffers failed with error "
+ << GetLastEGLErrorString();
+ return false;
+ }
+
+ return true;
+}
+
+gfx::Size NativeViewEGLContext::GetSize() {
+#if defined(OS_WIN)
+ RECT rect;
+ if (!GetClientRect(static_cast<HWND>(window_), &rect)) {
+ DCHECK(false) << "GetClientRect failed.";
+ return gfx::Size();
+ }
+
+ return gfx::Size(rect.right - rect.left, rect.bottom - rect.top);
+#else
+ // TODO(piman): This doesn't work correctly on Windows yet, the size doesn't
+ // get updated on resize. When it does, we can share the code.
+ EGLint width;
+ EGLint height;
+ if (!eglQuerySurface(
+ g_display, surface_->egl_surface(), EGL_WIDTH, &width) ||
+ !eglQuerySurface(
+ g_display, surface_->egl_surface(), EGL_HEIGHT, &height)) {
+ NOTREACHED() << "eglQuerySurface failed with error "
+ << GetLastEGLErrorString();
+ return gfx::Size();
+ }
+
+ return gfx::Size(width, height);
+#endif
+}
+
+void* NativeViewEGLContext::GetHandle() {
+ return context_;
+}
+
+void NativeViewEGLContext::SetSwapInterval(int interval) {
+ DCHECK(IsCurrent());
+ if (!eglSwapInterval(g_display, interval)) {
+ LOG(ERROR) << "eglSwapInterval failed with error "
+ << GetLastEGLErrorString();
+ }
+}
+
+SharedEGLSurface* NativeViewEGLContext::GetSurface() {
+ return surface_;
+}
+
+SecondaryEGLContext::SecondaryEGLContext()
+ : context_(NULL)
+{
+}
+
+SecondaryEGLContext::~SecondaryEGLContext() {
+}
+
+bool SecondaryEGLContext::Initialize(GLContext* shared_context) {
+ DCHECK(!context_);
+
+ static const EGLint kContextAttributes[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+
+ if (shared_context) {
+ surface_ = static_cast<BaseEGLContext*>(shared_context)->GetSurface();
+
+ // Create a context.
+ context_ = eglCreateContext(g_display,
+ g_config,
+ shared_context->GetHandle(),
+ kContextAttributes);
+ } else {
+#ifdef EGL_HAS_PBUFFERS
+ static const EGLint kPbufferAttribs[] = {
+ EGL_WIDTH, 1,
+ EGL_HEIGHT, 1,
+ EGL_NONE
+ };
+
+ surface_ = new SharedEGLSurface(eglCreatePbufferSurface(g_display,
+ g_config,
+ kPbufferAttribs));
+ if (!surface_->egl_surface()) {
+ LOG(ERROR) << "eglCreatePbufferSurface failed with error "
+ << GetLastEGLErrorString();
+ Destroy();
+ return false;
+ }
+
+ context_ = eglCreateContext(g_display, g_config, NULL, kContextAttributes);
+#else
+ NOTIMPLEMENTED() << "Offscreen non-shared GLES context";
+ return false;
+#endif
+ }
+
+ if (!context_) {
+ LOG(ERROR) << "eglCreateContext failed with error "
+ << GetLastEGLErrorString();
+ Destroy();
+ return false;
+ }
+
+ return true;
+}
+
+void SecondaryEGLContext::Destroy() {
+ if (context_) {
+ if (!eglDestroyContext(g_display, context_)) {
+ LOG(ERROR) << "eglDestroyContext failed with error "
+ << GetLastEGLErrorString();
+ }
+
+ context_ = NULL;
+ }
+
+ surface_ = NULL;
+}
+
+bool SecondaryEGLContext::MakeCurrent() {
+ DCHECK(context_);
+ if (!eglMakeCurrent(g_display,
+ surface_->egl_surface(),
+ surface_->egl_surface(),
+ context_)) {
+ VLOG(1) << "eglMakeCurrent failed with error "
+ << GetLastEGLErrorString();
+ return false;
+ }
+
+ return true;
+}
+
+bool SecondaryEGLContext::IsCurrent() {
+ DCHECK(context_);
+ return context_ == eglGetCurrentContext();
+}
+
+bool SecondaryEGLContext::IsOffscreen() {
+ return true;
+}
+
+bool SecondaryEGLContext::SwapBuffers() {
+ NOTREACHED() << "Attempted to call SwapBuffers on a SecondaryEGLContext.";
+ return false;
+}
+
+gfx::Size SecondaryEGLContext::GetSize() {
+ NOTREACHED() << "Should not be requesting size of this SecondaryEGLContext.";
+ return gfx::Size(1, 1);
+}
+
+void* SecondaryEGLContext::GetHandle() {
+ return context_;
+}
+
+void SecondaryEGLContext::SetSwapInterval(int interval) {
+ DCHECK(IsCurrent());
+ NOTREACHED() << "Attempt to call SetSwapInterval on a SecondaryEGLContext.";
+}
+
+SharedEGLSurface* SecondaryEGLContext::GetSurface() {
+ return surface_;
+}
+
+} // namespace gfx
diff --git a/ui/gfx/gl/gl_context_egl.h b/ui/gfx/gl/gl_context_egl.h
new file mode 100644
index 0000000..4250457
--- /dev/null
+++ b/ui/gfx/gl/gl_context_egl.h
@@ -0,0 +1,119 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_GFX_GL_GL_CONTEXT_EGL_H_
+#define UI_GFX_GL_GL_CONTEXT_EGL_H_
+#pragma once
+
+#include "base/memory/ref_counted.h"
+#include "ui/gfx/gl/gl_context.h"
+#include "ui/gfx/size.h"
+
+typedef void* EGLDisplay;
+typedef void* EGLContext;
+typedef void* EGLSurface;
+
+namespace gfx {
+
+// Takes ownership of an EGL surface and reference counts it so it can be shared
+// by multiple EGL contexts and destroyed with the last.
+class SharedEGLSurface : public base::RefCounted<SharedEGLSurface> {
+ public:
+ explicit SharedEGLSurface(EGLSurface surface);
+ ~SharedEGLSurface();
+
+ EGLSurface egl_surface() const;
+
+ private:
+ EGLSurface surface_;
+ DISALLOW_COPY_AND_ASSIGN(SharedEGLSurface);
+};
+
+// Interface for EGL contexts. Adds an EGL specific accessor for retreiving
+// the surface.
+class BaseEGLContext : public GLContext {
+ public:
+ BaseEGLContext() {}
+ virtual ~BaseEGLContext() {}
+
+ static bool InitializeOneOff();
+
+ static EGLDisplay GetDisplay();
+
+ // Get the associated EGL surface.
+ virtual SharedEGLSurface* GetSurface() = 0;
+
+ // Implement GLContext.
+ virtual std::string GetExtensions();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(BaseEGLContext);
+};
+
+// Encapsulates an EGL OpenGL ES context that renders to a view.
+class NativeViewEGLContext : public BaseEGLContext {
+ public:
+ explicit NativeViewEGLContext(void* window);
+ virtual ~NativeViewEGLContext();
+
+ // Initialize an EGL context.
+ bool Initialize();
+
+ // Implement GLContext.
+ virtual void Destroy();
+ virtual bool MakeCurrent();
+ virtual bool IsCurrent();
+ virtual bool IsOffscreen();
+ virtual bool SwapBuffers();
+ virtual gfx::Size GetSize();
+ virtual void* GetHandle();
+ virtual void SetSwapInterval(int interval);
+
+ // Implement BaseEGLContext.
+ virtual SharedEGLSurface* GetSurface();
+
+ private:
+ void* window_;
+ scoped_refptr<SharedEGLSurface> surface_;
+ EGLContext context_;
+
+ DISALLOW_COPY_AND_ASSIGN(NativeViewEGLContext);
+};
+
+// Encapsulates an EGL OpenGL ES context intended for offscreen use. It is
+// actually associated with a native window or a pbuffer on supporting platforms
+// and will render to it. The caller must bind an FBO to prevent this.
+// TODO(apatrick): implement pbuffers in ANGLE and change this to
+// PbufferEGLContext and use it on all EGL platforms.
+class SecondaryEGLContext : public BaseEGLContext {
+ public:
+ SecondaryEGLContext();
+ virtual ~SecondaryEGLContext();
+
+ // Initialize an EGL context that shares a namespace with another.
+ bool Initialize(GLContext* shared_context);
+
+ // Implement GLContext.
+ virtual void Destroy();
+ virtual bool MakeCurrent();
+ virtual bool IsCurrent();
+ virtual bool IsOffscreen();
+ virtual bool SwapBuffers();
+ virtual gfx::Size GetSize();
+ virtual void* GetHandle();
+ virtual void SetSwapInterval(int interval);
+
+ // Implement BaseEGLContext.
+ virtual SharedEGLSurface* GetSurface();
+
+ private:
+ scoped_refptr<SharedEGLSurface> surface_;
+ EGLContext context_;
+
+ DISALLOW_COPY_AND_ASSIGN(SecondaryEGLContext);
+};
+
+} // namespace gfx
+
+#endif // UI_GFX_GL_GL_CONTEXT_EGL_H_
diff --git a/ui/gfx/gl/gl_context_linux.cc b/ui/gfx/gl/gl_context_linux.cc
new file mode 100644
index 0000000..430bba5
--- /dev/null
+++ b/ui/gfx/gl/gl_context_linux.cc
@@ -0,0 +1,830 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file implements the ViewGLContext and PbufferGLContext classes.
+
+#include "ui/gfx/gl/gl_context.h"
+
+extern "C" {
+#include <X11/Xlib.h>
+}
+
+#include <GL/osmesa.h>
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "ui/base/x/x11_util.h"
+#include "ui/gfx/gl/gl_bindings.h"
+#include "ui/gfx/gl/gl_context_egl.h"
+#include "ui/gfx/gl/gl_context_osmesa.h"
+#include "ui/gfx/gl/gl_context_stub.h"
+#include "ui/gfx/gl/gl_implementation.h"
+
+namespace {
+
+Display* GetXDisplayHelper() {
+ static Display* display = NULL;
+
+ if (!display) {
+ display = XOpenDisplay(NULL);
+ CHECK(display);
+ }
+
+ return display;
+}
+
+} // namespace
+
+namespace gfx {
+
+typedef GLXContext GLContextHandle;
+typedef GLXPbuffer PbufferHandle;
+
+class BaseLinuxGLContext : public GLContext {
+ public:
+ virtual std::string GetExtensions();
+};
+
+// This class is a wrapper around a GL context that renders directly to a
+// window.
+class ViewGLContext : public GLContext {
+ public:
+ explicit ViewGLContext(gfx::PluginWindowHandle window)
+ : window_(window),
+ context_(NULL) {
+ DCHECK(window);
+ }
+
+ // Initializes the GL context.
+ bool Initialize(bool multisampled);
+
+ virtual void Destroy();
+ virtual bool MakeCurrent();
+ virtual bool IsCurrent();
+ virtual bool IsOffscreen();
+ virtual bool SwapBuffers();
+ virtual gfx::Size GetSize();
+ virtual void* GetHandle();
+ virtual void SetSwapInterval(int interval);
+
+ private:
+ gfx::PluginWindowHandle window_;
+ GLContextHandle context_;
+
+ DISALLOW_COPY_AND_ASSIGN(ViewGLContext);
+};
+
+// This class is a wrapper around a GL context that uses OSMesa to render
+// to an offscreen buffer and then blits it to a window.
+class OSMesaViewGLContext : public GLContext {
+ public:
+ explicit OSMesaViewGLContext(gfx::PluginWindowHandle window)
+ : window_graphics_context_(0),
+ window_(window),
+ pixmap_graphics_context_(0),
+ pixmap_(0) {
+ DCHECK(window);
+ }
+
+ // Initializes the GL context.
+ bool Initialize();
+
+ virtual void Destroy();
+ virtual bool MakeCurrent();
+ virtual bool IsCurrent();
+ virtual bool IsOffscreen();
+ virtual bool SwapBuffers();
+ virtual gfx::Size GetSize();
+ virtual void* GetHandle();
+ virtual void SetSwapInterval(int interval);
+
+ private:
+ bool UpdateSize();
+
+ GC window_graphics_context_;
+ gfx::PluginWindowHandle window_;
+ GC pixmap_graphics_context_;
+ Pixmap pixmap_;
+ OSMesaGLContext osmesa_context_;
+
+ DISALLOW_COPY_AND_ASSIGN(OSMesaViewGLContext);
+};
+
+// This class is a wrapper around a GL context used for offscreen rendering.
+// It is initially backed by a 1x1 pbuffer. Use it to create an FBO to do useful
+// rendering.
+class PbufferGLContext : public GLContext {
+ public:
+ explicit PbufferGLContext()
+ : context_(NULL),
+ pbuffer_(0) {
+ }
+
+ // Initializes the GL context.
+ bool Initialize(GLContext* shared_context);
+
+ virtual void Destroy();
+ virtual bool MakeCurrent();
+ virtual bool IsCurrent();
+ virtual bool IsOffscreen();
+ virtual bool SwapBuffers();
+ virtual gfx::Size GetSize();
+ virtual void* GetHandle();
+ virtual void SetSwapInterval(int interval);
+
+ private:
+ GLContextHandle context_;
+ PbufferHandle pbuffer_;
+
+ DISALLOW_COPY_AND_ASSIGN(PbufferGLContext);
+};
+
+// Backup context if Pbuffers (GLX 1.3) aren't supported. May run slower...
+class PixmapGLContext : public GLContext {
+ public:
+ explicit PixmapGLContext()
+ : context_(NULL),
+ pixmap_(0),
+ glx_pixmap_(0) {
+ }
+
+ // Initializes the GL context.
+ bool Initialize(GLContext* shared_context);
+
+ virtual void Destroy();
+ virtual bool MakeCurrent();
+ virtual bool IsCurrent();
+ virtual bool IsOffscreen();
+ virtual bool SwapBuffers();
+ virtual gfx::Size GetSize();
+ virtual void* GetHandle();
+ virtual void SetSwapInterval(int interval);
+
+ private:
+ GLContextHandle context_;
+ Pixmap pixmap_;
+ GLXPixmap glx_pixmap_;
+
+ DISALLOW_COPY_AND_ASSIGN(PixmapGLContext);
+};
+
+// scoped_ptr functor for XFree(). Use as follows:
+// scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> foo(...);
+// where "XVisualInfo" is any X type that is freed with XFree.
+class ScopedPtrXFree {
+ public:
+ void operator()(void* x) const {
+ ::XFree(x);
+ }
+};
+
+bool GLContext::InitializeOneOff() {
+ static bool initialized = false;
+ if (initialized)
+ return true;
+
+ static const GLImplementation kAllowedGLImplementations[] = {
+ kGLImplementationDesktopGL,
+ kGLImplementationEGLGLES2,
+ kGLImplementationOSMesaGL
+ };
+
+ if (!InitializeRequestedGLBindings(
+ kAllowedGLImplementations,
+ kAllowedGLImplementations + arraysize(kAllowedGLImplementations),
+ kGLImplementationDesktopGL)) {
+ LOG(ERROR) << "InitializeRequestedGLBindings failed.";
+ return false;
+ }
+
+ switch (GetGLImplementation()) {
+ case kGLImplementationDesktopGL: {
+ // Only check the GLX version if we are in fact using GLX. We might
+ // actually be using the mock GL implementation.
+ Display* display = GetXDisplayHelper();
+ int major, minor;
+ if (!glXQueryVersion(display, &major, &minor)) {
+ LOG(ERROR) << "glxQueryVersion failed";
+ return false;
+ }
+
+ if (major == 1 && minor < 3) {
+ LOG(WARNING) << "GLX 1.3 or later is recommended.";
+ }
+
+ break;
+ }
+ case kGLImplementationEGLGLES2:
+ if (!BaseEGLContext::InitializeOneOff()) {
+ LOG(ERROR) << "BaseEGLContext::InitializeOneOff failed.";
+ return false;
+ }
+ break;
+ default:
+ break;
+ }
+
+ initialized = true;
+ return true;
+}
+
+std::string BaseLinuxGLContext::GetExtensions() {
+ Display* display = GetXDisplayHelper();
+ const char* extensions = glXQueryExtensionsString(display, 0);
+ if (extensions) {
+ return GLContext::GetExtensions() + " " + extensions;
+ }
+
+ return GLContext::GetExtensions();
+}
+
+bool ViewGLContext::Initialize(bool multisampled) {
+ if (multisampled) {
+ LOG(WARNING) << "Multisampling not implemented.";
+ }
+
+ Display* display = GetXDisplayHelper();
+ XWindowAttributes attributes;
+ XGetWindowAttributes(display, window_, &attributes);
+ XVisualInfo visual_info_template;
+ visual_info_template.visualid = XVisualIDFromVisual(attributes.visual);
+ int visual_info_count = 0;
+ scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> visual_info_list(
+ XGetVisualInfo(display, VisualIDMask,
+ &visual_info_template,
+ &visual_info_count));
+ DCHECK(visual_info_list.get());
+ DCHECK_GT(visual_info_count, 0);
+ context_ = NULL;
+ for (int i = 0; i < visual_info_count; ++i) {
+ context_ = glXCreateContext(display, visual_info_list.get() + i, 0, True);
+ if (context_)
+ break;
+ }
+ if (!context_) {
+ LOG(ERROR) << "Couldn't create GL context.";
+ return false;
+ }
+
+ if (!MakeCurrent()) {
+ Destroy();
+ LOG(ERROR) << "Couldn't make context current for initialization.";
+ return false;
+ }
+
+ if (!InitializeCommon()) {
+ LOG(ERROR) << "GLContext::InitlializeCommon failed.";
+ Destroy();
+ return false;
+ }
+
+ return true;
+}
+
+void ViewGLContext::Destroy() {
+ Display* display = GetXDisplayHelper();
+ bool result = glXMakeCurrent(display, 0, 0);
+
+ // glXMakeCurrent isn't supposed to fail when unsetting the context, unless
+ // we have pending draws on an invalid window - which shouldn't be the case
+ // here.
+ DCHECK(result);
+ if (context_) {
+ glXDestroyContext(display, context_);
+ context_ = NULL;
+ }
+}
+
+bool ViewGLContext::MakeCurrent() {
+ if (IsCurrent()) {
+ return true;
+ }
+
+ Display* display = GetXDisplayHelper();
+ if (glXMakeCurrent(display, window_, context_) != True) {
+ glXDestroyContext(display, context_);
+ context_ = 0;
+ LOG(ERROR) << "Couldn't make context current.";
+ return false;
+ }
+
+ return true;
+}
+
+bool ViewGLContext::IsCurrent() {
+ return glXGetCurrentDrawable() == window_ &&
+ glXGetCurrentContext() == context_;
+}
+
+bool ViewGLContext::IsOffscreen() {
+ return false;
+}
+
+bool ViewGLContext::SwapBuffers() {
+ Display* display = GetXDisplayHelper();
+ glXSwapBuffers(display, window_);
+ return true;
+}
+
+gfx::Size ViewGLContext::GetSize() {
+ XWindowAttributes attributes;
+ Display* display = GetXDisplayHelper();
+ XGetWindowAttributes(display, window_, &attributes);
+ return gfx::Size(attributes.width, attributes.height);
+}
+
+void* ViewGLContext::GetHandle() {
+ return context_;
+}
+
+void ViewGLContext::SetSwapInterval(int interval) {
+ DCHECK(IsCurrent());
+ if (HasExtension("GLX_EXT_swap_control") && glXSwapIntervalEXT) {
+ Display* display = GetXDisplayHelper();
+ glXSwapIntervalEXT(display, window_, interval);
+ }
+}
+
+bool OSMesaViewGLContext::Initialize() {
+ if (!osmesa_context_.Initialize(OSMESA_BGRA, NULL)) {
+ LOG(ERROR) << "OSMesaGLContext::Initialize failed.";
+ Destroy();
+ return false;
+ }
+
+ window_graphics_context_ = XCreateGC(GetXDisplayHelper(),
+ window_,
+ 0,
+ NULL);
+ if (!window_graphics_context_) {
+ LOG(ERROR) << "XCreateGC failed.";
+ Destroy();
+ return false;
+ }
+
+ UpdateSize();
+
+ return true;
+}
+
+void OSMesaViewGLContext::Destroy() {
+ osmesa_context_.Destroy();
+
+ Display* display = GetXDisplayHelper();
+
+ if (pixmap_graphics_context_) {
+ XFreeGC(display, pixmap_graphics_context_);
+ pixmap_graphics_context_ = NULL;
+ }
+
+ if (pixmap_) {
+ XFreePixmap(display, pixmap_);
+ pixmap_ = 0;
+ }
+
+ if (window_graphics_context_) {
+ XFreeGC(display, window_graphics_context_);
+ window_graphics_context_ = NULL;
+ }
+}
+
+bool OSMesaViewGLContext::MakeCurrent() {
+ // TODO(apatrick): This is a bit of a hack. The window might have had zero
+ // size when the context was initialized. Assume it has a valid size when
+ // MakeCurrent is called and resize the back buffer if necessary.
+ UpdateSize();
+ return osmesa_context_.MakeCurrent();
+}
+
+bool OSMesaViewGLContext::IsCurrent() {
+ return osmesa_context_.IsCurrent();
+}
+
+bool OSMesaViewGLContext::IsOffscreen() {
+ return false;
+}
+
+bool OSMesaViewGLContext::SwapBuffers() {
+ // Update the size before blitting so that the blit size is exactly the same
+ // as the window.
+ if (!UpdateSize()) {
+ LOG(ERROR) << "Failed to update size of OSMesaGLContext.";
+ return false;
+ }
+
+ gfx::Size size = osmesa_context_.GetSize();
+
+ Display* display = GetXDisplayHelper();
+
+ // Copy the frame into the pixmap.
+ XWindowAttributes attributes;
+ XGetWindowAttributes(display, window_, &attributes);
+ ui::PutARGBImage(display,
+ attributes.visual,
+ attributes.depth,
+ pixmap_,
+ pixmap_graphics_context_,
+ static_cast<const uint8*>(osmesa_context_.buffer()),
+ size.width(),
+ size.height());
+
+ // Copy the pixmap to the window.
+ XCopyArea(display,
+ pixmap_,
+ window_,
+ window_graphics_context_,
+ 0, 0,
+ size.width(), size.height(),
+ 0, 0);
+
+ return true;
+}
+
+gfx::Size OSMesaViewGLContext::GetSize() {
+ return osmesa_context_.GetSize();
+}
+
+void* OSMesaViewGLContext::GetHandle() {
+ return osmesa_context_.GetHandle();
+}
+
+void OSMesaViewGLContext::SetSwapInterval(int interval) {
+ DCHECK(IsCurrent());
+ // Fail silently. It is legitimate to set the swap interval on a view context
+ // but XLib does not have those semantics.
+}
+
+bool OSMesaViewGLContext::UpdateSize() {
+ // Get the window size.
+ XWindowAttributes attributes;
+ Display* display = GetXDisplayHelper();
+ XGetWindowAttributes(display, window_, &attributes);
+ gfx::Size window_size = gfx::Size(std::max(1, attributes.width),
+ std::max(1, attributes.height));
+
+ // Early out if the size has not changed.
+ gfx::Size osmesa_size = osmesa_context_.GetSize();
+ if (pixmap_graphics_context_ && pixmap_ && window_size == osmesa_size)
+ return true;
+
+ // Change osmesa surface size to that of window.
+ osmesa_context_.Resize(window_size);
+
+ // Destroy the previous pixmap and graphics context.
+ if (pixmap_graphics_context_) {
+ XFreeGC(display, pixmap_graphics_context_);
+ pixmap_graphics_context_ = NULL;
+ }
+ if (pixmap_) {
+ XFreePixmap(display, pixmap_);
+ pixmap_ = 0;
+ }
+
+ // Recreate a pixmap to hold the frame.
+ pixmap_ = XCreatePixmap(display,
+ window_,
+ window_size.width(),
+ window_size.height(),
+ attributes.depth);
+ if (!pixmap_) {
+ LOG(ERROR) << "XCreatePixmap failed.";
+ return false;
+ }
+
+ // Recreate a graphics context for the pixmap.
+ pixmap_graphics_context_ = XCreateGC(display, pixmap_, 0, NULL);
+ if (!pixmap_graphics_context_) {
+ LOG(ERROR) << "XCreateGC failed";
+ return false;
+ }
+
+ return true;
+}
+
+GLContext* GLContext::CreateViewGLContext(gfx::PluginWindowHandle window,
+ bool multisampled) {
+ switch (GetGLImplementation()) {
+ case kGLImplementationDesktopGL: {
+ scoped_ptr<ViewGLContext> context(new ViewGLContext(window));
+
+ if (!context->Initialize(multisampled))
+ return NULL;
+
+ return context.release();
+ }
+ case kGLImplementationEGLGLES2: {
+ scoped_ptr<NativeViewEGLContext> context(
+ new NativeViewEGLContext(reinterpret_cast<void *>(window)));
+ if (!context->Initialize())
+ return NULL;
+
+ return context.release();
+ }
+ case kGLImplementationOSMesaGL: {
+ scoped_ptr<OSMesaViewGLContext> context(new OSMesaViewGLContext(window));
+
+ if (!context->Initialize())
+ return NULL;
+
+ return context.release();
+ }
+ case kGLImplementationMockGL:
+ return new StubGLContext;
+ default:
+ NOTREACHED();
+ return NULL;
+ }
+}
+
+bool PbufferGLContext::Initialize(GLContext* shared_context) {
+ static const int config_attributes[] = {
+ GLX_DRAWABLE_TYPE,
+ GLX_PBUFFER_BIT,
+ GLX_RENDER_TYPE,
+ GLX_RGBA_BIT,
+ GLX_DOUBLEBUFFER,
+ 0,
+ 0
+ };
+
+ Display* display = GetXDisplayHelper();
+
+ int nelements = 0;
+ // TODO(kbr): figure out whether hardcoding screen to 0 is sufficient.
+ scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> config(
+ glXChooseFBConfig(display, 0, config_attributes, &nelements));
+ if (!config.get()) {
+ LOG(ERROR) << "glXChooseFBConfig failed.";
+ return false;
+ }
+ if (!nelements) {
+ LOG(ERROR) << "glXChooseFBConfig returned 0 elements.";
+ return false;
+ }
+
+ GLContextHandle shared_handle = NULL;
+ if (shared_context)
+ shared_handle = static_cast<GLContextHandle>(shared_context->GetHandle());
+
+ context_ = glXCreateNewContext(display,
+ config.get()[0],
+ GLX_RGBA_TYPE,
+ shared_handle,
+ True);
+ if (!context_) {
+ LOG(ERROR) << "glXCreateNewContext failed.";
+ return false;
+ }
+ static const int pbuffer_attributes[] = {
+ GLX_PBUFFER_WIDTH,
+ 1,
+ GLX_PBUFFER_HEIGHT,
+ 1,
+ 0
+ };
+ pbuffer_ = glXCreatePbuffer(display,
+ config.get()[0], pbuffer_attributes);
+ if (!pbuffer_) {
+ Destroy();
+ LOG(ERROR) << "glXCreatePbuffer failed.";
+ return false;
+ }
+
+ if (!MakeCurrent()) {
+ Destroy();
+ LOG(ERROR) << "Couldn't make context current for initialization.";
+ return false;
+ }
+
+ if (!InitializeCommon()) {
+ LOG(ERROR) << "GLContext::InitializeCommon failed.";
+ Destroy();
+ return false;
+ }
+
+ return true;
+}
+
+void PbufferGLContext::Destroy() {
+ Display* display = GetXDisplayHelper();
+ bool result = glXMakeCurrent(display, 0, 0);
+ // glXMakeCurrent isn't supposed to fail when unsetting the context, unless
+ // we have pending draws on an invalid window - which shouldn't be the case
+ // here.
+ DCHECK(result);
+ if (context_) {
+ glXDestroyContext(display, context_);
+ context_ = NULL;
+ }
+
+ if (pbuffer_) {
+ glXDestroyPbuffer(display, pbuffer_);
+ pbuffer_ = 0;
+ }
+}
+
+bool PbufferGLContext::MakeCurrent() {
+ if (IsCurrent()) {
+ return true;
+ }
+ Display* display = GetXDisplayHelper();
+ if (glXMakeCurrent(display, pbuffer_, context_) != True) {
+ glXDestroyContext(display, context_);
+ context_ = NULL;
+ LOG(ERROR) << "Couldn't make context current.";
+ return false;
+ }
+
+ return true;
+}
+
+bool PbufferGLContext::IsCurrent() {
+ return glXGetCurrentDrawable() == pbuffer_ &&
+ glXGetCurrentContext() == context_;
+}
+
+bool PbufferGLContext::IsOffscreen() {
+ return true;
+}
+
+bool PbufferGLContext::SwapBuffers() {
+ NOTREACHED() << "Attempted to call SwapBuffers on a pbuffer.";
+ return false;
+}
+
+gfx::Size PbufferGLContext::GetSize() {
+ NOTREACHED() << "Should not be requesting size of this pbuffer.";
+ return gfx::Size(1, 1);
+}
+
+void* PbufferGLContext::GetHandle() {
+ return context_;
+}
+
+void PbufferGLContext::SetSwapInterval(int interval) {
+ DCHECK(IsCurrent());
+ NOTREACHED();
+}
+
+bool PixmapGLContext::Initialize(GLContext* shared_context) {
+ VLOG(1) << "GL context: using pixmaps.";
+
+ static int attributes[] = {
+ GLX_RGBA,
+ 0
+ };
+
+ Display* display = GetXDisplayHelper();
+ int screen = DefaultScreen(display);
+
+ scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> visual_info(
+ glXChooseVisual(display, screen, attributes));
+
+ if (!visual_info.get()) {
+ LOG(ERROR) << "glXChooseVisual failed.";
+ return false;
+ }
+
+ GLContextHandle shared_handle = NULL;
+ if (shared_context)
+ shared_handle = static_cast<GLContextHandle>(shared_context->GetHandle());
+
+ context_ = glXCreateContext(display, visual_info.get(), shared_handle, True);
+ if (!context_) {
+ LOG(ERROR) << "glXCreateContext failed.";
+ return false;
+ }
+
+ pixmap_ = XCreatePixmap(display, RootWindow(display, screen), 1, 1,
+ visual_info->depth);
+ if (!pixmap_) {
+ LOG(ERROR) << "XCreatePixmap failed.";
+ return false;
+ }
+
+ glx_pixmap_ = glXCreateGLXPixmap(display, visual_info.get(), pixmap_);
+ if (!glx_pixmap_) {
+ LOG(ERROR) << "XCreatePixmap failed.";
+ return false;
+ }
+
+ if (!MakeCurrent()) {
+ Destroy();
+ LOG(ERROR) << "Couldn't make context current for initialization.";
+ return false;
+ }
+
+ if (!InitializeCommon()) {
+ LOG(ERROR) << "GLContext::InitializeCommon failed.";
+ Destroy();
+ return false;
+ }
+
+ return true;
+}
+
+void PixmapGLContext::Destroy() {
+ Display* display = GetXDisplayHelper();
+ bool result = glXMakeCurrent(display, 0, 0);
+ // glXMakeCurrent isn't supposed to fail when unsetting the context, unless
+ // we have pending draws on an invalid window - which shouldn't be the case
+ // here.
+ DCHECK(result);
+ if (context_) {
+ glXDestroyContext(display, context_);
+ context_ = NULL;
+ }
+
+ if (glx_pixmap_) {
+ glXDestroyGLXPixmap(display, glx_pixmap_);
+ glx_pixmap_ = 0;
+ }
+
+ if (pixmap_) {
+ XFreePixmap(display, pixmap_);
+ pixmap_ = 0;
+ }
+}
+
+bool PixmapGLContext::MakeCurrent() {
+ if (IsCurrent()) {
+ return true;
+ }
+ Display* display = GetXDisplayHelper();
+ if (glXMakeCurrent(display, glx_pixmap_, context_) != True) {
+ glXDestroyContext(display, context_);
+ context_ = NULL;
+ LOG(ERROR) << "Couldn't make context current.";
+ return false;
+ }
+
+ return true;
+}
+
+bool PixmapGLContext::IsCurrent() {
+ return glXGetCurrentDrawable() == glx_pixmap_ &&
+ glXGetCurrentContext() == context_;
+}
+
+bool PixmapGLContext::IsOffscreen() {
+ return true;
+}
+
+bool PixmapGLContext::SwapBuffers() {
+ NOTREACHED() << "Attempted to call SwapBuffers on a pixmap.";
+ return false;
+}
+
+gfx::Size PixmapGLContext::GetSize() {
+ NOTREACHED() << "Should not be requesting size of this pixmap.";
+ return gfx::Size(1, 1);
+}
+
+void* PixmapGLContext::GetHandle() {
+ return context_;
+}
+
+void PixmapGLContext::SetSwapInterval(int interval) {
+ DCHECK(IsCurrent());
+ NOTREACHED();
+}
+
+GLContext* GLContext::CreateOffscreenGLContext(GLContext* shared_context) {
+ switch (GetGLImplementation()) {
+ case kGLImplementationDesktopGL: {
+ scoped_ptr<PbufferGLContext> context(new PbufferGLContext);
+ if (context->Initialize(shared_context))
+ return context.release();
+
+ scoped_ptr<PixmapGLContext> context_pixmap(new PixmapGLContext);
+ if (context_pixmap->Initialize(shared_context))
+ return context_pixmap.release();
+
+ return NULL;
+ }
+ case kGLImplementationEGLGLES2: {
+ scoped_ptr<SecondaryEGLContext> context(
+ new SecondaryEGLContext());
+ if (!context->Initialize(shared_context))
+ return NULL;
+
+ return context.release();
+ }
+ case kGLImplementationOSMesaGL: {
+ scoped_ptr<OSMesaGLContext> context(new OSMesaGLContext);
+ if (!context->Initialize(OSMESA_RGBA, shared_context))
+ return NULL;
+
+ return context.release();
+ }
+ case kGLImplementationMockGL:
+ return new StubGLContext;
+ default:
+ NOTREACHED();
+ return NULL;
+ }
+}
+
+} // namespace gfx
diff --git a/ui/gfx/gl/gl_context_mac.cc b/ui/gfx/gl/gl_context_mac.cc
new file mode 100644
index 0000000..10e8bf3
--- /dev/null
+++ b/ui/gfx/gl/gl_context_mac.cc
@@ -0,0 +1,209 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file implements the ViewGLContext and PbufferGLContext classes.
+
+#include "ui/gfx/gl/gl_context.h"
+
+#include <GL/osmesa.h>
+#include <OpenGL/OpenGL.h>
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "ui/gfx/gl/gl_bindings.h"
+#include "ui/gfx/gl/gl_context_osmesa.h"
+#include "ui/gfx/gl/gl_context_stub.h"
+#include "ui/gfx/gl/gl_implementation.h"
+
+namespace gfx {
+
+typedef CGLContextObj GLContextHandle;
+typedef CGLPBufferObj PbufferHandle;
+
+// This class is a wrapper around a GL context used for offscreen rendering.
+// It is initially backed by a 1x1 pbuffer. Use it to create an FBO to do useful
+// rendering.
+class PbufferGLContext : public GLContext {
+ public:
+ PbufferGLContext()
+ : context_(NULL),
+ pbuffer_(NULL) {
+ }
+
+ // Initializes the GL context.
+ bool Initialize(GLContext* shared_context);
+
+ virtual void Destroy();
+ virtual bool MakeCurrent();
+ virtual bool IsCurrent();
+ virtual bool IsOffscreen();
+ virtual bool SwapBuffers();
+ virtual gfx::Size GetSize();
+ virtual void* GetHandle();
+ virtual void SetSwapInterval(int interval);
+
+ private:
+ GLContextHandle context_;
+ PbufferHandle pbuffer_;
+
+ DISALLOW_COPY_AND_ASSIGN(PbufferGLContext);
+};
+
+bool GLContext::InitializeOneOff() {
+ static bool initialized = false;
+ if (initialized)
+ return true;
+
+ static const GLImplementation kAllowedGLImplementations[] = {
+ kGLImplementationDesktopGL,
+ kGLImplementationOSMesaGL
+ };
+
+ if (!InitializeRequestedGLBindings(
+ kAllowedGLImplementations,
+ kAllowedGLImplementations + arraysize(kAllowedGLImplementations),
+ kGLImplementationDesktopGL)) {
+ LOG(ERROR) << "InitializeRequestedGLBindings failed.";
+ return false;
+ }
+
+ initialized = true;
+ return true;
+}
+
+bool PbufferGLContext::Initialize(GLContext* shared_context) {
+ // Create a 1x1 pbuffer and associated context to bootstrap things.
+ static const CGLPixelFormatAttribute attribs[] = {
+ (CGLPixelFormatAttribute) kCGLPFAPBuffer,
+ (CGLPixelFormatAttribute) 0
+ };
+ CGLPixelFormatObj pixel_format;
+ GLint num_pixel_formats;
+ if (CGLChoosePixelFormat(attribs,
+ &pixel_format,
+ &num_pixel_formats) != kCGLNoError) {
+ LOG(ERROR) << "Error choosing pixel format.";
+ Destroy();
+ return false;
+ }
+ if (!pixel_format) {
+ LOG(ERROR) << "pixel_format == 0.";
+ return false;
+ }
+
+ GLContextHandle shared_handle = NULL;
+ if (shared_context)
+ shared_handle = static_cast<GLContextHandle>(shared_context->GetHandle());
+
+ CGLError res = CGLCreateContext(pixel_format, shared_handle, &context_);
+ CGLDestroyPixelFormat(pixel_format);
+ if (res != kCGLNoError) {
+ LOG(ERROR) << "Error creating context.";
+ Destroy();
+ return false;
+ }
+ if (CGLCreatePBuffer(1, 1,
+ GL_TEXTURE_2D, GL_RGBA,
+ 0, &pbuffer_) != kCGLNoError) {
+ LOG(ERROR) << "Error creating pbuffer.";
+ Destroy();
+ return false;
+ }
+ if (CGLSetPBuffer(context_, pbuffer_, 0, 0, 0) != kCGLNoError) {
+ LOG(ERROR) << "Error attaching pbuffer to context.";
+ Destroy();
+ return false;
+ }
+
+ if (!MakeCurrent()) {
+ Destroy();
+ LOG(ERROR) << "Couldn't make context current for initialization.";
+ return false;
+ }
+
+ if (!InitializeCommon()) {
+ LOG(ERROR) << "GLContext::InitializeCommon failed.";
+ Destroy();
+ return false;
+ }
+
+ return true;
+}
+
+void PbufferGLContext::Destroy() {
+ if (context_) {
+ CGLDestroyContext(context_);
+ context_ = NULL;
+ }
+
+ if (pbuffer_) {
+ CGLDestroyPBuffer(pbuffer_);
+ pbuffer_ = NULL;
+ }
+}
+
+bool PbufferGLContext::MakeCurrent() {
+ if (!IsCurrent()) {
+ if (CGLSetCurrentContext(context_) != kCGLNoError) {
+ LOG(ERROR) << "Unable to make gl context current.";
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool PbufferGLContext::IsCurrent() {
+ return CGLGetCurrentContext() == context_;
+}
+
+bool PbufferGLContext::IsOffscreen() {
+ return true;
+}
+
+bool PbufferGLContext::SwapBuffers() {
+ NOTREACHED() << "Cannot call SwapBuffers on a PbufferGLContext.";
+ return false;
+}
+
+gfx::Size PbufferGLContext::GetSize() {
+ NOTREACHED() << "Should not be requesting size of a PbufferGLContext.";
+ return gfx::Size(1, 1);
+}
+
+void* PbufferGLContext::GetHandle() {
+ return context_;
+}
+
+void PbufferGLContext::SetSwapInterval(int interval) {
+ DCHECK(IsCurrent());
+ NOTREACHED() << "Attempt to call SetSwapInterval on a PbufferGLContext.";
+}
+
+GLContext* GLContext::CreateOffscreenGLContext(GLContext* shared_context) {
+ switch (GetGLImplementation()) {
+ case kGLImplementationDesktopGL: {
+ scoped_ptr<PbufferGLContext> context(new PbufferGLContext);
+ if (!context->Initialize(shared_context))
+ return NULL;
+
+ return context.release();
+ }
+ case kGLImplementationOSMesaGL: {
+ scoped_ptr<OSMesaGLContext> context(new OSMesaGLContext);
+ if (!context->Initialize(OSMESA_RGBA, shared_context))
+ return NULL;
+
+ return context.release();
+ }
+ case kGLImplementationMockGL:
+ return new StubGLContext;
+ default:
+ NOTREACHED();
+ return NULL;
+ }
+}
+
+} // namespace gfx
diff --git a/ui/gfx/gl/gl_context_osmesa.cc b/ui/gfx/gl/gl_context_osmesa.cc
new file mode 100644
index 0000000..9d1e802
--- /dev/null
+++ b/ui/gfx/gl/gl_context_osmesa.cc
@@ -0,0 +1,131 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <GL/osmesa.h>
+
+#include <algorithm>
+
+#include "base/logging.h"
+#include "ui/gfx/gl/gl_bindings.h"
+#include "ui/gfx/gl/gl_context_osmesa.h"
+
+namespace gfx {
+
+OSMesaGLContext::OSMesaGLContext() : context_(NULL)
+{
+}
+
+OSMesaGLContext::~OSMesaGLContext() {
+}
+
+bool OSMesaGLContext::Initialize(GLuint format, GLContext* shared_context) {
+ DCHECK(!context_);
+
+ size_ = gfx::Size(1, 1);
+ buffer_.reset(new int32[1]);
+
+ OSMesaContext shared_handle = NULL;
+ if (shared_context)
+ shared_handle = static_cast<OSMesaContext>(shared_context->GetHandle());
+
+ context_ = OSMesaCreateContextExt(format,
+ 24, // depth bits
+ 8, // stencil bits
+ 0, // accum bits
+ shared_handle);
+ if (!context_) {
+ LOG(ERROR) << "OSMesaCreateContextExt failed.";
+ return false;
+ }
+
+ if (!MakeCurrent()) {
+ LOG(ERROR) << "MakeCurrent failed.";
+ Destroy();
+ return false;
+ }
+
+ // Row 0 is at the top.
+ OSMesaPixelStore(OSMESA_Y_UP, 0);
+
+ if (!InitializeCommon()) {
+ LOG(ERROR) << "GLContext::InitializeCommon failed.";
+ Destroy();
+ return false;
+ }
+
+ return true;
+}
+
+void OSMesaGLContext::Resize(const gfx::Size& new_size) {
+ if (new_size == size_)
+ return;
+
+ // Allocate a new back buffer.
+ scoped_array<int32> new_buffer(new int32[new_size.GetArea()]);
+ memset(new_buffer.get(), 0, new_size.GetArea() * sizeof(new_buffer[0]));
+
+ // Copy the current back buffer into the new buffer.
+ int copy_width = std::min(size_.width(), new_size.width());
+ int copy_height = std::min(size_.height(), new_size.height());
+ for (int y = 0; y < copy_height; ++y) {
+ for (int x = 0; x < copy_width; ++x) {
+ new_buffer[y * new_size.width() + x] = buffer_[y * size_.width() + x];
+ }
+ }
+
+ buffer_.reset(new_buffer.release());
+ size_ = new_size;
+
+ // If this context is current, need to call MakeCurrent again so OSMesa uses
+ // the new buffer.
+ if (IsCurrent())
+ MakeCurrent();
+}
+
+void OSMesaGLContext::Destroy() {
+ if (context_) {
+ OSMesaDestroyContext(static_cast<OSMesaContext>(context_));
+ context_ = NULL;
+ }
+ buffer_.reset();
+ size_ = gfx::Size();
+}
+
+bool OSMesaGLContext::MakeCurrent() {
+ DCHECK(context_);
+ return OSMesaMakeCurrent(static_cast<OSMesaContext>(context_),
+ buffer_.get(),
+ GL_UNSIGNED_BYTE,
+ size_.width(), size_.height()) == GL_TRUE;
+ return true;
+}
+
+bool OSMesaGLContext::IsCurrent() {
+ DCHECK(context_);
+ return context_ == OSMesaGetCurrentContext();
+}
+
+bool OSMesaGLContext::IsOffscreen() {
+ return true;
+}
+
+bool OSMesaGLContext::SwapBuffers() {
+ NOTREACHED() << "Should not call SwapBuffers on an OSMesaGLContext.";
+ return false;
+}
+
+gfx::Size OSMesaGLContext::GetSize() {
+ return size_;
+}
+
+void* OSMesaGLContext::GetHandle() {
+ return context_;
+}
+
+void OSMesaGLContext::SetSwapInterval(int interval) {
+ DCHECK(IsCurrent());
+ NOTREACHED() << "Attempt to call SetSwapInterval on an OSMesaGLContext.";
+}
+
+} // namespace gfx
diff --git a/ui/gfx/gl/gl_context_osmesa.h b/ui/gfx/gl/gl_context_osmesa.h
new file mode 100644
index 0000000..77ca820
--- /dev/null
+++ b/ui/gfx/gl/gl_context_osmesa.h
@@ -0,0 +1,54 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_GFX_GL_GL_CONTEXT_OSMESA_H_
+#define UI_GFX_GL_GL_CONTEXT_OSMESA_H_
+#pragma once
+
+#include "base/memory/scoped_ptr.h"
+#include "ui/gfx/gl/gl_context.h"
+#include "ui/gfx/size.h"
+
+typedef struct osmesa_context *OSMesaContext;
+
+namespace gfx {
+
+// Encapsulates an OSMesa OpenGL context that uses software rendering.
+class OSMesaGLContext : public GLContext {
+ public:
+ OSMesaGLContext();
+ virtual ~OSMesaGLContext();
+
+ // Initialize an OSMesa GL context with the default 1 x 1 initial size.
+ bool Initialize(GLuint format, GLContext* shared_context);
+
+ // Resize the back buffer, preserving the old content. Does nothing if the
+ // size is unchanged.
+ void Resize(const gfx::Size& new_size);
+
+ const void* buffer() const {
+ return buffer_.get();
+ }
+
+ // Implement GLContext.
+ virtual void Destroy();
+ virtual bool MakeCurrent();
+ virtual bool IsCurrent();
+ virtual bool IsOffscreen();
+ virtual bool SwapBuffers();
+ virtual gfx::Size GetSize();
+ virtual void* GetHandle();
+ virtual void SetSwapInterval(int interval);
+
+ private:
+ gfx::Size size_;
+ scoped_array<int32> buffer_;
+ OSMesaContext context_;
+
+ DISALLOW_COPY_AND_ASSIGN(OSMesaGLContext);
+};
+
+} // namespace gfx
+
+#endif // UI_GFX_GL_GL_CONTEXT_OSMESA_H_
diff --git a/ui/gfx/gl/gl_context_stub.cc b/ui/gfx/gl/gl_context_stub.cc
new file mode 100644
index 0000000..6462f61
--- /dev/null
+++ b/ui/gfx/gl/gl_context_stub.cc
@@ -0,0 +1,39 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/gfx/gl/gl_context_stub.h"
+
+namespace gfx {
+
+StubGLContext::~StubGLContext() {}
+
+bool StubGLContext::MakeCurrent() {
+ return true;
+}
+
+bool StubGLContext::IsCurrent() {
+ return true;
+}
+
+bool StubGLContext::IsOffscreen() {
+ return false;
+}
+
+bool StubGLContext::SwapBuffers() {
+ return true;
+}
+
+gfx::Size StubGLContext::GetSize() {
+ return size_;
+}
+
+void* StubGLContext::GetHandle() {
+ return NULL;
+}
+
+std::string StubGLContext::GetExtensions() {
+ return std::string();
+}
+
+} // namespace gfx
diff --git a/ui/gfx/gl/gl_context_stub.h b/ui/gfx/gl/gl_context_stub.h
new file mode 100644
index 0000000..03e5cf4
--- /dev/null
+++ b/ui/gfx/gl/gl_context_stub.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file implements the StubGLContext.
+
+#ifndef UI_GFX_GL_GL_CONTEXT_STUB_H_
+#define UI_GFX_GL_GL_CONTEXT_STUB_H_
+#pragma once
+
+#include "ui/gfx/gl/gl_context.h"
+
+namespace gfx {
+
+// A GLContext that does nothing for unit tests.
+class StubGLContext : public gfx::GLContext {
+ public:
+ virtual ~StubGLContext();
+
+ void SetSize(const gfx::Size& size) { size_ = size; }
+
+ // Implement GLContext.
+ virtual void Destroy() {}
+ virtual bool MakeCurrent();
+ virtual bool IsCurrent();
+ virtual bool IsOffscreen();
+ virtual bool SwapBuffers();
+ virtual gfx::Size GetSize();
+ virtual void* GetHandle();
+ virtual void SetSwapInterval(int interval) {}
+ virtual std::string GetExtensions();
+
+ private:
+ gfx::Size size_;
+};
+
+} // namespace gfx
+
+#endif // UI_GFX_GL_GL_CONTEXT_STUB_H_
diff --git a/ui/gfx/gl/gl_context_win.cc b/ui/gfx/gl/gl_context_win.cc
new file mode 100644
index 0000000..23f98b2
--- /dev/null
+++ b/ui/gfx/gl/gl_context_win.cc
@@ -0,0 +1,743 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file implements the NativeViewGLContext and PbufferGLContext classes.
+
+#include "ui/gfx/gl/gl_context.h"
+
+#include <GL/osmesa.h>
+
+#include <algorithm>
+
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "ui/gfx/gl/gl_bindings.h"
+#include "ui/gfx/gl/gl_context_egl.h"
+#include "ui/gfx/gl/gl_context_osmesa.h"
+#include "ui/gfx/gl/gl_context_stub.h"
+#include "ui/gfx/gl/gl_implementation.h"
+
+namespace gfx {
+
+typedef HGLRC GLContextHandle;
+typedef HPBUFFERARB PbufferHandle;
+
+class BaseWinGLContext : public GLContext {
+ public:
+ virtual std::string GetExtensions();
+
+ virtual HDC GetDC() = 0;
+};
+
+// This class is a wrapper around a GL context that renders directly to a
+// window.
+class NativeViewGLContext : public BaseWinGLContext {
+ public:
+ explicit NativeViewGLContext(gfx::PluginWindowHandle window)
+ : window_(window),
+ device_context_(NULL),
+ context_(NULL) {
+ DCHECK(window);
+ }
+
+ // Initializes the GL context.
+ bool Initialize(bool multisampled);
+
+ virtual void Destroy();
+ virtual bool MakeCurrent();
+ virtual bool IsCurrent();
+ virtual bool IsOffscreen();
+ virtual bool SwapBuffers();
+ virtual gfx::Size GetSize();
+ virtual void* GetHandle();
+ virtual void SetSwapInterval(int interval);
+
+ virtual HDC GetDC();
+
+ private:
+ gfx::PluginWindowHandle window_;
+ HDC device_context_;
+ GLContextHandle context_;
+
+ DISALLOW_COPY_AND_ASSIGN(NativeViewGLContext);
+};
+
+// This class is a wrapper around a GL context that uses OSMesa to render
+// to an offscreen buffer and then blits it to a window.
+class OSMesaViewGLContext : public GLContext {
+ public:
+ explicit OSMesaViewGLContext(gfx::PluginWindowHandle window)
+ : window_(window),
+ device_context_(NULL) {
+ DCHECK(window);
+ }
+
+ // Initializes the GL context.
+ bool Initialize();
+
+ virtual void Destroy();
+ virtual bool MakeCurrent();
+ virtual bool IsCurrent();
+ virtual bool IsOffscreen();
+ virtual bool SwapBuffers();
+ virtual gfx::Size GetSize();
+ virtual void* GetHandle();
+ virtual void SetSwapInterval(int interval);
+
+ private:
+ void UpdateSize();
+
+ gfx::PluginWindowHandle window_;
+ HDC device_context_;
+ OSMesaGLContext osmesa_context_;
+
+ DISALLOW_COPY_AND_ASSIGN(OSMesaViewGLContext);
+};
+
+// This class is a wrapper around a GL context used for offscreen rendering.
+// It is initially backed by a 1x1 pbuffer. Use it to create an FBO to do useful
+// rendering.
+class PbufferGLContext : public GLContext {
+ public:
+ PbufferGLContext()
+ : context_(NULL),
+ device_context_(NULL),
+ pbuffer_(NULL) {
+ }
+
+ // Initializes the GL context.
+ bool Initialize(GLContext* shared_context);
+
+ virtual void Destroy();
+ virtual bool MakeCurrent();
+ virtual bool IsCurrent();
+ virtual bool IsOffscreen();
+ virtual bool SwapBuffers();
+ virtual gfx::Size GetSize();
+ virtual void* GetHandle();
+ virtual void SetSwapInterval(int interval);
+
+ virtual HDC GetDC();
+
+ private:
+ GLContextHandle context_;
+ HDC device_context_;
+ PbufferHandle pbuffer_;
+
+ DISALLOW_COPY_AND_ASSIGN(PbufferGLContext);
+};
+
+static HWND g_window;
+static int g_regular_pixel_format = 0;
+static int g_multisampled_pixel_format = 0;
+
+// When using ANGLE we still need a window for D3D. This context creates the
+// D3D device.
+static BaseEGLContext* g_default_context;
+
+const PIXELFORMATDESCRIPTOR kPixelFormatDescriptor = {
+ sizeof(kPixelFormatDescriptor), // Size of structure.
+ 1, // Default version.
+ PFD_DRAW_TO_WINDOW | // Window drawing support.
+ PFD_SUPPORT_OPENGL | // OpenGL support.
+ PFD_DOUBLEBUFFER, // Double buffering support (not stereo).
+ PFD_TYPE_RGBA, // RGBA color mode (not indexed).
+ 24, // 24 bit color mode.
+ 0, 0, 0, 0, 0, 0, // Don't set RGB bits & shifts.
+ 8, 0, // 8 bit alpha
+ 0, // No accumulation buffer.
+ 0, 0, 0, 0, // Ignore accumulation bits.
+ 24, // 24 bit z-buffer size.
+ 8, // 8-bit stencil buffer.
+ 0, // No aux buffer.
+ PFD_MAIN_PLANE, // Main drawing plane (not overlay).
+ 0, // Reserved.
+ 0, 0, 0, // Layer masks ignored.
+};
+
+LRESULT CALLBACK IntermediateWindowProc(HWND window,
+ UINT message,
+ WPARAM w_param,
+ LPARAM l_param) {
+ return ::DefWindowProc(window, message, w_param, l_param);
+}
+
+// Helper routine that does one-off initialization like determining the
+// pixel format and initializing the GL bindings.
+bool GLContext::InitializeOneOff() {
+ static bool initialized = false;
+ if (initialized)
+ return true;
+
+ static const GLImplementation kAllowedGLImplementations[] = {
+ kGLImplementationEGLGLES2,
+ kGLImplementationDesktopGL,
+ kGLImplementationOSMesaGL
+ };
+
+ if (!InitializeRequestedGLBindings(
+ kAllowedGLImplementations,
+ kAllowedGLImplementations + arraysize(kAllowedGLImplementations),
+ kGLImplementationEGLGLES2)) {
+ LOG(ERROR) << "InitializeRequestedGLBindings failed.";
+ return false;
+ }
+
+ // We must initialize a GL context before we can determine the multi-
+ // sampling supported on the current hardware, so we create an intermediate
+ // window and context here.
+ HINSTANCE module_handle;
+ if (!::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT |
+ GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
+ reinterpret_cast<wchar_t*>(IntermediateWindowProc),
+ &module_handle)) {
+ LOG(ERROR) << "GetModuleHandleEx failed.";
+ return false;
+ }
+
+ WNDCLASS intermediate_class;
+ intermediate_class.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
+ intermediate_class.lpfnWndProc = IntermediateWindowProc;
+ intermediate_class.cbClsExtra = 0;
+ intermediate_class.cbWndExtra = 0;
+ intermediate_class.hInstance = module_handle;
+ intermediate_class.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+ intermediate_class.hCursor = LoadCursor(NULL, IDC_ARROW);
+ intermediate_class.hbrBackground = NULL;
+ intermediate_class.lpszMenuName = NULL;
+ intermediate_class.lpszClassName = L"Intermediate GL Window";
+
+ ATOM class_registration = ::RegisterClass(&intermediate_class);
+ if (!class_registration) {
+ LOG(ERROR) << "RegisterClass failed.";
+ return false;
+ }
+
+ g_window = ::CreateWindow(
+ reinterpret_cast<wchar_t*>(class_registration),
+ L"",
+ WS_OVERLAPPEDWINDOW,
+ 0, 0,
+ 100, 100,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+
+ if (!g_window) {
+ ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration),
+ module_handle);
+ LOG(ERROR) << "CreateWindow failed.";
+ return false;
+ }
+
+ // Early out if OSMesa offscreen renderer or EGL is present.
+ switch (GetGLImplementation()) {
+ case kGLImplementationDesktopGL: {
+ HDC intermediate_dc = ::GetDC(g_window);
+ g_regular_pixel_format = ::ChoosePixelFormat(intermediate_dc,
+ &kPixelFormatDescriptor);
+ if (g_regular_pixel_format == 0) {
+ LOG(ERROR) << "Unable to get the pixel format for GL context.";
+ ::ReleaseDC(g_window, intermediate_dc);
+ ::DestroyWindow(g_window);
+ ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration),
+ module_handle);
+ return false;
+ }
+ if (!::SetPixelFormat(intermediate_dc, g_regular_pixel_format,
+ &kPixelFormatDescriptor)) {
+ LOG(ERROR) << "Unable to set the pixel format for GL context.";
+ ::ReleaseDC(g_window, intermediate_dc);
+ ::DestroyWindow(g_window);
+ ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration),
+ module_handle);
+ return false;
+ }
+
+ // Create a temporary GL context to query for multisampled pixel formats.
+ HGLRC gl_context = wglCreateContext(intermediate_dc);
+ if (wglMakeCurrent(intermediate_dc, gl_context)) {
+ // Get bindings to extension functions that cannot be acquired without a
+ // current context.
+ InitializeGLBindingsGL();
+ InitializeGLBindingsWGL();
+
+ // If the multi-sample extensions are present, query the api to
+ // determine the pixel format.
+ if (wglGetExtensionsStringARB) {
+ std::string extensions =
+ std::string(wglGetExtensionsStringARB(intermediate_dc));
+ extensions += std::string(" ");
+ if (extensions.find("WGL_ARB_pixel_format ")) {
+ int pixel_attributes[] = {
+ WGL_SAMPLES_ARB, 4,
+ WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
+ WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
+ WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
+ WGL_COLOR_BITS_ARB, 24,
+ WGL_ALPHA_BITS_ARB, 8,
+ WGL_DEPTH_BITS_ARB, 24,
+ WGL_STENCIL_BITS_ARB, 8,
+ WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
+ WGL_SAMPLE_BUFFERS_ARB, GL_TRUE,
+ 0, 0};
+
+ float pixel_attributes_f[] = {0, 0};
+ unsigned int num_formats;
+
+ // Query for the highest sampling rate supported, starting at 4x.
+ static const int kSampleCount[] = {4, 2};
+ static const int kNumSamples = 2;
+ for (int sample = 0; sample < kNumSamples; ++sample) {
+ pixel_attributes[1] = kSampleCount[sample];
+ if (wglChoosePixelFormatARB(intermediate_dc,
+ pixel_attributes,
+ pixel_attributes_f,
+ 1,
+ &g_multisampled_pixel_format,
+ &num_formats)) {
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ wglMakeCurrent(intermediate_dc, NULL);
+ wglDeleteContext(gl_context);
+ ReleaseDC(g_window, intermediate_dc);
+ UnregisterClass(reinterpret_cast<wchar_t*>(class_registration),
+ module_handle);
+ break;
+ }
+ case kGLImplementationEGLGLES2:
+ if (!BaseEGLContext::InitializeOneOff()) {
+ LOG(ERROR) << "BaseEGLContext::InitializeOneOff failed.";
+ return false;
+ }
+ break;
+ }
+
+ initialized = true;
+ return true;
+}
+
+
+std::string BaseWinGLContext::GetExtensions() {
+ if (wglGetExtensionsStringARB) {
+ const char* extensions = wglGetExtensionsStringARB(GetDC());
+ if (extensions) {
+ return GLContext::GetExtensions() + " " + extensions;
+ }
+ }
+
+ return GLContext::GetExtensions();
+}
+
+bool NativeViewGLContext::Initialize(bool multisampled) {
+ // The GL context will render to this window.
+ device_context_ = ::GetDC(window_);
+
+ int pixel_format =
+ multisampled ? g_multisampled_pixel_format : g_regular_pixel_format;
+ if (!SetPixelFormat(device_context_,
+ pixel_format,
+ &kPixelFormatDescriptor)) {
+ LOG(ERROR) << "Unable to set the pixel format for GL context.";
+ Destroy();
+ return false;
+ }
+
+ context_ = wglCreateContext(device_context_);
+ if (!context_) {
+ LOG(ERROR) << "Failed to create GL context.";
+ Destroy();
+ return false;
+ }
+
+ if (!MakeCurrent()) {
+ LOG(ERROR) << "MakeCurrent failed.";
+ Destroy();
+ return false;
+ }
+
+ if (!InitializeCommon()) {
+ LOG(ERROR) << "GLContext::InitializeCommon failed.";
+ Destroy();
+ return false;
+ }
+
+ return true;
+}
+
+void NativeViewGLContext::Destroy() {
+ if (context_) {
+ wglDeleteContext(context_);
+ context_ = NULL;
+ }
+
+ if (window_ && device_context_)
+ ReleaseDC(window_, device_context_);
+
+ window_ = NULL;
+ device_context_ = NULL;
+}
+
+bool NativeViewGLContext::MakeCurrent() {
+ if (IsCurrent()) {
+ return true;
+ }
+ if (!wglMakeCurrent(device_context_, context_)) {
+ LOG(ERROR) << "Unable to make gl context current.";
+ return false;
+ }
+
+ return true;
+}
+
+bool NativeViewGLContext::IsCurrent() {
+ return wglGetCurrentDC() == device_context_ &&
+ wglGetCurrentContext() == context_;
+}
+
+bool NativeViewGLContext::IsOffscreen() {
+ return false;
+}
+
+bool NativeViewGLContext::SwapBuffers() {
+ DCHECK(device_context_);
+ return ::SwapBuffers(device_context_) == TRUE;
+}
+
+gfx::Size NativeViewGLContext::GetSize() {
+ RECT rect;
+ CHECK(GetClientRect(window_, &rect));
+ return gfx::Size(rect.right - rect.left, rect.bottom - rect.top);
+}
+
+void* NativeViewGLContext::GetHandle() {
+ return context_;
+}
+
+void NativeViewGLContext::SetSwapInterval(int interval) {
+ DCHECK(IsCurrent());
+ if (HasExtension("WGL_EXT_swap_control") && wglSwapIntervalEXT) {
+ wglSwapIntervalEXT(interval);
+ }
+}
+
+HDC NativeViewGLContext::GetDC() {
+ return device_context_;
+}
+
+bool OSMesaViewGLContext::Initialize() {
+ // The GL context will render to this window.
+ device_context_ = GetDC(window_);
+
+ if (!osmesa_context_.Initialize(OSMESA_RGBA, NULL)) {
+ LOG(ERROR) << "OSMesaGLContext::Initialize failed.";
+ Destroy();
+ return false;
+ }
+
+ UpdateSize();
+
+ return true;
+}
+
+void OSMesaViewGLContext::Destroy() {
+ osmesa_context_.Destroy();
+
+ if (window_ && device_context_)
+ ReleaseDC(window_, device_context_);
+
+ window_ = NULL;
+ device_context_ = NULL;
+}
+
+bool OSMesaViewGLContext::MakeCurrent() {
+ // TODO(apatrick): This is a bit of a hack. The window might have had zero
+ // size when the context was initialized. Assume it has a valid size when
+ // MakeCurrent is called and resize the back buffer if necessary.
+ UpdateSize();
+ return osmesa_context_.MakeCurrent();
+}
+
+bool OSMesaViewGLContext::IsCurrent() {
+ return osmesa_context_.IsCurrent();
+}
+
+bool OSMesaViewGLContext::IsOffscreen() {
+ return false;
+}
+
+bool OSMesaViewGLContext::SwapBuffers() {
+ DCHECK(device_context_);
+
+ // Update the size before blitting so that the blit size is exactly the same
+ // as the window.
+ UpdateSize();
+
+ gfx::Size size = osmesa_context_.GetSize();
+
+ // Note: negating the height below causes GDI to treat the bitmap data as row
+ // 0 being at the top.
+ BITMAPV4HEADER info = { sizeof(BITMAPV4HEADER) };
+ info.bV4Width = size.width();
+ info.bV4Height = -size.height();
+ info.bV4Planes = 1;
+ info.bV4BitCount = 32;
+ info.bV4V4Compression = BI_BITFIELDS;
+ info.bV4RedMask = 0x000000FF;
+ info.bV4GreenMask = 0x0000FF00;
+ info.bV4BlueMask = 0x00FF0000;
+ info.bV4AlphaMask = 0xFF000000;
+
+ // Copy the back buffer to the window's device context. Do not check whether
+ // StretchDIBits succeeds or not. It will fail if the window has been
+ // destroyed but it is preferable to allow rendering to silently fail if the
+ // window is destroyed. This is because the primary application of this
+ // class of GLContext is for testing and we do not want every GL related ui /
+ // browser test to become flaky if there is a race condition between GL
+ // context destruction and window destruction.
+ StretchDIBits(device_context_,
+ 0, 0, size.width(), size.height(),
+ 0, 0, size.width(), size.height(),
+ osmesa_context_.buffer(),
+ reinterpret_cast<BITMAPINFO*>(&info),
+ DIB_RGB_COLORS,
+ SRCCOPY);
+
+ return true;
+}
+
+gfx::Size OSMesaViewGLContext::GetSize() {
+ return osmesa_context_.GetSize();
+}
+
+void* OSMesaViewGLContext::GetHandle() {
+ return osmesa_context_.GetHandle();
+}
+
+void OSMesaViewGLContext::SetSwapInterval(int interval) {
+ DCHECK(IsCurrent());
+ // Fail silently. It is legitimate to set the swap interval on a view context
+ // but GDI does not have those semantics.
+}
+
+void OSMesaViewGLContext::UpdateSize() {
+ // Change back buffer size to that of window. If window handle is invalid, do
+ // not change the back buffer size.
+ RECT rect;
+ if (!GetClientRect(window_, &rect))
+ return;
+
+ gfx::Size window_size = gfx::Size(
+ std::max(1, static_cast<int>(rect.right - rect.left)),
+ std::max(1, static_cast<int>(rect.bottom - rect.top)));
+ osmesa_context_.Resize(window_size);
+}
+
+GLContext* GLContext::CreateViewGLContext(gfx::PluginWindowHandle window,
+ bool multisampled) {
+ switch (GetGLImplementation()) {
+ case kGLImplementationOSMesaGL: {
+ scoped_ptr<OSMesaViewGLContext> context(new OSMesaViewGLContext(window));
+ if (!context->Initialize())
+ return NULL;
+
+ return context.release();
+ }
+ case kGLImplementationEGLGLES2: {
+ scoped_ptr<NativeViewEGLContext> context(
+ new NativeViewEGLContext(window));
+ if (!context->Initialize())
+ return NULL;
+
+ return context.release();
+ }
+ case kGLImplementationDesktopGL: {
+ scoped_ptr<NativeViewGLContext> context(new NativeViewGLContext(window));
+ if (!context->Initialize(multisampled))
+ return NULL;
+
+ return context.release();
+ }
+ case kGLImplementationMockGL:
+ return new StubGLContext;
+ default:
+ NOTREACHED();
+ return NULL;
+ }
+}
+
+bool PbufferGLContext::Initialize(GLContext* shared_context) {
+ // Create a device context compatible with the primary display.
+ HDC display_device_context = ::CreateDC(L"DISPLAY", NULL, NULL, NULL);
+
+ // Create a 1 x 1 pbuffer suitable for use with the device. This is just
+ // a stepping stone towards creating a frame buffer object. It doesn't
+ // matter what size it is.
+ if (!wglCreatePbufferARB) {
+ LOG(ERROR) << "wglCreatePbufferARB not available.";
+ Destroy();
+ return false;
+ }
+ const int kNoAttributes[] = { 0 };
+ pbuffer_ = wglCreatePbufferARB(display_device_context,
+ g_regular_pixel_format,
+ 1, 1,
+ kNoAttributes);
+ ::DeleteDC(display_device_context);
+ if (!pbuffer_) {
+ LOG(ERROR) << "Unable to create pbuffer.";
+ Destroy();
+ return false;
+ }
+
+ device_context_ = wglGetPbufferDCARB(pbuffer_);
+ if (!device_context_) {
+ LOG(ERROR) << "Unable to get pbuffer device context.";
+ Destroy();
+ return false;
+ }
+
+ context_ = wglCreateContext(device_context_);
+ if (!context_) {
+ LOG(ERROR) << "Failed to create GL context.";
+ Destroy();
+ return false;
+ }
+
+ if (shared_context) {
+ if (!wglShareLists(
+ static_cast<GLContextHandle>(shared_context->GetHandle()), context_)) {
+ LOG(ERROR) << "Could not share GL contexts.";
+ Destroy();
+ return false;
+ }
+ }
+
+ if (!MakeCurrent()) {
+ LOG(ERROR) << "MakeCurrent failed.";
+ Destroy();
+ return false;
+ }
+
+ if (!InitializeCommon()) {
+ LOG(ERROR) << "GLContext::InitializeCommon failed.";
+ Destroy();
+ return false;
+ }
+
+ return true;
+}
+
+void PbufferGLContext::Destroy() {
+ if (context_) {
+ wglDeleteContext(context_);
+ context_ = NULL;
+ }
+
+ if (pbuffer_ && device_context_)
+ wglReleasePbufferDCARB(pbuffer_, device_context_);
+
+ device_context_ = NULL;
+
+ if (pbuffer_) {
+ wglDestroyPbufferARB(pbuffer_);
+ pbuffer_ = NULL;
+ }
+}
+
+bool PbufferGLContext::MakeCurrent() {
+ if (IsCurrent()) {
+ return true;
+ }
+ if (!wglMakeCurrent(device_context_, context_)) {
+ LOG(ERROR) << "Unable to make gl context current.";
+ return false;
+ }
+
+ return true;
+}
+
+bool PbufferGLContext::IsCurrent() {
+ return wglGetCurrentDC() == device_context_ &&
+ wglGetCurrentContext() == context_;
+}
+
+bool PbufferGLContext::IsOffscreen() {
+ return true;
+}
+
+bool PbufferGLContext::SwapBuffers() {
+ NOTREACHED() << "Attempted to call SwapBuffers on a pbuffer.";
+ return false;
+}
+
+gfx::Size PbufferGLContext::GetSize() {
+ NOTREACHED() << "Should not be requesting size of this pbuffer.";
+ return gfx::Size(1, 1);
+}
+
+void* PbufferGLContext::GetHandle() {
+ return context_;
+}
+
+void PbufferGLContext::SetSwapInterval(int interval) {
+ DCHECK(IsCurrent());
+ NOTREACHED() << "Attempt to call SetSwapInterval on a PbufferGLContext.";
+}
+
+HDC PbufferGLContext::GetDC() {
+ return device_context_;
+}
+
+GLContext* GLContext::CreateOffscreenGLContext(GLContext* shared_context) {
+ switch (GetGLImplementation()) {
+ case kGLImplementationOSMesaGL: {
+ scoped_ptr<OSMesaGLContext> context(new OSMesaGLContext);
+ if (!context->Initialize(OSMESA_RGBA, shared_context))
+ return NULL;
+
+ return context.release();
+ }
+ case kGLImplementationEGLGLES2: {
+ if (!shared_context) {
+ if (!g_default_context) {
+ scoped_ptr<NativeViewEGLContext> default_context(
+ new NativeViewEGLContext(g_window));
+ if (!default_context->Initialize())
+ return NULL;
+
+ g_default_context = default_context.release();
+ }
+ shared_context = g_default_context;
+ }
+
+ scoped_ptr<SecondaryEGLContext> context(
+ new SecondaryEGLContext());
+ if (!context->Initialize(shared_context))
+ return NULL;
+
+ return context.release();
+ }
+ case kGLImplementationDesktopGL: {
+ scoped_ptr<PbufferGLContext> context(new PbufferGLContext);
+ if (!context->Initialize(shared_context))
+ return NULL;
+
+ return context.release();
+ }
+ case kGLImplementationMockGL:
+ return new StubGLContext;
+ default:
+ NOTREACHED();
+ return NULL;
+ }
+}
+
+} // namespace gfx
diff --git a/ui/gfx/gl/gl_implementation.cc b/ui/gfx/gl/gl_implementation.cc
new file mode 100644
index 0000000..b38b2647
--- /dev/null
+++ b/ui/gfx/gl/gl_implementation.cc
@@ -0,0 +1,147 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/gfx/gl/gl_implementation.h"
+
+#include <algorithm>
+#include <string>
+
+#include "base/at_exit.h"
+#include "base/command_line.h"
+#include "base/logging.h"
+#include "ui/gfx/gl/gl_switches.h"
+
+namespace gfx {
+
+const char kGLImplementationDesktopName[] = "desktop";
+const char kGLImplementationOSMesaName[] = "osmesa";
+const char kGLImplementationEGLName[] = "egl";
+const char kGLImplementationMockName[] = "mock";
+
+namespace {
+
+const struct {
+ const char* name;
+ GLImplementation implementation;
+} kGLImplementationNamePairs[] = {
+ { kGLImplementationDesktopName, kGLImplementationDesktopGL },
+ { kGLImplementationOSMesaName, kGLImplementationOSMesaGL },
+ { kGLImplementationEGLName, kGLImplementationEGLGLES2 },
+ { kGLImplementationMockName, kGLImplementationMockGL }
+};
+
+typedef std::vector<base::NativeLibrary> LibraryArray;
+
+GLImplementation g_gl_implementation = kGLImplementationNone;
+LibraryArray* g_libraries;
+GLGetProcAddressProc g_get_proc_address;
+
+void CleanupNativeLibraries(void* unused) {
+ if (g_libraries) {
+ for (LibraryArray::iterator it = g_libraries->begin();
+ it != g_libraries->end(); ++it) {
+ base::UnloadNativeLibrary(*it);
+ }
+ delete g_libraries;
+ g_libraries = NULL;
+ }
+}
+}
+
+GLImplementation GetNamedGLImplementation(const std::string& name) {
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kGLImplementationNamePairs); ++i) {
+ if (name == kGLImplementationNamePairs[i].name)
+ return kGLImplementationNamePairs[i].implementation;
+ }
+
+ return kGLImplementationNone;
+}
+
+const char* GetGLImplementationName(GLImplementation implementation) {
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kGLImplementationNamePairs); ++i) {
+ if (implementation == kGLImplementationNamePairs[i].implementation)
+ return kGLImplementationNamePairs[i].name;
+ }
+
+ return "unknown";
+}
+
+bool InitializeRequestedGLBindings(
+ const GLImplementation* allowed_implementations_begin,
+ const GLImplementation* allowed_implementations_end,
+ GLImplementation default_implementation) {
+ if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseGL)) {
+ std::string requested_implementation_name =
+ CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switches::kUseGL);
+ GLImplementation requested_implementation =
+ GetNamedGLImplementation(requested_implementation_name);
+ if (std::find(allowed_implementations_begin,
+ allowed_implementations_end,
+ requested_implementation) == allowed_implementations_end) {
+ LOG(ERROR) << "Requested GL implementation is not available.";
+ return false;
+ }
+
+ InitializeGLBindings(requested_implementation);
+ } else {
+ InitializeGLBindings(default_implementation);
+ }
+
+ if (GetGLImplementation() == kGLImplementationNone) {
+ LOG(ERROR) << "Could not initialize GL.";
+ return false;
+ } else {
+ LOG(INFO) << "Using "
+ << GetGLImplementationName(GetGLImplementation())
+ << " GL implementation.";
+ return true;
+ }
+}
+
+void SetGLImplementation(GLImplementation implementation) {
+ g_gl_implementation = implementation;
+}
+
+GLImplementation GetGLImplementation() {
+ return g_gl_implementation;
+}
+
+void AddGLNativeLibrary(base::NativeLibrary library) {
+ DCHECK(library);
+
+ if (!g_libraries) {
+ g_libraries = new LibraryArray;
+ base::AtExitManager::RegisterCallback(CleanupNativeLibraries, NULL);
+ }
+
+ g_libraries->push_back(library);
+}
+
+void SetGLGetProcAddressProc(GLGetProcAddressProc proc) {
+ DCHECK(proc);
+ g_get_proc_address = proc;
+}
+
+void* GetGLProcAddress(const char* name) {
+ DCHECK(g_gl_implementation != kGLImplementationNone);
+
+ if (g_libraries) {
+ for (size_t i = 0; i < g_libraries->size(); ++i) {
+ void* proc = base::GetFunctionPointerFromNativeLibrary((*g_libraries)[i],
+ name);
+ if (proc)
+ return proc;
+ }
+ }
+
+ if (g_get_proc_address) {
+ void* proc = g_get_proc_address(name);
+ if (proc)
+ return proc;
+ }
+
+ return NULL;
+}
+
+} // namespace gfx
diff --git a/ui/gfx/gl/gl_implementation.h b/ui/gfx/gl/gl_implementation.h
new file mode 100644
index 0000000..f357b31
--- /dev/null
+++ b/ui/gfx/gl/gl_implementation.h
@@ -0,0 +1,74 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_GFX_GL_GL_IMPLEMENTATION_H_
+#define UI_GFX_GL_GL_IMPLEMENTATION_H_
+#pragma once
+
+#include <string>
+
+#include "base/native_library.h"
+#include "build/build_config.h"
+
+namespace gfx {
+
+// The GL implementation currently in use.
+enum GLImplementation {
+ kGLImplementationNone,
+ kGLImplementationDesktopGL,
+ kGLImplementationOSMesaGL,
+ kGLImplementationEGLGLES2,
+ kGLImplementationMockGL
+};
+
+// The GL implementation names that can be passed to --use-gl.
+extern const char kGLImplementationDesktopName[];
+extern const char kGLImplementationOSMesaName[];
+extern const char kGLImplementationEGLName[];
+extern const char kGLImplementationMockName[];
+
+#if defined(OS_WIN)
+typedef void* (WINAPI *GLGetProcAddressProc)(const char* name);
+#else
+typedef void* (*GLGetProcAddressProc)(const char* name);
+#endif
+
+// Initialize a particular GL implementation.
+bool InitializeGLBindings(GLImplementation implementation);
+
+// Initialize Debug logging wrappers for GL bindings.
+void InitializeDebugGLBindings();
+
+// Set the current GL implementation.
+void SetGLImplementation(GLImplementation implementation);
+
+// Get the current GL implementation.
+GLImplementation GetGLImplementation();
+
+// Get the GL implementation with a given name.
+GLImplementation GetNamedGLImplementation(const std::wstring& name);
+
+// Get the name of a GL implementation.
+const char* GetGLImplementationName(GLImplementation implementation);
+
+// Initialize the preferred GL binding from the given list. The preferred GL
+// bindings depend on command line switches passed by the user and which GL
+// implementation is the default on a given platform.
+bool InitializeRequestedGLBindings(
+ const GLImplementation* allowed_implementations_begin,
+ const GLImplementation* allowed_implementations_end,
+ GLImplementation default_implementation);
+
+// Add a native library to those searched for GL entry points.
+void AddGLNativeLibrary(base::NativeLibrary library);
+
+// Set an additional function that will be called to find GL entry points.
+void SetGLGetProcAddressProc(GLGetProcAddressProc proc);
+
+// Find an entry point in the current GL implementation.
+void* GetGLProcAddress(const char* name);
+
+} // namespace gfx
+
+#endif // UI_GFX_GL_GL_IMPLEMENTATION_H_
diff --git a/ui/gfx/gl/gl_implementation_linux.cc b/ui/gfx/gl/gl_implementation_linux.cc
new file mode 100644
index 0000000..34069cf
--- /dev/null
+++ b/ui/gfx/gl/gl_implementation_linux.cc
@@ -0,0 +1,160 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <vector>
+
+#include "base/base_paths.h"
+#include "base/command_line.h"
+#include "base/file_path.h"
+#include "base/logging.h"
+#include "base/native_library.h"
+#include "base/path_service.h"
+#include "ui/gfx/gl/gl_bindings.h"
+#include "ui/gfx/gl/gl_implementation.h"
+
+namespace gfx {
+namespace {
+
+// TODO(piman): it should be Desktop GL marshalling from double to float. Today
+// on native GLES, we do float->double->float.
+void GL_BINDING_CALL MarshalClearDepthToClearDepthf(GLclampd depth) {
+ glClearDepthf(static_cast<GLclampf>(depth));
+}
+
+void GL_BINDING_CALL MarshalDepthRangeToDepthRangef(GLclampd z_near,
+ GLclampd z_far) {
+ glDepthRangef(static_cast<GLclampf>(z_near), static_cast<GLclampf>(z_far));
+}
+
+} // namespace anonymous
+
+bool InitializeGLBindings(GLImplementation implementation) {
+ // Prevent reinitialization with a different implementation. Once the gpu
+ // unit tests have initialized with kGLImplementationMock, we don't want to
+ // later switch to another GL implementation.
+ if (GetGLImplementation() != kGLImplementationNone)
+ return true;
+
+ switch (implementation) {
+ case kGLImplementationOSMesaGL: {
+ FilePath module_path;
+ if (!PathService::Get(base::DIR_MODULE, &module_path)) {
+ LOG(ERROR) << "PathService::Get failed.";
+ return false;
+ }
+
+ base::NativeLibrary library = base::LoadNativeLibrary(
+ module_path.Append("libosmesa.so"));
+ if (!library) {
+ VLOG(1) << "libosmesa.so not found";
+ return false;
+ }
+
+ GLGetProcAddressProc get_proc_address =
+ reinterpret_cast<GLGetProcAddressProc>(
+ base::GetFunctionPointerFromNativeLibrary(
+ library, "OSMesaGetProcAddress"));
+ if (!get_proc_address) {
+ LOG(ERROR) << "OSMesaGetProcAddress not found.";
+ base::UnloadNativeLibrary(library);
+ return false;
+ }
+
+ SetGLGetProcAddressProc(get_proc_address);
+ AddGLNativeLibrary(library);
+ SetGLImplementation(kGLImplementationOSMesaGL);
+
+ InitializeGLBindingsGL();
+ InitializeGLBindingsOSMESA();
+ break;
+ }
+ case kGLImplementationDesktopGL: {
+ base::NativeLibrary library = base::LoadNativeLibrary(
+ FilePath("libGL.so.1"));
+ if (!library) {
+ VLOG(1) << "libGL.so.1 not found.";
+ return false;
+ }
+
+ GLGetProcAddressProc get_proc_address =
+ reinterpret_cast<GLGetProcAddressProc>(
+ base::GetFunctionPointerFromNativeLibrary(
+ library, "glXGetProcAddress"));
+ if (!get_proc_address) {
+ LOG(ERROR) << "glxGetProcAddress not found.";
+ base::UnloadNativeLibrary(library);
+ return false;
+ }
+
+ SetGLGetProcAddressProc(get_proc_address);
+ AddGLNativeLibrary(library);
+ SetGLImplementation(kGLImplementationDesktopGL);
+
+ InitializeGLBindingsGL();
+ InitializeGLBindingsGLX();
+ break;
+ }
+ case kGLImplementationEGLGLES2: {
+ base::NativeLibrary gles_library = base::LoadNativeLibrary(
+ FilePath("libGLESv2.so"));
+ if (!gles_library) {
+ VLOG(1) << "libGLESv2.so not found";
+ return false;
+ }
+
+ base::NativeLibrary egl_library = base::LoadNativeLibrary(
+ FilePath("libEGL.so"));
+ if (!egl_library) {
+ VLOG(1) << "libEGL.so not found";
+ base::UnloadNativeLibrary(gles_library);
+ return false;
+ }
+
+ GLGetProcAddressProc get_proc_address =
+ reinterpret_cast<GLGetProcAddressProc>(
+ base::GetFunctionPointerFromNativeLibrary(
+ egl_library, "eglGetProcAddress"));
+ if (!get_proc_address) {
+ LOG(ERROR) << "eglGetProcAddress not found.";
+ base::UnloadNativeLibrary(egl_library);
+ base::UnloadNativeLibrary(gles_library);
+ return false;
+ }
+
+ SetGLGetProcAddressProc(get_proc_address);
+ AddGLNativeLibrary(egl_library);
+ AddGLNativeLibrary(gles_library);
+ SetGLImplementation(kGLImplementationEGLGLES2);
+
+ InitializeGLBindingsGL();
+ InitializeGLBindingsEGL();
+
+ // These two functions take single precision float rather than double
+ // precision float parameters in GLES.
+ ::gfx::g_glClearDepth = MarshalClearDepthToClearDepthf;
+ ::gfx::g_glDepthRange = MarshalDepthRangeToDepthRangef;
+ break;
+ }
+ case kGLImplementationMockGL: {
+ SetGLGetProcAddressProc(GetMockGLProcAddress);
+ SetGLImplementation(kGLImplementationMockGL);
+ InitializeGLBindingsGL();
+ break;
+ }
+ default:
+ return false;
+ }
+
+
+ return true;
+}
+
+void InitializeDebugGLBindings() {
+ InitializeDebugGLBindingsEGL();
+ InitializeDebugGLBindingsGL();
+ InitializeDebugGLBindingsGLX();
+ InitializeDebugGLBindingsOSMESA();
+}
+
+} // namespace gfx
diff --git a/ui/gfx/gl/gl_implementation_mac.cc b/ui/gfx/gl/gl_implementation_mac.cc
new file mode 100644
index 0000000..00ed6bb
--- /dev/null
+++ b/ui/gfx/gl/gl_implementation_mac.cc
@@ -0,0 +1,92 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/base_paths.h"
+#include "base/file_path.h"
+#include "base/logging.h"
+#include "base/native_library.h"
+#include "base/path_service.h"
+#include "ui/gfx/gl/gl_bindings.h"
+#include "ui/gfx/gl/gl_implementation.h"
+
+namespace gfx {
+namespace {
+const char kOpenGLFrameworkPath[] =
+ "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL";
+} // namespace anonymous
+
+bool InitializeGLBindings(GLImplementation implementation) {
+ // Prevent reinitialization with a different implementation. Once the gpu
+ // unit tests have initialized with kGLImplementationMock, we don't want to
+ // later switch to another GL implementation.
+ if (GetGLImplementation() != kGLImplementationNone)
+ return true;
+
+ switch (implementation) {
+ case kGLImplementationOSMesaGL: {
+ FilePath module_path;
+ if (!PathService::Get(base::DIR_MODULE, &module_path)) {
+ LOG(ERROR) << "PathService::Get failed.";
+ return false;
+ }
+
+ // When using OSMesa, just use OSMesaGetProcAddress to find entry points.
+ base::NativeLibrary library = base::LoadNativeLibrary(
+ module_path.Append("osmesa.so"));
+ if (!library) {
+ VLOG(1) << "osmesa.so not found";
+ return false;
+ }
+
+ GLGetProcAddressProc get_proc_address =
+ reinterpret_cast<GLGetProcAddressProc>(
+ base::GetFunctionPointerFromNativeLibrary(
+ library, "OSMesaGetProcAddress"));
+ if (!get_proc_address) {
+ LOG(ERROR) << "OSMesaGetProcAddress not found.";
+ base::UnloadNativeLibrary(library);
+ return false;
+ }
+
+ SetGLGetProcAddressProc(get_proc_address);
+ AddGLNativeLibrary(library);
+ SetGLImplementation(kGLImplementationOSMesaGL);
+
+ InitializeGLBindingsGL();
+ InitializeGLBindingsOSMESA();
+ break;
+ }
+ case kGLImplementationDesktopGL: {
+ base::NativeLibrary library = base::LoadNativeLibrary(
+ FilePath(kOpenGLFrameworkPath));
+ if (!library) {
+ LOG(ERROR) << "OpenGL framework not found";
+ return false;
+ }
+
+ AddGLNativeLibrary(library);
+ SetGLImplementation(kGLImplementationDesktopGL);
+
+ InitializeGLBindingsGL();
+ break;
+ }
+ case kGLImplementationMockGL: {
+ SetGLGetProcAddressProc(GetMockGLProcAddress);
+ SetGLImplementation(kGLImplementationMockGL);
+ InitializeGLBindingsGL();
+ break;
+ }
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+void InitializeDebugGLBindings() {
+ InitializeDebugGLBindingsGL();
+ InitializeDebugGLBindingsOSMESA();
+}
+
+} // namespace gfx
diff --git a/ui/gfx/gl/gl_implementation_win.cc b/ui/gfx/gl/gl_implementation_win.cc
new file mode 100644
index 0000000..ee07cfc
--- /dev/null
+++ b/ui/gfx/gl/gl_implementation_win.cc
@@ -0,0 +1,168 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <vector>
+
+#include "base/base_paths.h"
+#include "base/file_path.h"
+#include "base/logging.h"
+#include "base/native_library.h"
+#include "base/path_service.h"
+#include "ui/gfx/gl/gl_bindings.h"
+#include "ui/gfx/gl/gl_implementation.h"
+
+namespace gfx {
+
+namespace {
+
+void GL_BINDING_CALL MarshalClearDepthToClearDepthf(GLclampd depth) {
+ glClearDepthf(static_cast<GLclampf>(depth));
+}
+
+void GL_BINDING_CALL MarshalDepthRangeToDepthRangef(GLclampd z_near,
+ GLclampd z_far) {
+ glDepthRangef(static_cast<GLclampf>(z_near), static_cast<GLclampf>(z_far));
+}
+
+} // namespace anonymous
+
+bool InitializeGLBindings(GLImplementation implementation) {
+ // Prevent reinitialization with a different implementation. Once the gpu
+ // unit tests have initialized with kGLImplementationMock, we don't want to
+ // later switch to another GL implementation.
+ if (GetGLImplementation() != kGLImplementationNone)
+ return true;
+
+ switch (implementation) {
+ case kGLImplementationOSMesaGL: {
+ FilePath module_path;
+ if (!PathService::Get(base::DIR_MODULE, &module_path)) {
+ LOG(ERROR) << "PathService::Get failed.";
+ return false;
+ }
+
+ base::NativeLibrary library = base::LoadNativeLibrary(
+ module_path.Append(L"osmesa.dll"));
+ if (!library) {
+ VLOG(1) << "osmesa.dll not found";
+ return false;
+ }
+
+ GLGetProcAddressProc get_proc_address =
+ reinterpret_cast<GLGetProcAddressProc>(
+ base::GetFunctionPointerFromNativeLibrary(
+ library, "OSMesaGetProcAddress"));
+ if (!get_proc_address) {
+ DLOG(ERROR) << "OSMesaGetProcAddress not found.";
+ base::UnloadNativeLibrary(library);
+ return false;
+ }
+
+ SetGLGetProcAddressProc(get_proc_address);
+ AddGLNativeLibrary(library);
+ SetGLImplementation(kGLImplementationOSMesaGL);
+
+ InitializeGLBindingsGL();
+ InitializeGLBindingsOSMESA();
+ break;
+ }
+ case kGLImplementationEGLGLES2: {
+ FilePath module_path;
+ if (!PathService::Get(base::DIR_MODULE, &module_path))
+ return false;
+
+ // Load libglesv2.dll before libegl.dll because the latter is dependent on
+ // the former and if there is another version of libglesv2.dll in the dll
+ // search path, it will get loaded.
+ base::NativeLibrary gles_library = base::LoadNativeLibrary(
+ module_path.Append(L"libglesv2.dll"));
+ if (!gles_library) {
+ VLOG(1) << "libglesv2.dll not found";
+ return false;
+ }
+
+ // When using EGL, first try eglGetProcAddress and then Windows
+ // GetProcAddress on both the EGL and GLES2 DLLs.
+ base::NativeLibrary egl_library = base::LoadNativeLibrary(
+ module_path.Append(L"libegl.dll"));
+ if (!egl_library) {
+ VLOG(1) << "libegl.dll not found.";
+ base::UnloadNativeLibrary(gles_library);
+ return false;
+ }
+
+ GLGetProcAddressProc get_proc_address =
+ reinterpret_cast<GLGetProcAddressProc>(
+ base::GetFunctionPointerFromNativeLibrary(
+ egl_library, "eglGetProcAddress"));
+ if (!get_proc_address) {
+ LOG(ERROR) << "eglGetProcAddress not found.";
+ base::UnloadNativeLibrary(egl_library);
+ base::UnloadNativeLibrary(gles_library);
+ return false;
+ }
+
+ SetGLGetProcAddressProc(get_proc_address);
+ AddGLNativeLibrary(egl_library);
+ AddGLNativeLibrary(gles_library);
+ SetGLImplementation(kGLImplementationEGLGLES2);
+
+ InitializeGLBindingsGL();
+ InitializeGLBindingsEGL();
+
+ // These two functions take single precision float rather than double
+ // precision float parameters in GLES.
+ ::gfx::g_glClearDepth = MarshalClearDepthToClearDepthf;
+ ::gfx::g_glDepthRange = MarshalDepthRangeToDepthRangef;
+ break;
+ }
+ case kGLImplementationDesktopGL: {
+ // When using Windows OpenGL, first try wglGetProcAddress and then
+ // Windows GetProcAddress.
+ base::NativeLibrary library = base::LoadNativeLibrary(
+ FilePath(L"opengl32.dll"));
+ if (!library) {
+ VLOG(1) << "opengl32.dll not found";
+ return false;
+ }
+
+ GLGetProcAddressProc get_proc_address =
+ reinterpret_cast<GLGetProcAddressProc>(
+ base::GetFunctionPointerFromNativeLibrary(
+ library, "wglGetProcAddress"));
+ if (!get_proc_address) {
+ LOG(ERROR) << "wglGetProcAddress not found.";
+ base::UnloadNativeLibrary(library);
+ return false;
+ }
+
+ SetGLGetProcAddressProc(get_proc_address);
+ AddGLNativeLibrary(library);
+ SetGLImplementation(kGLImplementationDesktopGL);
+
+ InitializeGLBindingsGL();
+ InitializeGLBindingsWGL();
+ break;
+ }
+ case kGLImplementationMockGL: {
+ SetGLGetProcAddressProc(GetMockGLProcAddress);
+ SetGLImplementation(kGLImplementationMockGL);
+ InitializeGLBindingsGL();
+ break;
+ }
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+void InitializeDebugGLBindings() {
+ InitializeDebugGLBindingsEGL();
+ InitializeDebugGLBindingsGL();
+ InitializeDebugGLBindingsOSMESA();
+ InitializeDebugGLBindingsWGL();
+}
+
+} // namespace gfx
diff --git a/ui/gfx/gl/gl_interface.cc b/ui/gfx/gl/gl_interface.cc
new file mode 100644
index 0000000..a671973
--- /dev/null
+++ b/ui/gfx/gl/gl_interface.cc
@@ -0,0 +1,20 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/gfx/gl/gl_interface.h"
+
+namespace gfx {
+
+GLInterface* GLInterface::interface_;
+
+void GLInterface::SetGLInterface(GLInterface* gl_interface) {
+ interface_ = gl_interface;
+}
+
+GLInterface* GLInterface::GetGLInterface() {
+ return interface_;
+}
+
+} // namespace gfx
+
diff --git a/ui/gfx/gl/gl_interface.h b/ui/gfx/gl/gl_interface.h
new file mode 100644
index 0000000..bbd2b63
--- /dev/null
+++ b/ui/gfx/gl/gl_interface.h
@@ -0,0 +1,436 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file implements glue to a GL interface so we can mock it for unit
+// testing. It has to be Desktop GL, not GLES2 as it is used to test the service
+// side code.
+
+#ifndef UI_GFX_GL_GL_INTERFACE_H_
+#define UI_GFX_GL_GL_INTERFACE_H_
+#pragma once
+
+#include "ui/gfx/gl/gl_bindings.h"
+
+namespace gfx {
+
+class GLInterface {
+ public:
+ virtual ~GLInterface() {
+ }
+
+ static void SetGLInterface(GLInterface* gl_interface);
+
+ static GLInterface* GetGLInterface();
+
+ virtual void ActiveTexture(GLenum texture) = 0;
+
+ virtual void AttachShader(GLuint program, GLuint shader) = 0;
+
+ virtual void BindAttribLocation(
+ GLuint program, GLuint index, const char* name) = 0;
+
+ virtual void BindBuffer(GLenum target, GLuint buffer) = 0;
+
+ virtual void BindFramebufferEXT(GLenum target, GLuint framebuffer) = 0;
+
+ virtual void BindRenderbufferEXT(GLenum target, GLuint renderbuffer) = 0;
+
+ virtual void BindTexture(GLenum target, GLuint texture) = 0;
+
+ virtual void BlendColor(
+ GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) = 0;
+
+ virtual void BlendEquation(GLenum mode) = 0;
+
+ virtual void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) = 0;
+
+ virtual void BlendFunc(GLenum sfactor, GLenum dfactor) = 0;
+
+ virtual void BlendFuncSeparate(
+ GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) = 0;
+
+ virtual void BlitFramebufferANGLE(
+ GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter) = 0;
+
+ virtual void BlitFramebufferEXT(
+ GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter) = 0;
+
+ virtual void BufferData(
+ GLenum target, GLsizeiptr size, const void* data, GLenum usage) = 0;
+
+ virtual void BufferSubData(
+ GLenum target, GLintptr offset, GLsizeiptr size, const void* data) = 0;
+
+ virtual GLenum CheckFramebufferStatusEXT(GLenum target) = 0;
+
+ virtual void Clear(GLbitfield mask) = 0;
+
+ virtual void ClearColor(
+ GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) = 0;
+
+ virtual void ClearDepth(GLclampd depth) = 0;
+
+ virtual void ClearDepthf(GLclampf depth) = 0;
+
+ virtual void ClearStencil(GLint s) = 0;
+
+ virtual void ColorMask(
+ GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) = 0;
+
+ virtual void CompileShader(GLuint shader) = 0;
+
+ virtual void CompressedTexImage2D(
+ GLenum target, GLint level, GLenum internalformat, GLsizei width,
+ GLsizei height, GLint border, GLsizei imageSize, const void* data) = 0;
+
+ virtual void CompressedTexSubImage2D(
+ GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
+ GLsizei height, GLenum format, GLsizei imageSize, const void* data) = 0;
+
+ virtual void CopyTexImage2D(
+ GLenum target, GLint level, GLenum internalformat, GLint x, GLint y,
+ GLsizei width, GLsizei height, GLint border) = 0;
+
+ virtual void CopyTexSubImage2D(
+ GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height) = 0;
+
+ virtual GLuint CreateProgram() = 0;
+
+ virtual GLuint CreateShader(GLenum type) = 0;
+
+ virtual void CullFace(GLenum mode) = 0;
+
+ virtual void DeleteBuffersARB(GLsizei n, const GLuint* buffers) = 0;
+
+ virtual void DeleteFramebuffersEXT(GLsizei n, const GLuint* framebuffers) = 0;
+
+ virtual void DeleteProgram(GLuint program) = 0;
+
+ virtual void DeleteRenderbuffersEXT(
+ GLsizei n, const GLuint* renderbuffers) = 0;
+
+ virtual void DeleteShader(GLuint shader) = 0;
+
+ virtual void DeleteTextures(GLsizei n, const GLuint* textures) = 0;
+
+ virtual void DepthFunc(GLenum func) = 0;
+
+ virtual void DepthMask(GLboolean flag) = 0;
+
+ virtual void DepthRange(GLclampd zNear, GLclampd zFar) = 0;
+
+ virtual void DepthRangef(GLclampf zNear, GLclampf zFar) = 0;
+
+ virtual void DetachShader(GLuint program, GLuint shader) = 0;
+
+ virtual void Disable(GLenum cap) = 0;
+
+ virtual void DisableVertexAttribArray(GLuint index) = 0;
+
+ virtual void DrawArrays(GLenum mode, GLint first, GLsizei count) = 0;
+
+ virtual void DrawElements(
+ GLenum mode, GLsizei count, GLenum type, const void* indices) = 0;
+
+ virtual void Enable(GLenum cap) = 0;
+
+ virtual void EnableVertexAttribArray(GLuint index) = 0;
+
+ virtual void Finish() = 0;
+
+ virtual void Flush() = 0;
+
+ virtual void FramebufferRenderbufferEXT(
+ GLenum target, GLenum attachment, GLenum renderbuffertarget,
+ GLuint renderbuffer) = 0;
+
+ virtual void FramebufferTexture2DEXT(
+ GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
+ GLint level) = 0;
+
+ virtual void FrontFace(GLenum mode) = 0;
+
+ virtual void GenBuffersARB(GLsizei n, GLuint* buffers) = 0;
+
+ virtual void GenerateMipmapEXT(GLenum target) = 0;
+
+ virtual void GenFramebuffersEXT(GLsizei n, GLuint* framebuffers) = 0;
+
+ virtual void GenRenderbuffersEXT(GLsizei n, GLuint* renderbuffers) = 0;
+
+ virtual void GenTextures(GLsizei n, GLuint* textures) = 0;
+
+ virtual void GetActiveAttrib(
+ GLuint program, GLuint index, GLsizei bufsize, GLsizei* length,
+ GLint* size, GLenum* type, char* name) = 0;
+
+ virtual void GetActiveUniform(
+ GLuint program, GLuint index, GLsizei bufsize, GLsizei* length,
+ GLint* size, GLenum* type, char* name) = 0;
+
+ virtual void GetAttachedShaders(
+ GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) = 0;
+
+ virtual GLint GetAttribLocation(GLuint program, const char* name) = 0;
+
+ virtual void GetBooleanv(GLenum pname, GLboolean* params) = 0;
+
+ virtual void GetBufferParameteriv(
+ GLenum target, GLenum pname, GLint* params) = 0;
+
+ virtual GLenum GetError() = 0;
+
+ virtual void GetFloatv(GLenum pname, GLfloat* params) = 0;
+
+ virtual void GetFramebufferAttachmentParameterivEXT(
+ GLenum target, GLenum attachment, GLenum pname, GLint* params) = 0;
+
+ virtual void GetIntegerv(GLenum pname, GLint* params) = 0;
+
+ virtual void GetProgramiv(GLuint program, GLenum pname, GLint* params) = 0;
+
+ // TODO(gman): Implement this
+ virtual void GetProgramInfoLog(
+ GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) = 0;
+
+ virtual void GetRenderbufferParameterivEXT(
+ GLenum target, GLenum pname, GLint* params) = 0;
+
+ virtual void GetShaderiv(GLuint shader, GLenum pname, GLint* params) = 0;
+
+ // TODO(gman): Implement this
+ virtual void GetShaderInfoLog(
+ GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) = 0;
+
+ virtual void GetShaderPrecisionFormat(
+ GLenum shadertype, GLenum precisiontype, GLint* range,
+ GLint* precision) = 0;
+
+ // TODO(gman): Implement this
+ virtual void GetShaderSource(
+ GLuint shader, GLsizei bufsize, GLsizei* length, char* source) = 0;
+
+ virtual const GLubyte* GetString(GLenum name) = 0;
+
+ virtual void GetTexLevelParameterfv(
+ GLenum target, GLint level, GLenum pname, GLfloat* params) = 0;
+
+ virtual void GetTexLevelParameteriv(
+ GLenum target, GLint level, GLenum pname, GLint* params) = 0;
+
+ virtual void GetTexParameterfv(
+ GLenum target, GLenum pname, GLfloat* params) = 0;
+
+ virtual void GetTexParameteriv(
+ GLenum target, GLenum pname, GLint* params) = 0;
+
+ virtual void GetUniformfv(
+ GLuint program, GLint location, GLfloat* params) = 0;
+
+ virtual void GetUniformiv(GLuint program, GLint location, GLint* params) = 0;
+
+ virtual GLint GetUniformLocation(GLuint program, const char* name) = 0;
+
+ virtual void GetVertexAttribfv(
+ GLuint index, GLenum pname, GLfloat* params) = 0;
+
+ virtual void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params) = 0;
+
+ virtual void GetVertexAttribPointerv(
+ GLuint index, GLenum pname, void** pointer) = 0;
+
+ virtual void Hint(GLenum target, GLenum mode) = 0;
+
+ virtual GLboolean IsBuffer(GLuint buffer) = 0;
+
+ virtual GLboolean IsEnabled(GLenum cap) = 0;
+
+ virtual GLboolean IsFramebufferEXT(GLuint framebuffer) = 0;
+
+ virtual GLboolean IsProgram(GLuint program) = 0;
+
+ virtual GLboolean IsRenderbufferEXT(GLuint renderbuffer) = 0;
+
+ virtual GLboolean IsShader(GLuint shader) = 0;
+
+ virtual GLboolean IsTexture(GLuint texture) = 0;
+
+ virtual void* MapBuffer(GLenum target, GLenum access) = 0;
+
+ virtual void LineWidth(GLfloat width) = 0;
+
+ virtual void LinkProgram(GLuint program) = 0;
+
+ virtual void PixelStorei(GLenum pname, GLint param) = 0;
+
+ virtual void PolygonOffset(GLfloat factor, GLfloat units) = 0;
+
+ virtual void ReadPixels(
+ GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
+ GLenum type, void* pixels) = 0;
+
+ virtual void ReleaseShaderCompiler(void) = 0;
+
+ virtual void RenderbufferStorageEXT(
+ GLenum target, GLenum internalformat, GLsizei width, GLsizei height) = 0;
+
+ virtual void RenderbufferStorageMultisampleANGLE(
+ GLenum target, GLsizei samples, GLenum internalformat,
+ GLsizei width, GLsizei height) = 0;
+
+ virtual void RenderbufferStorageMultisampleEXT(
+ GLenum target, GLsizei samples, GLenum internalformat,
+ GLsizei width, GLsizei height) = 0;
+
+ virtual void SampleCoverage(GLclampf value, GLboolean invert) = 0;
+
+ virtual void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) = 0;
+
+ virtual void ShaderBinary(
+ GLsizei n, const GLuint* shaders, GLenum binaryformat,
+ const void* binary, GLsizei length) = 0;
+
+ virtual void ShaderSource(
+ GLuint shader, GLsizei count, const char** str, const
+ GLint* length) = 0;
+
+ virtual void StencilFunc(GLenum func, GLint ref, GLuint mask) = 0;
+
+ virtual void StencilFuncSeparate(
+ GLenum face, GLenum func, GLint ref, GLuint mask) = 0;
+
+ virtual void StencilMask(GLuint mask) = 0;
+
+ virtual void StencilMaskSeparate(GLenum face, GLuint mask) = 0;
+
+ virtual void StencilOp(GLenum fail, GLenum zfail, GLenum zpass) = 0;
+
+ virtual void StencilOpSeparate(
+ GLenum face, GLenum fail, GLenum zfail, GLenum zpass) = 0;
+
+ virtual void TexImage2D(
+ GLenum target, GLint level, GLint internalformat, GLsizei width,
+ GLsizei height, GLint border, GLenum format, GLenum type,
+ const void* pixels) = 0;
+
+ virtual void TexParameterf(GLenum target, GLenum pname, GLfloat param) = 0;
+
+ virtual void TexParameterfv(
+ GLenum target, GLenum pname, const GLfloat* params) = 0;
+
+ virtual void TexParameteri(GLenum target, GLenum pname, GLint param) = 0;
+
+ virtual void TexParameteriv(
+ GLenum target, GLenum pname, const GLint* params) = 0;
+
+ virtual void TexSubImage2D(
+ GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
+ GLsizei height, GLenum format, GLenum type, const void* pixels) = 0;
+
+ virtual void Uniform1f(GLint location, GLfloat x) = 0;
+
+ virtual void Uniform1fv(GLint location, GLsizei count, const GLfloat* v) = 0;
+
+ virtual void Uniform1i(GLint location, GLint x) = 0;
+
+ virtual void Uniform1iv(GLint location, GLsizei count, const GLint* v) = 0;
+
+ virtual void Uniform2f(GLint location, GLfloat x, GLfloat y) = 0;
+
+ virtual void Uniform2fv(GLint location, GLsizei count, const GLfloat* v) = 0;
+
+ virtual void Uniform2i(GLint location, GLint x, GLint y) = 0;
+
+ virtual void Uniform2iv(GLint location, GLsizei count, const GLint* v) = 0;
+
+ virtual void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) = 0;
+
+ virtual void Uniform3fv(GLint location, GLsizei count, const GLfloat* v) = 0;
+
+ virtual void Uniform3i(GLint location, GLint x, GLint y, GLint z) = 0;
+
+ virtual void Uniform3iv(GLint location, GLsizei count, const GLint* v) = 0;
+
+ virtual void Uniform4f(
+ GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) = 0;
+
+ virtual void Uniform4fv(GLint location, GLsizei count, const GLfloat* v) = 0;
+
+ virtual void Uniform4i(
+ GLint location, GLint x, GLint y, GLint z, GLint w) = 0;
+
+ virtual void Uniform4iv(GLint location, GLsizei count, const GLint* v) = 0;
+
+ virtual void UniformMatrix2fv(
+ GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat* value) = 0;
+
+ virtual void UniformMatrix3fv(
+ GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat* value) = 0;
+
+ virtual void UniformMatrix4fv(
+ GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat* value) = 0;
+
+ virtual GLboolean UnmapBuffer(GLenum target) = 0;
+
+ virtual void UseProgram(GLuint program) = 0;
+
+ virtual void ValidateProgram(GLuint program) = 0;
+
+ virtual void VertexAttrib1f(GLuint indx, GLfloat x) = 0;
+
+ virtual void VertexAttrib1fv(GLuint indx, const GLfloat* values) = 0;
+
+ virtual void VertexAttrib2f(GLuint indx, GLfloat x, GLfloat y) = 0;
+
+ virtual void VertexAttrib2fv(GLuint indx, const GLfloat* values) = 0;
+
+ virtual void VertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z) = 0;
+
+ virtual void VertexAttrib3fv(GLuint indx, const GLfloat* values) = 0;
+
+ virtual void VertexAttrib4f(
+ GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) = 0;
+
+ virtual void VertexAttrib4fv(GLuint indx, const GLfloat* values) = 0;
+
+ virtual void VertexAttribPointer(
+ GLuint indx, GLint size, GLenum type, GLboolean normalized,
+ GLsizei stride, const void* ptr) = 0;
+
+ virtual void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) = 0;
+
+ virtual void SwapBuffers() = 0;
+
+ virtual GLuint GetMaxValueInBufferCHROMIUM(
+ GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) = 0;
+
+ virtual void GenFencesNV(GLsizei n, GLuint *fences) = 0;
+
+ virtual void DeleteFencesNV(GLsizei n, const GLuint *fences) = 0;
+
+ virtual void SetFenceNV(GLuint fence, GLenum condition) = 0;
+
+ virtual GLboolean TestFenceNV(GLuint fence) = 0;
+
+ virtual void FinishFenceNV(GLuint fence) = 0;
+
+ virtual GLboolean IsFenceNV(GLuint fence) = 0;
+
+ virtual void GetFenceivNV(GLuint fence, GLenum pname, GLint *params) = 0;
+
+ private:
+ static GLInterface* interface_;
+};
+
+} // namespace gfx
+
+#endif // UI_GFX_GL_GL_INTERFACE_H_
diff --git a/ui/gfx/surface/accelerated_surface_mac.cc b/ui/gfx/surface/accelerated_surface_mac.cc
index 59919f8..4007c03 100644
--- a/ui/gfx/surface/accelerated_surface_mac.cc
+++ b/ui/gfx/surface/accelerated_surface_mac.cc
@@ -4,10 +4,10 @@
#include "ui/gfx/surface/accelerated_surface_mac.h"
-#include "app/gfx/gl/gl_bindings.h"
-#include "app/gfx/gl/gl_implementation.h"
#include "base/logging.h"
#include "base/mac/scoped_cftyperef.h"
+#include "ui/gfx/gl/gl_bindings.h"
+#include "ui/gfx/gl/gl_implementation.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/surface/io_surface_support_mac.h"
diff --git a/ui/gfx/surface/accelerated_surface_mac.h b/ui/gfx/surface/accelerated_surface_mac.h
index 004f49a..8491091 100644
--- a/ui/gfx/surface/accelerated_surface_mac.h
+++ b/ui/gfx/surface/accelerated_surface_mac.h
@@ -8,12 +8,12 @@
#include <CoreFoundation/CoreFoundation.h>
-#include "app/gfx/gl/gl_context.h"
#include "base/callback.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/memory/scoped_ptr.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"
+#include "ui/gfx/gl/gl_context.h"
#include "ui/gfx/surface/transport_dib.h"
// Should not include GL headers in a header file. Forward declare these types
diff --git a/ui/gfx/surface/surface.gyp b/ui/gfx/surface/surface.gyp
index c7d1dca..0cbfe94 100644
--- a/ui/gfx/surface/surface.gyp
+++ b/ui/gfx/surface/surface.gyp
@@ -38,8 +38,8 @@
'msvs_guid': '6C99567D-6F02-43B5-BB35-D8E3F8D0D6D2',
'dependencies': [
'<(DEPTH)/base/base.gyp:base',
- '<(DEPTH)/app/app.gyp:app_base',
'<(DEPTH)/skia/skia.gyp:skia',
+ '<(DEPTH)/ui/gfx/gl/gl.gyp:gl',
'<(DEPTH)/ui/ui.gyp:ui_gfx',
],
'sources': [
diff --git a/ui/ui_gfx.gypi b/ui/ui_gfx.gypi
index 4e6d2ee..0fffbec 100644
--- a/ui/ui_gfx.gypi
+++ b/ui/ui_gfx.gypi
@@ -76,8 +76,6 @@
'gfx/gfx_paths.h',
'gfx/gfx_module.cc',
'gfx/gfx_module.h',
- 'gfx/gl/gl_switches.cc',
- 'gfx/gl/gl_switches.h',
'gfx/image.cc',
'gfx/image.h',
'gfx/image_mac.mm',