Hash :
99db3471
Author :
Date :
2020-05-13T18:50:51
Unset the ActiveTextureCache entry if the program does not reference it When changing uniforms of a program, State::onActiveTextureChange is called to update the ActiveTextureCache. If the sampler uniform type changes to TextureType::InvalidEnum, the entry in ActiveTextureCache was not cleared. This causes stale entries in ActiveTextureCache because the cache no longer matches what textures are bound and the cache does not add references to the textures in it. BUG=chromium:1078375 BUG=chromium:1072406 BUG=chromium:1078866 Change-Id: If9719dcd4fc865b2301db450eb8115e7cfe46c4a Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2199654 Reviewed-by: Tim Van Patten <timvp@google.com> Commit-Queue: Geoff Lang <geofflang@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ActiveTextureCacheTest.cpp: Regression tests of ANGLE's ActiveTextureCache inside gl::State.
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
namespace angle
{
class ActiveTextureCacheTest : public ANGLETest
{
protected:
ActiveTextureCacheTest()
{
setWindowWidth(128);
setWindowHeight(128);
setConfigRedBits(8);
setConfigGreenBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
}
void testSetUp() override
{
constexpr char kVS[] =
"precision highp float;\n"
"\n"
"void main()\n"
"{\n"
" gl_Position = vec4(0.0, 0.0, 0.0, 0.0);\n"
"}\n";
constexpr char k2DFS[] =
"precision highp float;\n"
"uniform sampler2D tex2D;\n"
"uniform samplerCube texCube;\n"
"\n"
"void main()\n"
"{\n"
" gl_FragColor = texture2D(tex2D, vec2(0.0, 0.0)) + textureCube(texCube, vec3(0.0, "
"0.0, 0.0));\n"
"}\n";
mProgram = CompileProgram(kVS, k2DFS);
ASSERT_NE(0u, mProgram);
m2DTextureLocation = glGetUniformLocation(mProgram, "tex2D");
ASSERT_NE(-1, m2DTextureLocation);
mCubeTextureLocation = glGetUniformLocation(mProgram, "texCube");
ASSERT_NE(-1, mCubeTextureLocation);
}
void testTearDown() override { glDeleteProgram(mProgram); }
GLuint mProgram = 0;
GLint m2DTextureLocation = -1;
GLint mCubeTextureLocation = -1;
};
// Regression test for a bug that causes the ActiveTexturesCache to get out of sync with the
// currently bound textures when changing program uniforms in such a way that the program becomes
// invalid.
TEST_P(ActiveTextureCacheTest, UniformChangeUpdatesActiveTextureCache)
{
glUseProgram(mProgram);
// Generate two textures and reset the texture binding
GLuint tex0 = 0;
glGenTextures(1, &tex0);
glBindTexture(GL_TEXTURE_2D, tex0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
GLuint tex1 = 0;
glGenTextures(1, &tex1);
glBindTexture(GL_TEXTURE_2D, tex1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glBindTexture(GL_TEXTURE_2D, 0);
// Set the active texture to 1 and bind tex0.
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, tex0);
// Point the program's 2D sampler at texture binding 1. The texture will be added to the
// ActiveTexturesCache because it matches the program's sampler type for this texture binding.
glUniform1i(m2DTextureLocation, 1);
// Point the program's cube sampler to texture binding 1 as well. This causes the program's
// samplers become invalid and the ActiveTexturesCache is NOT updated.
glUniform1i(mCubeTextureLocation, 1);
// Bind tex1. ActiveTexturesCache is NOT updated (still contains tex0). The current texture
// bindings do not match ActiveTexturesCache's state.
glBindTexture(GL_TEXTURE_2D, tex1);
// Delete tex0. The ActiveTexturesCache entry that points to tex0 is not cleared because tex0 is
// not currently bound.
glDeleteTextures(1, &tex0);
// Use-after-free occurs during context destruction when the ActiveTexturesCache is cleared.
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against.
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(ActiveTextureCacheTest);
} // namespace angle