| 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 d428c376a54635794bdf14fe743de67548c1a4e9..9828c1ff09e43175e81a2fd66d9349f734f96c4b 100644
|
| --- a/gpu/command_buffer/service/texture_manager.cc
|
| +++ b/gpu/command_buffer/service/texture_manager.cc
|
| @@ -71,20 +71,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,
|
| + const 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,
|
| @@ -97,20 +89,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;
|
| @@ -289,7 +281,6 @@ TextureManager::~TextureManager() {
|
| // a Texture belonging to this.
|
| CHECK_EQ(texture_count_, 0u);
|
|
|
| - DCHECK_EQ(0, num_unrenderable_textures_);
|
| DCHECK_EQ(0, num_unsafe_textures_);
|
| DCHECK_EQ(0, num_uncleared_mips_);
|
| DCHECK_EQ(0, num_images_);
|
| @@ -321,16 +312,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),
|
| @@ -441,39 +423,67 @@ Texture::CanRenderCondition Texture::GetCanRenderCondition() const {
|
| }
|
| }
|
|
|
| - 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;
|
| -
|
| - if (!is_npot_compatible) {
|
| - if (target_ == GL_TEXTURE_RECTANGLE_ARB)
|
| - return CAN_RENDER_NEVER;
|
| - else if (npot())
|
| - return CAN_RENDER_ONLY_IF_NPOT;
|
| - }
|
| -
|
| - return CAN_RENDER_ALWAYS;
|
| + // Texture may be renderable, but it depends on the sampler it's used with,
|
| + // the context that's using it, and the extensions available.
|
| + return CAN_RENDER_NEEDS_VALIDATION;
|
| }
|
|
|
| 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 {
|
| switch (can_render_condition_) {
|
| case CAN_RENDER_ALWAYS:
|
| return true;
|
| case CAN_RENDER_NEVER:
|
| return false;
|
| - case CAN_RENDER_ONLY_IF_NPOT:
|
| + case CAN_RENDER_NEEDS_VALIDATION:
|
| 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) {
|
| + 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 (!texture_complete()) {
|
| + return false;
|
| + } else 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;
|
| + }
|
| + }
|
| +
|
| + if (!feature_info->IsES3Enabled()) {
|
| + bool is_npot_compatible = !needs_mips &&
|
| + 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)
|
| + return false;
|
| + else if (npot())
|
| + return feature_info->feature_flags().npot_ok;
|
| + }
|
| + }
|
| +
|
| + return true;
|
| }
|
|
|
| void Texture::AddToSignature(
|
| @@ -495,20 +505,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 +567,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) {
|
| @@ -750,13 +752,7 @@ void Texture::UpdateMipCleared(LevelInfo* info,
|
| }
|
|
|
| void Texture::UpdateCanRenderCondition() {
|
| - CanRenderCondition can_render_condition = GetCanRenderCondition();
|
| - if (can_render_condition_ == can_render_condition)
|
| - return;
|
| - for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it)
|
| - (*it)->manager()->UpdateCanRenderCondition(can_render_condition_,
|
| - can_render_condition);
|
| - can_render_condition_ = can_render_condition;
|
| + can_render_condition_ = GetCanRenderCondition();
|
| }
|
|
|
| void Texture::UpdateHasImages() {
|
| @@ -995,43 +991,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) {
|
| @@ -1084,10 +1080,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) {
|
| @@ -1126,16 +1122,6 @@ 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;
|
| }
|
|
|
| bool texture_level0_complete = true;
|
| @@ -1456,7 +1442,6 @@ TextureManager::TextureManager(MemoryTracker* memory_tracker,
|
| max_3d_texture_size,
|
| max_3d_texture_size)),
|
| use_default_textures_(use_default_textures),
|
| - num_unrenderable_textures_(0),
|
| num_unsafe_textures_(0),
|
| num_uncleared_mips_(0),
|
| num_images_(0),
|
| @@ -1744,8 +1729,6 @@ void TextureManager::StartTracking(TextureRef* ref) {
|
| num_uncleared_mips_ += texture->num_uncleared_mips();
|
| if (!texture->SafeToRenderFrom())
|
| ++num_unsafe_textures_;
|
| - if (!texture->CanRender(feature_info_.get()))
|
| - ++num_unrenderable_textures_;
|
| if (texture->HasImages())
|
| ++num_images_;
|
| }
|
| @@ -1765,10 +1748,6 @@ void TextureManager::StopTracking(TextureRef* ref) {
|
| DCHECK_NE(0, num_images_);
|
| --num_images_;
|
| }
|
| - if (!texture->CanRender(feature_info_.get())) {
|
| - DCHECK_NE(0, num_unrenderable_textures_);
|
| - --num_unrenderable_textures_;
|
| - }
|
| if (!texture->SafeToRenderFrom()) {
|
| DCHECK_NE(0, num_unsafe_textures_);
|
| --num_unsafe_textures_;
|
| @@ -1836,21 +1815,6 @@ void TextureManager::UpdateUnclearedMips(int delta) {
|
| DCHECK_GE(num_uncleared_mips_, 0);
|
| }
|
|
|
| -void TextureManager::UpdateCanRenderCondition(
|
| - Texture::CanRenderCondition old_condition,
|
| - Texture::CanRenderCondition new_condition) {
|
| - if (old_condition == Texture::CAN_RENDER_NEVER ||
|
| - (old_condition == Texture::CAN_RENDER_ONLY_IF_NPOT &&
|
| - !feature_info_->feature_flags().npot_ok)) {
|
| - DCHECK_GT(num_unrenderable_textures_, 0);
|
| - --num_unrenderable_textures_;
|
| - }
|
| - if (new_condition == Texture::CAN_RENDER_NEVER ||
|
| - (new_condition == Texture::CAN_RENDER_ONLY_IF_NPOT &&
|
| - !feature_info_->feature_flags().npot_ok))
|
| - ++num_unrenderable_textures_;
|
| -}
|
| -
|
| void TextureManager::UpdateNumImages(int delta) {
|
| num_images_ += delta;
|
| DCHECK_GE(num_images_, 0);
|
|
|