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)) { |