| 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 4dbf5289e1397a61baef1b921f031535ba73448c..c5c7116c6e403fa8e48bbdded7da606b697a8c74 100644
|
| --- a/gpu/command_buffer/service/texture_manager.cc
|
| +++ b/gpu/command_buffer/service/texture_manager.cc
|
| @@ -629,6 +629,55 @@ void Texture::SetLevelInfo(
|
| width, height, format, type, 4, &info.estimated_size, NULL, NULL);
|
| estimated_size_ += info.estimated_size;
|
|
|
| + UpdateLevelInfo(info, feature_info, level, cleared);
|
| +}
|
| +
|
| +void Texture::SetCompressedLevelInfo(const FeatureInfo* feature_info,
|
| + GLenum target,
|
| + GLint level,
|
| + GLenum internal_format,
|
| + GLsizei width,
|
| + GLsizei height,
|
| + GLsizei depth,
|
| + GLint border,
|
| + GLsizei image_size,
|
| + bool cleared) {
|
| + size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
|
| + DCHECK_GE(level, 0);
|
| + 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_GE(width, 0);
|
| + DCHECK_GE(height, 0);
|
| + DCHECK_GE(depth, 0);
|
| + DCHECK_EQ(border, 0);
|
| + Texture::LevelInfo& info = face_infos_[face_index].level_infos[level];
|
| + info.target = target;
|
| + info.level = level;
|
| + info.internal_format = internal_format;
|
| + info.width = width;
|
| + info.height = height;
|
| + info.depth = depth;
|
| + info.border = border;
|
| + // TODO(peterp): Compressed formats only have the internal format and no type,
|
| + // but we could potentially have a lookup table to figure that out.
|
| + // In practice it seems to work ok to always treat compressed formats as
|
| + // RGBA + UNSIGNED_BYTE through.
|
| + info.format = GL_RGBA;
|
| + info.type = GL_UNSIGNED_BYTE;
|
| + info.image = 0;
|
| +
|
| + estimated_size_ -= info.estimated_size;
|
| + info.estimated_size = image_size;
|
| + estimated_size_ += info.estimated_size;
|
| +
|
| + UpdateLevelInfo(info, feature_info, level, cleared);
|
| +}
|
| +
|
| +void Texture::UpdateLevelInfo(Texture::LevelInfo& info,
|
| + const FeatureInfo* feature_info,
|
| + GLint level,
|
| + bool cleared) {
|
| UpdateMipCleared(&info, cleared);
|
| max_level_set_ = std::max(max_level_set_, level);
|
| Update(feature_info);
|
| @@ -1244,6 +1293,26 @@ void TextureManager::SetLevelInfo(
|
| texture->GetMemTracker()->TrackMemAlloc(texture->estimated_size());
|
| }
|
|
|
| +void TextureManager::SetCompressedLevelInfo(TextureRef* ref,
|
| + GLenum target,
|
| + GLint level,
|
| + GLenum internal_format,
|
| + GLsizei width,
|
| + GLsizei height,
|
| + GLsizei depth,
|
| + GLint border,
|
| + GLsizei image_size,
|
| + bool cleared) {
|
| + DCHECK(ref);
|
| + Texture* texture = ref->texture();
|
| +
|
| + texture->GetMemTracker()->TrackMemFree(texture->estimated_size());
|
| + texture->SetCompressedLevelInfo(feature_info_.get(), target, level,
|
| + internal_format, width, height, depth, border,
|
| + image_size, cleared);
|
| + texture->GetMemTracker()->TrackMemAlloc(texture->estimated_size());
|
| +}
|
| +
|
| Texture* TextureManager::Produce(TextureRef* ref) {
|
| DCHECK(ref);
|
| return ref->texture();
|
| @@ -1713,6 +1782,71 @@ void TextureManager::DoTexImage2D(
|
| }
|
| }
|
|
|
| +bool TextureManager::ValidateCompressedTexImage2D(
|
| + ContextState* state,
|
| + const char* function_name,
|
| + const DoCompressedTexImage2DArguments& args,
|
| + TextureRef** texture_ref) {
|
| + ErrorState* error_state = state->GetErrorState();
|
| + const Validators* validators = feature_info_->validators();
|
| + if (!validators->texture_target.IsValid(args.target)) {
|
| + ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(error_state, function_name,
|
| + args.target, "target");
|
| + return false;
|
| + }
|
| + if (!validators->compressed_texture_format.IsValid(args.internal_format)) {
|
| + ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(
|
| + error_state, function_name, args.internal_format, "internal_format");
|
| + return false;
|
| + }
|
| + if (!ValidForTarget(args.target, args.level, args.width, args.height, 1) ||
|
| + args.border != 0) {
|
| + ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, function_name,
|
| + "dimensions out of range");
|
| + return false;
|
| + }
|
| +
|
| + if (!GLES2Util::IsValidCompressedImageSize(
|
| + args.level, args.width, args.height, args.internal_format)) {
|
| + ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, function_name,
|
| + "width or height invalid for level");
|
| + return false;
|
| + }
|
| + int bytes_required = 0;
|
| + if (!GLES2Util::ComputeCompressedImageSize(
|
| + args.width, args.height, args.internal_format, &bytes_required) ||
|
| + args.image_size != static_cast<GLsizei>(bytes_required)) {
|
| + ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, function_name,
|
| + "size is not correct for dimension");
|
| + return false;
|
| + }
|
| +
|
| + TextureRef* local_texture_ref = GetTextureInfoForTarget(state, args.target);
|
| + if (!local_texture_ref) {
|
| + ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, function_name,
|
| + "unknown texture for target");
|
| + return false;
|
| + }
|
| + if (local_texture_ref->texture()->IsImmutable()) {
|
| + ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, function_name,
|
| + "texture is immutable");
|
| + return false;
|
| + }
|
| +
|
| + // TODO - verify that using the managed vs unmanaged does not matter.
|
| + // They both use the same MemoryTracker, and this call just re-routes
|
| + // to it.
|
| + if (!memory_tracker_managed_->EnsureGPUMemoryAvailable(args.image_size)) {
|
| + ERRORSTATE_SET_GL_ERROR(error_state, GL_OUT_OF_MEMORY, "glTexImage2D",
|
| + "out of memory");
|
| + return false;
|
| + }
|
| +
|
| + // Write the TextureReference since this is valid.
|
| + *texture_ref = local_texture_ref;
|
| + return true;
|
| +}
|
| +
|
| ScopedTextureUploadTimer::ScopedTextureUploadTimer(
|
| DecoderTextureState* texture_state)
|
| : texture_state_(texture_state),
|
|
|