1/* 2 * Copyright (C) 2011 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 USE(3D_GRAPHICS) 29 30#include "Extensions3DOpenGL.h" 31 32#include "GraphicsContext3D.h" 33#include <wtf/Vector.h> 34 35#if PLATFORM(IOS) 36#include "ANGLE/ShaderLang.h" 37#include <OpenGLES/ES2/glext.h> 38#elif PLATFORM(MAC) 39#include "ANGLE/ShaderLang.h" 40#include <OpenGL/gl.h> 41#elif PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN) 42#include "OpenGLShims.h" 43#endif 44 45#if PLATFORM(IOS) 46#include "GraphicsContext3DIOS.h" 47#endif 48 49namespace WebCore { 50 51Extensions3DOpenGL::Extensions3DOpenGL(GraphicsContext3D* context) 52 : Extensions3DOpenGLCommon(context) 53{ 54} 55 56Extensions3DOpenGL::~Extensions3DOpenGL() 57{ 58} 59 60 61void Extensions3DOpenGL::blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1, long dstX0, long dstY0, long dstX1, long dstY1, unsigned long mask, unsigned long filter) 62{ 63#if PLATFORM(IOS) 64 UNUSED_PARAM(srcX0); 65 UNUSED_PARAM(srcY0); 66 UNUSED_PARAM(srcX1); 67 UNUSED_PARAM(srcY1); 68 UNUSED_PARAM(dstX0); 69 UNUSED_PARAM(dstY0); 70 UNUSED_PARAM(dstX1); 71 UNUSED_PARAM(dstY1); 72 UNUSED_PARAM(mask); 73 UNUSED_PARAM(filter); 74 ::glResolveMultisampleFramebufferAPPLE(); 75#else 76 ::glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); 77#endif 78} 79 80void Extensions3DOpenGL::renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height) 81{ 82 ::glRenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height); 83} 84 85Platform3DObject Extensions3DOpenGL::createVertexArrayOES() 86{ 87 m_context->makeContextCurrent(); 88 GLuint array = 0; 89#if (PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN) || PLATFORM(IOS)) 90 if (isVertexArrayObjectSupported()) 91 glGenVertexArrays(1, &array); 92#elif defined(GL_APPLE_vertex_array_object) && GL_APPLE_vertex_array_object 93 glGenVertexArraysAPPLE(1, &array); 94#endif 95 return array; 96} 97 98void Extensions3DOpenGL::deleteVertexArrayOES(Platform3DObject array) 99{ 100 if (!array) 101 return; 102 103 m_context->makeContextCurrent(); 104#if (PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN) || PLATFORM(IOS)) 105 if (isVertexArrayObjectSupported()) 106 glDeleteVertexArrays(1, &array); 107#elif defined(GL_APPLE_vertex_array_object) && GL_APPLE_vertex_array_object 108 glDeleteVertexArraysAPPLE(1, &array); 109#endif 110} 111 112GC3Dboolean Extensions3DOpenGL::isVertexArrayOES(Platform3DObject array) 113{ 114 if (!array) 115 return GL_FALSE; 116 117 m_context->makeContextCurrent(); 118#if (PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN) || PLATFORM(IOS)) 119 if (isVertexArrayObjectSupported()) 120 return glIsVertexArray(array); 121#elif defined(GL_APPLE_vertex_array_object) && GL_APPLE_vertex_array_object 122 return glIsVertexArrayAPPLE(array); 123#endif 124 return GL_FALSE; 125} 126 127void Extensions3DOpenGL::bindVertexArrayOES(Platform3DObject array) 128{ 129 m_context->makeContextCurrent(); 130#if (PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN) || PLATFORM(IOS)) 131 if (isVertexArrayObjectSupported()) 132 glBindVertexArray(array); 133#elif defined(GL_APPLE_vertex_array_object) && GL_APPLE_vertex_array_object 134 glBindVertexArrayAPPLE(array); 135#else 136 UNUSED_PARAM(array); 137#endif 138} 139 140void Extensions3DOpenGL::insertEventMarkerEXT(const String&) 141{ 142 // FIXME: implement this function and add GL_EXT_debug_marker in supports(). 143 return; 144} 145 146void Extensions3DOpenGL::pushGroupMarkerEXT(const String&) 147{ 148 // FIXME: implement this function and add GL_EXT_debug_marker in supports(). 149 return; 150} 151 152void Extensions3DOpenGL::popGroupMarkerEXT(void) 153{ 154 // FIXME: implement this function and add GL_EXT_debug_marker in supports(). 155 return; 156} 157 158bool Extensions3DOpenGL::supportsExtension(const String& name) 159{ 160 // GL_ANGLE_framebuffer_blit and GL_ANGLE_framebuffer_multisample are "fake". They are implemented using other 161 // extensions. In particular GL_EXT_framebuffer_blit and GL_EXT_framebuffer_multisample 162 if (name == "GL_ANGLE_framebuffer_blit") 163 return m_availableExtensions.contains("GL_EXT_framebuffer_blit"); 164 if (name == "GL_ANGLE_framebuffer_multisample") 165 return m_availableExtensions.contains("GL_EXT_framebuffer_multisample"); 166 167 if (name == "GL_ANGLE_instanced_arrays") { 168 return (m_availableExtensions.contains("GL_ARB_instanced_arrays") || m_availableExtensions.contains("GL_EXT_instanced_arrays")) 169 && (m_availableExtensions.contains("GL_ARB_draw_instanced") || m_availableExtensions.contains("GL_EXT_draw_instanced")); 170 } 171 172 // Desktop GL always supports GL_OES_rgb8_rgba8. 173 if (name == "GL_OES_rgb8_rgba8") 174 return true; 175 176 // If GL_ARB_texture_float or GL_OES_texture_float is available then we report 177 // GL_OES_texture_half_float, GL_OES_texture_float_linear and GL_OES_texture_half_float_linear as available. 178 if (name == "GL_OES_texture_float" || name == "GL_OES_texture_half_float" || name == "GL_OES_texture_float_linear" || name == "GL_OES_texture_half_float_linear") 179 return m_availableExtensions.contains("GL_ARB_texture_float") || m_availableExtensions.contains("GL_OES_texture_float"); 180 181 // GL_OES_vertex_array_object 182 if (name == "GL_OES_vertex_array_object") { 183#if (PLATFORM(GTK) || PLATFORM(EFL)) 184 return m_availableExtensions.contains("GL_ARB_vertex_array_object"); 185#elif PLATFORM(IOS) 186 return m_availableExtensions.contains("GL_OES_vertex_array_object"); 187#else 188 return m_availableExtensions.contains("GL_APPLE_vertex_array_object"); 189#endif 190 } 191 192 // Desktop GL always supports the standard derivative functions 193 if (name == "GL_OES_standard_derivatives") 194 return true; 195 196 // Desktop GL always supports UNSIGNED_INT indices 197 if (name == "GL_OES_element_index_uint") 198 return true; 199 200 if (name == "GL_EXT_shader_texture_lod") 201 return m_availableExtensions.contains("GL_EXT_shader_texture_lod"); 202 203 if (name == "GL_EXT_texture_filter_anisotropic") 204 return m_availableExtensions.contains("GL_EXT_texture_filter_anisotropic"); 205 206 if (name == "GL_EXT_draw_buffers") { 207#if PLATFORM(MAC) || PLATFORM(GTK) 208 return m_availableExtensions.contains("GL_ARB_draw_buffers"); 209#else 210 // FIXME: implement support for other platforms. 211 return false; 212#endif 213 } 214 215#if PLATFORM(IOS) 216 if (name == "GL_EXT_packed_depth_stencil") 217 return m_availableExtensions.contains("GL_OES_packed_depth_stencil"); 218#endif 219 220 return m_availableExtensions.contains(name); 221} 222 223void Extensions3DOpenGL::drawBuffersEXT(GC3Dsizei n, const GC3Denum* bufs) 224{ 225 // FIXME: implement support for other platforms. 226#if PLATFORM(MAC) 227 ::glDrawBuffersARB(n, bufs); 228#elif PLATFORM(GTK) 229 ::glDrawBuffers(n, bufs); 230#else 231 UNUSED_PARAM(n); 232 UNUSED_PARAM(bufs); 233#endif 234} 235 236void Extensions3DOpenGL::drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount) 237{ 238 m_context->makeContextCurrent(); 239#if PLATFORM(GTK) 240 ::glDrawArraysInstanced(mode, first, count, primcount); 241#elif PLATFORM(IOS) || PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 242 ::glDrawArraysInstancedARB(mode, first, count, primcount); 243#else 244 UNUSED_PARAM(mode); 245 UNUSED_PARAM(first); 246 UNUSED_PARAM(count); 247 UNUSED_PARAM(primcount); 248#endif 249} 250 251void Extensions3DOpenGL::drawElementsInstanced(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, GC3Dsizei primcount) 252{ 253 m_context->makeContextCurrent(); 254#if PLATFORM(GTK) 255 ::glDrawElementsInstanced(mode, count, type, reinterpret_cast<GLvoid*>(static_cast<intptr_t>(offset)), primcount); 256#elif PLATFORM(IOS) || PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 257 ::glDrawElementsInstancedARB(mode, count, type, reinterpret_cast<GLvoid*>(static_cast<intptr_t>(offset)), primcount); 258#else 259 UNUSED_PARAM(mode); 260 UNUSED_PARAM(count); 261 UNUSED_PARAM(type); 262 UNUSED_PARAM(offset); 263 UNUSED_PARAM(primcount); 264#endif 265} 266 267void Extensions3DOpenGL::vertexAttribDivisor(GC3Duint index, GC3Duint divisor) 268{ 269 m_context->makeContextCurrent(); 270#if PLATFORM(GTK) 271 ::glVertexAttribDivisor(index, divisor); 272#elif PLATFORM(IOS) || PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 273 ::glVertexAttribDivisorARB(index, divisor); 274#else 275 UNUSED_PARAM(index); 276 UNUSED_PARAM(divisor); 277#endif 278} 279 280String Extensions3DOpenGL::getExtensions() 281{ 282 return String(reinterpret_cast<const char*>(::glGetString(GL_EXTENSIONS))); 283} 284 285#if (PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN) || PLATFORM(IOS)) 286bool Extensions3DOpenGL::isVertexArrayObjectSupported() 287{ 288 static const bool supportsVertexArrayObject = supports("GL_OES_vertex_array_object"); 289 return supportsVertexArrayObject; 290} 291#endif 292 293} // namespace WebCore 294 295#endif // USE(3D_GRAPHICS) 296