diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp')
-rw-r--r-- | Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp | 275 |
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) |