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

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

Issue 8341128: Defer clearing textures and renderbuffers (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix one more unit test Created 9 years, 2 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
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 329a1f8568f1402a56000d8fe287ee7a9e321298..e5ace9f8b912c91606779728ec16485269ecc4a7 100644
--- a/gpu/command_buffer/service/texture_manager.cc
+++ b/gpu/command_buffer/service/texture_manager.cc
@@ -118,14 +118,15 @@ bool TextureManager::TextureInfo::MarkMipmapsGenerated(
GLsizei width = info1.width;
GLsizei height = info1.height;
GLsizei depth = info1.depth;
+ GLenum target = target_ == GL_TEXTURE_2D ? GL_TEXTURE_2D :
+ FaceIndexToGLTarget(ii);
int num_mips = ComputeMipMapCount(width, height, depth);
for (int level = 1; level < num_mips; ++level) {
width = std::max(1, width >> 1);
height = std::max(1, height >> 1);
depth = std::max(1, depth >> 1);
SetLevelInfo(feature_info,
- target_ == GL_TEXTURE_2D ? GL_TEXTURE_2D :
- FaceIndexToGLTarget(ii),
+ target,
level,
info1.internal_format,
width,
@@ -133,9 +134,11 @@ bool TextureManager::TextureInfo::MarkMipmapsGenerated(
depth,
info1.border,
info1.format,
- info1.type);
+ info1.type,
+ true);
}
}
+
return true;
}
@@ -165,7 +168,7 @@ bool TextureManager::TextureInfo::CanGenerateMipmaps(
// TODO(gman): Check internal_format, format and type.
for (size_t ii = 0; ii < level_infos_.size(); ++ii) {
const LevelInfo& info = level_infos_[ii][0];
- if ((!info.valid) ||
+ if ((info.target == 0) ||
(info.width != first.width) ||
(info.height != first.height) ||
(info.depth != 1) ||
@@ -178,6 +181,43 @@ bool TextureManager::TextureInfo::CanGenerateMipmaps(
return true;
}
+void TextureManager::TextureInfo::SetLevelCleared(GLenum target, GLint level) {
+ DCHECK_GE(level, 0);
+ DCHECK_LT(static_cast<size_t>(GLTargetToFaceIndex(target)),
+ level_infos_.size());
+ DCHECK_LT(static_cast<size_t>(level),
+ level_infos_[GLTargetToFaceIndex(target)].size());
+ TextureInfo::LevelInfo& info =
+ level_infos_[GLTargetToFaceIndex(target)][level];
+ if (!info.cleared) {
+ DCHECK_NE(0, num_uncleared_mips_);
+ --num_uncleared_mips_;
+ }
+ info.cleared = true;
+ UpdateCleared();
+}
+
+void TextureManager::TextureInfo::UpdateCleared() {
+ if (level_infos_.empty()) {
+ return;
+ }
+
+ const TextureInfo::LevelInfo& first_face = level_infos_[0][0];
+ int levels_needed = ComputeMipMapCount(
+ first_face.width, first_face.height, first_face.depth);
+ cleared_ = true;
+ for (size_t ii = 0; ii < level_infos_.size(); ++ii) {
+ for (GLint jj = 0; jj < levels_needed; ++jj) {
+ const TextureInfo::LevelInfo& info = level_infos_[ii][jj];
+ if (info.width > 0 && info.height > 0 && info.depth > 0 &&
+ !info.cleared) {
+ cleared_ = false;
+ return;
+ }
+ }
+ }
+}
+
void TextureManager::TextureInfo::SetLevelInfo(
const FeatureInfo* feature_info,
GLenum target,
@@ -188,7 +228,8 @@ void TextureManager::TextureInfo::SetLevelInfo(
GLsizei depth,
GLint border,
GLenum format,
- GLenum type) {
+ GLenum type,
+ bool cleared) {
DCHECK_GE(level, 0);
DCHECK_LT(static_cast<size_t>(GLTargetToFaceIndex(target)),
level_infos_.size());
@@ -199,7 +240,8 @@ void TextureManager::TextureInfo::SetLevelInfo(
DCHECK_GE(depth, 0);
TextureInfo::LevelInfo& info =
level_infos_[GLTargetToFaceIndex(target)][level];
- info.valid = true;
+ info.target = target;
+ info.level = level;
info.internal_format = internal_format;
info.width = width;
info.height = height;
@@ -207,8 +249,17 @@ void TextureManager::TextureInfo::SetLevelInfo(
info.border = border;
info.format = format;
info.type = type;
+ if (!info.cleared) {
+ DCHECK_NE(0, num_uncleared_mips_);
+ --num_uncleared_mips_;
+ }
+ info.cleared = cleared;
+ if (!info.cleared) {
+ ++num_uncleared_mips_;
+ }
max_level_set_ = std::max(max_level_set_, level);
Update(feature_info);
+ UpdateCleared();
}
bool TextureManager::TextureInfo::ValidForTexture(
@@ -246,7 +297,7 @@ bool TextureManager::TextureInfo::GetLevelSize(
if (!IsDeleted() && level >= 0 && face_index < level_infos_.size() &&
static_cast<size_t>(level) < level_infos_[face_index].size()) {
const LevelInfo& info = level_infos_[GLTargetToFaceIndex(face)][level];
- if (info.valid) {
+ if (info.target != 0) {
*width = info.width;
*height = info.height;
return true;
@@ -263,7 +314,7 @@ bool TextureManager::TextureInfo::GetLevelType(
if (!IsDeleted() && level >= 0 && face_index < level_infos_.size() &&
static_cast<size_t>(level) < level_infos_[face_index].size()) {
const LevelInfo& info = level_infos_[GLTargetToFaceIndex(face)][level];
- if (info.valid) {
+ if (info.target != 0) {
*type = info.type;
*internal_format = info.internal_format;
return true;
@@ -318,6 +369,7 @@ bool TextureManager::TextureInfo::SetParameter(
return false;
}
Update(feature_info);
+ UpdateCleared();
return true;
}
@@ -331,6 +383,7 @@ void TextureManager::TextureInfo::Update(const FeatureInfo* feature_info) {
return;
}
+ // checks that the first mip of any face is npot.
for (size_t ii = 0; ii < level_infos_.size(); ++ii) {
const TextureInfo::LevelInfo& info = level_infos_[ii][0];
if (GLES2Util::IsNPOT(info.width) ||
@@ -367,7 +420,7 @@ void TextureManager::TextureInfo::Update(const FeatureInfo* feature_info) {
ii < level_infos_.size() && (cube_complete_ || texture_complete_);
++ii) {
const TextureInfo::LevelInfo& level0 = level_infos_[ii][0];
- if (!level0.valid ||
+ if (level0.target == 0 ||
level0.width != first_face.width ||
level0.height != first_face.height ||
level0.depth != 1 ||
@@ -386,7 +439,7 @@ void TextureManager::TextureInfo::Update(const FeatureInfo* feature_info) {
height = std::max(1, height >> 1);
depth = std::max(1, depth >> 1);
const TextureInfo::LevelInfo& info = level_infos_[ii][jj];
- if (!info.valid ||
+ if (info.target == 0 ||
info.width != width ||
info.height != height ||
info.depth != depth ||
@@ -400,6 +453,80 @@ void TextureManager::TextureInfo::Update(const FeatureInfo* feature_info) {
}
}
+bool TextureManager::TextureInfo::ClearRenderableLevels(GLES2Decoder* decoder) {
+ DCHECK(decoder);
+ if (SafeToRenderFrom()) {
+ return true;
+ }
+
+ const TextureInfo::LevelInfo& first_face = level_infos_[0][0];
+ int levels_needed = ComputeMipMapCount(
+ first_face.width, first_face.height, first_face.depth);
+
+ for (size_t ii = 0; ii < level_infos_.size(); ++ii) {
+ for (GLint jj = 0; jj < levels_needed; ++jj) {
+ TextureInfo::LevelInfo& info = level_infos_[ii][jj];
+ if (info.target != 0) {
+ if (!ClearLevel(decoder, info.target, jj)) {
+ return false;
+ }
+ }
+ }
+ }
+ cleared_ = true;
+ return true;
+}
+
+bool TextureManager::TextureInfo::IsLevelCleared(GLenum target, GLint level) {
+ size_t face_index = GLTargetToFaceIndex(target);
+ if (IsDeleted() ||
+ face_index >= level_infos_.size() ||
+ level >= static_cast<GLint>(level_infos_[face_index].size())) {
+ return true;
+ }
+
+ TextureInfo::LevelInfo& info = level_infos_[face_index][level];
+
+ return info.cleared;
+}
+
+bool TextureManager::TextureInfo::ClearLevel(
+ GLES2Decoder* decoder, GLenum target, GLint level) {
+ DCHECK(decoder);
+ size_t face_index = GLTargetToFaceIndex(target);
+ if (IsDeleted() ||
+ face_index >= level_infos_.size() ||
+ level >= static_cast<GLint>(level_infos_[face_index].size())) {
+ return true;
+ }
+
+ TextureInfo::LevelInfo& info = level_infos_[face_index][level];
+
+ DCHECK(target == info.target);
+
+ if (info.target == 0 ||
+ info.cleared ||
+ info.width == 0 ||
+ info.height == 0 ||
+ info.depth == 0) {
+ return true;
+ }
+
+ DCHECK_NE(0, num_uncleared_mips_);
+ --num_uncleared_mips_;
+
+ // NOTE: It seems kind of gross to call back into the decoder for this
+ // but only the decoder knows all the state (like unpack_alignment_) that's
+ // needed to be able to call GL correctly.
+ info.cleared = decoder->ClearLevel(
+ service_id_, target_, info.target, info.level, info.format, info.type,
+ info.width, info.height);
+ if (!info.cleared) {
+ ++num_uncleared_mips_;
+ }
+ return info.cleared;
+}
+
TextureManager::TextureManager(
GLint max_texture_size,
GLint max_cube_map_texture_size)
@@ -412,6 +539,8 @@ TextureManager::TextureManager(
max_cube_map_texture_size,
max_cube_map_texture_size)),
num_unrenderable_textures_(0),
+ num_unsafe_textures_(0),
+ num_uncleared_mips_(0),
black_2d_texture_id_(0),
black_cube_texture_id_(0) {
}
@@ -439,23 +568,30 @@ bool TextureManager::Initialize(const FeatureInfo* feature_info) {
glBindTexture(GL_TEXTURE_2D, 0);
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
+ // Since we are manually setting up these textures
+ // we need to manually manipulate some of the their bookkeeping.
+ num_unrenderable_textures_ += 2;
FeatureInfo temp_feature_info;
default_texture_2d_ = TextureInfo::Ref(new TextureInfo(ids[1]));
SetInfoTarget(feature_info, default_texture_2d_, GL_TEXTURE_2D);
- default_texture_2d_->SetLevelInfo(&temp_feature_info,
- GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE);
+ SetLevelInfo(&temp_feature_info, default_texture_2d_,
+ GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true);
default_texture_cube_map_ = TextureInfo::Ref(new TextureInfo(ids[3]));
SetInfoTarget(feature_info, default_texture_cube_map_, GL_TEXTURE_CUBE_MAP);
for (int ii = 0; ii < GLES2Util::kNumFaces; ++ii) {
- default_texture_cube_map_->SetLevelInfo(
- &temp_feature_info, GLES2Util::IndexToGLFaceTarget(ii),
- 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE);
+ SetLevelInfo(
+ &temp_feature_info, default_texture_cube_map_,
+ GLES2Util::IndexToGLFaceTarget(ii),
+ 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true);
}
black_2d_texture_id_ = ids[0];
black_cube_texture_id_ = ids[2];
if (feature_info->feature_flags().oes_egl_image_external) {
+ // Since we are manually setting up these textures
+ // we need to manually manipulate some of the their bookkeeping.
+ num_unrenderable_textures_ += 1;
GLuint external_ids[2];
glGenTextures(arraysize(external_ids), external_ids);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
@@ -466,7 +602,7 @@ bool TextureManager::Initialize(const FeatureInfo* feature_info) {
GL_TEXTURE_EXTERNAL_OES);
default_texture_external_oes_->SetLevelInfo(
&temp_feature_info, GL_TEXTURE_EXTERNAL_OES, 0,
- GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE);
+ GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true);
// Sampling a texture not associated with any EGLImage sibling will return
// black values according to the spec.
@@ -499,9 +635,10 @@ bool TextureManager::ValidForTarget(
void TextureManager::SetInfoTarget(
const FeatureInfo* feature_info,
- TextureInfo* info, GLenum target) {
+ TextureManager::TextureInfo* info, GLenum target) {
DCHECK(info);
if (!info->CanRender(feature_info)) {
+ DCHECK_NE(0, num_unrenderable_textures_);
--num_unrenderable_textures_;
}
info->SetTarget(target, MaxLevelsForTarget(target));
@@ -510,6 +647,65 @@ void TextureManager::SetInfoTarget(
}
}
+void TextureManager::SetLevelCleared(
+ TextureManager::TextureInfo* info, GLenum target, GLint level) {
+ DCHECK(info);
+ DCHECK(!info->IsDeleted());
+ if (!info->SafeToRenderFrom()) {
+ DCHECK_NE(0, num_unsafe_textures_);
+ --num_unsafe_textures_;
+ }
+ num_uncleared_mips_ -= info->num_uncleared_mips();
+ DCHECK_GE(num_uncleared_mips_, 0);
+ info->SetLevelCleared(target, level);
+ num_uncleared_mips_ += info->num_uncleared_mips();
+ if (!info->SafeToRenderFrom()) {
+ ++num_unsafe_textures_;
+ }
+}
+
+bool TextureManager::ClearRenderableLevels(
+ GLES2Decoder* decoder,TextureManager::TextureInfo* info) {
+ DCHECK(info);
+ DCHECK(!info->IsDeleted());
+ if (info->SafeToRenderFrom()) {
+ return true;
+ }
+ DCHECK_NE(0, num_unsafe_textures_);
+ --num_unsafe_textures_;
+ num_uncleared_mips_ -= info->num_uncleared_mips();
+ DCHECK_GE(num_uncleared_mips_, 0);
+ bool result = info->ClearRenderableLevels(decoder);
+ num_uncleared_mips_ += info->num_uncleared_mips();
+ if (!info->SafeToRenderFrom()) {
+ ++num_unsafe_textures_;
+ }
+ return result;
+}
+
+bool TextureManager::ClearTextureLevel(
+ GLES2Decoder* decoder,TextureManager::TextureInfo* info,
+ GLenum target, GLint level) {
+ DCHECK(info);
+ DCHECK(!info->IsDeleted());
+ if (info->num_uncleared_mips() == 0) {
+ return true;
+ }
+ num_uncleared_mips_ -= info->num_uncleared_mips();
+ DCHECK_GE(num_uncleared_mips_, 0);
+ if (!info->SafeToRenderFrom()) {
+ DCHECK_NE(0, num_unsafe_textures_);
+ --num_unsafe_textures_;
+ }
+ bool result = info->ClearLevel(decoder, target, level);
+ info->UpdateCleared();
+ num_uncleared_mips_ += info->num_uncleared_mips();
+ if (!info->SafeToRenderFrom()) {
+ ++num_unsafe_textures_;
+ }
+ return result;
+}
+
void TextureManager::SetLevelInfo(
const FeatureInfo* feature_info,
TextureManager::TextureInfo* info,
@@ -521,18 +717,30 @@ void TextureManager::SetLevelInfo(
GLsizei depth,
GLint border,
GLenum format,
- GLenum type) {
+ GLenum type,
+ bool cleared) {
DCHECK(info);
DCHECK(!info->IsDeleted());
if (!info->CanRender(feature_info)) {
+ DCHECK_NE(0, num_unrenderable_textures_);
--num_unrenderable_textures_;
}
+ if (!info->SafeToRenderFrom()) {
+ DCHECK_NE(0, num_unsafe_textures_);
+ --num_unsafe_textures_;
+ }
+ num_uncleared_mips_ -= info->num_uncleared_mips();
+ DCHECK_GE(num_uncleared_mips_, 0);
info->SetLevelInfo(
feature_info, target, level, internal_format, width, height, depth,
- border, format, type);
+ border, format, type, cleared);
+ num_uncleared_mips_ += info->num_uncleared_mips();
if (!info->CanRender(feature_info)) {
++num_unrenderable_textures_;
}
+ if (!info->SafeToRenderFrom()) {
+ ++num_unsafe_textures_;
+ }
}
bool TextureManager::SetParameter(
@@ -542,12 +750,20 @@ bool TextureManager::SetParameter(
DCHECK(info);
DCHECK(!info->IsDeleted());
if (!info->CanRender(feature_info)) {
+ DCHECK_NE(0, num_unrenderable_textures_);
--num_unrenderable_textures_;
}
+ if (!info->SafeToRenderFrom()) {
+ DCHECK_NE(0, num_unsafe_textures_);
+ --num_unsafe_textures_;
+ }
bool result = info->SetParameter(feature_info, pname, param);
if (!info->CanRender(feature_info)) {
++num_unrenderable_textures_;
}
+ if (!info->SafeToRenderFrom()) {
+ ++num_unsafe_textures_;
+ }
return result;
}
@@ -557,12 +773,23 @@ bool TextureManager::MarkMipmapsGenerated(
DCHECK(info);
DCHECK(!info->IsDeleted());
if (!info->CanRender(feature_info)) {
+ DCHECK_NE(0, num_unrenderable_textures_);
--num_unrenderable_textures_;
}
+ if (!info->SafeToRenderFrom()) {
+ DCHECK_NE(0, num_unsafe_textures_);
+ --num_unsafe_textures_;
+ }
+ num_uncleared_mips_ -= info->num_uncleared_mips();
+ DCHECK_GE(num_uncleared_mips_, 0);
bool result = info->MarkMipmapsGenerated(feature_info);
+ num_uncleared_mips_ += info->num_uncleared_mips();
if (!info->CanRender(feature_info)) {
++num_unrenderable_textures_;
}
+ if (!info->SafeToRenderFrom()) {
+ ++num_unsafe_textures_;
+ }
return result;
}
@@ -576,6 +803,10 @@ TextureManager::TextureInfo* TextureManager::CreateTextureInfo(
if (!info->CanRender(feature_info)) {
++num_unrenderable_textures_;
}
+ if (!info->SafeToRenderFrom()) {
+ ++num_unsafe_textures_;
+ }
+ num_uncleared_mips_ += info->num_uncleared_mips();
return info.get();
}
@@ -591,8 +822,15 @@ void TextureManager::RemoveTextureInfo(
if (it != texture_infos_.end()) {
TextureInfo* info = it->second;
if (!info->CanRender(feature_info)) {
+ DCHECK_NE(0, num_unrenderable_textures_);
--num_unrenderable_textures_;
}
+ if (!info->SafeToRenderFrom()) {
+ DCHECK_NE(0, num_unsafe_textures_);
+ --num_unsafe_textures_;
+ }
+ num_uncleared_mips_ -= info->num_uncleared_mips();
+ DCHECK_GE(num_uncleared_mips_, 0);
info->MarkAsDeleted();
texture_infos_.erase(it);
}
« no previous file with comments | « gpu/command_buffer/service/texture_manager.h ('k') | gpu/command_buffer/service/texture_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698