Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(353)

Unified Diff: gpu/command_buffer/service/texture_manager.cc

Issue 2895493002: Fix fbo completeness check when non-base-level texture image is attached. (Closed)
Patch Set: handle a bug related to TexStorage Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gpu/command_buffer/service/texture_manager.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gpu/command_buffer/service/texture_manager.cc
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc
index b597d29640fcc38e2fd8a44c06e12375b0a19223..abfd3bf54522e137e9951d74a83e59b4ce19874d 100644
--- a/gpu/command_buffer/service/texture_manager.cc
+++ b/gpu/command_buffer/service/texture_manager.cc
@@ -519,8 +519,8 @@ Texture::Texture(GLuint service_id)
swizzle_a_(GL_ALPHA),
max_level_set_(-1),
texture_complete_(false),
- texture_mips_dirty_(false),
cube_complete_(false),
+ completeness_dirty_(false),
npot_(false),
has_been_bound_(false),
framebuffer_attachment_count_(0),
@@ -835,7 +835,7 @@ bool Texture::CanGenerateMipmaps(const FeatureInfo* feature_info) const {
return false;
}
}
- if (face_infos_.size() == 6 && !cube_complete_) {
+ if (face_infos_.size() == 6 && !cube_complete()) {
return false;
}
return true;
@@ -1071,19 +1071,31 @@ 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);
+ }
+ 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(
- std::max(0, max_level_ - base_level_ + 1),
- TextureManager::ComputeMipMapCount(
- target_, info.width, info.height, info.depth));
+ max_num_mip_levels, TextureManager::ComputeMipMapCount(
+ target_, info.width, info.height, info.depth));
}
// mipmap-completeness needs to be re-evaluated.
- texture_mips_dirty_ = true;
+ completeness_dirty_ = true;
+ Update();
+ UpdateCanRenderCondition();
}
void Texture::SetLevelInfo(GLenum target,
@@ -1111,13 +1123,9 @@ void Texture::SetLevelInfo(GLenum target,
// Update counters only if any attributes have changed. Counters are
// comparisons between the old and new values so it must be done before any
// assignment has been done to the LevelInfo.
- if (info.target != target ||
- info.internal_format != internal_format ||
- info.width != width ||
- info.height != height ||
- info.depth != depth ||
- info.format != format ||
- info.type != type) {
+ if (info.target != target || info.internal_format != internal_format ||
+ info.width != width || info.height != height || info.depth != depth ||
+ info.format != format || info.type != type || info.internal_workaround) {
if (level == base_level_) {
// Calculate the mip level count.
face_infos_[face_index].num_mip_levels = std::min(
@@ -1132,7 +1140,7 @@ void Texture::SetLevelInfo(GLenum target,
}
// Signify that at least one of the mips has changed.
- texture_mips_dirty_ = true;
+ completeness_dirty_ = true;
}
info.target = target;
@@ -1197,6 +1205,9 @@ void Texture::MarkLevelAsInternalWorkaround(GLenum target, GLint level) {
Texture::LevelInfo& info =
face_infos_[face_index].level_infos[level];
info.internal_workaround = true;
+ completeness_dirty_ = true;
+ Update();
+ UpdateCanRenderCondition();
}
bool Texture::ValidForTexture(
@@ -1442,6 +1453,9 @@ void Texture::Update() {
// Assume GL_TEXTURE_EXTERNAL_OES textures are npot, all others
npot_ = (target_ == GL_TEXTURE_EXTERNAL_OES) || (num_npot_faces_ > 0);
+ if (!completeness_dirty_)
+ return;
+
if (face_infos_.empty() ||
static_cast<size_t>(base_level_) >= face_infos_[0].level_infos.size()) {
texture_complete_ = false;
@@ -1487,7 +1501,7 @@ void Texture::Update() {
cube_complete_ &= texture_level0_complete;
bool texture_mips_complete = true;
- if (texture_complete_ && texture_mips_dirty_) {
+ if (texture_complete_) {
for (size_t ii = 0; ii < face_infos_.size() && texture_mips_complete;
++ii) {
const Texture::FaceInfo& face_info = face_infos_[ii];
@@ -1510,9 +1524,9 @@ void Texture::Update() {
}
}
}
- texture_mips_dirty_ = false;
}
texture_complete_ &= texture_mips_complete;
+ completeness_dirty_ = false;
}
bool Texture::ClearRenderableLevels(GLES2Decoder* decoder) {
@@ -1537,17 +1551,23 @@ bool Texture::ClearRenderableLevels(GLES2Decoder* decoder) {
return true;
}
+void Texture::SetImmutable(bool immutable) {
+ if (immutable_ == immutable)
+ return;
+ immutable_ = immutable;
+
+ UpdateNumMipLevels();
+}
+
GLint Texture::GetImmutableLevels() const {
if (!immutable_)
return 0;
GLint levels = 0;
- if (immutable_) {
- DCHECK(face_infos_.size() > 0);
- for (size_t ii = 0; ii < face_infos_[0].level_infos.size(); ++ii) {
- const Texture::LevelInfo& info = face_infos_[0].level_infos[ii];
- if (info.target != 0)
- levels++;
- }
+ DCHECK(face_infos_.size() > 0);
+ for (size_t ii = 0; ii < face_infos_[0].level_infos.size(); ++ii) {
+ const Texture::LevelInfo& info = face_infos_[0].level_infos[ii];
+ if (info.target != 0)
+ levels++;
}
return levels;
}
@@ -1809,10 +1829,13 @@ bool Texture::CanRenderTo(const FeatureInfo* feature_info, GLint level) const {
// recent OpenGL core versions or OpenGL ES 3.0+. Therefore, for consistency,
// it is better to deviate from ES2 spec and require cube completeness all
// the time.
- if (face_infos_.size() == 6 && !cube_complete_)
+ if (face_infos_.size() == 6 && !cube_complete())
return false;
DCHECK(level >= 0 &&
level < static_cast<GLint>(face_infos_[0].level_infos.size()));
+ if (level > base_level_ && !texture_complete()) {
+ return false;
+ }
GLenum internal_format = face_infos_[0].level_infos[level].internal_format;
bool color_renderable = ColorRenderable(feature_info, internal_format,
immutable_);
« no previous file with comments | « gpu/command_buffer/service/texture_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698