summaryrefslogtreecommitdiff
path: root/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp')
-rw-r--r--Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp275
1 files changed, 224 insertions, 51 deletions
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)