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
Feature disableWorkerContexts = {"disable_worker_contexts", FeatureCategory::OpenGLWorkarounds,
"Some tests have been seen to fail using worker contexts",
&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;
......
......@@ -294,6 +294,11 @@ static gl::TextureCaps GenerateTextureFormatCaps(const FunctionsGL *functions,
}
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
// multisampling and supersampling. These are non-conformant and should not be
// exposed through ANGLE. Query which formats are conformant from the driver if
......@@ -459,10 +464,17 @@ void GenerateCaps(const FunctionsGL *functions,
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)) ||
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
{
......@@ -470,15 +482,18 @@ void GenerateCaps(const FunctionsGL *functions,
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 =
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)) ||
functions->hasGLExtension("GL_EXT_texture_array") ||
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
{
......@@ -795,13 +810,19 @@ void GenerateCaps(const FunctionsGL *functions,
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
if (functions->isAtLeastGL(gl::Version(3, 0)) ||
functions->hasGLExtension("GL_EXT_framebuffer_multisample") ||
functions->isAtLeastGLES(gl::Version(3, 0)) ||
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
{
......@@ -864,7 +885,8 @@ void GenerateCaps(const FunctionsGL *functions,
{
caps->maxFramebufferWidth = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_WIDTH);
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
{
......@@ -875,9 +897,12 @@ void GenerateCaps(const FunctionsGL *functions,
functions->hasGLExtension("GL_ARB_texture_multisample"))
{
caps->maxSampleMaskWords = QuerySingleGLInt(functions, GL_MAX_SAMPLE_MASK_WORDS);
caps->maxColorTextureSamples = QuerySingleGLInt(functions, GL_MAX_COLOR_TEXTURE_SAMPLES);
caps->maxDepthTextureSamples = QuerySingleGLInt(functions, GL_MAX_DEPTH_TEXTURE_SAMPLES);
caps->maxIntegerSamples = QuerySingleGLInt(functions, GL_MAX_INTEGER_SAMPLES);
caps->maxColorTextureSamples =
std::min(QuerySingleGLInt(functions, GL_MAX_COLOR_TEXTURE_SAMPLES), sampleCountLimit);
caps->maxDepthTextureSamples =
std::min(QuerySingleGLInt(functions, GL_MAX_DEPTH_TEXTURE_SAMPLES), sampleCountLimit);
caps->maxIntegerSamples =
std::min(QuerySingleGLInt(functions, GL_MAX_INTEGER_SAMPLES), sampleCountLimit);
}
else
{
......@@ -1268,8 +1293,8 @@ void GenerateCaps(const FunctionsGL *functions,
functions->hasGLExtension("GL_ARB_texture_rectangle"))
{
extensions->textureRectangle = true;
caps->maxRectangleTextureSize =
QuerySingleGLInt(functions, GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE);
caps->maxRectangleTextureSize = std::min(
QuerySingleGLInt(functions, GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE), textureSizeLimit);
}
// 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
// crbug.com/922936
features->disableWorkerContexts.enabled =
(IsWindows() && (IsIntel(vendor) || IsAMD(vendor))) || (IsLinux() && IsNvidia(vendor));
features->limitMaxTextureSizeTo4096.enabled = IsAndroid();
features->limitMaxMSAASamplesTo4.enabled = IsAndroid();
}
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