Chromium Code Reviews| 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 e74393623618ef865d805c3dae92e6d9b54b6799..5a90b3f7d40a071425b879fcc07c65b3133916b0 100644 |
| --- a/gpu/command_buffer/service/texture_manager.cc |
| +++ b/gpu/command_buffer/service/texture_manager.cc |
| @@ -65,20 +65,12 @@ struct TextureSignature { |
| // of relying on compilers adhering to this deep dark corner specification. |
| TextureSignature(GLenum target, |
| GLint level, |
| - GLenum min_filter, |
| - GLenum mag_filter, |
| - GLenum wrap_r, |
| - GLenum wrap_s, |
| - GLenum wrap_t, |
| + SamplerState sampler_state, |
| GLenum usage, |
| GLenum internal_format, |
| - GLenum compare_func, |
| - GLenum compare_mode, |
| GLsizei width, |
| GLsizei height, |
| GLsizei depth, |
| - GLfloat max_lod, |
| - GLfloat min_lod, |
| GLint base_level, |
| GLint border, |
| GLint max_level, |
| @@ -91,20 +83,20 @@ struct TextureSignature { |
| memset(this, 0, sizeof(TextureSignature)); |
| target_ = target; |
| level_ = level; |
| - min_filter_ = min_filter; |
| - mag_filter_ = mag_filter; |
| - wrap_r_ = wrap_r; |
| - wrap_s_ = wrap_s; |
| - wrap_t_ = wrap_t; |
| + min_filter_ = sampler_state.min_filter; |
| + mag_filter_ = sampler_state.mag_filter; |
| + wrap_r_ = sampler_state.wrap_r; |
| + wrap_s_ = sampler_state.wrap_s; |
| + wrap_t_ = sampler_state.wrap_t; |
| usage_ = usage; |
| internal_format_ = internal_format; |
| - compare_func_ = compare_func; |
| - compare_mode_ = compare_mode; |
| + compare_func_ = sampler_state.compare_func; |
| + compare_mode_ = sampler_state.compare_mode; |
| width_ = width; |
| height_ = height; |
| depth_ = depth; |
| - max_lod_ = max_lod; |
| - min_lod_ = min_lod; |
| + max_lod_ = sampler_state.max_lod; |
| + min_lod_ = sampler_state.min_lod; |
| base_level_ = base_level; |
| border_ = border; |
| max_level_ = max_level; |
| @@ -306,7 +298,7 @@ void TextureManager::Destroy(bool have_context) { |
| DCHECK_EQ(0u, memory_type_tracker_->GetMemRepresented()); |
| } |
| -Texture::Texture(GLuint service_id) |
| +Texture::Texture(GLuint service_id, bool is_es3_enabled) |
|
Zhenyao Mo
2015/12/11 20:18:54
Per our offline discussion, I suggest we don't add
|
| : mailbox_manager_(NULL), |
| memory_tracking_ref_(NULL), |
| service_id_(service_id), |
| @@ -314,16 +306,7 @@ Texture::Texture(GLuint service_id) |
| num_uncleared_mips_(0), |
| num_npot_faces_(0), |
| target_(0), |
| - min_filter_(GL_NEAREST_MIPMAP_LINEAR), |
| - mag_filter_(GL_LINEAR), |
| - wrap_r_(GL_REPEAT), |
| - wrap_s_(GL_REPEAT), |
| - wrap_t_(GL_REPEAT), |
| usage_(GL_NONE), |
| - compare_func_(GL_LEQUAL), |
| - compare_mode_(GL_NONE), |
| - max_lod_(1000.0f), |
| - min_lod_(-1000.0f), |
| base_level_(0), |
| max_level_(1000), |
| max_level_set_(-1), |
| @@ -338,7 +321,8 @@ Texture::Texture(GLuint service_id) |
| has_images_(false), |
| estimated_size_(0), |
| can_render_condition_(CAN_RENDER_ALWAYS), |
| - texture_max_anisotropy_initialized_(false) { |
| + texture_max_anisotropy_initialized_(false), |
| + is_es3_enabled_(is_es3_enabled) { |
| } |
| Texture::~Texture() { |
| @@ -437,18 +421,23 @@ Texture::CanRenderCondition Texture::GetCanRenderCondition() const { |
| } |
| } |
| + if (target_ == GL_TEXTURE_CUBE_MAP && !cube_complete()) |
| + return CAN_RENDER_NEVER; |
| + |
| + if (is_es3_enabled_) |
| + return CAN_RENDER_WITH_VALID_SAMPLER; |
| + |
| + // NeedsMips checkes the built-in sampler state, and so shouldn't be used to |
| + // determine renderability with ES3 contexts. |
| bool needs_mips = NeedsMips(); |
| if (needs_mips) { |
| if (!texture_complete()) |
| return CAN_RENDER_NEVER; |
| } |
| - if (target_ == GL_TEXTURE_CUBE_MAP && !cube_complete()) |
| - return CAN_RENDER_NEVER; |
| - |
| bool is_npot_compatible = !needs_mips && |
| - wrap_s_ == GL_CLAMP_TO_EDGE && |
| - wrap_t_ == GL_CLAMP_TO_EDGE; |
| + sampler_state_.wrap_s == GL_CLAMP_TO_EDGE && |
| + sampler_state_.wrap_t == GL_CLAMP_TO_EDGE; |
| if (!is_npot_compatible) { |
| if (target_ == GL_TEXTURE_RECTANGLE_ARB) |
| @@ -461,15 +450,49 @@ Texture::CanRenderCondition Texture::GetCanRenderCondition() const { |
| } |
| bool Texture::CanRender(const FeatureInfo* feature_info) const { |
| + return CanRenderWithSampler(feature_info, sampler_state()); |
| +} |
| + |
| +bool Texture::CanRenderWithSampler(const FeatureInfo* feature_info, |
| + const SamplerState* sampler_state) const { |
| + DCHECK(sampler_state); |
| + |
| switch (can_render_condition_) { |
| case CAN_RENDER_ALWAYS: |
| return true; |
| case CAN_RENDER_NEVER: |
| return false; |
| case CAN_RENDER_ONLY_IF_NPOT: |
| + return feature_info->feature_flags().npot_ok; |
| + case CAN_RENDER_WITH_VALID_SAMPLER: |
| break; |
| } |
| - return feature_info->feature_flags().npot_ok; |
| + |
| + bool needs_mips = sampler_state->min_filter != GL_NEAREST && |
| + sampler_state->min_filter != GL_LINEAR; |
| + if (needs_mips && !texture_complete()) |
| + return false; |
| + |
| + if (static_cast<size_t>(base_level_) >= face_infos_[0].level_infos.size()) { |
| + return false; |
| + } |
| + |
| + const Texture::LevelInfo& first_level = |
| + face_infos_[0].level_infos[base_level_]; |
| + |
| + if (first_level.type == GL_FLOAT && |
| + !feature_info->feature_flags().enable_texture_float_linear && |
| + (sampler_state->min_filter != GL_NEAREST_MIPMAP_NEAREST || |
| + sampler_state->mag_filter != GL_NEAREST)) { |
| + return false; |
| + } else if (first_level.type == GL_HALF_FLOAT_OES && |
| + !feature_info->feature_flags().enable_texture_half_float_linear && |
| + (sampler_state->min_filter != GL_NEAREST_MIPMAP_NEAREST || |
| + sampler_state->mag_filter != GL_NEAREST)) { |
| + return false; |
| + } |
| + |
| + return true; |
| } |
| void Texture::AddToSignature( |
| @@ -491,20 +514,12 @@ void Texture::AddToSignature( |
| TextureSignature signature_data(target, |
| level, |
| - min_filter_, |
| - mag_filter_, |
| - wrap_r_, |
| - wrap_s_, |
| - wrap_t_, |
| + sampler_state_, |
| usage_, |
| info.internal_format, |
| - compare_func_, |
| - compare_mode_, |
| info.width, |
| info.height, |
| info.depth, |
| - max_lod_, |
| - min_lod_, |
| base_level_, |
| info.border, |
| max_level_, |
| @@ -565,8 +580,8 @@ void Texture::SetTarget( |
| } |
| if (target == GL_TEXTURE_EXTERNAL_OES || target == GL_TEXTURE_RECTANGLE_ARB) { |
| - min_filter_ = GL_LINEAR; |
| - wrap_s_ = wrap_t_ = GL_CLAMP_TO_EDGE; |
| + sampler_state_.min_filter = GL_LINEAR; |
| + sampler_state_.wrap_s = sampler_state_.wrap_t = GL_CLAMP_TO_EDGE; |
| } |
| if (target == GL_TEXTURE_EXTERNAL_OES) { |
| @@ -982,43 +997,43 @@ GLenum Texture::SetParameteri( |
| if (!feature_info->validators()->texture_min_filter_mode.IsValid(param)) { |
| return GL_INVALID_ENUM; |
| } |
| - min_filter_ = param; |
| + sampler_state_.min_filter = param; |
| break; |
| case GL_TEXTURE_MAG_FILTER: |
| if (!feature_info->validators()->texture_mag_filter_mode.IsValid(param)) { |
| return GL_INVALID_ENUM; |
| } |
| - mag_filter_ = param; |
| + sampler_state_.mag_filter = param; |
| break; |
| case GL_TEXTURE_WRAP_R: |
| if (!feature_info->validators()->texture_wrap_mode.IsValid(param)) { |
| return GL_INVALID_ENUM; |
| } |
| - wrap_r_ = param; |
| + sampler_state_.wrap_r = param; |
| break; |
| case GL_TEXTURE_WRAP_S: |
| if (!feature_info->validators()->texture_wrap_mode.IsValid(param)) { |
| return GL_INVALID_ENUM; |
| } |
| - wrap_s_ = param; |
| + sampler_state_.wrap_s = param; |
| break; |
| case GL_TEXTURE_WRAP_T: |
| if (!feature_info->validators()->texture_wrap_mode.IsValid(param)) { |
| return GL_INVALID_ENUM; |
| } |
| - wrap_t_ = param; |
| + sampler_state_.wrap_t = param; |
| break; |
| case GL_TEXTURE_COMPARE_FUNC: |
| if (!feature_info->validators()->texture_compare_func.IsValid(param)) { |
| return GL_INVALID_ENUM; |
| } |
| - compare_func_ = param; |
| + sampler_state_.compare_func = param; |
| break; |
| case GL_TEXTURE_COMPARE_MODE: |
| if (!feature_info->validators()->texture_compare_mode.IsValid(param)) { |
| return GL_INVALID_ENUM; |
| } |
| - compare_mode_ = param; |
| + sampler_state_.compare_mode = param; |
| break; |
| case GL_TEXTURE_BASE_LEVEL: |
| if (param < 0) { |
| @@ -1071,10 +1086,10 @@ GLenum Texture::SetParameterf( |
| return SetParameteri(feature_info, pname, iparam); |
| } |
| case GL_TEXTURE_MIN_LOD: |
| - min_lod_ = param; |
| + sampler_state_.min_lod = param; |
| break; |
| case GL_TEXTURE_MAX_LOD: |
| - max_lod_ = param; |
| + sampler_state_.max_lod = param; |
| break; |
| case GL_TEXTURE_MAX_ANISOTROPY_EXT: |
| if (param < 1.f) { |
| @@ -1112,16 +1127,18 @@ void Texture::Update(const FeatureInfo* feature_info) { |
| if (first_level.width == 0 || first_level.height == 0) { |
| texture_complete_ = false; |
| - } else if (first_level.type == GL_FLOAT && |
| - !feature_info->feature_flags().enable_texture_float_linear && |
| - (min_filter_ != GL_NEAREST_MIPMAP_NEAREST || |
| - mag_filter_ != GL_NEAREST)) { |
| - texture_complete_ = false; |
| - } else if (first_level.type == GL_HALF_FLOAT_OES && |
| - !feature_info->feature_flags().enable_texture_half_float_linear && |
| - (min_filter_ != GL_NEAREST_MIPMAP_NEAREST || |
| - mag_filter_ != GL_NEAREST)) { |
| - texture_complete_ = false; |
| + } else if (!is_es3_enabled_) { |
|
Zhenyao Mo
2015/12/11 20:18:54
Shouldn't we still check the following in ES3?
|
| + if (first_level.type == GL_FLOAT && |
| + !feature_info->feature_flags().enable_texture_float_linear && |
| + (sampler_state_.min_filter != GL_NEAREST_MIPMAP_NEAREST || |
| + sampler_state_.mag_filter != GL_NEAREST)) { |
| + texture_complete_ = false; |
| + } else if (first_level.type == GL_HALF_FLOAT_OES && |
| + !feature_info->feature_flags().enable_texture_half_float_linear && |
| + (sampler_state_.min_filter != GL_NEAREST_MIPMAP_NEAREST || |
| + sampler_state_.mag_filter != GL_NEAREST)) { |
| + texture_complete_ = false; |
| + } |
| } |
| bool texture_level0_complete = true; |
| @@ -1379,7 +1396,8 @@ TextureRef::TextureRef(TextureManager* manager, |
| scoped_refptr<TextureRef> TextureRef::Create(TextureManager* manager, |
| GLuint client_id, |
| GLuint service_id) { |
| - return new TextureRef(manager, client_id, new Texture(service_id)); |
| + return new TextureRef(manager, client_id, new Texture(service_id, |
| + manager->feature_info_->IsES3Enabled())); |
| } |
| TextureRef::~TextureRef() { |
| @@ -1705,7 +1723,8 @@ void TextureManager::StartTracking(TextureRef* ref) { |
| num_uncleared_mips_ += texture->num_uncleared_mips(); |
| if (!texture->SafeToRenderFrom()) |
| ++num_unsafe_textures_; |
| - if (!texture->CanRender(feature_info_.get())) |
| + if (!feature_info_->IsES3Enabled() && |
| + !texture->CanRender(feature_info_.get())) |
| ++num_unrenderable_textures_; |
| if (texture->HasImages()) |
| ++num_images_; |
| @@ -1726,7 +1745,8 @@ void TextureManager::StopTracking(TextureRef* ref) { |
| DCHECK_NE(0, num_images_); |
| --num_images_; |
| } |
| - if (!texture->CanRender(feature_info_.get())) { |
| + if (!feature_info_->IsES3Enabled() && |
| + !texture->CanRender(feature_info_.get())) { |
| DCHECK_NE(0, num_unrenderable_textures_); |
| --num_unrenderable_textures_; |
| } |
| @@ -1800,6 +1820,8 @@ void TextureManager::UpdateUnclearedMips(int delta) { |
| void TextureManager::UpdateCanRenderCondition( |
| Texture::CanRenderCondition old_condition, |
| Texture::CanRenderCondition new_condition) { |
| + if (feature_info_->IsES3Enabled()) |
| + return; |
| if (old_condition == Texture::CAN_RENDER_NEVER || |
| (old_condition == Texture::CAN_RENDER_ONLY_IF_NPOT && |
| !feature_info_->feature_flags().npot_ok)) { |