Commit 5a0925de by Geoff Lang Committed by Commit Bot

GL: Recreate textures on eglReleaseTexImage.

Texture data should be reset on eglReleaseTexImage but ANGLE sometimes skipped this because it generated GL errors on Mac. Instead, delete and recreate the native texture to make sure ANGLE doesn't hold any references. Bug: chromium:1181068 Change-Id: I1252b0900361852f66f73b8c9d20a29c53897ee4 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2897544 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarKenneth Russell <kbr@chromium.org>
parent 35f59118
...@@ -343,12 +343,6 @@ struct FeaturesGL : FeatureSetBase ...@@ -343,12 +343,6 @@ struct FeaturesGL : FeatureSetBase
"Issues with blitFramebuffer when the parameters don't match the framebuffer size.", "Issues with blitFramebuffer when the parameters don't match the framebuffer size.",
&members, "http://crbug.com/830046"}; &members, "http://crbug.com/830046"};
// Calling glTexImage2D with zero size generates GL errors
Feature resettingTexturesGeneratesErrors = {
"reset_texture_generates_errors", FeatureCategory::OpenGLWorkarounds,
"Calling glTexImage2D with zero size generates errors.", &members,
"http://anglebug.com/3859"};
// Mac Intel samples transparent black from GL_COMPRESSED_RGB_S3TC_DXT1_EXT // Mac Intel samples transparent black from GL_COMPRESSED_RGB_S3TC_DXT1_EXT
Feature rgbDXT1TexturesSampleZeroAlpha = { Feature rgbDXT1TexturesSampleZeroAlpha = {
"rgb_dxt1_textures_sample_zero_alpha", FeatureCategory::OpenGLWorkarounds, "rgb_dxt1_textures_sample_zero_alpha", FeatureCategory::OpenGLWorkarounds,
......
...@@ -1370,21 +1370,7 @@ angle::Result TextureGL::bindTexImage(const gl::Context *context, egl::Surface * ...@@ -1370,21 +1370,7 @@ angle::Result TextureGL::bindTexImage(const gl::Context *context, egl::Surface *
angle::Result TextureGL::releaseTexImage(const gl::Context *context) angle::Result TextureGL::releaseTexImage(const gl::Context *context)
{ {
ASSERT(getType() == gl::TextureType::_2D || getType() == gl::TextureType::Rectangle); ANGLE_TRY(recreateTexture(context));
const angle::FeaturesGL &features = GetFeaturesGL(context);
if (!features.resettingTexturesGeneratesErrors.enabled)
{
// Not all Surface implementations reset the size of mip 0 when releasing, do it manually
const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
stateManager->bindTexture(getType(), mTextureID);
ASSERT(nativegl::UseTexImage2D(getType()));
ANGLE_GL_TRY(context, functions->texImage2D(ToGLenum(getType()), 0, GL_RGBA, 0, 0, 0,
GL_RGBA, GL_UNSIGNED_BYTE, nullptr));
}
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -1425,13 +1411,14 @@ angle::Result TextureGL::syncState(const gl::Context *context, ...@@ -1425,13 +1411,14 @@ angle::Result TextureGL::syncState(const gl::Context *context,
stateManager->bindTexture(getType(), mTextureID); stateManager->bindTexture(getType(), mTextureID);
gl::Texture::DirtyBits syncDirtyBits = dirtyBits | mLocalDirtyBits;
if (dirtyBits[gl::Texture::DIRTY_BIT_BASE_LEVEL] || dirtyBits[gl::Texture::DIRTY_BIT_MAX_LEVEL]) if (dirtyBits[gl::Texture::DIRTY_BIT_BASE_LEVEL] || dirtyBits[gl::Texture::DIRTY_BIT_MAX_LEVEL])
{ {
// Don't know if the previous base level was using any workarounds, always re-sync the // Don't know if the previous base level was using any workarounds, always re-sync the
// workaround dirty bits // workaround dirty bits
mLocalDirtyBits |= GetLevelWorkaroundDirtyBits(); syncDirtyBits |= GetLevelWorkaroundDirtyBits();
} }
for (auto dirtyBit : (dirtyBits | mLocalDirtyBits)) for (auto dirtyBit : syncDirtyBits)
{ {
switch (dirtyBit) switch (dirtyBit)
...@@ -1596,6 +1583,7 @@ angle::Result TextureGL::syncState(const gl::Context *context, ...@@ -1596,6 +1583,7 @@ angle::Result TextureGL::syncState(const gl::Context *context,
} }
} }
mAllModifiedDirtyBits |= syncDirtyBits;
mLocalDirtyBits.reset(); mLocalDirtyBits.reset();
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -1759,6 +1747,33 @@ bool TextureGL::hasEmulatedAlphaChannel(const gl::ImageIndex &index) const ...@@ -1759,6 +1747,33 @@ bool TextureGL::hasEmulatedAlphaChannel(const gl::ImageIndex &index) const
.emulatedAlphaChannel; .emulatedAlphaChannel;
} }
angle::Result TextureGL::recreateTexture(const gl::Context *context)
{
const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
stateManager->bindTexture(getType(), mTextureID);
stateManager->deleteTexture(mTextureID);
functions->genTextures(1, &mTextureID);
stateManager->bindTexture(getType(), mTextureID);
mLevelInfo.clear();
mLevelInfo.resize(GetMaxLevelInfoCountForTextureType(getType()));
mAppliedSwizzle = gl::SwizzleState();
mAppliedSampler = gl::SamplerState::CreateDefaultForTarget(getType());
mAppliedBaseLevel = 0;
mAppliedBaseLevel = gl::kInitialMaxLevel;
mLocalDirtyBits = mAllModifiedDirtyBits;
onStateChange(angle::SubjectMessage::SubjectChanged);
return angle::Result::Continue;
}
angle::Result TextureGL::syncTextureStateSwizzle(const gl::Context *context, angle::Result TextureGL::syncTextureStateSwizzle(const gl::Context *context,
const FunctionsGL *functions, const FunctionsGL *functions,
GLenum name, GLenum name,
......
...@@ -215,6 +215,8 @@ class TextureGL : public TextureImpl ...@@ -215,6 +215,8 @@ class TextureGL : public TextureImpl
bool hasEmulatedAlphaChannel(const gl::ImageIndex &index) const; bool hasEmulatedAlphaChannel(const gl::ImageIndex &index) const;
private: private:
angle::Result recreateTexture(const gl::Context *context);
angle::Result setImageHelper(const gl::Context *context, angle::Result setImageHelper(const gl::Context *context,
gl::TextureTarget target, gl::TextureTarget target,
size_t level, size_t level,
...@@ -273,6 +275,11 @@ class TextureGL : public TextureImpl ...@@ -273,6 +275,11 @@ class TextureGL : public TextureImpl
std::vector<LevelInfoGL> mLevelInfo; std::vector<LevelInfoGL> mLevelInfo;
gl::Texture::DirtyBits mLocalDirtyBits; gl::Texture::DirtyBits mLocalDirtyBits;
// All dirty bits ever sychronized by this texture OR'd together. Used to know what state needs
// to be resynced if the texture is ever recreated without needing extension checks or state
// comparisons.
gl::Texture::DirtyBits mAllModifiedDirtyBits;
gl::SwizzleState mAppliedSwizzle; gl::SwizzleState mAppliedSwizzle;
gl::SamplerState mAppliedSampler; gl::SamplerState mAppliedSampler;
GLuint mAppliedBaseLevel; GLuint mAppliedBaseLevel;
......
...@@ -1975,9 +1975,6 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature ...@@ -1975,9 +1975,6 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature
ANGLE_FEATURE_CONDITION(features, clipSrcRegionBlitFramebuffer, ANGLE_FEATURE_CONDITION(features, clipSrcRegionBlitFramebuffer,
IsApple() || (IsLinux() && isAMD)); IsApple() || (IsLinux() && isAMD));
ANGLE_FEATURE_CONDITION(features, resettingTexturesGeneratesErrors,
IsApple() || (IsWindows() && isAMD));
ANGLE_FEATURE_CONDITION(features, rgbDXT1TexturesSampleZeroAlpha, IsApple()); ANGLE_FEATURE_CONDITION(features, rgbDXT1TexturesSampleZeroAlpha, IsApple());
ANGLE_FEATURE_CONDITION(features, unfoldShortCircuits, IsApple()); ANGLE_FEATURE_CONDITION(features, unfoldShortCircuits, IsApple());
......
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