summaryrefslogtreecommitdiffstats
path: root/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp')
-rw-r--r--WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp117
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;