summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'gpu')
-rw-r--r--gpu/command_buffer/client/gles2_implementation.cc38
-rw-r--r--gpu/command_buffer/client/gles2_implementation.h3
-rw-r--r--gpu/command_buffer/service/context_group.cc193
-rw-r--r--gpu/command_buffer/service/context_group.h39
-rw-r--r--gpu/command_buffer/service/context_group_unittest.cc338
-rw-r--r--gpu/command_buffer/service/feature_info.cc266
-rw-r--r--gpu/command_buffer/service/feature_info.h74
-rw-r--r--gpu/command_buffer/service/feature_info_unittest.cc380
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc65
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.h7
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc4
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h6
-rw-r--r--gpu/command_buffer/service/gles2_cmd_validation.h4
-rw-r--r--gpu/command_buffer/service/gpu_processor.cc6
-rw-r--r--gpu/command_buffer/service/test_helper.cc24
-rw-r--r--gpu/command_buffer/service/test_helper.h6
-rw-r--r--gpu/command_buffer/service/texture_manager.cc84
-rw-r--r--gpu/command_buffer/service/texture_manager.h57
-rw-r--r--gpu/command_buffer/service/texture_manager_unittest.cc270
-rw-r--r--gpu/gpu.gyp3
20 files changed, 1081 insertions, 786 deletions
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index 58ddd2b..d9cbd4c 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -1144,22 +1144,32 @@ void GLES2Implementation::GetShaderPrecisionFormat(
}
const GLubyte* GLES2Implementation::GetString(GLenum name) {
- const char* result;
- GLStringMap::const_iterator it = gl_strings_.find(name);
- if (it != gl_strings_.end()) {
- result = it->second.c_str();
- } else {
- // Clear the bucket so if we the command fails nothing will be in it.
- helper_->SetBucketSize(kResultBucketId, 0);
- helper_->GetString(name, kResultBucketId);
- std::string str;
- if (GetBucketAsString(kResultBucketId, &str)) {
- std::pair<GLStringMap::const_iterator, bool> insert_result =
- gl_strings_.insert(std::make_pair(name, str));
+ const char* result = NULL;
+ // Clear the bucket so if the command fails nothing will be in it.
+ helper_->SetBucketSize(kResultBucketId, 0);
+ helper_->GetString(name, kResultBucketId);
+ std::string str;
+ if (GetBucketAsString(kResultBucketId, &str)) {
+ // Because of WebGL the extensions can change. We have to cache each
+ // unique result since we don't know when the client will stop referring to
+ // a previous one it queries.
+ GLStringMap::iterator it = gl_strings_.find(name);
+ if (it == gl_strings_.end()) {
+ std::set<std::string> strings;
+ std::pair<GLStringMap::iterator, bool> insert_result =
+ gl_strings_.insert(std::make_pair(name, strings));
GPU_DCHECK(insert_result.second);
- result = insert_result.first->second.c_str();
+ it = insert_result.first;
+ }
+ std::set<std::string>& string_set = it->second;
+ std::set<std::string>::const_iterator sit = string_set.find(str);
+ if (sit != string_set.end()) {
+ result = sit->c_str();
} else {
- result = NULL;
+ std::pair<std::set<std::string>::const_iterator, bool> insert_result =
+ string_set.insert(str);
+ GPU_DCHECK(insert_result.second);
+ result = insert_result.first->c_str();
}
}
return reinterpret_cast<const GLubyte*>(result);
diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h
index ef702fd..0b0e242 100644
--- a/gpu/command_buffer/client/gles2_implementation.h
+++ b/gpu/command_buffer/client/gles2_implementation.h
@@ -8,6 +8,7 @@
#include <GLES2/gl2.h>
#include <map>
+#include <set>
#include <string>
#include <vector>
@@ -375,7 +376,7 @@ class GLES2Implementation {
// Map of GLenum to Strings for glGetString. We need to cache these because
// the pointer passed back to the client has to remain valid for eternity.
- typedef std::map<uint32, std::string> GLStringMap;
+ typedef std::map<uint32, std::set<std::string> > GLStringMap;
GLStringMap gl_strings_;
typedef std::map<const void*, MappedBuffer> MappedBufferMap;
diff --git a/gpu/command_buffer/service/context_group.cc b/gpu/command_buffer/service/context_group.cc
index 358e149..c2c9c1f 100644
--- a/gpu/command_buffer/service/context_group.cc
+++ b/gpu/command_buffer/service/context_group.cc
@@ -43,189 +43,19 @@ static void GetIntegerv(GLenum pname, uint32* var) {
*var = value;
}
-bool ContextGroup::Initialize() {
- if (initialized_) {
- return true;
- }
-
- // Figure out what extensions to turn on.
- const char* extensions =
- reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
- bool npot_ok = false;
-
- AddExtensionString("GL_CHROMIUM_map_sub");
-
- // Check if we should allow GL_EXT_texture_compression_dxt1 and
- // GL_EXT_texture_compression_s3tc.
- bool enable_dxt1 = false;
- bool enable_s3tc = false;
- if (strstr(extensions, "GL_EXT_texture_compression_dxt1")) {
- enable_dxt1 = true;
- }
- if (strstr(extensions, "GL_EXT_texture_compression_s3tc")) {
- enable_dxt1 = true;
- enable_s3tc = true;
- }
-
- if (enable_dxt1) {
- AddExtensionString("GL_EXT_texture_compression_dxt1");
- validators_.compressed_texture_format.AddValue(
- GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
- validators_.compressed_texture_format.AddValue(
- GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
- }
-
- if (enable_s3tc) {
- AddExtensionString("GL_EXT_texture_compression_s3tc");
- validators_.compressed_texture_format.AddValue(
- GL_COMPRESSED_RGBA_S3TC_DXT3_EXT);
- validators_.compressed_texture_format.AddValue(
- GL_COMPRESSED_RGBA_S3TC_DXT5_EXT);
- }
- // Check if we should enable GL_EXT_texture_filter_anisotropic.
- if (strstr(extensions, "GL_EXT_texture_filter_anisotropic")) {
- AddExtensionString("GL_EXT_texture_filter_anisotropic");
- validators_.texture_parameter.AddValue(
- GL_TEXTURE_MAX_ANISOTROPY_EXT);
- validators_.g_l_state.AddValue(
- GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT);
- }
-
- // Check if we should support GL_OES_packed_depth_stencil and/or
- // GL_GOOGLE_depth_texture.
- // NOTE: GL_OES_depth_texture requires support for depth
- // cubemaps. GL_ARB_depth_texture requires other features that
- // GL_OES_packed_depth_stencil does not provide. Therefore we made up
- // GL_GOOGLE_depth_texture.
- bool enable_depth_texture = false;
- if (strstr(extensions, "GL_ARB_depth_texture") ||
- strstr(extensions, "GL_OES_depth_texture")) {
- enable_depth_texture = true;
- AddExtensionString("GL_GOOGLE_depth_texture");
- validators_.texture_internal_format.AddValue(GL_DEPTH_COMPONENT);
- validators_.texture_format.AddValue(GL_DEPTH_COMPONENT);
- validators_.pixel_type.AddValue(GL_UNSIGNED_SHORT);
- validators_.pixel_type.AddValue(GL_UNSIGNED_INT);
- }
- // TODO(gman): Add depth types fo ElementsPerGroup and BytesPerElement
-
- if (strstr(extensions, "GL_EXT_packed_depth_stencil") ||
- strstr(extensions, "GL_OES_packed_depth_stencil")) {
- AddExtensionString("GL_OES_packed_depth_stencil");
- if (enable_depth_texture) {
- validators_.texture_internal_format.AddValue(GL_DEPTH_STENCIL);
- validators_.texture_format.AddValue(GL_DEPTH_STENCIL);
- validators_.pixel_type.AddValue(GL_UNSIGNED_INT_24_8);
- }
- validators_.render_buffer_format.AddValue(GL_DEPTH24_STENCIL8);
- }
-
- bool enable_texture_format_bgra8888 = false;
- bool enable_read_format_bgra = false;
- // Check if we should allow GL_EXT_texture_format_BGRA8888
- if (strstr(extensions, "GL_EXT_texture_format_BGRA8888") ||
- strstr(extensions, "GL_APPLE_texture_format_BGRA8888")) {
- enable_texture_format_bgra8888 = true;
- }
-
- if (strstr(extensions, "GL_EXT_bgra")) {
- enable_texture_format_bgra8888 = true;
- enable_read_format_bgra = true;
- }
-
- if (strstr(extensions, "GL_EXT_read_format_bgra")) {
- enable_read_format_bgra = true;
- }
-
- if (enable_texture_format_bgra8888) {
- AddExtensionString("GL_EXT_texture_format_BGRA8888");
- validators_.texture_internal_format.AddValue(GL_BGRA_EXT);
- validators_.texture_format.AddValue(GL_BGRA_EXT);
- }
-
- if (enable_read_format_bgra) {
- AddExtensionString("GL_EXT_read_format_bgra");
- validators_.read_pixel_format.AddValue(GL_BGRA_EXT);
- }
-
- // Check if we should allow GL_OES_texture_npot
- if (strstr(extensions, "GL_ARB_texture_non_power_of_two") ||
- strstr(extensions, "GL_OES_texture_npot")) {
- AddExtensionString("GL_OES_texture_npot");
- npot_ok = true;
- }
-
- // Check if we should allow GL_OES_texture_float, GL_OES_texture_half_float,
- // GL_OES_texture_float_linear, GL_OES_texture_half_float_linear
- bool enable_texture_float = false;
- bool enable_texture_float_linear = false;
- bool enable_texture_half_float = false;
- bool enable_texture_half_float_linear = false;
- if (strstr(extensions, "GL_ARB_texture_float")) {
- enable_texture_float = true;
- enable_texture_float_linear = true;
- enable_texture_half_float = true;
- enable_texture_half_float_linear = true;
- } else {
- if (strstr(extensions, "GL_OES_texture_float")) {
- enable_texture_float = true;
- if (strstr(extensions, "GL_OES_texture_float_linear")) {
- enable_texture_float_linear = true;
- }
- }
- if (strstr(extensions, "GL_OES_texture_half_float")) {
- enable_texture_half_float = true;
- if (strstr(extensions, "GL_OES_texture_half_float_linear")) {
- enable_texture_half_float_linear = true;
- }
- }
- }
-
- if (enable_texture_float) {
- validators_.pixel_type.AddValue(GL_FLOAT);
- AddExtensionString("GL_OES_texture_float");
- if (enable_texture_float_linear) {
- AddExtensionString("GL_OES_texture_float_linear");
- }
- }
-
- if (enable_texture_half_float) {
- validators_.pixel_type.AddValue(GL_HALF_FLOAT_OES);
- AddExtensionString("GL_OES_texture_half_float");
- if (enable_texture_half_float_linear) {
- AddExtensionString("GL_OES_texture_half_float_linear");
- }
- }
-
- // Check for multisample support
- if (strstr(extensions, "GL_EXT_framebuffer_multisample")) {
- extension_flags_.ext_framebuffer_multisample = true;
- validators_.frame_buffer_target.AddValue(GL_READ_FRAMEBUFFER_EXT);
- validators_.frame_buffer_target.AddValue(GL_DRAW_FRAMEBUFFER_EXT);
- validators_.g_l_state.AddValue(GL_READ_FRAMEBUFFER_BINDING_EXT);
- validators_.render_buffer_parameter.AddValue(GL_MAX_SAMPLES_EXT);
- AddExtensionString("GL_EXT_framebuffer_multisample");
- AddExtensionString("GL_EXT_framebuffer_blit");
- }
-
- if (strstr(extensions, "GL_OES_depth24") ||
- gfx::GetGLImplementation() == gfx::kGLImplementationDesktopGL) {
- AddExtensionString("GL_OES_depth24");
- validators_.render_buffer_format.AddValue(GL_DEPTH_COMPONENT24);
+bool ContextGroup::Initialize(const char* allowed_features) {
+ if (initialized_) {
+ return true;
}
- if (strstr(extensions, "GL_OES_standard_derivatives") ||
- gfx::GetGLImplementation() == gfx::kGLImplementationDesktopGL) {
- AddExtensionString("GL_OES_standard_derivatives");
- extension_flags_.oes_standard_derivatives = true;
+ if (!feature_info_.Initialize(allowed_features)) {
+ LOG(ERROR) << "ContextGroup::Initialize failed because FeatureInfo "
+ << "initialization failed.";
+ return false;
}
- // TODO(gman): Add support for these extensions.
- // GL_OES_depth32
- // GL_OES_element_index_uint
-
buffer_manager_.reset(new BufferManager());
framebuffer_manager_.reset(new FramebufferManager());
renderbuffer_manager_.reset(new RenderbufferManager());
@@ -253,10 +83,7 @@ bool ContextGroup::Initialize() {
GLint max_cube_map_texture_size;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_texture_size);
- texture_manager_.reset(new TextureManager(npot_ok,
- enable_texture_float_linear,
- enable_texture_half_float_linear,
- max_texture_size,
+ texture_manager_.reset(new TextureManager(max_texture_size,
max_cube_map_texture_size));
GetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max_texture_image_units_);
@@ -320,10 +147,6 @@ void ContextGroup::Destroy(bool have_context) {
}
}
-void ContextGroup::AddExtensionString(const std::string& str) {
- extensions_ += (extensions_.empty() ? "" : " ") + str;
-}
-
IdAllocator* ContextGroup::GetIdAllocator(unsigned namespace_id) {
IdAllocatorMap::iterator it = id_namespaces_.find(namespace_id);
if (it != id_namespaces_.end()) {
diff --git a/gpu/command_buffer/service/context_group.h b/gpu/command_buffer/service/context_group.h
index e48cacd..4df515c 100644
--- a/gpu/command_buffer/service/context_group.h
+++ b/gpu/command_buffer/service/context_group.h
@@ -11,6 +11,7 @@
#include "base/linked_ptr.h"
#include "base/scoped_ptr.h"
#include "gpu/command_buffer/service/gles2_cmd_validation.h"
+#include "gpu/command_buffer/service/feature_info.h"
namespace gpu {
@@ -30,21 +31,11 @@ class TextureManager;
// resources.
class ContextGroup {
public:
- struct ExtensionFlags {
- ExtensionFlags()
- : ext_framebuffer_multisample(false),
- oes_standard_derivatives(false) {
- }
-
- bool ext_framebuffer_multisample;
- bool oes_standard_derivatives;
- };
-
ContextGroup();
~ContextGroup();
// This should only be called by GLES2Decoder.
- bool Initialize();
+ bool Initialize(const char* allowed_features);
// Destroys all the resources. MUST be called before destruction.
void Destroy(bool have_context);
@@ -77,6 +68,10 @@ class ContextGroup {
return max_vertex_uniform_vectors_;
}
+ FeatureInfo* feature_info() {
+ return &feature_info_;
+ }
+
BufferManager* buffer_manager() const {
return buffer_manager_.get();
}
@@ -103,21 +98,7 @@ class ContextGroup {
IdAllocator* GetIdAllocator(unsigned namepsace_id);
- const Validators* validators() const {
- return &validators_;
- }
-
- const std::string& extensions() const {
- return extensions_;
- }
-
- const ExtensionFlags& extension_flags() const {
- return extension_flags_;
- }
-
private:
- void AddExtensionString(const std::string& str);
-
// Whether or not this context is initialized.
bool initialized_;
@@ -144,13 +125,7 @@ class ContextGroup {
typedef std::map<uint32, linked_ptr<IdAllocator> > IdAllocatorMap;
IdAllocatorMap id_namespaces_;
- Validators validators_;
-
- // The extensions string returned by glGetString(GL_EXTENSIONS);
- std::string extensions_;
-
- // Flags for some extensions
- ExtensionFlags extension_flags_;
+ FeatureInfo feature_info_;
DISALLOW_COPY_AND_ASSIGN(ContextGroup);
};
diff --git a/gpu/command_buffer/service/context_group_unittest.cc b/gpu/command_buffer/service/context_group_unittest.cc
index 4384ea6..4cfd4c7 100644
--- a/gpu/command_buffer/service/context_group_unittest.cc
+++ b/gpu/command_buffer/service/context_group_unittest.cc
@@ -32,10 +32,6 @@ class ContextGroupTest : public testing::Test {
ContextGroupTest() {
}
- void SetupInitExpectations(const char* extensions) {
- TestHelper::SetupContextGroupInitExpectations(gl_.get(), extensions);
- }
-
protected:
virtual void SetUp() {
gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>());
@@ -67,321 +63,31 @@ TEST_F(ContextGroupTest, Basic) {
EXPECT_TRUE(group_.texture_manager() == NULL);
EXPECT_TRUE(group_.program_manager() == NULL);
EXPECT_TRUE(group_.shader_manager() == NULL);
- EXPECT_FALSE(group_.extension_flags().ext_framebuffer_multisample);
- EXPECT_FALSE(group_.extension_flags().oes_standard_derivatives);
}
TEST_F(ContextGroupTest, InitializeNoExtensions) {
- SetupInitExpectations("");
- group_.Initialize();
- // Check a couple of random extensions that should not be there.
- EXPECT_THAT(group_.extensions(), Not(HasSubstr("GL_OES_texture_npot")));
- EXPECT_THAT(group_.extensions(),
- Not(HasSubstr("GL_EXT_texture_compression_dxt1")));
- EXPECT_FALSE(group_.texture_manager()->npot_ok());
- EXPECT_FALSE(group_.validators()->compressed_texture_format.IsValid(
- GL_COMPRESSED_RGB_S3TC_DXT1_EXT));
- EXPECT_FALSE(group_.validators()->compressed_texture_format.IsValid(
- GL_COMPRESSED_RGBA_S3TC_DXT1_EXT));
- EXPECT_FALSE(group_.validators()->compressed_texture_format.IsValid(
- GL_COMPRESSED_RGBA_S3TC_DXT3_EXT));
- EXPECT_FALSE(group_.validators()->compressed_texture_format.IsValid(
- GL_COMPRESSED_RGBA_S3TC_DXT5_EXT));
- EXPECT_FALSE(group_.validators()->read_pixel_format.IsValid(
- GL_BGRA_EXT));
- EXPECT_FALSE(group_.validators()->texture_parameter.IsValid(
- GL_TEXTURE_MAX_ANISOTROPY_EXT));
- EXPECT_FALSE(group_.validators()->g_l_state.IsValid(
- GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT));
- EXPECT_FALSE(group_.validators()->frame_buffer_target.IsValid(
- GL_READ_FRAMEBUFFER_EXT));
- EXPECT_FALSE(group_.validators()->frame_buffer_target.IsValid(
- GL_DRAW_FRAMEBUFFER_EXT));
- EXPECT_FALSE(group_.validators()->g_l_state.IsValid(
- GL_READ_FRAMEBUFFER_BINDING_EXT));
- EXPECT_FALSE(group_.validators()->render_buffer_parameter.IsValid(
- GL_MAX_SAMPLES_EXT));
- EXPECT_FALSE(group_.validators()->texture_internal_format.IsValid(
- GL_DEPTH_COMPONENT));
- EXPECT_FALSE(group_.validators()->texture_format.IsValid(GL_DEPTH_COMPONENT));
- EXPECT_FALSE(group_.validators()->pixel_type.IsValid(GL_UNSIGNED_SHORT));
- EXPECT_FALSE(group_.validators()->pixel_type.IsValid(GL_UNSIGNED_INT));
- EXPECT_FALSE(group_.validators()->render_buffer_format.IsValid(
- GL_DEPTH24_STENCIL8));
- EXPECT_FALSE(group_.validators()->texture_internal_format.IsValid(
- GL_DEPTH_STENCIL));
- EXPECT_FALSE(group_.validators()->texture_format.IsValid(
- GL_DEPTH_STENCIL));
- EXPECT_FALSE(group_.validators()->pixel_type.IsValid(
- GL_UNSIGNED_INT_24_8));
- EXPECT_FALSE(group_.validators()->render_buffer_format.IsValid(
- GL_DEPTH_COMPONENT24));
-}
-
-TEST_F(ContextGroupTest, InitializeNPOTExtensionGLES) {
- SetupInitExpectations("GL_OES_texture_npot");
- group_.Initialize();
- EXPECT_THAT(group_.extensions(), HasSubstr("GL_OES_texture_npot"));
- EXPECT_TRUE(group_.texture_manager()->npot_ok());
-}
-
-TEST_F(ContextGroupTest, InitializeNPOTExtensionGL) {
- SetupInitExpectations("GL_ARB_texture_non_power_of_two");
- group_.Initialize();
- EXPECT_THAT(group_.extensions(), HasSubstr("GL_OES_texture_npot"));
- EXPECT_TRUE(group_.texture_manager()->npot_ok());
-}
-
-TEST_F(ContextGroupTest, InitializeDXTExtensionGLES2) {
- SetupInitExpectations("GL_EXT_texture_compression_dxt1");
- group_.Initialize();
- EXPECT_THAT(group_.extensions(),
- HasSubstr("GL_EXT_texture_compression_dxt1"));
- EXPECT_TRUE(group_.validators()->compressed_texture_format.IsValid(
- GL_COMPRESSED_RGB_S3TC_DXT1_EXT));
- EXPECT_TRUE(group_.validators()->compressed_texture_format.IsValid(
- GL_COMPRESSED_RGBA_S3TC_DXT1_EXT));
- EXPECT_FALSE(group_.validators()->compressed_texture_format.IsValid(
- GL_COMPRESSED_RGBA_S3TC_DXT3_EXT));
- EXPECT_FALSE(group_.validators()->compressed_texture_format.IsValid(
- GL_COMPRESSED_RGBA_S3TC_DXT5_EXT));
-}
-
-TEST_F(ContextGroupTest, InitializeDXTExtensionGL) {
- SetupInitExpectations("GL_EXT_texture_compression_s3tc");
- group_.Initialize();
- EXPECT_THAT(group_.extensions(),
- HasSubstr("GL_EXT_texture_compression_dxt1"));
- EXPECT_THAT(group_.extensions(),
- HasSubstr("GL_EXT_texture_compression_s3tc"));
- EXPECT_TRUE(group_.validators()->compressed_texture_format.IsValid(
- GL_COMPRESSED_RGB_S3TC_DXT1_EXT));
- EXPECT_TRUE(group_.validators()->compressed_texture_format.IsValid(
- GL_COMPRESSED_RGBA_S3TC_DXT1_EXT));
- EXPECT_TRUE(group_.validators()->compressed_texture_format.IsValid(
- GL_COMPRESSED_RGBA_S3TC_DXT3_EXT));
- EXPECT_TRUE(group_.validators()->compressed_texture_format.IsValid(
- GL_COMPRESSED_RGBA_S3TC_DXT5_EXT));
-}
-
-TEST_F(ContextGroupTest, InitializeEXT_texture_format_BGRA8888GLES2) {
- SetupInitExpectations("GL_EXT_texture_format_BGRA8888");
- group_.Initialize();
- EXPECT_THAT(group_.extensions(),
- HasSubstr("GL_EXT_texture_format_BGRA8888"));
- EXPECT_TRUE(group_.validators()->texture_format.IsValid(
- GL_BGRA_EXT));
- EXPECT_TRUE(group_.validators()->texture_internal_format.IsValid(
- GL_BGRA_EXT));
-}
-
-TEST_F(ContextGroupTest, InitializeEXT_texture_format_BGRA8888GL) {
- SetupInitExpectations("GL_EXT_bgra");
- group_.Initialize();
- EXPECT_THAT(group_.extensions(),
- HasSubstr("GL_EXT_texture_format_BGRA8888"));
- EXPECT_THAT(group_.extensions(),
- HasSubstr("GL_EXT_read_format_bgra"));
- EXPECT_TRUE(group_.validators()->texture_format.IsValid(
- GL_BGRA_EXT));
- EXPECT_TRUE(group_.validators()->texture_internal_format.IsValid(
- GL_BGRA_EXT));
- EXPECT_TRUE(group_.validators()->read_pixel_format.IsValid(
- GL_BGRA_EXT));
-}
-
-TEST_F(ContextGroupTest, InitializeEXT_texture_format_BGRA8888Apple) {
- SetupInitExpectations("GL_APPLE_texture_format_BGRA8888");
- group_.Initialize();
- EXPECT_THAT(group_.extensions(),
- HasSubstr("GL_EXT_texture_format_BGRA8888"));
- EXPECT_TRUE(group_.validators()->texture_format.IsValid(
- GL_BGRA_EXT));
- EXPECT_TRUE(group_.validators()->texture_internal_format.IsValid(
- GL_BGRA_EXT));
-}
-
-TEST_F(ContextGroupTest, InitializeEXT_read_format_bgra) {
- SetupInitExpectations("GL_EXT_read_format_bgra");
- group_.Initialize();
- EXPECT_THAT(group_.extensions(),
- HasSubstr("GL_EXT_read_format_bgra"));
- EXPECT_FALSE(group_.validators()->texture_format.IsValid(
- GL_BGRA_EXT));
- EXPECT_FALSE(group_.validators()->texture_internal_format.IsValid(
- GL_BGRA_EXT));
- EXPECT_TRUE(group_.validators()->read_pixel_format.IsValid(
- GL_BGRA_EXT));
-}
-
-TEST_F(ContextGroupTest, InitializeOES_texture_floatGLES2) {
- SetupInitExpectations("GL_OES_texture_float");
- group_.Initialize();
- EXPECT_FALSE(group_.texture_manager()->enable_float_linear());
- EXPECT_FALSE(group_.texture_manager()->enable_half_float_linear());
- EXPECT_THAT(group_.extensions(), HasSubstr("GL_OES_texture_float"));
- EXPECT_THAT(group_.extensions(), Not(HasSubstr("GL_OES_texture_half_float")));
- EXPECT_THAT(group_.extensions(),
- Not(HasSubstr("GL_OES_texture_float_linear")));
- EXPECT_THAT(group_.extensions(),
- Not(HasSubstr("GL_OES_texture_half_float_linear")));
- EXPECT_TRUE(group_.validators()->pixel_type.IsValid(GL_FLOAT));
- EXPECT_FALSE(group_.validators()->pixel_type.IsValid(GL_HALF_FLOAT_OES));
-}
-
-TEST_F(ContextGroupTest, InitializeOES_texture_float_linearGLES2) {
- SetupInitExpectations("GL_OES_texture_float GL_OES_texture_float_linear");
- group_.Initialize();
- EXPECT_TRUE(group_.texture_manager()->enable_float_linear());
- EXPECT_FALSE(group_.texture_manager()->enable_half_float_linear());
- EXPECT_THAT(group_.extensions(), HasSubstr("GL_OES_texture_float"));
- EXPECT_THAT(group_.extensions(), Not(HasSubstr("GL_OES_texture_half_float")));
- EXPECT_THAT(group_.extensions(), HasSubstr("GL_OES_texture_float_linear"));
- EXPECT_THAT(group_.extensions(),
- Not(HasSubstr("GL_OES_texture_half_float_linear")));
- EXPECT_TRUE(group_.validators()->pixel_type.IsValid(GL_FLOAT));
- EXPECT_FALSE(group_.validators()->pixel_type.IsValid(GL_HALF_FLOAT_OES));
-}
-
-TEST_F(ContextGroupTest, InitializeOES_texture_half_floatGLES2) {
- SetupInitExpectations("GL_OES_texture_half_float");
- group_.Initialize();
- EXPECT_FALSE(group_.texture_manager()->enable_float_linear());
- EXPECT_FALSE(group_.texture_manager()->enable_half_float_linear());
- EXPECT_THAT(group_.extensions(), Not(HasSubstr("GL_OES_texture_float")));
- EXPECT_THAT(group_.extensions(), HasSubstr("GL_OES_texture_half_float"));
- EXPECT_THAT(group_.extensions(),
- Not(HasSubstr("GL_OES_texture_float_linear")));
- EXPECT_THAT(group_.extensions(),
- Not(HasSubstr("GL_OES_texture_half_float_linear")));
- EXPECT_FALSE(group_.validators()->pixel_type.IsValid(GL_FLOAT));
- EXPECT_TRUE(group_.validators()->pixel_type.IsValid(GL_HALF_FLOAT_OES));
-}
-
-TEST_F(ContextGroupTest, InitializeOES_texture_half_float_linearGLES2) {
- SetupInitExpectations(
- "GL_OES_texture_half_float GL_OES_texture_half_float_linear");
- group_.Initialize();
- EXPECT_FALSE(group_.texture_manager()->enable_float_linear());
- EXPECT_TRUE(group_.texture_manager()->enable_half_float_linear());
- EXPECT_THAT(group_.extensions(), Not(HasSubstr("GL_OES_texture_float")));
- EXPECT_THAT(group_.extensions(), HasSubstr("GL_OES_texture_half_float"));
- EXPECT_THAT(group_.extensions(),
- Not(HasSubstr("GL_OES_texture_float_linear")));
- EXPECT_THAT(group_.extensions(),
- HasSubstr("GL_OES_texture_half_float_linear"));
- EXPECT_FALSE(group_.validators()->pixel_type.IsValid(GL_FLOAT));
- EXPECT_TRUE(group_.validators()->pixel_type.IsValid(GL_HALF_FLOAT_OES));
-}
-
-TEST_F(ContextGroupTest, InitializeEXT_framebuffer_multisample) {
- SetupInitExpectations("GL_EXT_framebuffer_multisample");
- group_.Initialize();
- EXPECT_TRUE(group_.extension_flags().ext_framebuffer_multisample);
- EXPECT_THAT(group_.extensions(), HasSubstr("GL_EXT_framebuffer_multisample"));
- EXPECT_THAT(group_.extensions(), HasSubstr("GL_EXT_framebuffer_blit"));
- EXPECT_TRUE(group_.validators()->frame_buffer_target.IsValid(
- GL_READ_FRAMEBUFFER_EXT));
- EXPECT_TRUE(group_.validators()->frame_buffer_target.IsValid(
- GL_DRAW_FRAMEBUFFER_EXT));
- EXPECT_TRUE(group_.validators()->g_l_state.IsValid(
- GL_READ_FRAMEBUFFER_BINDING_EXT));
- EXPECT_TRUE(group_.validators()->render_buffer_parameter.IsValid(
- GL_MAX_SAMPLES_EXT));
-}
-
-TEST_F(ContextGroupTest, InitializeEXT_texture_filter_anisotropic) {
- SetupInitExpectations("GL_EXT_texture_filter_anisotropic");
- group_.Initialize();
- EXPECT_THAT(group_.extensions(),
- HasSubstr("GL_EXT_texture_filter_anisotropic"));
- EXPECT_TRUE(group_.validators()->texture_parameter.IsValid(
- GL_TEXTURE_MAX_ANISOTROPY_EXT));
- EXPECT_TRUE(group_.validators()->g_l_state.IsValid(
- GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT));
-}
-
-TEST_F(ContextGroupTest, InitializeEXT_ARB_depth_texture) {
- SetupInitExpectations("GL_ARB_depth_texture");
- group_.Initialize();
- EXPECT_THAT(group_.extensions(),
- HasSubstr("GL_GOOGLE_depth_texture"));
- EXPECT_TRUE(group_.validators()->texture_internal_format.IsValid(
- GL_DEPTH_COMPONENT));
- EXPECT_TRUE(group_.validators()->texture_format.IsValid(GL_DEPTH_COMPONENT));
- EXPECT_TRUE(group_.validators()->pixel_type.IsValid(GL_UNSIGNED_SHORT));
- EXPECT_TRUE(group_.validators()->pixel_type.IsValid(GL_UNSIGNED_INT));
-}
-
-TEST_F(ContextGroupTest, InitializeOES_ARB_depth_texture) {
- SetupInitExpectations("GL_OES_depth_texture");
- group_.Initialize();
- EXPECT_THAT(group_.extensions(),
- HasSubstr("GL_GOOGLE_depth_texture"));
- EXPECT_TRUE(group_.validators()->texture_internal_format.IsValid(
- GL_DEPTH_COMPONENT));
- EXPECT_TRUE(group_.validators()->texture_format.IsValid(GL_DEPTH_COMPONENT));
- EXPECT_TRUE(group_.validators()->pixel_type.IsValid(GL_UNSIGNED_SHORT));
- EXPECT_TRUE(group_.validators()->pixel_type.IsValid(GL_UNSIGNED_INT));
-}
-
-TEST_F(ContextGroupTest, InitializeEXT_packed_depth_stencil) {
- SetupInitExpectations("GL_EXT_packed_depth_stencil");
- group_.Initialize();
- EXPECT_THAT(group_.extensions(),
- HasSubstr("GL_OES_packed_depth_stencil"));
- EXPECT_TRUE(group_.validators()->render_buffer_format.IsValid(
- GL_DEPTH24_STENCIL8));
- EXPECT_FALSE(group_.validators()->texture_internal_format.IsValid(
- GL_DEPTH_COMPONENT));
- EXPECT_FALSE(group_.validators()->texture_format.IsValid(GL_DEPTH_COMPONENT));
- EXPECT_FALSE(group_.validators()->pixel_type.IsValid(GL_UNSIGNED_SHORT));
- EXPECT_FALSE(group_.validators()->pixel_type.IsValid(GL_UNSIGNED_INT));
-}
-
-TEST_F(ContextGroupTest, InitializeOES_packed_depth_stencil) {
- SetupInitExpectations("GL_OES_packed_depth_stencil");
- group_.Initialize();
- EXPECT_THAT(group_.extensions(),
- HasSubstr("GL_OES_packed_depth_stencil"));
- EXPECT_TRUE(group_.validators()->render_buffer_format.IsValid(
- GL_DEPTH24_STENCIL8));
- EXPECT_FALSE(group_.validators()->texture_internal_format.IsValid(
- GL_DEPTH_COMPONENT));
- EXPECT_FALSE(group_.validators()->texture_format.IsValid(GL_DEPTH_COMPONENT));
- EXPECT_FALSE(group_.validators()->pixel_type.IsValid(GL_UNSIGNED_SHORT));
- EXPECT_FALSE(group_.validators()->pixel_type.IsValid(GL_UNSIGNED_INT));
-}
-
-TEST_F(ContextGroupTest,
- InitializeOES_packed_depth_stencil_and_GL_ARB_depth_texture) {
- SetupInitExpectations("GL_OES_packed_depth_stencil GL_ARB_depth_texture");
- group_.Initialize();
- EXPECT_THAT(group_.extensions(),
- HasSubstr("GL_OES_packed_depth_stencil"));
- EXPECT_TRUE(group_.validators()->render_buffer_format.IsValid(
- GL_DEPTH24_STENCIL8));
- EXPECT_TRUE(group_.validators()->texture_internal_format.IsValid(
- GL_DEPTH_STENCIL));
- EXPECT_TRUE(group_.validators()->texture_format.IsValid(
- GL_DEPTH_STENCIL));
- EXPECT_TRUE(group_.validators()->pixel_type.IsValid(
- GL_UNSIGNED_INT_24_8));
-}
-
-TEST_F(ContextGroupTest, InitializeOES_depth24) {
- SetupInitExpectations("GL_OES_depth24");
- group_.Initialize();
- EXPECT_THAT(group_.extensions(), HasSubstr("GL_OES_depth24"));
- EXPECT_TRUE(group_.validators()->render_buffer_format.IsValid(
- GL_DEPTH_COMPONENT24));
-}
-
-TEST_F(ContextGroupTest, InitializeOES_standard_derivatives) {
- SetupInitExpectations("GL_OES_standard_derivatives");
- group_.Initialize();
- EXPECT_THAT(group_.extensions(), HasSubstr("GL_OES_standard_derivatives"));
- EXPECT_TRUE(group_.extension_flags().oes_standard_derivatives);
+ TestHelper::SetupContextGroupInitExpectations(gl_.get(), "");
+ group_.Initialize("");
+ EXPECT_EQ(static_cast<uint32>(TestHelper::kNumVertexAttribs),
+ group_.max_vertex_attribs());
+ EXPECT_EQ(static_cast<uint32>(TestHelper::kNumTextureUnits),
+ group_.max_texture_units());
+ EXPECT_EQ(static_cast<uint32>(TestHelper::kMaxTextureImageUnits),
+ group_.max_texture_image_units());
+ EXPECT_EQ(static_cast<uint32>(TestHelper::kMaxVertexTextureImageUnits),
+ group_.max_vertex_texture_image_units());
+ EXPECT_EQ(static_cast<uint32>(TestHelper::kMaxFragmentUniformVectors),
+ group_.max_fragment_uniform_vectors());
+ EXPECT_EQ(static_cast<uint32>(TestHelper::kMaxVaryingVectors),
+ group_.max_varying_vectors());
+ EXPECT_EQ(static_cast<uint32>(TestHelper::kMaxVertexUniformVectors),
+ group_.max_vertex_uniform_vectors());
+ EXPECT_TRUE(group_.buffer_manager() != NULL);
+ EXPECT_TRUE(group_.framebuffer_manager() != NULL);
+ EXPECT_TRUE(group_.renderbuffer_manager() != NULL);
+ EXPECT_TRUE(group_.texture_manager() != NULL);
+ EXPECT_TRUE(group_.program_manager() != NULL);
+ EXPECT_TRUE(group_.shader_manager() != NULL);
}
} // namespace gles2
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
new file mode 100644
index 0000000..883dcd0
--- /dev/null
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -0,0 +1,266 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <set>
+#include <string>
+#include "app/gfx/gl/gl_implementation.h"
+#include "gpu/command_buffer/service/feature_info.h"
+#include "gpu/command_buffer/service/gl_utils.h"
+#include "gpu/GLES2/gles2_command_buffer.h"
+
+namespace gpu {
+namespace gles2 {
+
+FeatureInfo::FeatureInfo() {
+}
+
+// Helps query for extensions.
+class ExtensionHelper {
+ public:
+ ExtensionHelper(const char* extensions, const char* allowed_features) {
+ std::set<std::string> sets[2];
+
+ for (int ii = 0; ii < 2; ++ii) {
+ const char* s = (ii == 0 ? extensions : allowed_features);
+ std::string str(s ? s : "");
+ std::string::size_type lastPos = 0;
+ while (true) {
+ std::string::size_type pos = str.find_first_of(" ", lastPos);
+ if (pos != std::string::npos) {
+ sets[ii].insert(str.substr(lastPos, pos - lastPos));
+ lastPos = pos + 1;
+ } else {
+ sets[ii].insert(str.substr(lastPos));
+ break;
+ }
+ }
+ }
+
+ if (allowed_features) {
+ std::set_intersection(
+ sets[0].begin(), sets[0].end(), sets[1].begin(), sets[1].end(),
+ std::inserter(extensions_, extensions_.begin()));
+ } else {
+ extensions_ = sets[0];
+ }
+ }
+
+ // Returns true if extension exists.
+ bool HasExtension(const char* extension) {
+ return extensions_.find(extension) != extensions_.end();
+ }
+
+ private:
+ std::set<std::string> extensions_;
+};
+
+bool FeatureInfo::Initialize(const char* allowed_features) {
+ AddFeatures(allowed_features);
+ return true;
+}
+
+void FeatureInfo::AddFeatures(const char* desired_features) {
+ // Figure out what extensions to turn on.
+ std::string gl_extensions(
+ reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)));
+
+ ExtensionHelper helper(
+ (gl_extensions +
+ (gl_extensions.empty() ? "" : " ") + "GL_CHROMIUM_map_sub").c_str(),
+ desired_features);
+
+ bool npot_ok = false;
+
+ if (helper.HasExtension("GL_CHROMIUM_map_sub")) {
+ AddExtensionString("GL_CHROMIUM_map_sub");
+ }
+
+ // Check if we should allow GL_EXT_texture_compression_dxt1 and
+ // GL_EXT_texture_compression_s3tc.
+ bool enable_dxt1 = false;
+ bool enable_s3tc = false;
+
+ if (helper.HasExtension("GL_EXT_texture_compression_dxt1")) {
+ enable_dxt1 = true;
+ }
+ if (helper.HasExtension("GL_EXT_texture_compression_s3tc")) {
+ enable_dxt1 = true;
+ enable_s3tc = true;
+ }
+
+ if (enable_dxt1) {
+ AddExtensionString("GL_EXT_texture_compression_dxt1");
+ validators_.compressed_texture_format.AddValue(
+ GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
+ validators_.compressed_texture_format.AddValue(
+ GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
+ }
+
+ if (enable_s3tc) {
+ AddExtensionString("GL_EXT_texture_compression_s3tc");
+ validators_.compressed_texture_format.AddValue(
+ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT);
+ validators_.compressed_texture_format.AddValue(
+ GL_COMPRESSED_RGBA_S3TC_DXT5_EXT);
+ }
+
+ // Check if we should enable GL_EXT_texture_filter_anisotropic.
+ if (helper.HasExtension("GL_EXT_texture_filter_anisotropic")) {
+ AddExtensionString("GL_EXT_texture_filter_anisotropic");
+ validators_.texture_parameter.AddValue(
+ GL_TEXTURE_MAX_ANISOTROPY_EXT);
+ validators_.g_l_state.AddValue(
+ GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT);
+ }
+
+ // Check if we should support GL_OES_packed_depth_stencil and/or
+ // GL_GOOGLE_depth_texture.
+ // NOTE: GL_OES_depth_texture requires support for depth
+ // cubemaps. GL_ARB_depth_texture requires other features that
+ // GL_OES_packed_depth_stencil does not provide. Therefore we made up
+ // GL_GOOGLE_depth_texture.
+ bool enable_depth_texture = false;
+ if (helper.HasExtension("GL_ARB_depth_texture") ||
+ helper.HasExtension("GL_OES_depth_texture")) {
+ enable_depth_texture = true;
+ AddExtensionString("GL_GOOGLE_depth_texture");
+ validators_.texture_internal_format.AddValue(GL_DEPTH_COMPONENT);
+ validators_.texture_format.AddValue(GL_DEPTH_COMPONENT);
+ validators_.pixel_type.AddValue(GL_UNSIGNED_SHORT);
+ validators_.pixel_type.AddValue(GL_UNSIGNED_INT);
+ }
+ // TODO(gman): Add depth types fo ElementsPerGroup and BytesPerElement
+
+ if (helper.HasExtension("GL_EXT_packed_depth_stencil") ||
+ helper.HasExtension("GL_OES_packed_depth_stencil")) {
+ AddExtensionString("GL_OES_packed_depth_stencil");
+ if (enable_depth_texture) {
+ validators_.texture_internal_format.AddValue(GL_DEPTH_STENCIL);
+ validators_.texture_format.AddValue(GL_DEPTH_STENCIL);
+ validators_.pixel_type.AddValue(GL_UNSIGNED_INT_24_8);
+ }
+ validators_.render_buffer_format.AddValue(GL_DEPTH24_STENCIL8);
+ }
+
+ bool enable_texture_format_bgra8888 = false;
+ bool enable_read_format_bgra = false;
+ // Check if we should allow GL_EXT_texture_format_BGRA8888
+ if (helper.HasExtension("GL_EXT_texture_format_BGRA8888") ||
+ helper.HasExtension("GL_APPLE_texture_format_BGRA8888")) {
+ enable_texture_format_bgra8888 = true;
+ }
+
+ if (helper.HasExtension("GL_EXT_bgra")) {
+ enable_texture_format_bgra8888 = true;
+ enable_read_format_bgra = true;
+ }
+
+ if (helper.HasExtension("GL_EXT_read_format_bgra")) {
+ enable_read_format_bgra = true;
+ }
+
+ if (enable_texture_format_bgra8888) {
+ AddExtensionString("GL_EXT_texture_format_BGRA8888");
+ validators_.texture_internal_format.AddValue(GL_BGRA_EXT);
+ validators_.texture_format.AddValue(GL_BGRA_EXT);
+ }
+
+ if (enable_read_format_bgra) {
+ AddExtensionString("GL_EXT_read_format_bgra");
+ validators_.read_pixel_format.AddValue(GL_BGRA_EXT);
+ }
+
+ // Check if we should allow GL_OES_texture_npot
+ if (helper.HasExtension("GL_ARB_texture_non_power_of_two") ||
+ helper.HasExtension("GL_OES_texture_npot")) {
+ AddExtensionString("GL_OES_texture_npot");
+ npot_ok = true;
+ }
+
+ // Check if we should allow GL_OES_texture_float, GL_OES_texture_half_float,
+ // GL_OES_texture_float_linear, GL_OES_texture_half_float_linear
+ bool enable_texture_float = false;
+ bool enable_texture_float_linear = false;
+ bool enable_texture_half_float = false;
+ bool enable_texture_half_float_linear = false;
+ if (helper.HasExtension("GL_ARB_texture_float")) {
+ enable_texture_float = true;
+ enable_texture_float_linear = true;
+ enable_texture_half_float = true;
+ enable_texture_half_float_linear = true;
+ } else {
+ if (helper.HasExtension("GL_OES_texture_float")) {
+ enable_texture_float = true;
+ if (helper.HasExtension("GL_OES_texture_float_linear")) {
+ enable_texture_float_linear = true;
+ }
+ }
+ if (helper.HasExtension("GL_OES_texture_half_float")) {
+ enable_texture_half_float = true;
+ if (helper.HasExtension("GL_OES_texture_half_float_linear")) {
+ enable_texture_half_float_linear = true;
+ }
+ }
+ }
+
+ if (enable_texture_float) {
+ validators_.pixel_type.AddValue(GL_FLOAT);
+ AddExtensionString("GL_OES_texture_float");
+ if (enable_texture_float_linear) {
+ AddExtensionString("GL_OES_texture_float_linear");
+ }
+ }
+
+ if (enable_texture_half_float) {
+ validators_.pixel_type.AddValue(GL_HALF_FLOAT_OES);
+ AddExtensionString("GL_OES_texture_half_float");
+ if (enable_texture_half_float_linear) {
+ AddExtensionString("GL_OES_texture_half_float_linear");
+ }
+ }
+
+ // Check for multisample support
+ if (helper.HasExtension("GL_EXT_framebuffer_multisample")) {
+ feature_flags_.ext_framebuffer_multisample = true;
+ validators_.frame_buffer_target.AddValue(GL_READ_FRAMEBUFFER_EXT);
+ validators_.frame_buffer_target.AddValue(GL_DRAW_FRAMEBUFFER_EXT);
+ validators_.g_l_state.AddValue(GL_READ_FRAMEBUFFER_BINDING_EXT);
+ validators_.render_buffer_parameter.AddValue(GL_MAX_SAMPLES_EXT);
+ AddExtensionString("GL_EXT_framebuffer_multisample");
+ AddExtensionString("GL_EXT_framebuffer_blit");
+ }
+
+ if (helper.HasExtension("GL_OES_depth24") ||
+ gfx::GetGLImplementation() == gfx::kGLImplementationDesktopGL) {
+ AddExtensionString("GL_OES_depth24");
+ validators_.render_buffer_format.AddValue(GL_DEPTH_COMPONENT24);
+ }
+
+ if (helper.HasExtension("GL_OES_standard_derivatives") ||
+ gfx::GetGLImplementation() == gfx::kGLImplementationDesktopGL) {
+ AddExtensionString("GL_OES_standard_derivatives");
+ feature_flags_.oes_standard_derivatives = true;
+ }
+
+ // TODO(gman): Add support for these extensions.
+ // GL_OES_depth32
+ // GL_OES_element_index_uint
+
+ feature_flags_.enable_texture_float_linear = enable_texture_float_linear;
+ feature_flags_.enable_texture_half_float_linear =
+ enable_texture_half_float_linear;
+ feature_flags_.npot_ok = npot_ok;
+}
+
+void FeatureInfo::AddExtensionString(const std::string& str) {
+ if (extensions_.find(str) == std::string::npos) {
+ extensions_ += (extensions_.empty() ? "" : " ") + str;
+ }
+}
+
+} // namespace gles2
+} // namespace gpu
+
+
+
diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h
new file mode 100644
index 0000000..ac6bbed
--- /dev/null
+++ b/gpu/command_buffer/service/feature_info.h
@@ -0,0 +1,74 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GPU_COMMAND_BUFFER_SERVICE_FEATURE_INFO_H_
+#define GPU_COMMAND_BUFFER_SERVICE_FEATURE_INFO_H_
+
+#include <string>
+#include "gpu/command_buffer/service/gles2_cmd_validation.h"
+
+namespace gpu {
+namespace gles2 {
+
+// FeatureInfo records the features that are available for a particular context.
+class FeatureInfo {
+ public:
+ struct FeatureFlags {
+ FeatureFlags()
+ : ext_framebuffer_multisample(false),
+ oes_standard_derivatives(false),
+ npot_ok(false),
+ enable_texture_float_linear(false),
+ enable_texture_half_float_linear(false) {
+ }
+
+ bool ext_framebuffer_multisample;
+ bool oes_standard_derivatives;
+ bool npot_ok;
+ bool enable_texture_float_linear;
+ bool enable_texture_half_float_linear;
+ };
+
+ FeatureInfo();
+
+ // If allowed features = NULL, all features are allowed. Otherwise
+ // only features that match the strings in allowed_features are allowed.
+ bool Initialize(const char* allowed_features);
+
+ // Turns on certain features if they can be turned on. NULL turns on
+ // all available features.
+ void AddFeatures(const char* desired_features);
+
+ const Validators* validators() const {
+ return &validators_;
+ }
+
+ const std::string& extensions() const {
+ return extensions_;
+ }
+
+ const FeatureFlags& feature_flags() const {
+ return feature_flags_;
+ }
+
+ private:
+ void AddExtensionString(const std::string& str);
+
+ Validators validators_;
+
+ // The extensions string returned by glGetString(GL_EXTENSIONS);
+ std::string extensions_;
+
+ // Flags for some features
+ FeatureFlags feature_flags_;
+
+ DISALLOW_COPY_AND_ASSIGN(FeatureInfo);
+};
+
+} // namespace gles2
+} // namespace gpu
+
+#endif // GPU_COMMAND_BUFFER_SERVICE_FEATURE_INFO_H_
+
+
diff --git a/gpu/command_buffer/service/feature_info_unittest.cc b/gpu/command_buffer/service/feature_info_unittest.cc
new file mode 100644
index 0000000..ba9884b
--- /dev/null
+++ b/gpu/command_buffer/service/feature_info_unittest.cc
@@ -0,0 +1,380 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/command_buffer/service/feature_info.h"
+#include "app/gfx/gl/gl_mock.h"
+#include "base/scoped_ptr.h"
+#include "gpu/command_buffer/service/test_helper.h"
+#include "gpu/command_buffer/service/texture_manager.h"
+#include "gpu/GLES2/gles2_command_buffer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::gfx::MockGLInterface;
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::HasSubstr;
+using ::testing::InSequence;
+using ::testing::MatcherCast;
+using ::testing::Not;
+using ::testing::Pointee;
+using ::testing::Return;
+using ::testing::SetArrayArgument;
+using ::testing::SetArgumentPointee;
+using ::testing::StrEq;
+using ::testing::StrictMock;
+
+namespace gpu {
+namespace gles2 {
+
+class FeatureInfoTest : public testing::Test {
+ public:
+ FeatureInfoTest() {
+ }
+
+ void SetupInitExpectations(const char* extensions) {
+ TestHelper::SetupFeatureInfoInitExpectations(gl_.get(), extensions);
+ }
+
+ protected:
+ virtual void SetUp() {
+ gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>());
+ ::gfx::GLInterface::SetGLInterface(gl_.get());
+ }
+
+ virtual void TearDown() {
+ ::gfx::GLInterface::SetGLInterface(NULL);
+ gl_.reset();
+ }
+
+ scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_;
+ FeatureInfo info_;
+};
+
+TEST_F(FeatureInfoTest, Basic) {
+ // Test it starts off uninitialized.
+ EXPECT_FALSE(info_.feature_flags().ext_framebuffer_multisample);
+ EXPECT_FALSE(info_.feature_flags().oes_standard_derivatives);
+ EXPECT_FALSE(info_.feature_flags().npot_ok);
+ EXPECT_FALSE(info_.feature_flags().enable_texture_float_linear);
+ EXPECT_FALSE(info_.feature_flags().enable_texture_half_float_linear);
+}
+
+TEST_F(FeatureInfoTest, InitializeNoExtensions) {
+ SetupInitExpectations("");
+ info_.Initialize(NULL);
+ // Check a couple of random extensions that should not be there.
+ EXPECT_THAT(info_.extensions(), Not(HasSubstr("GL_OES_texture_npot")));
+ EXPECT_THAT(info_.extensions(),
+ Not(HasSubstr("GL_EXT_texture_compression_dxt1")));
+ EXPECT_FALSE(info_.feature_flags().npot_ok);
+ EXPECT_FALSE(info_.validators()->compressed_texture_format.IsValid(
+ GL_COMPRESSED_RGB_S3TC_DXT1_EXT));
+ EXPECT_FALSE(info_.validators()->compressed_texture_format.IsValid(
+ GL_COMPRESSED_RGBA_S3TC_DXT1_EXT));
+ EXPECT_FALSE(info_.validators()->compressed_texture_format.IsValid(
+ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT));
+ EXPECT_FALSE(info_.validators()->compressed_texture_format.IsValid(
+ GL_COMPRESSED_RGBA_S3TC_DXT5_EXT));
+ EXPECT_FALSE(info_.validators()->read_pixel_format.IsValid(
+ GL_BGRA_EXT));
+ EXPECT_FALSE(info_.validators()->texture_parameter.IsValid(
+ GL_TEXTURE_MAX_ANISOTROPY_EXT));
+ EXPECT_FALSE(info_.validators()->g_l_state.IsValid(
+ GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT));
+ EXPECT_FALSE(info_.validators()->frame_buffer_target.IsValid(
+ GL_READ_FRAMEBUFFER_EXT));
+ EXPECT_FALSE(info_.validators()->frame_buffer_target.IsValid(
+ GL_DRAW_FRAMEBUFFER_EXT));
+ EXPECT_FALSE(info_.validators()->g_l_state.IsValid(
+ GL_READ_FRAMEBUFFER_BINDING_EXT));
+ EXPECT_FALSE(info_.validators()->render_buffer_parameter.IsValid(
+ GL_MAX_SAMPLES_EXT));
+ EXPECT_FALSE(info_.validators()->texture_internal_format.IsValid(
+ GL_DEPTH_COMPONENT));
+ EXPECT_FALSE(info_.validators()->texture_format.IsValid(GL_DEPTH_COMPONENT));
+ EXPECT_FALSE(info_.validators()->pixel_type.IsValid(GL_UNSIGNED_SHORT));
+ EXPECT_FALSE(info_.validators()->pixel_type.IsValid(GL_UNSIGNED_INT));
+ EXPECT_FALSE(info_.validators()->render_buffer_format.IsValid(
+ GL_DEPTH24_STENCIL8));
+ EXPECT_FALSE(info_.validators()->texture_internal_format.IsValid(
+ GL_DEPTH_STENCIL));
+ EXPECT_FALSE(info_.validators()->texture_format.IsValid(
+ GL_DEPTH_STENCIL));
+ EXPECT_FALSE(info_.validators()->pixel_type.IsValid(
+ GL_UNSIGNED_INT_24_8));
+ EXPECT_FALSE(info_.validators()->render_buffer_format.IsValid(
+ GL_DEPTH_COMPONENT24));
+}
+
+TEST_F(FeatureInfoTest, InitializeNPOTExtensionGLES) {
+ SetupInitExpectations("GL_OES_texture_npot");
+ info_.Initialize(NULL);
+ EXPECT_THAT(info_.extensions(), HasSubstr("GL_OES_texture_npot"));
+ EXPECT_TRUE(info_.feature_flags().npot_ok);
+}
+
+TEST_F(FeatureInfoTest, InitializeNPOTExtensionGL) {
+ SetupInitExpectations("GL_ARB_texture_non_power_of_two");
+ info_.Initialize(NULL);
+ EXPECT_THAT(info_.extensions(), HasSubstr("GL_OES_texture_npot"));
+ EXPECT_TRUE(info_.feature_flags().npot_ok);
+}
+
+TEST_F(FeatureInfoTest, InitializeDXTExtensionGLES2) {
+ SetupInitExpectations("GL_EXT_texture_compression_dxt1");
+ info_.Initialize(NULL);
+ EXPECT_THAT(info_.extensions(),
+ HasSubstr("GL_EXT_texture_compression_dxt1"));
+ EXPECT_TRUE(info_.validators()->compressed_texture_format.IsValid(
+ GL_COMPRESSED_RGB_S3TC_DXT1_EXT));
+ EXPECT_TRUE(info_.validators()->compressed_texture_format.IsValid(
+ GL_COMPRESSED_RGBA_S3TC_DXT1_EXT));
+ EXPECT_FALSE(info_.validators()->compressed_texture_format.IsValid(
+ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT));
+ EXPECT_FALSE(info_.validators()->compressed_texture_format.IsValid(
+ GL_COMPRESSED_RGBA_S3TC_DXT5_EXT));
+}
+
+TEST_F(FeatureInfoTest, InitializeDXTExtensionGL) {
+ SetupInitExpectations("GL_EXT_texture_compression_s3tc");
+ info_.Initialize(NULL);
+ EXPECT_THAT(info_.extensions(),
+ HasSubstr("GL_EXT_texture_compression_dxt1"));
+ EXPECT_THAT(info_.extensions(),
+ HasSubstr("GL_EXT_texture_compression_s3tc"));
+ EXPECT_TRUE(info_.validators()->compressed_texture_format.IsValid(
+ GL_COMPRESSED_RGB_S3TC_DXT1_EXT));
+ EXPECT_TRUE(info_.validators()->compressed_texture_format.IsValid(
+ GL_COMPRESSED_RGBA_S3TC_DXT1_EXT));
+ EXPECT_TRUE(info_.validators()->compressed_texture_format.IsValid(
+ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT));
+ EXPECT_TRUE(info_.validators()->compressed_texture_format.IsValid(
+ GL_COMPRESSED_RGBA_S3TC_DXT5_EXT));
+}
+
+TEST_F(FeatureInfoTest, InitializeEXT_texture_format_BGRA8888GLES2) {
+ SetupInitExpectations("GL_EXT_texture_format_BGRA8888");
+ info_.Initialize(NULL);
+ EXPECT_THAT(info_.extensions(),
+ HasSubstr("GL_EXT_texture_format_BGRA8888"));
+ EXPECT_TRUE(info_.validators()->texture_format.IsValid(
+ GL_BGRA_EXT));
+ EXPECT_TRUE(info_.validators()->texture_internal_format.IsValid(
+ GL_BGRA_EXT));
+}
+
+TEST_F(FeatureInfoTest, InitializeEXT_texture_format_BGRA8888GL) {
+ SetupInitExpectations("GL_EXT_bgra");
+ info_.Initialize(NULL);
+ EXPECT_THAT(info_.extensions(),
+ HasSubstr("GL_EXT_texture_format_BGRA8888"));
+ EXPECT_THAT(info_.extensions(),
+ HasSubstr("GL_EXT_read_format_bgra"));
+ EXPECT_TRUE(info_.validators()->texture_format.IsValid(
+ GL_BGRA_EXT));
+ EXPECT_TRUE(info_.validators()->texture_internal_format.IsValid(
+ GL_BGRA_EXT));
+ EXPECT_TRUE(info_.validators()->read_pixel_format.IsValid(
+ GL_BGRA_EXT));
+}
+
+TEST_F(FeatureInfoTest, InitializeEXT_texture_format_BGRA8888Apple) {
+ SetupInitExpectations("GL_APPLE_texture_format_BGRA8888");
+ info_.Initialize(NULL);
+ EXPECT_THAT(info_.extensions(),
+ HasSubstr("GL_EXT_texture_format_BGRA8888"));
+ EXPECT_TRUE(info_.validators()->texture_format.IsValid(
+ GL_BGRA_EXT));
+ EXPECT_TRUE(info_.validators()->texture_internal_format.IsValid(
+ GL_BGRA_EXT));
+}
+
+TEST_F(FeatureInfoTest, InitializeEXT_read_format_bgra) {
+ SetupInitExpectations("GL_EXT_read_format_bgra");
+ info_.Initialize(NULL);
+ EXPECT_THAT(info_.extensions(),
+ HasSubstr("GL_EXT_read_format_bgra"));
+ EXPECT_FALSE(info_.validators()->texture_format.IsValid(
+ GL_BGRA_EXT));
+ EXPECT_FALSE(info_.validators()->texture_internal_format.IsValid(
+ GL_BGRA_EXT));
+ EXPECT_TRUE(info_.validators()->read_pixel_format.IsValid(
+ GL_BGRA_EXT));
+}
+
+TEST_F(FeatureInfoTest, InitializeOES_texture_floatGLES2) {
+ SetupInitExpectations("GL_OES_texture_float");
+ info_.Initialize(NULL);
+ EXPECT_FALSE(info_.feature_flags().enable_texture_float_linear);
+ EXPECT_FALSE(info_.feature_flags().enable_texture_half_float_linear);
+ EXPECT_THAT(info_.extensions(), HasSubstr("GL_OES_texture_float"));
+ EXPECT_THAT(info_.extensions(), Not(HasSubstr("GL_OES_texture_half_float")));
+ EXPECT_THAT(info_.extensions(),
+ Not(HasSubstr("GL_OES_texture_float_linear")));
+ EXPECT_THAT(info_.extensions(),
+ Not(HasSubstr("GL_OES_texture_half_float_linear")));
+ EXPECT_TRUE(info_.validators()->pixel_type.IsValid(GL_FLOAT));
+ EXPECT_FALSE(info_.validators()->pixel_type.IsValid(GL_HALF_FLOAT_OES));
+}
+
+TEST_F(FeatureInfoTest, InitializeOES_texture_float_linearGLES2) {
+ SetupInitExpectations("GL_OES_texture_float GL_OES_texture_float_linear");
+ info_.Initialize(NULL);
+ EXPECT_TRUE(info_.feature_flags().enable_texture_float_linear);
+ EXPECT_FALSE(info_.feature_flags().enable_texture_half_float_linear);
+ EXPECT_THAT(info_.extensions(), HasSubstr("GL_OES_texture_float"));
+ EXPECT_THAT(info_.extensions(), Not(HasSubstr("GL_OES_texture_half_float")));
+ EXPECT_THAT(info_.extensions(), HasSubstr("GL_OES_texture_float_linear"));
+ EXPECT_THAT(info_.extensions(),
+ Not(HasSubstr("GL_OES_texture_half_float_linear")));
+ EXPECT_TRUE(info_.validators()->pixel_type.IsValid(GL_FLOAT));
+ EXPECT_FALSE(info_.validators()->pixel_type.IsValid(GL_HALF_FLOAT_OES));
+}
+
+TEST_F(FeatureInfoTest, InitializeOES_texture_half_floatGLES2) {
+ SetupInitExpectations("GL_OES_texture_half_float");
+ info_.Initialize(NULL);
+ EXPECT_FALSE(info_.feature_flags().enable_texture_float_linear);
+ EXPECT_FALSE(info_.feature_flags().enable_texture_half_float_linear);
+ EXPECT_THAT(info_.extensions(), Not(HasSubstr("GL_OES_texture_float")));
+ EXPECT_THAT(info_.extensions(), HasSubstr("GL_OES_texture_half_float"));
+ EXPECT_THAT(info_.extensions(),
+ Not(HasSubstr("GL_OES_texture_float_linear")));
+ EXPECT_THAT(info_.extensions(),
+ Not(HasSubstr("GL_OES_texture_half_float_linear")));
+ EXPECT_FALSE(info_.validators()->pixel_type.IsValid(GL_FLOAT));
+ EXPECT_TRUE(info_.validators()->pixel_type.IsValid(GL_HALF_FLOAT_OES));
+}
+
+TEST_F(FeatureInfoTest, InitializeOES_texture_half_float_linearGLES2) {
+ SetupInitExpectations(
+ "GL_OES_texture_half_float GL_OES_texture_half_float_linear");
+ info_.Initialize(NULL);
+ EXPECT_FALSE(info_.feature_flags().enable_texture_float_linear);
+ EXPECT_TRUE(info_.feature_flags().enable_texture_half_float_linear);
+ EXPECT_THAT(info_.extensions(), Not(HasSubstr("GL_OES_texture_float")));
+ EXPECT_THAT(info_.extensions(), HasSubstr("GL_OES_texture_half_float"));
+ EXPECT_THAT(info_.extensions(),
+ Not(HasSubstr("GL_OES_texture_float_linear")));
+ EXPECT_THAT(info_.extensions(),
+ HasSubstr("GL_OES_texture_half_float_linear"));
+ EXPECT_FALSE(info_.validators()->pixel_type.IsValid(GL_FLOAT));
+ EXPECT_TRUE(info_.validators()->pixel_type.IsValid(GL_HALF_FLOAT_OES));
+}
+
+TEST_F(FeatureInfoTest, InitializeEXT_framebuffer_multisample) {
+ SetupInitExpectations("GL_EXT_framebuffer_multisample");
+ info_.Initialize(NULL);
+ EXPECT_TRUE(info_.feature_flags().ext_framebuffer_multisample);
+ EXPECT_THAT(info_.extensions(), HasSubstr("GL_EXT_framebuffer_multisample"));
+ EXPECT_THAT(info_.extensions(), HasSubstr("GL_EXT_framebuffer_blit"));
+ EXPECT_TRUE(info_.validators()->frame_buffer_target.IsValid(
+ GL_READ_FRAMEBUFFER_EXT));
+ EXPECT_TRUE(info_.validators()->frame_buffer_target.IsValid(
+ GL_DRAW_FRAMEBUFFER_EXT));
+ EXPECT_TRUE(info_.validators()->g_l_state.IsValid(
+ GL_READ_FRAMEBUFFER_BINDING_EXT));
+ EXPECT_TRUE(info_.validators()->render_buffer_parameter.IsValid(
+ GL_MAX_SAMPLES_EXT));
+}
+
+TEST_F(FeatureInfoTest, InitializeEXT_texture_filter_anisotropic) {
+ SetupInitExpectations("GL_EXT_texture_filter_anisotropic");
+ info_.Initialize(NULL);
+ EXPECT_THAT(info_.extensions(),
+ HasSubstr("GL_EXT_texture_filter_anisotropic"));
+ EXPECT_TRUE(info_.validators()->texture_parameter.IsValid(
+ GL_TEXTURE_MAX_ANISOTROPY_EXT));
+ EXPECT_TRUE(info_.validators()->g_l_state.IsValid(
+ GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT));
+}
+
+TEST_F(FeatureInfoTest, InitializeEXT_ARB_depth_texture) {
+ SetupInitExpectations("GL_ARB_depth_texture");
+ info_.Initialize(NULL);
+ EXPECT_THAT(info_.extensions(),
+ HasSubstr("GL_GOOGLE_depth_texture"));
+ EXPECT_TRUE(info_.validators()->texture_internal_format.IsValid(
+ GL_DEPTH_COMPONENT));
+ EXPECT_TRUE(info_.validators()->texture_format.IsValid(GL_DEPTH_COMPONENT));
+ EXPECT_TRUE(info_.validators()->pixel_type.IsValid(GL_UNSIGNED_SHORT));
+ EXPECT_TRUE(info_.validators()->pixel_type.IsValid(GL_UNSIGNED_INT));
+}
+
+TEST_F(FeatureInfoTest, InitializeOES_ARB_depth_texture) {
+ SetupInitExpectations("GL_OES_depth_texture");
+ info_.Initialize(NULL);
+ EXPECT_THAT(info_.extensions(),
+ HasSubstr("GL_GOOGLE_depth_texture"));
+ EXPECT_TRUE(info_.validators()->texture_internal_format.IsValid(
+ GL_DEPTH_COMPONENT));
+ EXPECT_TRUE(info_.validators()->texture_format.IsValid(GL_DEPTH_COMPONENT));
+ EXPECT_TRUE(info_.validators()->pixel_type.IsValid(GL_UNSIGNED_SHORT));
+ EXPECT_TRUE(info_.validators()->pixel_type.IsValid(GL_UNSIGNED_INT));
+}
+
+TEST_F(FeatureInfoTest, InitializeEXT_packed_depth_stencil) {
+ SetupInitExpectations("GL_EXT_packed_depth_stencil");
+ info_.Initialize(NULL);
+ EXPECT_THAT(info_.extensions(),
+ HasSubstr("GL_OES_packed_depth_stencil"));
+ EXPECT_TRUE(info_.validators()->render_buffer_format.IsValid(
+ GL_DEPTH24_STENCIL8));
+ EXPECT_FALSE(info_.validators()->texture_internal_format.IsValid(
+ GL_DEPTH_COMPONENT));
+ EXPECT_FALSE(info_.validators()->texture_format.IsValid(GL_DEPTH_COMPONENT));
+ EXPECT_FALSE(info_.validators()->pixel_type.IsValid(GL_UNSIGNED_SHORT));
+ EXPECT_FALSE(info_.validators()->pixel_type.IsValid(GL_UNSIGNED_INT));
+}
+
+TEST_F(FeatureInfoTest, InitializeOES_packed_depth_stencil) {
+ SetupInitExpectations("GL_OES_packed_depth_stencil");
+ info_.Initialize(NULL);
+ EXPECT_THAT(info_.extensions(),
+ HasSubstr("GL_OES_packed_depth_stencil"));
+ EXPECT_TRUE(info_.validators()->render_buffer_format.IsValid(
+ GL_DEPTH24_STENCIL8));
+ EXPECT_FALSE(info_.validators()->texture_internal_format.IsValid(
+ GL_DEPTH_COMPONENT));
+ EXPECT_FALSE(info_.validators()->texture_format.IsValid(GL_DEPTH_COMPONENT));
+ EXPECT_FALSE(info_.validators()->pixel_type.IsValid(GL_UNSIGNED_SHORT));
+ EXPECT_FALSE(info_.validators()->pixel_type.IsValid(GL_UNSIGNED_INT));
+}
+
+TEST_F(FeatureInfoTest,
+ InitializeOES_packed_depth_stencil_and_GL_ARB_depth_texture) {
+ SetupInitExpectations("GL_OES_packed_depth_stencil GL_ARB_depth_texture");
+ info_.Initialize(NULL);
+ EXPECT_THAT(info_.extensions(),
+ HasSubstr("GL_OES_packed_depth_stencil"));
+ EXPECT_TRUE(info_.validators()->render_buffer_format.IsValid(
+ GL_DEPTH24_STENCIL8));
+ EXPECT_TRUE(info_.validators()->texture_internal_format.IsValid(
+ GL_DEPTH_STENCIL));
+ EXPECT_TRUE(info_.validators()->texture_format.IsValid(
+ GL_DEPTH_STENCIL));
+ EXPECT_TRUE(info_.validators()->pixel_type.IsValid(
+ GL_UNSIGNED_INT_24_8));
+}
+
+TEST_F(FeatureInfoTest, InitializeOES_depth24) {
+ SetupInitExpectations("GL_OES_depth24");
+ info_.Initialize(NULL);
+ EXPECT_THAT(info_.extensions(), HasSubstr("GL_OES_depth24"));
+ EXPECT_TRUE(info_.validators()->render_buffer_format.IsValid(
+ GL_DEPTH_COMPONENT24));
+}
+
+TEST_F(FeatureInfoTest, InitializeOES_standard_derivatives) {
+ SetupInitExpectations("GL_OES_standard_derivatives");
+ info_.Initialize(NULL);
+ EXPECT_THAT(info_.extensions(), HasSubstr("GL_OES_standard_derivatives"));
+ EXPECT_TRUE(info_.feature_flags().oes_standard_derivatives);
+}
+
+} // namespace gles2
+} // namespace gpu
+
+
+
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 68fa2f3..df03682 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -26,6 +26,7 @@
#include "gpu/command_buffer/service/buffer_manager.h"
#include "gpu/command_buffer/service/cmd_buffer_engine.h"
#include "gpu/command_buffer/service/context_group.h"
+#include "gpu/command_buffer/service/feature_info.h"
#include "gpu/command_buffer/service/framebuffer_manager.h"
#include "gpu/command_buffer/service/gl_utils.h"
#include "gpu/command_buffer/service/gles2_cmd_validation.h"
@@ -604,7 +605,8 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
// Creates a TextureInfo for the given texture.
TextureManager::TextureInfo* CreateTextureInfo(
GLuint client_id, GLuint service_id) {
- return texture_manager()->CreateTextureInfo(client_id, service_id);
+ return texture_manager()->CreateTextureInfo(
+ feature_info_, client_id, service_id);
}
// Gets the texture info for the given texture. Returns NULL if none exists.
@@ -616,7 +618,7 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
// Deletes the texture info for the given texture.
void RemoveTextureInfo(GLuint client_id) {
- texture_manager()->RemoveTextureInfo(client_id);
+ texture_manager()->RemoveTextureInfo(feature_info_, client_id);
}
// Get the size (in pixels) of the currently bound frame buffer (either FBO
@@ -1264,8 +1266,9 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
scoped_ptr<ShaderTranslator> vertex_translator_;
scoped_ptr<ShaderTranslator> fragment_translator_;
- // Cached from the context group.
+ // Cached from ContextGroup
const Validators* validators_;
+ FeatureInfo* feature_info_;
// Supported extensions.
bool depth24_stencil8_oes_supported_;
@@ -1515,7 +1518,8 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
anti_aliased_(false),
current_decoder_error_(error::kNoError),
use_shader_translator_(true),
- validators_(group->validators()),
+ validators_(group_->feature_info()->validators()),
+ feature_info_(group_->feature_info()),
depth24_stencil8_oes_supported_(false) {
attrib_0_value_.v[0] = 0.0f;
attrib_0_value_.v[1] = 0.0f;
@@ -1557,13 +1561,6 @@ bool GLES2DecoderImpl::Initialize(gfx::GLContext* context,
CHECK_GL_ERROR();
- if (!group_->Initialize()) {
- LOG(ERROR) << "GLES2DecoderImpl::Initialize failed becaue "
- << "ContextGroup failed to initialize.";
- Destroy();
- return false;
- }
-
vertex_attrib_manager_.Initialize(group_->max_vertex_attribs());
// Check supported extensions.
@@ -1669,7 +1666,7 @@ bool GLES2DecoderImpl::Initialize(gfx::GLContext* context,
group_->max_fragment_uniform_vectors();
resources.MaxDrawBuffers = 1;
resources.OES_standard_derivatives =
- group_->extension_flags().oes_standard_derivatives ? 1 : 0;
+ feature_info_->feature_flags().oes_standard_derivatives ? 1 : 0;
vertex_translator_.reset(new ShaderTranslator);
if (!vertex_translator_->Init(EShLangVertex, &resources)) {
LOG(ERROR) << "Could not initialize vertex shader translator.";
@@ -1827,7 +1824,7 @@ static void RebindCurrentFramebuffer(
}
void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
- if (!group_->extension_flags().ext_framebuffer_multisample) {
+ if (!feature_info_->feature_flags().ext_framebuffer_multisample) {
RebindCurrentFramebuffer(
GL_FRAMEBUFFER,
bound_draw_framebuffer_.get(),
@@ -1862,7 +1859,7 @@ gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
int width = 0;
int height = 0;
- GLenum target = group_->extension_flags().ext_framebuffer_multisample ?
+ GLenum target = feature_info_->feature_flags().ext_framebuffer_multisample ?
GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
// Assume we have to have COLOR_ATTACHMENT0. Should we check for depth and
@@ -2033,6 +2030,7 @@ bool GLES2DecoderImpl::UpdateOffscreenFrameBufferSize() {
DCHECK(info);
texture_manager()->SetLevelInfo(
+ feature_info_,
info,
GL_TEXTURE_2D,
0, // level
@@ -2107,7 +2105,7 @@ void GLES2DecoderImpl::Destroy() {
GLuint service_id = offscreen_saved_color_texture_->id();
GLuint client_id = 0;
if (parent_->texture_manager()->GetClientId(service_id, &client_id)) {
- parent_->texture_manager()->RemoveTextureInfo(client_id);
+ parent_->texture_manager()->RemoveTextureInfo(feature_info_, client_id);
}
glDeleteFramebuffersEXT(1, &copy_texture_to_parent_texture_fb_);
@@ -2435,7 +2433,7 @@ void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
- if (!info || !texture_manager()->MarkMipmapsGenerated(info)) {
+ if (!info || !texture_manager()->MarkMipmapsGenerated(feature_info_, info)) {
SetGLError(GL_INVALID_OPERATION,
"glGenerateMipmaps: Can not generate mips for npot textures");
return;
@@ -3131,7 +3129,7 @@ void GLES2DecoderImpl::DoBlitFramebufferEXT(
GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter) {
- if (!group_->extension_flags().ext_framebuffer_multisample) {
+ if (!feature_info_->feature_flags().ext_framebuffer_multisample) {
SetGLError(GL_INVALID_OPERATION,
"glBlitFramebufferEXT: function not available");
}
@@ -3142,7 +3140,7 @@ void GLES2DecoderImpl::DoBlitFramebufferEXT(
void GLES2DecoderImpl::DoRenderbufferStorageMultisample(
GLenum target, GLsizei samples, GLenum internalformat,
GLsizei width, GLsizei height) {
- if (!group_->extension_flags().ext_framebuffer_multisample) {
+ if (!feature_info_->feature_flags().ext_framebuffer_multisample) {
SetGLError(GL_INVALID_OPERATION,
"glRenderbufferStorageMultisampleEXT: function not available");
return;
@@ -3222,7 +3220,8 @@ void GLES2DecoderImpl::DoTexParameterf(
if (!info) {
SetGLError(GL_INVALID_VALUE, "glTexParameterf: unknown texture");
} else {
- texture_manager()->SetParameter(info, pname, static_cast<GLint>(param));
+ texture_manager()->SetParameter(
+ feature_info_, info, pname, static_cast<GLint>(param));
glTexParameterf(target, pname, param);
}
}
@@ -3233,7 +3232,7 @@ void GLES2DecoderImpl::DoTexParameteri(
if (!info) {
SetGLError(GL_INVALID_VALUE, "glTexParameteri: unknown texture");
} else {
- texture_manager()->SetParameter(info, pname, param);
+ texture_manager()->SetParameter(feature_info_, info, pname, param);
glTexParameteri(target, pname, param);
}
}
@@ -3245,7 +3244,7 @@ void GLES2DecoderImpl::DoTexParameterfv(
SetGLError(GL_INVALID_VALUE, "glTexParameterfv: unknown texture");
} else {
texture_manager()->SetParameter(
- info, pname, *reinterpret_cast<const GLint*>(params));
+ feature_info_, info, pname, *reinterpret_cast<const GLint*>(params));
glTexParameterfv(target, pname, params);
}
}
@@ -3256,7 +3255,7 @@ void GLES2DecoderImpl::DoTexParameteriv(
if (!info) {
SetGLError(GL_INVALID_VALUE, "glTexParameteriv: unknown texture");
} else {
- texture_manager()->SetParameter(info, pname, *params);
+ texture_manager()->SetParameter(feature_info_, info, pname, *params);
glTexParameteriv(target, pname, params);
}
}
@@ -3468,7 +3467,7 @@ bool GLES2DecoderImpl::SetBlackTextureForNonRenderableTextures() {
uniform_info->type == GL_SAMPLER_2D ?
texture_unit.bound_texture_2d :
texture_unit.bound_texture_cube_map;
- if (!texture_info || !texture_info->CanRender(texture_manager())) {
+ if (!texture_info || !texture_info->CanRender(feature_info_)) {
textures_set = true;
glActiveTexture(GL_TEXTURE0 + texture_unit_index);
glBindTexture(
@@ -3500,7 +3499,7 @@ void GLES2DecoderImpl::RestoreStateForNonRenderableTextures() {
uniform_info->type == GL_SAMPLER_2D ?
texture_unit.bound_texture_2d :
texture_unit.bound_texture_cube_map;
- if (!texture_info || !texture_info->CanRender(texture_manager())) {
+ if (!texture_info || !texture_info->CanRender(feature_info_)) {
glActiveTexture(GL_TEXTURE0 + texture_unit_index);
// Get the texture info that was previously bound here.
texture_info = texture_unit.bind_target == GL_TEXTURE_2D ?
@@ -4491,7 +4490,7 @@ error::Error GLES2DecoderImpl::HandleGetString(
str = "OpenGL ES GLSL ES 1.0 Chromium";
break;
case GL_EXTENSIONS:
- str = group_->extensions().c_str();
+ str = feature_info_->extensions().c_str();
break;
default:
str = gl_str;
@@ -4606,7 +4605,8 @@ error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
"glCompressedTexImage2D: internal_format GL_INVALID_ENUM");
return error::kNoError;
}
- if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
+ if (!texture_manager()->ValidForTarget(
+ feature_info_, target, level, width, height, 1) ||
border != 0) {
SetGLError(GL_INVALID_VALUE,
"glCompressedTexImage2D: dimensions out of range");
@@ -4630,6 +4630,7 @@ error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
GLenum error = glGetError();
if (error == GL_NO_ERROR) {
texture_manager()->SetLevelInfo(
+ feature_info_,
info, target, level, internal_format, width, height, 1, border, 0, 0);
}
return error::kNoError;
@@ -4763,7 +4764,8 @@ error::Error GLES2DecoderImpl::DoTexImage2D(
SetGLError(GL_INVALID_OPERATION, "glTexImage2D: format != internalFormat");
return error::kNoError;
}
- if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
+ if (!texture_manager()->ValidForTarget(
+ feature_info_, target, level, width, height, 1) ||
border != 0) {
SetGLError(GL_INVALID_VALUE, "glTexImage2D: dimensions out of range");
return error::kNoError;
@@ -4806,7 +4808,7 @@ error::Error GLES2DecoderImpl::DoTexImage2D(
pixels);
GLenum error = glGetError();
if (error == GL_NO_ERROR) {
- texture_manager()->SetLevelInfo(info,
+ texture_manager()->SetLevelInfo(feature_info_, info,
target, level, internal_format, width, height, 1, border, format, type);
}
return error::kNoError;
@@ -4912,7 +4914,8 @@ void GLES2DecoderImpl::DoCopyTexImage2D(
"glCopyTexImage2D: unknown texture for target");
return;
}
- if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
+ if (!texture_manager()->ValidForTarget(
+ feature_info_, target, level, width, height, 1) ||
border != 0) {
SetGLError(GL_INVALID_VALUE, "glCopyTexImage2D: dimensions out of range");
return;
@@ -4926,8 +4929,8 @@ void GLES2DecoderImpl::DoCopyTexImage2D(
GLenum error = glGetError();
if (error == GL_NO_ERROR) {
texture_manager()->SetLevelInfo(
- info, target, level, internal_format, width, height, 1, border,
- internal_format, GL_UNSIGNED_BYTE);
+ feature_info_, info, target, level, internal_format, width, height, 1,
+ border, internal_format, GL_UNSIGNED_BYTE);
}
}
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h
index 694fa37..57ec8b5 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.h
@@ -48,10 +48,13 @@ class GLES2Decoder : public CommonDecoder {
// Parameters:
// context: the GL context to render to.
// size: the size if the GL context is offscreen.
+ // allowed_features: A string in the same format as
+ // glGetString(GL_EXTENSIONS) that lists the extensions this context
+ // should allow. Passing NULL means allow all extensions.
// parent: the GLES2 decoder that can access this decoder's front buffer
- // through a texture ID in its namespace.
+ // through a texture ID in its namespace.
// parent_client_texture_id: the texture ID of the front buffer in the
- // parent's namespace.
+ // parent's namespace.
// Returns:
// true if successful.
virtual bool Initialize(gfx::GLContext* context,
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 9f3f769..c1f3c46 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
@@ -42,7 +42,9 @@ void GLES2DecoderTestBase::InitDecoder(const char* extensions) {
InSequence sequence;
- TestHelper::SetupContextGroupInitExpectations(gl_.get(), "");
+ TestHelper::SetupContextGroupInitExpectations(gl_.get(), extensions);
+
+ EXPECT_TRUE(group_.Initialize(extensions));
EXPECT_CALL(*gl_, EnableVertexAttribArray(0))
.Times(1)
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 dfd78dc..05c92d9 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
@@ -32,8 +32,8 @@ class GLES2DecoderTestBase : public testing::Test {
client_program_id_(102),
client_renderbuffer_id_(103),
client_shader_id_(104),
- client_texture_id_(105),
- client_element_buffer_id_(106) {
+ client_texture_id_(106),
+ client_element_buffer_id_(107) {
memset(immediate_buffer_, 0xEE, sizeof(immediate_buffer_));
}
@@ -56,7 +56,7 @@ class GLES2DecoderTestBase : public testing::Test {
static const GLuint kServiceTextureId = 304;
static const GLuint kServiceProgramId = 305;
static const GLuint kServiceShaderId = 306;
- static const GLuint kServiceElementBufferId = 307;
+ static const GLuint kServiceElementBufferId = 308;
static const int32 kSharedMemoryId = 401;
static const size_t kSharedBufferSize = 2048;
diff --git a/gpu/command_buffer/service/gles2_cmd_validation.h b/gpu/command_buffer/service/gles2_cmd_validation.h
index 07ec6cd..d98212b 100644
--- a/gpu/command_buffer/service/gles2_cmd_validation.h
+++ b/gpu/command_buffer/service/gles2_cmd_validation.h
@@ -28,7 +28,9 @@ class ValueValidator {
}
void AddValue(const T value) {
- valid_values_.push_back(value);
+ if (!IsValid(value)) {
+ valid_values_.push_back(value);
+ }
}
bool IsValid(const T value) const {
diff --git a/gpu/command_buffer/service/gpu_processor.cc b/gpu/command_buffer/service/gpu_processor.cc
index f4bc650..4bb0e64 100644
--- a/gpu/command_buffer/service/gpu_processor.cc
+++ b/gpu/command_buffer/service/gpu_processor.cc
@@ -57,6 +57,12 @@ bool GPUProcessor::InitializeCommon(gfx::GLContext* context,
decoder_.get()));
}
+ if (!group_.Initialize(NULL)) {
+ LOG(ERROR) << "GPUProcessor::InitializeCommon failed because group "
+ << "failed to initialize.";
+ Destroy();
+ }
+
// Initialize the decoder with either the view or pbuffer GLContext.
if (!decoder_->Initialize(context,
size,
diff --git a/gpu/command_buffer/service/test_helper.cc b/gpu/command_buffer/service/test_helper.cc
index 9002e7f..578c3c9 100644
--- a/gpu/command_buffer/service/test_helper.cc
+++ b/gpu/command_buffer/service/test_helper.cc
@@ -36,8 +36,11 @@ const GLint TestHelper::kNumTextureUnits;
const GLint TestHelper::kMaxTextureImageUnits;
const GLint TestHelper::kMaxVertexTextureImageUnits;
const GLint TestHelper::kMaxFragmentUniformVectors;
+const GLint TestHelper::kMaxFragmentUniformComponents;
const GLint TestHelper::kMaxVaryingVectors;
+const GLint TestHelper::kMaxVaryingFloats;
const GLint TestHelper::kMaxVertexUniformVectors;
+const GLint TestHelper::kMaxVertexUniformComponents;
#endif
void TestHelper::SetupTextureManagerInitExpectations(
@@ -90,9 +93,8 @@ void TestHelper::SetupContextGroupInitExpectations(
::gfx::MockGLInterface* gl, const char* extensions) {
InSequence sequence;
- EXPECT_CALL(*gl, GetString(GL_EXTENSIONS))
- .WillOnce(Return(reinterpret_cast<const uint8*>(extensions)))
- .RetiresOnSaturation();
+ SetupFeatureInfoInitExpectations(gl, extensions);
+
EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_ATTRIBS, _))
.WillOnce(SetArgumentPointee<1>(kNumVertexAttribs))
.RetiresOnSaturation();
@@ -105,6 +107,7 @@ void TestHelper::SetupContextGroupInitExpectations(
EXPECT_CALL(*gl, GetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, _))
.WillOnce(SetArgumentPointee<1>(kMaxCubeMapTextureSize))
.RetiresOnSaturation();
+
EXPECT_CALL(*gl, GetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, _))
.WillOnce(SetArgumentPointee<1>(kMaxTextureImageUnits))
.RetiresOnSaturation();
@@ -112,18 +115,27 @@ void TestHelper::SetupContextGroupInitExpectations(
.WillOnce(SetArgumentPointee<1>(kMaxVertexTextureImageUnits))
.RetiresOnSaturation();
EXPECT_CALL(*gl, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, _))
- .WillOnce(SetArgumentPointee<1>(kMaxFragmentUniformVectors))
+ .WillOnce(SetArgumentPointee<1>(kMaxFragmentUniformComponents))
.RetiresOnSaturation();
EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VARYING_FLOATS, _))
- .WillOnce(SetArgumentPointee<1>(kMaxVaryingVectors))
+ .WillOnce(SetArgumentPointee<1>(kMaxVaryingFloats))
.RetiresOnSaturation();
EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, _))
- .WillOnce(SetArgumentPointee<1>(kMaxVertexUniformVectors))
+ .WillOnce(SetArgumentPointee<1>(kMaxVertexUniformComponents))
.RetiresOnSaturation();
SetupTextureManagerInitExpectations(gl);
}
+void TestHelper::SetupFeatureInfoInitExpectations(
+ ::gfx::MockGLInterface* gl, const char* extensions) {
+ InSequence sequence;
+
+ EXPECT_CALL(*gl, GetString(GL_EXTENSIONS))
+ .WillOnce(Return(reinterpret_cast<const uint8*>(extensions)))
+ .RetiresOnSaturation();
+}
+
} // namespace gles2
} // namespace gpu
diff --git a/gpu/command_buffer/service/test_helper.h b/gpu/command_buffer/service/test_helper.h
index 2858b50..159665c 100644
--- a/gpu/command_buffer/service/test_helper.h
+++ b/gpu/command_buffer/service/test_helper.h
@@ -25,11 +25,17 @@ class TestHelper {
static const GLint kMaxTextureImageUnits = 8;
static const GLint kMaxVertexTextureImageUnits = 2;
static const GLint kMaxFragmentUniformVectors = 16;
+ static const GLint kMaxFragmentUniformComponents =
+ kMaxFragmentUniformVectors * 4;
static const GLint kMaxVaryingVectors = 8;
+ static const GLint kMaxVaryingFloats = kMaxVaryingVectors * 4;
static const GLint kMaxVertexUniformVectors = 128;
+ static const GLint kMaxVertexUniformComponents = kMaxVertexUniformVectors * 4;
static void SetupContextGroupInitExpectations(
::gfx::MockGLInterface* gl, const char* extensions);
+ static void SetupFeatureInfoInitExpectations(
+ ::gfx::MockGLInterface* gl, const char* extensions);
static void SetupTextureManagerInitExpectations(::gfx::MockGLInterface* gl);
};
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc
index 66a8d55..250da70 100644
--- a/gpu/command_buffer/service/texture_manager.cc
+++ b/gpu/command_buffer/service/texture_manager.cc
@@ -5,7 +5,7 @@
#include "gpu/command_buffer/service/texture_manager.h"
#include "base/bits.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
-#include "gpu/command_buffer/service/context_group.h"
+#include "gpu/command_buffer/service/feature_info.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
#include "gpu/GLES2/gles2_command_buffer.h"
@@ -87,13 +87,12 @@ void TextureManager::Destroy(bool have_context) {
}
bool TextureManager::TextureInfo::CanRender(
- const TextureManager* manager) const {
- DCHECK(manager);
+ const FeatureInfo* feature_info) const {
if (target_ == 0 || IsDeleted()) {
return false;
}
bool needs_mips = NeedsMips();
- if (npot() && !manager->npot_ok()) {
+ if (npot() && !feature_info->feature_flags().npot_ok) {
return !needs_mips &&
wrap_s_ == GL_CLAMP_TO_EDGE &&
wrap_t_ == GL_CLAMP_TO_EDGE;
@@ -110,8 +109,8 @@ bool TextureManager::TextureInfo::CanRender(
}
bool TextureManager::TextureInfo::MarkMipmapsGenerated(
- const TextureManager* manager) {
- if (!CanGenerateMipmaps(manager)) {
+ const FeatureInfo* feature_info) {
+ if (!CanGenerateMipmaps(feature_info)) {
return false;
}
for (size_t ii = 0; ii < level_infos_.size(); ++ii) {
@@ -124,7 +123,7 @@ bool TextureManager::TextureInfo::MarkMipmapsGenerated(
width = std::max(1, width >> 1);
height = std::max(1, height >> 1);
depth = std::max(1, depth >> 1);
- SetLevelInfo(manager,
+ SetLevelInfo(feature_info,
target_ == GL_TEXTURE_2D ? GL_TEXTURE_2D :
FaceIndexToGLTarget(ii),
level,
@@ -141,8 +140,9 @@ bool TextureManager::TextureInfo::MarkMipmapsGenerated(
}
bool TextureManager::TextureInfo::CanGenerateMipmaps(
- const TextureManager* manager) const {
- if ((npot() && !manager->npot_ok()) || level_infos_.empty() || IsDeleted()) {
+ const FeatureInfo* feature_info) const {
+ if ((npot() && !feature_info->feature_flags().npot_ok) ||
+ level_infos_.empty() || IsDeleted()) {
return false;
}
const TextureInfo::LevelInfo& first = level_infos_[0][0];
@@ -163,7 +163,7 @@ bool TextureManager::TextureInfo::CanGenerateMipmaps(
}
void TextureManager::TextureInfo::SetLevelInfo(
- const TextureManager* manager,
+ const FeatureInfo* feature_info,
GLenum target,
GLint level,
GLenum internal_format,
@@ -192,7 +192,7 @@ void TextureManager::TextureInfo::SetLevelInfo(
info.format = format;
info.type = type;
max_level_set_ = std::max(max_level_set_, level);
- Update(manager);
+ Update(feature_info);
}
bool TextureManager::TextureInfo::ValidForTexture(
@@ -253,8 +253,7 @@ bool TextureManager::TextureInfo::GetLevelType(
}
void TextureManager::TextureInfo::SetParameter(
- const TextureManager* manager, GLenum pname, GLint param) {
- DCHECK(manager);
+ const FeatureInfo* feature_info, GLenum pname, GLint param) {
switch (pname) {
case GL_TEXTURE_MIN_FILTER:
min_filter_ = param;
@@ -275,10 +274,10 @@ void TextureManager::TextureInfo::SetParameter(
NOTREACHED();
break;
}
- Update(manager);
+ Update(feature_info);
}
-void TextureManager::TextureInfo::Update(const TextureManager* manager) {
+void TextureManager::TextureInfo::Update(const FeatureInfo* feature_info) {
// Update npot status.
npot_ = false;
for (size_t ii = 0; ii < level_infos_.size(); ++ii) {
@@ -300,12 +299,13 @@ void TextureManager::TextureInfo::Update(const TextureManager* manager) {
max_level_set_ >= 0;
cube_complete_ = (level_infos_.size() == 6) &&
(first_face.width == first_face.height);
- if (first_face.type == GL_FLOAT && !manager->enable_float_linear() &&
+ if (first_face.type == GL_FLOAT &&
+ !feature_info->feature_flags().enable_texture_float_linear &&
(min_filter_ != GL_NEAREST_MIPMAP_NEAREST ||
mag_filter_ != GL_NEAREST)) {
texture_complete_ = false;
} else if (first_face.type == GL_HALF_FLOAT_OES &&
- !manager->enable_half_float_linear() &&
+ !feature_info->feature_flags().enable_texture_half_float_linear &&
(min_filter_ != GL_NEAREST_MIPMAP_NEAREST ||
mag_filter_ != GL_NEAREST)) {
texture_complete_ = false;
@@ -348,15 +348,9 @@ void TextureManager::TextureInfo::Update(const TextureManager* manager) {
}
TextureManager::TextureManager(
- bool npot_ok,
- bool enable_float_linear,
- bool enable_half_float_linear,
GLint max_texture_size,
GLint max_cube_map_texture_size)
- : npot_ok_(npot_ok),
- enable_float_linear_(enable_float_linear),
- enable_half_float_linear_(enable_half_float_linear),
- max_texture_size_(max_texture_size),
+ : max_texture_size_(max_texture_size),
max_cube_map_texture_size_(max_cube_map_texture_size),
max_levels_(ComputeMipMapCount(max_texture_size,
max_texture_size,
@@ -392,15 +386,16 @@ bool TextureManager::Initialize() {
glBindTexture(GL_TEXTURE_2D, 0);
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
+ FeatureInfo temp_feature_info;
default_texture_2d_ = TextureInfo::Ref(new TextureInfo(ids[1]));
SetInfoTarget(default_texture_2d_, GL_TEXTURE_2D);
- default_texture_2d_->SetLevelInfo(
- this, GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE);
+ default_texture_2d_->SetLevelInfo(&temp_feature_info,
+ GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE);
default_texture_cube_map_ = TextureInfo::Ref(new TextureInfo(ids[3]));
SetInfoTarget(default_texture_cube_map_, GL_TEXTURE_CUBE_MAP);
for (int ii = 0; ii < GLES2Util::kNumFaces; ++ii) {
default_texture_cube_map_->SetLevelInfo(
- this, GLES2Util::IndexToGLFaceTarget(ii),
+ &temp_feature_info, GLES2Util::IndexToGLFaceTarget(ii),
0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE);
}
@@ -411,6 +406,7 @@ bool TextureManager::Initialize() {
}
bool TextureManager::ValidForTarget(
+ const FeatureInfo* feature_info,
GLenum target, GLint level,
GLsizei width, GLsizei height, GLsizei depth) {
GLsizei max_size = MaxSizeForTarget(target);
@@ -422,7 +418,7 @@ bool TextureManager::ValidForTarget(
width <= max_size &&
height <= max_size &&
depth <= max_size &&
- (level == 0 || npot_ok() ||
+ (level == 0 || feature_info->feature_flags().npot_ok ||
(!GLES2Util::IsNPOT(width) &&
!GLES2Util::IsNPOT(height) &&
!GLES2Util::IsNPOT(depth))) &&
@@ -431,6 +427,7 @@ bool TextureManager::ValidForTarget(
}
void TextureManager::SetLevelInfo(
+ const FeatureInfo* feature_info,
TextureManager::TextureInfo* info,
GLenum target,
GLint level,
@@ -443,50 +440,54 @@ void TextureManager::SetLevelInfo(
GLenum type) {
DCHECK(info);
DCHECK(!info->IsDeleted());
- if (!info->CanRender(this)) {
+ if (!info->CanRender(feature_info)) {
--num_unrenderable_textures_;
}
info->SetLevelInfo(
- this, target, level, internal_format, width, height, depth,
+ feature_info, target, level, internal_format, width, height, depth,
border, format, type);
- if (!info->CanRender(this)) {
+ if (!info->CanRender(feature_info)) {
++num_unrenderable_textures_;
}
}
void TextureManager::SetParameter(
+ const FeatureInfo* feature_info,
TextureManager::TextureInfo* info, GLenum pname, GLint param) {
DCHECK(info);
DCHECK(!info->IsDeleted());
- if (!info->CanRender(this)) {
+ if (!info->CanRender(feature_info)) {
--num_unrenderable_textures_;
}
- info->SetParameter(this, pname, param);
- if (!info->CanRender(this)) {
+ info->SetParameter(feature_info, pname, param);
+ if (!info->CanRender(feature_info)) {
++num_unrenderable_textures_;
}
}
-bool TextureManager::MarkMipmapsGenerated(TextureManager::TextureInfo* info) {
+bool TextureManager::MarkMipmapsGenerated(
+ const FeatureInfo* feature_info,
+ TextureManager::TextureInfo* info) {
DCHECK(info);
DCHECK(!info->IsDeleted());
- if (!info->CanRender(this)) {
+ if (!info->CanRender(feature_info)) {
--num_unrenderable_textures_;
}
- bool result = info->MarkMipmapsGenerated(this);
- if (!info->CanRender(this)) {
+ bool result = info->MarkMipmapsGenerated(feature_info);
+ if (!info->CanRender(feature_info)) {
++num_unrenderable_textures_;
}
return result;
}
TextureManager::TextureInfo* TextureManager::CreateTextureInfo(
+ const FeatureInfo* feature_info,
GLuint client_id, GLuint service_id) {
TextureInfo::Ref info(new TextureInfo(service_id));
std::pair<TextureInfoMap::iterator, bool> result =
texture_infos_.insert(std::make_pair(client_id, info));
DCHECK(result.second);
- if (!info->CanRender(this)) {
+ if (!info->CanRender(feature_info)) {
++num_unrenderable_textures_;
}
return info.get();
@@ -498,11 +499,12 @@ TextureManager::TextureInfo* TextureManager::GetTextureInfo(
return it != texture_infos_.end() ? it->second : NULL;
}
-void TextureManager::RemoveTextureInfo(GLuint client_id) {
+void TextureManager::RemoveTextureInfo(
+ const FeatureInfo* feature_info, GLuint client_id) {
TextureInfoMap::iterator it = texture_infos_.find(client_id);
if (it != texture_infos_.end()) {
TextureInfo* info = it->second;
- if (!info->CanRender(this)) {
+ if (!info->CanRender(feature_info)) {
--num_unrenderable_textures_;
}
info->MarkAsDeleted();
diff --git a/gpu/command_buffer/service/texture_manager.h b/gpu/command_buffer/service/texture_manager.h
index 2ec46c1..182e0d1 100644
--- a/gpu/command_buffer/service/texture_manager.h
+++ b/gpu/command_buffer/service/texture_manager.h
@@ -15,6 +15,8 @@
namespace gpu {
namespace gles2 {
+class FeatureInfo;
+
// This class keeps track of the textures and their sizes so we can do NPOT and
// texture complete checking.
//
@@ -43,7 +45,7 @@ class TextureManager {
// True if this texture meets all the GLES2 criteria for rendering.
// See section 3.8.2 of the GLES2 spec.
- bool CanRender(const TextureManager* manager) const;
+ bool CanRender(const FeatureInfo* feature_info) const;
// The service side OpenGL id of the texture.
GLuint service_id() const {
@@ -76,7 +78,7 @@ class TextureManager {
}
// Returns true if mipmaps can be generated by GL.
- bool CanGenerateMipmaps(const TextureManager* manager) const;
+ bool CanGenerateMipmaps(const FeatureInfo* feature_info) const;
// Get the width and height for a particular level. Returns false if level
// does not exist.
@@ -133,7 +135,7 @@ class TextureManager {
// Set the info for a particular level.
void SetLevelInfo(
- const TextureManager* manager,
+ const FeatureInfo* feature_info,
GLenum target,
GLint level,
GLenum internal_format,
@@ -146,10 +148,11 @@ class TextureManager {
// Sets a texture parameter.
// TODO(gman): Expand to SetParameteri,f,iv,fv
- void SetParameter(const TextureManager* manager, GLenum pname, GLint param);
+ void SetParameter(
+ const FeatureInfo* feature_info, GLenum pname, GLint param);
// Makes each of the mip levels as though they were generated.
- bool MarkMipmapsGenerated(const TextureManager* manager);
+ bool MarkMipmapsGenerated(const FeatureInfo* feature_info);
void MarkAsDeleted() {
service_id_ = 0;
@@ -175,7 +178,7 @@ class TextureManager {
}
// Update info about this texture.
- void Update(const TextureManager* manager);
+ void Update(const FeatureInfo* feature_info);
// Info about each face and level of texture.
std::vector<std::vector<LevelInfo> > level_infos_;
@@ -210,10 +213,7 @@ class TextureManager {
DISALLOW_COPY_AND_ASSIGN(TextureInfo);
};
- TextureManager(bool npot_ok,
- bool enable_float_linear,
- bool enable_half_float_linear,
- GLsizei max_texture_size,
+ TextureManager(GLsizei max_texture_size,
GLsizei max_cube_map_texture_size);
~TextureManager();
@@ -223,21 +223,6 @@ class TextureManager {
// Must call before destruction.
void Destroy(bool have_context);
- // Whether or not npot textures can render.
- bool npot_ok() const {
- return npot_ok_;
- }
-
- // Whether float textures can have linear filtering.
- bool enable_float_linear() const {
- return enable_float_linear_;
- }
-
- // Whether half float textures can have linear filtering.
- bool enable_half_float_linear() const {
- return enable_half_float_linear_;
- }
-
// Returns the maximum number of levels.
GLint MaxLevelsForTarget(GLenum target) const {
return (target == GL_TEXTURE_2D) ? max_levels_ : max_cube_map_levels_;
@@ -251,6 +236,7 @@ class TextureManager {
// Checks if a dimensions are valid for a given target.
bool ValidForTarget(
+ const FeatureInfo* feature_info,
GLenum target, GLint level,
GLsizei width, GLsizei height, GLsizei depth);
@@ -265,6 +251,7 @@ class TextureManager {
// Set the info for a particular level in a TexureInfo.
void SetLevelInfo(
+ const FeatureInfo* feature_info,
TextureInfo* info,
GLenum target,
GLint level,
@@ -278,20 +265,25 @@ class TextureManager {
// Sets a texture parameter of a TextureInfo
// TODO(gman): Expand to SetParameteri,f,iv,fv
- void SetParameter(TextureInfo* info, GLenum pname, GLint param);
+ void SetParameter(
+ const FeatureInfo* feature_info,
+ TextureInfo* info, GLenum pname, GLint param);
// Makes each of the mip levels as though they were generated.
// Returns false if that's not allowed for the given texture.
- bool MarkMipmapsGenerated(TextureManager::TextureInfo* info);
+ bool MarkMipmapsGenerated(
+ const FeatureInfo* feature_info,
+ TextureManager::TextureInfo* info);
// Creates a new texture info.
- TextureInfo* CreateTextureInfo(GLuint client_id, GLuint service_id);
+ TextureInfo* CreateTextureInfo(
+ const FeatureInfo* feature_info, GLuint client_id, GLuint service_id);
// Gets the texture info for the given texture.
TextureInfo* GetTextureInfo(GLuint client_id);
// Removes a texture info.
- void RemoveTextureInfo(GLuint client_id);
+ void RemoveTextureInfo(const FeatureInfo* feature_info, GLuint client_id);
// Gets a client id for a given service id.
bool GetClientId(GLuint service_id, GLuint* client_id) const;
@@ -306,8 +298,8 @@ class TextureManager {
}
GLuint black_texture_id(GLenum target) const {
- return target == GL_SAMPLER_2D ? black_2d_texture_id_ :
- black_cube_texture_id_;
+ return target == GL_SAMPLER_2D ? black_2d_texture_id_ :
+ black_cube_texture_id_;
}
private:
@@ -316,9 +308,6 @@ class TextureManager {
typedef std::map<GLuint, TextureInfo::Ref> TextureInfoMap;
TextureInfoMap texture_infos_;
- bool npot_ok_;
- bool enable_float_linear_;
- bool enable_half_float_linear_;
GLsizei max_texture_size_;
GLsizei max_cube_map_texture_size_;
GLint max_levels_;
diff --git a/gpu/command_buffer/service/texture_manager_unittest.cc b/gpu/command_buffer/service/texture_manager_unittest.cc
index b313b32..b845e7f 100644
--- a/gpu/command_buffer/service/texture_manager_unittest.cc
+++ b/gpu/command_buffer/service/texture_manager_unittest.cc
@@ -7,6 +7,7 @@
#include "app/gfx/gl/gl_mock.h"
#include "gpu/GLES2/gles2_command_buffer.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "gpu/command_buffer/service/feature_info.h"
#include "gpu/command_buffer/service/test_helper.h"
using ::testing::Pointee;
@@ -29,7 +30,7 @@ class TextureManagerTest : public testing::Test {
TextureManagerTest()
- : manager_(false, false, false, kMaxTextureSize, kMaxCubeMapTextureSize) {
+ : manager_(kMaxTextureSize, kMaxCubeMapTextureSize) {
}
~TextureManagerTest() {
@@ -53,6 +54,7 @@ class TextureManagerTest : public testing::Test {
// Use StrictMock to make 100% sure we know how GL will be called.
scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_;
TextureManager manager_;
+ FeatureInfo feature_info_;
};
// GCC requires these declarations, but MSVC requires they not be present
@@ -73,7 +75,7 @@ TEST_F(TextureManagerTest, Basic) {
const GLuint kClient2Id = 2;
EXPECT_FALSE(manager_.HaveUnrenderableTextures());
// Check we can create texture.
- manager_.CreateTextureInfo(kClient1Id, kService1Id);
+ manager_.CreateTextureInfo(&feature_info_, kClient1Id, kService1Id);
// Check texture got created.
TextureManager::TextureInfo* info1 = manager_.GetTextureInfo(kClient1Id);
ASSERT_TRUE(info1 != NULL);
@@ -84,9 +86,9 @@ TEST_F(TextureManagerTest, Basic) {
// Check we get nothing for a non-existent texture.
EXPECT_TRUE(manager_.GetTextureInfo(kClient2Id) == NULL);
// Check trying to a remove non-existent textures does not crash.
- manager_.RemoveTextureInfo(kClient2Id);
+ manager_.RemoveTextureInfo(&feature_info_, kClient2Id);
// Check we can't get the texture after we remove it.
- manager_.RemoveTextureInfo(kClient1Id);
+ manager_.RemoveTextureInfo(&feature_info_, kClient1Id);
EXPECT_TRUE(manager_.GetTextureInfo(kClient1Id) == NULL);
}
@@ -95,7 +97,7 @@ TEST_F(TextureManagerTest, Destroy) {
const GLuint kService1Id = 11;
EXPECT_FALSE(manager_.HaveUnrenderableTextures());
// Check we can create texture.
- manager_.CreateTextureInfo(kClient1Id, kService1Id);
+ manager_.CreateTextureInfo(&feature_info_, kClient1Id, kService1Id);
// Check texture got created.
TextureManager::TextureInfo* info1 = manager_.GetTextureInfo(kClient1Id);
ASSERT_TRUE(info1 != NULL);
@@ -124,66 +126,73 @@ TEST_F(TextureManagerTest, MaxValues) {
TEST_F(TextureManagerTest, ValidForTarget) {
// check 2d
EXPECT_TRUE(manager_.ValidForTarget(
- GL_TEXTURE_2D, 0,
+ &feature_info_, GL_TEXTURE_2D, 0,
kMaxTextureSize, kMaxTextureSize, 1));
EXPECT_TRUE(manager_.ValidForTarget(
- GL_TEXTURE_2D, kMax2dLevels - 1,
+ &feature_info_, GL_TEXTURE_2D, kMax2dLevels - 1,
kMaxTextureSize, kMaxTextureSize, 1));
EXPECT_TRUE(manager_.ValidForTarget(
- GL_TEXTURE_2D, kMax2dLevels - 1,
+ &feature_info_, GL_TEXTURE_2D, kMax2dLevels - 1,
1, kMaxTextureSize, 1));
EXPECT_TRUE(manager_.ValidForTarget(
- GL_TEXTURE_2D, kMax2dLevels - 1,
+ &feature_info_, GL_TEXTURE_2D, kMax2dLevels - 1,
kMaxTextureSize, 1, 1));
// check level out of range.
EXPECT_FALSE(manager_.ValidForTarget(
- GL_TEXTURE_2D, kMax2dLevels,
+ &feature_info_, GL_TEXTURE_2D, kMax2dLevels,
kMaxTextureSize, 1, 1));
// check has depth.
EXPECT_FALSE(manager_.ValidForTarget(
- GL_TEXTURE_2D, kMax2dLevels,
+ &feature_info_, GL_TEXTURE_2D, kMax2dLevels,
kMaxTextureSize, 1, 2));
// Check NPOT width on level 0
- EXPECT_TRUE(manager_.ValidForTarget(GL_TEXTURE_2D, 0, 5, 2, 1));
+ EXPECT_TRUE(manager_.ValidForTarget(
+ &feature_info_, GL_TEXTURE_2D, 0, 5, 2, 1));
// Check NPOT height on level 0
- EXPECT_TRUE(manager_.ValidForTarget(GL_TEXTURE_2D, 0, 2, 5, 1));
+ EXPECT_TRUE(manager_.ValidForTarget(
+ &feature_info_, GL_TEXTURE_2D, 0, 2, 5, 1));
// Check NPOT width on level 1
- EXPECT_FALSE(manager_.ValidForTarget(GL_TEXTURE_2D, 1, 5, 2, 1));
+ EXPECT_FALSE(manager_.ValidForTarget(
+ &feature_info_, GL_TEXTURE_2D, 1, 5, 2, 1));
// Check NPOT height on level 1
- EXPECT_FALSE(manager_.ValidForTarget(GL_TEXTURE_2D, 1, 2, 5, 1));
+ EXPECT_FALSE(manager_.ValidForTarget(
+ &feature_info_, GL_TEXTURE_2D, 1, 2, 5, 1));
// check cube
EXPECT_TRUE(manager_.ValidForTarget(
- GL_TEXTURE_CUBE_MAP, 0,
+ &feature_info_, GL_TEXTURE_CUBE_MAP, 0,
kMaxCubeMapTextureSize, kMaxCubeMapTextureSize, 1));
EXPECT_TRUE(manager_.ValidForTarget(
- GL_TEXTURE_CUBE_MAP, kMaxCubeMapLevels - 1,
+ &feature_info_, GL_TEXTURE_CUBE_MAP, kMaxCubeMapLevels - 1,
kMaxCubeMapTextureSize, kMaxCubeMapTextureSize, 1));
// check level out of range.
EXPECT_FALSE(manager_.ValidForTarget(
- GL_TEXTURE_CUBE_MAP, kMaxCubeMapLevels,
+ &feature_info_, GL_TEXTURE_CUBE_MAP, kMaxCubeMapLevels,
kMaxCubeMapTextureSize, 1, 1));
// check not square.
EXPECT_FALSE(manager_.ValidForTarget(
- GL_TEXTURE_CUBE_MAP, kMaxCubeMapLevels,
+ &feature_info_, GL_TEXTURE_CUBE_MAP, kMaxCubeMapLevels,
kMaxCubeMapTextureSize, 1, 1));
// check has depth.
EXPECT_FALSE(manager_.ValidForTarget(
- GL_TEXTURE_CUBE_MAP, kMaxCubeMapLevels,
+ &feature_info_, GL_TEXTURE_CUBE_MAP, kMaxCubeMapLevels,
kMaxCubeMapTextureSize, 1, 2));
}
TEST_F(TextureManagerTest, ValidForTargetNPOT) {
- TextureManager manager(
- true, false, false, kMaxTextureSize, kMaxCubeMapTextureSize);
+ TextureManager manager(kMaxTextureSize, kMaxCubeMapTextureSize);
+ TestHelper::SetupFeatureInfoInitExpectations(
+ gl_.get(), "GL_OES_texture_npot");
+ FeatureInfo feature_info;
+ feature_info.Initialize(NULL);
// Check NPOT width on level 0
- EXPECT_TRUE(manager.ValidForTarget(GL_TEXTURE_2D, 0, 5, 2, 1));
+ EXPECT_TRUE(manager.ValidForTarget(&feature_info, GL_TEXTURE_2D, 0, 5, 2, 1));
// Check NPOT height on level 0
- EXPECT_TRUE(manager.ValidForTarget(GL_TEXTURE_2D, 0, 2, 5, 1));
+ EXPECT_TRUE(manager.ValidForTarget(&feature_info, GL_TEXTURE_2D, 0, 2, 5, 1));
// Check NPOT width on level 1
- EXPECT_TRUE(manager.ValidForTarget(GL_TEXTURE_2D, 1, 5, 2, 1));
+ EXPECT_TRUE(manager.ValidForTarget(&feature_info, GL_TEXTURE_2D, 1, 5, 2, 1));
// Check NPOT height on level 1
- EXPECT_TRUE(manager.ValidForTarget(GL_TEXTURE_2D, 1, 2, 5, 1));
+ EXPECT_TRUE(manager.ValidForTarget(&feature_info, GL_TEXTURE_2D, 1, 2, 5, 1));
manager.Destroy(false);
}
@@ -197,7 +206,7 @@ class TextureInfoTest : public testing::Test {
static const GLuint kService1Id = 11;
TextureInfoTest()
- : manager_(false, false, false, kMaxTextureSize, kMaxCubeMapTextureSize) {
+ : manager_(kMaxTextureSize, kMaxCubeMapTextureSize) {
}
~TextureInfoTest() {
manager_.Destroy(false);
@@ -207,7 +216,7 @@ class TextureInfoTest : public testing::Test {
virtual void SetUp() {
gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>());
::gfx::GLInterface::SetGLInterface(gl_.get());
- manager_.CreateTextureInfo(kClient1Id, kService1Id);
+ manager_.CreateTextureInfo(&feature_info_, kClient1Id, kService1Id);
info_ = manager_.GetTextureInfo(kClient1Id);
ASSERT_TRUE(info_ != NULL);
}
@@ -221,15 +230,16 @@ class TextureInfoTest : public testing::Test {
scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_;
TextureManager manager_;
TextureManager::TextureInfo* info_;
+ FeatureInfo feature_info_;
};
TEST_F(TextureInfoTest, Basic) {
EXPECT_EQ(0u, info_->target());
EXPECT_FALSE(info_->texture_complete());
EXPECT_FALSE(info_->cube_complete());
- EXPECT_FALSE(info_->CanGenerateMipmaps(&manager_));
+ EXPECT_FALSE(info_->CanGenerateMipmaps(&feature_info_));
EXPECT_FALSE(info_->npot());
- EXPECT_FALSE(info_->CanRender(&manager_));
+ EXPECT_FALSE(info_->CanRender(&feature_info_));
EXPECT_TRUE(manager_.HaveUnrenderableTextures());
}
@@ -237,41 +247,43 @@ TEST_F(TextureInfoTest, POT2D) {
manager_.SetInfoTarget(info_, GL_TEXTURE_2D);
EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), info_->target());
// Check Setting level 0 to POT
- manager_.SetLevelInfo(info_,
+ manager_.SetLevelInfo(&feature_info_, info_,
GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE);
EXPECT_FALSE(info_->npot());
EXPECT_FALSE(info_->texture_complete());
- EXPECT_FALSE(info_->CanRender(&manager_));
+ EXPECT_FALSE(info_->CanRender(&feature_info_));
EXPECT_TRUE(manager_.HaveUnrenderableTextures());
// Set filters to something that will work with a single mip.
- manager_.SetParameter(info_, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- EXPECT_TRUE(info_->CanRender(&manager_));
+ manager_.SetParameter(
+ &feature_info_, info_, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ EXPECT_TRUE(info_->CanRender(&feature_info_));
EXPECT_FALSE(manager_.HaveUnrenderableTextures());
// Set them back.
- manager_.SetParameter(info_, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ manager_.SetParameter(
+ &feature_info_, info_, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
EXPECT_TRUE(manager_.HaveUnrenderableTextures());
- EXPECT_TRUE(info_->CanGenerateMipmaps(&manager_));
+ EXPECT_TRUE(info_->CanGenerateMipmaps(&feature_info_));
// Make mips.
- EXPECT_TRUE(manager_.MarkMipmapsGenerated(info_));
+ EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_));
EXPECT_TRUE(info_->texture_complete());
- EXPECT_TRUE(info_->CanRender(&manager_));
+ EXPECT_TRUE(info_->CanRender(&feature_info_));
EXPECT_FALSE(manager_.HaveUnrenderableTextures());
// Change a mip.
- manager_.SetLevelInfo(info_,
+ manager_.SetLevelInfo(&feature_info_, info_,
GL_TEXTURE_2D, 1, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE);
EXPECT_FALSE(info_->npot());
EXPECT_FALSE(info_->texture_complete());
- EXPECT_TRUE(info_->CanGenerateMipmaps(&manager_));
- EXPECT_FALSE(info_->CanRender(&manager_));
+ EXPECT_TRUE(info_->CanGenerateMipmaps(&feature_info_));
+ EXPECT_FALSE(info_->CanRender(&feature_info_));
EXPECT_TRUE(manager_.HaveUnrenderableTextures());
// Set a level past the number of mips that would get generated.
- manager_.SetLevelInfo(info_,
+ manager_.SetLevelInfo(&feature_info_, info_,
GL_TEXTURE_2D, 3, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE);
- EXPECT_TRUE(info_->CanGenerateMipmaps(&manager_));
+ EXPECT_TRUE(info_->CanGenerateMipmaps(&feature_info_));
// Make mips.
- EXPECT_TRUE(manager_.MarkMipmapsGenerated(info_));
- EXPECT_FALSE(info_->CanRender(&manager_));
+ EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_));
+ EXPECT_FALSE(info_->CanRender(&feature_info_));
EXPECT_FALSE(info_->texture_complete());
EXPECT_TRUE(manager_.HaveUnrenderableTextures());
}
@@ -280,51 +292,57 @@ TEST_F(TextureInfoTest, NPOT2D) {
manager_.SetInfoTarget(info_, GL_TEXTURE_2D);
EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), info_->target());
// Check Setting level 0 to NPOT
- manager_.SetLevelInfo(info_,
+ manager_.SetLevelInfo(&feature_info_, info_,
GL_TEXTURE_2D, 0, GL_RGBA, 4, 5, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE);
EXPECT_TRUE(info_->npot());
EXPECT_FALSE(info_->texture_complete());
- EXPECT_FALSE(info_->CanGenerateMipmaps(&manager_));
- EXPECT_FALSE(info_->CanRender(&manager_));
+ EXPECT_FALSE(info_->CanGenerateMipmaps(&feature_info_));
+ EXPECT_FALSE(info_->CanRender(&feature_info_));
EXPECT_TRUE(manager_.HaveUnrenderableTextures());
- manager_.SetParameter(info_, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- EXPECT_FALSE(info_->CanRender(&manager_));
+ manager_.SetParameter(
+ &feature_info_, info_, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ EXPECT_FALSE(info_->CanRender(&feature_info_));
EXPECT_TRUE(manager_.HaveUnrenderableTextures());
- manager_.SetParameter(info_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- EXPECT_FALSE(info_->CanRender(&manager_));
+ manager_.SetParameter(
+ &feature_info_, info_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ EXPECT_FALSE(info_->CanRender(&feature_info_));
EXPECT_TRUE(manager_.HaveUnrenderableTextures());
- manager_.SetParameter(info_, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- EXPECT_TRUE(info_->CanRender(&manager_));
+ manager_.SetParameter(
+ &feature_info_, info_, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ EXPECT_TRUE(info_->CanRender(&feature_info_));
EXPECT_FALSE(manager_.HaveUnrenderableTextures());
// Change it to POT.
- manager_.SetLevelInfo(info_,
+ manager_.SetLevelInfo(&feature_info_, info_,
GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE);
EXPECT_FALSE(info_->npot());
EXPECT_FALSE(info_->texture_complete());
- EXPECT_TRUE(info_->CanGenerateMipmaps(&manager_));
+ EXPECT_TRUE(info_->CanGenerateMipmaps(&feature_info_));
EXPECT_FALSE(manager_.HaveUnrenderableTextures());
}
TEST_F(TextureInfoTest, NPOT2DNPOTOK) {
- TextureManager manager(
- true, false, false, kMaxTextureSize, kMaxCubeMapTextureSize);
- manager.CreateTextureInfo(kClient1Id, kService1Id);
+ TextureManager manager(kMaxTextureSize, kMaxCubeMapTextureSize);
+ TestHelper::SetupFeatureInfoInitExpectations(
+ gl_.get(), "GL_OES_texture_npot");
+ FeatureInfo feature_info;
+ feature_info.Initialize(NULL);
+ manager.CreateTextureInfo(&feature_info, kClient1Id, kService1Id);
TextureManager::TextureInfo* info = manager_.GetTextureInfo(kClient1Id);
ASSERT_TRUE(info_ != NULL);
manager.SetInfoTarget(info, GL_TEXTURE_2D);
EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), info->target());
// Check Setting level 0 to NPOT
- manager.SetLevelInfo(info,
+ manager.SetLevelInfo(&feature_info, info,
GL_TEXTURE_2D, 0, GL_RGBA, 4, 5, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE);
EXPECT_TRUE(info->npot());
EXPECT_FALSE(info->texture_complete());
- EXPECT_TRUE(info->CanGenerateMipmaps(&manager));
- EXPECT_FALSE(info->CanRender(&manager));
+ EXPECT_TRUE(info->CanGenerateMipmaps(&feature_info));
+ EXPECT_FALSE(info->CanRender(&feature_info));
EXPECT_TRUE(manager.HaveUnrenderableTextures());
- EXPECT_TRUE(manager.MarkMipmapsGenerated(info));
+ EXPECT_TRUE(manager.MarkMipmapsGenerated(&feature_info, info));
EXPECT_TRUE(info->texture_complete());
- EXPECT_TRUE(info->CanRender(&manager));
+ EXPECT_TRUE(info->CanRender(&feature_info));
EXPECT_FALSE(manager.HaveUnrenderableTextures());
manager.Destroy(false);
}
@@ -333,90 +351,90 @@ TEST_F(TextureInfoTest, POTCubeMap) {
manager_.SetInfoTarget(info_, GL_TEXTURE_CUBE_MAP);
EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_CUBE_MAP), info_->target());
// Check Setting level 0 each face to POT
- manager_.SetLevelInfo(info_,
+ manager_.SetLevelInfo(&feature_info_, info_,
GL_TEXTURE_CUBE_MAP_POSITIVE_X,
0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE);
EXPECT_FALSE(info_->npot());
EXPECT_FALSE(info_->texture_complete());
EXPECT_FALSE(info_->cube_complete());
- EXPECT_FALSE(info_->CanGenerateMipmaps(&manager_));
- EXPECT_FALSE(info_->CanRender(&manager_));
+ EXPECT_FALSE(info_->CanGenerateMipmaps(&feature_info_));
+ EXPECT_FALSE(info_->CanRender(&feature_info_));
EXPECT_TRUE(manager_.HaveUnrenderableTextures());
- manager_.SetLevelInfo(info_,
+ manager_.SetLevelInfo(&feature_info_, info_,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE);
EXPECT_FALSE(info_->npot());
EXPECT_FALSE(info_->texture_complete());
EXPECT_FALSE(info_->cube_complete());
- EXPECT_FALSE(info_->CanGenerateMipmaps(&manager_));
- EXPECT_FALSE(info_->CanRender(&manager_));
+ EXPECT_FALSE(info_->CanGenerateMipmaps(&feature_info_));
+ EXPECT_FALSE(info_->CanRender(&feature_info_));
EXPECT_TRUE(manager_.HaveUnrenderableTextures());
- manager_.SetLevelInfo(info_,
+ manager_.SetLevelInfo(&feature_info_, info_,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE);
EXPECT_FALSE(info_->npot());
EXPECT_FALSE(info_->texture_complete());
EXPECT_FALSE(info_->cube_complete());
- EXPECT_FALSE(info_->CanGenerateMipmaps(&manager_));
- EXPECT_FALSE(info_->CanRender(&manager_));
+ EXPECT_FALSE(info_->CanGenerateMipmaps(&feature_info_));
+ EXPECT_FALSE(info_->CanRender(&feature_info_));
EXPECT_TRUE(manager_.HaveUnrenderableTextures());
- manager_.SetLevelInfo(info_,
+ manager_.SetLevelInfo(&feature_info_, info_,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE);
EXPECT_FALSE(info_->npot());
EXPECT_FALSE(info_->texture_complete());
EXPECT_FALSE(info_->cube_complete());
- EXPECT_FALSE(info_->CanRender(&manager_));
- EXPECT_FALSE(info_->CanGenerateMipmaps(&manager_));
+ EXPECT_FALSE(info_->CanRender(&feature_info_));
+ EXPECT_FALSE(info_->CanGenerateMipmaps(&feature_info_));
EXPECT_TRUE(manager_.HaveUnrenderableTextures());
- manager_.SetLevelInfo(info_,
+ manager_.SetLevelInfo(&feature_info_, info_,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE);
EXPECT_FALSE(info_->npot());
EXPECT_FALSE(info_->texture_complete());
EXPECT_FALSE(info_->cube_complete());
- EXPECT_FALSE(info_->CanGenerateMipmaps(&manager_));
- EXPECT_FALSE(info_->CanRender(&manager_));
+ EXPECT_FALSE(info_->CanGenerateMipmaps(&feature_info_));
+ EXPECT_FALSE(info_->CanRender(&feature_info_));
EXPECT_TRUE(manager_.HaveUnrenderableTextures());
- manager_.SetLevelInfo(info_,
+ manager_.SetLevelInfo(&feature_info_, info_,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE);
EXPECT_FALSE(info_->npot());
EXPECT_FALSE(info_->texture_complete());
EXPECT_TRUE(info_->cube_complete());
- EXPECT_TRUE(info_->CanGenerateMipmaps(&manager_));
- EXPECT_FALSE(info_->CanRender(&manager_));
+ EXPECT_TRUE(info_->CanGenerateMipmaps(&feature_info_));
+ EXPECT_FALSE(info_->CanRender(&feature_info_));
EXPECT_TRUE(manager_.HaveUnrenderableTextures());
// Make mips.
- EXPECT_TRUE(manager_.MarkMipmapsGenerated(info_));
+ EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_));
EXPECT_TRUE(info_->texture_complete());
EXPECT_TRUE(info_->cube_complete());
- EXPECT_TRUE(info_->CanRender(&manager_));
+ EXPECT_TRUE(info_->CanRender(&feature_info_));
EXPECT_FALSE(manager_.HaveUnrenderableTextures());
// Change a mip.
- manager_.SetLevelInfo(info_,
+ manager_.SetLevelInfo(&feature_info_, info_,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
1, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE);
EXPECT_FALSE(info_->npot());
EXPECT_FALSE(info_->texture_complete());
EXPECT_TRUE(info_->cube_complete());
- EXPECT_TRUE(info_->CanGenerateMipmaps(&manager_));
+ EXPECT_TRUE(info_->CanGenerateMipmaps(&feature_info_));
// Set a level past the number of mips that would get generated.
- manager_.SetLevelInfo(info_,
+ manager_.SetLevelInfo(&feature_info_, info_,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
3, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE);
- EXPECT_TRUE(info_->CanGenerateMipmaps(&manager_));
+ EXPECT_TRUE(info_->CanGenerateMipmaps(&feature_info_));
// Make mips.
- EXPECT_TRUE(manager_.MarkMipmapsGenerated(info_));
+ EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_));
EXPECT_FALSE(info_->texture_complete());
EXPECT_TRUE(info_->cube_complete());
}
TEST_F(TextureInfoTest, GetLevelSize) {
manager_.SetInfoTarget(info_, GL_TEXTURE_2D);
- manager_.SetLevelInfo(info_,
+ manager_.SetLevelInfo(&feature_info_, info_,
GL_TEXTURE_2D, 1, GL_RGBA, 4, 5, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE);
GLsizei width = -1;
GLsizei height = -1;
@@ -428,13 +446,13 @@ TEST_F(TextureInfoTest, GetLevelSize) {
EXPECT_TRUE(info_->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height));
EXPECT_EQ(4, width);
EXPECT_EQ(5, height);
- manager_.RemoveTextureInfo(kClient1Id);
+ manager_.RemoveTextureInfo(&feature_info_, kClient1Id);
EXPECT_FALSE(info_->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height));
}
TEST_F(TextureInfoTest, GetLevelType) {
manager_.SetInfoTarget(info_, GL_TEXTURE_2D);
- manager_.SetLevelInfo(info_,
+ manager_.SetLevelInfo(&feature_info_, info_,
GL_TEXTURE_2D, 1, GL_RGBA, 4, 5, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE);
GLenum type = -1;
GLenum format = -1;
@@ -446,13 +464,13 @@ TEST_F(TextureInfoTest, GetLevelType) {
EXPECT_TRUE(info_->GetLevelType(GL_TEXTURE_2D, 1, &type, &format));
EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
EXPECT_EQ(static_cast<GLenum>(GL_RGBA), format);
- manager_.RemoveTextureInfo(kClient1Id);
+ manager_.RemoveTextureInfo(&feature_info_, kClient1Id);
EXPECT_FALSE(info_->GetLevelType(GL_TEXTURE_2D, 1, &type, &format));
}
TEST_F(TextureInfoTest, ValidForTexture) {
manager_.SetInfoTarget(info_, GL_TEXTURE_2D);
- manager_.SetLevelInfo(info_,
+ manager_.SetLevelInfo(&feature_info_, info_,
GL_TEXTURE_2D, 1, GL_RGBA, 4, 5, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE);
// Check bad face.
EXPECT_FALSE(info_->ValidForTexture(
@@ -491,70 +509,84 @@ TEST_F(TextureInfoTest, ValidForTexture) {
// Check valid particial size.
EXPECT_TRUE(info_->ValidForTexture(
GL_TEXTURE_2D, 1, 1, 1, 2, 3, GL_RGBA, GL_UNSIGNED_BYTE));
- manager_.RemoveTextureInfo(kClient1Id);
+ manager_.RemoveTextureInfo(&feature_info_, kClient1Id);
EXPECT_FALSE(info_->ValidForTexture(
GL_TEXTURE_2D, 1, 0, 0, 4, 5, GL_RGBA, GL_UNSIGNED_BYTE));
}
TEST_F(TextureInfoTest, FloatNotLinear) {
- TextureManager manager(
- false, false, false, kMaxTextureSize, kMaxCubeMapTextureSize);
- manager.CreateTextureInfo(kClient1Id, kService1Id);
+ TextureManager manager(kMaxTextureSize, kMaxCubeMapTextureSize);
+ TestHelper::SetupFeatureInfoInitExpectations(
+ gl_.get(), "GL_OES_texture_float");
+ FeatureInfo feature_info;
+ feature_info.Initialize(NULL);
+ manager.CreateTextureInfo(&feature_info, kClient1Id, kService1Id);
TextureManager::TextureInfo* info = manager_.GetTextureInfo(kClient1Id);
- ASSERT_TRUE(info_ != NULL);
+ ASSERT_TRUE(info != NULL);
manager.SetInfoTarget(info, GL_TEXTURE_2D);
EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), info->target());
- manager.SetLevelInfo(info,
+ manager.SetLevelInfo(&feature_info, info,
GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_FLOAT);
EXPECT_FALSE(info->texture_complete());
- manager.SetParameter(info, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ manager.SetParameter(&feature_info, info, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
EXPECT_FALSE(info->texture_complete());
- manager.SetParameter(info, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
+ manager.SetParameter(
+ &feature_info, info, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
EXPECT_TRUE(info->texture_complete());
manager.Destroy(false);
}
TEST_F(TextureInfoTest, FloatLinear) {
- TextureManager manager(
- false, true, false, kMaxTextureSize, kMaxCubeMapTextureSize);
- manager.CreateTextureInfo(kClient1Id, kService1Id);
+ TextureManager manager(kMaxTextureSize, kMaxCubeMapTextureSize);
+ TestHelper::SetupFeatureInfoInitExpectations(
+ gl_.get(), "GL_OES_texture_float GL_OES_texture_float_linear");
+ FeatureInfo feature_info;
+ feature_info.Initialize(NULL);
+ manager.CreateTextureInfo(&feature_info, kClient1Id, kService1Id);
TextureManager::TextureInfo* info = manager_.GetTextureInfo(kClient1Id);
- ASSERT_TRUE(info_ != NULL);
+ ASSERT_TRUE(info != NULL);
manager.SetInfoTarget(info, GL_TEXTURE_2D);
EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), info->target());
- manager.SetLevelInfo(info,
+ manager.SetLevelInfo(&feature_info, info,
GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_FLOAT);
EXPECT_TRUE(info->texture_complete());
manager.Destroy(false);
}
TEST_F(TextureInfoTest, HalfFloatNotLinear) {
- TextureManager manager(
- false, false, false, kMaxTextureSize, kMaxCubeMapTextureSize);
- manager.CreateTextureInfo(kClient1Id, kService1Id);
+ TextureManager manager(kMaxTextureSize, kMaxCubeMapTextureSize);
+ TestHelper::SetupFeatureInfoInitExpectations(
+ gl_.get(), "GL_OES_texture_half_float");
+ FeatureInfo feature_info;
+ feature_info.Initialize(NULL);
+ manager.CreateTextureInfo(&feature_info, kClient1Id, kService1Id);
TextureManager::TextureInfo* info = manager_.GetTextureInfo(kClient1Id);
- ASSERT_TRUE(info_ != NULL);
+ ASSERT_TRUE(info != NULL);
manager.SetInfoTarget(info, GL_TEXTURE_2D);
EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), info->target());
- manager.SetLevelInfo(info,
+ manager.SetLevelInfo(&feature_info, info,
GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_HALF_FLOAT_OES);
EXPECT_FALSE(info->texture_complete());
- manager.SetParameter(info, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ manager.SetParameter(&feature_info, info, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
EXPECT_FALSE(info->texture_complete());
- manager.SetParameter(info, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
+ manager.SetParameter(
+ &feature_info, info, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
EXPECT_TRUE(info->texture_complete());
manager.Destroy(false);
}
TEST_F(TextureInfoTest, HalfFloatLinear) {
- TextureManager manager(
- false, false, true, kMaxTextureSize, kMaxCubeMapTextureSize);
- manager.CreateTextureInfo(kClient1Id, kService1Id);
+ TextureManager manager(kMaxTextureSize, kMaxCubeMapTextureSize);
+ TestHelper::SetupFeatureInfoInitExpectations(
+ gl_.get(), "GL_OES_texture_half_float GL_OES_texture_half_float_linear");
+ FeatureInfo feature_info;
+ feature_info.Initialize(NULL);
+ manager.CreateTextureInfo(&feature_info, kClient1Id, kService1Id);
TextureManager::TextureInfo* info = manager_.GetTextureInfo(kClient1Id);
- ASSERT_TRUE(info_ != NULL);
+ ASSERT_TRUE(info != NULL);
manager.SetInfoTarget(info, GL_TEXTURE_2D);
EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), info->target());
- manager.SetLevelInfo(info,
+ manager.SetLevelInfo(&feature_info, info,
GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_HALF_FLOAT_OES);
EXPECT_TRUE(info->texture_complete());
manager.Destroy(false);
diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp
index 8b6622a..6f1b4d7 100644
--- a/gpu/gpu.gyp
+++ b/gpu/gpu.gyp
@@ -149,6 +149,8 @@
'command_buffer/service/common_decoder.h',
'command_buffer/service/context_group.h',
'command_buffer/service/context_group.cc',
+ 'command_buffer/service/feature_info.h',
+ 'command_buffer/service/feature_info.cc',
'command_buffer/service/gles2_cmd_decoder.h',
'command_buffer/service/gles2_cmd_decoder_autogen.h',
'command_buffer/service/gles2_cmd_decoder.cc',
@@ -246,6 +248,7 @@
'command_buffer/service/cmd_parser_test.cc',
'command_buffer/service/cmd_parser_test.cc',
'command_buffer/service/common_decoder_unittest.cc',
+ 'command_buffer/service/feature_info_unittest.cc',
'command_buffer/service/framebuffer_manager_unittest.cc',
'command_buffer/service/gpu_processor_unittest.cc',
'command_buffer/service/gles2_cmd_decoder_unittest_base.h',