Skip to content

Commit

Permalink
Move workarounds to one spot.
Browse files Browse the repository at this point in the history
I felt like all the platform checks should only be in one place
and the workarounds should work on flags rather than specific
platforms.

BUG=none


Review URL: https://chromiumcodereview.appspot.com/11250002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@163709 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
gman@chromium.org committed Oct 23, 2012
1 parent e4de4d1 commit 62e155e
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 217 deletions.
36 changes: 9 additions & 27 deletions gpu/command_buffer/service/context_group.cc
Original file line number Diff line number Diff line change
Expand Up @@ -139,34 +139,16 @@ bool ContextGroup::Initialize(const DisallowedFeatures& disallowed_features,
return false;
}

// Limit Intel on Mac to 4096 max tex size and 1024 max cube map tex size.
// Limit AMD on Mac to 4096 max tex size and max cube map tex size.
// TODO(gman): Update this code to check for a specific version of
// the drivers above which we no longer need this fix.
#if defined(OS_MACOSX)
if (!feature_info_->feature_flags().disable_workarounds) {
if (feature_info_->feature_flags().is_intel) {
max_texture_size = std::min(
static_cast<GLint>(4096), max_texture_size);

GLint cubemap_size_limit = 1024;
// Cubemaps > 512 in size were broken before 10.7.3.
int32 major, minor, bugfix;
base::SysInfo::OperatingSystemVersionNumbers(&major, &minor, &bugfix);
if (major < 10 ||
(major == 10 && ((minor == 7 && bugfix < 3) || (minor < 7))))
cubemap_size_limit = 512;
max_cube_map_texture_size = std::min(
cubemap_size_limit, max_cube_map_texture_size);
}
if (feature_info_->feature_flags().is_amd) {
max_texture_size = std::min(
static_cast<GLint>(4096), max_texture_size);
max_cube_map_texture_size = std::min(
static_cast<GLint>(4096), max_cube_map_texture_size);
}
if (feature_info_->workarounds().max_texture_size) {
max_texture_size = std::min(
max_texture_size, feature_info_->workarounds().max_texture_size);
}
#endif
if (feature_info_->workarounds().max_cube_map_texture_size) {
max_cube_map_texture_size = std::min(
max_cube_map_texture_size,
feature_info_->workarounds().max_cube_map_texture_size);
}

texture_manager_.reset(new TextureManager(memory_tracker_,
feature_info_.get(),
max_texture_size,
Expand Down
77 changes: 64 additions & 13 deletions gpu/command_buffer/service/feature_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,19 @@ FeatureInfo::FeatureFlags::FeatureFlags()
occlusion_query_boolean(false),
use_arb_occlusion_query2_for_occlusion_query_boolean(false),
use_arb_occlusion_query_for_occlusion_query_boolean(false),
native_vertex_array_object_(false),
disable_workarounds(false),
is_intel(false),
is_nvidia(false),
is_amd(false),
is_mesa(false) {
native_vertex_array_object(false),
disable_workarounds(false) {
}

FeatureInfo::Workarounds::Workarounds()
: clear_alpha_in_readpixels(false),
needs_glsl_built_in_function_emulation(false),
needs_offscreen_buffer_workaround(false),
reverse_point_sprite_coord_origin(false),
set_texture_filter_before_generating_mipmap(false),
use_current_program_after_successful_link(false),
max_texture_size(0),
max_cube_map_texture_size(0) {
}

FeatureInfo::FeatureInfo() {
Expand Down Expand Up @@ -198,17 +205,20 @@ void FeatureInfo::AddFeatures(const char* desired_features) {
GL_VENDOR,
GL_RENDERER,
};
bool is_intel = false;
bool is_nvidia = false;
bool is_amd = false;
bool is_mesa = false;
for (size_t ii = 0; ii < arraysize(string_ids); ++ii) {
const char* str = reinterpret_cast<const char*>(
glGetString(string_ids[ii]));
if (str) {
std::string lstr(StringToLowerASCII(std::string(str)));
StringSet string_set(lstr);
feature_flags_.is_intel |= string_set.Contains("intel");
feature_flags_.is_nvidia |= string_set.Contains("nvidia");
feature_flags_.is_amd |=
string_set.Contains("amd") || string_set.Contains("ati");
feature_flags_.is_mesa |= string_set.Contains("mesa");
is_intel |= string_set.Contains("intel");
is_nvidia |= string_set.Contains("nvidia");
is_amd |= string_set.Contains("amd") || string_set.Contains("ati");
is_mesa |= string_set.Contains("mesa");
}
}

Expand Down Expand Up @@ -351,7 +361,7 @@ void FeatureInfo::AddFeatures(const char* desired_features) {
if (ext.Have("GL_OES_vertex_array_object") ||
ext.Have("GL_ARB_vertex_array_object") ||
ext.Have("GL_APPLE_vertex_array_object")) {
feature_flags_.native_vertex_array_object_ = true;
feature_flags_.native_vertex_array_object = true;
}

// OES_vertex_array_object is emulated if not present natively,
Expand Down Expand Up @@ -607,7 +617,7 @@ void FeatureInfo::AddFeatures(const char* desired_features) {
#if defined(OS_LINUX)
if (!feature_flags_.disable_workarounds) {
// Intel drivers on Linux appear to be buggy.
ext_occlusion_query_disallowed = feature_flags_.is_intel;
ext_occlusion_query_disallowed = is_intel;
}
#endif

Expand Down Expand Up @@ -636,6 +646,47 @@ void FeatureInfo::AddFeatures(const char* desired_features) {

if (!disallowed_features_.swap_buffer_complete_callback)
AddExtensionString("GL_CHROMIUM_swapbuffers_complete_callback");

if (!feature_flags_.disable_workarounds) {
workarounds_.set_texture_filter_before_generating_mipmap = true;
workarounds_.clear_alpha_in_readpixels = true;

if (is_nvidia) {
workarounds_.use_current_program_after_successful_link = true;
}

#if defined(OS_MACOSX)
workarounds_.needs_offscreen_buffer_workaround = is_nvidia;
workarounds_.needs_glsl_built_in_function_emulation = is_amd;

if ((is_amd || is_intel) &&
gfx::GetGLImplementation() == gfx::kGLImplementationDesktopGL) {
workarounds_.reverse_point_sprite_coord_origin = true;
}

// Limit Intel on Mac to 4096 max tex size and 1024 max cube map tex size.
// Limit AMD on Mac to 4096 max tex size and max cube map tex size.
// TODO(gman): Update this code to check for a specific version of
// the drivers above which we no longer need this fix.
if (is_intel) {
workarounds_.max_texture_size = 4096;
workarounds_.max_cube_map_texture_size = 1024;
// Cubemaps > 512 in size were broken before 10.7.3.
int32 major = 0;
int32 minor = 0;
int32 bugfix = 0;
base::SysInfo::OperatingSystemVersionNumbers(&major, &minor, &bugfix);
if (major < 10 ||
(major == 10 && ((minor == 7 && bugfix < 3) || (minor < 7))))
workarounds_.max_cube_map_texture_size = 512;
}

if (is_amd) {
workarounds_.max_texture_size = 4096;
workarounds_.max_cube_map_texture_size = 4096;
}
#endif
}
}

void FeatureInfo::AddExtensionString(const std::string& str) {
Expand Down
30 changes: 25 additions & 5 deletions gpu/command_buffer/service/feature_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <string>
#include "base/hash_tables.h"
#include "base/memory/ref_counted.h"
#include "base/sys_info.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
#include "gpu/command_buffer/service/gles2_cmd_validation.h"
#include "gpu/gpu_export.h"
Expand Down Expand Up @@ -38,12 +39,24 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> {
bool occlusion_query_boolean;
bool use_arb_occlusion_query2_for_occlusion_query_boolean;
bool use_arb_occlusion_query_for_occlusion_query_boolean;
bool native_vertex_array_object_;
bool native_vertex_array_object;
bool disable_workarounds;
bool is_intel;
bool is_nvidia;
bool is_amd;
bool is_mesa;
};

struct Workarounds {
Workarounds();

bool clear_alpha_in_readpixels;
bool clear_uniforms_before_program_use;
bool needs_glsl_built_in_function_emulation;
bool needs_offscreen_buffer_workaround;
bool reverse_point_sprite_coord_origin;
bool set_texture_filter_before_generating_mipmap;
bool use_current_program_after_successful_link;

// Note: 0 here means use driver limit.
GLint max_texture_size;
GLint max_cube_map_texture_size;
};

FeatureInfo();
Expand Down Expand Up @@ -74,6 +87,10 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> {
return feature_flags_;
}

const Workarounds& workarounds() const {
return workarounds_;
}

private:
friend class base::RefCounted<FeatureInfo>;

Expand All @@ -94,6 +111,9 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> {
// Flags for some features
FeatureFlags feature_flags_;

// Flags for Workarounds.
Workarounds workarounds_;

DISALLOW_COPY_AND_ASSIGN(FeatureInfo);
};

Expand Down
117 changes: 11 additions & 106 deletions gpu/command_buffer/service/feature_info_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,13 @@ TEST_F(FeatureInfoTest, Basic) {
).use_arb_occlusion_query2_for_occlusion_query_boolean);
EXPECT_FALSE(info_->feature_flags(
).use_arb_occlusion_query_for_occlusion_query_boolean);
EXPECT_FALSE(info_->feature_flags().native_vertex_array_object_);
EXPECT_FALSE(info_->feature_flags().is_intel);
EXPECT_FALSE(info_->feature_flags().is_nvidia);
EXPECT_FALSE(info_->feature_flags().is_amd);
EXPECT_FALSE(info_->feature_flags().is_mesa);
EXPECT_FALSE(info_->feature_flags().native_vertex_array_object);
EXPECT_FALSE(info_->workarounds().reverse_point_sprite_coord_origin);
EXPECT_FALSE(
info_->workarounds().set_texture_filter_before_generating_mipmap);
EXPECT_FALSE(info_->workarounds().clear_alpha_in_readpixels);
EXPECT_EQ(0, info_->workarounds().max_texture_size);
EXPECT_EQ(0, info_->workarounds().max_cube_map_texture_size);

// Test good types.
{
Expand Down Expand Up @@ -769,23 +771,23 @@ TEST_F(FeatureInfoTest, InitializeOES_vertex_array_object) {
info_->Initialize(NULL);
EXPECT_THAT(info_->extensions(),
HasSubstr("GL_OES_vertex_array_object"));
EXPECT_TRUE(info_->feature_flags().native_vertex_array_object_);
EXPECT_TRUE(info_->feature_flags().native_vertex_array_object);
}

TEST_F(FeatureInfoTest, InitializeARB_vertex_array_object) {
SetupInitExpectations("GL_ARB_vertex_array_object");
info_->Initialize(NULL);
EXPECT_THAT(info_->extensions(),
HasSubstr("GL_OES_vertex_array_object"));
EXPECT_TRUE(info_->feature_flags().native_vertex_array_object_);
EXPECT_TRUE(info_->feature_flags().native_vertex_array_object);
}

TEST_F(FeatureInfoTest, InitializeAPPLE_vertex_array_object) {
SetupInitExpectations("GL_APPLE_vertex_array_object");
info_->Initialize(NULL);
EXPECT_THAT(info_->extensions(),
HasSubstr("GL_OES_vertex_array_object"));
EXPECT_TRUE(info_->feature_flags().native_vertex_array_object_);
EXPECT_TRUE(info_->feature_flags().native_vertex_array_object);
}

TEST_F(FeatureInfoTest, InitializeNo_vertex_array_object) {
Expand All @@ -796,7 +798,7 @@ TEST_F(FeatureInfoTest, InitializeNo_vertex_array_object) {
// scenario native_vertex_array_object must be false.
EXPECT_THAT(info_->extensions(),
HasSubstr("GL_OES_vertex_array_object"));
EXPECT_FALSE(info_->feature_flags().native_vertex_array_object_);
EXPECT_FALSE(info_->feature_flags().native_vertex_array_object);
}

TEST_F(FeatureInfoTest, InitializeOES_element_index_uint) {
Expand All @@ -807,102 +809,5 @@ TEST_F(FeatureInfoTest, InitializeOES_element_index_uint) {
EXPECT_TRUE(info_->validators()->index_type.IsValid(GL_UNSIGNED_INT));
}

TEST_F(FeatureInfoTest, IsIntel) {
SetupInitExpectationsWithVendor("", "iNTel", "");
info_->Initialize(NULL);
EXPECT_TRUE(info_->feature_flags().is_intel);
EXPECT_FALSE(info_->feature_flags().is_nvidia);
EXPECT_FALSE(info_->feature_flags().is_amd);
EXPECT_FALSE(info_->feature_flags().is_mesa);

SetupInitExpectationsWithVendor("", "", "IntEl");
FeatureInfo::Ref feature_info(new FeatureInfo());
feature_info->Initialize(NULL);
EXPECT_TRUE(feature_info->feature_flags().is_intel);
EXPECT_FALSE(feature_info->feature_flags().is_nvidia);
EXPECT_FALSE(feature_info->feature_flags().is_amd);
EXPECT_FALSE(info_->feature_flags().is_mesa);
}

TEST_F(FeatureInfoTest, IsNvidia) {
SetupInitExpectationsWithVendor("", "nvIdIa", "");
info_->Initialize(NULL);
EXPECT_FALSE(info_->feature_flags().is_intel);
EXPECT_TRUE(info_->feature_flags().is_nvidia);
EXPECT_FALSE(info_->feature_flags().is_amd);
EXPECT_FALSE(info_->feature_flags().is_mesa);

SetupInitExpectationsWithVendor("", "", "NViDiA");
{
FeatureInfo::Ref feature_info(new FeatureInfo());
feature_info->Initialize(NULL);
EXPECT_FALSE(feature_info->feature_flags().is_intel);
EXPECT_TRUE(feature_info->feature_flags().is_nvidia);
EXPECT_FALSE(feature_info->feature_flags().is_amd);
EXPECT_FALSE(feature_info->feature_flags().is_mesa);
}

SetupInitExpectationsWithVendor("", "NVIDIA Corporation", "");
{
FeatureInfo::Ref feature_info(new FeatureInfo());
feature_info->Initialize(NULL);
EXPECT_FALSE(feature_info->feature_flags().is_intel);
EXPECT_TRUE(feature_info->feature_flags().is_nvidia);
EXPECT_FALSE(feature_info->feature_flags().is_amd);
EXPECT_FALSE(feature_info->feature_flags().is_mesa);
}
}

TEST_F(FeatureInfoTest, IsAMD) {
SetupInitExpectationsWithVendor("", "aMd", "");
info_->Initialize(NULL);
EXPECT_FALSE(info_->feature_flags().is_intel);
EXPECT_FALSE(info_->feature_flags().is_nvidia);
EXPECT_TRUE(info_->feature_flags().is_amd);
EXPECT_FALSE(info_->feature_flags().is_mesa);

SetupInitExpectationsWithVendor("", "", "AmD");
FeatureInfo::Ref feature_info(new FeatureInfo());
feature_info->Initialize(NULL);
EXPECT_FALSE(feature_info->feature_flags().is_intel);
EXPECT_FALSE(feature_info->feature_flags().is_nvidia);
EXPECT_TRUE(feature_info->feature_flags().is_amd);
EXPECT_FALSE(feature_info->feature_flags().is_mesa);
}

TEST_F(FeatureInfoTest, IsAMDATI) {
SetupInitExpectationsWithVendor("", "aTI", "");
info_->Initialize(NULL);
EXPECT_FALSE(info_->feature_flags().is_intel);
EXPECT_FALSE(info_->feature_flags().is_nvidia);
EXPECT_TRUE(info_->feature_flags().is_amd);
EXPECT_FALSE(info_->feature_flags().is_mesa);

SetupInitExpectationsWithVendor("", "", "AtI");
FeatureInfo::Ref feature_info(new FeatureInfo());
feature_info->Initialize(NULL);
EXPECT_FALSE(feature_info->feature_flags().is_intel);
EXPECT_FALSE(feature_info->feature_flags().is_nvidia);
EXPECT_TRUE(feature_info->feature_flags().is_amd);
EXPECT_FALSE(feature_info->feature_flags().is_mesa);
}

TEST_F(FeatureInfoTest, IsMesa) {
SetupInitExpectationsWithVendor("", "MesA", "");
info_->Initialize(NULL);
EXPECT_FALSE(info_->feature_flags().is_intel);
EXPECT_FALSE(info_->feature_flags().is_nvidia);
EXPECT_FALSE(info_->feature_flags().is_amd);
EXPECT_TRUE(info_->feature_flags().is_mesa);

SetupInitExpectationsWithVendor("", "", "meSa");
FeatureInfo::Ref feature_info(new FeatureInfo());
feature_info->Initialize(NULL);
EXPECT_FALSE(feature_info->feature_flags().is_intel);
EXPECT_FALSE(feature_info->feature_flags().is_nvidia);
EXPECT_FALSE(feature_info->feature_flags().is_amd);
EXPECT_TRUE(feature_info->feature_flags().is_mesa);
}

} // namespace gles2
} // namespace gpu
Loading

0 comments on commit 62e155e

Please sign in to comment.