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

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

Issue 2208733002: Command buffer: clear rect for a specific layer/level of the uncleared texture for CopyTexSubImage3D (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Do not assign a default value 0 to layer, UpdateMipCleared for all layers for 3D texture Created 4 years, 4 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 48b41c05511206835d60362f56dad766953c9844..abe56a84b037647af1e24f30365289da54a9d5cd 100644
--- a/gpu/command_buffer/service/texture_manager.cc
+++ b/gpu/command_buffer/service/texture_manager.cc
@@ -422,6 +422,18 @@ MemoryTypeTracker* Texture::GetMemTracker() {
return memory_tracking_ref_->manager()->GetMemTracker();
}
+Texture::LayerInfo::LayerInfo()
+ : image_state(UNBOUND),
+ layer(0) {}
+
+Texture::LayerInfo::LayerInfo(const LayerInfo& rhs)
+ : image(rhs.image),
+ image_state(rhs.image_state),
+ layer(rhs.layer) {}
+
+Texture::LayerInfo::~LayerInfo() {
+}
+
Texture::LevelInfo::LevelInfo()
: target(0),
level(-1),
@@ -432,13 +444,12 @@ Texture::LevelInfo::LevelInfo()
border(0),
format(0),
type(0),
- image_state(UNBOUND),
estimated_size(0),
- internal_workaround(false) {}
+ internal_workaround(false),
+ num_uncleared_layers(0) {}
Texture::LevelInfo::LevelInfo(const LevelInfo& rhs)
- : cleared_rect(rhs.cleared_rect),
- target(rhs.target),
+ : target(rhs.target),
level(rhs.level),
internal_format(rhs.internal_format),
width(rhs.width),
@@ -447,10 +458,17 @@ Texture::LevelInfo::LevelInfo(const LevelInfo& rhs)
border(rhs.border),
format(rhs.format),
type(rhs.type),
- image(rhs.image),
- image_state(rhs.image_state),
estimated_size(rhs.estimated_size),
- internal_workaround(rhs.internal_workaround) {}
+ internal_workaround(rhs.internal_workaround),
+ num_uncleared_layers(rhs.num_uncleared_layers) {
+ GLint layers = rhs.layer_infos.size();
+ layer_infos.resize(layers);
+ for (int jj = 0; jj < layers; ++jj) {
+ layer_infos[jj].cleared_rect = rhs.layer_infos[jj].cleared_rect;
+ layer_infos[jj].image = rhs.layer_infos[jj].image;
+ layer_infos[jj].image_state = rhs.layer_infos[jj].image_state;
+ }
+}
Texture::LevelInfo::~LevelInfo() {
}
@@ -564,6 +582,7 @@ void Texture::AddToSignature(
const FeatureInfo* feature_info,
GLenum target,
GLint level,
+ GLint layer,
std::string* signature) const {
DCHECK(feature_info);
DCHECK(signature);
@@ -573,24 +592,27 @@ void Texture::AddToSignature(
face_infos_.size());
DCHECK_LT(static_cast<size_t>(level),
face_infos_[face_index].level_infos.size());
+ DCHECK_LT(static_cast<size_t>(layer),
+ face_infos_[face_index].level_infos[level].layer_infos.size());
- const Texture::LevelInfo& info =
+ const Texture::LevelInfo& level_info =
face_infos_[face_index].level_infos[level];
+ const Texture::LayerInfo& layer_info = level_info.layer_infos[layer];
TextureSignature signature_data(target,
level,
sampler_state_,
usage_,
- info.internal_format,
- info.width,
- info.height,
- info.depth,
+ level_info.internal_format,
+ level_info.width,
+ level_info.height,
+ level_info.depth,
base_level_,
- info.border,
+ level_info.border,
max_level_,
- info.format,
- info.type,
- info.image.get() != NULL,
+ level_info.format,
+ level_info.type,
+ layer_info.image.get() != NULL,
CanRender(feature_info),
CanRenderTo(feature_info, level),
npot_,
@@ -629,13 +651,20 @@ void Texture::MarkMipmapsGenerated() {
}
}
-void Texture::SetTarget(GLenum target, GLint max_levels) {
+void Texture::SetTarget(GLenum target, GLint max_levels, GLint layers) {
DCHECK_EQ(0u, target_); // you can only set this once.
target_ = target;
size_t num_faces = (target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
face_infos_.resize(num_faces);
for (size_t ii = 0; ii < num_faces; ++ii) {
face_infos_[ii].level_infos.resize(max_levels);
+ for (int jj = 0; jj < max_levels; ++jj) {
+ Texture::LevelInfo& level_info = face_infos_[ii].level_infos[jj];
+ level_info.layer_infos.resize(layers);
+ level_info.num_uncleared_layers = 0;
+ for (int kk = 0; kk < layers; ++kk)
+ level_info.layer_infos[kk].image_state = UNBOUND;
+ }
}
if (target == GL_TEXTURE_EXTERNAL_OES || target == GL_TEXTURE_RECTANGLE_ARB) {
@@ -676,13 +705,17 @@ bool Texture::CanGenerateMipmaps(const FeatureInfo* feature_info) const {
}
for (size_t ii = 0; ii < face_infos_.size(); ++ii) {
- const LevelInfo& info = face_infos_[ii].level_infos[base_level_];
- if ((info.target == 0) ||
+ const LevelInfo& level_info = face_infos_[ii].level_infos[base_level_];
+ if ((level_info.target == 0) ||
feature_info->validators()->compressed_texture_format.IsValid(
- info.internal_format) ||
- info.image.get()) {
+ level_info.internal_format)) {
return false;
}
+ for (size_t jj = 0; jj < level_info.layer_infos.size(); ++jj) {
+ if ( level_info.layer_infos[jj].image.get()) {
+ return false;
+ }
+ }
}
if (face_infos_.size() == 6 && !cube_complete_) {
return false;
@@ -779,28 +812,37 @@ bool Texture::TextureFilterable(const FeatureInfo* feature_info,
void Texture::SetLevelClearedRect(GLenum target,
GLint level,
+ GLint layer,
const gfx::Rect& cleared_rect) {
DCHECK_GE(level, 0);
+ DCHECK_GE(layer, 0);
size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
DCHECK_LT(static_cast<size_t>(face_index),
face_infos_.size());
DCHECK_LT(static_cast<size_t>(level),
face_infos_[face_index].level_infos.size());
+ DCHECK_LT(static_cast<size_t>(layer),
+ face_infos_[face_index].level_infos[level].layer_infos.size());
Texture::LevelInfo& info =
face_infos_[face_index].level_infos[level];
- UpdateMipCleared(&info, info.width, info.height, cleared_rect);
+ UpdateMipCleared(&info, info.width, info.height, cleared_rect, layer);
UpdateCleared();
}
-void Texture::SetLevelCleared(GLenum target, GLint level, bool cleared) {
+void Texture::SetLevelCleared(GLenum target,
+ GLint level,
+ GLint layer,
+ bool cleared) {
DCHECK_GE(level, 0);
+ DCHECK_GE(layer, 0);
size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
DCHECK_LT(static_cast<size_t>(face_index), face_infos_.size());
DCHECK_LT(static_cast<size_t>(level),
face_infos_[face_index].level_infos.size());
Texture::LevelInfo& info = face_infos_[face_index].level_infos[level];
UpdateMipCleared(&info, info.width, info.height,
- cleared ? gfx::Rect(info.width, info.height) : gfx::Rect());
+ cleared ? gfx::Rect(info.width, info.height) : gfx::Rect(),
+ layer);
UpdateCleared();
}
@@ -829,21 +871,36 @@ void Texture::UpdateSafeToRenderFrom(bool cleared) {
(*it)->manager()->UpdateSafeToRenderFrom(delta);
}
+void Texture::UpdateMipClearedHelper(LevelInfo* info) {
+ int layers = info->layer_infos.size();
+ const gfx::Rect cleared_rect = info->layer_infos[0].cleared_rect;
+ for (int ii = 1; ii < layers; ++ii) {
+ info->layer_infos[ii].cleared_rect = cleared_rect;
+ }
+}
+
void Texture::UpdateMipCleared(LevelInfo* info,
GLsizei width,
GLsizei height,
- const gfx::Rect& cleared_rect) {
- bool was_cleared = info->cleared_rect == gfx::Rect(info->width, info->height);
+ const gfx::Rect& cleared_rect,
+ GLint layer) {
+ bool was_cleared = info->layer_infos[layer].cleared_rect ==
+ gfx::Rect(info->width, info->height);
info->width = width;
info->height = height;
- info->cleared_rect = cleared_rect;
- bool cleared = info->cleared_rect == gfx::Rect(info->width, info->height);
+ info->layer_infos[layer].cleared_rect = cleared_rect;
+ bool cleared = info->layer_infos[layer].cleared_rect ==
+ gfx::Rect(info->width, info->height);
if (cleared == was_cleared)
return;
int delta = cleared ? -1 : +1;
- num_uncleared_mips_ += delta;
- for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it)
- (*it)->manager()->UpdateUnclearedMips(delta);
+ if (info->num_uncleared_layers == 0 ||
+ info->num_uncleared_layers + delta == 0) {
+ num_uncleared_mips_ += delta;
+ for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it)
+ (*it)->manager()->UpdateUnclearedMips(delta);
+ }
+ info->num_uncleared_layers += delta;
}
void Texture::UpdateCanRenderCondition() {
@@ -857,10 +914,12 @@ void Texture::UpdateHasImages() {
bool has_images = false;
for (size_t ii = 0; ii < face_infos_.size(); ++ii) {
for (size_t jj = 0; jj < face_infos_[ii].level_infos.size(); ++jj) {
- const Texture::LevelInfo& info = face_infos_[ii].level_infos[jj];
- if (info.image.get() != NULL) {
- has_images = true;
- break;
+ const Texture::LevelInfo& level_info = face_infos_[ii].level_infos[jj];
+ for (size_t kk = 0; kk < level_info.layer_infos.size(); ++kk) {
+ if (level_info.layer_infos[kk].image.get() != NULL) {
+ has_images = true;
+ break;
+ }
}
}
}
@@ -876,9 +935,11 @@ void Texture::UpdateHasImages() {
void Texture::UpdateEmulatingRGB() {
for (const FaceInfo& face_info : face_infos_) {
for (const LevelInfo& level_info : face_info.level_infos) {
- if (level_info.image && level_info.image->EmulatingRGB()) {
- emulating_rgb_ = true;
- return;
+ for (const LayerInfo& layer_info : level_info.layer_infos) {
+ if (layer_info.image && layer_info.image->EmulatingRGB()) {
+ emulating_rgb_ = true;
+ return;
+ }
}
}
}
@@ -942,6 +1003,8 @@ void Texture::SetLevelInfo(GLenum target,
face_infos_.size());
DCHECK_LT(static_cast<size_t>(level),
face_infos_[face_index].level_infos.size());
+ DCHECK_LE(static_cast<size_t>(depth),
+ face_infos_[face_index].level_infos[level].layer_infos.size());
DCHECK_GE(width, 0);
DCHECK_GE(height, 0);
DCHECK_GE(depth, 0);
@@ -982,12 +1045,19 @@ void Texture::SetLevelInfo(GLenum target,
info.border = border;
info.format = format;
info.type = type;
- info.image = 0;
- info.stream_texture_image = 0;
- info.image_state = UNBOUND;
+ info.layer_infos[depth - 1].image = 0;
+ info.layer_infos[depth - 1].stream_texture_image = 0;
+ info.layer_infos[depth - 1].image_state = UNBOUND;
info.internal_workaround = false;
- UpdateMipCleared(&info, width, height, cleared_rect);
+ // UpdateMipCleared(&info, width, height, cleared_rect, depth - 1);
+ UpdateMipCleared(&info, width, height, cleared_rect, 0);
+ if (target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY) {
+ // UpdateMipClearedHelper(&info);
+ for (int i = 1; i < depth; ++i) {
+ UpdateMipCleared(&info, width, height, cleared_rect, i);
+ }
+ }
estimated_size_ -= info.estimated_size;
GLES2Util::ComputeImageDataSizes(
@@ -1356,7 +1426,7 @@ bool Texture::ClearRenderableLevels(GLES2Decoder* decoder) {
jj < base_level_ + face_info.num_mip_levels; ++jj) {
const Texture::LevelInfo& info = face_info.level_infos[jj];
if (info.target != 0) {
- if (!ClearLevel(decoder, info.target, jj)) {
+ if (!ClearLevel(decoder, info.target, jj, 0)) {
return false;
}
}
@@ -1381,39 +1451,52 @@ GLint Texture::GetImmutableLevels() const {
return levels;
}
-gfx::Rect Texture::GetLevelClearedRect(GLenum target, GLint level) const {
+gfx::Rect Texture::GetLevelClearedRect(GLenum target,
+ GLint level,
+ GLint layer) const {
size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
if (face_index >= face_infos_.size() ||
- level >= static_cast<GLint>(face_infos_[face_index].level_infos.size())) {
+ level >= static_cast<GLint>(face_infos_[face_index].level_infos.size()) ||
+ layer >= static_cast<GLint>(face_infos_[face_index].
+ level_infos[level].layer_infos.size())) {
return gfx::Rect();
}
- const Texture::LevelInfo& info = face_infos_[face_index].level_infos[level];
+ const Texture::LayerInfo& layer_info =
+ face_infos_[face_index].level_infos[level].layer_infos[layer];
- return info.cleared_rect;
+ return layer_info.cleared_rect;
}
-bool Texture::IsLevelCleared(GLenum target, GLint level) const {
+bool Texture::IsLevelCleared(GLenum target, GLint level, GLint layer) const {
size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
if (face_index >= face_infos_.size() ||
level < 0 ||
level >= static_cast<GLint>(face_infos_[face_index].level_infos.size())) {
return true;
}
- const Texture::LevelInfo& info = face_infos_[face_index].level_infos[level];
- return info.cleared_rect == gfx::Rect(info.width, info.height);
+ const Texture::LevelInfo& level_info =
+ face_infos_[face_index].level_infos[level];
+ const Texture::LayerInfo& layer_info = level_info.layer_infos[layer];
+ return layer_info.cleared_rect ==
+ gfx::Rect(level_info.width, level_info.height);
}
-bool Texture::IsLevelPartiallyCleared(GLenum target, GLint level) const {
+bool Texture::IsLevelPartiallyCleared(GLenum target,
+ GLint level,
+ GLint layer) const {
size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
if (face_index >= face_infos_.size() ||
level < 0 ||
level >= static_cast<GLint>(face_infos_[face_index].level_infos.size())) {
return false;
}
- const Texture::LevelInfo& info = face_infos_[face_index].level_infos[level];
- return (info.cleared_rect != gfx::Rect(info.width, info.height) &&
- info.cleared_rect != gfx::Rect());
+ const Texture::LevelInfo& level_info =
+ face_infos_[face_index].level_infos[level];
+ const Texture::LayerInfo& layer_info = level_info.layer_infos[layer];
+ return (layer_info.cleared_rect !=
+ gfx::Rect(level_info.width, level_info.height) &&
+ layer_info.cleared_rect != gfx::Rect());
}
void Texture::InitTextureMaxAnisotropyIfNeeded(GLenum target) {
@@ -1425,7 +1508,7 @@ void Texture::InitTextureMaxAnisotropyIfNeeded(GLenum target) {
}
bool Texture::ClearLevel(
- GLES2Decoder* decoder, GLenum target, GLint level) {
+ GLES2Decoder* decoder, GLenum target, GLint level, GLint layer) {
DCHECK(decoder);
size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
if (face_index >= face_infos_.size() || level < 0 ||
@@ -1433,44 +1516,51 @@ bool Texture::ClearLevel(
return true;
}
- Texture::LevelInfo& info = face_infos_[face_index].level_infos[level];
+ Texture::LevelInfo& level_info = face_infos_[face_index].level_infos[level];
+ Texture::LayerInfo& layer_info = level_info.layer_infos[layer];
- DCHECK(target == info.target);
+ DCHECK(target == level_info.target);
- if (info.target == 0 ||
- info.cleared_rect == gfx::Rect(info.width, info.height) ||
- info.width == 0 || info.height == 0 || info.depth == 0) {
+ if (level_info.target == 0 ||
+ layer_info.cleared_rect ==
+ gfx::Rect(level_info.width, level_info.height) ||
+ level_info.width == 0 ||
+ level_info.height == 0 ||
+ level_info.depth == 0) {
return true;
}
- if (info.target == GL_TEXTURE_3D || info.target == GL_TEXTURE_2D_ARRAY) {
+ if (level_info.target == GL_TEXTURE_3D ||
+ level_info.target == GL_TEXTURE_2D_ARRAY) {
// For 3D textures, we always clear the entire texture.
- DCHECK(info.cleared_rect == gfx::Rect());
+ DCHECK(layer_info.cleared_rect == gfx::Rect());
bool cleared = decoder->ClearLevel3D(
- this, info.target, info.level, info.format, info.type,
- info.width, info.height, info.depth);
+ this, level_info.target, level_info.level, level_info.format,
+ level_info.type, level_info.width, level_info.height, level_info.depth);
if (!cleared)
return false;
} else {
- if (decoder->IsCompressedTextureFormat(info.internal_format)) {
+ if (decoder->IsCompressedTextureFormat(level_info.internal_format)) {
// An uncleared level of a compressed texture can only occur when
// allocating the texture with TexStorage2D. In this case the level
// is cleared just before a call to CompressedTexSubImage2D, to avoid
// having to clear a sub-rectangle of a compressed texture, which
// would be problematic.
DCHECK(IsImmutable());
- DCHECK(info.cleared_rect == gfx::Rect());
+ DCHECK(layer_info.cleared_rect == gfx::Rect());
bool cleared = decoder->ClearCompressedTextureLevel(
- this, info.target, info.level, info.internal_format,
- info.width, info.height);
+ this, level_info.target, level_info.level, level_info.internal_format,
+ level_info.width, level_info.height);
if (!cleared)
return false;
} else {
// Clear all remaining sub regions.
const int x[] = {
- 0, info.cleared_rect.x(), info.cleared_rect.right(), info.width};
+ 0, layer_info.cleared_rect.x(),
+ layer_info.cleared_rect.right(), level_info.width};
const int y[] = {
- 0, info.cleared_rect.y(), info.cleared_rect.bottom(), info.height};
+ 0, layer_info.cleared_rect.y(),
+ layer_info.cleared_rect.bottom(), level_info.height};
for (size_t j = 0; j < 3; ++j) {
for (size_t i = 0; i < 3; ++i) {
@@ -1486,8 +1576,8 @@ bool Texture::ClearLevel(
// but only the decoder knows all the state (like unpack_alignment_)
// that's needed to be able to call GL correctly.
bool cleared = decoder->ClearLevel(
- this, info.target, info.level, info.format, info.type,
- rect.x(), rect.y(), rect.width(), rect.height());
+ this, level_info.target, level_info.level, level_info.format,
+ level_info.type, rect.x(), rect.y(), rect.width(), rect.height());
if (!cleared)
return false;
}
@@ -1495,13 +1585,21 @@ bool Texture::ClearLevel(
}
}
- UpdateMipCleared(&info, info.width, info.height,
- gfx::Rect(info.width, info.height));
+ UpdateMipCleared(&level_info, level_info.width, level_info.height,
+ gfx::Rect(level_info.width, level_info.height), 0);
+ if (level_info.target == GL_TEXTURE_3D ||
+ level_info.target == GL_TEXTURE_2D_ARRAY) {
+ for (int i = 1; i < level_info.depth; ++i) {
+ UpdateMipCleared(&level_info, level_info.width, level_info.height,
+ gfx::Rect(level_info.width, level_info.height), i);
+ }
+ }
return true;
}
void Texture::SetLevelImageInternal(GLenum target,
GLint level,
+ GLint layer,
gl::GLImage* image,
GLStreamTextureImage* stream_texture_image,
ImageState state) {
@@ -1511,12 +1609,16 @@ void Texture::SetLevelImageInternal(GLenum target,
DCHECK_LT(static_cast<size_t>(face_index), face_infos_.size());
DCHECK_LT(static_cast<size_t>(level),
face_infos_[face_index].level_infos.size());
- Texture::LevelInfo& info = face_infos_[face_index].level_infos[level];
- DCHECK_EQ(info.target, target);
- DCHECK_EQ(info.level, level);
- info.image = image;
- info.stream_texture_image = stream_texture_image;
- info.image_state = state;
+ DCHECK_LT(static_cast<size_t>(layer),
+ face_infos_[face_index].level_infos[level].layer_infos.size());
+ Texture::LevelInfo& level_info = face_infos_[face_index].level_infos[level];
+ DCHECK_EQ(level_info.target, target);
+ DCHECK_EQ(level_info.level, level);
+
+ Texture::LayerInfo& layer_info = level_info.layer_infos[layer];
+ layer_info.image = image;
+ layer_info.stream_texture_image = stream_texture_image;
+ layer_info.image_state = state;
UpdateCanRenderCondition();
UpdateHasImages();
@@ -1525,35 +1627,44 @@ void Texture::SetLevelImageInternal(GLenum target,
void Texture::SetLevelImage(GLenum target,
GLint level,
+ GLint layer,
gl::GLImage* image,
ImageState state) {
SetStreamTextureServiceId(0);
- SetLevelImageInternal(target, level, image, nullptr, state);
+ SetLevelImageInternal(target, level, layer, image, nullptr, state);
}
void Texture::SetLevelStreamTextureImage(GLenum target,
GLint level,
+ GLint layer,
GLStreamTextureImage* image,
ImageState state,
GLuint service_id) {
SetStreamTextureServiceId(service_id);
- SetLevelImageInternal(target, level, image, image, state);
+ SetLevelImageInternal(target, level, layer, image, image, state);
}
-void Texture::SetLevelImageState(GLenum target, GLint level, ImageState state) {
+void Texture::SetLevelImageState(GLenum target,
+ GLint level,
+ GLint layer,
+ ImageState state) {
DCHECK_GE(level, 0);
size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
DCHECK_LT(static_cast<size_t>(face_index), face_infos_.size());
DCHECK_LT(static_cast<size_t>(level),
face_infos_[face_index].level_infos.size());
- Texture::LevelInfo& info = face_infos_[face_index].level_infos[level];
- DCHECK_EQ(info.target, target);
- DCHECK_EQ(info.level, level);
- info.image_state = state;
+ DCHECK_LT(static_cast<size_t>(layer),
+ face_infos_[face_index].level_infos[level].layer_infos.size());
+ Texture::LevelInfo& level_info = face_infos_[face_index].level_infos[level];
+ DCHECK_EQ(level_info.target, target);
+ DCHECK_EQ(level_info.level, level);
+ Texture::LayerInfo& layer_info = level_info.layer_infos[layer];
+ layer_info.image_state = state;
}
const Texture::LevelInfo* Texture::GetLevelInfo(GLint target,
GLint level) const {
+ // TODO(yunchao): add TEXTURE_3D and TEXTURE_2D_ARRAY
if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES &&
target != GL_TEXTURE_RECTANGLE_ARB) {
return NULL;
@@ -1571,27 +1682,37 @@ const Texture::LevelInfo* Texture::GetLevelInfo(GLint target,
gl::GLImage* Texture::GetLevelImage(GLint target,
GLint level,
+ GLint layer,
ImageState* state) const {
- const LevelInfo* info = GetLevelInfo(target, level);
- if (!info)
+ const LevelInfo* level_info = GetLevelInfo(target, level);
+ if (!level_info)
+ return nullptr;
+ if (static_cast<size_t>(layer) >= level_info->layer_infos.size())
return nullptr;
+ const LayerInfo& layer_info = level_info->layer_infos[layer];
if (state)
- *state = info->image_state;
- return info->image.get();
+ *state = layer_info.image_state;
+ return layer_info.image.get();
}
-gl::GLImage* Texture::GetLevelImage(GLint target, GLint level) const {
- return GetLevelImage(target, level, nullptr);
+gl::GLImage* Texture::GetLevelImage(GLint target,
+ GLint level,
+ GLint layer) const {
+ return GetLevelImage(target, level, layer, nullptr);
}
GLStreamTextureImage* Texture::GetLevelStreamTextureImage(GLint target,
- GLint level) const {
- const LevelInfo* info = GetLevelInfo(target, level);
- if (!info)
+ GLint level,
+ GLint layer) const {
+ const LevelInfo* level_info = GetLevelInfo(target, level);
+ if (!level_info)
+ return nullptr;
+ if (static_cast<size_t>(layer) >= level_info->layer_infos.size())
return nullptr;
+ const LayerInfo& layer_info = level_info->layer_infos[layer];
- return info->stream_texture_image.get();
+ return layer_info.stream_texture_image.get();
}
void Texture::DumpLevelMemory(base::trace_event::ProcessMemoryDump* pmd,
@@ -1606,26 +1727,33 @@ void Texture::DumpLevelMemory(base::trace_event::ProcessMemoryDump* pmd,
if (!level_infos[level_index].estimated_size)
continue;
- // If a level has a GLImage, ask the GLImage to dump itself.
- if (level_infos[level_index].image) {
- level_infos[level_index].image->OnMemoryDump(
- pmd, client_tracing_id,
- base::StringPrintf("%s/face_%d/level_%d", dump_name.c_str(),
- face_index, level_index));
- }
+ for (uint32_t layer_index = 0;
+ layer_index < level_infos[level_index].layer_infos.size();
+ ++layer_index) {
+ // If a level has a GLImage, ask the GLImage to dump itself.
+ if (level_infos[level_index].layer_infos[layer_index].image) {
+ level_infos[level_index].layer_infos[layer_index].image->OnMemoryDump(
+ pmd, client_tracing_id,
+ base::StringPrintf("%s/face_%d/level_%d/layer_%d",
+ dump_name.c_str(),
+ face_index, level_index, layer_index));
+ }
// If a level does not have a GLImage bound to it, then dump the
// texture allocation also as the storage is not provided by the
// GLImage in that case.
- if (level_infos[level_index].image_state != BOUND) {
+ if (level_infos[level_index].layer_infos[layer_index].image_state
+ != BOUND) {
base::trace_event::MemoryAllocatorDump* dump = pmd->CreateAllocatorDump(
- base::StringPrintf("%s/face_%d/level_%d", dump_name.c_str(),
- face_index, level_index));
+ base::StringPrintf("%s/face_%d/level_%d/layer_%d",
+ dump_name.c_str(),
+ face_index, level_index, layer_index));
dump->AddScalar(
base::trace_event::MemoryAllocatorDump::kNameSize,
base::trace_event::MemoryAllocatorDump::kUnitsBytes,
static_cast<uint64_t>(level_infos[level_index].estimated_size));
}
+ }
}
}
}
@@ -1889,23 +2017,36 @@ bool TextureManager::ValidForTarget(
void TextureManager::SetTarget(TextureRef* ref, GLenum target) {
DCHECK(ref);
- ref->texture()->SetTarget(target, MaxLevelsForTarget(target));
+ GLint layers;
+ switch (target) {
+ case GL_TEXTURE_3D:
+ layers = max_3d_texture_size();
+ break;
+ case GL_TEXTURE_2D_ARRAY:
+ layers = max_array_texture_layers();
+ break;
+ default:
+ layers = 1;
+ }
+ ref->texture()->SetTarget(target, MaxLevelsForTarget(target), layers);
}
void TextureManager::SetLevelClearedRect(TextureRef* ref,
GLenum target,
GLint level,
+ GLint layer,
const gfx::Rect& cleared_rect) {
DCHECK(ref);
- ref->texture()->SetLevelClearedRect(target, level, cleared_rect);
+ ref->texture()->SetLevelClearedRect(target, level, layer, cleared_rect);
}
void TextureManager::SetLevelCleared(TextureRef* ref,
GLenum target,
GLint level,
+ GLint layer,
bool cleared) {
DCHECK(ref);
- ref->texture()->SetLevelCleared(target, level, cleared);
+ ref->texture()->SetLevelCleared(target, level, layer, cleared);
}
bool TextureManager::ClearRenderableLevels(
@@ -1922,7 +2063,7 @@ bool TextureManager::ClearTextureLevel(
if (texture->num_uncleared_mips() == 0) {
return true;
}
- bool result = texture->ClearLevel(decoder, target, level);
+ bool result = texture->ClearLevel(decoder, target, level, 0);
texture->UpdateCleared();
return result;
}
@@ -2114,29 +2255,32 @@ GLsizei TextureManager::ComputeMipMapCount(GLenum target,
void TextureManager::SetLevelImage(TextureRef* ref,
GLenum target,
GLint level,
+ GLint layer,
gl::GLImage* image,
Texture::ImageState state) {
DCHECK(ref);
- ref->texture()->SetLevelImage(target, level, image, state);
+ ref->texture()->SetLevelImage(target, level, layer, image, state);
}
void TextureManager::SetLevelStreamTextureImage(TextureRef* ref,
GLenum target,
GLint level,
+ GLint layer,
GLStreamTextureImage* image,
Texture::ImageState state,
GLuint service_id) {
DCHECK(ref);
- ref->texture()->SetLevelStreamTextureImage(target, level, image, state,
+ ref->texture()->SetLevelStreamTextureImage(target, level, layer, image, state,
service_id);
}
void TextureManager::SetLevelImageState(TextureRef* ref,
GLenum target,
GLint level,
+ GLint layer,
Texture::ImageState state) {
DCHECK(ref);
- ref->texture()->SetLevelImageState(target, level, state);
+ ref->texture()->SetLevelImageState(target, level, layer, state);
}
size_t TextureManager::GetSignatureSize() const {
@@ -2147,8 +2291,10 @@ void TextureManager::AddToSignature(
TextureRef* ref,
GLenum target,
GLint level,
+ GLint layer,
std::string* signature) const {
- ref->texture()->AddToSignature(feature_info_.get(), target, level, signature);
+ ref->texture()->AddToSignature(feature_info_.get(), target,
+ level, layer, signature);
}
void TextureManager::UpdateSafeToRenderFrom(int delta) {
@@ -2453,7 +2599,8 @@ void TextureManager::ValidateAndDoTexImage(
DoTexSubImageRowByRowWorkaround(texture_state, state, sub_args,
unpack_params);
- SetLevelCleared(texture_ref, args.target, args.level, true);
+ SetLevelCleared(texture_ref, args.target,
+ args.level, args.depth - 1, true);
return;
}
}
@@ -2474,7 +2621,8 @@ void TextureManager::ValidateAndDoTexImage(
DoTexSubImageArguments::kTexSubImage2D};
DoTexSubImageWithAlignmentWorkaround(texture_state, state, sub_args);
- SetLevelCleared(texture_ref, args.target, args.level, true);
+ SetLevelCleared(texture_ref, args.target,
+ args.level, args.depth - 1, true);
return;
}
}
@@ -2625,14 +2773,17 @@ void TextureManager::ValidateAndDoTexSubImage(
gfx::Rect cleared_rect;
if (args.command_type == DoTexSubImageArguments::kTexSubImage2D &&
CombineAdjacentRects(
- texture->GetLevelClearedRect(args.target, args.level),
+ texture->GetLevelClearedRect(args.target, args.level,
+ args.depth - 1),
gfx::Rect(args.xoffset, args.yoffset, args.width, args.height),
&cleared_rect)) {
DCHECK_GE(cleared_rect.size().GetArea(),
- texture->GetLevelClearedRect(args.target, args.level)
+ texture->GetLevelClearedRect(args.target, args.level,
+ args.depth - 1)
.size()
.GetArea());
- SetLevelClearedRect(texture_ref, args.target, args.level, cleared_rect);
+ SetLevelClearedRect(texture_ref, args.target,
+ args.level, args.depth - 1, cleared_rect);
} else {
// Otherwise clear part of texture level that is not already cleared.
if (!ClearTextureLevel(decoder, texture_ref, args.target, args.level)) {
@@ -2643,7 +2794,8 @@ void TextureManager::ValidateAndDoTexSubImage(
}
full_image = false;
} else {
- SetLevelCleared(texture_ref, args.target, args.level, true);
+ SetLevelCleared(texture_ref, args.target,
+ args.level, args.depth - 1, true);
full_image = true;
}
« 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