summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-10-24 15:48:34 +0200
committerMichael BrĂ¼ning <michael.bruning@qt.io>2018-11-01 15:29:55 +0000
commit37b5fe3597c6f0912e7fd6b2d6ab17a0ab2cbc30 (patch)
treecfc5efb517e7d20995cf9fa32d1feaa85a79001c
parentddd25ab971f12dea79a2c638678ed685bfa94ab5 (diff)
[Backport] Fix for CVE-2018-17470
Implement immutable texture base/max level clamping It seems some drivers fail to handle that gracefully, so let's always clamp to be on the safe side. BUG=877874 TEST=test case in the bug, gpu_unittests R=kbr@chromium.org Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel Reviewed-on: https://chromium-review.googlesource.com/1194994 Reviewed-by: Kenneth Russell <kbr@chromium.org> Commit-Queue: Zhenyao Mo <zmo@chromium.org> Cr-Commit-Position: refs/heads/master@{#587264} Change-Id: Ia409bc5607e2c9e17c7a6c95904b6e4d05e9e318 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc75
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc164
-rw-r--r--chromium/gpu/command_buffer/service/texture_manager.cc52
-rw-r--r--chromium/gpu/command_buffer/service/texture_manager.h7
-rw-r--r--chromium/gpu/config/gpu_driver_bug_list.json239
5 files changed, 470 insertions, 67 deletions
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc
index bb809b0ba7e..d6c5828a132 100644
--- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -11212,29 +11212,24 @@ void GLES2DecoderImpl::GetTexParameterImpl(
return;
}
break;
- // Get the level information from the texture to avoid a Mac driver
- // bug where they store the levels in int16_t, making values bigger
- // than 2^15-1 overflow in the negative range.
case GL_TEXTURE_BASE_LEVEL:
- if (workarounds().use_shadowed_tex_level_params) {
- if (fparams) {
- fparams[0] = static_cast<GLfloat>(texture->base_level());
- } else {
- iparams[0] = texture->base_level();
- }
- return;
+ // Use shadowed value in case it's clamped; also because older MacOSX
+ // stores the value on int16_t (see https://crbug.com/610153).
+ if (fparams) {
+ fparams[0] = static_cast<GLfloat>(texture->unclamped_base_level());
+ } else {
+ iparams[0] = texture->unclamped_base_level();
}
- break;
+ return;
case GL_TEXTURE_MAX_LEVEL:
- if (workarounds().use_shadowed_tex_level_params) {
- if (fparams) {
- fparams[0] = static_cast<GLfloat>(texture->max_level());
- } else {
- iparams[0] = texture->max_level();
- }
- return;
+ // Use shadowed value in case it's clamped; also because older MacOSX
+ // stores the value on int16_t (see https://crbug.com/610153).
+ if (fparams) {
+ fparams[0] = static_cast<GLfloat>(texture->unclamped_max_level());
+ } else {
+ iparams[0] = texture->unclamped_max_level();
}
- break;
+ return;
case GL_TEXTURE_SWIZZLE_R:
if (fparams) {
fparams[0] = static_cast<GLfloat>(texture->swizzle_r());
@@ -18010,25 +18005,6 @@ void GLES2DecoderImpl::TexStorageImpl(GLenum target,
compatibility_internal_format = format_info->decompressed_internal_format;
}
- if (workarounds().reset_base_mipmap_level_before_texstorage &&
- texture->base_level() > 0)
- api()->glTexParameteriFn(target, GL_TEXTURE_BASE_LEVEL, 0);
-
- // TODO(zmo): We might need to emulate TexStorage using TexImage or
- // CompressedTexImage on Mac OSX where we expose ES3 APIs when the underlying
- // driver is lower than 4.2 and ARB_texture_storage extension doesn't exist.
- if (dimension == ContextState::k2D) {
- api()->glTexStorage2DEXTFn(target, levels, compatibility_internal_format,
- width, height);
- } else {
- api()->glTexStorage3DFn(target, levels, compatibility_internal_format,
- width, height, depth);
- }
- if (workarounds().reset_base_mipmap_level_before_texstorage &&
- texture->base_level() > 0)
- api()->glTexParameteriFn(target, GL_TEXTURE_BASE_LEVEL,
- texture->base_level());
-
{
GLsizei level_width = width;
GLsizei level_height = height;
@@ -18056,6 +18032,29 @@ void GLES2DecoderImpl::TexStorageImpl(GLenum target,
}
texture->SetImmutable(true);
}
+
+ if (workarounds().reset_base_mipmap_level_before_texstorage &&
+ texture->base_level() > 0)
+ api()->glTexParameteriFn(target, GL_TEXTURE_BASE_LEVEL, 0);
+
+ // TODO(zmo): We might need to emulate TexStorage using TexImage or
+ // CompressedTexImage on Mac OSX where we expose ES3 APIs when the underlying
+ // driver is lower than 4.2 and ARB_texture_storage extension doesn't exist.
+ if (dimension == ContextState::k2D) {
+ api()->glTexStorage2DEXTFn(target, levels, compatibility_internal_format,
+ width, height);
+ } else {
+ api()->glTexStorage3DFn(target, levels, compatibility_internal_format,
+ width, height, depth);
+ }
+ if (workarounds().reset_base_mipmap_level_before_texstorage &&
+ texture->base_level() > 0) {
+ // Note base_level is already clamped due to texture->SetImmutable(true).
+ // This is necessary for certain NVidia Linux drivers; otherwise they
+ // may trigger segmentation fault. See https://crbug.com/877874.
+ api()->glTexParameteriFn(target, GL_TEXTURE_BASE_LEVEL,
+ texture->base_level());
+ }
}
void GLES2DecoderImpl::DoTexStorage2DEXT(GLenum target,
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc
index 17d773b3569..63434c3f309 100644
--- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc
@@ -4809,6 +4809,170 @@ TEST_P(GLES2DecoderTest, TestDiscardableTextureBindGeneratesUnlocked) {
EXPECT_EQ(GL_NO_ERROR, GetGLError());
}
+TEST_P(GLES2DecoderTest, CopySubTextureCHROMIUMTwiceClearsUnclearedTexture) {
+ // Create uninitialized source texture.
+ EXPECT_CALL(*gl_, GenTextures(1, _))
+ .WillOnce(SetArgPointee<1>(kNewServiceId))
+ .RetiresOnSaturation();
+ GenHelper<GenTexturesImmediate>(kNewClientId);
+ DoBindTexture(GL_TEXTURE_2D, kNewClientId, kNewServiceId);
+ DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0,
+ 0);
+
+ // Create uninitialized dest texture.
+ DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+ DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0,
+ 0);
+
+ // This will write the top half of the destination.
+ {
+ // Source is undefined, so first call to CopySubTexture will clear the
+ // source.
+ SetupClearTextureExpectations(kNewServiceId, kServiceTextureId,
+ GL_TEXTURE_2D, GL_TEXTURE_2D, 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, 0, 0, 2, 2, 0);
+ CopySubTextureCHROMIUM cmd;
+ cmd.Init(kNewClientId /* source_id */, 0 /* source_level */,
+ GL_TEXTURE_2D /* dest_target */, client_texture_id_ /* dest_id */,
+ 0 /* dest_level */, 0 /* xoffset */, 0 /* yoffset */, 0 /* x */,
+ 0 /* y */, 2 /* width */, 1 /* height */,
+ false /* unpack_flip_y */, false /* unpack_premultiply_alpha */,
+ false /* unpack_unmultiply_alpha */);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ }
+
+ // This will write the bottom right pixel of the destination.
+ {
+ // This will clear the bottom part of destination as a rectangle is not
+ // sufficient to keep track of the initialized area.
+ SetupClearTextureExpectations(kServiceTextureId, kServiceTextureId,
+ GL_TEXTURE_2D, GL_TEXTURE_2D, 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, 0, 1, 2, 1, 0);
+ CopySubTextureCHROMIUM cmd;
+ cmd.Init(kNewClientId /* source_id */, 0 /* source_level */,
+ GL_TEXTURE_2D /* dest_target */, client_texture_id_ /* dest_id */,
+ 0 /* dest_level */, 1 /* xoffset */, 1 /* yoffset */, 0 /* x */,
+ 0 /* y */, 1 /* width */, 1 /* height */,
+ false /* unpack_flip_y */, false /* unpack_premultiply_alpha */,
+ false /* unpack_unmultiply_alpha */);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ }
+
+ TextureManager* manager = group().texture_manager();
+ TextureRef* texture_ref = manager->GetTexture(client_texture_id_);
+ ASSERT_TRUE(texture_ref != nullptr);
+ Texture* texture = texture_ref->texture();
+ EXPECT_TRUE(texture->SafeToRenderFrom());
+}
+
+TEST_P(GLES3DecoderTest, ImmutableTextureBaseLevelMaxLevelClamping) {
+ GLenum kTarget = GL_TEXTURE_3D;
+ GLint kBaseLevel = 1416354905;
+ GLint kMaxLevel = 800;
+ GLsizei kLevels = 4;
+ GLenum kInternalFormat = GL_R8;
+ GLsizei kWidth = 20;
+ GLsizei kHeight = 20;
+ GLsizei kDepth = 20;
+ GLint kClampedBaseLevel = kLevels - 1;
+ GLint kClampedMaxLevel = kLevels - 1;
+
+ DoBindTexture(kTarget, client_texture_id_, kServiceTextureId);
+ TextureRef* texture_ref =
+ group().texture_manager()->GetTexture(client_texture_id_);
+ ASSERT_TRUE(texture_ref != nullptr);
+ Texture* texture = texture_ref->texture();
+
+ // Before TexStorage3D call, base/max levels are not clamped.
+ {
+ EXPECT_CALL(*gl_, TexParameteri(kTarget, GL_TEXTURE_BASE_LEVEL, kBaseLevel))
+ .Times(1)
+ .RetiresOnSaturation();
+ TexParameteri cmd;
+ cmd.Init(kTarget, GL_TEXTURE_BASE_LEVEL, kBaseLevel);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ }
+ {
+ EXPECT_CALL(*gl_, TexParameteri(kTarget, GL_TEXTURE_MAX_LEVEL, kMaxLevel))
+ .Times(1)
+ .RetiresOnSaturation();
+ TexParameteri cmd;
+ cmd.Init(kTarget, GL_TEXTURE_MAX_LEVEL, kMaxLevel);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ }
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ EXPECT_EQ(kBaseLevel, texture->base_level());
+ EXPECT_EQ(kMaxLevel, texture->max_level());
+
+ {
+ EXPECT_CALL(*gl_, TexStorage3D(kTarget, kLevels, kInternalFormat, kWidth,
+ kHeight, kDepth))
+ .Times(1)
+ .RetiresOnSaturation();
+ TexStorage3D cmd;
+ cmd.Init(kTarget, kLevels, kInternalFormat, kWidth, kHeight, kDepth);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ }
+ EXPECT_EQ(kClampedBaseLevel, texture->base_level());
+ EXPECT_EQ(kClampedMaxLevel, texture->max_level());
+
+ GLint kNewBaseLevel = 827344;
+ GLint kNewMaxLevel = 17619;
+ // After TexStorage3D call, base/max levels are clamped.
+ {
+ EXPECT_CALL(
+ *gl_, TexParameteri(kTarget, GL_TEXTURE_BASE_LEVEL, kClampedBaseLevel))
+ .Times(1)
+ .RetiresOnSaturation();
+ TexParameteri cmd;
+ cmd.Init(kTarget, GL_TEXTURE_BASE_LEVEL, kNewBaseLevel);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ }
+ {
+ EXPECT_CALL(*gl_,
+ TexParameteri(kTarget, GL_TEXTURE_MAX_LEVEL, kClampedMaxLevel))
+ .Times(1)
+ .RetiresOnSaturation();
+ TexParameteri cmd;
+ cmd.Init(kTarget, GL_TEXTURE_MAX_LEVEL, kNewMaxLevel);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ }
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ EXPECT_EQ(kClampedBaseLevel, texture->base_level());
+ EXPECT_EQ(kClampedMaxLevel, texture->max_level());
+
+ // GetTexParameteriv still returns unclamped values.
+ {
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ typedef GetTexParameteriv::Result Result;
+ Result* result = static_cast<Result*>(shared_memory_address_);
+ result->size = 0;
+ GetTexParameteriv cmd;
+ cmd.Init(kTarget, GL_TEXTURE_BASE_LEVEL, shared_memory_id_,
+ shared_memory_offset_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(kNewBaseLevel, static_cast<GLint>(result->GetData()[0]));
+ }
+ {
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ typedef GetTexParameteriv::Result Result;
+ Result* result = static_cast<Result*>(shared_memory_address_);
+ result->size = 0;
+ GetTexParameteriv cmd;
+ cmd.Init(kTarget, GL_TEXTURE_MAX_LEVEL, shared_memory_id_,
+ shared_memory_offset_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(kNewMaxLevel, static_cast<GLint>(result->GetData()[0]));
+ }
+}
+
// TODO(gman): Complete this test.
// TEST_P(GLES2DecoderTest, CompressedTexImage2DGLError) {
// }
diff --git a/chromium/gpu/command_buffer/service/texture_manager.cc b/chromium/gpu/command_buffer/service/texture_manager.cc
index 683e216abf3..4e5971cda00 100644
--- a/chromium/gpu/command_buffer/service/texture_manager.cc
+++ b/chromium/gpu/command_buffer/service/texture_manager.cc
@@ -1078,17 +1078,17 @@ void Texture::IncAllFramebufferStateChangeCount() {
}
void Texture::UpdateBaseLevel(GLint base_level) {
- if (base_level_ == base_level)
+ if (unclamped_base_level_ == base_level)
return;
- base_level_ = base_level;
+ unclamped_base_level_ = base_level;
UpdateNumMipLevels();
}
void Texture::UpdateMaxLevel(GLint max_level) {
- if (max_level_ == max_level)
+ if (unclamped_max_level_ == max_level)
return;
- max_level_ = max_level;
+ unclamped_max_level_ = max_level;
UpdateNumMipLevels();
}
@@ -1097,22 +1097,24 @@ void Texture::UpdateNumMipLevels() {
if (face_infos_.empty())
return;
- GLint base_level = base_level_;
- GLint max_level = max_level_;
if (immutable_) {
GLint levels = GetImmutableLevels();
DCHECK_LE(1, levels);
- DCHECK_LE(0, base_level_);
- base_level = std::min(base_level_, levels - 1);
- max_level = std::max(base_level, max_level_);
- max_level = std::min(max_level, levels - 1);
+ DCHECK_LE(0, unclamped_base_level_);
+ DCHECK_LE(0, unclamped_max_level_);
+ base_level_ = std::min(unclamped_base_level_, levels - 1);
+ max_level_ = std::max(base_level_, unclamped_max_level_);
+ max_level_ = std::min(max_level_, levels - 1);
+ } else {
+ base_level_ = unclamped_base_level_;
+ max_level_ = unclamped_max_level_;
}
- GLint max_num_mip_levels = std::max(0, max_level - base_level + 1);
+ GLint max_num_mip_levels = std::max(0, max_level_ - base_level_ + 1);
for (size_t ii = 0; ii < face_infos_.size(); ++ii) {
Texture::FaceInfo& face_info = face_infos_[ii];
- if (static_cast<size_t>(base_level) >= face_info.level_infos.size())
+ if (static_cast<size_t>(base_level_) >= face_info.level_infos.size())
continue;
- const Texture::LevelInfo& info = face_info.level_infos[base_level];
+ const Texture::LevelInfo& info = face_info.level_infos[base_level_];
face_info.num_mip_levels = std::min(
max_num_mip_levels, TextureManager::ComputeMipMapCount(
target_, info.width, info.height, info.depth));
@@ -2223,6 +2225,14 @@ void TextureManager::SetParameteri(
glTexParameteri(texture->target(), pname,
texture->GetCompatibilitySwizzleForChannel(param));
break;
+ case GL_TEXTURE_BASE_LEVEL:
+ // base level might have been clamped.
+ glTexParameteri(texture->target(), pname, texture->base_level());
+ break;
+ case GL_TEXTURE_MAX_LEVEL:
+ // max level might have been clamped.
+ glTexParameteri(texture->target(), pname, texture->max_level());
+ break;
default:
glTexParameteri(texture->target(), pname, param);
break;
@@ -2246,7 +2256,21 @@ void TextureManager::SetParameterf(
error_state, result, function_name, pname, param);
}
} else {
- glTexParameterf(texture->target(), pname, param);
+ switch (pname) {
+ case GL_TEXTURE_BASE_LEVEL:
+ // base level might have been clamped.
+ glTexParameterf(texture->target(), pname,
+ static_cast<GLfloat>(texture->base_level()));
+ break;
+ case GL_TEXTURE_MAX_LEVEL:
+ // max level might have been clamped.
+ glTexParameterf(texture->target(), pname,
+ static_cast<GLfloat>(texture->max_level()));
+ break;
+ default:
+ glTexParameterf(texture->target(), pname, param);
+ break;
+ }
}
}
diff --git a/chromium/gpu/command_buffer/service/texture_manager.h b/chromium/gpu/command_buffer/service/texture_manager.h
index ec79a33ce40..2c3183947bc 100644
--- a/chromium/gpu/command_buffer/service/texture_manager.h
+++ b/chromium/gpu/command_buffer/service/texture_manager.h
@@ -155,6 +155,10 @@ class GPU_GLES2_EXPORT Texture final : public TextureBase {
return max_level_;
}
+ GLint unclamped_base_level() const { return unclamped_base_level_; }
+
+ GLint unclamped_max_level() const { return unclamped_max_level_; }
+
GLenum swizzle_r() const { return swizzle_r_; }
GLenum swizzle_g() const { return swizzle_g_; }
@@ -578,6 +582,9 @@ class GPU_GLES2_EXPORT Texture final : public TextureBase {
GLenum swizzle_b_;
GLenum swizzle_a_;
+ GLint unclamped_base_level_ = 0;
+ GLint unclamped_max_level_ = 1000;
+
// The maximum level that has been set.
GLint max_level_set_;
diff --git a/chromium/gpu/config/gpu_driver_bug_list.json b/chromium/gpu/config/gpu_driver_bug_list.json
index 0b1ed081cc6..5e9c63156e9 100644
--- a/chromium/gpu/config/gpu_driver_bug_list.json
+++ b/chromium/gpu/config/gpu_driver_bug_list.json
@@ -1683,21 +1683,6 @@
]
},
{
- "id": 169,
- "description": "Mac Drivers store texture level parameters on int16_t that overflow",
- "cr_bugs": [610153],
- "os": {
- "type": "macosx",
- "version": {
- "op": "<",
- "value": "10.12.2"
- }
- },
- "features": [
- "use_shadowed_tex_level_params"
- ]
- },
- {
"id": 170,
"description": "Zero copy DXGI video hangs on shutdown on Win < 8.1",
"cr_bugs": [621190],
@@ -2832,6 +2817,230 @@
"features": [
"max_msaa_sample_count_4"
]
+ },
+ {
+ "id": 260,
+ "cr_bugs": [760389],
+ "description": "eglClientWaitSyncKHR with nonzero timeout waits too long",
+ "comment": [
+ "This bug is specific to Samsung S8/S8+ on Android N, but there ",
+ "isn't currently a way to restrict the filter to those devices. The ",
+ "functionality is currently only used for WebVR on Daydream ready ",
+ "devices, and the non-Samsung Daydream devices generally use ",
+ "Android O, so an overbroad match seems acceptable."
+ ],
+ "os": {
+ "type": "android",
+ "version": {
+ "op": "<",
+ "value": "8.0"
+ }
+ },
+ "gl_renderer": "Adreno \\(TM\\) 540",
+ "features": [
+ "dont_use_eglclientwaitsync_with_timeout"
+ ]
+ },
+ {
+ "id": 261,
+ "cr_bugs": [817286],
+ "description": "Fallback to D3D9 if basic info collection fails on Win7",
+ "os": {
+ "type": "win",
+ "version": {
+ "op": "=",
+ "value": "6.1"
+ }
+ },
+ "vendor_id": "0xffff",
+ "device_id": ["0xfffe"],
+ "features": [
+ "disable_d3d11"
+ ]
+ },
+ {
+ "id": 262,
+ "description": "Program fails in PowerVR*GX6250 drivers if gl_Position is not set",
+ "cr_bugs": [286468, 416670],
+ "os": {
+ "type": "android"
+ },
+ "gl_vendor": "Imagination.*",
+ "gl_renderer": "PowerVR.*GX6250",
+ "features": [
+ "init_gl_position_in_vertex_shader"
+ ]
+ },
+ {
+ "id": 263,
+ "description": "Program fails in PowerVR SGX54x drivers if gl_Position is not set",
+ "cr_bugs": [286468, 416670],
+ "os": {
+ "type": "android"
+ },
+ "gl_vendor": "Imagination.*",
+ "gl_renderer": "PowerVR SGX 54.*",
+ "features": [
+ "init_gl_position_in_vertex_shader"
+ ]
+ },
+ {
+ "id": 264,
+ "description": "Program fails in PowerVR G6200 drivers if gl_Position is not set",
+ "cr_bugs": [286468, 416670],
+ "os": {
+ "type": "android"
+ },
+ "gl_vendor": "Imagination.*",
+ "gl_renderer": "PowerVR.*G6200.*",
+ "features": [
+ "init_gl_position_in_vertex_shader"
+ ]
+ },
+ {
+ "id": 265,
+ "cr_bugs": [811661],
+ "description": "Crash in glQueryCounter() and glBeginQuery() with VMware driver ",
+ "os": {
+ "type": "linux"
+ },
+ "gl_vendor": "VMware.*",
+ "features": [
+ "disable_timestamp_queries"
+ ],
+ "disabled_extensions": [
+ "GL_ARB_timer_query",
+ "GL_EXT_disjoint_timer_query",
+ "GL_EXT_disjoint_timer_query_webgl2"
+ ]
+ },
+ {
+ "id": 266,
+ "cr_bugs": [828721],
+ "description": "Crash in gl::GLApiBase::glGetQueryObjectui64vFn with NetEase devices ",
+ "os": {
+ "type": "android"
+ },
+ "gl_vendor": "NetEase",
+ "gl_renderer": "MuMu GL.*",
+ "features": [
+ "disable_timestamp_queries"
+ ],
+ "disabled_extensions": [
+ "GL_EXT_disjoint_timer_query",
+ "GL_EXT_disjoint_timer_query_webgl2"
+ ]
+ },
+ {
+ "id": 267,
+ "cr_bugs": [831781],
+ "description": "WebGL with multisampling produces errors on Mali",
+ "os": {
+ "type": "linux"
+ },
+ "gl_vendor": "ARM",
+ "gl_renderer": "Mali-TDVX",
+ "disabled_extensions": [
+ "GL_EXT_multisampled_render_to_texture"
+ ],
+ "features": [
+ "disable_chromium_framebuffer_multisample"
+ ]
+ },
+ {
+ "id": 268,
+ "cr_bugs": [797243],
+ "description": "Limit MSAA to 4x on Android devices",
+ "os": {
+ "type": "android"
+ },
+ "features": [
+ "max_msaa_sample_count_4"
+ ]
+ },
+ {
+ "id": 269,
+ "cr_bugs": [841755],
+ "description": "glFlush error on Mac",
+ "os": {
+ "type": "macosx"
+ },
+ "features": [
+ "disable_2d_canvas_auto_flush"
+ ]
+ },
+ {
+ "id": 270,
+ "cr_bugs": [859998],
+ "description": "AMD Linux driver crashes when copyTexImage2D is called with PIXEL_UNPACK_BUFFER set to an uninitialized buffer",
+ "os": {
+ "type": "linux"
+ },
+ "vendor_id": "0x1002",
+ "features": [
+ "clear_pixel_unpack_buffer_before_copyteximage"
+ ]
+ },
+ {
+ "id": 271,
+ "cr_bugs": [860418],
+ "description": "Frequent crashes in glClear on Mali-T7xx on N with driver 12.1.01alp0",
+ "os": {
+ "type": "android",
+ "version": {
+ "op": "<",
+ "value": "8.0"
+ }
+ },
+ "driver_version": {
+ "op": "=",
+ "value": "12.1.01alp0"
+ },
+ "gl_renderer": ".*Mali-T7.*",
+ "features": [
+ "gl_clear_broken"
+ ]
+ },
+ {
+ "id": 272,
+ "cr_bugs": [858879],
+ "description": "A deleted query id for GL_TIMESTAMP cannot be reused for other query targets",
+ "os": {
+ "type": "android"
+ },
+ "gl_vendor": "Qualcomm.*",
+ "features": [
+ "disable_timestamp_queries"
+ ]
+ },
+ {
+ "id":273,
+ "cr_bugs": [866613],
+ "description": "Frequent crashes on Adreno (TM) on L and below",
+ "os": {
+ "type": "android",
+ "version": {
+ "op": "<",
+ "value": "6.0"
+ }
+ },
+ "gl_renderer": "Adreno.*",
+ "features": [
+ "use_es2_for_oopr"
+ ]
+ },
+ {
+ "id": 274,
+ "description": "glTexStorage* are buggy when base mipmap level is not 0",
+ "cr_bugs": [877874],
+ "os": {
+ "type": "linux"
+ },
+ "vendor_id": "0x10de",
+ "gl_vendor": "NVIDIA.*",
+ "features": [
+ "reset_base_mipmap_level_before_texstorage"
+ ]
}
]
}