summaryrefslogtreecommitdiff
path: root/Source/WebCore/platform/graphics/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/graphics/opengl')
-rw-r--r--Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp124
-rw-r--r--Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h41
-rw-r--r--Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp112
-rw-r--r--Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.h52
-rw-r--r--Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLES.cpp74
-rw-r--r--Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLES.h30
-rw-r--r--Source/WebCore/platform/graphics/opengl/GLDefs.h74
-rw-r--r--Source/WebCore/platform/graphics/opengl/GLPlatformContext.cpp273
-rw-r--r--Source/WebCore/platform/graphics/opengl/GLPlatformContext.h94
-rw-r--r--Source/WebCore/platform/graphics/opengl/GLPlatformSurface.h93
-rw-r--r--Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp172
-rw-r--r--Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp446
-rw-r--r--Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp275
-rw-r--r--Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.cpp4
-rw-r--r--Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.h2
15 files changed, 1534 insertions, 332 deletions
diff --git a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp
index f8321cac0..5da632035 100644
--- a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp
+++ b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp
@@ -25,20 +25,17 @@
#include "config.h"
-#if USE(3D_GRAPHICS)
+#if ENABLE(GRAPHICS_CONTEXT_3D)
#include "Extensions3DOpenGL.h"
#include "GraphicsContext3D.h"
-#include <wtf/Vector.h>
#if PLATFORM(IOS)
-#include "ANGLE/ShaderLang.h"
#include <OpenGLES/ES2/glext.h>
#elif PLATFORM(MAC)
-#include "ANGLE/ShaderLang.h"
#include <OpenGL/gl.h>
-#elif PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN)
+#elif PLATFORM(GTK) || PLATFORM(WIN)
#include "OpenGLShims.h"
#endif
@@ -48,8 +45,8 @@
namespace WebCore {
-Extensions3DOpenGL::Extensions3DOpenGL(GraphicsContext3D* context)
- : Extensions3DOpenGLCommon(context)
+Extensions3DOpenGL::Extensions3DOpenGL(GraphicsContext3D* context, bool useIndexedGetString)
+ : Extensions3DOpenGLCommon(context, useIndexedGetString)
{
}
@@ -86,7 +83,7 @@ Platform3DObject Extensions3DOpenGL::createVertexArrayOES()
{
m_context->makeContextCurrent();
GLuint array = 0;
-#if (PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN))
+#if (PLATFORM(GTK) || PLATFORM(WIN) || PLATFORM(IOS))
if (isVertexArrayObjectSupported())
glGenVertexArrays(1, &array);
#elif defined(GL_APPLE_vertex_array_object) && GL_APPLE_vertex_array_object
@@ -101,7 +98,7 @@ void Extensions3DOpenGL::deleteVertexArrayOES(Platform3DObject array)
return;
m_context->makeContextCurrent();
-#if (PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN))
+#if (PLATFORM(GTK) || PLATFORM(WIN) || PLATFORM(IOS))
if (isVertexArrayObjectSupported())
glDeleteVertexArrays(1, &array);
#elif defined(GL_APPLE_vertex_array_object) && GL_APPLE_vertex_array_object
@@ -115,7 +112,7 @@ GC3Dboolean Extensions3DOpenGL::isVertexArrayOES(Platform3DObject array)
return GL_FALSE;
m_context->makeContextCurrent();
-#if (PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN))
+#if (PLATFORM(GTK) || PLATFORM(WIN) || PLATFORM(IOS))
if (isVertexArrayObjectSupported())
return glIsVertexArray(array);
#elif defined(GL_APPLE_vertex_array_object) && GL_APPLE_vertex_array_object
@@ -126,12 +123,8 @@ GC3Dboolean Extensions3DOpenGL::isVertexArrayOES(Platform3DObject array)
void Extensions3DOpenGL::bindVertexArrayOES(Platform3DObject array)
{
-#if PLATFORM(IOS)
- UNUSED_PARAM(array);
-#endif
-
m_context->makeContextCurrent();
-#if (PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN))
+#if (PLATFORM(GTK) || PLATFORM(WIN) || PLATFORM(IOS))
if (isVertexArrayObjectSupported())
glBindVertexArray(array);
#elif defined(GL_APPLE_vertex_array_object) && GL_APPLE_vertex_array_object
@@ -141,12 +134,6 @@ void Extensions3DOpenGL::bindVertexArrayOES(Platform3DObject array)
#endif
}
-void Extensions3DOpenGL::copyTextureCHROMIUM(GC3Denum, Platform3DObject, Platform3DObject, GC3Dint, GC3Denum)
-{
- // FIXME: implement this function and add GL_CHROMIUM_copy_texture in supports().
- return;
-}
-
void Extensions3DOpenGL::insertEventMarkerEXT(const String&)
{
// FIXME: implement this function and add GL_EXT_debug_marker in supports().
@@ -168,25 +155,50 @@ void Extensions3DOpenGL::popGroupMarkerEXT(void)
bool Extensions3DOpenGL::supportsExtension(const String& name)
{
// GL_ANGLE_framebuffer_blit and GL_ANGLE_framebuffer_multisample are "fake". They are implemented using other
- // extensions. In particular GL_EXT_framebuffer_blit and GL_EXT_framebuffer_multisample
+ // extensions. In particular GL_EXT_framebuffer_blit and GL_EXT_framebuffer_multisample/GL_APPLE_framebuffer_multisample.
if (name == "GL_ANGLE_framebuffer_blit")
return m_availableExtensions.contains("GL_EXT_framebuffer_blit");
if (name == "GL_ANGLE_framebuffer_multisample")
+#if PLATFORM(IOS)
+ return m_availableExtensions.contains("GL_APPLE_framebuffer_multisample");
+#else
return m_availableExtensions.contains("GL_EXT_framebuffer_multisample");
+#endif
+
+ if (name == "GL_ANGLE_instanced_arrays") {
+ return (m_availableExtensions.contains("GL_ARB_instanced_arrays") || m_availableExtensions.contains("GL_EXT_instanced_arrays"))
+ && (m_availableExtensions.contains("GL_ARB_draw_instanced") || m_availableExtensions.contains("GL_EXT_draw_instanced"));
+ }
+
+ if (name == "GL_EXT_sRGB")
+#if PLATFORM(IOS)
+ return m_availableExtensions.contains("GL_EXT_sRGB");
+#else
+ return m_availableExtensions.contains("GL_EXT_texture_sRGB") && (m_availableExtensions.contains("GL_EXT_framebuffer_sRGB") || m_availableExtensions.contains("GL_ARB_framebuffer_sRGB"));
+#endif
+
+ if (name == "GL_EXT_frag_depth")
+#if PLATFORM(MAC)
+ return true;
+#else
+ return m_availableExtensions.contains("GL_EXT_frag_depth");
+#endif
// Desktop GL always supports GL_OES_rgb8_rgba8.
if (name == "GL_OES_rgb8_rgba8")
return true;
- // If GL_ARB_texture_float is available then we report GL_OES_texture_float,
+ // If GL_ARB_texture_float or GL_OES_texture_float is available then we report
// GL_OES_texture_half_float, GL_OES_texture_float_linear and GL_OES_texture_half_float_linear as available.
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")
- return m_availableExtensions.contains("GL_ARB_texture_float");
+ return m_availableExtensions.contains("GL_ARB_texture_float") || m_availableExtensions.contains("GL_OES_texture_float");
// GL_OES_vertex_array_object
if (name == "GL_OES_vertex_array_object") {
-#if (PLATFORM(GTK) || PLATFORM(EFL))
+#if (PLATFORM(GTK))
return m_availableExtensions.contains("GL_ARB_vertex_array_object");
+#elif PLATFORM(IOS)
+ return m_availableExtensions.contains("GL_OES_vertex_array_object");
#else
return m_availableExtensions.contains("GL_APPLE_vertex_array_object");
#endif
@@ -199,12 +211,17 @@ bool Extensions3DOpenGL::supportsExtension(const String& name)
// Desktop GL always supports UNSIGNED_INT indices
if (name == "GL_OES_element_index_uint")
return true;
-
+
+ if (name == "GL_EXT_shader_texture_lod")
+ return m_availableExtensions.contains("GL_EXT_shader_texture_lod");
+
if (name == "GL_EXT_texture_filter_anisotropic")
return m_availableExtensions.contains("GL_EXT_texture_filter_anisotropic");
if (name == "GL_EXT_draw_buffers") {
-#if PLATFORM(MAC)
+#if PLATFORM(IOS)
+ return m_availableExtensions.contains(name);
+#elif PLATFORM(MAC) || PLATFORM(GTK)
return m_availableExtensions.contains("GL_ARB_draw_buffers");
#else
// FIXME: implement support for other platforms.
@@ -223,20 +240,67 @@ bool Extensions3DOpenGL::supportsExtension(const String& name)
void Extensions3DOpenGL::drawBuffersEXT(GC3Dsizei n, const GC3Denum* bufs)
{
// FIXME: implement support for other platforms.
-#if PLATFORM(MAC) && !PLATFORM(IOS)
+#if PLATFORM(MAC)
::glDrawBuffersARB(n, bufs);
+#elif PLATFORM(GTK)
+ ::glDrawBuffers(n, bufs);
#else
UNUSED_PARAM(n);
UNUSED_PARAM(bufs);
#endif
}
+void Extensions3DOpenGL::drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount)
+{
+ m_context->makeContextCurrent();
+#if PLATFORM(GTK)
+ ::glDrawArraysInstanced(mode, first, count, primcount);
+#elif PLATFORM(COCOA)
+ ::glDrawArraysInstancedARB(mode, first, count, primcount);
+#else
+ UNUSED_PARAM(mode);
+ UNUSED_PARAM(first);
+ UNUSED_PARAM(count);
+ UNUSED_PARAM(primcount);
+#endif
+}
+
+void Extensions3DOpenGL::drawElementsInstanced(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, GC3Dsizei primcount)
+{
+ m_context->makeContextCurrent();
+#if PLATFORM(GTK)
+ ::glDrawElementsInstanced(mode, count, type, reinterpret_cast<GLvoid*>(static_cast<intptr_t>(offset)), primcount);
+#elif PLATFORM(COCOA)
+ ::glDrawElementsInstancedARB(mode, count, type, reinterpret_cast<GLvoid*>(static_cast<intptr_t>(offset)), primcount);
+#else
+ UNUSED_PARAM(mode);
+ UNUSED_PARAM(count);
+ UNUSED_PARAM(type);
+ UNUSED_PARAM(offset);
+ UNUSED_PARAM(primcount);
+#endif
+}
+
+void Extensions3DOpenGL::vertexAttribDivisor(GC3Duint index, GC3Duint divisor)
+{
+ m_context->makeContextCurrent();
+#if PLATFORM(GTK)
+ ::glVertexAttribDivisor(index, divisor);
+#elif PLATFORM(COCOA)
+ ::glVertexAttribDivisorARB(index, divisor);
+#else
+ UNUSED_PARAM(index);
+ UNUSED_PARAM(divisor);
+#endif
+}
+
String Extensions3DOpenGL::getExtensions()
{
+ ASSERT(!m_useIndexedGetString);
return String(reinterpret_cast<const char*>(::glGetString(GL_EXTENSIONS)));
}
-#if (PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN))
+#if (PLATFORM(GTK) || PLATFORM(WIN) || PLATFORM(IOS))
bool Extensions3DOpenGL::isVertexArrayObjectSupported()
{
static const bool supportsVertexArrayObject = supports("GL_OES_vertex_array_object");
@@ -246,4 +310,4 @@ bool Extensions3DOpenGL::isVertexArrayObjectSupported()
} // namespace WebCore
-#endif // USE(3D_GRAPHICS)
+#endif // ENABLE(GRAPHICS_CONTEXT_3D)
diff --git a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h
index 81c5e49d5..c3fe83eb5 100644
--- a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h
+++ b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h
@@ -23,8 +23,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef Extensions3DOpenGL_h
-#define Extensions3DOpenGL_h
+#pragma once
#include "Extensions3DOpenGLCommon.h"
@@ -37,35 +36,35 @@ namespace WebCore {
class Extensions3DOpenGL : public Extensions3DOpenGLCommon {
WTF_MAKE_FAST_ALLOCATED;
public:
+ // This class only needs to be instantiated by GraphicsContext3D implementations.
+ Extensions3DOpenGL(GraphicsContext3D*, bool useIndexedGetString);
virtual ~Extensions3DOpenGL();
// Extensions3D methods.
- virtual void blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1, long dstX0, long dstY0, long dstX1, long dstY1, unsigned long mask, unsigned long filter);
- virtual void renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height);
+ void blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1, long dstX0, long dstY0, long dstX1, long dstY1, unsigned long mask, unsigned long filter) override;
+ void renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height) override;
+
+ Platform3DObject createVertexArrayOES() override;
+ void deleteVertexArrayOES(Platform3DObject) override;
+ GC3Dboolean isVertexArrayOES(Platform3DObject) override;
+ void bindVertexArrayOES(Platform3DObject) override;
+ void insertEventMarkerEXT(const String&) override;
+ void pushGroupMarkerEXT(const String&) override;
+ void popGroupMarkerEXT(void) override;
+ void drawBuffersEXT(GC3Dsizei, const GC3Denum*) override;
- virtual Platform3DObject createVertexArrayOES();
- virtual void deleteVertexArrayOES(Platform3DObject);
- virtual GC3Dboolean isVertexArrayOES(Platform3DObject);
- virtual void bindVertexArrayOES(Platform3DObject);
- virtual void copyTextureCHROMIUM(GC3Denum, Platform3DObject, Platform3DObject, GC3Dint, GC3Denum);
- virtual void insertEventMarkerEXT(const String&);
- virtual void pushGroupMarkerEXT(const String&);
- virtual void popGroupMarkerEXT(void);
- virtual void drawBuffersEXT(GC3Dsizei, const GC3Denum*);
+ void drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount) override;
+ void drawElementsInstanced(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, GC3Dsizei primcount) override;
+ void vertexAttribDivisor(GC3Duint index, GC3Duint divisor) override;
protected:
- // This class only needs to be instantiated by GraphicsContext3D implementations.
- friend class GraphicsContext3D;
- Extensions3DOpenGL(GraphicsContext3D*);
+ bool supportsExtension(const WTF::String&) override;
+ String getExtensions() override;
- virtual bool supportsExtension(const WTF::String&);
- virtual String getExtensions();
-#if (PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN))
private:
+#if (PLATFORM(GTK) || PLATFORM(WIN) || PLATFORM(IOS))
bool isVertexArrayObjectSupported();
#endif
};
} // namespace WebCore
-
-#endif // Extensions3DOpenGL_h
diff --git a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp
index 9b7c5ab65..d28d765df 100644
--- a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp
+++ b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp
@@ -26,7 +26,7 @@
#include "config.h"
-#if USE(3D_GRAPHICS)
+#if ENABLE(GRAPHICS_CONTEXT_3D)
#include "Extensions3DOpenGLCommon.h"
#include "ANGLEWebKitBridge.h"
@@ -34,14 +34,18 @@
#if PLATFORM(IOS)
#include <OpenGLES/ES2/glext.h>
+#include <OpenGLES/ES3/gl.h>
#else
#if USE(OPENGL_ES_2)
#include "OpenGLESShims.h"
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#elif PLATFORM(MAC)
+#define GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED
#include <OpenGL/gl.h>
-#elif PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN)
+#include <OpenGL/gl3.h>
+#undef GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED
+#elif PLATFORM(GTK) || PLATFORM(WIN)
#include "OpenGLShims.h"
#endif
#endif
@@ -49,54 +53,39 @@
#include <wtf/MainThread.h>
#include <wtf/Vector.h>
-#if PLATFORM(WIN) || (PLATFORM(GTK) && OS(WINDOWS))
-#undef NO_ERROR
-#endif
-
namespace WebCore {
-Extensions3DOpenGLCommon::Extensions3DOpenGLCommon(GraphicsContext3D* context)
+Extensions3DOpenGLCommon::Extensions3DOpenGLCommon(GraphicsContext3D* context, bool useIndexedGetString)
: m_initializedAvailableExtensions(false)
, m_context(context)
, m_isNVIDIA(false)
, m_isAMD(false)
, m_isIntel(false)
- , m_maySupportMultisampling(true)
+ , m_isImagination(false)
, m_requiresBuiltInFunctionEmulation(false)
+ , m_requiresRestrictedMaximumTextureSize(false)
+ , m_useIndexedGetString(useIndexedGetString)
{
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);
+ m_vendor.convertToASCIILowercase().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) && !PLATFORM(IOS)
+#if PLATFORM(MAC)
if (m_isAMD || m_isIntel)
m_requiresBuiltInFunctionEmulation = true;
- // Currently in Mac we only allow multisampling if the vendor is NVIDIA,
- // or if the vendor is AMD/ATI and the system is 10.7.2 and above.
-
- bool systemSupportsMultisampling = true;
-#if !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED < 1080
- ASSERT(isMainThread());
- static SInt32 version;
- if (!version) {
- if (Gestalt(gestaltSystemVersion, &version) != noErr)
- systemSupportsMultisampling = false;
- }
- // See https://bugs.webkit.org/show_bug.cgi?id=77922 for more details
- if (systemSupportsMultisampling)
- systemSupportsMultisampling = version >= 0x1072;
-#endif // SNOW_LEOPARD and LION
-
- if (m_isAMD && !systemSupportsMultisampling)
- m_maySupportMultisampling = false;
+ // Intel HD 3000 devices have problems with large textures. <rdar://problem/16649140>
+ m_requiresRestrictedMaximumTextureSize = m_renderer.startsWith("Intel HD Graphics 3000");
#endif
}
@@ -109,6 +98,12 @@ bool Extensions3DOpenGLCommon::supports(const String& name)
if (!m_initializedAvailableExtensions)
initializeAvailableExtensions();
+ // We explicitly do not support this extension until
+ // we fix the following bug:
+ // https://bugs.webkit.org/show_bug.cgi?id=149734
+ if (name == "GL_ANGLE_translated_shader_source")
+ return false;
+
return supportsExtension(name);
}
@@ -131,6 +126,22 @@ void Extensions3DOpenGLCommon::ensureEnabled(const String& name)
m_context->getIntegerv(Extensions3D::MAX_DRAW_BUFFERS_EXT, &ANGLEResources.MaxDrawBuffers);
compiler.setResources(ANGLEResources);
}
+ } else if (name == "GL_EXT_shader_texture_lod") {
+ // Enable support in ANGLE (if not enabled already)
+ 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") {
+ // Enable support in ANGLE (if not enabled already)
+ ANGLEWebKitBridge& compiler = m_context->m_compiler;
+ ShBuiltInResources ANGLEResources = compiler.getResources();
+ if (!ANGLEResources.EXT_frag_depth) {
+ ANGLEResources.EXT_frag_depth = 1;
+ compiler.setResources(ANGLEResources);
+ }
}
}
@@ -174,22 +185,20 @@ String Extensions3DOpenGLCommon::getTranslatedShaderSourceANGLE(Platform3DObject
String translatedShaderSource;
String shaderInfoLog;
- int extraCompileOptions = SH_MAP_LONG_VARIABLE_NAMES | SH_CLAMP_INDIRECT_ARRAY_BOUNDS | SH_UNFOLD_SHORT_CIRCUIT | SH_ENFORCE_PACKING_RESTRICTIONS;
+ int extraCompileOptions = SH_CLAMP_INDIRECT_ARRAY_BOUNDS | SH_UNFOLD_SHORT_CIRCUIT | SH_INIT_OUTPUT_VARIABLES | SH_ENFORCE_PACKING_RESTRICTIONS | SH_LIMIT_EXPRESSION_COMPLEXITY | SH_LIMIT_CALL_STACK_DEPTH;
if (m_requiresBuiltInFunctionEmulation)
- extraCompileOptions |= SH_EMULATE_BUILT_IN_FUNCTIONS;
+ extraCompileOptions |= SH_EMULATE_ABS_INT_FUNCTION;
- Vector<ANGLEShaderSymbol> symbols;
+ Vector<std::pair<ANGLEShaderSymbolType, sh::ShaderVariable>> 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);
+ for (const std::pair<ANGLEShaderSymbolType, sh::ShaderVariable>& pair : symbols) {
+ const std::string& name = pair.second.name;
+ entry.symbolMap(pair.first).set(String(name.c_str(), name.length()), pair.second);
}
if (!isValid)
@@ -200,11 +209,30 @@ String Extensions3DOpenGLCommon::getTranslatedShaderSourceANGLE(Platform3DObject
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]);
+#if PLATFORM(MAC) || (PLATFORM(GTK) && !USE(OPENGL_ES_2))
+ if (m_useIndexedGetString) {
+ GLint numExtensions = 0;
+ ::glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
+ for (GLint i = 0; i < numExtensions; ++i)
+ m_availableExtensions.add(glGetStringi(GL_EXTENSIONS, i));
+
+ if (!m_availableExtensions.contains(ASCIILiteral("GL_ARB_texture_storage"))) {
+ GLint majorVersion;
+ glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
+ GLint minorVersion;
+ glGetIntegerv(GL_MINOR_VERSION, &minorVersion);
+ if (majorVersion > 4 || (majorVersion == 4 && minorVersion >= 2))
+ m_availableExtensions.add(ASCIILiteral("GL_ARB_texture_storage"));
+ }
+ } else
+#endif
+ {
+ 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;
}
@@ -225,4 +253,4 @@ void Extensions3DOpenGLCommon::getnUniformivEXT(GC3Duint, int, GC3Dsizei, int *)
} // namespace WebCore
-#endif // USE(3D_GRAPHICS)
+#endif // ENABLE(GRAPHICS_CONTEXT_3D)
diff --git a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.h b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.h
index 4cc8dbac1..7c614fb40 100644
--- a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.h
+++ b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.h
@@ -24,8 +24,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef Extensions3DOpenGLCommon_h
-#define Extensions3DOpenGLCommon_h
+#pragma once
#include "Extensions3D.h"
@@ -40,36 +39,37 @@ public:
virtual ~Extensions3DOpenGLCommon();
// Extensions3D methods.
- virtual bool supports(const String&);
- virtual void ensureEnabled(const String&);
- virtual bool isEnabled(const String&);
- virtual int getGraphicsResetStatusARB();
+ bool supports(const String&) override;
+ void ensureEnabled(const String&) override;
+ bool isEnabled(const String&) override;
+ int getGraphicsResetStatusARB() override;
- virtual Platform3DObject createVertexArrayOES() = 0;
- virtual void deleteVertexArrayOES(Platform3DObject) = 0;
- virtual GC3Dboolean isVertexArrayOES(Platform3DObject) = 0;
- virtual void bindVertexArrayOES(Platform3DObject) = 0;
+ Platform3DObject createVertexArrayOES() override = 0;
+ void deleteVertexArrayOES(Platform3DObject) override = 0;
+ GC3Dboolean isVertexArrayOES(Platform3DObject) override = 0;
+ void bindVertexArrayOES(Platform3DObject) override = 0;
- virtual void drawBuffersEXT(GC3Dsizei, const GC3Denum*) = 0;
+ void drawBuffersEXT(GC3Dsizei, const GC3Denum*) override = 0;
- virtual String getTranslatedShaderSourceANGLE(Platform3DObject);
+ String getTranslatedShaderSourceANGLE(Platform3DObject) override;
// EXT Robustness - uses getGraphicsResetStatusARB()
- virtual void readnPixelsEXT(int x, int y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, GC3Dsizei bufSize, void *data);
- virtual void getnUniformfvEXT(GC3Duint program, int location, GC3Dsizei bufSize, float *params);
- virtual void getnUniformivEXT(GC3Duint program, int location, GC3Dsizei bufSize, int *params);
+ void readnPixelsEXT(int x, int y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, GC3Dsizei bufSize, void *data) override;
+ void getnUniformfvEXT(GC3Duint program, int location, GC3Dsizei bufSize, float *params) override;
+ void getnUniformivEXT(GC3Duint program, int location, GC3Dsizei bufSize, int *params) override;
- virtual bool isNVIDIA() { return m_isNVIDIA; }
- virtual bool isAMD() { return m_isAMD; }
- virtual bool isIntel() { return m_isIntel; }
- virtual String vendor() { return m_vendor; }
+ bool isNVIDIA() override { return m_isNVIDIA; }
+ bool isAMD() override { return m_isAMD; }
+ bool isIntel() override { return m_isIntel; }
+ bool isImagination() override { return m_isImagination; }
+ String vendor() override { return m_vendor; }
- virtual bool maySupportMultisampling() { return m_maySupportMultisampling; }
- virtual bool requiresBuiltInFunctionEmulation() { return m_requiresBuiltInFunctionEmulation; }
+ bool requiresBuiltInFunctionEmulation() override { return m_requiresBuiltInFunctionEmulation; }
+ bool requiresRestrictedMaximumTextureSize() override { return m_requiresRestrictedMaximumTextureSize; }
protected:
friend class Extensions3DOpenGLES;
- Extensions3DOpenGLCommon(GraphicsContext3D*);
+ Extensions3DOpenGLCommon(GraphicsContext3D*, bool useIndexedGetString);
virtual bool supportsExtension(const String&) = 0;
virtual String getExtensions() = 0;
@@ -84,12 +84,14 @@ protected:
bool m_isNVIDIA;
bool m_isAMD;
bool m_isIntel;
- bool m_maySupportMultisampling;
+ bool m_isImagination;
bool m_requiresBuiltInFunctionEmulation;
+ bool m_requiresRestrictedMaximumTextureSize;
+
+ bool m_useIndexedGetString { false };
String m_vendor;
+ String m_renderer;
};
} // namespace WebCore
-
-#endif // Extensions3DOpenGLCommon_h
diff --git a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLES.cpp b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLES.cpp
index dc9e59252..958e09383 100644
--- a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLES.cpp
+++ b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLES.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
* Copyright (C) 2012 Research In Motion Limited. All rights reserved.
+ * Copyright (C) 2014 Collabora Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,21 +26,23 @@
*/
#include "config.h"
-#if USE(3D_GRAPHICS)
+
+#if USE(OPENGL_ES_2)
#include "Extensions3DOpenGLES.h"
+#if ENABLE(GRAPHICS_CONTEXT_3D)
#include "GraphicsContext3D.h"
#include "NotImplemented.h"
#include <EGL/egl.h>
-#include <wtf/Vector.h>
namespace WebCore {
-Extensions3DOpenGLES::Extensions3DOpenGLES(GraphicsContext3D* context)
- : Extensions3DOpenGLCommon(context)
+Extensions3DOpenGLES::Extensions3DOpenGLES(GraphicsContext3D* context, bool useIndexedGetString)
+ : Extensions3DOpenGLCommon(context, useIndexedGetString)
, m_contextResetStatus(GL_NO_ERROR)
, m_supportsOESvertexArrayObject(false)
, m_supportsIMGMultisampledRenderToTexture(false)
+ , m_supportsANGLEinstancedArrays(false)
, m_glFramebufferTexture2DMultisampleIMG(0)
, m_glRenderbufferStorageMultisampleIMG(0)
, m_glBindVertexArrayOES(0)
@@ -50,6 +53,9 @@ Extensions3DOpenGLES::Extensions3DOpenGLES(GraphicsContext3D* context)
, m_glReadnPixelsEXT(0)
, m_glGetnUniformfvEXT(0)
, m_glGetnUniformivEXT(0)
+ , m_glVertexAttribDivisorANGLE(nullptr)
+ , m_glDrawArraysInstancedANGLE(nullptr)
+ , m_glDrawElementsInstancedANGLE(nullptr)
{
}
@@ -73,7 +79,7 @@ void Extensions3DOpenGLES::renderbufferStorageMultisampleIMG(unsigned long targe
m_context->synthesizeGLError(GL_INVALID_OPERATION);
}
-void Extensions3DOpenGLES::blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1, long dstX0, long dstY0, long dstX1, long dstY1, unsigned long mask, unsigned long filter)
+void Extensions3DOpenGLES::blitFramebuffer(long /* srcX0 */, long /* srcY0 */, long /* srcX1 */, long /* srcY1 */, long /* dstX0 */, long /* dstY0 */, long /* dstX1 */, long /* dstY1 */, unsigned long /* mask */, unsigned long /* filter */)
{
notImplemented();
}
@@ -86,11 +92,6 @@ void Extensions3DOpenGLES::renderbufferStorageMultisample(unsigned long target,
notImplemented();
}
-void Extensions3DOpenGLES::copyTextureCHROMIUM(GC3Denum, Platform3DObject, Platform3DObject, GC3Dint, GC3Denum)
-{
- notImplemented();
-}
-
void Extensions3DOpenGLES::insertEventMarkerEXT(const String&)
{
notImplemented();
@@ -156,9 +157,10 @@ void Extensions3DOpenGLES::bindVertexArrayOES(Platform3DObject array)
m_context->synthesizeGLError(GL_INVALID_OPERATION);
}
-void Extensions3DOpenGLES::drawBuffersEXT(GC3Dsizei n, const GC3Denum* bufs)
+void Extensions3DOpenGLES::drawBuffersEXT(GC3Dsizei /* n */, const GC3Denum* /* bufs */)
{
// FIXME: implement the support.
+ notImplemented();
}
int Extensions3DOpenGLES::getGraphicsResetStatusARB()
@@ -184,9 +186,9 @@ int Extensions3DOpenGLES::getGraphicsResetStatusARB()
return false;
}
-void Extensions3DOpenGLES::setEXTContextLostCallback(PassOwnPtr<GraphicsContext3D::ContextLostCallback> callback)
+void Extensions3DOpenGLES::setEXTContextLostCallback(std::unique_ptr<GraphicsContext3D::ContextLostCallback> callback)
{
- m_contextLostCallback = callback;
+ m_contextLostCallback = WTFMove(callback);
}
void Extensions3DOpenGLES::readnPixelsEXT(int x, int y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, GC3Dsizei bufSize, void *data)
@@ -228,6 +230,39 @@ void Extensions3DOpenGLES::getnUniformivEXT(GC3Duint program, int location, GC3D
m_context->synthesizeGLError(GL_INVALID_OPERATION);
}
+void Extensions3DOpenGLES::drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount)
+{
+ if (!m_glDrawArraysInstancedANGLE) {
+ m_context->synthesizeGLError(GL_INVALID_OPERATION);
+ return;
+ }
+
+ m_context->makeContextCurrent();
+ m_glDrawArraysInstancedANGLE(mode, first, count, primcount);
+}
+
+void Extensions3DOpenGLES::drawElementsInstanced(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, GC3Dsizei primcount)
+{
+ if (!m_glDrawElementsInstancedANGLE) {
+ m_context->synthesizeGLError(GL_INVALID_OPERATION);
+ return;
+ }
+
+ m_context->makeContextCurrent();
+ m_glDrawElementsInstancedANGLE(mode, count, type, reinterpret_cast<GLvoid*>(static_cast<intptr_t>(offset)), primcount);
+}
+
+void Extensions3DOpenGLES::vertexAttribDivisor(GC3Duint index, GC3Duint divisor)
+{
+ if (!m_glVertexAttribDivisorANGLE) {
+ m_context->synthesizeGLError(GL_INVALID_OPERATION);
+ return;
+ }
+
+ m_context->makeContextCurrent();
+ m_glVertexAttribDivisorANGLE(index, divisor);
+}
+
bool Extensions3DOpenGLES::supportsExtension(const String& name)
{
if (m_availableExtensions.contains(name)) {
@@ -238,14 +273,19 @@ bool Extensions3DOpenGLES::supportsExtension(const String& name)
m_glIsVertexArrayOES = reinterpret_cast<PFNGLISVERTEXARRAYOESPROC>(eglGetProcAddress("glIsVertexArrayOES"));
m_supportsOESvertexArrayObject = true;
} else if (!m_supportsIMGMultisampledRenderToTexture && name == "GL_IMG_multisampled_render_to_texture") {
- m_glFramebufferTexture2DMultisampleIMG = reinterpret_cast<PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMG>(eglGetProcAddress("glFramebufferTexture2DMultisampleIMG"));
- m_glRenderbufferStorageMultisampleIMG = reinterpret_cast<PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMG>(eglGetProcAddress("glRenderbufferStorageMultisampleIMG"));
+ m_glFramebufferTexture2DMultisampleIMG = reinterpret_cast<PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC>(eglGetProcAddress("glFramebufferTexture2DMultisampleIMG"));
+ m_glRenderbufferStorageMultisampleIMG = reinterpret_cast<PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC>(eglGetProcAddress("glRenderbufferStorageMultisampleIMG"));
m_supportsIMGMultisampledRenderToTexture = true;
} else if (!m_glGetGraphicsResetStatusEXT && name == "GL_EXT_robustness") {
m_glGetGraphicsResetStatusEXT = reinterpret_cast<PFNGLGETGRAPHICSRESETSTATUSEXTPROC>(eglGetProcAddress("glGetGraphicsResetStatusEXT"));
m_glReadnPixelsEXT = reinterpret_cast<PFNGLREADNPIXELSEXTPROC>(eglGetProcAddress("glReadnPixelsEXT"));
m_glGetnUniformfvEXT = reinterpret_cast<PFNGLGETNUNIFORMFVEXTPROC>(eglGetProcAddress("glGetnUniformfvEXT"));
m_glGetnUniformivEXT = reinterpret_cast<PFNGLGETNUNIFORMIVEXTPROC>(eglGetProcAddress("glGetnUniformivEXT"));
+ } else if (!m_supportsANGLEinstancedArrays && name == "GL_ANGLE_instanced_arrays") {
+ m_glVertexAttribDivisorANGLE = reinterpret_cast<PFNGLVERTEXATTRIBDIVISORANGLEPROC>(eglGetProcAddress("glVertexAttribDivisorANGLE"));
+ m_glDrawArraysInstancedANGLE = reinterpret_cast<PFNGLDRAWARRAYSINSTANCEDANGLEPROC >(eglGetProcAddress("glDrawArraysInstancedANGLE"));
+ m_glDrawElementsInstancedANGLE = reinterpret_cast<PFNGLDRAWELEMENTSINSTANCEDANGLEPROC >(eglGetProcAddress("glDrawElementsInstancedANGLE"));
+ m_supportsANGLEinstancedArrays = true;
} else if (name == "GL_EXT_draw_buffers") {
// FIXME: implement the support.
return false;
@@ -263,4 +303,6 @@ String Extensions3DOpenGLES::getExtensions()
} // namespace WebCore
-#endif // USE(3D_GRAPHICS)
+#endif // ENABLE(GRAPHICS_CONTEXT_3D)
+
+#endif // USE(OPENGL_ES_2)
diff --git a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLES.h b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLES.h
index 7c40566e9..316e5e9b5 100644
--- a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLES.h
+++ b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLES.h
@@ -24,11 +24,12 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef Extensions3DOpenGLES_h
-#define Extensions3DOpenGLES_h
+#pragma once
#include "Extensions3DOpenGLCommon.h"
+#if USE(OPENGL_ES_2)
+
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
@@ -61,6 +62,8 @@ namespace WebCore {
class Extensions3DOpenGLES : public Extensions3DOpenGLCommon {
public:
+ // This class only needs to be instantiated by GraphicsContext3D implementations.
+ Extensions3DOpenGLES(GraphicsContext3D*, bool useIndexedGetString);
virtual ~Extensions3DOpenGLES();
virtual void framebufferTexture2DMultisampleIMG(unsigned long target, unsigned long attachment, unsigned long textarget, unsigned int texture, int level, unsigned long samples);
@@ -69,7 +72,6 @@ public:
// Extension3D methods
virtual void blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1, long dstX0, long dstY0, long dstX1, long dstY1, unsigned long mask, unsigned long filter);
virtual void renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height);
- virtual void copyTextureCHROMIUM(GC3Denum, Platform3DObject, Platform3DObject, GC3Dint, GC3Denum);
virtual void insertEventMarkerEXT(const String&);
virtual void pushGroupMarkerEXT(const String&);
virtual void popGroupMarkerEXT(void);
@@ -80,9 +82,13 @@ public:
virtual void bindVertexArrayOES(Platform3DObject);
virtual void drawBuffersEXT(GC3Dsizei, const GC3Denum*);
+ virtual void drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount);
+ virtual void drawElementsInstanced(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, GC3Dsizei primcount);
+ virtual void vertexAttribDivisor(GC3Duint index, GC3Duint divisor);
+
// EXT Robustness - reset
virtual int getGraphicsResetStatusARB();
- void setEXTContextLostCallback(PassOwnPtr<GraphicsContext3D::ContextLostCallback>);
+ void setEXTContextLostCallback(std::unique_ptr<GraphicsContext3D::ContextLostCallback>);
// EXT Robustness - etc
virtual void readnPixelsEXT(int x, int y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, GC3Dsizei bufSize, void *data);
@@ -90,10 +96,6 @@ public:
virtual void getnUniformivEXT(GC3Duint program, int location, GC3Dsizei bufSize, int *params);
protected:
- // This class only needs to be instantiated by GraphicsContext3D implementations.
- friend class GraphicsContext3D;
- Extensions3DOpenGLES(GraphicsContext3D*);
-
virtual bool supportsExtension(const String&);
virtual String getExtensions();
@@ -101,9 +103,10 @@ protected:
bool m_supportsOESvertexArrayObject;
bool m_supportsIMGMultisampledRenderToTexture;
+ bool m_supportsANGLEinstancedArrays;
- PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMG m_glFramebufferTexture2DMultisampleIMG;
- PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMG m_glRenderbufferStorageMultisampleIMG;
+ PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC m_glFramebufferTexture2DMultisampleIMG;
+ PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC m_glRenderbufferStorageMultisampleIMG;
PFNGLBINDVERTEXARRAYOESPROC m_glBindVertexArrayOES;
PFNGLDELETEVERTEXARRAYSOESPROC m_glDeleteVertexArraysOES;
PFNGLGENVERTEXARRAYSOESPROC m_glGenVertexArraysOES;
@@ -112,10 +115,13 @@ protected:
PFNGLREADNPIXELSEXTPROC m_glReadnPixelsEXT;
PFNGLGETNUNIFORMFVEXTPROC m_glGetnUniformfvEXT;
PFNGLGETNUNIFORMIVEXTPROC m_glGetnUniformivEXT;
+ PFNGLVERTEXATTRIBDIVISORANGLEPROC m_glVertexAttribDivisorANGLE;
+ PFNGLDRAWARRAYSINSTANCEDANGLEPROC m_glDrawArraysInstancedANGLE;
+ PFNGLDRAWELEMENTSINSTANCEDANGLEPROC m_glDrawElementsInstancedANGLE;
- OwnPtr<GraphicsContext3D::ContextLostCallback> m_contextLostCallback;
+ std::unique_ptr<GraphicsContext3D::ContextLostCallback> m_contextLostCallback;
};
} // namespace WebCore
-#endif // Extensions3DOpenGLES_h
+#endif // USE(OPENGL_ES_2)
diff --git a/Source/WebCore/platform/graphics/opengl/GLDefs.h b/Source/WebCore/platform/graphics/opengl/GLDefs.h
new file mode 100644
index 000000000..9a2c2fffd
--- /dev/null
+++ b/Source/WebCore/platform/graphics/opengl/GLDefs.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GLDefs_h
+#define GLDefs_h
+
+#define GL_GLEXT_PROTOTYPES 1
+
+#if USE(OPENGL_ES_2)
+#include "Extensions3DOpenGLES.h"
+#include "OpenGLESShims.h"
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#else
+#include "Extensions3DOpenGL.h"
+#include "OpenGLShims.h"
+#include <GL/gl.h>
+#include <GL/glext.h>
+#if USE(GLX)
+#define GLX_GLXEXT_PROTOTYPES 1
+#include <GL/glx.h>
+#include <GL/glxext.h>
+#endif
+#endif
+
+#if USE(EGL)
+#define EGL_EGLEXT_PROTOTYPES 1
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#endif
+
+namespace WebCore {
+
+typedef uint32_t PlatformBufferHandle;
+
+#if USE(GLX)
+typedef GLXContext PlatformContext;
+typedef GLXFBConfig PlatformSurfaceConfig;
+typedef GLXDrawable PlatformDrawable;
+#elif USE(EGL)
+typedef EGLContext PlatformContext;
+typedef EGLConfig PlatformSurfaceConfig;
+typedef EGLSurface PlatformDrawable;
+#else
+typedef void* PlatformContext;
+typedef void* PlatformSurfaceConfig;
+typedef void* PlatformDrawable;
+#endif
+
+}
+
+#endif
diff --git a/Source/WebCore/platform/graphics/opengl/GLPlatformContext.cpp b/Source/WebCore/platform/graphics/opengl/GLPlatformContext.cpp
new file mode 100644
index 000000000..5219a2391
--- /dev/null
+++ b/Source/WebCore/platform/graphics/opengl/GLPlatformContext.cpp
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(GRAPHICS_CONTEXT_3D)
+#include "GLPlatformContext.h"
+
+#if USE(GLX)
+#include "GLXContext.h"
+#elif USE(EGL)
+#include "EGLContext.h"
+#endif
+
+#include "NotImplemented.h"
+
+namespace WebCore {
+
+#if USE(OPENGL_ES_2)
+static PFNGLGETGRAPHICSRESETSTATUSEXTPROC glGetGraphicsResetStatus = 0;
+#else
+static PFNGLGETGRAPHICSRESETSTATUSARBPROC glGetGraphicsResetStatus = 0;
+#endif
+
+class GLCurrentContextWrapper : public GLPlatformContext {
+
+public:
+ GLCurrentContextWrapper()
+ : GLPlatformContext()
+ {
+#if USE(GLX)
+ m_contextHandle = glXGetCurrentContext();
+#elif USE(EGL)
+ m_contextHandle = eglGetCurrentContext();
+#endif
+ }
+
+ virtual ~GLCurrentContextWrapper() { }
+
+ bool isCurrentContext() const override
+ {
+ return true;
+ }
+};
+
+static std::unique_ptr<GLPlatformContext> createOffScreenContext()
+{
+#if USE(GLX)
+ return std::make_unique<GLXOffScreenContext>();
+#elif USE(EGL)
+ return std::make_unique<EGLOffScreenContext>();
+#else
+ return nullptr;
+#endif
+}
+
+static HashSet<String> parseExtensions(const String& extensionsString)
+{
+ Vector<String> extNames;
+ extensionsString.split(' ', extNames);
+ HashSet<String> splitExtNames;
+ unsigned size = extNames.size();
+ for (unsigned i = 0; i < size; ++i)
+ splitExtNames.add(extNames[i]);
+ extNames.clear();
+
+ return splitExtNames;
+}
+
+static void resolveResetStatusExtension()
+{
+ static bool resolvedRobustnessExtension = false;
+ if (!resolvedRobustnessExtension) {
+ resolvedRobustnessExtension = true;
+#if USE(OPENGL_ES_2)
+ glGetGraphicsResetStatus = reinterpret_cast<PFNGLGETGRAPHICSRESETSTATUSEXTPROC>(eglGetProcAddress("glGetGraphicsResetStatusEXT"));
+#elif USE(EGL)
+ glGetGraphicsResetStatus = reinterpret_cast<PFNGLGETGRAPHICSRESETSTATUSARBPROC>(eglGetProcAddress("glGetGraphicsResetStatusARB"));
+#elif USE(GLX)
+ glGetGraphicsResetStatus = reinterpret_cast<PFNGLGETGRAPHICSRESETSTATUSARBPROC>(glXGetProcAddressARB(reinterpret_cast<const GLubyte*>("glGetGraphicsResetStatusARB")));
+#endif
+ }
+}
+
+std::unique_ptr<GLPlatformContext> GLPlatformContext::createContext(GraphicsContext3D::RenderStyle renderStyle)
+{
+#if !USE(OPENGL_ES_2)
+ if (!initializeOpenGLShims())
+ return nullptr;
+#endif
+
+ switch (renderStyle) {
+ case GraphicsContext3D::RenderOffscreen:
+ return createOffScreenContext();
+ case GraphicsContext3D::RenderToCurrentGLContext:
+ return std::make_unique<GLCurrentContextWrapper>();
+ case GraphicsContext3D::RenderDirectlyToHostWindow:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+
+ return nullptr;
+}
+
+bool GLPlatformContext::supportsGLExtension(const String& name)
+{
+ static HashSet<String> supportedExtensions;
+
+ if (!supportedExtensions.size()) {
+ String rawExtensions = reinterpret_cast<const char*>(::glGetString(GL_EXTENSIONS));
+ supportedExtensions = parseExtensions(rawExtensions);
+ }
+
+ if (supportedExtensions.contains(name))
+ return true;
+
+ return false;
+}
+
+#if USE(EGL)
+bool GLPlatformContext::supportsEGLExtension(EGLDisplay display, const String& name)
+{
+ static HashSet<String> supportedExtensions;
+
+ if (!supportedExtensions.size()) {
+ if (display == EGL_NO_DISPLAY)
+ return false;
+
+ String rawExtensions = reinterpret_cast<const char*>(eglQueryString(display, EGL_EXTENSIONS));
+ supportedExtensions = parseExtensions(rawExtensions);
+ }
+
+ if (supportedExtensions.contains(name))
+ return true;
+
+ return false;
+}
+#endif
+
+#if USE(GLX)
+bool GLPlatformContext::supportsGLXExtension(Display* display, const String& name)
+{
+ static HashSet<String> supportedExtensions;
+
+ if (!supportedExtensions.size()) {
+ if (!display)
+ return false;
+
+ String rawExtensions = glXQueryExtensionsString(display, DefaultScreen(display));
+ supportedExtensions = parseExtensions(rawExtensions);
+ }
+
+ if (supportedExtensions.contains(name))
+ return true;
+
+ return false;
+}
+#endif
+
+GLPlatformContext::GLPlatformContext()
+ : m_contextHandle(0)
+ , m_resetLostContext(false)
+{
+}
+
+GLPlatformContext::~GLPlatformContext()
+{
+}
+
+bool GLPlatformContext::makeCurrent(GLPlatformSurface* surface)
+{
+ m_contextLost = false;
+
+ if (isCurrentContext() && (!surface || surface->isCurrentDrawable()))
+ return true;
+
+ GLPlatformContext* currentContext = 0;
+
+ if (!surface || (surface && !surface->drawable()))
+ platformReleaseCurrent();
+ else if (platformMakeCurrent(surface)) {
+ currentContext = this;
+ surface->onMakeCurrent();
+ }
+
+ if (m_resetLostContext) {
+ resolveResetStatusExtension();
+
+ if (glGetGraphicsResetStatus) {
+ GLenum status = glGetGraphicsResetStatus();
+
+ switch (status) {
+ case PLATFORMCONTEXT_NO_ERROR:
+ break;
+ case PLATFORMCONTEXT_GUILTY_CONTEXT_RESET:
+ m_contextLost = true;
+ break;
+ case PLATFORMCONTEXT_INNOCENT_CONTEXT_RESET:
+ break;
+ case PLATFORMCONTEXT_UNKNOWN_CONTEXT_RESET:
+ m_contextLost = true;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ return currentContext;
+}
+
+bool GLPlatformContext::isValid() const
+{
+ return !m_contextLost;
+}
+
+void GLPlatformContext::releaseCurrent()
+{
+ if (isCurrentContext())
+ platformReleaseCurrent();
+}
+
+PlatformContext GLPlatformContext::handle() const
+{
+ return m_contextHandle;
+}
+
+bool GLPlatformContext::initialize(GLPlatformSurface*, PlatformContext)
+{
+ return true;
+}
+
+bool GLPlatformContext::platformMakeCurrent(GLPlatformSurface*)
+{
+ return true;
+}
+
+void GLPlatformContext::platformReleaseCurrent()
+{
+ notImplemented();
+}
+
+void GLPlatformContext::destroy()
+{
+ m_contextHandle = 0;
+ m_resetLostContext = false;
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/platform/graphics/opengl/GLPlatformContext.h b/Source/WebCore/platform/graphics/opengl/GLPlatformContext.h
new file mode 100644
index 000000000..a999cc0cf
--- /dev/null
+++ b/Source/WebCore/platform/graphics/opengl/GLPlatformContext.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GLPlatformContext_h
+#define GLPlatformContext_h
+
+#include "GLDefs.h"
+#include "GLPlatformSurface.h"
+#include "GraphicsContext3D.h"
+#include <wtf/Noncopyable.h>
+
+// Encapsulates an OpenGL context, hiding platform specific management.
+namespace WebCore {
+
+class GLPlatformContext {
+ WTF_MAKE_NONCOPYABLE(GLPlatformContext);
+
+public:
+ // From http://www.khronos.org/registry/gles/extensions/EXT/EXT_robustness.txt
+ enum PlatformContextReset {
+ PLATFORMCONTEXT_NO_ERROR = 0x0000,
+ PLATFORMCONTEXT_GUILTY_CONTEXT_RESET = 0x8253,
+ PLATFORMCONTEXT_INNOCENT_CONTEXT_RESET = 0x8254,
+ PLATFORMCONTEXT_UNKNOWN_CONTEXT_RESET = 0x8255,
+ };
+
+ static std::unique_ptr<GLPlatformContext> createContext(GraphicsContext3D::RenderStyle);
+
+ static bool supportsGLExtension(const String&);
+
+#if USE(EGL)
+ static bool supportsEGLExtension(EGLDisplay, const String&);
+#endif
+
+#if USE(GLX)
+ static bool supportsGLXExtension(Display*, const String&);
+#endif
+
+ virtual ~GLPlatformContext();
+
+ virtual bool initialize(GLPlatformSurface*, PlatformContext = 0);
+
+ // Makes this and surface as current context and drawable.
+ // Calling this function with no surface is same as calling releaseCurrent.
+ // Does nothing if this is already current Context.
+ bool makeCurrent(GLPlatformSurface* = 0);
+
+ // Sets Current Context and Drawable as Null.
+ // Doesn't have any effect if this is not the current Context.
+ void releaseCurrent();
+
+ virtual PlatformContext handle() const;
+
+ virtual bool isCurrentContext() const = 0;
+
+ bool isValid() const;
+
+ // Destroys any GL resources associated with this context.
+ virtual void destroy();
+
+protected:
+ GLPlatformContext();
+ virtual bool platformMakeCurrent(GLPlatformSurface*);
+ virtual void platformReleaseCurrent();
+ PlatformContext m_contextHandle;
+ bool m_resetLostContext;
+ bool m_contextLost;
+};
+
+} // namespace WebCore
+
+#endif // GLNativeContext_H
diff --git a/Source/WebCore/platform/graphics/opengl/GLPlatformSurface.h b/Source/WebCore/platform/graphics/opengl/GLPlatformSurface.h
new file mode 100644
index 000000000..2d99d6f2d
--- /dev/null
+++ b/Source/WebCore/platform/graphics/opengl/GLPlatformSurface.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GLPlatformSurface_h
+#define GLPlatformSurface_h
+
+#include "GLDefs.h"
+#include "IntRect.h"
+#include <wtf/Noncopyable.h>
+
+// Encapsulates a surface that can be rendered to with GL, hiding platform
+// specific management.
+namespace WebCore {
+
+class GLPlatformSurface {
+ WTF_MAKE_NONCOPYABLE(GLPlatformSurface);
+
+public:
+ enum Attributes {
+ Default = 0x00, // No Alpha channel. Only R,G,B values set.
+ SupportAlpha = 0x01,
+ DoubleBuffered = 0x02
+ };
+
+ typedef unsigned SurfaceAttributes;
+ // Creates a GL surface used for offscreen rendering.
+ static std::unique_ptr<GLPlatformSurface> createOffScreenSurface(SurfaceAttributes = GLPlatformSurface::Default);
+
+ virtual ~GLPlatformSurface();
+
+ const IntRect& geometry() const;
+
+ // Get the underlying platform specific buffer handle.
+ // The handle will be null if surface doesn't support
+ // buffer sharing.
+ PlatformBufferHandle handle() const;
+
+ PlatformDrawable drawable() const;
+
+ virtual SurfaceAttributes attributes() const;
+
+ virtual void swapBuffers();
+
+ virtual bool isCurrentDrawable() const = 0;
+
+ virtual void onMakeCurrent();
+
+ // Convenience Function to update surface backbuffer with texture contents.
+ // Note that the function doesn't track or restore any GL states.
+ // Function does the following(in order):
+ // a) Blits texture contents to back buffer.
+ // b) Calls Swap Buffers.
+ virtual void updateContents(const uint32_t);
+
+ virtual void setGeometry(const IntRect&);
+
+ virtual PlatformSurfaceConfig configuration();
+
+ virtual void destroy();
+
+protected:
+ GLPlatformSurface(SurfaceAttributes);
+
+ PlatformDrawable m_drawable;
+ PlatformBufferHandle m_bufferHandle;
+ IntRect m_rect;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
index 02e1b9ec8..25c9a221c 100644
--- a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
+++ b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
@@ -11,10 +11,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -26,7 +26,7 @@
#include "config.h"
-#if USE(3D_GRAPHICS)
+#if ENABLE(GRAPHICS_CONTEXT_3D)
#include "GraphicsContext3D.h"
#if PLATFORM(IOS)
@@ -44,14 +44,21 @@
#include <wtf/MainThread.h>
#include <wtf/text/CString.h>
+#if USE(ACCELERATE)
+#include <Accelerate/Accelerate.h>
+#endif
+
#if PLATFORM(IOS)
#import <OpenGLES/ES2/glext.h>
// From <OpenGLES/glext.h>
#define GL_RGBA32F_ARB 0x8814
#define GL_RGB32F_ARB 0x8815
#elif PLATFORM(MAC)
+#define GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED
#include <OpenGL/gl.h>
-#elif PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN)
+#include <OpenGL/gl3.h>
+#undef GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED
+#elif PLATFORM(GTK) || PLATFORM(WIN)
#include "OpenGLShims.h"
#endif
@@ -65,7 +72,32 @@ void GraphicsContext3D::releaseShaderCompiler()
void GraphicsContext3D::readPixelsAndConvertToBGRAIfNecessary(int x, int y, int width, int height, unsigned char* pixels)
{
- ::glReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels);
+ // NVIDIA drivers have a bug where calling readPixels in BGRA can return the wrong values for the alpha channel when the alpha is off for the context.
+ if (!m_attrs.alpha && getExtensions().isNVIDIA()) {
+ ::glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+#if USE(ACCELERATE)
+ vImage_Buffer src;
+ src.height = height;
+ src.width = width;
+ src.rowBytes = width * 4;
+ src.data = pixels;
+
+ vImage_Buffer dest;
+ dest.height = height;
+ dest.width = width;
+ dest.rowBytes = width * 4;
+ dest.data = pixels;
+
+ // Swap pixel channels from RGBA to BGRA.
+ const uint8_t map[4] = { 2, 1, 0, 3 };
+ vImagePermuteChannels_ARGB8888(&src, &dest, map, kvImageNoFlags);
+#else
+ int totalBytes = width * height * 4;
+ for (int i = 0; i < totalBytes; i += 4)
+ std::swap(pixels[i], pixels[i + 2]);
+#endif
+ } else
+ ::glReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels);
}
void GraphicsContext3D::validateAttributes()
@@ -89,9 +121,9 @@ bool GraphicsContext3D::reshapeFBOs(const IntSize& size)
// We don't allow the logic where stencil is required and depth is not.
// See GraphicsContext3D::validateAttributes.
- Extensions3D* extensions = getExtensions();
+ Extensions3D& extensions = getExtensions();
// Use a 24 bit depth buffer where we know we have it.
- if (extensions->supports("GL_EXT_packed_depth_stencil"))
+ if (extensions.supports("GL_EXT_packed_depth_stencil"))
internalDepthStencilFormat = GL_DEPTH24_STENCIL8_EXT;
else
#if PLATFORM(IOS)
@@ -110,7 +142,11 @@ bool GraphicsContext3D::reshapeFBOs(const IntSize& size)
sampleCount = maxSampleCount;
::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
+#if PLATFORM(IOS)
+ ::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, GL_RGBA8_OES, width, height);
+#else
::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, m_internalColorFormat, width, height);
+#endif
::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
if (m_attrs.stencil || m_attrs.depth) {
::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
@@ -143,9 +179,31 @@ bool GraphicsContext3D::reshapeFBOs(const IntSize& size)
::glBindTexture(GL_TEXTURE_2D, m_compositorTexture);
::glTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
::glBindTexture(GL_TEXTURE_2D, 0);
+#if USE(COORDINATED_GRAPHICS_THREADED)
+ ::glBindTexture(GL_TEXTURE_2D, m_intermediateTexture);
+ ::glTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
+ ::glBindTexture(GL_TEXTURE_2D, 0);
+#endif
}
#endif
+ attachDepthAndStencilBufferIfNeeded(internalDepthStencilFormat, width, height);
+
+ bool mustRestoreFBO = true;
+ if (m_attrs.antialias) {
+ ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
+ if (m_state.boundFBO == m_multisampleFBO)
+ mustRestoreFBO = false;
+ } else {
+ if (m_state.boundFBO == m_fbo)
+ mustRestoreFBO = false;
+ }
+
+ return mustRestoreFBO;
+}
+
+void GraphicsContext3D::attachDepthAndStencilBufferIfNeeded(GLuint internalDepthStencilFormat, int width, int height)
+{
if (!m_attrs.antialias && (m_attrs.stencil || m_attrs.depth)) {
::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalDepthStencilFormat, width, height);
@@ -160,18 +218,6 @@ bool GraphicsContext3D::reshapeFBOs(const IntSize& size)
// FIXME: cleanup
notImplemented();
}
-
- bool mustRestoreFBO = true;
- if (m_attrs.antialias) {
- ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
- if (m_state.boundFBO == m_multisampleFBO)
- mustRestoreFBO = false;
- } else {
- if (m_state.boundFBO == m_fbo)
- mustRestoreFBO = false;
- }
-
- return mustRestoreFBO;
}
void GraphicsContext3D::resolveMultisamplingIfNecessary(const IntRect& rect)
@@ -181,11 +227,20 @@ void GraphicsContext3D::resolveMultisamplingIfNecessary(const IntRect& rect)
TemporaryOpenGLSetting scopedDepth(GL_DEPTH_TEST, GL_FALSE);
TemporaryOpenGLSetting scopedStencil(GL_STENCIL_TEST, GL_FALSE);
+#if PLATFORM(IOS)
+ GLint boundFrameBuffer;
+ ::glGetIntegerv(GL_FRAMEBUFFER_BINDING, &boundFrameBuffer);
+#endif
+
::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
#if PLATFORM(IOS)
UNUSED_PARAM(rect);
+ ::glFlush();
::glResolveMultisampleFramebufferAPPLE();
+ const GLenum discards[] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT };
+ ::glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER_APPLE, 2, discards);
+ ::glBindFramebuffer(GL_FRAMEBUFFER, boundFrameBuffer);
#else
IntRect resolveRect = rect;
if (rect.isEmpty())
@@ -236,10 +291,29 @@ void GraphicsContext3D::getIntegerv(GC3Denum pname, GC3Dint* value)
*value /= 4;
break;
case MAX_VARYING_VECTORS:
- ::glGetIntegerv(GL_MAX_VARYING_FLOATS, value);
- *value /= 4;
+ if (isGLES2Compliant()) {
+ ASSERT(::glGetError() == GL_NO_ERROR);
+ ::glGetIntegerv(GL_MAX_VARYING_VECTORS, value);
+ if (::glGetError() == GL_INVALID_ENUM) {
+ ::glGetIntegerv(GL_MAX_VARYING_COMPONENTS, value);
+ *value /= 4;
+ }
+ } else {
+ ::glGetIntegerv(GL_MAX_VARYING_FLOATS, value);
+ *value /= 4;
+ }
break;
#endif
+ case MAX_TEXTURE_SIZE:
+ ::glGetIntegerv(MAX_TEXTURE_SIZE, value);
+ if (getExtensions().requiresRestrictedMaximumTextureSize())
+ *value = std::min(4096, *value);
+ break;
+ case MAX_CUBE_MAP_TEXTURE_SIZE:
+ ::glGetIntegerv(MAX_CUBE_MAP_TEXTURE_SIZE, value);
+ if (getExtensions().requiresRestrictedMaximumTextureSize())
+ *value = std::min(1024, *value);
+ break;
default:
::glGetIntegerv(pname, value);
}
@@ -283,14 +357,15 @@ bool GraphicsContext3D::texImage2D(GC3Denum target, GC3Dint level, GC3Denum inte
return false;
}
+ GC3Denum openGLFormat = format;
GC3Denum openGLInternalFormat = internalformat;
+#if !PLATFORM(IOS)
if (type == GL_FLOAT) {
if (format == GL_RGBA)
openGLInternalFormat = GL_RGBA32F_ARB;
else if (format == GL_RGB)
openGLInternalFormat = GL_RGB32F_ARB;
} else if (type == HALF_FLOAT_OES) {
-#if !PLATFORM(IOS)
if (format == GL_RGBA)
openGLInternalFormat = GL_RGBA16F_ARB;
else if (format == GL_RGB)
@@ -302,9 +377,25 @@ bool GraphicsContext3D::texImage2D(GC3Denum target, GC3Dint level, GC3Denum inte
else if (format == GL_LUMINANCE_ALPHA)
openGLInternalFormat = GL_LUMINANCE_ALPHA16F_ARB;
type = GL_HALF_FLOAT_ARB;
+ }
+
+ ASSERT(format != Extensions3D::SRGB8_ALPHA8_EXT);
+ if (format == Extensions3D::SRGB_ALPHA_EXT)
+ openGLFormat = GL_RGBA;
+ else if (format == Extensions3D::SRGB_EXT)
+ openGLFormat = GL_RGB;
#endif
+
+ if (m_usingCoreProfile && openGLInternalFormat == ALPHA) {
+ // We are using a core profile. This means that GL_ALPHA, which is a valid format in WebGL for texImage2D
+ // is not supported in OpenGL. It needs to be backed with a GL_RED plane. We change the formats to GL_RED
+ // (both need to be GL_ALPHA in WebGL) and instruct the texture to swizzle the red component values with
+ // the the alpha component values.
+ openGLInternalFormat = openGLFormat = RED;
+ texParameteri(target, TEXTURE_SWIZZLE_A, RED);
}
- texImage2DDirect(target, level, openGLInternalFormat, width, height, border, format, type, pixels);
+
+ texImage2DDirect(target, level, openGLInternalFormat, width, height, border, openGLFormat, type, pixels);
return true;
}
@@ -328,12 +419,14 @@ void GraphicsContext3D::clearDepth(GC3Dclampf depth)
#endif
}
-Extensions3D* GraphicsContext3D::getExtensions()
+#if !PLATFORM(GTK)
+Extensions3D& GraphicsContext3D::getExtensions()
{
if (!m_extensions)
- m_extensions = adoptPtr(new Extensions3DOpenGL(this));
- return m_extensions.get();
+ m_extensions = std::make_unique<Extensions3DOpenGL>(this, isGLES2Compliant());
+ return *m_extensions;
}
+#endif
void GraphicsContext3D::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, void* data)
{
@@ -351,31 +444,6 @@ void GraphicsContext3D::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsi
::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO);
}
-#if !PLATFORM(MAC)
-void GraphicsContext3D::drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount)
-{
- UNUSED_PARAM(mode);
- UNUSED_PARAM(first);
- UNUSED_PARAM(count);
- UNUSED_PARAM(primcount);
-}
-
-void GraphicsContext3D::drawElementsInstanced(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset, GC3Dsizei primcount)
-{
- UNUSED_PARAM(mode);
- UNUSED_PARAM(count);
- UNUSED_PARAM(type);
- UNUSED_PARAM(offset);
- UNUSED_PARAM(primcount);
-}
-
-void GraphicsContext3D::vertexAttribDivisor(GC3Duint index, GC3Duint divisor)
-{
- UNUSED_PARAM(index);
- UNUSED_PARAM(divisor);
-}
-#endif
-
}
-#endif // USE(3D_GRAPHICS)
+#endif // ENABLE(GRAPHICS_CONTEXT_3D)
diff --git a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp
index c1356a0e9..1536faf42 100644
--- a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp
+++ b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp
@@ -13,10 +13,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -28,7 +28,7 @@
#include "config.h"
-#if USE(3D_GRAPHICS)
+#if ENABLE(GRAPHICS_CONTEXT_3D)
#include "GraphicsContext3D.h"
#if PLATFORM(IOS)
@@ -40,26 +40,26 @@
#else
#include "Extensions3DOpenGL.h"
#endif
+#include "ANGLEWebKitBridge.h"
#include "GraphicsContext.h"
#include "ImageBuffer.h"
#include "ImageData.h"
#include "IntRect.h"
#include "IntSize.h"
#include "Logging.h"
-#include "NotImplemented.h"
#include "TemporaryOpenGLSetting.h"
+#include "WebGLRenderingContextBase.h"
#include <cstring>
-#include <runtime/ArrayBuffer.h>
-#include <runtime/ArrayBufferView.h>
-#include <runtime/Float32Array.h>
-#include <runtime/Int32Array.h>
-#include <runtime/Uint8Array.h>
+#include <wtf/HexNumber.h>
#include <wtf/MainThread.h>
+#include <wtf/ThreadSpecific.h>
#include <wtf/text/CString.h>
+#include <wtf/text/StringBuilder.h>
#include <yarr/RegularExpression.h>
#if PLATFORM(IOS)
#import <OpenGLES/ES2/glext.h>
+#import <OpenGLES/ES3/gl.h>
// From <OpenGLES/glext.h>
#define GL_RGBA32F_ARB 0x8814
#define GL_RGB32F_ARB 0x8815
@@ -67,15 +67,35 @@
#if USE(OPENGL_ES_2)
#include "OpenGLESShims.h"
#elif PLATFORM(MAC)
+#define GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED
#include <OpenGL/gl.h>
-#elif PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN)
+#include <OpenGL/gl3.h>
+#include <OpenGL/gl3ext.h>
+#undef GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED
+#elif PLATFORM(GTK) || PLATFORM(WIN)
#include "OpenGLShims.h"
#endif
#endif
+using namespace WTF;
+
namespace WebCore {
-static ShaderNameHash* currentNameHashMapForShader;
+static ThreadSpecific<ShaderNameHash*>& getCurrentNameHashMapForShader()
+{
+ static std::once_flag onceFlag;
+ static ThreadSpecific<ShaderNameHash*>* sharedNameHash;
+ std::call_once(onceFlag, [] {
+ sharedNameHash = new ThreadSpecific<ShaderNameHash*>;
+ });
+
+ return *sharedNameHash;
+}
+
+static void setCurrentNameHashMapForShader(ShaderNameHash* shaderNameHash)
+{
+ *getCurrentNameHashMapForShader() = shaderNameHash;
+}
// Hash function used by the ANGLE translator/compiler to do
// symbol name mangling. Since this is a static method, before
@@ -90,11 +110,10 @@ static uint64_t nameHashForShader(const char* name, size_t length)
CString nameAsCString = CString(name);
// Look up name in our local map.
- if (currentNameHashMapForShader) {
- ShaderNameHash::iterator result = currentNameHashMapForShader->find(nameAsCString);
- if (result != currentNameHashMapForShader->end())
- return result->value;
- }
+ ShaderNameHash*& currentNameHashMapForShader = *getCurrentNameHashMapForShader();
+ ShaderNameHash::iterator findResult = currentNameHashMapForShader->find(nameAsCString);
+ if (findResult != currentNameHashMapForShader->end())
+ return findResult->value;
unsigned hashValue = nameAsCString.hash();
@@ -111,37 +130,39 @@ static uint64_t nameHashForShader(const char* name, size_t length)
return result;
}
-PassRefPtr<GraphicsContext3D> GraphicsContext3D::createForCurrentGLContext()
+RefPtr<GraphicsContext3D> GraphicsContext3D::createForCurrentGLContext()
{
- RefPtr<GraphicsContext3D> context = adoptRef(new GraphicsContext3D(Attributes(), 0, GraphicsContext3D::RenderToCurrentGLContext));
- return context->m_private ? context.release() : 0;
+ auto context = adoptRef(*new GraphicsContext3D({ }, 0, GraphicsContext3D::RenderToCurrentGLContext));
+#if USE(TEXTURE_MAPPER)
+ if (!context->m_texmapLayer)
+ return nullptr;
+#else
+ if (!context->m_private)
+ return nullptr;
+#endif
+ return WTFMove(context);
}
void GraphicsContext3D::validateDepthStencil(const char* packedDepthStencilExtension)
{
- Extensions3D* extensions = getExtensions();
+ Extensions3D& extensions = getExtensions();
if (m_attrs.stencil) {
- if (extensions->supports(packedDepthStencilExtension)) {
- extensions->ensureEnabled(packedDepthStencilExtension);
+ if (extensions.supports(packedDepthStencilExtension)) {
+ extensions.ensureEnabled(packedDepthStencilExtension);
// Force depth if stencil is true.
m_attrs.depth = true;
} else
m_attrs.stencil = false;
}
if (m_attrs.antialias) {
- if (!extensions->maySupportMultisampling() || !extensions->supports("GL_ANGLE_framebuffer_multisample") || isGLES2Compliant())
+ if (!extensions.supports("GL_ANGLE_framebuffer_multisample") || isGLES2Compliant())
m_attrs.antialias = false;
else
- extensions->ensureEnabled("GL_ANGLE_framebuffer_multisample");
+ extensions.ensureEnabled("GL_ANGLE_framebuffer_multisample");
}
}
-bool GraphicsContext3D::isResourceSafe()
-{
- return false;
-}
-
-void GraphicsContext3D::paintRenderingResultsToCanvas(ImageBuffer* imageBuffer, DrawingBuffer*)
+void GraphicsContext3D::paintRenderingResultsToCanvas(ImageBuffer* imageBuffer)
{
int rowBytes = m_currentWidth * 4;
int totalBytes = rowBytes * m_currentHeight;
@@ -165,8 +186,7 @@ void GraphicsContext3D::paintRenderingResultsToCanvas(ImageBuffer* imageBuffer,
paintToCanvas(pixels.get(), m_currentWidth, m_currentHeight,
imageBuffer->internalSize().width(), imageBuffer->internalSize().height(), imageBuffer->context());
#else
- paintToCanvas(pixels.get(), m_currentWidth, m_currentHeight,
- imageBuffer->internalSize().width(), imageBuffer->internalSize().height(), imageBuffer->context()->platformContext());
+ paintToCanvas(pixels.get(), m_currentWidth, m_currentHeight, imageBuffer->internalSize().width(), imageBuffer->internalSize().height(), imageBuffer->context().platformContext());
#endif
#if PLATFORM(IOS)
@@ -180,14 +200,14 @@ bool GraphicsContext3D::paintCompositedResultsToCanvas(ImageBuffer*)
return false;
}
-PassRefPtr<ImageData> GraphicsContext3D::paintRenderingResultsToImageData(DrawingBuffer*)
+RefPtr<ImageData> GraphicsContext3D::paintRenderingResultsToImageData()
{
// Reading premultiplied alpha would involve unpremultiplying, which is
// lossy.
if (m_attrs.premultipliedAlpha)
- return 0;
+ return nullptr;
- RefPtr<ImageData> imageData = ImageData::create(IntSize(m_currentWidth, m_currentHeight));
+ auto imageData = ImageData::create(IntSize(m_currentWidth, m_currentHeight));
unsigned char* pixels = imageData->data()->data();
int totalBytes = 4 * m_currentWidth * m_currentHeight;
@@ -197,7 +217,7 @@ PassRefPtr<ImageData> GraphicsContext3D::paintRenderingResultsToImageData(Drawin
for (int i = 0; i < totalBytes; i += 4)
std::swap(pixels[i], pixels[i + 2]);
- return imageData.release();
+ return imageData;
}
void GraphicsContext3D::prepareTexture()
@@ -207,12 +227,28 @@ void GraphicsContext3D::prepareTexture()
makeContextCurrent();
+#if !USE(COORDINATED_GRAPHICS_THREADED)
TemporaryOpenGLSetting scopedScissor(GL_SCISSOR_TEST, GL_FALSE);
TemporaryOpenGLSetting scopedDither(GL_DITHER, GL_FALSE);
-
+#endif
+
if (m_attrs.antialias)
resolveMultisamplingIfNecessary();
+#if USE(COORDINATED_GRAPHICS_THREADED)
+ std::swap(m_texture, m_compositorTexture);
+ std::swap(m_texture, m_intermediateTexture);
+ ::glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
+ ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0);
+ glFlush();
+
+ if (m_state.boundFBO != m_fbo)
+ ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_state.boundFBO);
+ else
+ ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_fbo);
+ return;
+#endif
+
::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_fbo);
::glActiveTexture(GL_TEXTURE0);
::glBindTexture(GL_TEXTURE_2D, m_compositorTexture);
@@ -221,8 +257,7 @@ void GraphicsContext3D::prepareTexture()
::glActiveTexture(m_state.activeTexture);
if (m_state.boundFBO != m_fbo)
::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_state.boundFBO);
- ::glFinish();
- m_layerComposited = true;
+ ::glFlush();
}
void GraphicsContext3D::readRenderingResults(unsigned char *pixels, int pixelsSize)
@@ -271,11 +306,6 @@ void GraphicsContext3D::reshape(int width, int height)
markContextChanged();
-#if PLATFORM(EFL) && USE(GRAPHICS_SURFACE)
- ::glFlush(); // Make sure all GL calls have been committed before resizing.
- createGraphicsSurfaces(IntSize(width, height));
-#endif
-
m_currentWidth = width;
m_currentHeight = height;
@@ -334,6 +364,49 @@ void GraphicsContext3D::reshape(int width, int height)
::glFlush();
}
+bool GraphicsContext3D::checkVaryingsPacking(Platform3DObject vertexShader, Platform3DObject fragmentShader) const
+{
+ ASSERT(m_shaderSourceMap.contains(vertexShader));
+ ASSERT(m_shaderSourceMap.contains(fragmentShader));
+ const auto& vertexEntry = m_shaderSourceMap.find(vertexShader)->value;
+ const auto& fragmentEntry = m_shaderSourceMap.find(fragmentShader)->value;
+
+ HashMap<String, sh::ShaderVariable> combinedVaryings;
+ for (const auto& vertexSymbol : vertexEntry.varyingMap) {
+ const String& symbolName = vertexSymbol.key;
+ // The varying map includes variables for each index of an array variable.
+ // We only want a single variable to represent the array.
+ if (symbolName.endsWith("]"))
+ continue;
+
+ // Don't count built in varyings.
+ if (symbolName == "gl_FragCoord" || symbolName == "gl_FrontFacing" || symbolName == "gl_PointCoord")
+ continue;
+
+ const auto& fragmentSymbol = fragmentEntry.varyingMap.find(symbolName);
+ if (fragmentSymbol != fragmentEntry.varyingMap.end())
+ combinedVaryings.add(symbolName, fragmentSymbol->value);
+ }
+
+ size_t numVaryings = combinedVaryings.size();
+ if (!numVaryings)
+ return true;
+
+ std::vector<sh::ShaderVariable> variables;
+ variables.reserve(combinedVaryings.size());
+ for (const auto& varyingSymbol : combinedVaryings.values())
+ variables.push_back(varyingSymbol);
+
+ GC3Dint maxVaryingVectors = 0;
+#if !PLATFORM(IOS) && !((PLATFORM(WIN) || PLATFORM(GTK)) && USE(OPENGL_ES_2))
+ GC3Dint maxVaryingFloats = 0;
+ ::glGetIntegerv(GL_MAX_VARYING_FLOATS, &maxVaryingFloats);
+ maxVaryingVectors = maxVaryingFloats / 4;
+#else
+ ::glGetIntegerv(MAX_VARYING_VECTORS, &maxVaryingVectors);
+#endif
+ return ShCheckVariablesWithinPackingLimits(maxVaryingVectors, variables);
+}
bool GraphicsContext3D::precisionsMatch(Platform3DObject vertexShader, Platform3DObject fragmentShader) const
{
@@ -342,13 +415,16 @@ bool GraphicsContext3D::precisionsMatch(Platform3DObject vertexShader, Platform3
const auto& vertexEntry = m_shaderSourceMap.find(vertexShader)->value;
const auto& fragmentEntry = m_shaderSourceMap.find(fragmentShader)->value;
- HashMap<String, ShPrecisionType> vertexSymbolPrecisionMap;
+ HashMap<String, sh::GLenum> vertexSymbolPrecisionMap;
- for (const auto& entry : vertexEntry.uniformMap)
- vertexSymbolPrecisionMap.add(entry.value.mappedName, entry.value.precision);
+ for (const auto& entry : vertexEntry.uniformMap) {
+ const std::string& mappedName = entry.value.mappedName;
+ vertexSymbolPrecisionMap.add(String(mappedName.c_str(), mappedName.length()), entry.value.precision);
+ }
for (const auto& entry : fragmentEntry.uniformMap) {
- const auto& vertexSymbol = vertexSymbolPrecisionMap.find(entry.value.mappedName);
+ const std::string& mappedName = entry.value.mappedName;
+ const auto& vertexSymbol = vertexSymbolPrecisionMap.find(String(mappedName.c_str(), mappedName.length()));
if (vertexSymbol != vertexSymbolPrecisionMap.end() && vertexSymbol->value != entry.value.precision)
return false;
}
@@ -373,6 +449,7 @@ void GraphicsContext3D::attachShader(Platform3DObject program, Platform3DObject
ASSERT(program);
ASSERT(shader);
makeContextCurrent();
+ m_shaderProgramSymbolCountMap.remove(program);
::glAttachShader(program, shader);
}
@@ -470,6 +547,38 @@ void GraphicsContext3D::bufferSubData(GC3Denum target, GC3Dintptr offset, GC3Dsi
::glBufferSubData(target, offset, size, data);
}
+#if PLATFORM(MAC) || PLATFORM(IOS)
+void* GraphicsContext3D::mapBufferRange(GC3Denum target, GC3Dintptr offset, GC3Dsizeiptr length, GC3Dbitfield access)
+{
+ makeContextCurrent();
+ return ::glMapBufferRange(target, offset, length, access);
+}
+
+GC3Dboolean GraphicsContext3D::unmapBuffer(GC3Denum target)
+{
+ makeContextCurrent();
+ return ::glUnmapBuffer(target);
+}
+
+void GraphicsContext3D::copyBufferSubData(GC3Denum readTarget, GC3Denum writeTarget, GC3Dintptr readOffset, GC3Dintptr writeOffset, GC3Dsizeiptr size)
+{
+ makeContextCurrent();
+ ::glCopyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size);
+}
+
+void GraphicsContext3D::texStorage2D(GC3Denum target, GC3Dsizei levels, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height)
+{
+ makeContextCurrent();
+ ::glTexStorage2D(target, levels, internalformat, width, height);
+}
+
+void GraphicsContext3D::texStorage3D(GC3Denum target, GC3Dsizei levels, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth)
+{
+ makeContextCurrent();
+ ::glTexStorage3D(target, levels, internalformat, width, height, depth);
+}
+#endif
+
GC3Denum GraphicsContext3D::checkFramebufferStatus(GC3Denum target)
{
makeContextCurrent();
@@ -512,15 +621,15 @@ void GraphicsContext3D::compileShader(Platform3DObject shader)
ANGLEResources.HashFunction = nameHashForShader;
if (!nameHashMapForShaders)
- nameHashMapForShaders = adoptPtr(new ShaderNameHash);
- currentNameHashMapForShader = nameHashMapForShaders.get();
+ nameHashMapForShaders = std::make_unique<ShaderNameHash>();
+ setCurrentNameHashMapForShader(nameHashMapForShaders.get());
m_compiler.setResources(ANGLEResources);
String translatedShaderSource = m_extensions->getTranslatedShaderSourceANGLE(shader);
ANGLEResources.HashFunction = previousHashFunction;
m_compiler.setResources(ANGLEResources);
- currentNameHashMapForShader = nullptr;
+ setCurrentNameHashMapForShader(nullptr);
if (!translatedShaderSource.length())
return;
@@ -560,8 +669,6 @@ void GraphicsContext3D::compileShader(Platform3DObject shader)
entry.isValid = false;
LOG(WebGL, "Error: shader translator produced a shader that OpenGL would not compile.");
}
-
- m_shaderSymbolCount = nullptr;
}
void GraphicsContext3D::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
@@ -611,6 +718,7 @@ void GraphicsContext3D::detachShader(Platform3DObject program, Platform3DObject
ASSERT(program);
ASSERT(shader);
makeContextCurrent();
+ m_shaderProgramSymbolCountMap.remove(program);
::glDetachShader(program, shader);
}
@@ -630,12 +738,14 @@ void GraphicsContext3D::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count
{
makeContextCurrent();
::glDrawArrays(mode, first, count);
+ checkGPUStatusIfNecessary();
}
void GraphicsContext3D::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset)
{
makeContextCurrent();
::glDrawElements(mode, count, type, reinterpret_cast<GLvoid*>(static_cast<intptr_t>(offset)));
+ checkGPUStatusIfNecessary();
}
void GraphicsContext3D::enable(GC3Denum cap)
@@ -718,8 +828,15 @@ bool GraphicsContext3D::getActiveAttribImpl(Platform3DObject program, GC3Duint i
bool GraphicsContext3D::getActiveAttrib(Platform3DObject program, GC3Duint index, ActiveInfo& info)
{
- ASSERT(!m_shaderSymbolCount || index < m_shaderSymbolCount->filteredToActualAttributeIndexMap.size());
- GC3Duint rawIndex = (m_shaderSymbolCount) ? m_shaderSymbolCount->filteredToActualAttributeIndexMap[index] : index;
+ GC3Dint symbolCount;
+ auto result = m_shaderProgramSymbolCountMap.find(program);
+ if (result == m_shaderProgramSymbolCountMap.end()) {
+ getNonBuiltInActiveSymbolCount(program, GraphicsContext3D::ACTIVE_ATTRIBUTES, &symbolCount);
+ result = m_shaderProgramSymbolCountMap.find(program);
+ }
+
+ ActiveShaderSymbolCounts& symbolCounts = result->value;
+ GC3Duint rawIndex = (index < symbolCounts.filteredToActualAttributeIndexMap.size()) ? symbolCounts.filteredToActualAttributeIndexMap[index] : -1;
return getActiveAttribImpl(program, rawIndex, info);
}
@@ -758,8 +875,15 @@ bool GraphicsContext3D::getActiveUniformImpl(Platform3DObject program, GC3Duint
bool GraphicsContext3D::getActiveUniform(Platform3DObject program, GC3Duint index, ActiveInfo& info)
{
- ASSERT(!m_shaderSymbolCount || index < m_shaderSymbolCount->filteredToActualUniformIndexMap.size());
- GC3Duint rawIndex = (m_shaderSymbolCount) ? m_shaderSymbolCount->filteredToActualUniformIndexMap[index] : index;
+ GC3Dint symbolCount;
+ auto result = m_shaderProgramSymbolCountMap.find(program);
+ if (result == m_shaderProgramSymbolCountMap.end()) {
+ getNonBuiltInActiveSymbolCount(program, GraphicsContext3D::ACTIVE_UNIFORMS, &symbolCount);
+ result = m_shaderProgramSymbolCountMap.find(program);
+ }
+
+ ActiveShaderSymbolCounts& symbolCounts = result->value;
+ GC3Duint rawIndex = (index < symbolCounts.filteredToActualUniformIndexMap.size()) ? symbolCounts.filteredToActualUniformIndexMap[index] : -1;
return getActiveUniformImpl(program, rawIndex, info);
}
@@ -774,10 +898,21 @@ void GraphicsContext3D::getAttachedShaders(Platform3DObject program, GC3Dsizei m
::glGetAttachedShaders(program, maxCount, count, shaders);
}
+static String generateHashedName(const String& name)
+{
+ if (name.isEmpty())
+ return name;
+ uint64_t number = nameHashForShader(name.utf8().data(), name.length());
+ StringBuilder builder;
+ builder.appendLiteral("webgl_");
+ appendUnsigned64AsHex(number, builder, Lowercase);
+ return builder.toString();
+}
+
String GraphicsContext3D::mappedSymbolName(Platform3DObject program, ANGLEShaderSymbolType symbolType, const String& name)
{
- GC3Dsizei count;
- Platform3DObject shaders[2];
+ GC3Dsizei count = 0;
+ Platform3DObject shaders[2] = { };
getAttachedShaders(program, 2, &count, shaders);
for (GC3Dsizei i = 0; i < count; ++i) {
@@ -787,9 +922,28 @@ String GraphicsContext3D::mappedSymbolName(Platform3DObject program, ANGLEShader
const ShaderSymbolMap& symbolMap = result->value.symbolMap(symbolType);
ShaderSymbolMap::const_iterator symbolEntry = symbolMap.find(name);
- if (symbolEntry != symbolMap.end())
- return symbolEntry->value.mappedName;
+ if (symbolEntry != symbolMap.end()) {
+ const std::string& mappedName = symbolEntry->value.mappedName;
+ return String(mappedName.c_str(), mappedName.length());
+ }
}
+
+ if (symbolType == SHADER_SYMBOL_TYPE_ATTRIBUTE && !name.isEmpty()) {
+ // Attributes are a special case: they may be requested before any shaders have been compiled,
+ // and aren't even required to be used in any shader program.
+ if (!nameHashMapForShaders)
+ nameHashMapForShaders = std::make_unique<ShaderNameHash>();
+ setCurrentNameHashMapForShader(nameHashMapForShaders.get());
+
+ String generatedName = generateHashedName(name);
+
+ setCurrentNameHashMapForShader(nullptr);
+
+ m_possiblyUnusedAttributeMap.set(generatedName, name);
+
+ return generatedName;
+ }
+
return name;
}
@@ -806,10 +960,20 @@ String GraphicsContext3D::originalSymbolName(Platform3DObject program, ANGLEShad
const ShaderSymbolMap& symbolMap = result->value.symbolMap(symbolType);
for (const auto& symbolEntry : symbolMap) {
- if (symbolEntry.value.mappedName == name)
+ if (name == symbolEntry.value.mappedName.c_str())
return symbolEntry.key;
}
}
+
+ if (symbolType == SHADER_SYMBOL_TYPE_ATTRIBUTE && !name.isEmpty()) {
+ // Attributes are a special case: they may be requested before any shaders have been compiled,
+ // and aren't even required to be used in any shader program.
+
+ const auto& cached = m_possiblyUnusedAttributeMap.find(name);
+ if (cached != m_possiblyUnusedAttributeMap.end())
+ return cached->value;
+ }
+
return name;
}
@@ -823,7 +987,7 @@ String GraphicsContext3D::mappedSymbolName(Platform3DObject shaders[2], size_t c
const ShaderSymbolMap& symbolMap = result->value.symbolMap(static_cast<enum ANGLEShaderSymbolType>(symbolType));
for (const auto& symbolEntry : symbolMap) {
- if (symbolEntry.value.mappedName == name)
+ if (name == symbolEntry.value.mappedName.c_str())
return symbolEntry.key;
}
}
@@ -843,18 +1007,38 @@ int GraphicsContext3D::getAttribLocation(Platform3DObject program, const String&
return ::glGetAttribLocation(program, mappedName.utf8().data());
}
-GraphicsContext3D::Attributes GraphicsContext3D::getContextAttributes()
+GraphicsContext3DAttributes GraphicsContext3D::getContextAttributes()
{
return m_attrs;
}
+bool GraphicsContext3D::moveErrorsToSyntheticErrorList()
+{
+ makeContextCurrent();
+ bool movedAnError = false;
+
+ // Set an arbitrary limit of 100 here to avoid creating a hang if
+ // a problem driver has a bug that causes it to never clear the error.
+ // Otherwise, we would just loop until we got NO_ERROR.
+ for (unsigned i = 0; i < 100; ++i) {
+ GC3Denum error = glGetError();
+ if (error == NO_ERROR)
+ break;
+ m_syntheticErrors.add(error);
+ movedAnError = true;
+ }
+
+ return movedAnError;
+}
+
GC3Denum GraphicsContext3D::getError()
{
- if (m_syntheticErrors.size() > 0) {
- ListHashSet<GC3Denum>::iterator iter = m_syntheticErrors.begin();
- GC3Denum err = *iter;
- m_syntheticErrors.remove(iter);
- return err;
+ if (!m_syntheticErrors.isEmpty()) {
+ // Need to move the current errors to the synthetic error list in case
+ // that error is already there, since the expected behavior of both
+ // glGetError and getError is to only report each error code once.
+ moveErrorsToSyntheticErrorList();
+ return m_syntheticErrors.takeFirst();
}
makeContextCurrent();
@@ -1228,6 +1412,57 @@ void GraphicsContext3D::viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsize
::glViewport(x, y, width, height);
}
+Platform3DObject GraphicsContext3D::createVertexArray()
+{
+ makeContextCurrent();
+ GLuint array = 0;
+#if !USE(OPENGL_ES_2) && (PLATFORM(GTK) || PLATFORM(WIN) || PLATFORM(IOS))
+ glGenVertexArrays(1, &array);
+#elif defined(GL_APPLE_vertex_array_object) && GL_APPLE_vertex_array_object
+ glGenVertexArraysAPPLE(1, &array);
+#endif
+ return array;
+}
+
+void GraphicsContext3D::deleteVertexArray(Platform3DObject array)
+{
+ if (!array)
+ return;
+
+ makeContextCurrent();
+#if !USE(OPENGL_ES_2) && (PLATFORM(GTK) || PLATFORM(WIN) || PLATFORM(IOS))
+ glDeleteVertexArrays(1, &array);
+#elif defined(GL_APPLE_vertex_array_object) && GL_APPLE_vertex_array_object
+ glDeleteVertexArraysAPPLE(1, &array);
+#endif
+}
+
+GC3Dboolean GraphicsContext3D::isVertexArray(Platform3DObject array)
+{
+ if (!array)
+ return GL_FALSE;
+
+ makeContextCurrent();
+#if !USE(OPENGL_ES_2) && (PLATFORM(GTK) || PLATFORM(WIN) || PLATFORM(IOS))
+ return glIsVertexArray(array);
+#elif defined(GL_APPLE_vertex_array_object) && GL_APPLE_vertex_array_object
+ return glIsVertexArrayAPPLE(array);
+#endif
+ return GL_FALSE;
+}
+
+void GraphicsContext3D::bindVertexArray(Platform3DObject array)
+{
+ makeContextCurrent();
+#if !USE(OPENGL_ES_2) && (PLATFORM(GTK) || PLATFORM(WIN) || PLATFORM(IOS))
+ glBindVertexArray(array);
+#elif defined(GL_APPLE_vertex_array_object) && GL_APPLE_vertex_array_object
+ glBindVertexArrayAPPLE(array);
+#else
+ UNUSED_PARAM(array);
+#endif
+}
+
void GraphicsContext3D::getBooleanv(GC3Denum pname, GC3Dboolean* value)
{
makeContextCurrent();
@@ -1245,6 +1480,15 @@ void GraphicsContext3D::getFloatv(GC3Denum pname, GC3Dfloat* value)
makeContextCurrent();
::glGetFloatv(pname, value);
}
+
+void GraphicsContext3D::getInteger64v(GC3Denum pname, GC3Dint64* value)
+{
+ UNUSED_PARAM(pname);
+ makeContextCurrent();
+ *value = 0;
+ // FIXME 141178: Before enabling this we must first switch over to using gl3.h and creating and initialing the WebGL2 context using OpenGL ES 3.0.
+ // ::glGetInteger64v(pname, value);
+}
void GraphicsContext3D::getFramebufferAttachmentParameteriv(GC3Denum target, GC3Denum attachment, GC3Denum pname, GC3Dint* value)
{
@@ -1267,13 +1511,14 @@ void GraphicsContext3D::getNonBuiltInActiveSymbolCount(Platform3DObject program,
return;
makeContextCurrent();
-
- if (m_shaderSymbolCount) {
- *value = m_shaderSymbolCount->countForType(pname);
+ const auto& result = m_shaderProgramSymbolCountMap.find(program);
+ if (result != m_shaderProgramSymbolCountMap.end()) {
+ *value = result->value.countForType(pname);
return;
}
- m_shaderSymbolCount = std::make_unique<ActiveShaderSymbolCounts>();
+ m_shaderProgramSymbolCountMap.set(program, ActiveShaderSymbolCounts());
+ ActiveShaderSymbolCounts& symbolCounts = m_shaderProgramSymbolCountMap.find(program)->value;
// Retrieve the active attributes, build a filtered count, and a mapping of
// our internal attributes indexes to the real unfiltered indexes inside OpenGL.
@@ -1285,7 +1530,7 @@ void GraphicsContext3D::getNonBuiltInActiveSymbolCount(Platform3DObject program,
if (info.name.startsWith("gl_"))
continue;
- m_shaderSymbolCount->filteredToActualAttributeIndexMap.append(i);
+ symbolCounts.filteredToActualAttributeIndexMap.append(i);
}
// Do the same for uniforms.
@@ -1297,10 +1542,10 @@ void GraphicsContext3D::getNonBuiltInActiveSymbolCount(Platform3DObject program,
if (info.name.startsWith("gl_"))
continue;
- m_shaderSymbolCount->filteredToActualUniformIndexMap.append(i);
+ symbolCounts.filteredToActualUniformIndexMap.append(i);
}
- *value = m_shaderSymbolCount->countForType(pname);
+ *value = symbolCounts.countForType(pname);
}
String GraphicsContext3D::getUnmangledInfoLog(Platform3DObject shaders[2], GC3Dsizei count, const String& log)
@@ -1309,7 +1554,7 @@ String GraphicsContext3D::getUnmangledInfoLog(Platform3DObject shaders[2], GC3Ds
JSC::Yarr::RegularExpression regExp("webgl_[0123456789abcdefABCDEF]+", TextCaseSensitive);
- String processedLog;
+ StringBuilder processedLog;
int startFrom = 0;
int matchedLength = 0;
@@ -1329,8 +1574,8 @@ String GraphicsContext3D::getUnmangledInfoLog(Platform3DObject shaders[2], GC3Ds
processedLog.append(log.substring(startFrom, log.length() - startFrom));
- LOG(WebGL, "-->: %s", processedLog.utf8().data());
- return processedLog;
+ LOG(WebGL, "-->: %s", processedLog.toString().utf8().data());
+ return processedLog.toString();
}
String GraphicsContext3D::getProgramInfoLog(Platform3DObject program)
@@ -1501,6 +1746,12 @@ void GraphicsContext3D::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xo
type = GL_HALF_FLOAT_ARB;
#endif
+ if (m_usingCoreProfile && format == ALPHA) {
+ // We are using a core profile. This means that GL_ALPHA, which is a valid format in WebGL for texSubImage2D
+ // is not supported in OpenGL. We are using GL_RED to back GL_ALPHA, so do it here as well.
+ format = RED;
+ }
+
// FIXME: we will need to deal with PixelStore params when dealing with image buffers that differ from the subimage size.
::glTexSubImage2D(target, level, xoff, yoff, width, height, format, type, pixels);
}
@@ -1606,6 +1857,10 @@ void GraphicsContext3D::deleteTexture(Platform3DObject texture)
void GraphicsContext3D::synthesizeGLError(GC3Denum error)
{
+ // Need to move the current errors to the synthetic error list to
+ // preserve the order of errors, so a caller to getError will get
+ // any errors from glError before the error we are synthesizing.
+ moveErrorsToSyntheticErrorList();
m_syntheticErrors.add(error);
}
@@ -1624,12 +1879,43 @@ bool GraphicsContext3D::layerComposited() const
return m_layerComposited;
}
+void GraphicsContext3D::forceContextLost()
+{
+#if ENABLE(WEBGL)
+ if (m_webglContext)
+ m_webglContext->forceLostContext(WebGLRenderingContextBase::RealLostContext);
+#endif
+}
+
+void GraphicsContext3D::recycleContext()
+{
+#if ENABLE(WEBGL)
+ if (m_webglContext)
+ m_webglContext->recycleContext();
+#endif
+}
+
void GraphicsContext3D::texImage2DDirect(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels)
{
makeContextCurrent();
::glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
}
+void GraphicsContext3D::drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount)
+{
+ getExtensions().drawArraysInstanced(mode, first, count, primcount);
+}
+
+void GraphicsContext3D::drawElementsInstanced(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset, GC3Dsizei primcount)
+{
+ getExtensions().drawElementsInstanced(mode, count, type, offset, primcount);
+}
+
+void GraphicsContext3D::vertexAttribDivisor(GC3Duint index, GC3Duint divisor)
+{
+ getExtensions().vertexAttribDivisor(index, divisor);
+}
+
}
-#endif // USE(3D_GRAPHICS)
+#endif // ENABLE(GRAPHICS_CONTEXT_3D)
diff --git a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp
index 546b2d433..6b608c66d 100644
--- a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp
+++ b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp
@@ -13,10 +13,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -28,7 +28,7 @@
#include "config.h"
-#if USE(3D_GRAPHICS)
+#if ENABLE(GRAPHICS_CONTEXT_3D)
#include "GraphicsContext3D.h"
@@ -37,6 +37,12 @@
#include "IntSize.h"
#include "NotImplemented.h"
+#if PLATFORM(WIN)
+#include <GLSLANG/ShaderLang.h>
+#else
+#include <ANGLE/ShaderLang.h>
+#endif
+
namespace WebCore {
void GraphicsContext3D::releaseShaderCompiler()
@@ -90,7 +96,7 @@ bool GraphicsContext3D::reshapeFBOs(const IntSize& size)
// We don't allow the logic where stencil is required and depth is not.
// See GraphicsContext3D::validateAttributes.
- bool supportPackedDepthStencilBuffer = (m_attrs.stencil || m_attrs.depth) && getExtensions()->supports("GL_OES_packed_depth_stencil");
+ bool supportPackedDepthStencilBuffer = (m_attrs.stencil || m_attrs.depth) && getExtensions().supports("GL_OES_packed_depth_stencil");
// Resize regular FBO.
bool mustRestoreFBO = false;
@@ -110,29 +116,64 @@ bool GraphicsContext3D::reshapeFBOs(const IntSize& size)
::glBindTexture(GL_TEXTURE_2D, 0);
}
- // We don't support antialiasing yet. See GraphicsContext3D::validateAttributes.
- ASSERT(!m_attrs.antialias);
-
- if (m_attrs.stencil || m_attrs.depth) {
- // Use a 24 bit depth buffer where we know we have it.
- if (supportPackedDepthStencilBuffer) {
- ::glBindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer);
- ::glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height);
- if (m_attrs.stencil)
- ::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilBuffer);
- if (m_attrs.depth)
- ::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilBuffer);
- ::glBindRenderbuffer(GL_RENDERBUFFER, 0);
- } else {
- if (m_attrs.stencil) {
- ::glBindRenderbuffer(GL_RENDERBUFFER, m_stencilBuffer);
- ::glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, width, height);
- ::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_stencilBuffer);
+#if USE(COORDINATED_GRAPHICS_THREADED)
+ ::glBindTexture(GL_TEXTURE_2D, m_intermediateTexture);
+ ::glTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
+ ::glBindTexture(GL_TEXTURE_2D, 0);
+#endif
+
+ Extensions3DOpenGLES& extensions = static_cast<Extensions3DOpenGLES&>(getExtensions());
+ if (extensions.isImagination() && m_attrs.antialias) {
+ GLint maxSampleCount;
+ ::glGetIntegerv(Extensions3D::MAX_SAMPLES_IMG, &maxSampleCount);
+ GLint sampleCount = std::min(8, maxSampleCount);
+
+ extensions.framebufferTexture2DMultisampleIMG(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0, sampleCount);
+
+ if (m_attrs.stencil || m_attrs.depth) {
+ // Use a 24 bit depth buffer where we know we have it.
+ if (supportPackedDepthStencilBuffer) {
+ ::glBindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer);
+ extensions.renderbufferStorageMultisample(GL_RENDERBUFFER, sampleCount, GL_DEPTH24_STENCIL8_OES, width, height);
+ if (m_attrs.stencil)
+ ::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilBuffer);
+ if (m_attrs.depth)
+ ::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilBuffer);
+ } else {
+ if (m_attrs.stencil) {
+ ::glBindRenderbuffer(GL_RENDERBUFFER, m_stencilBuffer);
+ extensions.renderbufferStorageMultisample(GL_RENDERBUFFER, sampleCount, GL_STENCIL_INDEX8, width, height);
+ ::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_stencilBuffer);
+ }
+ if (m_attrs.depth) {
+ ::glBindRenderbuffer(GL_RENDERBUFFER, m_depthBuffer);
+ extensions.renderbufferStorageMultisample(GL_RENDERBUFFER, sampleCount, GL_DEPTH_COMPONENT16, width, height);
+ ::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthBuffer);
+ }
}
- if (m_attrs.depth) {
- ::glBindRenderbuffer(GL_RENDERBUFFER, m_depthBuffer);
- ::glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
- ::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthBuffer);
+ ::glBindRenderbuffer(GL_RENDERBUFFER, 0);
+ }
+ } else {
+ if (m_attrs.stencil || m_attrs.depth) {
+ // Use a 24 bit depth buffer where we know we have it.
+ if (supportPackedDepthStencilBuffer) {
+ ::glBindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer);
+ ::glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height);
+ if (m_attrs.stencil)
+ ::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilBuffer);
+ if (m_attrs.depth)
+ ::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilBuffer);
+ } else {
+ if (m_attrs.stencil) {
+ ::glBindRenderbuffer(GL_RENDERBUFFER, m_stencilBuffer);
+ ::glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, width, height);
+ ::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_stencilBuffer);
+ }
+ if (m_attrs.depth) {
+ ::glBindRenderbuffer(GL_RENDERBUFFER, m_depthBuffer);
+ ::glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
+ ::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthBuffer);
+ }
}
::glBindRenderbuffer(GL_RENDERBUFFER, 0);
}
@@ -145,7 +186,7 @@ bool GraphicsContext3D::reshapeFBOs(const IntSize& size)
return mustRestoreFBO;
}
-void GraphicsContext3D::resolveMultisamplingIfNecessary(const IntRect& rect)
+void GraphicsContext3D::resolveMultisamplingIfNecessary(const IntRect&)
{
// FIXME: We don't support antialiasing yet.
notImplemented();
@@ -187,11 +228,8 @@ void GraphicsContext3D::validateAttributes()
{
validateDepthStencil("GL_OES_packed_depth_stencil");
- if (m_attrs.antialias) {
- Extensions3D* extensions = getExtensions();
- if (!extensions->supports("GL_IMG_multisampled_render_to_texture"))
- m_attrs.antialias = false;
- }
+ if (m_attrs.antialias && !getExtensions().supports("GL_IMG_multisampled_render_to_texture"))
+ m_attrs.antialias = false;
}
void GraphicsContext3D::depthRange(GC3Dclampf zNear, GC3Dclampf zFar)
@@ -206,36 +244,171 @@ void GraphicsContext3D::clearDepth(GC3Dclampf depth)
::glClearDepthf(depth);
}
-void GraphicsContext3D::drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount)
+#if !PLATFORM(GTK)
+Extensions3D& GraphicsContext3D::getExtensions()
+{
+ if (!m_extensions)
+ m_extensions = std::make_unique<Extensions3DOpenGLES>(this, isGLES2Compliant());
+ return *m_extensions;
+}
+#endif
+
+#if PLATFORM(WIN) && !USE(CAIRO)
+RefPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3DAttributes attributes, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle)
{
- UNUSED_PARAM(mode);
- UNUSED_PARAM(first);
- UNUSED_PARAM(count);
- UNUSED_PARAM(primcount);
+ // This implementation doesn't currently support rendering directly to the HostWindow.
+ if (renderStyle == RenderDirectlyToHostWindow)
+ return nullptr;
+
+ static bool initialized = false;
+ static bool success = true;
+ if (!initialized) {
+#if !USE(OPENGL_ES_2)
+ success = initializeOpenGLShims();
+#endif
+ initialized = true;
+ }
+ if (!success)
+ return nullptr;
+
+ return adoptRef(new GraphicsContext3D(attributes, hostWindow, renderStyle));
}
-void GraphicsContext3D::drawElementsInstanced(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset, GC3Dsizei primcount)
+GraphicsContext3D::GraphicsContext3D(GraphicsContext3DAttributes attributes, HostWindow*, GraphicsContext3D::RenderStyle renderStyle)
+ : m_currentWidth(0)
+ , m_currentHeight(0)
+ , m_compiler(isGLES2Compliant() ? SH_ESSL_OUTPUT : SH_GLSL_COMPATIBILITY_OUTPUT)
+ , m_attrs(attributes)
+ , m_texture(0)
+ , m_fbo(0)
+ , m_depthStencilBuffer(0)
+ , m_multisampleFBO(0)
+ , m_multisampleDepthStencilBuffer(0)
+ , m_multisampleColorBuffer(0)
+ , m_private(std::make_unique<GraphicsContext3DPrivate>(this, renderStyle))
{
- UNUSED_PARAM(mode);
- UNUSED_PARAM(count);
- UNUSED_PARAM(type);
- UNUSED_PARAM(offset);
- UNUSED_PARAM(primcount);
+ makeContextCurrent();
+
+ validateAttributes();
+
+ if (renderStyle == RenderOffscreen) {
+ // Create a texture to render into.
+ ::glGenTextures(1, &m_texture);
+ ::glBindTexture(GL_TEXTURE_2D, m_texture);
+ ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ ::glBindTexture(GL_TEXTURE_2D, 0);
+
+ // Create an FBO.
+ ::glGenFramebuffers(1, &m_fbo);
+ ::glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
+
+ m_state.boundFBO = m_fbo;
+ if (!m_attrs.antialias && (m_attrs.stencil || m_attrs.depth))
+ ::glGenRenderbuffers(1, &m_depthStencilBuffer);
+
+ // Create a multisample FBO.
+ if (m_attrs.antialias) {
+ ::glGenFramebuffers(1, &m_multisampleFBO);
+ ::glBindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO);
+ m_state.boundFBO = m_multisampleFBO;
+ ::glGenRenderbuffers(1, &m_multisampleColorBuffer);
+ if (m_attrs.stencil || m_attrs.depth)
+ ::glGenRenderbuffers(1, &m_multisampleDepthStencilBuffer);
+ }
+ }
+
+ // ANGLE initialization.
+ ShBuiltInResources ANGLEResources;
+ ShInitBuiltInResources(&ANGLEResources);
+
+ getIntegerv(GraphicsContext3D::MAX_VERTEX_ATTRIBS, &ANGLEResources.MaxVertexAttribs);
+ getIntegerv(GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS, &ANGLEResources.MaxVertexUniformVectors);
+ getIntegerv(GraphicsContext3D::MAX_VARYING_VECTORS, &ANGLEResources.MaxVaryingVectors);
+ getIntegerv(GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxVertexTextureImageUnits);
+ getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxCombinedTextureImageUnits);
+ getIntegerv(GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxTextureImageUnits);
+ getIntegerv(GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS, &ANGLEResources.MaxFragmentUniformVectors);
+
+ // Always set to 1 for OpenGL ES.
+ ANGLEResources.MaxDrawBuffers = 1;
+
+ GC3Dint range[2], precision;
+ getShaderPrecisionFormat(GraphicsContext3D::FRAGMENT_SHADER, GraphicsContext3D::HIGH_FLOAT, range, &precision);
+ ANGLEResources.FragmentPrecisionHigh = (range[0] || range[1] || precision);
+
+ m_compiler.setResources(ANGLEResources);
+
+#if !USE(OPENGL_ES_2)
+ ::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
+ ::glEnable(GL_POINT_SPRITE);
+#endif
+
+ ::glClearColor(0, 0, 0, 0);
}
-void GraphicsContext3D::vertexAttribDivisor(GC3Duint index, GC3Duint divisor)
+GraphicsContext3D::~GraphicsContext3D()
{
- UNUSED_PARAM(index);
- UNUSED_PARAM(divisor);
+ makeContextCurrent();
+ ::glDeleteTextures(1, &m_texture);
+ if (m_attrs.antialias) {
+ ::glDeleteRenderbuffers(1, &m_multisampleColorBuffer);
+ if (m_attrs.stencil || m_attrs.depth)
+ ::glDeleteRenderbuffers(1, &m_multisampleDepthStencilBuffer);
+ ::glDeleteFramebuffers(1, &m_multisampleFBO);
+ } else {
+ if (m_attrs.stencil || m_attrs.depth)
+ ::glDeleteRenderbuffers(1, &m_depthStencilBuffer);
+ }
+ ::glDeleteFramebuffers(1, &m_fbo);
}
-Extensions3D* GraphicsContext3D::getExtensions()
+void GraphicsContext3D::setContextLostCallback(std::unique_ptr<ContextLostCallback>)
{
- if (!m_extensions)
- m_extensions = adoptPtr(new Extensions3DOpenGLES(this));
- return m_extensions.get();
}
+void GraphicsContext3D::setErrorMessageCallback(std::unique_ptr<ErrorMessageCallback>)
+{
+}
+
+bool GraphicsContext3D::makeContextCurrent()
+{
+ if (!m_private)
+ return false;
+ return m_private->makeContextCurrent();
+}
+
+void GraphicsContext3D::checkGPUStatusIfNecessary()
+{
+}
+
+PlatformGraphicsContext3D GraphicsContext3D::platformGraphicsContext3D()
+{
+ return m_private->platformContext();
+}
+
+Platform3DObject GraphicsContext3D::platformTexture() const
+{
+ return m_texture;
+}
+
+bool GraphicsContext3D::isGLES2Compliant() const
+{
+#if USE(OPENGL_ES_2)
+ return true;
+#else
+ return false;
+#endif
+}
+
+PlatformLayer* GraphicsContext3D::platformLayer() const
+{
+ return m_webGLLayer->platformLayer();
+}
+#endif
+
}
-#endif // USE(3D_GRAPHICS)
+#endif // ENABLE(GRAPHICS_CONTEXT_3D)
diff --git a/Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.cpp b/Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.cpp
index a0163770c..7438d9e14 100644
--- a/Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.cpp
+++ b/Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.cpp
@@ -26,7 +26,7 @@
#include "config.h"
-#if USE(3D_GRAPHICS)
+#if ENABLE(GRAPHICS_CONTEXT_3D)
#include "TemporaryOpenGLSetting.h"
#if USE(OPENGL_ES_2)
@@ -36,7 +36,7 @@
#include <OpenGLES/ES2/gl.h>
#elif PLATFORM(MAC)
#include <OpenGL/gl.h>
-#elif PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN)
+#elif PLATFORM(GTK) || PLATFORM(WIN)
#include "OpenGLShims.h"
#endif
diff --git a/Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.h b/Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.h
index 833f8b6be..cb51695b7 100644
--- a/Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.h
+++ b/Source/WebCore/platform/graphics/opengl/TemporaryOpenGLSetting.h
@@ -38,7 +38,7 @@ namespace WebCore {
// value upon destruction, making it an alternative to checking, clearing, and resetting each flag
// at all of a block's exit points.
//
-// Based on WTF::TemporaryChange<>
+// Based on WTF::SetForScope<>
class TemporaryOpenGLSetting {
WTF_MAKE_NONCOPYABLE(TemporaryOpenGLSetting);