summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gpu/GLES2/extensions/CHROMIUM/CHROMIUM_color_buffer_float_rgb.txt64
-rw-r--r--gpu/GLES2/extensions/CHROMIUM/CHROMIUM_color_buffer_float_rgba.txt64
-rw-r--r--gpu/GLES2/gl2extchromium.h14
-rw-r--r--gpu/command_buffer/service/context_group_unittest.cc4
-rw-r--r--gpu/command_buffer/service/feature_info.cc90
-rw-r--r--gpu/command_buffer/service/feature_info.h2
-rw-r--r--gpu/command_buffer/service/feature_info_unittest.cc17
-rw-r--r--gpu/command_buffer/service/framebuffer_manager_unittest.cc153
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc26
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc72
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc47
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h6
-rw-r--r--gpu/command_buffer/service/test_helper.cc82
-rw-r--r--gpu/command_buffer/service/test_helper.h3
-rw-r--r--gpu/command_buffer/service/texture_manager.cc78
-rw-r--r--gpu/command_buffer/service/texture_manager.h11
-rw-r--r--gpu/command_buffer/service/texture_manager_unittest.cc27
-rw-r--r--ui/gl/gl_context.cc10
-rw-r--r--ui/gl/gl_context.h9
-rw-r--r--ui/gl/gl_context_stub.cc4
-rw-r--r--ui/gl/gl_context_stub.h1
-rw-r--r--ui/gl/gl_gl_api_implementation.cc33
-rw-r--r--ui/gl/gl_version_info.cc8
-rw-r--r--ui/gl/gl_version_info.h4
24 files changed, 678 insertions, 151 deletions
diff --git a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_color_buffer_float_rgb.txt b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_color_buffer_float_rgb.txt
new file mode 100644
index 0000000..7f22008
--- /dev/null
+++ b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_color_buffer_float_rgb.txt
@@ -0,0 +1,64 @@
+Name
+
+ CHROMIUM_color_buffer_float_rgb
+
+Name Strings
+
+ GL_CHROMIUM_color_buffer_float_rgb
+
+Version
+
+ Last Modifed Date: February 7, 2014
+
+Dependencies
+
+ This extension is written against the OpenGL ES 2.0 specification.
+
+ OpenGL ES 2.0 is required.
+
+ OES_texture_float is required.
+
+Overview
+
+ This extension implements a subset of ARB_color_buffer_float on top of
+ OpenGL ES 2.0.
+
+ This extension enables rendering to floating point RGB textures. When
+ this extension is enabled:
+
+ * The 32-bit floating point type GL_RGB32F becomes available as a
+ color-renderable internal format. Textures created with type = FLOAT,
+ and internal format GL_RGB32F, can be attached to framebuffer object
+ color attachments for rendering.
+
+ * GL_RGB / GL_RGB32F becomes an allowable format / internalformat parameter
+ pair for TexImage2D. The restriction in section 3.7.1 of the OpenGL ES
+ 2.0 spec that the internalformat parameter and format parameter of
+ TexImage2D must match is lifted for this case.
+
+ Floating point RGB textures may still be created also with the unsized
+ GL_RGB internal format, but whether such textures are renderable is not
+ guaranteed.
+
+New Tokens
+
+ Accepted by the <internalformat> parameter of TexImage2D:
+
+ GL_RGB32F 0x8815
+
+New Procedures and Functions
+
+ None.
+
+Errors
+
+ None.
+
+New State
+
+ None.
+
+Revision History
+
+ 2/7/2014 Documented the extension
+
diff --git a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_color_buffer_float_rgba.txt b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_color_buffer_float_rgba.txt
new file mode 100644
index 0000000..d52bab851
--- /dev/null
+++ b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_color_buffer_float_rgba.txt
@@ -0,0 +1,64 @@
+Name
+
+ CHROMIUM_color_buffer_float_rgba
+
+Name Strings
+
+ GL_CHROMIUM_color_buffer_float_rgba
+
+Version
+
+ Last Modifed Date: February 7, 2014
+
+Dependencies
+
+ This extension is written against the OpenGL ES 2.0 specification.
+
+ OpenGL ES 2.0 is required.
+
+ OES_texture_float is required.
+
+Overview
+
+ This extension implements a subset of EXT_color_buffer_float on top of
+ OpenGL ES 2.0.
+
+ This extension enables rendering to floating point RGBA textures. When
+ this extension is enabled:
+
+ * The 32-bit floating point type GL_RGBA32F becomes available as a
+ color-renderable internal format. Textures created with type = FLOAT,
+ and internal format GL_RGBA32F, can be attached to framebuffer object
+ color attachments for rendering.
+
+ * GL_RGBA / GL_RGBA32F becomes an allowable format / internalformat
+ parameter pair for TexImage2D. The restriction in section 3.7.1 of the
+ OpenGL ES 2.0 spec that the internalformat parameter and format parameter
+ of TexImage2D must match is lifted for this case.
+
+ Floating point RGBA textures may still be created also with the unsized
+ GL_RGBA internal format, but whether such textures are renderable is not
+ guaranteed.
+
+New Tokens
+
+ Accepted by the <internalformat> parameter of TexImage2D:
+
+ GL_RGBA32F 0x8814
+
+New Procedures and Functions
+
+ None.
+
+Errors
+
+ None.
+
+New State
+
+ None.
+
+Revision History
+
+ 2/7/2014 Documented the extension
+
diff --git a/gpu/GLES2/gl2extchromium.h b/gpu/GLES2/gl2extchromium.h
index 11db4b7..50a6247 100644
--- a/gpu/GLES2/gl2extchromium.h
+++ b/gpu/GLES2/gl2extchromium.h
@@ -618,6 +618,20 @@ typedef GLuint (GL_APIENTRYP PFNGLINSERTSYNCPOINTCHROMIUMPROC) ();
typedef void (GL_APIENTRYP PFNGLWAITSYNCPOINTCHROMIUMPROC) (GLuint sync_point);
#endif /* GL_CHROMIUM_sync_point */
+#ifndef GL_CHROMIUM_color_buffer_float_rgba
+#define GL_CHROMIUM_color_buffer_float_rgba 1
+#ifndef GL_RGBA32F
+#define GL_RGBA32F 0x8814
+#endif
+#endif /* GL_CHROMIUM_color_buffer_float_rgba */
+
+#ifndef GL_CHROMIUM_color_buffer_float_rgb
+#define GL_CHROMIUM_color_buffer_float_rgb 1
+#ifndef GL_RGB32F
+#define GL_RGB32F 0x8815
+#endif
+#endif /* GL_CHROMIUM_color_buffer_float_rgb */
+
#ifdef __cplusplus
}
#endif
diff --git a/gpu/command_buffer/service/context_group_unittest.cc b/gpu/command_buffer/service/context_group_unittest.cc
index 3cce29c..23919bf 100644
--- a/gpu/command_buffer/service/context_group_unittest.cc
+++ b/gpu/command_buffer/service/context_group_unittest.cc
@@ -71,7 +71,7 @@ TEST_F(ContextGroupTest, Basic) {
TEST_F(ContextGroupTest, InitializeNoExtensions) {
TestHelper::SetupContextGroupInitExpectations(gl_.get(),
- DisallowedFeatures(), "");
+ DisallowedFeatures(), "", "");
group_->Initialize(decoder_.get(), DisallowedFeatures());
EXPECT_EQ(static_cast<uint32>(TestHelper::kNumVertexAttribs),
group_->max_vertex_attribs());
@@ -106,7 +106,7 @@ TEST_F(ContextGroupTest, InitializeNoExtensions) {
TEST_F(ContextGroupTest, MultipleContexts) {
scoped_ptr<MockGLES2Decoder> decoder2_(new MockGLES2Decoder());
TestHelper::SetupContextGroupInitExpectations(gl_.get(),
- DisallowedFeatures(), "");
+ DisallowedFeatures(), "", "");
group_->Initialize(decoder_.get(), DisallowedFeatures());
group_->Initialize(decoder2_.get(), DisallowedFeatures());
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
index 573cec4..e3ed72b 100644
--- a/gpu/command_buffer/service/feature_info.cc
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -7,6 +7,7 @@
#include <set>
#include "base/command_line.h"
+#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
@@ -99,7 +100,9 @@ void StringToWorkarounds(
} // anonymous namespace.
FeatureInfo::FeatureFlags::FeatureFlags()
- : chromium_framebuffer_multisample(false),
+ : chromium_color_buffer_float_rgba(false),
+ chromium_color_buffer_float_rgb(false),
+ chromium_framebuffer_multisample(false),
use_core_framebuffer_multisample(false),
multisampled_render_to_texture(false),
use_img_for_multisampled_render_to_texture(false),
@@ -437,26 +440,28 @@ void FeatureInfo::InitializeFeatures() {
bool enable_texture_half_float = false;
bool enable_texture_half_float_linear = false;
- bool have_arb_texture_float = extensions.Contains("GL_ARB_texture_float");
+ bool may_enable_chromium_color_buffer_float = false;
- if (have_arb_texture_float) {
+ if (extensions.Contains("GL_ARB_texture_float")) {
enable_texture_float = true;
enable_texture_float_linear = true;
enable_texture_half_float = true;
enable_texture_half_float_linear = true;
+ may_enable_chromium_color_buffer_float = true;
} else {
- if (extensions.Contains("GL_OES_texture_float") || have_arb_texture_float) {
+ if (extensions.Contains("GL_OES_texture_float")) {
enable_texture_float = true;
- if (extensions.Contains("GL_OES_texture_float_linear") ||
- have_arb_texture_float) {
+ if (extensions.Contains("GL_OES_texture_float_linear")) {
enable_texture_float_linear = true;
}
+ if ((is_es3 && extensions.Contains("GL_EXT_color_buffer_float")) ||
+ feature_flags_.is_angle) {
+ may_enable_chromium_color_buffer_float = true;
+ }
}
- if (extensions.Contains("GL_OES_texture_half_float") ||
- have_arb_texture_float) {
+ if (extensions.Contains("GL_OES_texture_half_float")) {
enable_texture_half_float = true;
- if (extensions.Contains("GL_OES_texture_half_float_linear") ||
- have_arb_texture_float) {
+ if (extensions.Contains("GL_OES_texture_half_float_linear")) {
enable_texture_half_float_linear = true;
}
}
@@ -490,6 +495,62 @@ void FeatureInfo::InitializeFeatures() {
}
}
+ if (may_enable_chromium_color_buffer_float) {
+ COMPILE_ASSERT(GL_RGBA32F_ARB == GL_RGBA32F &&
+ GL_RGBA32F_EXT == GL_RGBA32F &&
+ GL_RGB32F_ARB == GL_RGB32F &&
+ GL_RGB32F_EXT == GL_RGB32F,
+ sized_float_internal_format_variations_must_match);
+ // We don't check extension support beyond ARB_texture_float on desktop GL,
+ // and format support varies between GL configurations. For example, spec
+ // prior to OpenGL 3.0 mandates framebuffer support only for one
+ // implementation-chosen format, and ES3.0 EXT_color_buffer_float does not
+ // support rendering to RGB32F. Check for framebuffer completeness with
+ // formats that the extensions expose, and only enable an extension when a
+ // framebuffer created with its texture format is reported as complete.
+ GLint fb_binding = 0;
+ GLint tex_binding = 0;
+ glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fb_binding);
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex_binding);
+
+ GLuint tex_id = 0;
+ GLuint fb_id = 0;
+ GLsizei width = 16;
+
+ glGenTextures(1, &tex_id);
+ glGenFramebuffersEXT(1, &fb_id);
+ glBindTexture(GL_TEXTURE_2D, tex_id);
+ // Nearest filter needed for framebuffer completeness on some drivers.
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, width, 0, GL_RGBA,
+ GL_FLOAT, NULL);
+ glBindFramebufferEXT(GL_FRAMEBUFFER, fb_id);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D, tex_id, 0);
+ GLenum statusRGBA = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, width, 0, GL_RGB,
+ GL_FLOAT, NULL);
+ GLenum statusRGB = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
+ glDeleteFramebuffersEXT(1, &fb_id);
+ glDeleteTextures(1, &tex_id);
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER, static_cast<GLuint>(fb_binding));
+ glBindTexture(GL_TEXTURE_2D, static_cast<GLuint>(tex_binding));
+
+ DCHECK(glGetError() == GL_NO_ERROR);
+
+ if (statusRGBA == GL_FRAMEBUFFER_COMPLETE) {
+ validators_.texture_internal_format.AddValue(GL_RGBA32F);
+ feature_flags_.chromium_color_buffer_float_rgba = true;
+ AddExtensionString("GL_CHROMIUM_color_buffer_float_rgba");
+ }
+ if (statusRGB == GL_FRAMEBUFFER_COMPLETE) {
+ validators_.texture_internal_format.AddValue(GL_RGB32F);
+ feature_flags_.chromium_color_buffer_float_rgb = true;
+ AddExtensionString("GL_CHROMIUM_color_buffer_float_rgb");
+ }
+ }
+
// Check for multisample support
if (!disallowed_features_.multisampling &&
!workarounds_.disable_framebuffer_multisample) {
@@ -719,7 +780,14 @@ void FeatureInfo::InitializeFeatures() {
}
void FeatureInfo::AddExtensionString(const std::string& str) {
- if (extensions_.find(str) == std::string::npos) {
+ size_t pos = extensions_.find(str);
+ while (pos != std::string::npos &&
+ pos + str.length() < extensions_.length() &&
+ extensions_.substr(pos + str.length(), 1) != " ") {
+ // This extension name is a substring of another.
+ pos = extensions_.find(str, pos + str.length());
+ }
+ if (pos == std::string::npos) {
extensions_ += (extensions_.empty() ? "" : " ") + str;
}
}
diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h
index 81a7f7c..a47a080 100644
--- a/gpu/command_buffer/service/feature_info.h
+++ b/gpu/command_buffer/service/feature_info.h
@@ -26,6 +26,8 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> {
struct FeatureFlags {
FeatureFlags();
+ bool chromium_color_buffer_float_rgba;
+ bool chromium_color_buffer_float_rgb;
bool chromium_framebuffer_multisample;
// Use glBlitFramebuffer() and glRenderbufferStorageMultisample() with
// GL_EXT_framebuffer_multisample-style semantics, since they are exposed
diff --git a/gpu/command_buffer/service/feature_info_unittest.cc b/gpu/command_buffer/service/feature_info_unittest.cc
index 53d1527..1a8cc12 100644
--- a/gpu/command_buffer/service/feature_info_unittest.cc
+++ b/gpu/command_buffer/service/feature_info_unittest.cc
@@ -280,6 +280,10 @@ TEST_F(FeatureInfoTest, InitializeNoExtensions) {
GL_DEPTH24_STENCIL8));
EXPECT_FALSE(info_->validators()->texture_internal_format.IsValid(
GL_DEPTH_STENCIL));
+ EXPECT_FALSE(info_->validators()->texture_internal_format.IsValid(
+ GL_RGBA32F));
+ EXPECT_FALSE(info_->validators()->texture_internal_format.IsValid(
+ GL_RGB32F));
EXPECT_FALSE(info_->validators()->texture_format.IsValid(
GL_DEPTH_STENCIL));
EXPECT_FALSE(info_->validators()->pixel_type.IsValid(
@@ -407,6 +411,19 @@ TEST_F(FeatureInfoTest, InitializeEXT_read_format_bgra) {
GL_BGRA8_EXT));
}
+TEST_F(FeatureInfoTest, InitializeARB_texture_float) {
+ SetupInitExpectations("GL_ARB_texture_float");
+ EXPECT_TRUE(info_->feature_flags().chromium_color_buffer_float_rgba);
+ EXPECT_TRUE(info_->feature_flags().chromium_color_buffer_float_rgb);
+ std::string extensions = info_->extensions() + " ";
+ EXPECT_THAT(extensions, HasSubstr("GL_CHROMIUM_color_buffer_float_rgb "));
+ EXPECT_THAT(extensions, HasSubstr("GL_CHROMIUM_color_buffer_float_rgba"));
+ EXPECT_TRUE(info_->validators()->texture_internal_format.IsValid(
+ GL_RGBA32F));
+ EXPECT_TRUE(info_->validators()->texture_internal_format.IsValid(
+ GL_RGB32F));
+}
+
TEST_F(FeatureInfoTest, InitializeOES_texture_floatGLES2) {
SetupInitExpectations("GL_OES_texture_float");
EXPECT_FALSE(info_->feature_flags().enable_texture_float_linear);
diff --git a/gpu/command_buffer/service/framebuffer_manager_unittest.cc b/gpu/command_buffer/service/framebuffer_manager_unittest.cc
index a9b4388..ba123dd 100644
--- a/gpu/command_buffer/service/framebuffer_manager_unittest.cc
+++ b/gpu/command_buffer/service/framebuffer_manager_unittest.cc
@@ -33,7 +33,6 @@ class FramebufferManagerTest : public testing::Test {
NULL, new FeatureInfo(), kMaxTextureSize, kMaxCubemapSize),
renderbuffer_manager_(NULL, kMaxRenderbufferSize, kMaxSamples,
kDepth24Supported) {
-
}
virtual ~FramebufferManagerTest() {
manager_.Destroy(false);
@@ -110,21 +109,29 @@ class FramebufferInfoTest : public testing::Test {
FramebufferInfoTest()
: manager_(1, 1),
- texture_manager_(
- NULL, new FeatureInfo(), kMaxTextureSize, kMaxCubemapSize),
+ feature_info_(new FeatureInfo()),
renderbuffer_manager_(NULL, kMaxRenderbufferSize, kMaxSamples,
kDepth24Supported) {
+ texture_manager_.reset(new TextureManager(NULL, feature_info_.get(),
+ kMaxTextureSize, kMaxCubemapSize));
}
virtual ~FramebufferInfoTest() {
manager_.Destroy(false);
- texture_manager_.Destroy(false);
+ texture_manager_->Destroy(false);
renderbuffer_manager_.Destroy(false);
}
protected:
virtual void SetUp() {
+ InitializeContext("", "");
+ }
+
+ void InitializeContext(const char* gl_version, const char* extensions) {
gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>());
::gfx::MockGLInterface::SetGLInterface(gl_.get());
+ TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(gl_.get(),
+ extensions, "", gl_version);
+ feature_info_->Initialize();
manager_.CreateFramebuffer(kClient1Id, kService1Id);
error_state_.reset(new ::testing::StrictMock<gles2::MockErrorState>());
framebuffer_ = manager_.GetFramebuffer(kClient1Id);
@@ -140,7 +147,8 @@ class FramebufferInfoTest : public testing::Test {
scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_;
FramebufferManager manager_;
Framebuffer* framebuffer_;
- TextureManager texture_manager_;
+ scoped_refptr<FeatureInfo> feature_info_;
+ scoped_ptr<TextureManager> texture_manager_;
RenderbufferManager renderbuffer_manager_;
scoped_ptr<MockErrorState> error_state_;
};
@@ -268,7 +276,7 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) {
// check marking them as cleared.
manager_.MarkAttachmentsAsCleared(
- framebuffer_, &renderbuffer_manager_, &texture_manager_);
+ framebuffer_, &renderbuffer_manager_, texture_manager_.get());
EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
@@ -319,7 +327,7 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) {
// Clear it.
manager_.MarkAttachmentsAsCleared(
- framebuffer_, &renderbuffer_manager_, &texture_manager_);
+ framebuffer_, &renderbuffer_manager_, texture_manager_.get());
EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
EXPECT_TRUE(framebuffer_->IsCleared());
@@ -419,9 +427,9 @@ TEST_F(FramebufferInfoTest, AttachTexture) {
EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT),
framebuffer_->IsPossiblyComplete());
- texture_manager_.CreateTexture(kTextureClient1Id, kTextureService1Id);
+ texture_manager_->CreateTexture(kTextureClient1Id, kTextureService1Id);
scoped_refptr<TextureRef> texture1(
- texture_manager_.GetTexture(kTextureClient1Id));
+ texture_manager_->GetTexture(kTextureClient1Id));
ASSERT_TRUE(texture1.get() != NULL);
// check adding one attachment
@@ -434,8 +442,8 @@ TEST_F(FramebufferInfoTest, AttachTexture) {
EXPECT_EQ(static_cast<GLenum>(0), framebuffer_->GetColorAttachmentFormat());
// Try format that doesn't work with COLOR_ATTACHMENT0
- texture_manager_.SetTarget(texture1.get(), GL_TEXTURE_2D);
- texture_manager_.SetLevelInfo(texture1.get(),
+ texture_manager_->SetTarget(texture1.get(), GL_TEXTURE_2D);
+ texture_manager_->SetLevelInfo(texture1.get(),
GL_TEXTURE_2D,
kLevel1,
kBadFormat1,
@@ -450,7 +458,7 @@ TEST_F(FramebufferInfoTest, AttachTexture) {
framebuffer_->IsPossiblyComplete());
// Try a good format.
- texture_manager_.SetLevelInfo(texture1.get(),
+ texture_manager_->SetLevelInfo(texture1.get(),
GL_TEXTURE_2D,
kLevel1,
kFormat1,
@@ -464,7 +472,7 @@ TEST_F(FramebufferInfoTest, AttachTexture) {
EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
framebuffer_->IsPossiblyComplete());
EXPECT_FALSE(framebuffer_->IsCleared());
- texture_manager_.SetLevelInfo(texture1.get(),
+ texture_manager_->SetLevelInfo(texture1.get(),
GL_TEXTURE_2D,
kLevel1,
kFormat1,
@@ -491,12 +499,12 @@ TEST_F(FramebufferInfoTest, AttachTexture) {
EXPECT_TRUE(attachment->cleared());
// Check replacing an attachment
- texture_manager_.CreateTexture(kTextureClient2Id, kTextureService2Id);
+ texture_manager_->CreateTexture(kTextureClient2Id, kTextureService2Id);
scoped_refptr<TextureRef> texture2(
- texture_manager_.GetTexture(kTextureClient2Id));
+ texture_manager_->GetTexture(kTextureClient2Id));
ASSERT_TRUE(texture2.get() != NULL);
- texture_manager_.SetTarget(texture2.get(), GL_TEXTURE_2D);
- texture_manager_.SetLevelInfo(texture2.get(),
+ texture_manager_->SetTarget(texture2.get(), GL_TEXTURE_2D);
+ texture_manager_->SetLevelInfo(texture2.get(),
GL_TEXTURE_2D,
kLevel2,
kFormat2,
@@ -525,7 +533,7 @@ TEST_F(FramebufferInfoTest, AttachTexture) {
EXPECT_TRUE(attachment->cleared());
// Check changing attachment
- texture_manager_.SetLevelInfo(texture2.get(),
+ texture_manager_->SetLevelInfo(texture2.get(),
GL_TEXTURE_2D,
kLevel3,
kFormat3,
@@ -550,7 +558,7 @@ TEST_F(FramebufferInfoTest, AttachTexture) {
EXPECT_FALSE(framebuffer_->IsCleared());
// Set to size 0
- texture_manager_.SetLevelInfo(texture2.get(),
+ texture_manager_->SetLevelInfo(texture2.get(),
GL_TEXTURE_2D,
kLevel3,
kFormat3,
@@ -574,6 +582,65 @@ TEST_F(FramebufferInfoTest, AttachTexture) {
EXPECT_TRUE(framebuffer_->IsCleared());
}
+class FramebufferInfoFloatTest : public FramebufferInfoTest {
+ public:
+ FramebufferInfoFloatTest()
+ : FramebufferInfoTest() {
+ }
+ virtual ~FramebufferInfoFloatTest() {
+ }
+
+ protected:
+ virtual void SetUp() {
+ InitializeContext("OpenGL ES 3.0",
+ "GL_OES_texture_float GL_EXT_color_buffer_float");
+ }
+};
+
+TEST_F(FramebufferInfoFloatTest, AttachFloatTexture) {
+ const GLuint kTextureClientId = 33;
+ const GLuint kTextureServiceId = 333;
+ const GLint kDepth = 1;
+ const GLint kBorder = 0;
+ const GLenum kType = GL_FLOAT;
+ const GLsizei kWidth = 16;
+ const GLsizei kHeight = 32;
+ const GLint kLevel = 0;
+ const GLenum kFormat = GL_RGBA;
+ const GLenum kInternalFormat = GL_RGBA32F;
+ const GLenum kTarget = GL_TEXTURE_2D;
+ const GLsizei kSamples = 0;
+ EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
+ EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
+ EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
+
+ texture_manager_->CreateTexture(kTextureClientId, kTextureServiceId);
+ scoped_refptr<TextureRef> texture(
+ texture_manager_->GetTexture(kTextureClientId));
+ ASSERT_TRUE(texture.get() != NULL);
+
+ framebuffer_->AttachTexture(
+ GL_COLOR_ATTACHMENT0, texture.get(), kTarget, kLevel, kSamples);
+ EXPECT_EQ(static_cast<GLenum>(0), framebuffer_->GetColorAttachmentFormat());
+
+ texture_manager_->SetTarget(texture.get(), GL_TEXTURE_2D);
+ texture_manager_->SetLevelInfo(texture.get(),
+ GL_TEXTURE_2D,
+ kLevel,
+ kInternalFormat,
+ kWidth,
+ kHeight,
+ kDepth,
+ kBorder,
+ kFormat,
+ kType,
+ false);
+ // Texture with a sized float internalformat is allowed as an attachment
+ // since float color attachment extension is present.
+ EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
+ framebuffer_->IsPossiblyComplete());
+}
+
TEST_F(FramebufferInfoTest, UnbindRenderbuffer) {
const GLuint kRenderbufferClient1Id = 33;
const GLuint kRenderbufferService1Id = 333;
@@ -618,13 +685,13 @@ TEST_F(FramebufferInfoTest, UnbindTexture) {
const GLint kLevel1 = 0;
const GLint kSamples1 = 0;
- texture_manager_.CreateTexture(kTextureClient1Id, kTextureService1Id);
+ texture_manager_->CreateTexture(kTextureClient1Id, kTextureService1Id);
scoped_refptr<TextureRef> texture1(
- texture_manager_.GetTexture(kTextureClient1Id));
+ texture_manager_->GetTexture(kTextureClient1Id));
ASSERT_TRUE(texture1.get() != NULL);
- texture_manager_.CreateTexture(kTextureClient2Id, kTextureService2Id);
+ texture_manager_->CreateTexture(kTextureClient2Id, kTextureService2Id);
scoped_refptr<TextureRef> texture2(
- texture_manager_.GetTexture(kTextureClient2Id));
+ texture_manager_->GetTexture(kTextureClient2Id));
ASSERT_TRUE(texture2.get() != NULL);
// Attach to 2 attachment points.
@@ -661,9 +728,9 @@ TEST_F(FramebufferInfoTest, IsCompleteMarkAsComplete) {
Renderbuffer* renderbuffer1 =
renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id);
ASSERT_TRUE(renderbuffer1 != NULL);
- texture_manager_.CreateTexture(kTextureClient2Id, kTextureService2Id);
+ texture_manager_->CreateTexture(kTextureClient2Id, kTextureService2Id);
scoped_refptr<TextureRef> texture2(
- texture_manager_.GetTexture(kTextureClient2Id));
+ texture_manager_->GetTexture(kTextureClient2Id));
ASSERT_TRUE(texture2.get() != NULL);
// Check MarkAsComlete marks as complete.
@@ -681,7 +748,7 @@ TEST_F(FramebufferInfoTest, IsCompleteMarkAsComplete) {
// Check MarkAttachmentsAsCleared marks as complete.
manager_.MarkAttachmentsAsCleared(
- framebuffer_, &renderbuffer_manager_, &texture_manager_);
+ framebuffer_, &renderbuffer_manager_, texture_manager_.get());
EXPECT_TRUE(manager_.IsComplete(framebuffer_));
// Check Unbind marks as not complete.
@@ -707,16 +774,16 @@ TEST_F(FramebufferInfoTest, GetStatus) {
Renderbuffer* renderbuffer1 =
renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id);
ASSERT_TRUE(renderbuffer1 != NULL);
- texture_manager_.CreateTexture(kTextureClient2Id, kTextureService2Id);
+ texture_manager_->CreateTexture(kTextureClient2Id, kTextureService2Id);
scoped_refptr<TextureRef> texture2(
- texture_manager_.GetTexture(kTextureClient2Id));
+ texture_manager_->GetTexture(kTextureClient2Id));
ASSERT_TRUE(texture2.get() != NULL);
- texture_manager_.SetTarget(texture2.get(), GL_TEXTURE_2D);
+ texture_manager_->SetTarget(texture2.get(), GL_TEXTURE_2D);
EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
.WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
.RetiresOnSaturation();
- framebuffer_->GetStatus(&texture_manager_, GL_FRAMEBUFFER);
+ framebuffer_->GetStatus(texture_manager_.get(), GL_FRAMEBUFFER);
// Check a second call for the same type does not call anything
if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
@@ -724,14 +791,14 @@ TEST_F(FramebufferInfoTest, GetStatus) {
.WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
.RetiresOnSaturation();
}
- framebuffer_->GetStatus(&texture_manager_, GL_FRAMEBUFFER);
+ framebuffer_->GetStatus(texture_manager_.get(), GL_FRAMEBUFFER);
// Check changing the attachments calls CheckFramebufferStatus.
framebuffer_->AttachTexture(
GL_COLOR_ATTACHMENT0, texture2.get(), kTarget1, kLevel1, kSamples1);
EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
.WillOnce(Return(GL_FRAMEBUFFER_COMPLETE)).RetiresOnSaturation();
- framebuffer_->GetStatus(&texture_manager_, GL_FRAMEBUFFER);
+ framebuffer_->GetStatus(texture_manager_.get(), GL_FRAMEBUFFER);
// Check a second call for the same type does not call anything.
if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
@@ -739,13 +806,13 @@ TEST_F(FramebufferInfoTest, GetStatus) {
.WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
.RetiresOnSaturation();
}
- framebuffer_->GetStatus(&texture_manager_, GL_FRAMEBUFFER);
+ framebuffer_->GetStatus(texture_manager_.get(), GL_FRAMEBUFFER);
// Check a second call with a different target calls CheckFramebufferStatus.
EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
.WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
.RetiresOnSaturation();
- framebuffer_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER);
+ framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
// Check a second call for the same type does not call anything.
if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
@@ -753,14 +820,14 @@ TEST_F(FramebufferInfoTest, GetStatus) {
.WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
.RetiresOnSaturation();
}
- framebuffer_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER);
+ framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
// Check adding another attachment calls CheckFramebufferStatus.
framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, renderbuffer1);
EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
.WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
.RetiresOnSaturation();
- framebuffer_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER);
+ framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
// Check a second call for the same type does not call anything.
if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
@@ -768,12 +835,12 @@ TEST_F(FramebufferInfoTest, GetStatus) {
.WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
.RetiresOnSaturation();
}
- framebuffer_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER);
+ framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
// Check changing the format calls CheckFramebuffferStatus.
TestHelper::SetTexParameterWithExpectations(gl_.get(),
error_state_.get(),
- &texture_manager_,
+ texture_manager_.get(),
texture2.get(),
GL_TEXTURE_WRAP_S,
GL_CLAMP_TO_EDGE,
@@ -783,11 +850,11 @@ TEST_F(FramebufferInfoTest, GetStatus) {
.WillOnce(Return(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT))
.WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
.RetiresOnSaturation();
- framebuffer_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER);
+ framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
// Check since it did not return FRAMEBUFFER_COMPLETE that it calls
// CheckFramebufferStatus
- framebuffer_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER);
+ framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
// Check putting it back does not call CheckFramebufferStatus.
if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
@@ -797,12 +864,12 @@ TEST_F(FramebufferInfoTest, GetStatus) {
}
TestHelper::SetTexParameterWithExpectations(gl_.get(),
error_state_.get(),
- &texture_manager_,
+ texture_manager_.get(),
texture2.get(),
GL_TEXTURE_WRAP_S,
GL_REPEAT,
GL_NO_ERROR);
- framebuffer_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER);
+ framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
// Check Unbinding does not call CheckFramebufferStatus
framebuffer_->UnbindRenderbuffer(GL_RENDERBUFFER, renderbuffer1);
@@ -811,7 +878,7 @@ TEST_F(FramebufferInfoTest, GetStatus) {
.WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
.RetiresOnSaturation();
}
- framebuffer_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER);
+ framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
}
} // namespace gles2
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 99b9976..414ecc6 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -8159,7 +8159,7 @@ void GLES2DecoderImpl::DoCompressedTexSubImage2D(
return;
}
if (!texture->ValidForTexture(
- target, level, xoffset, yoffset, width, height, format, type)) {
+ target, level, xoffset, yoffset, width, height, type)) {
LOCAL_SET_GL_ERROR(
GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
return;
@@ -8228,9 +8228,9 @@ void GLES2DecoderImpl::DoCopyTexImage2D(
GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
return;
}
- if (!texture_manager()->ValidateTextureParameters(
- state_.GetErrorState(), "glCopyTexImage2D", target, internal_format,
- GL_UNSIGNED_BYTE, level)) {
+ if (!texture_manager()->ValidateFormatAndTypeCombination(
+ state_.GetErrorState(), "glCopyTexImage2D", internal_format,
+ GL_UNSIGNED_BYTE)) {
return;
}
@@ -8343,7 +8343,7 @@ void GLES2DecoderImpl::DoCopyTexSubImage2D(
GLenum format = 0;
if (!texture->GetLevelType(target, level, &type, &format) ||
!texture->ValidForTexture(
- target, level, xoffset, yoffset, width, height, format, type)) {
+ target, level, xoffset, yoffset, width, height, type)) {
LOCAL_SET_GL_ERROR(
GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
return;
@@ -8449,14 +8449,6 @@ bool GLES2DecoderImpl::ValidateTexSubImage2D(
LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
return false;
}
- if (!validators_->texture_format.IsValid(format)) {
- LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
- return false;
- }
- if (!validators_->pixel_type.IsValid(type)) {
- LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
- return false;
- }
TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
&state_, target);
if (!texture_ref) {
@@ -8473,10 +8465,8 @@ bool GLES2DecoderImpl::ValidateTexSubImage2D(
GL_INVALID_OPERATION, function_name, "level does not exist.");
return false;
}
- if (format != internal_format) {
- LOCAL_SET_GL_ERROR(
- GL_INVALID_OPERATION,
- function_name, "format does not match internal format.");
+ if (!texture_manager()->ValidateTextureParameters(state_.GetErrorState(),
+ function_name, format, type, internal_format, level)) {
return false;
}
if (type != current_type) {
@@ -8492,7 +8482,7 @@ bool GLES2DecoderImpl::ValidateTexSubImage2D(
return false;
}
if (!texture->ValidForTexture(
- target, level, xoffset, yoffset, width, height, format, type)) {
+ target, level, xoffset, yoffset, width, height, type)) {
LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
return false;
}
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
index 2756257..4d1c77e 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
@@ -8903,6 +8903,78 @@ TEST_F(GLES2DecoderManualInitTest, ClearUniformsBeforeFirstProgramUse) {
}
}
+TEST_F(GLES2DecoderManualInitTest, TexImage2DFloatOnGLES2) {
+ InitDecoder("GL_OES_texture_float", // extensions
+ "opengl es 2.0", // gl version
+ false, // has alpha
+ false, // has depth
+ false, // has stencil
+ false, // request alpha
+ false, // request depth
+ false, // request stencil
+ false); // bind generates resource
+ DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+ DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 17, 0, GL_RGBA, GL_FLOAT, 0, 0);
+ DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 16, 17, 0, GL_RGB, GL_FLOAT, 0, 0);
+ DoTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 16, 17, 0, GL_LUMINANCE,
+ GL_FLOAT, 0, 0);
+ DoTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 16, 17, 0, GL_ALPHA, GL_FLOAT,
+ 0, 0);
+ DoTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 16, 17, 0,
+ GL_LUMINANCE_ALPHA, GL_FLOAT, 0, 0);
+}
+
+TEST_F(GLES2DecoderManualInitTest, TexImage2DFloatOnGLES3) {
+ InitDecoder("GL_OES_texture_float GL_EXT_color_buffer_float", // extensions
+ "opengl es 3.0", // gl version
+ false, // has alpha
+ false, // has depth
+ false, // has stencil
+ false, // request alpha
+ false, // request depth
+ false, // request stencil
+ false); // bind generates resource
+ DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+ DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 17, 0, GL_RGBA, GL_FLOAT, 0, 0);
+ DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 16, 17, 0, GL_RGB, GL_FLOAT, 0, 0);
+ DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 16, 17, 0, GL_RGBA, GL_FLOAT, 0,
+ 0);
+ DoTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 16, 17, 0, GL_LUMINANCE,
+ GL_FLOAT, 0, 0);
+ DoTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 16, 17, 0, GL_ALPHA, GL_FLOAT,
+ 0, 0);
+ DoTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 16, 17, 0,
+ GL_LUMINANCE_ALPHA, GL_FLOAT, 0, 0);
+}
+
+TEST_F(GLES2DecoderManualInitTest, TexImage2DFloatConvertsFormatDesktop) {
+ InitDecoder("GL_ARB_texture_float", // extensions
+ "2.1", // gl version
+ false, // has alpha
+ false, // has depth
+ false, // has stencil
+ false, // request alpha
+ false, // request depth
+ false, // request stencil
+ false); // bind generates resource
+ DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+ DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 16, 17, 0, GL_RGBA, GL_FLOAT, 0,
+ 0);
+ DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, 16, 17, 0, GL_RGB, GL_FLOAT, 0, 0);
+ DoTexImage2DConvertInternalFormat(GL_TEXTURE_2D, 0, GL_RGBA, 16, 17, 0,
+ GL_RGBA, GL_FLOAT, 0, 0, GL_RGBA32F_ARB);
+ DoTexImage2DConvertInternalFormat(GL_TEXTURE_2D, 0, GL_RGB, 16, 17, 0,
+ GL_RGB, GL_FLOAT, 0, 0, GL_RGB32F_ARB);
+ DoTexImage2DConvertInternalFormat(GL_TEXTURE_2D, 0, GL_LUMINANCE, 16, 17, 0,
+ GL_LUMINANCE, GL_FLOAT, 0, 0,
+ GL_LUMINANCE32F_ARB);
+ DoTexImage2DConvertInternalFormat(GL_TEXTURE_2D, 0, GL_ALPHA, 16, 17, 0,
+ GL_ALPHA, GL_FLOAT, 0, 0, GL_ALPHA32F_ARB);
+ DoTexImage2DConvertInternalFormat(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 16,
+ 17, 0, GL_LUMINANCE_ALPHA, GL_FLOAT, 0, 0,
+ GL_LUMINANCE_ALPHA32F_ARB);
+}
+
// TODO(gman): Complete this test.
// TEST_F(GLES2DecoderTest, CompressedTexImage2DGLError) {
// }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
index 6f74bde..0b35b39 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
@@ -141,8 +141,21 @@ void GLES2DecoderTestBase::InitDecoderWithCommandLine(
InSequence sequence;
+ surface_ = new gfx::GLSurfaceStub;
+ surface_->SetSize(gfx::Size(kBackBufferWidth, kBackBufferHeight));
+
+ // Context needs to be created before initializing ContextGroup, which will
+ // in turn initialize FeatureInfo, which needs a context to determine
+ // extension support.
+ context_ = new gfx::GLContextStubWithExtensions;
+ context_->AddExtensionsString(extensions);
+ context_->SetGLVersionString(gl_version);
+
+ context_->MakeCurrent(surface_.get());
+ gfx::GLSurface::InitializeDynamicMockBindingsForTests(context_);
+
TestHelper::SetupContextGroupInitExpectations(gl_.get(),
- DisallowedFeatures(), extensions);
+ DisallowedFeatures(), extensions, gl_version);
// We initialize the ContextGroup with a MockGLES2Decoder so that
// we can use the ContextGroup to figure out how the real GLES2Decoder
@@ -281,16 +294,6 @@ void GLES2DecoderTestBase::InitDecoderWithCommandLine(
shared_memory_id_ = kSharedMemoryId;
shared_memory_base_ = buffer.ptr;
- surface_ = new gfx::GLSurfaceStub;
- surface_->SetSize(gfx::Size(kBackBufferWidth, kBackBufferHeight));
-
- context_ = new gfx::GLContextStubWithExtensions;
- context_->AddExtensionsString(extensions);
- context_->SetGLVersionString(gl_version);
-
- context_->MakeCurrent(surface_.get());
- gfx::GLSurface::InitializeDynamicMockBindingsForTests(context_);
-
int32 attributes[] = {
EGL_ALPHA_SIZE, request_alpha ? 8 : 0,
EGL_DEPTH_SIZE, request_depth ? 24 : 0,
@@ -834,6 +837,28 @@ void GLES2DecoderTestBase::DoTexImage2D(
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
}
+void GLES2DecoderTestBase::DoTexImage2DConvertInternalFormat(
+ GLenum target, GLint level, GLenum requested_internal_format,
+ GLsizei width, GLsizei height, GLint border,
+ GLenum format, GLenum type,
+ uint32 shared_memory_id, uint32 shared_memory_offset,
+ GLenum expected_internal_format) {
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, TexImage2D(target, level, expected_internal_format,
+ width, height, border, format, type, _))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ cmds::TexImage2D cmd;
+ cmd.Init(target, level, requested_internal_format, width, height, border,
+ format, type, shared_memory_id, shared_memory_offset);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
void GLES2DecoderTestBase::DoCompressedTexImage2D(
GLenum target, GLint level, GLenum format,
GLsizei width, GLsizei height, GLint border,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
index 733724f..62ca07c 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
@@ -244,6 +244,12 @@ class GLES2DecoderTestBase : public testing::Test {
GLsizei width, GLsizei height, GLint border,
GLenum format, GLenum type,
uint32 shared_memory_id, uint32 shared_memory_offset);
+ void DoTexImage2DConvertInternalFormat(
+ GLenum target, GLint level, GLenum requested_internal_format,
+ GLsizei width, GLsizei height, GLint border,
+ GLenum format, GLenum type,
+ uint32 shared_memory_id, uint32 shared_memory_offset,
+ GLenum expected_internal_format);
void DoRenderbufferStorage(
GLenum target, GLenum internal_format, GLenum actual_format,
GLsizei width, GLsizei height, GLenum error);
diff --git a/gpu/command_buffer/service/test_helper.cc b/gpu/command_buffer/service/test_helper.cc
index 92c5ec4..c164eea 100644
--- a/gpu/command_buffer/service/test_helper.cc
+++ b/gpu/command_buffer/service/test_helper.cc
@@ -227,16 +227,20 @@ void TestHelper::SetupTextureManagerDestructionExpectations(
void TestHelper::SetupContextGroupInitExpectations(
::gfx::MockGLInterface* gl,
const DisallowedFeatures& disallowed_features,
- const char* extensions) {
+ const char* extensions,
+ const char* gl_version) {
InSequence sequence;
- SetupFeatureInfoInitExpectations(gl, extensions);
+ SetupFeatureInfoInitExpectationsWithGLVersion(gl, extensions, "", gl_version);
+
+ std::string l_version(StringToLowerASCII(std::string(gl_version)));
+ bool is_es3 = (l_version.substr(0, 12) == "opengl es 3.");
EXPECT_CALL(*gl, GetIntegerv(GL_MAX_RENDERBUFFER_SIZE, _))
.WillOnce(SetArgumentPointee<1>(kMaxRenderbufferSize))
.RetiresOnSaturation();
if (strstr(extensions, "GL_EXT_framebuffer_multisample") ||
- strstr(extensions, "GL_EXT_multisampled_render_to_texture")) {
+ strstr(extensions, "GL_EXT_multisampled_render_to_texture") || is_es3) {
EXPECT_CALL(*gl, GetIntegerv(GL_MAX_SAMPLES, _))
.WillOnce(SetArgumentPointee<1>(kMaxSamples))
.RetiresOnSaturation();
@@ -297,6 +301,78 @@ void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(
EXPECT_CALL(*gl, GetString(GL_VERSION))
.WillOnce(Return(reinterpret_cast<const uint8*>(gl_version)))
.RetiresOnSaturation();
+
+ std::string l_version(StringToLowerASCII(std::string(gl_version)));
+ bool is_es3 = (l_version.substr(0, 12) == "opengl es 3.");
+
+ if (strstr(extensions, "GL_ARB_texture_float") ||
+ (is_es3 && strstr(extensions, "GL_EXT_color_buffer_float"))) {
+ static const GLuint gl_ids[] = {101, 102};
+ const GLsizei width = 16;
+ EXPECT_CALL(*gl, GetIntegerv(GL_FRAMEBUFFER_BINDING, _))
+ .WillOnce(SetArgumentPointee<1>(gl_ids[0]))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl, GetIntegerv(GL_TEXTURE_BINDING_2D, _))
+ .WillOnce(SetArgumentPointee<1>(gl_ids[0]))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl, GenTextures(1, _))
+ .WillOnce(SetArrayArgument<1>(gl_ids + 1, gl_ids + 2))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl, GenFramebuffersEXT(1, _))
+ .WillOnce(SetArrayArgument<1>(gl_ids + 1, gl_ids + 2))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl, BindTexture(GL_TEXTURE_2D, gl_ids[1]))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl, TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ GL_NEAREST))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl, TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, width, 0,
+ GL_RGBA, GL_FLOAT, _))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl, BindFramebufferEXT(GL_FRAMEBUFFER, gl_ids[1]))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl, FramebufferTexture2DEXT(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl_ids[1], 0))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
+ .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl, TexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, width, 0,
+ GL_RGB, GL_FLOAT, _))
+ .Times(1)
+ .RetiresOnSaturation();
+ if (is_es3) {
+ EXPECT_CALL(*gl, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
+ .WillOnce(Return(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT))
+ .RetiresOnSaturation();
+ } else {
+ EXPECT_CALL(*gl, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
+ .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
+ .RetiresOnSaturation();
+ }
+ EXPECT_CALL(*gl, DeleteFramebuffersEXT(1, _))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl, DeleteTextures(1, _))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl, BindFramebufferEXT(GL_FRAMEBUFFER, gl_ids[0]))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl, BindTexture(GL_TEXTURE_2D, gl_ids[0]))
+ .Times(1)
+ .RetiresOnSaturation();
+ if (DCHECK_IS_ON()) {
+ EXPECT_CALL(*gl, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ }
+ }
}
void TestHelper::SetupExpectationsForClearingUniforms(
diff --git a/gpu/command_buffer/service/test_helper.h b/gpu/command_buffer/service/test_helper.h
index a619073..99041e7 100644
--- a/gpu/command_buffer/service/test_helper.h
+++ b/gpu/command_buffer/service/test_helper.h
@@ -65,7 +65,8 @@ class TestHelper {
static void SetupContextGroupInitExpectations(
::gfx::MockGLInterface* gl,
const DisallowedFeatures& disallowed_features,
- const char* extensions);
+ const char* extensions,
+ const char* gl_version);
static void SetupFeatureInfoInitExpectations(
::gfx::MockGLInterface* gl, const char* extensions);
static void SetupFeatureInfoInitExpectationsWithGLVersion(
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc
index 72d3b4c..a0a60c1 100644
--- a/gpu/command_buffer/service/texture_manager.cc
+++ b/gpu/command_buffer/service/texture_manager.cc
@@ -517,7 +517,6 @@ bool Texture::ValidForTexture(
GLint yoffset,
GLsizei width,
GLsizei height,
- GLenum format,
GLenum type) const {
size_t face_index = GLTargetToFaceIndex(target);
if (level >= 0 && face_index < level_infos_.size() &&
@@ -531,7 +530,6 @@ bool Texture::ValidForTexture(
yoffset >= 0 &&
right <= info.width &&
top <= info.height &&
- format == info.internal_format &&
type == info.type;
}
return false;
@@ -1259,20 +1257,10 @@ void TextureManager::IncFramebufferStateChangeCount() {
framebuffer_manager_->IncFramebufferStateChangeCount();
}
-bool TextureManager::ValidateTextureParameters(
- ErrorState* error_state, const char* function_name,
- GLenum target, GLenum format, GLenum type, GLint level) {
+bool TextureManager::ValidateFormatAndTypeCombination(
+ ErrorState* error_state, const char* function_name, GLenum format,
+ GLenum type) {
if (!feature_info_->GetTextureFormatValidator(format).IsValid(type)) {
- ERRORSTATE_SET_GL_ERROR(
- error_state, GL_INVALID_OPERATION, function_name,
- (std::string("invalid type ") +
- GLES2Util::GetStringEnum(type) + " for format " +
- GLES2Util::GetStringEnum(format)).c_str());
- return false;
- }
-
- uint32 channels = GLES2Util::GetChannelsForFormat(format);
- if ((channels & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && level) {
ERRORSTATE_SET_GL_ERROR(
error_state, GL_INVALID_OPERATION, function_name,
(std::string("invalid type ") +
@@ -1283,6 +1271,40 @@ bool TextureManager::ValidateTextureParameters(
return true;
}
+bool TextureManager::ValidateTextureParameters(
+ ErrorState* error_state, const char* function_name,
+ GLenum format, GLenum type, GLenum internal_format, GLint level) {
+ const Validators* validators = feature_info_->validators();
+ if (!validators->texture_format.IsValid(format)) {
+ ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(
+ error_state, function_name, format, "format");
+ return false;
+ }
+ if (!validators->pixel_type.IsValid(type)) {
+ ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(
+ error_state, function_name, type, "type");
+ return false;
+ }
+ if (format != internal_format &&
+ !((internal_format == GL_RGBA32F && format == GL_RGBA) ||
+ (internal_format == GL_RGB32F && format == GL_RGB))) {
+ ERRORSTATE_SET_GL_ERROR(
+ error_state, GL_INVALID_OPERATION, function_name,
+ "format != internalformat");
+ return false;
+ }
+ uint32 channels = GLES2Util::GetChannelsForFormat(format);
+ if ((channels & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && level) {
+ ERRORSTATE_SET_GL_ERROR(
+ error_state, GL_INVALID_OPERATION, function_name,
+ (std::string("invalid format ") + GLES2Util::GetStringEnum(format) +
+ " for level != 0").c_str());
+ return false;
+ }
+ return ValidateFormatAndTypeCombination(error_state, function_name,
+ format, type);
+}
+
// Gets the texture id for a given target.
TextureRef* TextureManager::GetTextureInfoForTarget(
ContextState* state, GLenum target) {
@@ -1336,31 +1358,15 @@ bool TextureManager::ValidateTexImage2D(
error_state, function_name, args.target, "target");
return false;
}
- if (!validators->texture_format.IsValid(args.internal_format)) {
+ if (!validators->texture_internal_format.IsValid(args.internal_format)) {
ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(
error_state, function_name, args.internal_format,
- "internal_format");
- return false;
- }
- if (!validators->texture_format.IsValid(args.format)) {
- ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(
- error_state, function_name, args.format, "format");
- return false;
- }
- if (!validators->pixel_type.IsValid(args.type)) {
- ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(
- error_state, function_name, args.type, "type");
- return false;
- }
- if (args.format != args.internal_format) {
- ERRORSTATE_SET_GL_ERROR(
- error_state, GL_INVALID_OPERATION, function_name,
- "format != internalFormat");
+ "internalformat");
return false;
}
if (!ValidateTextureParameters(
- error_state, function_name, args.target, args.format, args.type,
- args.level)) {
+ error_state, function_name, args.format, args.type,
+ args.internal_format, args.level)) {
return false;
}
if (!ValidForTarget(args.target, args.level, args.width, args.height, 1) ||
@@ -1396,7 +1402,7 @@ bool TextureManager::ValidateTexImage2D(
// They both use the same MemoryTracker, and this call just re-routes
// to it.
if (!memory_tracker_managed_->EnsureGPUMemoryAvailable(args.pixels_size)) {
- ERRORSTATE_SET_GL_ERROR(error_state, GL_OUT_OF_MEMORY, "glTexImage2D",
+ ERRORSTATE_SET_GL_ERROR(error_state, GL_OUT_OF_MEMORY, function_name,
"out of memory");
return false;
}
diff --git a/gpu/command_buffer/service/texture_manager.h b/gpu/command_buffer/service/texture_manager.h
index b74ef91..c44bef3 100644
--- a/gpu/command_buffer/service/texture_manager.h
+++ b/gpu/command_buffer/service/texture_manager.h
@@ -116,7 +116,7 @@ class GPU_EXPORT Texture {
}
// Returns true of the given dimensions are inside the dimensions of the
- // level and if the format and type match the level.
+ // level and if the type matches the level.
bool ValidForTexture(
GLint target,
GLint level,
@@ -124,7 +124,6 @@ class GPU_EXPORT Texture {
GLint yoffset,
GLsizei width,
GLsizei height,
- GLenum format,
GLenum type) const;
bool IsValid() const {
@@ -707,9 +706,15 @@ class GPU_EXPORT TextureManager {
TextureRef* GetTextureInfoForTargetUnlessDefault(
ContextState* state, GLenum target);
+ bool ValidateFormatAndTypeCombination(
+ ErrorState* error_state, const char* function_name,
+ GLenum format, GLenum type);
+
+ // Note that internal_format is only checked in relation to the format
+ // parameter, so that this function may be used to validate texSubImage2D.
bool ValidateTextureParameters(
ErrorState* error_state, const char* function_name,
- GLenum target, GLenum format, GLenum type, GLint level);
+ GLenum format, GLenum type, GLenum internal_format, GLint level);
private:
friend class Texture;
diff --git a/gpu/command_buffer/service/texture_manager_unittest.cc b/gpu/command_buffer/service/texture_manager_unittest.cc
index 002f2f8..ada24a8 100644
--- a/gpu/command_buffer/service/texture_manager_unittest.cc
+++ b/gpu/command_buffer/service/texture_manager_unittest.cc
@@ -1042,43 +1042,40 @@ TEST_F(TextureTest, ValidForTexture) {
Texture* texture = texture_ref_->texture();
EXPECT_FALSE(texture->ValidForTexture(
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
- 1, 0, 0, 4, 5, GL_RGBA, GL_UNSIGNED_BYTE));
+ 1, 0, 0, 4, 5, GL_UNSIGNED_BYTE));
// Check bad level.
EXPECT_FALSE(texture->ValidForTexture(
- GL_TEXTURE_2D, 0, 0, 0, 4, 5, GL_RGBA, GL_UNSIGNED_BYTE));
+ GL_TEXTURE_2D, 0, 0, 0, 4, 5, GL_UNSIGNED_BYTE));
// Check bad xoffset.
EXPECT_FALSE(texture->ValidForTexture(
- GL_TEXTURE_2D, 1, -1, 0, 4, 5, GL_RGBA, GL_UNSIGNED_BYTE));
+ GL_TEXTURE_2D, 1, -1, 0, 4, 5, GL_UNSIGNED_BYTE));
// Check bad xoffset + width > width.
EXPECT_FALSE(texture->ValidForTexture(
- GL_TEXTURE_2D, 1, 1, 0, 4, 5, GL_RGBA, GL_UNSIGNED_BYTE));
+ GL_TEXTURE_2D, 1, 1, 0, 4, 5, GL_UNSIGNED_BYTE));
// Check bad yoffset.
EXPECT_FALSE(texture->ValidForTexture(
- GL_TEXTURE_2D, 1, 0, -1, 4, 5, GL_RGBA, GL_UNSIGNED_BYTE));
+ GL_TEXTURE_2D, 1, 0, -1, 4, 5, GL_UNSIGNED_BYTE));
// Check bad yoffset + height > height.
EXPECT_FALSE(texture->ValidForTexture(
- GL_TEXTURE_2D, 1, 0, 1, 4, 5, GL_RGBA, GL_UNSIGNED_BYTE));
+ GL_TEXTURE_2D, 1, 0, 1, 4, 5, GL_UNSIGNED_BYTE));
// Check bad width.
EXPECT_FALSE(texture->ValidForTexture(
- GL_TEXTURE_2D, 1, 0, 0, 5, 5, GL_RGBA, GL_UNSIGNED_BYTE));
+ GL_TEXTURE_2D, 1, 0, 0, 5, 5, GL_UNSIGNED_BYTE));
// Check bad height.
EXPECT_FALSE(texture->ValidForTexture(
- GL_TEXTURE_2D, 1, 0, 0, 4, 6, GL_RGBA, GL_UNSIGNED_BYTE));
- // Check bad format.
- EXPECT_FALSE(texture->ValidForTexture(
- GL_TEXTURE_2D, 1, 0, 0, 4, 5, GL_RGB, GL_UNSIGNED_BYTE));
+ GL_TEXTURE_2D, 1, 0, 0, 4, 6, GL_UNSIGNED_BYTE));
// Check bad type.
EXPECT_FALSE(texture->ValidForTexture(
- GL_TEXTURE_2D, 1, 0, 0, 4, 5, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4));
+ GL_TEXTURE_2D, 1, 0, 0, 4, 5, GL_UNSIGNED_SHORT_4_4_4_4));
// Check valid full size
EXPECT_TRUE(texture->ValidForTexture(
- GL_TEXTURE_2D, 1, 0, 0, 4, 5, GL_RGBA, GL_UNSIGNED_BYTE));
+ GL_TEXTURE_2D, 1, 0, 0, 4, 5, GL_UNSIGNED_BYTE));
// Check valid particial size.
EXPECT_TRUE(texture->ValidForTexture(
- GL_TEXTURE_2D, 1, 1, 1, 2, 3, GL_RGBA, GL_UNSIGNED_BYTE));
+ GL_TEXTURE_2D, 1, 1, 1, 2, 3, GL_UNSIGNED_BYTE));
manager_->RemoveTexture(kClient1Id);
EXPECT_TRUE(texture->ValidForTexture(
- GL_TEXTURE_2D, 1, 0, 0, 4, 5, GL_RGBA, GL_UNSIGNED_BYTE));
+ GL_TEXTURE_2D, 1, 0, 0, 4, 5, GL_UNSIGNED_BYTE));
}
TEST_F(TextureTest, FloatNotLinear) {
diff --git a/ui/gl/gl_context.cc b/ui/gl/gl_context.cc
index dc3a3e8..cd9a28c 100644
--- a/ui/gl/gl_context.cc
+++ b/ui/gl/gl_context.cc
@@ -66,6 +66,13 @@ std::string GLContext::GetGLVersion() {
return std::string(version ? version : "");
}
+std::string GLContext::GetGLRenderer() {
+ DCHECK(IsCurrent(NULL));
+ const char *renderer =
+ reinterpret_cast<const char*>(glGetString(GL_RENDERER));
+ return std::string(renderer ? renderer : "");
+}
+
bool GLContext::HasExtension(const char* name) {
std::string extensions = GetExtensions();
extensions += " ";
@@ -79,8 +86,9 @@ bool GLContext::HasExtension(const char* name) {
const GLVersionInfo* GLContext::GetVersionInfo() {
if(!version_info_) {
std::string version = GetGLVersion();
+ std::string renderer = GetGLRenderer();
version_info_ = scoped_ptr<GLVersionInfo>(
- new GLVersionInfo(version.c_str()));
+ new GLVersionInfo(version.c_str(), renderer.c_str()));
}
return version_info_.get();
}
diff --git a/ui/gl/gl_context.h b/ui/gl/gl_context.h
index 66a7631..f40b1bb 100644
--- a/ui/gl/gl_context.h
+++ b/ui/gl/gl_context.h
@@ -108,6 +108,12 @@ class GL_EXPORT GLContext : public base::RefCounted<GLContext> {
// being released or destroyed.
void OnReleaseVirtuallyCurrent(GLContext* virtual_context);
+ // Returns the GL version string. The context must be current.
+ virtual std::string GetGLVersion();
+
+ // Returns the GL renderer string. The context must be current.
+ virtual std::string GetGLRenderer();
+
protected:
virtual ~GLContext();
@@ -123,9 +129,6 @@ class GL_EXPORT GLContext : public base::RefCounted<GLContext> {
// Returns the last real (non-virtual) GLContext made current.
static GLContext* GetRealCurrent();
- // Returns the GL version string. The context must be current.
- virtual std::string GetGLVersion();
-
private:
friend class base::RefCounted<GLContext>;
diff --git a/ui/gl/gl_context_stub.cc b/ui/gl/gl_context_stub.cc
index 56fb3c7..1d39d3e 100644
--- a/ui/gl/gl_context_stub.cc
+++ b/ui/gl/gl_context_stub.cc
@@ -39,6 +39,10 @@ std::string GLContextStub::GetExtensions() {
return std::string();
}
+std::string GLContextStub::GetGLRenderer() {
+ return std::string("CHROMIUM");
+}
+
GLContextStub::~GLContextStub() {}
} // namespace gfx
diff --git a/ui/gl/gl_context_stub.h b/ui/gl/gl_context_stub.h
index 8fca5b7..d57e02e 100644
--- a/ui/gl/gl_context_stub.h
+++ b/ui/gl/gl_context_stub.h
@@ -24,6 +24,7 @@ class GL_EXPORT GLContextStub : public GLContextReal {
virtual void* GetHandle() OVERRIDE;
virtual void SetSwapInterval(int interval) OVERRIDE;
virtual std::string GetExtensions() OVERRIDE;
+ virtual std::string GetGLRenderer() OVERRIDE;
protected:
virtual ~GLContextStub();
diff --git a/ui/gl/gl_gl_api_implementation.cc b/ui/gl/gl_gl_api_implementation.cc
index 9184fc3..fe98fba 100644
--- a/ui/gl/gl_gl_api_implementation.cc
+++ b/ui/gl/gl_gl_api_implementation.cc
@@ -14,6 +14,7 @@
#include "ui/gl/gl_state_restorer.h"
#include "ui/gl/gl_surface.h"
#include "ui/gl/gl_switches.h"
+#include "ui/gl/gl_version_info.h"
namespace gfx {
@@ -23,6 +24,8 @@ static GLApi* g_gl;
static RealGLApi* g_real_gl;
// A GL Api that calls TRACE and then calls another GL api.
static TraceGLApi* g_trace_gl;
+// GL version used when initializing dynamic bindings.
+static GLVersionInfo* g_version_info = NULL;
namespace {
@@ -40,7 +43,28 @@ static inline GLenum GetTexInternalFormat(GLenum internal_format,
GLenum type) {
GLenum gl_internal_format = GetInternalFormat(internal_format);
- if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
+ // g_version_info must be initialized when this function is bound.
+ DCHECK(gfx::g_version_info);
+ if (type == GL_FLOAT && gfx::g_version_info->is_angle &&
+ gfx::g_version_info->is_es2) {
+ // It's possible that the texture is using a sized internal format, and
+ // ANGLE exposing GLES2 API doesn't support those.
+ // TODO(oetuaho@nvidia.com): Remove these conversions once ANGLE has the
+ // support.
+ // http://code.google.com/p/angleproject/issues/detail?id=556
+ switch (format) {
+ case GL_RGBA:
+ gl_internal_format = GL_RGBA;
+ break;
+ case GL_RGB:
+ gl_internal_format = GL_RGB;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (gfx::g_version_info->is_es)
return gl_internal_format;
if (type == GL_FLOAT) {
@@ -208,6 +232,9 @@ void SetGLToRealGLApi() {
void InitializeDynamicGLBindingsGL(GLContext* context) {
g_driver_gl.InitializeCustomDynamicBindings(context);
+ DCHECK(context && context->IsCurrent(NULL) && !g_version_info);
+ g_version_info = new GLVersionInfo(context->GetGLVersion().c_str(),
+ context->GetGLRenderer().c_str());
}
void InitializeDebugGLBindingsGL() {
@@ -233,6 +260,10 @@ void ClearGLBindingsGL() {
delete g_current_gl_context_tls;
g_current_gl_context_tls = NULL;
}
+ if (g_version_info) {
+ delete g_version_info;
+ g_version_info = NULL;
+ }
}
GLApi::GLApi() {
diff --git a/ui/gl/gl_version_info.cc b/ui/gl/gl_version_info.cc
index a45219a..996c44f 100644
--- a/ui/gl/gl_version_info.cc
+++ b/ui/gl/gl_version_info.cc
@@ -8,7 +8,7 @@
namespace gfx {
-GLVersionInfo::GLVersionInfo(const char* version_str)
+GLVersionInfo::GLVersionInfo(const char* version_str, const char* renderer_str)
: is_es(false),
is_es1(false),
is_es2(false),
@@ -16,7 +16,8 @@ GLVersionInfo::GLVersionInfo(const char* version_str)
is_gl1(false),
is_gl2(false),
is_gl3(false),
- is_gl4(false) {
+ is_gl4(false),
+ is_angle(false) {
if (version_str) {
std::string lstr(StringToLowerASCII(std::string(version_str)));
is_es = (lstr.substr(0, 9) == "opengl es");
@@ -33,6 +34,9 @@ GLVersionInfo::GLVersionInfo(const char* version_str)
is_gl1 = !is_gl2 && !is_gl3 && !is_gl4;
}
}
+ if (renderer_str) {
+ is_angle = StartsWithASCII(renderer_str, "ANGLE", true);
+ }
}
} // namespace gfx
diff --git a/ui/gl/gl_version_info.h b/ui/gl/gl_version_info.h
index c8ecb07..13b323f 100644
--- a/ui/gl/gl_version_info.h
+++ b/ui/gl/gl_version_info.h
@@ -11,7 +11,7 @@
namespace gfx {
struct GLVersionInfo {
- explicit GLVersionInfo(const char* version_str);
+ GLVersionInfo(const char* version_str, const char* renderer_str);
// New flags, such as is_gl4_4 could be introduced as needed.
// For now, this level of granularity is enough.
@@ -25,6 +25,8 @@ struct GLVersionInfo {
bool is_gl3;
bool is_gl4;
+ bool is_angle;
+
private:
DISALLOW_COPY_AND_ASSIGN(GLVersionInfo);
};