1 /*
2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include "config.h"
27
28 #if ENABLE(WEBGL)
29
30 #include "Extensions3DOpenGL.h"
31
32 #include "GraphicsContext3D.h"
33 #include <wtf/Vector.h>
34
35 #if PLATFORM(MAC)
36 #include "ANGLE/ShaderLang.h"
37 #include <OpenGL/gl.h>
38 #elif PLATFORM(GTK)
39 #include "OpenGLShims.h"
40 #endif
41
42 namespace WebCore {
43
Extensions3DOpenGL(GraphicsContext3D * context)44 Extensions3DOpenGL::Extensions3DOpenGL(GraphicsContext3D* context)
45 : m_initializedAvailableExtensions(false)
46 , m_context(context)
47 {
48 }
49
~Extensions3DOpenGL()50 Extensions3DOpenGL::~Extensions3DOpenGL()
51 {
52 }
53
supports(const String & name)54 bool Extensions3DOpenGL::supports(const String& name)
55 {
56 // Note on support for BGRA:
57 //
58 // For OpenGL ES2.0, requires checking for
59 // GL_EXT_texture_format_BGRA8888 and GL_EXT_read_format_bgra.
60 // For desktop GL, BGRA has been supported since OpenGL 1.2.
61 //
62 // However, note that the GL ES2 extension requires the
63 // internalFormat to glTexImage2D() be GL_BGRA, while desktop GL
64 // will not accept GL_BGRA (must be GL_RGBA), so this must be
65 // checked on each platform. Desktop GL offers neither
66 // GL_EXT_texture_format_BGRA8888 or GL_EXT_read_format_bgra, so
67 // treat them as unsupported here.
68 if (!m_initializedAvailableExtensions) {
69 String extensionsString(reinterpret_cast<const char*>(::glGetString(GL_EXTENSIONS)));
70 Vector<String> availableExtensions;
71 extensionsString.split(" ", availableExtensions);
72 for (size_t i = 0; i < availableExtensions.size(); ++i)
73 m_availableExtensions.add(availableExtensions[i]);
74 m_initializedAvailableExtensions = true;
75 }
76
77 // GL_ANGLE_framebuffer_blit and GL_ANGLE_framebuffer_multisample are "fake". They are implemented using other
78 // extensions. In particular GL_EXT_framebuffer_blit and GL_EXT_framebuffer_multisample
79 if (name == "GL_ANGLE_framebuffer_blit")
80 return m_availableExtensions.contains("GL_EXT_framebuffer_blit");
81 if (name == "GL_ANGLE_framebuffer_multisample")
82 return m_availableExtensions.contains("GL_EXT_framebuffer_multisample");
83
84 // Desktop GL always supports GL_OES_rgb8_rgba8.
85 if (name == "GL_OES_rgb8_rgba8")
86 return true;
87
88 // If GL_ARB_texture_float is available then we report GL_OES_texture_float and
89 // GL_OES_texture_half_float as available.
90 if (name == "GL_OES_texture_float" || name == "GL_OES_texture_half_float")
91 return m_availableExtensions.contains("GL_ARB_texture_float");
92
93 // GL_OES_vertex_array_object
94 if (name == "GL_OES_vertex_array_object")
95 return m_availableExtensions.contains("GL_APPLE_vertex_array_object");
96
97 // Desktop GL always supports the standard derivative functions
98 if (name == "GL_OES_standard_derivatives")
99 return true;
100
101 return m_availableExtensions.contains(name);
102 }
103
ensureEnabled(const String & name)104 void Extensions3DOpenGL::ensureEnabled(const String& name)
105 {
106 #if PLATFORM(MAC)
107 if (name == "GL_OES_standard_derivatives") {
108 // Enable support in ANGLE (if not enabled already)
109 ANGLEWebKitBridge& compiler = m_context->m_compiler;
110 ShBuiltInResources ANGLEResources = compiler.getResources();
111 if (!ANGLEResources.OES_standard_derivatives) {
112 ANGLEResources.OES_standard_derivatives = 1;
113 compiler.setResources(ANGLEResources);
114 }
115 }
116 #else
117 ASSERT_UNUSED(name, supports(name));
118 #endif
119 }
120
isEnabled(const String & name)121 bool Extensions3DOpenGL::isEnabled(const String& name)
122 {
123 #if PLATFORM(MAC)
124 if (name == "GL_OES_standard_derivatives") {
125 ANGLEWebKitBridge& compiler = m_context->m_compiler;
126 return compiler.getResources().OES_standard_derivatives;
127 }
128 #endif
129 return supports(name);
130 }
131
getGraphicsResetStatusARB()132 int Extensions3DOpenGL::getGraphicsResetStatusARB()
133 {
134 return GraphicsContext3D::NO_ERROR;
135 }
136
blitFramebuffer(long srcX0,long srcY0,long srcX1,long srcY1,long dstX0,long dstY0,long dstX1,long dstY1,unsigned long mask,unsigned long filter)137 void Extensions3DOpenGL::blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1, long dstX0, long dstY0, long dstX1, long dstY1, unsigned long mask, unsigned long filter)
138 {
139 ::glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
140 }
141
renderbufferStorageMultisample(unsigned long target,unsigned long samples,unsigned long internalformat,unsigned long width,unsigned long height)142 void Extensions3DOpenGL::renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height)
143 {
144 ::glRenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height);
145 }
146
createVertexArrayOES()147 Platform3DObject Extensions3DOpenGL::createVertexArrayOES()
148 {
149 m_context->makeContextCurrent();
150 #if !PLATFORM(GTK) && defined(GL_APPLE_vertex_array_object) && GL_APPLE_vertex_array_object
151 GLuint array = 0;
152 glGenVertexArraysAPPLE(1, &array);
153 return array;
154 #else
155 return 0;
156 #endif
157 }
158
deleteVertexArrayOES(Platform3DObject array)159 void Extensions3DOpenGL::deleteVertexArrayOES(Platform3DObject array)
160 {
161 if (!array)
162 return;
163
164 m_context->makeContextCurrent();
165 #if !PLATFORM(GTK) && defined(GL_APPLE_vertex_array_object) && GL_APPLE_vertex_array_object
166 glDeleteVertexArraysAPPLE(1, &array);
167 #endif
168 }
169
isVertexArrayOES(Platform3DObject array)170 GC3Dboolean Extensions3DOpenGL::isVertexArrayOES(Platform3DObject array)
171 {
172 if (!array)
173 return GL_FALSE;
174
175 m_context->makeContextCurrent();
176 #if !PLATFORM(GTK) && defined(GL_APPLE_vertex_array_object) && GL_APPLE_vertex_array_object
177 return glIsVertexArrayAPPLE(array);
178 #else
179 return GL_FALSE;
180 #endif
181 }
182
bindVertexArrayOES(Platform3DObject array)183 void Extensions3DOpenGL::bindVertexArrayOES(Platform3DObject array)
184 {
185 if (!array)
186 return;
187
188 m_context->makeContextCurrent();
189 #if !PLATFORM(GTK) && defined(GL_APPLE_vertex_array_object) && GL_APPLE_vertex_array_object
190 glBindVertexArrayAPPLE(array);
191 #endif
192 }
193
194 } // namespace WebCore
195
196 #endif // ENABLE(WEBGL)
197