summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-09 22:06:15 +0000
committerapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-09 22:06:15 +0000
commitb9363b2794c6f287be68eebb361117cdfbf060ca (patch)
tree74408c31f3920ae183663b0f16e633349805798e /app
parentc8c9712650efaa201c97ad6ff4edb6aa092dfd17 (diff)
downloadchromium_src-b9363b2794c6f287be68eebb361117cdfbf060ca.zip
chromium_src-b9363b2794c6f287be68eebb361117cdfbf060ca.tar.gz
chromium_src-b9363b2794c6f287be68eebb361117cdfbf060ca.tar.bz2
Added EGL based GLContext.
Python script to generate code to dynamically bind to GL functions (native GL, OSMesa, EGL or mock GL for unit tests). This replaces GLEW because GLEW doesn't bind to the GLES dialect of GL. Moved the mock GL code into app/gfx/gl. Updated the GPU code and AcceleratedSurface to use the new GL bindings. TEST=trybots BUG=none Review URL: http://codereview.chromium.org/2134006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@49332 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'app')
-rw-r--r--app/app_base.gypi103
-rw-r--r--app/gfx/gl/generate_bindings.py548
-rw-r--r--app/gfx/gl/gl_bindings.h77
-rw-r--r--app/gfx/gl/gl_context.cc68
-rw-r--r--app/gfx/gl/gl_context.h4
-rw-r--r--app/gfx/gl/gl_context_egl.cc241
-rw-r--r--app/gfx/gl/gl_context_egl.h93
-rw-r--r--app/gfx/gl/gl_context_linux.cc159
-rw-r--r--app/gfx/gl/gl_context_mac.cc54
-rw-r--r--app/gfx/gl/gl_context_osmesa.cc18
-rw-r--r--app/gfx/gl/gl_context_osmesa.h4
-rw-r--r--app/gfx/gl/gl_context_stub.h34
-rw-r--r--app/gfx/gl/gl_context_win.cc329
-rw-r--r--app/gfx/gl/gl_implementation.h30
-rw-r--r--app/gfx/gl/gl_implementation_linux.cc80
-rw-r--r--app/gfx/gl/gl_implementation_mac.cc76
-rw-r--r--app/gfx/gl/gl_implementation_win.cc140
-rw-r--r--app/gfx/gl/gl_interface.cc20
-rw-r--r--app/gfx/gl/gl_interface.h396
-rw-r--r--app/gfx/gl/gl_mock.h393
-rw-r--r--app/surface/accelerated_surface_mac.cc1
-rw-r--r--app/surface/accelerated_surface_mac.h8
22 files changed, 2514 insertions, 362 deletions
diff --git a/app/app_base.gypi b/app/app_base.gypi
index 4f391c5..247118a 100644
--- a/app/app_base.gypi
+++ b/app/app_base.gypi
@@ -67,6 +67,7 @@
'msvs_guid': '4631946D-7D5F-44BD-A5A8-504C0A7033BE',
'variables': {
'app_base_target': 1,
+ 'gl_binding_output_dir': '<(SHARED_INTERMEDIATE_DIR)/app',
},
'dependencies': [
# app resources and app_strings should be shared with the 64-bit
@@ -85,17 +86,17 @@
'../third_party/sqlite/sqlite.gyp:sqlite',
'../third_party/zlib/zlib.gyp:zlib',
],
- 'defines': [
- 'GLEW_STATIC',
- ],
'include_dirs': [
- '../third_party/glew/include',
+ '../third_party/mesa/MesaLib/include',
+ '<(gl_binding_output_dir)',
],
# TODO(gregoryd): The direct_dependent_settings should be shared with
# the 64-bit target, but it doesn't work due to a bug in gyp
'direct_dependent_settings': {
'include_dirs': [
'..',
+ '../third_party/mesa/MesaLib/include',
+ '<(gl_binding_output_dir)',
],
},
'sources': [
@@ -123,16 +124,23 @@
'file_download_interface.h',
'gfx/font_util.h',
'gfx/font_util.cc',
+ 'gfx/gl/gl_bindings.h',
'gfx/gl/gl_context.cc',
'gfx/gl/gl_context.h',
- 'gfx/gl/gl_context_osmesa.cc',
- 'gfx/gl/gl_context_osmesa.h',
'gfx/gl/gl_context_linux.cc',
- 'gfx/gl/gl_context_linux.h',
'gfx/gl/gl_context_mac.cc',
- 'gfx/gl/gl_context_mac.h',
+ 'gfx/gl/gl_context_osmesa.cc',
+ 'gfx/gl/gl_context_osmesa.h',
+ 'gfx/gl/gl_context_stub.h',
'gfx/gl/gl_context_win.cc',
- 'gfx/gl/gl_context_win.h',
+ 'gfx/gl/gl_headers.h',
+ 'gfx/gl/gl_implementation.h',
+ 'gfx/gl/gl_implementation_linux.cc',
+ 'gfx/gl/gl_implementation_mac.cc',
+ 'gfx/gl/gl_implementation_win.cc',
+ 'gfx/gl/gl_interface.h',
+ 'gfx/gl/gl_interface.cc',
+ 'gfx/gl/gl_mock.h',
'gtk_dnd_util.cc',
'gtk_dnd_util.h',
'gtk_signal.cc',
@@ -203,7 +211,42 @@
'x11_util.cc',
'x11_util.h',
'x11_util_internal.h',
- '../third_party/glew/src/glew.c',
+ '<(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 targtets. 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': [
+ 'gfx/gl/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',
+ 'gfx/gl/generate_bindings.py',
+ '<(gl_binding_output_dir)',
+ ],
+ },
],
'conditions': [
['OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
@@ -255,6 +298,46 @@
'win/window_impl.h',
],
}],
+ ['OS=="linux"', {
+ 'sources': [
+ '<(gl_binding_output_dir)/gl_bindings_autogen_glx.cc',
+ '<(gl_binding_output_dir)/gl_bindings_autogen_glx.h',
+ ],
+ 'all_dependent_settings': {
+ 'defines': [
+ 'GL_GLEXT_PROTOTYPES',
+ ],
+ 'ldflags': [
+ '-L<(PRODUCT_DIR)',
+ ],
+ 'link_settings': {
+ 'libraries': [
+ '-lX11',
+ '-ldl',
+ ],
+ },
+ },
+ }],
+ ['OS=="mac"', {
+ 'link_settings': {
+ 'libraries': [
+ '$(SDKROOT)/System/Library/Frameworks/OpenGL.framework',
+ ],
+ },
+ }],
+ ['OS=="win"', {
+ 'include_dirs': [
+ '../third_party/angle/include',
+ ],
+ 'sources': [
+ 'gfx/gl/gl_context_egl.cc',
+ 'gfx/gl/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',
+ ],
+ }],
],
},
],
diff --git a/app/gfx/gl/generate_bindings.py b/app/gfx/gl/generate_bindings.py
new file mode 100644
index 0000000..7aaf6d4
--- /dev/null
+++ b/app/gfx/gl/generate_bindings.py
@@ -0,0 +1,548 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2010 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', ['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', ['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', ['glIsFramebuffer'], 'GLuint framebuffer'],
+['GLboolean', ['glIsProgram'], 'GLuint program'],
+['GLboolean', ['glIsRenderbuffer'], 'GLuint renderbuffer'],
+['GLboolean', ['glIsShader'], 'GLuint shader'],
+['GLboolean', ['glIsTexture'], 'GLuint texture'],
+['void', ['glLineWidth'], 'GLfloat width'],
+['void', ['glLinkProgram'], 'GLuint program'],
+['void', ['glPixelStorei'], 'GLenum pname, GLint param'],
+['void', ['glPolygonOffset'], 'GLfloat factor, GLfloat units'],
+['void', ['glReadPixels'],
+ 'GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, '
+ 'GLenum type, void* pixels'],
+['void', ['glReleaseShaderCompiler'], 'void'],
+['void', ['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'],
+['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'],
+]
+
+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'], 'void* 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, void* win, const EGLint* attrib_list'],
+['EGLSurface', ['eglCreatePbufferSurface'],
+ 'EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list'],
+['EGLSurface', ['eglCreatePixmapSurface'],
+ 'EGLDisplay dpy, EGLConfig config, void* 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, void* 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', ['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'],
+]
+
+FUNCTION_SETS = [
+ [GL_FUNCTIONS, 'gl'],
+ [OSMESA_FUNCTIONS, 'osmesa'],
+ [EGL_FUNCTIONS, 'egl'],
+ [WGL_FUNCTIONS, 'wgl'],
+ [GLX_FUNCTIONS, 'glx'],
+]
+
+def GenerateHeader(file, functions, setName):
+ """Generates gl_binding_autogen_x.h"""
+
+ # Write file header.
+ file.write('// Copyright (c) 2010 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 APP_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' % setName.upper())
+ file.write('#define APP_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' % setName.upper())
+
+ # Write prototype for initialization function.
+ file.write('\n')
+ file.write('namespace gfx {\n')
+ file.write('\n')
+ file.write('void InitializeGLBindings%s();\n' % setName.upper())
+
+ # Write typedefs for function pointer types. Always use the GL name for the
+ # typedef.
+ file.write('\n')
+ for [returnType, names, arguments] in functions:
+ file.write('typedef %s (GL_BINDING_CALL *%sProc)(%s);\n' %
+ (returnType, names[0], arguments))
+
+ # Write declarations for function pointers. Always use the GL name for the
+ # declaration.
+ file.write('\n')
+ for [returnType, 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 [returnType, names, arguments] in functions:
+ file.write('#define %s ::gfx::g_%s\n' %
+ (names[0], names[0]))
+
+ file.write('\n')
+ file.write('#endif // APP_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' %
+ setName.upper())
+
+def GenerateSource(file, functions, setName):
+ """Generates gl_binding_autogen_x.cc"""
+
+ # Write file header.
+ file.write('// Copyright (c) 2010 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 "app/gfx/gl/gl_bindings.h"\n')
+ file.write('#include "app/gfx/gl/gl_implementation.h"\n')
+
+ # Write definitions of function pointers.
+ file.write('\n')
+ file.write('namespace gfx {\n')
+ file.write('\n')
+ for [returnType, names, arguments] in functions:
+ file.write('%sProc g_%s;\n' % (names[0], names[0]))
+
+ # Write function to initialize the function pointers.
+ file.write('\n')
+ file.write('void InitializeGLBindings%s() {\n' % setName.upper())
+ for [returnType, 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')
+ file.write( '} // namespace gfx\n')
+
+def GenerateMockSource(file, functions):
+ """Generates functions that invoke a mock GLInterface"""
+
+ file.write('// Copyright (c) 2010 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 "app/gfx/gl/gl_interface.h"\n')
+
+ file.write('\n')
+ file.write('namespace gfx {\n')
+
+ # Write function that trampoline into the GLInterface.
+ for [returnType, names, arguments] in functions:
+ file.write('\n')
+ file.write('%s GL_BINDING_CALL Mock_%s(%s) {\n' %
+ (returnType, names[0], arguments))
+ argumentNames = re.sub(r'(const )?[a-zA-Z0-9]+\** ([a-zA-Z0-9]+)', r'\2',
+ arguments)
+ if argumentNames == 'void':
+ argumentNames = ''
+ functionName = names[0][2:]
+ if returnType == 'void':
+ file.write(' GLInterface::GetGLInterface()->%s(%s);\n' %
+ (functionName, argumentNames))
+ else:
+ file.write(' return GLInterface::GetGLInterface()->%s(%s);\n' %
+ (functionName, argumentNames))
+ 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 [returnType, 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, setName] in FUNCTION_SETS:
+ headerFile = open(
+ os.path.join(dir, 'gl_bindings_autogen_%s.h' % setName), 'wb')
+ GenerateHeader(headerFile, functions, setName)
+ headerFile.close()
+
+ sourceFile = open(
+ os.path.join(dir, 'gl_bindings_autogen_%s.cc' % setName), 'wb')
+ GenerateSource(sourceFile, functions, setName)
+ sourceFile.close()
+
+ sourceFile = open(os.path.join(dir, 'gl_bindings_autogen_mock.cc'), 'wb')
+ GenerateMockSource(sourceFile, GL_FUNCTIONS)
+ sourceFile.close()
+
+if __name__ == '__main__':
+ main(sys.argv[1:])
diff --git a/app/gfx/gl/gl_bindings.h b/app/gfx/gl/gl_bindings.h
new file mode 100644
index 0000000..c9dbbee
--- /dev/null
+++ b/app/gfx/gl/gl_bindings.h
@@ -0,0 +1,77 @@
+// Copyright (c) 2010 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 APP_GFX_GL_GL_BINDINGS_H_
+#define APP_GFX_GL_GL_BINDINGS_H_
+
+#include <GL/gl.h>
+#include <GL/glext.h>
+
+#include "build/build_config.h"
+
+// 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
+
+// Forward declare OSMesa types.
+typedef struct osmesa_context *OSMesaContext;
+typedef void (*OSMESAproc)();
+
+#if defined(OS_WIN)
+
+// 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);
+
+#endif // OS_WIN
+
+#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_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 // APP_GFX_GL_GL_BINDINGS_H_
diff --git a/app/gfx/gl/gl_context.cc b/app/gfx/gl/gl_context.cc
index f4e7073..d9b81f3 100644
--- a/app/gfx/gl/gl_context.cc
+++ b/app/gfx/gl/gl_context.cc
@@ -2,77 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <GL/glew.h>
-
#include "app/gfx/gl/gl_context.h"
+#include "app/gfx/gl/gl_bindings.h"
+#include "app/gfx/gl/gl_implementation.h"
#include "base/logging.h"
namespace gfx {
-// GLEW initialization is extremely expensive because it looks up
-// hundreds of function pointers. Realistically we are not going to
-// switch between GL implementations on the fly, so for the time being
-// we only do the context-dependent GLEW initialization once.
-bool InitializeGLEW() {
-#if defined(UNIT_TEST)
- return true;
-#else
- static bool initialized = false;
- if (initialized)
- return true;
-
- // Initializes context-dependent parts of GLEW.
- if (glewInit() != GLEW_OK) {
- LOG(ERROR) << "GLEW failed initialization";
- return false;
- }
-
- // Check to see that we can use the OpenGL vertex attribute APIs
- // TODO(petersont): Return false if this check fails, but because some
- // Intel hardware does not support OpenGL 2.0, yet does support all of the
- // extensions we require, we only log an error. A future CL should change
- // this check to ensure that all of the extension strings we require are
- // present.
- if (!GLEW_VERSION_2_0) {
- DLOG(ERROR) << "GL drivers do not have OpenGL 2.0 functionality.";
- }
-
- // Check for necessary extensions.
- bool extensions_found = true;
- if (!GLEW_ARB_vertex_buffer_object) {
- // NOTE: Linux NVidia drivers claim to support OpenGL 2.0 when using
- // indirect rendering (e.g. remote X), but it is actually lying. The
- // ARB_vertex_buffer_object functions silently no-op (!) when using
- // indirect rendering, leading to crashes. Fortunately, in that case, the
- // driver claims to not support ARB_vertex_buffer_object, so fail in that
- // case.
- DLOG(ERROR) << "GL drivers do not support vertex buffer objects.";
- extensions_found = false;
- }
- if (!GLEW_EXT_framebuffer_object) {
- DLOG(ERROR) << "GL drivers do not support framebuffer objects.";
- extensions_found = false;
- }
- if (!GLEW_VERSION_2_0 && !GLEW_EXT_stencil_two_side) {
- DLOG(ERROR) << "Two sided stencil extension missing.";
- extensions_found = false;
- }
- if (!GLEW_VERSION_1_4 && !GLEW_EXT_blend_func_separate) {
- DLOG(ERROR) <<"Separate blend func extension missing.";
- extensions_found = false;
- }
- if (!GLEW_VERSION_2_0 && !GLEW_EXT_blend_equation_separate) {
- DLOG(ERROR) << "Separate blend function extension missing.";
- extensions_found = false;
- }
- if (!extensions_found)
- return false;
-
- initialized = true;
- return true;
-#endif
-}
-
bool GLContext::InitializeCommon() {
if (!MakeCurrent())
return false;
diff --git a/app/gfx/gl/gl_context.h b/app/gfx/gl/gl_context.h
index 2a9b3df..1b04985 100644
--- a/app/gfx/gl/gl_context.h
+++ b/app/gfx/gl/gl_context.h
@@ -12,8 +12,6 @@
namespace gfx {
-bool InitializeGLEW();
-
// Encapsulates an OpenGL context, hiding platform specific management.
class GLContext {
public:
@@ -50,7 +48,7 @@ class GLContext {
// 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.
- static GLContext* CreateOffscreenGLContext(void* shared_handle);
+ static GLContext* CreateOffscreenGLContext(GLContext* shared_context);
protected:
bool InitializeCommon();
diff --git a/app/gfx/gl/gl_context_egl.cc b/app/gfx/gl/gl_context_egl.cc
new file mode 100644
index 0000000..ec64ae91
--- /dev/null
+++ b/app/gfx/gl/gl_context_egl.cc
@@ -0,0 +1,241 @@
+// Copyright (c) 2010 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 <EGL/egl.h>
+
+#include "base/scoped_ptr.h"
+#include "app/gfx/gl/gl_bindings.h"
+#include "app/gfx/gl/gl_context_egl.h"
+
+namespace gfx {
+
+namespace {
+
+// The EGL configuration to use.
+EGLDisplay g_display;
+EGLConfig g_config;
+
+bool InitializeOneOff() {
+ static bool initialized = false;
+ if (initialized)
+ return true;
+
+ g_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (!g_display)
+ return false;
+
+ if (!eglInitialize(g_display, NULL, NULL) == EGL_TRUE)
+ 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, 24,
+ EGL_STENCIL_SIZE, 8,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_NONE
+ };
+
+ EGLint num_configs;
+ if (!eglChooseConfig(g_display,
+ kConfigAttribs,
+ NULL,
+ 0,
+ &num_configs)) {
+ return false;
+ }
+
+ if (num_configs == 0)
+ return false;
+
+ scoped_array<EGLConfig> configs(new EGLConfig[num_configs]);
+ if (!eglChooseConfig(g_display,
+ kConfigAttribs,
+ configs.get(),
+ num_configs,
+ &num_configs)) {
+ return false;
+ }
+
+ g_config = configs[0];
+
+ initialized = true;
+ return true;
+}
+} // namespace anonymous
+
+NativeViewEGLContext::NativeViewEGLContext(void* window)
+ : window_(window),
+ surface_(NULL),
+ context_(NULL)
+{
+}
+
+NativeViewEGLContext::~NativeViewEGLContext() {
+}
+
+bool NativeViewEGLContext::Initialize() {
+ DCHECK(!context_);
+
+ if (!InitializeOneOff())
+ return NULL;
+
+ // Create a surface for the native window.
+ surface_ = eglCreateWindowSurface(g_display,
+ g_config,
+ static_cast<EGLNativeWindowType>(window_),
+ NULL);
+ if (!surface_) {
+ Destroy();
+ return false;
+ }
+
+ // Create a context.
+ context_ = eglCreateContext(g_display, g_config, NULL, NULL);
+ if (!context_) {
+ Destroy();
+ return false;
+ }
+
+ if (!MakeCurrent()) {
+ Destroy();
+ return false;
+ }
+
+ if (!InitializeCommon()) {
+ Destroy();
+ return false;
+ }
+
+ return true;
+}
+
+void NativeViewEGLContext::Destroy() {
+ if (context_) {
+ eglDestroyContext(g_display, context_);
+ context_ = NULL;
+ }
+
+ if (surface_) {
+ eglDestroySurface(g_display, surface_);
+ surface_ = NULL;
+ }
+}
+
+bool NativeViewEGLContext::MakeCurrent() {
+ DCHECK(context_);
+ return eglMakeCurrent(g_display,
+ surface_, surface_,
+ context_) == GL_TRUE;
+}
+
+bool NativeViewEGLContext::IsCurrent() {
+ DCHECK(context_);
+ return context_ == eglGetCurrentContext();
+}
+
+bool NativeViewEGLContext::IsOffscreen() {
+ return false;
+}
+
+void NativeViewEGLContext::SwapBuffers() {
+ eglSwapBuffers(g_display, surface_);
+}
+
+gfx::Size NativeViewEGLContext::GetSize() {
+#if defined(OS_WIN)
+ RECT rect;
+ CHECK(GetClientRect(static_cast<HWND>(window_), &rect));
+ return gfx::Size(rect.right - rect.left, rect.bottom - rect.top);
+#else
+ NOTREACHED()
+ << "NativeViewEGLContext::GetSize not implemented on this platform.";
+#endif
+}
+
+void* NativeViewEGLContext::GetHandle() {
+ return context_;
+}
+
+EGLSurface NativeViewEGLContext::GetSurface() {
+ return surface_;
+}
+
+SecondaryEGLContext::SecondaryEGLContext()
+ : surface_(NULL),
+ context_(NULL)
+{
+}
+
+SecondaryEGLContext::~SecondaryEGLContext() {
+}
+
+bool SecondaryEGLContext::Initialize(GLContext* shared_context) {
+ DCHECK(shared_context);
+ DCHECK(!context_);
+
+ if (!InitializeOneOff())
+ return NULL;
+
+ surface_ = static_cast<BaseEGLContext*>(shared_context)->GetSurface();
+
+ // Create a context.
+ context_ = eglCreateContext(g_display,
+ g_config,
+ shared_context->GetHandle(),
+ NULL);
+ if (!context_) {
+ Destroy();
+ return false;
+ }
+
+ return true;
+}
+
+void SecondaryEGLContext::Destroy() {
+ surface_ = NULL;
+
+ if (context_) {
+ eglDestroyContext(g_display, context_);
+ context_ = NULL;
+ }
+}
+
+bool SecondaryEGLContext::MakeCurrent() {
+ DCHECK(context_);
+ return eglMakeCurrent(g_display,
+ surface_, surface_,
+ context_) == GL_TRUE;
+}
+
+bool SecondaryEGLContext::IsCurrent() {
+ DCHECK(context_);
+ return context_ == eglGetCurrentContext();
+}
+
+bool SecondaryEGLContext::IsOffscreen() {
+ return true;
+}
+
+void SecondaryEGLContext::SwapBuffers() {
+ NOTREACHED() << "Attempted to call SwapBuffers on a SecondaryEGLContext.";
+}
+
+gfx::Size SecondaryEGLContext::GetSize() {
+ NOTREACHED() << "Should not be requesting size of this SecondaryEGLContext.";
+ return gfx::Size(1, 1);
+}
+
+void* SecondaryEGLContext::GetHandle() {
+ return context_;
+}
+
+EGLSurface SecondaryEGLContext::GetSurface() {
+ return surface_;
+}
+
+} // namespace gfx
diff --git a/app/gfx/gl/gl_context_egl.h b/app/gfx/gl/gl_context_egl.h
new file mode 100644
index 0000000..4bfff9b
--- /dev/null
+++ b/app/gfx/gl/gl_context_egl.h
@@ -0,0 +1,93 @@
+// Copyright (c) 2010 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 APP_GFX_GL_GL_CONTEXT_EGL_H_
+#define APP_GFX_GL_GL_CONTEXT_EGL_H_
+
+#include "gfx/size.h"
+#include "app/gfx/gl/gl_context.h"
+
+typedef void *EGLContext;
+typedef void* EGLSurface;
+
+namespace gfx {
+
+// Interface for EGL contexts. Adds an EGL specific accessor for retreiving
+// the surface.
+class BaseEGLContext : public GLContext {
+ public:
+ BaseEGLContext() {}
+ virtual ~BaseEGLContext() {}
+
+ // Implement GLContext.
+ virtual EGLSurface GetSurface() = 0;
+
+ 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 void SwapBuffers();
+ virtual gfx::Size GetSize();
+ virtual void* GetHandle();
+
+ // Implement BaseEGLContext.
+ virtual EGLSurface GetSurface();
+
+ private:
+ void* window_;
+ EGLSurface 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 and will render to it. The caller
+// must bind an FBO to prevent this. Not using pbuffers because ANGLE does not
+// support them.
+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 void SwapBuffers();
+ virtual gfx::Size GetSize();
+ virtual void* GetHandle();
+
+ // Implement BaseEGLContext.
+ virtual EGLSurface GetSurface();
+
+ private:
+ // All offscreen
+ EGLSurface surface_;
+ EGLContext context_;
+
+ DISALLOW_COPY_AND_ASSIGN(SecondaryEGLContext);
+};
+
+} // namespace gfx
+
+#endif // APP_GFX_GL_GL_CONTEXT_EGL_H_
diff --git a/app/gfx/gl/gl_context_linux.cc b/app/gfx/gl/gl_context_linux.cc
index 77d6573..d2c5a4f 100644
--- a/app/gfx/gl/gl_context_linux.cc
+++ b/app/gfx/gl/gl_context_linux.cc
@@ -4,19 +4,14 @@
// This file implements the ViewGLContext and PbufferGLContext classes.
-#include <dlfcn.h>
-#include <GL/glew.h>
-#include <GL/glxew.h>
-#include <GL/glx.h>
-#include <GL/osmew.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
#include "app/x11_util.h"
#include "base/logging.h"
#include "base/scoped_ptr.h"
+#include "app/gfx/gl/gl_bindings.h"
#include "app/gfx/gl/gl_context.h"
#include "app/gfx/gl/gl_context_osmesa.h"
+#include "app/gfx/gl/gl_context_stub.h"
+#include "app/gfx/gl/gl_implementation.h"
namespace gfx {
@@ -62,7 +57,7 @@ class PbufferGLContext : public GLContext {
}
// Initializes the GL context.
- bool Initialize(void* shared_handle);
+ bool Initialize(GLContext* shared_context);
virtual void Destroy();
virtual bool MakeCurrent();
@@ -89,7 +84,7 @@ class PixmapGLContext : public GLContext {
}
// Initializes the GL context.
- bool Initialize(void* shared_handle);
+ bool Initialize(GLContext* shared_context);
virtual void Destroy();
virtual bool MakeCurrent();
@@ -117,39 +112,23 @@ class ScopedPtrXFree {
}
};
-// Some versions of NVIDIA's GL libGL.so include a broken version of
-// dlopen/dlsym, and so linking it into chrome breaks it. So we dynamically
-// load it, and use glew to dynamically resolve symbols.
-// See http://code.google.com/p/chromium/issues/detail?id=16800
-
static bool InitializeOneOff() {
static bool initialized = false;
if (initialized)
return true;
- osmewInit();
- if (!OSMesaCreateContext) {
- void* handle = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL);
- if (!handle) {
- LOG(ERROR) << "Could not find libGL.so.1";
- return false;
- }
+ // Initialize the GL bindings if they haven't already been initialized. If
+ // the GPU unit tests are running, the mock GL implementation will already
+ // have been initialized.
+ if (!InitializeGLBindings(kGLImplementationDesktopGL)) {
+ LOG(ERROR) << "Could not initialize GL.";
+ return false;
+ }
- // Initializes context-independent parts of GLEW
- if (glxewInit() != GLEW_OK) {
- LOG(ERROR) << "glxewInit failed";
- return false;
- }
- // glxewContextInit really only needs a display connection to
- // complete, and we don't want to have to create an OpenGL context
- // just to get access to GLX 1.3 entry points to create pbuffers.
- // We therefore added a glxewContextInitWithDisplay entry point.
+ // Only check the GLX version if we are in fact using GLX. We might actually
+ // be using the mock GL implementation.
+ if (GetGLImplementation() == kGLImplementationDesktopGL) {
Display* display = x11_util::GetXDisplay();
- if (glxewContextInitWithDisplay(display) != GLEW_OK) {
- LOG(ERROR) << "glxewContextInit failed";
- return false;
- }
-
int major, minor;
if (!glXQueryVersion(display, &major, &minor)) {
LOG(ERROR) << "glxQueryVersion failed";
@@ -199,11 +178,6 @@ bool ViewGLContext::Initialize(bool multisampled) {
return false;
}
- if (!InitializeGLEW()) {
- Destroy();
- return false;
- }
-
if (!InitializeCommon()) {
Destroy();
return false;
@@ -214,7 +188,7 @@ bool ViewGLContext::Initialize(bool multisampled) {
void ViewGLContext::Destroy() {
Display* display = x11_util::GetXDisplay();
- Bool result = glXMakeCurrent(display, 0, 0);
+ 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
@@ -272,29 +246,24 @@ GLContext* GLContext::CreateViewGLContext(gfx::PluginWindowHandle window,
if (!InitializeOneOff())
return NULL;
- if (OSMesaCreateContext) {
- // TODO(apatrick): Support OSMesa rendering to a window on Linux.
- NOTREACHED() << "OSMesa rendering to a window is not yet implemented.";
- return NULL;
- } else {
- scoped_ptr<ViewGLContext> context(new ViewGLContext(window));
+ switch (GetGLImplementation()) {
+ case kGLImplementationDesktopGL: {
+ scoped_ptr<ViewGLContext> context(new ViewGLContext(window));
- if (!context->Initialize(multisampled))
- return NULL;
+ if (!context->Initialize(multisampled))
+ return NULL;
- return context.release();
+ return context.release();
+ }
+ case kGLImplementationMockGL:
+ return new StubGLContext;
+ default:
+ NOTREACHED();
+ return NULL;
}
}
-bool PbufferGLContext::Initialize(void* shared_handle) {
- if (!glXChooseFBConfig ||
- !glXCreateNewContext ||
- !glXCreatePbuffer ||
- !glXDestroyPbuffer) {
- LOG(ERROR) << "Pbuffer support not available.";
- return false;
- }
-
+bool PbufferGLContext::Initialize(GLContext* shared_context) {
static const int config_attributes[] = {
GLX_DRAWABLE_TYPE,
GLX_PBUFFER_BIT,
@@ -319,10 +288,15 @@ bool PbufferGLContext::Initialize(void* shared_handle) {
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,
- static_cast<GLContextHandle>(shared_handle),
+ shared_handle,
True);
if (!context_) {
LOG(ERROR) << "glXCreateNewContext failed.";
@@ -349,11 +323,6 @@ bool PbufferGLContext::Initialize(void* shared_handle) {
return false;
}
- if (!InitializeGLEW()) {
- Destroy();
- return false;
- }
-
if (!InitializeCommon()) {
Destroy();
return false;
@@ -364,7 +333,7 @@ bool PbufferGLContext::Initialize(void* shared_handle) {
void PbufferGLContext::Destroy() {
Display* display = x11_util::GetXDisplay();
- Bool result = glXMakeCurrent(display, 0, 0);
+ 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.
@@ -417,14 +386,8 @@ void* PbufferGLContext::GetHandle() {
return context_;
}
-bool PixmapGLContext::Initialize(void* shared_handle) {
+bool PixmapGLContext::Initialize(GLContext* shared_context) {
LOG(INFO) << "GL context: using pixmaps.";
- if (!glXChooseVisual ||
- !glXCreateGLXPixmap ||
- !glXDestroyGLXPixmap) {
- LOG(ERROR) << "Pixmap support not available.";
- return false;
- }
static int attributes[] = {
GLX_RGBA,
@@ -441,9 +404,12 @@ bool PixmapGLContext::Initialize(void* shared_handle) {
LOG(ERROR) << "glXChooseVisual failed.";
return false;
}
- context_ = glXCreateContext(display, visual_info.get(),
- static_cast<GLContextHandle>(shared_handle),
- True);
+
+ 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;
@@ -468,11 +434,6 @@ bool PixmapGLContext::Initialize(void* shared_handle) {
return false;
}
- if (!InitializeGLEW()) {
- Destroy();
- return false;
- }
-
if (!InitializeCommon()) {
Destroy();
return false;
@@ -483,7 +444,7 @@ bool PixmapGLContext::Initialize(void* shared_handle) {
void PixmapGLContext::Destroy() {
Display* display = x11_util::GetXDisplay();
- Bool result = glXMakeCurrent(display, 0, 0);
+ 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.
@@ -541,27 +502,27 @@ void* PixmapGLContext::GetHandle() {
return context_;
}
-GLContext* GLContext::CreateOffscreenGLContext(void* shared_handle) {
+GLContext* GLContext::CreateOffscreenGLContext(GLContext* shared_context) {
if (!InitializeOneOff())
return NULL;
- if (OSMesaCreateContext) {
- scoped_ptr<OSMesaGLContext> context(new OSMesaGLContext);
+ switch (GetGLImplementation()) {
+ case kGLImplementationDesktopGL: {
+ scoped_ptr<PbufferGLContext> context(new PbufferGLContext);
+ if (context->Initialize(shared_context))
+ return context.release();
- if (!context->Initialize(shared_handle))
- return NULL;
-
- return context.release();
- } else {
- scoped_ptr<PbufferGLContext> context(new PbufferGLContext);
- if (context->Initialize(shared_handle))
- return context.release();
+ scoped_ptr<PixmapGLContext> context_pixmap(new PixmapGLContext);
+ if (context_pixmap->Initialize(shared_context))
+ return context_pixmap.release();
- scoped_ptr<PixmapGLContext> context_pixmap(new PixmapGLContext);
- if (context_pixmap->Initialize(shared_handle))
- return context_pixmap.release();
-
- return NULL;
+ return NULL;
+ }
+ case kGLImplementationMockGL:
+ return new StubGLContext;
+ default:
+ NOTREACHED();
+ return NULL;
}
}
diff --git a/app/gfx/gl/gl_context_mac.cc b/app/gfx/gl/gl_context_mac.cc
index ab08c60..e69f644 100644
--- a/app/gfx/gl/gl_context_mac.cc
+++ b/app/gfx/gl/gl_context_mac.cc
@@ -4,15 +4,15 @@
// This file implements the ViewGLContext and PbufferGLContext classes.
-#include <GL/glew.h>
-#include <GL/osmew.h>
#include <OpenGL/OpenGL.h>
#include "app/surface/accelerated_surface_mac.h"
#include "base/logging.h"
#include "base/scoped_ptr.h"
+#include "app/gfx/gl/gl_bindings.h"
#include "app/gfx/gl/gl_context.h"
-#include "app/gfx/gl/gl_context_osmesa.h"
+#include "app/gfx/gl/gl_context_stub.h"
+#include "app/gfx/gl/gl_implementation.h"
namespace gfx {
@@ -30,7 +30,7 @@ class PbufferGLContext : public GLContext {
}
// Initializes the GL context.
- bool Initialize(void* shared_handle);
+ bool Initialize(GLContext* shared_context);
virtual void Destroy();
virtual bool MakeCurrent();
@@ -52,12 +52,16 @@ static bool InitializeOneOff() {
if (initialized)
return true;
- osmewInit();
+ if (!InitializeGLBindings(kGLImplementationDesktopGL)) {
+ LOG(ERROR) << "Could not initialize GL.";
+ return false;
+ }
+
initialized = true;
return true;
}
-bool PbufferGLContext::Initialize(void* shared_handle) {
+bool PbufferGLContext::Initialize(GLContext* shared_context) {
// Create a 1x1 pbuffer and associated context to bootstrap things.
static const CGLPixelFormatAttribute attribs[] = {
(CGLPixelFormatAttribute) kCGLPFAPBuffer,
@@ -75,9 +79,12 @@ bool PbufferGLContext::Initialize(void* shared_handle) {
if (!pixel_format) {
return false;
}
- CGLError res = CGLCreateContext(pixel_format,
- static_cast<GLContextHandle>(shared_handle),
- &context_);
+
+ 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) {
DLOG(ERROR) << "Error creating context.";
@@ -103,11 +110,6 @@ bool PbufferGLContext::Initialize(void* shared_handle) {
return false;
}
- if (!InitializeGLEW()) {
- Destroy();
- return false;
- }
-
if (!InitializeCommon()) {
Destroy();
return false;
@@ -160,23 +162,23 @@ void* PbufferGLContext::GetHandle() {
return context_;
}
-GLContext* GLContext::CreateOffscreenGLContext(void* shared_handle) {
+GLContext* GLContext::CreateOffscreenGLContext(GLContext* shared_context) {
if (!InitializeOneOff())
return NULL;
- if (OSMesaCreateContext) {
- scoped_ptr<OSMesaGLContext> context(new OSMesaGLContext);
-
- if (!context->Initialize(shared_handle))
- return NULL;
+ switch (GetGLImplementation()) {
+ case kGLImplementationDesktopGL: {
+ scoped_ptr<PbufferGLContext> context(new PbufferGLContext);
+ if (!context->Initialize(shared_context))
+ return NULL;
- return context.release();
- } else {
- scoped_ptr<PbufferGLContext> context(new PbufferGLContext);
- if (!context->Initialize(shared_handle))
+ return context.release();
+ }
+ case kGLImplementationMockGL:
+ return new StubGLContext;
+ default:
+ NOTREACHED();
return NULL;
-
- return context.release();
}
}
diff --git a/app/gfx/gl/gl_context_osmesa.cc b/app/gfx/gl/gl_context_osmesa.cc
index 49057d2..6d144cb 100644
--- a/app/gfx/gl/gl_context_osmesa.cc
+++ b/app/gfx/gl/gl_context_osmesa.cc
@@ -2,11 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <GL/glew.h>
-#include <GL/osmew.h>
-
#include <algorithm>
+#include "app/gfx/gl/gl_bindings.h"
#include "app/gfx/gl/gl_context_osmesa.h"
namespace gfx {
@@ -18,14 +16,17 @@ OSMesaGLContext::OSMesaGLContext() : context_(NULL)
OSMesaGLContext::~OSMesaGLContext() {
}
-bool OSMesaGLContext::Initialize(void* shared_handle) {
+bool OSMesaGLContext::Initialize(GLContext* shared_context) {
DCHECK(!context_);
size_ = gfx::Size(1, 1);
buffer_.reset(new int32[1]);
- context_ = OSMesaCreateContext(GL_RGBA,
- static_cast<OSMesaContext>(shared_handle));
+ OSMesaContext shared_handle = NULL;
+ if (shared_context)
+ shared_handle = static_cast<OSMesaContext>(shared_context->GetHandle());
+
+ context_ = OSMesaCreateContext(GL_RGBA, shared_handle);
if (!context_)
return false;
@@ -34,11 +35,6 @@ bool OSMesaGLContext::Initialize(void* shared_handle) {
return false;
}
- if (!InitializeGLEW()) {
- Destroy();
- return false;
- }
-
if (!InitializeCommon()) {
Destroy();
return false;
diff --git a/app/gfx/gl/gl_context_osmesa.h b/app/gfx/gl/gl_context_osmesa.h
index 4959c846..62acc5b 100644
--- a/app/gfx/gl/gl_context_osmesa.h
+++ b/app/gfx/gl/gl_context_osmesa.h
@@ -20,7 +20,7 @@ class OSMesaGLContext : public GLContext {
virtual ~OSMesaGLContext();
// Initialize an OSMesa GL context with the default 1 x 1 initial size.
- bool Initialize(void* shared_handle);
+ bool Initialize(GLContext* shared_context);
// Implement GLContext.
virtual void Destroy();
@@ -40,11 +40,9 @@ class OSMesaGLContext : public GLContext {
}
private:
-#if !defined(UNIT_TEST)
gfx::Size size_;
scoped_array<int32> buffer_;
OSMesaContext context_;
-#endif
DISALLOW_COPY_AND_ASSIGN(OSMesaGLContext);
};
diff --git a/app/gfx/gl/gl_context_stub.h b/app/gfx/gl/gl_context_stub.h
new file mode 100644
index 0000000..f7b6044
--- /dev/null
+++ b/app/gfx/gl/gl_context_stub.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2010 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 APP_GFX_GL_GL_CONTEXT_STUB_H_
+#define APP_GFX_GL_GL_CONTEXT_STUB_H_
+
+#include "app/gfx/gl/gl_context.h"
+
+namespace gfx {
+
+// A GLContext that does nothing for unit tests.
+class StubGLContext : public gfx::GLContext {
+ public:
+ // Implement GLContext.
+ virtual void Destroy() {}
+ virtual bool MakeCurrent() { return true; }
+ virtual bool IsCurrent() { return true; }
+ virtual bool IsOffscreen() { return false; }
+ virtual void SwapBuffers() {}
+ virtual gfx::Size GetSize() { return size_; }
+ virtual void* GetHandle() { return NULL; }
+
+ void SetSize(const gfx::Size& size) { size_ = size; }
+
+ private:
+ gfx::Size size_;
+};
+
+} // namespace gfx
+
+#endif // APP_GFX_GL_GL_CONTEXT_STUB_H_
diff --git a/app/gfx/gl/gl_context_win.cc b/app/gfx/gl/gl_context_win.cc
index 8bbb6268..b6bac4d 100644
--- a/app/gfx/gl/gl_context_win.cc
+++ b/app/gfx/gl/gl_context_win.cc
@@ -4,17 +4,16 @@
// This file implements the NativeViewGLContext and PbufferGLContext classes.
-#include <GL/glew.h>
-#include <GL/osmew.h>
-#include <GL/wglew.h>
-#include <windows.h>
-
#include <algorithm>
#include "base/logging.h"
#include "base/scoped_ptr.h"
+#include "app/gfx/gl/gl_bindings.h"
#include "app/gfx/gl/gl_context.h"
+#include "app/gfx/gl/gl_context_egl.h"
#include "app/gfx/gl/gl_context_osmesa.h"
+#include "app/gfx/gl/gl_context_stub.h"
+#include "app/gfx/gl/gl_implementation.h"
namespace gfx {
@@ -100,7 +99,7 @@ class PbufferGLContext : public GLContext {
}
// Initializes the GL context.
- bool Initialize(void* shared_handle);
+ bool Initialize(GLContext* shared_context);
virtual void Destroy();
virtual bool MakeCurrent();
@@ -118,9 +117,14 @@ class PbufferGLContext : public GLContext {
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.
@@ -155,94 +159,103 @@ static bool InitializeOneOff() {
if (initialized)
return true;
- osmewInit();
- if (!OSMesaCreateContext) {
- // 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)) {
- return false;
+ if (!InitializeGLBindings(kGLImplementationOSMesaGL)) {
+ if (!InitializeGLBindings(kGLImplementationEGLGLES2)) {
+ if (!InitializeGLBindings(kGLImplementationDesktopGL)) {
+ LOG(ERROR) << "Could not initialize GL.";
+ 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) {
- return false;
- }
- HWND intermediate_window = ::CreateWindow(
- reinterpret_cast<wchar_t*>(class_registration),
- L"",
- WS_OVERLAPPEDWINDOW,
- 0, 0,
- CW_USEDEFAULT, CW_USEDEFAULT,
- NULL,
- NULL,
- NULL,
- NULL);
-
- if (!intermediate_window) {
- ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration),
- module_handle);
- 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)) {
+ return false;
+ }
- HDC intermediate_dc = ::GetDC(intermediate_window);
- g_regular_pixel_format = ::ChoosePixelFormat(intermediate_dc,
- &kPixelFormatDescriptor);
- if (g_regular_pixel_format == 0) {
- DLOG(ERROR) << "Unable to get the pixel format for GL context.";
- ::ReleaseDC(intermediate_window, intermediate_dc);
- ::DestroyWindow(intermediate_window);
- ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration),
- module_handle);
- return false;
- }
- if (!::SetPixelFormat(intermediate_dc, g_regular_pixel_format,
- &kPixelFormatDescriptor)) {
- DLOG(ERROR) << "Unable to set the pixel format for GL context.";
- ::ReleaseDC(intermediate_window, intermediate_dc);
- ::DestroyWindow(intermediate_window);
- ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration),
- module_handle);
- 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) {
+ 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)) {
- // GL context was successfully created and applied to the window's DC.
- // Startup GLEW, the GL extensions wrangler.
- if (InitializeGLEW()) {
- DLOG(INFO) << "Initialized GLEW " << glewGetString(GLEW_VERSION);
- } else {
- ::wglMakeCurrent(intermediate_dc, NULL);
- ::wglDeleteContext(gl_context);
- ::ReleaseDC(intermediate_window, intermediate_dc);
- ::DestroyWindow(intermediate_window);
- ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration),
- module_handle);
- 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);
+ return false;
+ }
+
+ // Early out if OSMesa offscreen renderer or EGL is present.
+ if (GetGLImplementation() != kGLImplementationDesktopGL) {
+ initialized = true;
+ return true;
+ }
+
+ HDC intermediate_dc = ::GetDC(g_window);
+ g_regular_pixel_format = ::ChoosePixelFormat(intermediate_dc,
+ &kPixelFormatDescriptor);
+ if (g_regular_pixel_format == 0) {
+ DLOG(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)) {
+ DLOG(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;
+ }
- // If the multi-sample extensions are present, query the api to determine
- // the pixel format.
- if (WGLEW_ARB_pixel_format && WGLEW_ARB_multisample) {
+ // 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,
@@ -264,28 +277,26 @@ static bool InitializeOneOff() {
static const int kNumSamples = 2;
for (int sample = 0; sample < kNumSamples; ++sample) {
pixel_attributes[1] = kSampleCount[sample];
- if (GL_TRUE == ::wglChoosePixelFormatARB(intermediate_dc,
- pixel_attributes,
- pixel_attributes_f,
- 1,
- &g_multisampled_pixel_format,
- &num_formats)) {
+ if (GL_TRUE == wglChoosePixelFormatARB(intermediate_dc,
+ pixel_attributes,
+ pixel_attributes_f,
+ 1,
+ &g_multisampled_pixel_format,
+ &num_formats)) {
break;
}
}
}
}
-
- ::wglMakeCurrent(intermediate_dc, NULL);
- ::wglDeleteContext(gl_context);
- ::ReleaseDC(intermediate_window, intermediate_dc);
- ::DestroyWindow(intermediate_window);
- ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration),
- module_handle);
}
- initialized = true;
+ wglMakeCurrent(intermediate_dc, NULL);
+ wglDeleteContext(gl_context);
+ ReleaseDC(g_window, intermediate_dc);
+ UnregisterClass(reinterpret_cast<wchar_t*>(class_registration),
+ module_handle);
+ initialized = true;
return true;
}
@@ -352,11 +363,6 @@ bool NativeViewGLContext::Initialize(bool multisampled) {
return false;
}
- if (!InitializeGLEW()) {
- Destroy();
- return false;
- }
-
if (!InitializeCommon()) {
Destroy();
return false;
@@ -510,7 +516,7 @@ void* OSMesaViewGLContext::GetHandle() {
void OSMesaViewGLContext::UpdateSize() {
// Change back buffer size to that of window.
RECT rect;
- GetWindowRect(window_, &rect);
+ GetClientRect(window_, &rect);
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)));
@@ -522,24 +528,38 @@ GLContext* GLContext::CreateViewGLContext(gfx::PluginWindowHandle window,
if (!InitializeOneOff())
return NULL;
- if (OSMesaCreateContext) {
- scoped_ptr<OSMesaViewGLContext> context(new OSMesaViewGLContext(window));
+ switch (GetGLImplementation()) {
+ case kGLImplementationOSMesaGL: {
+ scoped_ptr<OSMesaViewGLContext> context(new OSMesaViewGLContext(window));
+ if (!context->Initialize())
+ return NULL;
- 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();
- } else {
- scoped_ptr<NativeViewGLContext> context(new NativeViewGLContext(window));
+ return context.release();
+ }
+ case kGLImplementationDesktopGL: {
+ scoped_ptr<NativeViewGLContext> context(new NativeViewGLContext(window));
+ if (!context->Initialize(multisampled))
+ return NULL;
- if (!context->Initialize(multisampled))
+ return context.release();
+ }
+ case kGLImplementationMockGL:
+ return new StubGLContext;
+ default:
+ NOTREACHED();
return NULL;
-
- return context.release();
}
}
-bool PbufferGLContext::Initialize(void* shared_handle) {
+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);
@@ -547,10 +567,10 @@ bool PbufferGLContext::Initialize(void* shared_handle) {
// a stepping stone towards creating a frame buffer object. It doesn't
// matter what size it is.
const int kNoAttributes[] = { 0 };
- pbuffer_ = ::wglCreatePbufferARB(display_device_context,
- g_regular_pixel_format,
- 1, 1,
- kNoAttributes);
+ pbuffer_ = wglCreatePbufferARB(display_device_context,
+ g_regular_pixel_format,
+ 1, 1,
+ kNoAttributes);
::DeleteDC(display_device_context);
if (!pbuffer_) {
DLOG(ERROR) << "Unable to create pbuffer.";
@@ -558,22 +578,23 @@ bool PbufferGLContext::Initialize(void* shared_handle) {
return false;
}
- device_context_ = ::wglGetPbufferDCARB(pbuffer_);
+ device_context_ = wglGetPbufferDCARB(pbuffer_);
if (!device_context_) {
DLOG(ERROR) << "Unable to get pbuffer device context.";
Destroy();
return false;
}
- context_ = ::wglCreateContext(device_context_);
+ context_ = wglCreateContext(device_context_);
if (!context_) {
DLOG(ERROR) << "Failed to create GL context.";
Destroy();
return false;
}
- if (shared_handle) {
- if (!wglShareLists(static_cast<GLContextHandle>(shared_handle), context_)) {
+ if (shared_context) {
+ if (!wglShareLists(
+ static_cast<GLContextHandle>(shared_context->GetHandle()), context_)) {
DLOG(ERROR) << "Could not share GL contexts.";
Destroy();
return false;
@@ -585,11 +606,6 @@ bool PbufferGLContext::Initialize(void* shared_handle) {
return false;
}
- if (!InitializeGLEW()) {
- Destroy();
- return false;
- }
-
if (!InitializeCommon()) {
Destroy();
return false;
@@ -649,23 +665,50 @@ void* PbufferGLContext::GetHandle() {
return context_;
}
-GLContext* GLContext::CreateOffscreenGLContext(void* shared_handle) {
+GLContext* GLContext::CreateOffscreenGLContext(GLContext* shared_context) {
if (!InitializeOneOff())
return NULL;
- if (OSMesaCreateContext) {
- scoped_ptr<OSMesaGLContext> context(new OSMesaGLContext);
+ switch (GetGLImplementation()) {
+ case kGLImplementationOSMesaGL: {
+ scoped_ptr<OSMesaGLContext> context(new OSMesaGLContext);
+ if (!context->Initialize(shared_context))
+ return NULL;
- if (!context->Initialize(shared_handle))
- 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;
+ }
- return context.release();
- } else {
- scoped_ptr<PbufferGLContext> context(new PbufferGLContext);
- if (!context->Initialize(shared_handle))
- return NULL;
+ scoped_ptr<SecondaryEGLContext> context(
+ new SecondaryEGLContext());
+ if (!context->Initialize(shared_context))
+ return NULL;
- return context.release();
+ 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;
}
}
diff --git a/app/gfx/gl/gl_implementation.h b/app/gfx/gl/gl_implementation.h
new file mode 100644
index 0000000..0f1df36
--- /dev/null
+++ b/app/gfx/gl/gl_implementation.h
@@ -0,0 +1,30 @@
+// Copyright (c) 2010 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 APP_GFX_GL_GL_IMPLEMENTATION_H_
+#define APP_GFX_GL_GL_IMPLEMENTATION_H_
+
+namespace gfx {
+
+// The GL implementation currently in use.
+enum GLImplementation {
+ kGLImplementationNone,
+ kGLImplementationDesktopGL,
+ kGLImplementationOSMesaGL,
+ kGLImplementationEGLGLES2,
+ kGLImplementationMockGL
+};
+
+// Initialize a particular GL implementation.
+bool InitializeGLBindings(GLImplementation implementation);
+
+// Get the current GL implementation.
+GLImplementation GetGLImplementation();
+
+// Find an entry point in the current GL implementation.
+void* GetGLProcAddress(const char* name);
+
+} // namespace gfx
+
+#endif // APP_GFX_GL_GL_IMPLEMENTATION_H_
diff --git a/app/gfx/gl/gl_implementation_linux.cc b/app/gfx/gl/gl_implementation_linux.cc
new file mode 100644
index 0000000..e27cdae
--- /dev/null
+++ b/app/gfx/gl/gl_implementation_linux.cc
@@ -0,0 +1,80 @@
+// Copyright (c) 2010 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 <dlfcn.h>
+
+#include "base/logging.h"
+#include "app/gfx/gl/gl_bindings.h"
+#include "app/gfx/gl/gl_context_stub.h"
+#include "app/gfx/gl/gl_implementation.h"
+
+namespace gfx {
+namespace {
+typedef void* (*GetProcAddressProc)(const char* name);
+
+GLImplementation g_gl_implementation = kGLImplementationNone;
+void* g_shared_library;
+GetProcAddressProc g_get_proc_address;
+} // 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 (g_gl_implementation != kGLImplementationNone)
+ return true;
+
+ switch (implementation) {
+ case kGLImplementationDesktopGL:
+ g_shared_library = dlopen("libGL.so.1", RTLD_LAZY | RTLD_LOCAL);
+ if (!g_shared_library)
+ return false;
+
+ g_gl_implementation = kGLImplementationDesktopGL;
+
+ g_get_proc_address = reinterpret_cast<GetProcAddressProc>(
+ dlsym(g_shared_library, "glXGetProcAddress"));
+ CHECK(g_get_proc_address);
+
+ InitializeGLBindingsGL();
+ InitializeGLBindingsGLX();
+ break;
+
+ case kGLImplementationMockGL:
+ g_get_proc_address = GetMockGLProcAddress;
+ g_gl_implementation = kGLImplementationMockGL;
+ InitializeGLBindingsGL();
+ break;
+
+ default:
+ return false;
+ }
+
+
+ return true;
+}
+
+GLImplementation GetGLImplementation() {
+ return g_gl_implementation;
+}
+
+void* GetGLProcAddress(const char* name) {
+ DCHECK(g_gl_implementation != kGLImplementationNone);
+
+ if (g_get_proc_address) {
+ void* proc = g_get_proc_address(name);
+ if (proc)
+ return proc;
+ }
+
+ if (g_shared_library) {
+ void* proc = dlsym(g_shared_library, name);
+ if (proc)
+ return proc;
+ }
+
+ return NULL;
+}
+
+} // namespace gfx
diff --git a/app/gfx/gl/gl_implementation_mac.cc b/app/gfx/gl/gl_implementation_mac.cc
new file mode 100644
index 0000000..7975726
--- /dev/null
+++ b/app/gfx/gl/gl_implementation_mac.cc
@@ -0,0 +1,76 @@
+// Copyright (c) 2010 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 <dlfcn.h>
+
+#include "base/logging.h"
+#include "app/gfx/gl/gl_bindings.h"
+#include "app/gfx/gl/gl_implementation.h"
+
+namespace gfx {
+namespace {
+typedef void* (*GetProcAddressProc)(const char* name);
+
+GLImplementation g_gl_implementation = kGLImplementationNone;
+void* g_shared_library;
+GetProcAddressProc g_get_proc_address;
+} // 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 (g_gl_implementation != kGLImplementationNone)
+ return true;
+
+ switch (implementation) {
+ case kGLImplementationDesktopGL:
+ g_shared_library = dlopen(
+ "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL",
+ RTLD_LAZY | RTLD_LOCAL);
+ if (!g_shared_library)
+ return false;
+
+ g_gl_implementation = kGLImplementationDesktopGL;
+ g_get_proc_address = NULL;
+
+ InitializeGLBindingsGL();
+ break;
+
+ case kGLImplementationMockGL:
+ g_get_proc_address = GetMockGLProcAddress;
+ g_gl_implementation = kGLImplementationMockGL;
+ InitializeGLBindingsGL();
+ break;
+
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+GLImplementation GetGLImplementation() {
+ return g_gl_implementation;
+}
+
+void* GetGLProcAddress(const char* name) {
+ DCHECK(g_gl_implementation != kGLImplementationNone);
+
+ if (g_get_proc_address) {
+ void* proc = g_get_proc_address(name);
+ if (proc)
+ return proc;
+ }
+
+ if (g_shared_library) {
+ void* proc = dlsym(g_shared_library, name);
+ if (proc)
+ return proc;
+ }
+
+ return NULL;
+}
+
+} // namespace gfx
diff --git a/app/gfx/gl/gl_implementation_win.cc b/app/gfx/gl/gl_implementation_win.cc
new file mode 100644
index 0000000..cb25f07
--- /dev/null
+++ b/app/gfx/gl/gl_implementation_win.cc
@@ -0,0 +1,140 @@
+// Copyright (c) 2010 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/logging.h"
+#include "app/gfx/gl/gl_bindings.h"
+#include "app/gfx/gl/gl_implementation.h"
+
+namespace gfx {
+
+namespace {
+
+typedef void* (GL_BINDING_CALL *GetProcAddressProc)(const char* name);
+
+GLImplementation g_gl_implementation = kGLImplementationNone;
+std::vector<HMODULE> g_modules;
+static GetProcAddressProc g_get_proc_address;
+
+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 (g_gl_implementation != kGLImplementationNone)
+ return true;
+
+ HMODULE module;
+ switch (implementation) {
+ case kGLImplementationOSMesaGL:
+ // When using OSMesa, just use OSMesaGetProcAddress to find entry points.
+ module = LoadLibraryA("osmesa.dll");
+ if (!module)
+ return false;
+
+ g_gl_implementation = kGLImplementationOSMesaGL;
+
+ g_get_proc_address = reinterpret_cast<GetProcAddressProc>(
+ GetProcAddress(module, "OSMesaGetProcAddress"));
+ DCHECK(g_get_proc_address);
+
+ InitializeGLBindingsGL();
+ InitializeGLBindingsOSMESA();
+ break;
+
+ case kGLImplementationEGLGLES2:
+ // When using EGL, first try eglGetProcAddress and then Windows
+ // GetProcAddress on both the EGL and GLES2 DLLs.
+ module = LoadLibraryA("libegl.dll");
+ if (!module)
+ return false;
+
+ g_gl_implementation = kGLImplementationEGLGLES2;
+
+ g_get_proc_address = reinterpret_cast<GetProcAddressProc>(
+ GetProcAddress(module, "eglGetProcAddress"));
+ DCHECK(g_get_proc_address);
+
+ g_modules.push_back(module);
+
+ module = LoadLibraryA("libglesv2.dll");
+ DCHECK(module);
+
+ g_modules.push_back(module);
+
+ InitializeGLBindingsGL();
+ InitializeGLBindingsEGL();
+
+ // These two functions take single precision float ranther 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.
+ module = LoadLibraryA("opengl32.dll");
+ if (!module)
+ return false;
+
+ g_gl_implementation = kGLImplementationDesktopGL;
+
+ g_get_proc_address = reinterpret_cast<GetProcAddressProc>(
+ GetProcAddress(module, "wglGetProcAddress"));
+ DCHECK(g_get_proc_address);
+
+ g_modules.push_back(module);
+
+ InitializeGLBindingsGL();
+ InitializeGLBindingsWGL();
+ break;
+
+ case kGLImplementationMockGL:
+ g_get_proc_address = GetMockGLProcAddress;
+ g_gl_implementation = kGLImplementationMockGL;
+ InitializeGLBindingsGL();
+ break;
+
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+GLImplementation GetGLImplementation() {
+ return g_gl_implementation;
+}
+
+void* GetGLProcAddress(const char* name) {
+ DCHECK(g_gl_implementation != kGLImplementationNone);
+
+ if (g_get_proc_address) {
+ void* proc = g_get_proc_address(name);
+ if (proc)
+ return proc;
+ }
+
+ for (size_t i = 0; i < g_modules.size(); ++i) {
+ void* proc = GetProcAddress(g_modules[i], name);
+ if (proc)
+ return proc;
+ }
+
+ return NULL;
+}
+
+} // namespace gfx
diff --git a/app/gfx/gl/gl_interface.cc b/app/gfx/gl/gl_interface.cc
new file mode 100644
index 0000000..22edd3d
--- /dev/null
+++ b/app/gfx/gl/gl_interface.cc
@@ -0,0 +1,20 @@
+// Copyright (c) 2009 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 "app/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/app/gfx/gl/gl_interface.h b/app/gfx/gl/gl_interface.h
new file mode 100644
index 0000000..2c9a6fb
--- /dev/null
+++ b/app/gfx/gl/gl_interface.h
@@ -0,0 +1,396 @@
+// Copyright (c) 2010 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 APP_GFX_GL_GL_INTERFACE_H_
+#define APP_GFX_GL_GL_INTERFACE_H_
+
+#include "app/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 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 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 IsFramebuffer(GLuint framebuffer) = 0;
+
+ virtual GLboolean IsProgram(GLuint program) = 0;
+
+ virtual GLboolean IsRenderbuffer(GLuint renderbuffer) = 0;
+
+ virtual GLboolean IsShader(GLuint shader) = 0;
+
+ virtual GLboolean IsTexture(GLuint texture) = 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 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 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 GetMaxValueInBuffer(
+ GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) = 0;
+
+ private:
+ static GLInterface* interface_;
+};
+
+} // namespace gfx
+
+#endif // APP_GFX_GL_GL_INTERFACE_H_
+
+
+
diff --git a/app/gfx/gl/gl_mock.h b/app/gfx/gl/gl_mock.h
new file mode 100644
index 0000000..47e048d
--- /dev/null
+++ b/app/gfx/gl/gl_mock.h
@@ -0,0 +1,393 @@
+// Copyright (c) 2010 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 mock GL Interface for unit testing. It has to mock
+// Desktop GL, not GLES2 as it is used to test the service side code.
+
+#ifndef APP_GFX_GL_GL_MOCK_H_
+#define APP_GFX_GL_GL_MOCK_H_
+
+#include "app/gfx/gl/gl_interface.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace gfx {
+
+class MockGLInterface : public GLInterface {
+ public:
+ virtual ~MockGLInterface() {
+ }
+
+ MOCK_METHOD1(ActiveTexture, void(GLenum texture));
+
+ MOCK_METHOD2(AttachShader, void(GLuint program, GLuint shader));
+
+ MOCK_METHOD3(BindAttribLocation, void(
+ GLuint program, GLuint index, const char* name));
+
+ MOCK_METHOD2(BindBuffer, void(GLenum target, GLuint buffer));
+
+ MOCK_METHOD2(BindFramebufferEXT, void(GLenum target, GLuint framebuffer));
+
+ MOCK_METHOD2(BindRenderbufferEXT, void(GLenum target, GLuint renderbuffer));
+
+ MOCK_METHOD2(BindTexture, void(GLenum target, GLuint texture));
+
+ MOCK_METHOD4(BlendColor, void(
+ GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha));
+
+ MOCK_METHOD1(BlendEquation, void(GLenum mode));
+
+ MOCK_METHOD2(BlendEquationSeparate, void(GLenum modeRGB, GLenum modeAlpha));
+
+ MOCK_METHOD2(BlendFunc, void(GLenum sfactor, GLenum dfactor));
+
+ MOCK_METHOD4(BlendFuncSeparate, void(
+ GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha));
+
+ MOCK_METHOD4(BufferData, void(
+ GLenum target, GLsizeiptr size, const void* data, GLenum usage));
+
+ MOCK_METHOD4(BufferSubData, void(
+ GLenum target, GLintptr offset, GLsizeiptr size, const void* data));
+
+ MOCK_METHOD1(CheckFramebufferStatusEXT, GLenum(GLenum target));
+
+ MOCK_METHOD1(Clear, void(GLbitfield mask));
+
+ MOCK_METHOD4(ClearColor, void(
+ GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha));
+
+ MOCK_METHOD1(ClearDepth, void(GLclampd depth));
+
+ MOCK_METHOD1(ClearDepthf, void(GLclampf depth));
+
+ MOCK_METHOD1(ClearStencil, void(GLint s));
+
+ MOCK_METHOD4(ColorMask, void(
+ GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha));
+
+ MOCK_METHOD1(CompileShader, void(GLuint shader));
+
+ MOCK_METHOD8(CompressedTexImage2D, void(
+ GLenum target, GLint level, GLenum internalformat, GLsizei width,
+ GLsizei height, GLint border, GLsizei imageSize, const void* data));
+
+ MOCK_METHOD9(CompressedTexSubImage2D, void(
+ GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
+ GLsizei height, GLenum format, GLsizei imageSize, const void* data));
+
+ MOCK_METHOD8(CopyTexImage2D, void(
+ GLenum target, GLint level, GLenum internalformat, GLint x, GLint y,
+ GLsizei width, GLsizei height, GLint border));
+
+ MOCK_METHOD8(CopyTexSubImage2D, void(
+ GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height));
+
+ MOCK_METHOD0(CreateProgram, GLuint());
+
+ MOCK_METHOD1(CreateShader, GLuint(GLenum type));
+
+ MOCK_METHOD1(CullFace, void(GLenum mode));
+
+ MOCK_METHOD2(DeleteBuffersARB, void(GLsizei n, const GLuint* buffers));
+
+ MOCK_METHOD2(DeleteFramebuffersEXT,
+ void(GLsizei n, const GLuint* framebuffers));
+
+ MOCK_METHOD1(DeleteProgram, void(GLuint program));
+
+ MOCK_METHOD2(DeleteRenderbuffersEXT, void(
+ GLsizei n, const GLuint* renderbuffers));
+
+ MOCK_METHOD1(DeleteShader, void(GLuint shader));
+
+ MOCK_METHOD2(DeleteTextures, void(GLsizei n, const GLuint* textures));
+
+ MOCK_METHOD1(DepthFunc, void(GLenum func));
+
+ MOCK_METHOD1(DepthMask, void(GLboolean flag));
+
+ MOCK_METHOD2(DepthRange, void(GLclampd zNear, GLclampd zFar));
+
+ MOCK_METHOD2(DepthRangef, void(GLclampf zNear, GLclampf zFar));
+
+ MOCK_METHOD2(DetachShader, void(GLuint program, GLuint shader));
+
+ MOCK_METHOD1(Disable, void(GLenum cap));
+
+ MOCK_METHOD1(DisableVertexAttribArray, void(GLuint index));
+
+ MOCK_METHOD3(DrawArrays, void(GLenum mode, GLint first, GLsizei count));
+
+ MOCK_METHOD4(DrawElements, void(
+ GLenum mode, GLsizei count, GLenum type, const void* indices));
+
+ MOCK_METHOD1(Enable, void(GLenum cap));
+
+ MOCK_METHOD1(EnableVertexAttribArray, void(GLuint index));
+
+ MOCK_METHOD0(Finish, void());
+
+ MOCK_METHOD0(Flush, void());
+
+ MOCK_METHOD4(FramebufferRenderbufferEXT, void(
+ GLenum target, GLenum attachment, GLenum renderbuffertarget,
+ GLuint renderbuffer));
+
+ MOCK_METHOD5(FramebufferTexture2DEXT, void(
+ GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
+ GLint level));
+
+ MOCK_METHOD1(FrontFace, void(GLenum mode));
+
+ MOCK_METHOD2(GenBuffersARB, void(GLsizei n, GLuint* buffers));
+
+ MOCK_METHOD1(GenerateMipmapEXT, void(GLenum target));
+
+ MOCK_METHOD2(GenFramebuffersEXT, void(GLsizei n, GLuint* framebuffers));
+
+ MOCK_METHOD2(GenRenderbuffersEXT, void(GLsizei n, GLuint* renderbuffers));
+
+ MOCK_METHOD2(GenTextures, void(GLsizei n, GLuint* textures));
+
+ MOCK_METHOD7(GetActiveAttrib, void(
+ GLuint program, GLuint index, GLsizei bufsize, GLsizei* length,
+ GLint* size, GLenum* type, char* name));
+
+ MOCK_METHOD7(GetActiveUniform, void(
+ GLuint program, GLuint index, GLsizei bufsize, GLsizei* length,
+ GLint* size, GLenum* type, char* name));
+
+ MOCK_METHOD4(GetAttachedShaders, void(
+ GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders));
+
+ MOCK_METHOD2(GetAttribLocation, GLint(GLuint program, const char* name));
+
+ MOCK_METHOD2(GetBooleanv, void(GLenum pname, GLboolean* params));
+
+ MOCK_METHOD3(GetBufferParameteriv, void(
+ GLenum target, GLenum pname, GLint* params));
+
+ MOCK_METHOD0(GetError, GLenum());
+
+ MOCK_METHOD2(GetFloatv, void(GLenum pname, GLfloat* params));
+
+ MOCK_METHOD4(GetFramebufferAttachmentParameterivEXT, void(
+ GLenum target, GLenum attachment, GLenum pname, GLint* params));
+
+ MOCK_METHOD2(GetIntegerv, void(GLenum pname, GLint* params));
+
+ MOCK_METHOD3(GetProgramiv, void(GLuint program, GLenum pname, GLint* params));
+
+ MOCK_METHOD4(GetProgramInfoLog, void(
+ GLuint program, GLsizei bufsize, GLsizei* length, char* infolog));
+
+ MOCK_METHOD3(GetRenderbufferParameterivEXT, void(
+ GLenum target, GLenum pname, GLint* params));
+
+ MOCK_METHOD3(GetShaderiv, void(GLuint shader, GLenum pname, GLint* params));
+
+ MOCK_METHOD4(GetShaderInfoLog, void(
+ GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog));
+
+ MOCK_METHOD4(GetShaderPrecisionFormat, void(
+ GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision));
+
+ MOCK_METHOD4(GetShaderSource, void(
+ GLuint shader, GLsizei bufsize, GLsizei* length, char* source));
+
+ MOCK_METHOD1(GetString, const GLubyte*(GLenum name));
+
+ MOCK_METHOD3(GetTexParameterfv, void(
+ GLenum target, GLenum pname, GLfloat* params));
+
+ MOCK_METHOD3(GetTexParameteriv, void(
+ GLenum target, GLenum pname, GLint* params));
+
+ MOCK_METHOD3(GetUniformfv,
+ void(GLuint program, GLint location, GLfloat* params));
+
+ MOCK_METHOD3(GetUniformiv,
+ void(GLuint program, GLint location, GLint* params));
+
+ MOCK_METHOD2(GetUniformLocation, GLint(GLuint program, const char* name));
+
+ MOCK_METHOD3(GetVertexAttribfv, void(
+ GLuint index, GLenum pname, GLfloat* params));
+
+ MOCK_METHOD3(GetVertexAttribiv,
+ void(GLuint index, GLenum pname, GLint* params));
+
+ MOCK_METHOD3(GetVertexAttribPointerv, void(
+ GLuint index, GLenum pname, void** pointer));
+
+ MOCK_METHOD2(Hint, void(GLenum target, GLenum mode));
+
+ MOCK_METHOD1(IsBuffer, GLboolean(GLuint buffer));
+
+ MOCK_METHOD1(IsEnabled, GLboolean(GLenum cap));
+
+ MOCK_METHOD1(IsFramebuffer, GLboolean(GLuint framebuffer));
+
+ MOCK_METHOD1(IsProgram, GLboolean(GLuint program));
+
+ MOCK_METHOD1(IsRenderbuffer, GLboolean(GLuint renderbuffer));
+
+ MOCK_METHOD1(IsShader, GLboolean(GLuint shader));
+
+ MOCK_METHOD1(IsTexture, GLboolean(GLuint texture));
+
+ MOCK_METHOD1(LineWidth, void(GLfloat width));
+
+ MOCK_METHOD1(LinkProgram, void(GLuint program));
+
+ MOCK_METHOD2(PixelStorei, void(GLenum pname, GLint param));
+
+ MOCK_METHOD2(PolygonOffset, void(GLfloat factor, GLfloat units));
+
+ MOCK_METHOD7(ReadPixels, void(
+ GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
+ GLenum type, void* pixels));
+
+ MOCK_METHOD0(ReleaseShaderCompiler, void());
+
+ MOCK_METHOD4(RenderbufferStorageEXT, void(
+ GLenum target, GLenum internalformat, GLsizei width, GLsizei height));
+
+ MOCK_METHOD2(SampleCoverage, void(GLclampf value, GLboolean invert));
+
+ MOCK_METHOD4(Scissor, void(GLint x, GLint y, GLsizei width, GLsizei height));
+
+ MOCK_METHOD5(ShaderBinary, void(
+ GLsizei n, const GLuint* shaders, GLenum binaryformat,
+ const void* binary, GLsizei length));
+
+ MOCK_METHOD4(ShaderSource, void(
+ GLuint shader, GLsizei count, const char** str, const GLint* length));
+
+ MOCK_METHOD3(StencilFunc, void(GLenum func, GLint ref, GLuint mask));
+
+ MOCK_METHOD4(StencilFuncSeparate, void(
+ GLenum face, GLenum func, GLint ref, GLuint mask));
+
+ MOCK_METHOD1(StencilMask, void(GLuint mask));
+
+ MOCK_METHOD2(StencilMaskSeparate, void(GLenum face, GLuint mask));
+
+ MOCK_METHOD3(StencilOp, void(GLenum fail, GLenum zfail, GLenum zpass));
+
+ MOCK_METHOD4(StencilOpSeparate, void(
+ GLenum face, GLenum fail, GLenum zfail, GLenum zpass));
+
+ MOCK_METHOD9(TexImage2D, void(
+ GLenum target, GLint level, GLint internalformat, GLsizei width,
+ GLsizei height, GLint border, GLenum format, GLenum type,
+ const void* pixels));
+
+ MOCK_METHOD3(TexParameterf, void(GLenum target, GLenum pname, GLfloat param));
+
+ MOCK_METHOD3(TexParameterfv, void(
+ GLenum target, GLenum pname, const GLfloat* params));
+
+ MOCK_METHOD3(TexParameteri, void(GLenum target, GLenum pname, GLint param));
+
+ MOCK_METHOD3(TexParameteriv, void(
+ GLenum target, GLenum pname, const GLint* params));
+
+ MOCK_METHOD9(TexSubImage2D, void(
+ GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
+ GLsizei height, GLenum format, GLenum type, const void* pixels));
+
+ MOCK_METHOD2(Uniform1f, void(GLint location, GLfloat x));
+
+ MOCK_METHOD3(Uniform1fv,
+ void(GLint location, GLsizei count, const GLfloat* v));
+
+ MOCK_METHOD2(Uniform1i, void(GLint location, GLint x));
+
+ MOCK_METHOD3(Uniform1iv, void(GLint location, GLsizei count, const GLint* v));
+
+ MOCK_METHOD3(Uniform2f, void(GLint location, GLfloat x, GLfloat y));
+
+ MOCK_METHOD3(Uniform2fv,
+ void(GLint location, GLsizei count, const GLfloat* v));
+
+ MOCK_METHOD3(Uniform2i, void(GLint location, GLint x, GLint y));
+
+ MOCK_METHOD3(Uniform2iv, void(GLint location, GLsizei count, const GLint* v));
+
+ MOCK_METHOD4(Uniform3f,
+ void(GLint location, GLfloat x, GLfloat y, GLfloat z));
+
+ MOCK_METHOD3(Uniform3fv,
+ void(GLint location, GLsizei count, const GLfloat* v));
+
+ MOCK_METHOD4(Uniform3i, void(GLint location, GLint x, GLint y, GLint z));
+
+ MOCK_METHOD3(Uniform3iv, void(GLint location, GLsizei count, const GLint* v));
+
+ MOCK_METHOD5(Uniform4f, void(
+ GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w));
+
+ MOCK_METHOD3(Uniform4fv,
+ void(GLint location, GLsizei count, const GLfloat* v));
+
+ MOCK_METHOD5(Uniform4i,
+ void(GLint location, GLint x, GLint y, GLint z, GLint w));
+
+ MOCK_METHOD3(Uniform4iv, void(GLint location, GLsizei count, const GLint* v));
+
+ MOCK_METHOD4(UniformMatrix2fv, void(
+ GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat* value));
+
+ MOCK_METHOD4(UniformMatrix3fv, void(
+ GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat* value));
+
+ MOCK_METHOD4(UniformMatrix4fv, void(
+ GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat* value));
+
+ MOCK_METHOD1(UseProgram, void(GLuint program));
+
+ MOCK_METHOD1(ValidateProgram, void(GLuint program));
+
+ MOCK_METHOD2(VertexAttrib1f, void(GLuint indx, GLfloat x));
+
+ MOCK_METHOD2(VertexAttrib1fv, void(GLuint indx, const GLfloat* values));
+
+ MOCK_METHOD3(VertexAttrib2f, void(GLuint indx, GLfloat x, GLfloat y));
+
+ MOCK_METHOD2(VertexAttrib2fv, void(GLuint indx, const GLfloat* values));
+
+ MOCK_METHOD4(VertexAttrib3f,
+ void(GLuint indx, GLfloat x, GLfloat y, GLfloat z));
+
+ MOCK_METHOD2(VertexAttrib3fv, void(GLuint indx, const GLfloat* values));
+
+ MOCK_METHOD5(VertexAttrib4f, void(
+ GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w));
+
+ MOCK_METHOD2(VertexAttrib4fv, void(GLuint indx, const GLfloat* values));
+
+ MOCK_METHOD6(VertexAttribPointer, void(
+ GLuint indx, GLint size, GLenum type, GLboolean normalized,
+ GLsizei stride, const void* ptr));
+
+ MOCK_METHOD4(Viewport, void(GLint x, GLint y, GLsizei width, GLsizei height));
+
+ MOCK_METHOD0(SwapBuffers, void());
+
+ MOCK_METHOD4(GetMaxValueInBuffer, GLuint(
+ GLuint buffer_id, GLsizei count, GLenum type, GLuint offset));
+};
+
+} // namespace gfx
+
+#endif // APP_GFX_GL_GL_MOCK_H_
+
+
+
diff --git a/app/surface/accelerated_surface_mac.cc b/app/surface/accelerated_surface_mac.cc
index 2d6ac7a..06e48ddb 100644
--- a/app/surface/accelerated_surface_mac.cc
+++ b/app/surface/accelerated_surface_mac.cc
@@ -4,6 +4,7 @@
#include "app/surface/accelerated_surface_mac.h"
+#include "app/gfx/gl/gl_bindings.h"
#include "app/surface/io_surface_support_mac.h"
#include "base/logging.h"
#include "gfx/rect.h"
diff --git a/app/surface/accelerated_surface_mac.h b/app/surface/accelerated_surface_mac.h
index f01bbc7..d1fe311 100644
--- a/app/surface/accelerated_surface_mac.h
+++ b/app/surface/accelerated_surface_mac.h
@@ -6,7 +6,6 @@
#define APP_SURFACE_ACCELERATED_SURFACE_MAC_H_
#include <CoreFoundation/CoreFoundation.h>
-#include <OpenGL/OpenGL.h>
#include "app/surface/transport_dib.h"
#include "base/callback.h"
@@ -15,6 +14,13 @@
#include "gfx/rect.h"
#include "gfx/size.h"
+// Should not include GL headers in a header file. Forward declare these types
+// instead.
+typedef struct _CGLContextObject* CGLContextObj;
+typedef struct _CGLPBufferObject* CGLPBufferObj;
+typedef unsigned int GLenum;
+typedef unsigned int GLuint;
+
namespace gfx {
class Rect;
}