diff options
Diffstat (limited to 'WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp')
-rw-r--r-- | WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp | 117 |
1 files changed, 83 insertions, 34 deletions
diff --git a/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp b/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp index 4cb701f..bd070c6 100644 --- a/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp +++ b/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp @@ -36,6 +36,7 @@ #include "app/gfx/gl/gl_bindings.h" #include "app/gfx/gl/gl_context.h" +#include "app/gfx/gl/gl_implementation.h" #include "NotImplemented.h" #include "WebView.h" #include <wtf/OwnArrayPtr.h> @@ -69,6 +70,10 @@ WebGraphicsContext3DDefaultImpl::VertexAttribPointerState::VertexAttribPointerSt WebGraphicsContext3DDefaultImpl::WebGraphicsContext3DDefaultImpl() : m_initialized(false) , m_renderDirectlyToWebView(false) + , m_isGLES2(false) + , m_haveEXTFramebufferObject(false) + , m_haveEXTFramebufferMultisample(false) + , m_haveANGLEFramebufferMultisample(false) , m_texture(0) , m_fbo(0) , m_depthStencilBuffer(0) @@ -166,10 +171,18 @@ bool WebGraphicsContext3DDefaultImpl::initialize(WebGraphicsContext3D::Attribute if (renderDirectlyToWebView) m_attributes.antialias = false; + m_isGLES2 = gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2; + const char* extensions = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)); + m_haveEXTFramebufferObject = strstr(extensions, "GL_EXT_framebuffer_object"); + m_haveEXTFramebufferMultisample = strstr(extensions, "GL_EXT_framebuffer_multisample"); + m_haveANGLEFramebufferMultisample = strstr(extensions, "GL_ANGLE_framebuffer_multisample"); + validateAttributes(); - glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); - glEnable(GL_POINT_SPRITE); + if (!m_isGLES2) { + glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); + glEnable(GL_POINT_SPRITE); + } if (!angleCreateCompilers()) { angleDestroyCompilers(); @@ -187,7 +200,8 @@ void WebGraphicsContext3DDefaultImpl::validateAttributes() const char* extensions = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)); if (m_attributes.stencil) { - if (strstr(extensions, "GL_EXT_packed_depth_stencil")) { + if (strstr(extensions, "GL_OES_packed_depth_stencil") + || strstr(extensions, "GL_EXT_packed_depth_stencil")) { if (!m_attributes.depth) m_attributes.depth = true; } else @@ -201,7 +215,9 @@ void WebGraphicsContext3DDefaultImpl::validateAttributes() if (!strstr(vendor, "NVIDIA")) isValidVendor = false; #endif - if (!isValidVendor || !strstr(extensions, "GL_EXT_framebuffer_multisample")) + if (!(isValidVendor + && (m_haveEXTFramebufferMultisample + || (m_haveANGLEFramebufferMultisample && strstr(extensions, "GL_OES_rgb8_rgba8"))))) m_attributes.antialias = false; // Don't antialias when using Mesa to ensure more reliable testing and @@ -220,7 +236,12 @@ void WebGraphicsContext3DDefaultImpl::resolveMultisampledFramebuffer(unsigned x, if (m_attributes.antialias) { glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); - glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR); + if (m_haveEXTFramebufferMultisample) + glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_NEAREST); + else { + ASSERT(m_haveANGLEFramebufferMultisample); + glBlitFramebufferANGLE(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_NEAREST); + } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); } } @@ -263,17 +284,7 @@ int WebGraphicsContext3DDefaultImpl::sizeInBytes(int type) bool WebGraphicsContext3DDefaultImpl::isGLES2Compliant() { - return false; -} - -bool WebGraphicsContext3DDefaultImpl::isGLES2NPOTStrict() -{ - return false; -} - -bool WebGraphicsContext3DDefaultImpl::isErrorGeneratedOnOutOfBoundsAccesses() -{ - return false; + return m_isGLES2; } unsigned int WebGraphicsContext3DDefaultImpl::getPlatformTextureId() @@ -328,12 +339,16 @@ void WebGraphicsContext3DDefaultImpl::reshape(int width, int height) } } - GLint internalColorFormat, colorFormat, internalDepthStencilFormat = 0; + GLint internalMultisampledColorFormat, internalColorFormat, colorFormat, internalDepthStencilFormat = 0; if (m_attributes.alpha) { - internalColorFormat = GL_RGBA8; + // GL_RGBA8_OES == GL_RGBA8 + internalMultisampledColorFormat = GL_RGBA8; + internalColorFormat = m_isGLES2 ? GL_RGBA : GL_RGBA8; colorFormat = GL_RGBA; } else { - internalColorFormat = GL_RGB8; + // GL_RGB8_OES == GL_RGB8 + internalMultisampledColorFormat = GL_RGB8; + internalColorFormat = m_isGLES2 ? GL_RGB : GL_RGB8; colorFormat = GL_RGB; } if (m_attributes.stencil || m_attributes.depth) { @@ -341,8 +356,12 @@ void WebGraphicsContext3DDefaultImpl::reshape(int width, int height) // See GraphicsContext3DInternal constructor. if (m_attributes.stencil && m_attributes.depth) internalDepthStencilFormat = GL_DEPTH24_STENCIL8_EXT; - else - internalDepthStencilFormat = GL_DEPTH_COMPONENT; + else { + if (m_isGLES2) + internalDepthStencilFormat = GL_DEPTH_COMPONENT16; + else + internalDepthStencilFormat = GL_DEPTH_COMPONENT; + } } bool mustRestoreFBO = false; @@ -357,11 +376,21 @@ void WebGraphicsContext3DDefaultImpl::reshape(int width, int height) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); } glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleColorBuffer); - glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalColorFormat, width, height); + if (m_haveEXTFramebufferMultisample) + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalMultisampledColorFormat, width, height); + else { + ASSERT(m_haveANGLEFramebufferMultisample); + glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER_EXT, sampleCount, internalMultisampledColorFormat, width, height); + } glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_multisampleColorBuffer); if (m_attributes.stencil || m_attributes.depth) { glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); - glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, width, height); + if (m_haveEXTFramebufferMultisample) + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, width, height); + else { + ASSERT(m_haveANGLEFramebufferMultisample); + glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, width, height); + } if (m_attributes.stencil) glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); if (m_attributes.depth) @@ -508,9 +537,15 @@ bool WebGraphicsContext3DDefaultImpl::readBackFramebuffer(unsigned char* pixels, mustRestorePackAlignment = true; } - // FIXME: OpenGL ES 2 does not support GL_BGRA so this fails when - // using that backend. - glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_BGRA, GL_UNSIGNED_BYTE, pixels); + if (m_isGLES2) { + // FIXME: consider testing for presence of GL_OES_read_format + // and GL_EXT_read_format_bgra, and using GL_BGRA_EXT here + // directly. + glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + for (size_t i = 0; i < bufferSize; i += 4) + std::swap(pixels[i], pixels[i + 2]); + } else + glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_BGRA, GL_UNSIGNED_BYTE, pixels); if (mustRestorePackAlignment) glPixelStorei(GL_PACK_ALIGNMENT, packAlignment); @@ -845,7 +880,7 @@ DELEGATE_TO_GL_1(frontFace, FrontFace, unsigned long) void WebGraphicsContext3DDefaultImpl::generateMipmap(unsigned long target) { makeContextCurrent(); - if (glGenerateMipmapEXT) + if (m_isGLES2 || m_haveEXTFramebufferObject) glGenerateMipmapEXT(target); // FIXME: provide alternative code path? This will be unpleasant // to implement if glGenerateMipmapEXT is not available -- it will @@ -951,11 +986,15 @@ void WebGraphicsContext3DDefaultImpl::getFramebufferAttachmentParameteriv(unsign void WebGraphicsContext3DDefaultImpl::getIntegerv(unsigned long pname, int* value) { + makeContextCurrent(); + if (m_isGLES2) { + glGetIntegerv(pname, value); + return; + } // Need to emulate MAX_FRAGMENT/VERTEX_UNIFORM_VECTORS and MAX_VARYING_VECTORS // because desktop GL's corresponding queries return the number of components // whereas GLES2 return the number of vectors (each vector has 4 components). // Therefore, the value returned by desktop GL needs to be divided by 4. - makeContextCurrent(); switch (pname) { case MAX_FRAGMENT_UNIFORM_VECTORS: glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, value); @@ -1096,10 +1135,10 @@ WebString WebGraphicsContext3DDefaultImpl::getString(unsigned long name) StringBuilder result; result.append(reinterpret_cast<const char*>(glGetString(name))); if (name == GL_EXTENSIONS) { - // GL_CHROMIUM_copy_texture_to_parent_texture requires this - // desktopGL-only function (GLES2 doesn't support it), so - // check for its existence here. - if (glGetTexLevelParameteriv) + // GL_CHROMIUM_copy_texture_to_parent_texture requires the + // desktopGL-only function glGetTexLevelParameteriv (GLES2 + // doesn't support it). + if (!m_isGLES2) result.append(" GL_CHROMIUM_copy_texture_to_parent_texture"); } return WebString(result.toString()); @@ -1551,11 +1590,21 @@ bool WebGraphicsContext3DDefaultImpl::angleValidateShaderSource(ShaderSourceEntr } int length = 0; - ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &length); + if (m_isGLES2) { + // ANGLE does not yet have a GLSL ES backend. Therefore if the + // compile succeeds we send the original source down. + length = strlen(entry.source); + if (length > 0) + ++length; // Add null terminator + } else + ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &length); if (length > 1) { if (!tryFastMalloc(length * sizeof(char)).getValue(entry.translatedSource)) return false; - ShGetObjectCode(compiler, entry.translatedSource); + if (m_isGLES2) + strncpy(entry.translatedSource, entry.source, length); + else + ShGetObjectCode(compiler, entry.translatedSource); } entry.isValid = true; return true; |