Extensions3DOpenGLCommon.cpp [plain text]
#include "config.h"
#if ENABLE(GRAPHICS_CONTEXT_3D)
#include "Extensions3DOpenGLCommon.h"
#include "ANGLEWebKitBridge.h"
#include "GraphicsContext3D.h"
#if PLATFORM(IOS)
#include <OpenGLES/ES2/glext.h>
#else
#if USE(OPENGL_ES_2)
#include "OpenGLESShims.h"
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#elif PLATFORM(MAC)
#include <OpenGL/gl.h>
#elif PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN)
#include "OpenGLShims.h"
#endif
#endif
#include <wtf/MainThread.h>
#include <wtf/Vector.h>
namespace WebCore {
Extensions3DOpenGLCommon::Extensions3DOpenGLCommon(GraphicsContext3D* context)
: m_initializedAvailableExtensions(false)
, m_context(context)
, m_isNVIDIA(false)
, m_isAMD(false)
, m_isIntel(false)
, m_isImagination(false)
, m_maySupportMultisampling(true)
, m_requiresBuiltInFunctionEmulation(false)
, m_requiresRestrictedMaximumTextureSize(false)
{
m_vendor = String(reinterpret_cast<const char*>(::glGetString(GL_VENDOR)));
m_renderer = String(reinterpret_cast<const char*>(::glGetString(GL_RENDERER)));
Vector<String> vendorComponents;
m_vendor.lower().split(' ', vendorComponents);
if (vendorComponents.contains("nvidia"))
m_isNVIDIA = true;
if (vendorComponents.contains("ati") || vendorComponents.contains("amd"))
m_isAMD = true;
if (vendorComponents.contains("intel"))
m_isIntel = true;
if (vendorComponents.contains("imagination"))
m_isImagination = true;
#if PLATFORM(MAC)
if (m_isAMD || m_isIntel)
m_requiresBuiltInFunctionEmulation = true;
bool systemSupportsMultisampling = true;
if (m_isAMD && !systemSupportsMultisampling)
m_maySupportMultisampling = false;
if (m_isIntel)
m_requiresRestrictedMaximumTextureSize = m_renderer.startsWith("Intel HD Graphics 3000");
#endif
}
Extensions3DOpenGLCommon::~Extensions3DOpenGLCommon()
{
}
bool Extensions3DOpenGLCommon::supports(const String& name)
{
if (!m_initializedAvailableExtensions)
initializeAvailableExtensions();
return supportsExtension(name);
}
void Extensions3DOpenGLCommon::ensureEnabled(const String& name)
{
if (name == "GL_OES_standard_derivatives") {
ANGLEWebKitBridge& compiler = m_context->m_compiler;
ShBuiltInResources ANGLEResources = compiler.getResources();
if (!ANGLEResources.OES_standard_derivatives) {
ANGLEResources.OES_standard_derivatives = 1;
compiler.setResources(ANGLEResources);
}
} else if (name == "GL_EXT_draw_buffers") {
ANGLEWebKitBridge& compiler = m_context->m_compiler;
ShBuiltInResources ANGLEResources = compiler.getResources();
if (!ANGLEResources.EXT_draw_buffers) {
ANGLEResources.EXT_draw_buffers = 1;
m_context->getIntegerv(Extensions3D::MAX_DRAW_BUFFERS_EXT, &ANGLEResources.MaxDrawBuffers);
compiler.setResources(ANGLEResources);
}
} else if (name == "GL_EXT_shader_texture_lod") {
ANGLEWebKitBridge& compiler = m_context->m_compiler;
ShBuiltInResources ANGLEResources = compiler.getResources();
if (!ANGLEResources.EXT_shader_texture_lod) {
ANGLEResources.EXT_shader_texture_lod = 1;
compiler.setResources(ANGLEResources);
}
} else if (name == "GL_EXT_frag_depth") {
ANGLEWebKitBridge& compiler = m_context->m_compiler;
ShBuiltInResources ANGLEResources = compiler.getResources();
if (!ANGLEResources.EXT_frag_depth) {
ANGLEResources.EXT_frag_depth = 1;
compiler.setResources(ANGLEResources);
}
}
}
bool Extensions3DOpenGLCommon::isEnabled(const String& name)
{
if (name == "GL_OES_standard_derivatives") {
ANGLEWebKitBridge& compiler = m_context->m_compiler;
return compiler.getResources().OES_standard_derivatives;
}
return supports(name);
}
int Extensions3DOpenGLCommon::getGraphicsResetStatusARB()
{
return GraphicsContext3D::NO_ERROR;
}
String Extensions3DOpenGLCommon::getTranslatedShaderSourceANGLE(Platform3DObject shader)
{
ASSERT(shader);
int GLshaderType;
ANGLEShaderType shaderType;
ANGLEWebKitBridge& compiler = m_context->m_compiler;
m_context->getShaderiv(shader, GraphicsContext3D::SHADER_TYPE, &GLshaderType);
if (GLshaderType == GraphicsContext3D::VERTEX_SHADER)
shaderType = SHADER_TYPE_VERTEX;
else if (GLshaderType == GraphicsContext3D::FRAGMENT_SHADER)
shaderType = SHADER_TYPE_FRAGMENT;
else
return "";
HashMap<Platform3DObject, GraphicsContext3D::ShaderSourceEntry>::iterator result = m_context->m_shaderSourceMap.find(shader);
if (result == m_context->m_shaderSourceMap.end())
return "";
GraphicsContext3D::ShaderSourceEntry& entry = result->value;
String translatedShaderSource;
String shaderInfoLog;
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;
if (m_requiresBuiltInFunctionEmulation)
extraCompileOptions |= SH_EMULATE_BUILT_IN_FUNCTIONS;
Vector<ANGLEShaderSymbol> symbols;
bool isValid = compiler.compileShaderSource(entry.source.utf8().data(), shaderType, translatedShaderSource, shaderInfoLog, symbols, extraCompileOptions);
entry.log = shaderInfoLog;
entry.isValid = isValid;
size_t numSymbols = symbols.size();
for (size_t i = 0; i < numSymbols; ++i) {
ANGLEShaderSymbol shaderSymbol = symbols[i];
GraphicsContext3D::SymbolInfo symbolInfo(shaderSymbol.dataType, shaderSymbol.size, shaderSymbol.mappedName, shaderSymbol.precision, shaderSymbol.staticUse);
entry.symbolMap(shaderSymbol.symbolType).set(shaderSymbol.name, symbolInfo);
}
if (!isValid)
return "";
return translatedShaderSource;
}
void Extensions3DOpenGLCommon::initializeAvailableExtensions()
{
String extensionsString = getExtensions();
Vector<String> availableExtensions;
extensionsString.split(' ', availableExtensions);
for (size_t i = 0; i < availableExtensions.size(); ++i)
m_availableExtensions.add(availableExtensions[i]);
m_initializedAvailableExtensions = true;
}
void Extensions3DOpenGLCommon::readnPixelsEXT(int, int, GC3Dsizei, GC3Dsizei, GC3Denum, GC3Denum, GC3Dsizei, void *)
{
m_context->synthesizeGLError(GL_INVALID_OPERATION);
}
void Extensions3DOpenGLCommon::getnUniformfvEXT(GC3Duint, int, GC3Dsizei, float *)
{
m_context->synthesizeGLError(GL_INVALID_OPERATION);
}
void Extensions3DOpenGLCommon::getnUniformivEXT(GC3Duint, int, GC3Dsizei, int *)
{
m_context->synthesizeGLError(GL_INVALID_OPERATION);
}
}
#endif // ENABLE(GRAPHICS_CONTEXT_3D)