Commit 647f2000 by Geoff Lang Committed by Commit Bot

Limit max texture size and max MSAA samples on Android.

Android devices will often fail to allocate textures this large and it is prefereable to return an error from ANGLE instead of losing the context due to an out of memory error. This mirrors the limits Chrome applies with the max_texture_size_limit_4096 and max_msaa_sample_count_4 workarounds that are broadly applied to Android. BUG=882580 Change-Id: I63890baa8712f13b37c607fa475432e67e9384a4 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1351357 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJonah Ryan-Davis <jonahr@google.com>
parent bce4b9f8
...@@ -267,6 +267,20 @@ struct FeaturesGL : FeatureSetBase ...@@ -267,6 +267,20 @@ struct FeaturesGL : FeatureSetBase
Feature disableWorkerContexts = {"disable_worker_contexts", FeatureCategory::OpenGLWorkarounds, Feature disableWorkerContexts = {"disable_worker_contexts", FeatureCategory::OpenGLWorkarounds,
"Some tests have been seen to fail using worker contexts", "Some tests have been seen to fail using worker contexts",
&members, "http://crbug.com/849576"}; &members, "http://crbug.com/849576"};
// Most Android devices fail to allocate a texture that is larger than 4096. Limit the caps
// instead of generating GL_OUT_OF_MEMORY errors.
Feature limitMaxTextureSizeTo4096 = {
"max_texture_size_limit_4096", FeatureCategory::OpenGLWorkarounds,
"Limit max texture size to 4096 to avoid frequent out-of-memory errors on Android",
&members};
// Prevent excessive MSAA allocations on Android devices, various rendering bugs have been
// observed and they tend to be high DPI anyways. http://crbug.com/797243
Feature limitMaxMSAASamplesTo4 = {
"max_msaa_sample_count_4", FeatureCategory::OpenGLWorkarounds,
"Various rendering bugs have been observed when using higher MSAA counts on Android",
&members, "http://crbug.com/797243"};
}; };
inline FeaturesGL::FeaturesGL() = default; inline FeaturesGL::FeaturesGL() = default;
......
...@@ -294,6 +294,11 @@ static gl::TextureCaps GenerateTextureFormatCaps(const FunctionsGL *functions, ...@@ -294,6 +294,11 @@ static gl::TextureCaps GenerateTextureFormatCaps(const FunctionsGL *functions,
} }
for (size_t sampleIndex = 0; sampleIndex < samples.size(); sampleIndex++) for (size_t sampleIndex = 0; sampleIndex < samples.size(); sampleIndex++)
{ {
if (features.limitMaxMSAASamplesTo4.enabled && samples[sampleIndex] > 4)
{
continue;
}
// Some NVIDIA drivers expose multisampling modes implemented as a combination of // Some NVIDIA drivers expose multisampling modes implemented as a combination of
// multisampling and supersampling. These are non-conformant and should not be // multisampling and supersampling. These are non-conformant and should not be
// exposed through ANGLE. Query which formats are conformant from the driver if // exposed through ANGLE. Query which formats are conformant from the driver if
...@@ -459,10 +464,17 @@ void GenerateCaps(const FunctionsGL *functions, ...@@ -459,10 +464,17 @@ void GenerateCaps(const FunctionsGL *functions,
caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max()); caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());
} }
GLint textureSizeLimit = std::numeric_limits<GLint>::max();
if (features.limitMaxTextureSizeTo4096.enabled)
{
textureSizeLimit = 4096;
}
if (functions->isAtLeastGL(gl::Version(1, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)) || if (functions->isAtLeastGL(gl::Version(1, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)) ||
functions->hasGLESExtension("GL_OES_texture_3D")) functions->hasGLESExtension("GL_OES_texture_3D"))
{ {
caps->max3DTextureSize = QuerySingleGLInt(functions, GL_MAX_3D_TEXTURE_SIZE); caps->max3DTextureSize =
std::min(QuerySingleGLInt(functions, GL_MAX_3D_TEXTURE_SIZE), textureSizeLimit);
} }
else else
{ {
...@@ -470,15 +482,18 @@ void GenerateCaps(const FunctionsGL *functions, ...@@ -470,15 +482,18 @@ void GenerateCaps(const FunctionsGL *functions,
LimitVersion(maxSupportedESVersion, gl::Version(2, 0)); LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
} }
caps->max2DTextureSize = QuerySingleGLInt(functions, GL_MAX_TEXTURE_SIZE); // GL 1.0 / ES 2.0 caps->max2DTextureSize = std::min(QuerySingleGLInt(functions, GL_MAX_TEXTURE_SIZE),
textureSizeLimit); // GL 1.0 / ES 2.0
caps->maxCubeMapTextureSize = caps->maxCubeMapTextureSize =
QuerySingleGLInt(functions, GL_MAX_CUBE_MAP_TEXTURE_SIZE); // GL 1.3 / ES 2.0 std::min(QuerySingleGLInt(functions, GL_MAX_CUBE_MAP_TEXTURE_SIZE),
textureSizeLimit); // GL 1.3 / ES 2.0
if (functions->isAtLeastGL(gl::Version(3, 0)) || if (functions->isAtLeastGL(gl::Version(3, 0)) ||
functions->hasGLExtension("GL_EXT_texture_array") || functions->hasGLExtension("GL_EXT_texture_array") ||
functions->isAtLeastGLES(gl::Version(3, 0))) functions->isAtLeastGLES(gl::Version(3, 0)))
{ {
caps->maxArrayTextureLayers = QuerySingleGLInt(functions, GL_MAX_ARRAY_TEXTURE_LAYERS); caps->maxArrayTextureLayers =
std::min(QuerySingleGLInt(functions, GL_MAX_ARRAY_TEXTURE_LAYERS), textureSizeLimit);
} }
else else
{ {
...@@ -795,13 +810,19 @@ void GenerateCaps(const FunctionsGL *functions, ...@@ -795,13 +810,19 @@ void GenerateCaps(const FunctionsGL *functions,
LimitVersion(maxSupportedESVersion, gl::Version(2, 0)); LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
} }
GLint sampleCountLimit = std::numeric_limits<GLint>::max();
if (features.limitMaxMSAASamplesTo4.enabled)
{
sampleCountLimit = 4;
}
// Table 6.35, Framebuffer Dependent Values // Table 6.35, Framebuffer Dependent Values
if (functions->isAtLeastGL(gl::Version(3, 0)) || if (functions->isAtLeastGL(gl::Version(3, 0)) ||
functions->hasGLExtension("GL_EXT_framebuffer_multisample") || functions->hasGLExtension("GL_EXT_framebuffer_multisample") ||
functions->isAtLeastGLES(gl::Version(3, 0)) || functions->isAtLeastGLES(gl::Version(3, 0)) ||
functions->hasGLESExtension("GL_EXT_multisampled_render_to_texture")) functions->hasGLESExtension("GL_EXT_multisampled_render_to_texture"))
{ {
caps->maxSamples = QuerySingleGLInt(functions, GL_MAX_SAMPLES); caps->maxSamples = std::min(QuerySingleGLInt(functions, GL_MAX_SAMPLES), sampleCountLimit);
} }
else else
{ {
...@@ -864,7 +885,8 @@ void GenerateCaps(const FunctionsGL *functions, ...@@ -864,7 +885,8 @@ void GenerateCaps(const FunctionsGL *functions,
{ {
caps->maxFramebufferWidth = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_WIDTH); caps->maxFramebufferWidth = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_WIDTH);
caps->maxFramebufferHeight = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_HEIGHT); caps->maxFramebufferHeight = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_HEIGHT);
caps->maxFramebufferSamples = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_SAMPLES); caps->maxFramebufferSamples =
std::min(QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_SAMPLES), sampleCountLimit);
} }
else else
{ {
...@@ -875,9 +897,12 @@ void GenerateCaps(const FunctionsGL *functions, ...@@ -875,9 +897,12 @@ void GenerateCaps(const FunctionsGL *functions,
functions->hasGLExtension("GL_ARB_texture_multisample")) functions->hasGLExtension("GL_ARB_texture_multisample"))
{ {
caps->maxSampleMaskWords = QuerySingleGLInt(functions, GL_MAX_SAMPLE_MASK_WORDS); caps->maxSampleMaskWords = QuerySingleGLInt(functions, GL_MAX_SAMPLE_MASK_WORDS);
caps->maxColorTextureSamples = QuerySingleGLInt(functions, GL_MAX_COLOR_TEXTURE_SAMPLES); caps->maxColorTextureSamples =
caps->maxDepthTextureSamples = QuerySingleGLInt(functions, GL_MAX_DEPTH_TEXTURE_SAMPLES); std::min(QuerySingleGLInt(functions, GL_MAX_COLOR_TEXTURE_SAMPLES), sampleCountLimit);
caps->maxIntegerSamples = QuerySingleGLInt(functions, GL_MAX_INTEGER_SAMPLES); caps->maxDepthTextureSamples =
std::min(QuerySingleGLInt(functions, GL_MAX_DEPTH_TEXTURE_SAMPLES), sampleCountLimit);
caps->maxIntegerSamples =
std::min(QuerySingleGLInt(functions, GL_MAX_INTEGER_SAMPLES), sampleCountLimit);
} }
else else
{ {
...@@ -1268,8 +1293,8 @@ void GenerateCaps(const FunctionsGL *functions, ...@@ -1268,8 +1293,8 @@ void GenerateCaps(const FunctionsGL *functions,
functions->hasGLExtension("GL_ARB_texture_rectangle")) functions->hasGLExtension("GL_ARB_texture_rectangle"))
{ {
extensions->textureRectangle = true; extensions->textureRectangle = true;
caps->maxRectangleTextureSize = caps->maxRectangleTextureSize = std::min(
QuerySingleGLInt(functions, GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE); QuerySingleGLInt(functions, GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE), textureSizeLimit);
} }
// OpenGL 4.3 (and above) can support all features and constants defined in // OpenGL 4.3 (and above) can support all features and constants defined in
...@@ -1477,6 +1502,9 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature ...@@ -1477,6 +1502,9 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature
// crbug.com/922936 // crbug.com/922936
features->disableWorkerContexts.enabled = features->disableWorkerContexts.enabled =
(IsWindows() && (IsIntel(vendor) || IsAMD(vendor))) || (IsLinux() && IsNvidia(vendor)); (IsWindows() && (IsIntel(vendor) || IsAMD(vendor))) || (IsLinux() && IsNvidia(vendor));
features->limitMaxTextureSizeTo4096.enabled = IsAndroid();
features->limitMaxMSAASamplesTo4.enabled = IsAndroid();
} }
void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features) void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment