1/* 2 * Copyright (C) 2011 Google Inc. All rights reserved. 3 * Copyright (C) 2012 Research In Motion Limited. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include "config.h" 28 29#if USE(3D_GRAPHICS) 30#include "Extensions3DOpenGLCommon.h" 31 32#include "ANGLEWebKitBridge.h" 33#include "GraphicsContext3D.h" 34 35#if PLATFORM(IOS) 36#include <OpenGLES/ES2/glext.h> 37#else 38#if USE(OPENGL_ES_2) 39#include "OpenGLESShims.h" 40#include <GLES2/gl2.h> 41#include <GLES2/gl2ext.h> 42#elif PLATFORM(MAC) 43#include <OpenGL/gl.h> 44#elif PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN) 45#include "OpenGLShims.h" 46#endif 47#endif 48 49#include <wtf/MainThread.h> 50#include <wtf/Vector.h> 51 52namespace WebCore { 53 54Extensions3DOpenGLCommon::Extensions3DOpenGLCommon(GraphicsContext3D* context) 55 : m_initializedAvailableExtensions(false) 56 , m_context(context) 57 , m_isNVIDIA(false) 58 , m_isAMD(false) 59 , m_isIntel(false) 60 , m_isImagination(false) 61 , m_maySupportMultisampling(true) 62 , m_requiresBuiltInFunctionEmulation(false) 63 , m_requiresRestrictedMaximumTextureSize(false) 64{ 65 m_vendor = String(reinterpret_cast<const char*>(::glGetString(GL_VENDOR))); 66 m_renderer = String(reinterpret_cast<const char*>(::glGetString(GL_RENDERER))); 67 68 Vector<String> vendorComponents; 69 m_vendor.lower().split(' ', vendorComponents); 70 if (vendorComponents.contains("nvidia")) 71 m_isNVIDIA = true; 72 if (vendorComponents.contains("ati") || vendorComponents.contains("amd")) 73 m_isAMD = true; 74 if (vendorComponents.contains("intel")) 75 m_isIntel = true; 76 if (vendorComponents.contains("imagination")) 77 m_isImagination = true; 78 79#if PLATFORM(MAC) 80 if (m_isAMD || m_isIntel) 81 m_requiresBuiltInFunctionEmulation = true; 82 83 // Currently in Mac we only allow multisampling if the vendor is NVIDIA, 84 // or if the vendor is AMD/ATI and the system is 10.7.2 and above. 85 86 bool systemSupportsMultisampling = true; 87#if !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED < 1080 88 ASSERT(isMainThread()); 89 static SInt32 version; 90 if (!version) { 91 if (Gestalt(gestaltSystemVersion, &version) != noErr) 92 systemSupportsMultisampling = false; 93 } 94 // See https://bugs.webkit.org/show_bug.cgi?id=77922 for more details 95 if (systemSupportsMultisampling) 96 systemSupportsMultisampling = version >= 0x1072; 97#endif // SNOW_LEOPARD and LION 98 99 if (m_isAMD && !systemSupportsMultisampling) 100 m_maySupportMultisampling = false; 101 102 // Intel HD 3000 devices have problems with large textures. <rdar://problem/16649140> 103 if (m_isIntel) 104 m_requiresRestrictedMaximumTextureSize = m_renderer.startsWith("Intel HD Graphics 3000"); 105#endif 106} 107 108Extensions3DOpenGLCommon::~Extensions3DOpenGLCommon() 109{ 110} 111 112bool Extensions3DOpenGLCommon::supports(const String& name) 113{ 114 if (!m_initializedAvailableExtensions) 115 initializeAvailableExtensions(); 116 117 return supportsExtension(name); 118} 119 120void Extensions3DOpenGLCommon::ensureEnabled(const String& name) 121{ 122 if (name == "GL_OES_standard_derivatives") { 123 // Enable support in ANGLE (if not enabled already) 124 ANGLEWebKitBridge& compiler = m_context->m_compiler; 125 ShBuiltInResources ANGLEResources = compiler.getResources(); 126 if (!ANGLEResources.OES_standard_derivatives) { 127 ANGLEResources.OES_standard_derivatives = 1; 128 compiler.setResources(ANGLEResources); 129 } 130 } else if (name == "GL_EXT_draw_buffers") { 131 // Enable support in ANGLE (if not enabled already) 132 ANGLEWebKitBridge& compiler = m_context->m_compiler; 133 ShBuiltInResources ANGLEResources = compiler.getResources(); 134 if (!ANGLEResources.EXT_draw_buffers) { 135 ANGLEResources.EXT_draw_buffers = 1; 136 m_context->getIntegerv(Extensions3D::MAX_DRAW_BUFFERS_EXT, &ANGLEResources.MaxDrawBuffers); 137 compiler.setResources(ANGLEResources); 138 } 139 } else if (name == "GL_EXT_shader_texture_lod") { 140 // Enable support in ANGLE (if not enabled already) 141 ANGLEWebKitBridge& compiler = m_context->m_compiler; 142 ShBuiltInResources ANGLEResources = compiler.getResources(); 143 if (!ANGLEResources.EXT_shader_texture_lod) { 144 ANGLEResources.EXT_shader_texture_lod = 1; 145 compiler.setResources(ANGLEResources); 146 } 147 } 148} 149 150bool Extensions3DOpenGLCommon::isEnabled(const String& name) 151{ 152 if (name == "GL_OES_standard_derivatives") { 153 ANGLEWebKitBridge& compiler = m_context->m_compiler; 154 return compiler.getResources().OES_standard_derivatives; 155 } 156 return supports(name); 157} 158 159int Extensions3DOpenGLCommon::getGraphicsResetStatusARB() 160{ 161 return GraphicsContext3D::NO_ERROR; 162} 163 164String Extensions3DOpenGLCommon::getTranslatedShaderSourceANGLE(Platform3DObject shader) 165{ 166 ASSERT(shader); 167 int GLshaderType; 168 ANGLEShaderType shaderType; 169 170 ANGLEWebKitBridge& compiler = m_context->m_compiler; 171 172 m_context->getShaderiv(shader, GraphicsContext3D::SHADER_TYPE, &GLshaderType); 173 174 if (GLshaderType == GraphicsContext3D::VERTEX_SHADER) 175 shaderType = SHADER_TYPE_VERTEX; 176 else if (GLshaderType == GraphicsContext3D::FRAGMENT_SHADER) 177 shaderType = SHADER_TYPE_FRAGMENT; 178 else 179 return ""; // Invalid shader type. 180 181 HashMap<Platform3DObject, GraphicsContext3D::ShaderSourceEntry>::iterator result = m_context->m_shaderSourceMap.find(shader); 182 183 if (result == m_context->m_shaderSourceMap.end()) 184 return ""; 185 186 GraphicsContext3D::ShaderSourceEntry& entry = result->value; 187 188 String translatedShaderSource; 189 String shaderInfoLog; 190 int extraCompileOptions = SH_CLAMP_INDIRECT_ARRAY_BOUNDS | SH_UNFOLD_SHORT_CIRCUIT | SH_ENFORCE_PACKING_RESTRICTIONS | SH_INIT_VARYINGS_WITHOUT_STATIC_USE | SH_LIMIT_EXPRESSION_COMPLEXITY | SH_LIMIT_CALL_STACK_DEPTH; 191 192 if (m_requiresBuiltInFunctionEmulation) 193 extraCompileOptions |= SH_EMULATE_BUILT_IN_FUNCTIONS; 194 195 Vector<ANGLEShaderSymbol> symbols; 196 bool isValid = compiler.compileShaderSource(entry.source.utf8().data(), shaderType, translatedShaderSource, shaderInfoLog, symbols, extraCompileOptions); 197 198 entry.log = shaderInfoLog; 199 entry.isValid = isValid; 200 201 size_t numSymbols = symbols.size(); 202 for (size_t i = 0; i < numSymbols; ++i) { 203 ANGLEShaderSymbol shaderSymbol = symbols[i]; 204 GraphicsContext3D::SymbolInfo symbolInfo(shaderSymbol.dataType, shaderSymbol.size, shaderSymbol.mappedName, shaderSymbol.precision, shaderSymbol.staticUse); 205 entry.symbolMap(shaderSymbol.symbolType).set(shaderSymbol.name, symbolInfo); 206 } 207 208 if (!isValid) 209 return ""; 210 211 return translatedShaderSource; 212} 213 214void Extensions3DOpenGLCommon::initializeAvailableExtensions() 215{ 216 String extensionsString = getExtensions(); 217 Vector<String> availableExtensions; 218 extensionsString.split(" ", availableExtensions); 219 for (size_t i = 0; i < availableExtensions.size(); ++i) 220 m_availableExtensions.add(availableExtensions[i]); 221 m_initializedAvailableExtensions = true; 222} 223 224void Extensions3DOpenGLCommon::readnPixelsEXT(int, int, GC3Dsizei, GC3Dsizei, GC3Denum, GC3Denum, GC3Dsizei, void *) 225{ 226 m_context->synthesizeGLError(GL_INVALID_OPERATION); 227} 228 229void Extensions3DOpenGLCommon::getnUniformfvEXT(GC3Duint, int, GC3Dsizei, float *) 230{ 231 m_context->synthesizeGLError(GL_INVALID_OPERATION); 232} 233 234void Extensions3DOpenGLCommon::getnUniformivEXT(GC3Duint, int, GC3Dsizei, int *) 235{ 236 m_context->synthesizeGLError(GL_INVALID_OPERATION); 237} 238 239} // namespace WebCore 240 241#endif // USE(3D_GRAPHICS) 242