| 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 27e48920ce501c572c4435da597e7d3918821743..4a2314510760eec30d78a58df857c683d4564595 100644
|
| --- a/gpu/command_buffer/service/texture_manager.cc
|
| +++ b/gpu/command_buffer/service/texture_manager.cc
|
| @@ -8,6 +8,7 @@
|
| #include "gpu/command_buffer/common/gles2_cmd_utils.h"
|
| #include "gpu/command_buffer/service/error_state.h"
|
| #include "gpu/command_buffer/service/feature_info.h"
|
| +#include "gpu/command_buffer/service/framebuffer_manager.h"
|
| #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
|
| #include "gpu/command_buffer/service/mailbox_manager.h"
|
| #include "gpu/command_buffer/service/memory_tracking.h"
|
| @@ -87,10 +88,9 @@ void TextureManager::Destroy(bool have_context) {
|
| DCHECK_EQ(0u, memory_tracker_unmanaged_->GetMemRepresented());
|
| }
|
|
|
| -Texture::Texture(TextureManager* manager, GLuint service_id)
|
| - : manager_(manager),
|
| +Texture::Texture(GLuint service_id)
|
| + : memory_tracking_ref_(NULL),
|
| service_id_(service_id),
|
| - deleted_(false),
|
| cleared_(true),
|
| num_uncleared_mips_(0),
|
| target_(0),
|
| @@ -109,24 +109,48 @@ Texture::Texture(TextureManager* manager, GLuint service_id)
|
| owned_(true),
|
| stream_texture_(false),
|
| immutable_(false),
|
| - estimated_size_(0) {
|
| - if (manager_) {
|
| - manager_->StartTracking(this);
|
| - }
|
| + estimated_size_(0),
|
| + can_render_condition_(CAN_RENDER_NEVER) {
|
| }
|
|
|
| Texture::~Texture() {
|
| - if (manager_) {
|
| - if (owned_ && manager_->have_context_) {
|
| +}
|
| +
|
| +void Texture::AddTextureRef(TextureRef* ref) {
|
| + DCHECK(refs_.find(ref) == refs_.end());
|
| + refs_.insert(ref);
|
| + if (!memory_tracking_ref_) {
|
| + memory_tracking_ref_ = ref;
|
| + GetMemTracker()->TrackMemAlloc(estimated_size());
|
| + }
|
| +}
|
| +
|
| +void Texture::RemoveTextureRef(TextureRef* ref, bool have_context) {
|
| + if (memory_tracking_ref_ == ref) {
|
| + GetMemTracker()->TrackMemFree(estimated_size());
|
| + memory_tracking_ref_ = NULL;
|
| + }
|
| + size_t result = refs_.erase(ref);
|
| + DCHECK_EQ(result, 1u);
|
| + if (refs_.empty()) {
|
| + if (owned_ && have_context) {
|
| GLuint id = service_id();
|
| glDeleteTextures(1, &id);
|
| }
|
| - MarkAsDeleted();
|
| - manager_->StopTracking(this);
|
| - manager_ = NULL;
|
| + delete this;
|
| + } else if (memory_tracking_ref_ == NULL) {
|
| + // TODO(piman): tune ownership semantics for cross-context group shared
|
| + // textures.
|
| + memory_tracking_ref_ = *refs_.begin();
|
| + GetMemTracker()->TrackMemAlloc(estimated_size());
|
| }
|
| }
|
|
|
| +MemoryTypeTracker* Texture::GetMemTracker() {
|
| + DCHECK(memory_tracking_ref_);
|
| + return memory_tracking_ref_->manager()->GetMemTracker(pool_);
|
| +}
|
| +
|
| Texture::LevelInfo::LevelInfo()
|
| : cleared(true),
|
| target(0),
|
| @@ -159,44 +183,59 @@ Texture::LevelInfo::LevelInfo(const LevelInfo& rhs)
|
| Texture::LevelInfo::~LevelInfo() {
|
| }
|
|
|
| -bool Texture::CanRender(const FeatureInfo* feature_info) const {
|
| - if (target_ == 0) {
|
| - return false;
|
| - }
|
| +Texture::CanRenderCondition Texture::GetCanRenderCondition() const {
|
| + if (target_ == 0)
|
| + return CAN_RENDER_NEVER;
|
|
|
| if (target_ == GL_TEXTURE_EXTERNAL_OES) {
|
| if (!IsStreamTexture()) {
|
| - return false;
|
| + return CAN_RENDER_NEVER;
|
| }
|
| } else {
|
| if (level_infos_.empty()) {
|
| - return false;
|
| + return CAN_RENDER_NEVER;
|
| }
|
|
|
| const Texture::LevelInfo& first_face = level_infos_[0][0];
|
| if (first_face.width == 0 ||
|
| first_face.height == 0 ||
|
| first_face.depth == 0) {
|
| - return false;
|
| + return CAN_RENDER_NEVER;
|
| }
|
| }
|
|
|
| bool needs_mips = NeedsMips();
|
| - if ((npot() && !feature_info->feature_flags().npot_ok) ||
|
| - (target_ == GL_TEXTURE_RECTANGLE_ARB)) {
|
| - return !needs_mips &&
|
| - wrap_s_ == GL_CLAMP_TO_EDGE &&
|
| - wrap_t_ == GL_CLAMP_TO_EDGE;
|
| - }
|
| if (needs_mips) {
|
| - if (target_ == GL_TEXTURE_2D) {
|
| - return texture_complete();
|
| - } else {
|
| - return texture_complete() && cube_complete();
|
| - }
|
| - } else {
|
| - return true;
|
| + 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;
|
| +}
|
| +
|
| +bool Texture::CanRender(const FeatureInfo* feature_info) const {
|
| + switch (can_render_condition_) {
|
| + case CAN_RENDER_ALWAYS:
|
| + return true;
|
| + case CAN_RENDER_NEVER:
|
| + return false;
|
| + case CAN_RENDER_ONLY_IF_NPOT:
|
| + break;
|
| + }
|
| + return feature_info->feature_flags().npot_ok;
|
| }
|
|
|
| void Texture::AddToSignature(
|
| @@ -280,6 +319,7 @@ void Texture::SetTarget(
|
| immutable_ = true;
|
| }
|
| Update(feature_info);
|
| + UpdateCanRenderCondition();
|
| }
|
|
|
| bool Texture::CanGenerateMipmaps(
|
| @@ -325,13 +365,7 @@ void Texture::SetLevelCleared(GLenum target, GLint level, bool cleared) {
|
| level_infos_[GLTargetToFaceIndex(target)].size());
|
| Texture::LevelInfo& info =
|
| level_infos_[GLTargetToFaceIndex(target)][level];
|
| - if (!info.cleared) {
|
| - DCHECK_NE(0, num_uncleared_mips_);
|
| - --num_uncleared_mips_;
|
| - } else {
|
| - ++num_uncleared_mips_;
|
| - }
|
| - info.cleared = cleared;
|
| + UpdateMipCleared(&info, cleared);
|
| UpdateCleared();
|
| }
|
|
|
| @@ -343,17 +377,61 @@ void Texture::UpdateCleared() {
|
| const Texture::LevelInfo& first_face = level_infos_[0][0];
|
| int levels_needed = TextureManager::ComputeMipMapCount(
|
| first_face.width, first_face.height, first_face.depth);
|
| - cleared_ = true;
|
| + bool cleared = true;
|
| for (size_t ii = 0; ii < level_infos_.size(); ++ii) {
|
| for (GLint jj = 0; jj < levels_needed; ++jj) {
|
| const Texture::LevelInfo& info = level_infos_[ii][jj];
|
| if (info.width > 0 && info.height > 0 && info.depth > 0 &&
|
| !info.cleared) {
|
| - cleared_ = false;
|
| - return;
|
| + cleared = false;
|
| + break;
|
| }
|
| }
|
| }
|
| + UpdateSafeToRenderFrom(cleared);
|
| +}
|
| +
|
| +void Texture::UpdateSafeToRenderFrom(bool cleared) {
|
| + if (cleared_ == cleared)
|
| + return;
|
| + cleared_ = cleared;
|
| + int delta = cleared ? -1 : +1;
|
| + for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it)
|
| + (*it)->manager()->UpdateSafeToRenderFrom(delta);
|
| +}
|
| +
|
| +void Texture::UpdateMipCleared(LevelInfo* info, bool cleared) {
|
| + if (info->cleared == cleared)
|
| + return;
|
| + info->cleared = cleared;
|
| + int delta = cleared ? -1 : +1;
|
| + num_uncleared_mips_ += delta;
|
| + for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it)
|
| + (*it)->manager()->UpdateUnclearedMips(delta);
|
| +}
|
| +
|
| +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;
|
| +}
|
| +
|
| +void Texture::IncAllFramebufferStateChangeCount() {
|
| + for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it)
|
| + (*it)->manager()->IncFramebufferStateChangeCount();
|
| +}
|
| +
|
| +AsyncPixelTransferState* Texture::GetAsyncTransferState() const {
|
| + for (RefSet::const_iterator it = refs_.begin(); it != refs_.end(); ++it) {
|
| + AsyncPixelTransferState* state = (*it)->async_transfer_state();
|
| + if (state)
|
| + return state;
|
| + }
|
| + return NULL;
|
| }
|
|
|
| void Texture::SetLevelInfo(
|
| @@ -394,17 +472,16 @@ void Texture::SetLevelInfo(
|
| width, height, format, type, 4, &info.estimated_size, NULL, NULL);
|
| estimated_size_ += info.estimated_size;
|
|
|
| - if (!info.cleared) {
|
| - DCHECK_NE(0, num_uncleared_mips_);
|
| - --num_uncleared_mips_;
|
| - }
|
| - info.cleared = cleared;
|
| - if (!info.cleared) {
|
| - ++num_uncleared_mips_;
|
| - }
|
| + UpdateMipCleared(&info, cleared);
|
| max_level_set_ = std::max(max_level_set_, level);
|
| Update(feature_info);
|
| UpdateCleared();
|
| + UpdateCanRenderCondition();
|
| + if (IsAttachedToFramebuffer()) {
|
| + // TODO(gman): If textures tracked which framebuffers they were attached to
|
| + // we could just mark those framebuffers as not complete.
|
| + IncAllFramebufferStateChangeCount();
|
| + }
|
| }
|
|
|
| bool Texture::ValidForTexture(
|
| @@ -499,9 +576,9 @@ GLenum Texture::SetParameter(
|
| if (!feature_info->validators()->texture_pool.IsValid(param)) {
|
| return GL_INVALID_ENUM;
|
| }
|
| - manager_->GetMemTracker(pool_)->TrackMemFree(estimated_size());
|
| + GetMemTracker()->TrackMemFree(estimated_size());
|
| pool_ = param;
|
| - manager_->GetMemTracker(pool_)->TrackMemAlloc(estimated_size());
|
| + GetMemTracker()->TrackMemAlloc(estimated_size());
|
| break;
|
| case GL_TEXTURE_WRAP_S:
|
| if (!feature_info->validators()->texture_wrap_mode.IsValid(param)) {
|
| @@ -532,6 +609,7 @@ GLenum Texture::SetParameter(
|
| }
|
| Update(feature_info);
|
| UpdateCleared();
|
| + UpdateCanRenderCondition();
|
| return GL_NO_ERROR;
|
| }
|
|
|
| @@ -619,7 +697,7 @@ void Texture::Update(const FeatureInfo* feature_info) {
|
|
|
| bool Texture::ClearRenderableLevels(GLES2Decoder* decoder) {
|
| DCHECK(decoder);
|
| - if (SafeToRenderFrom()) {
|
| + if (cleared_) {
|
| return true;
|
| }
|
|
|
| @@ -637,7 +715,7 @@ bool Texture::ClearRenderableLevels(GLES2Decoder* decoder) {
|
| }
|
| }
|
| }
|
| - cleared_ = true;
|
| + UpdateSafeToRenderFrom(true);
|
| return true;
|
| }
|
|
|
| @@ -674,18 +752,13 @@ bool Texture::ClearLevel(
|
| return true;
|
| }
|
|
|
| - DCHECK_NE(0, num_uncleared_mips_);
|
| - --num_uncleared_mips_;
|
| -
|
| // NOTE: It seems kind of gross to call back into the decoder for this
|
| // but only the decoder knows all the state (like unpack_alignment_) that's
|
| // needed to be able to call GL correctly.
|
| - info.cleared = decoder->ClearLevel(
|
| + bool cleared = decoder->ClearLevel(
|
| service_id_, target_, info.target, info.level, info.format, info.type,
|
| info.width, info.height, immutable_);
|
| - if (!info.cleared) {
|
| - ++num_uncleared_mips_;
|
| - }
|
| + UpdateMipCleared(&info, cleared);
|
| return info.cleared;
|
| }
|
|
|
| @@ -704,6 +777,7 @@ void Texture::SetLevelImage(
|
| DCHECK_EQ(info.target, target);
|
| DCHECK_EQ(info.level, level);
|
| info.image = image;
|
| + UpdateCanRenderCondition();
|
| }
|
|
|
| gfx::GLImage* Texture::GetLevelImage(
|
| @@ -719,6 +793,28 @@ gfx::GLImage* Texture::GetLevelImage(
|
| return 0;
|
| }
|
|
|
| +
|
| +TextureRef::TextureRef(TextureManager* manager, Texture* texture)
|
| + : manager_(manager),
|
| + texture_(texture) {
|
| + DCHECK(manager_);
|
| + DCHECK(texture_);
|
| + texture_->AddTextureRef(this);
|
| + manager_->StartTracking(this);
|
| +}
|
| +
|
| +scoped_refptr<TextureRef> TextureRef::Create(TextureManager* manager,
|
| + GLuint service_id) {
|
| + return new TextureRef(manager, new Texture(service_id));
|
| +}
|
| +
|
| +TextureRef::~TextureRef() {
|
| + manager_->StopTracking(this);
|
| + texture_->RemoveTextureRef(this, manager_->have_context_);
|
| + manager_ = NULL;
|
| +}
|
| +
|
| +
|
| TextureManager::TextureManager(
|
| MemoryTracker* memory_tracker,
|
| FeatureInfo* feature_info,
|
| @@ -729,6 +825,7 @@ TextureManager::TextureManager(
|
| memory_tracker_unmanaged_(
|
| new MemoryTypeTracker(memory_tracker, MemoryTracker::kUnmanaged)),
|
| feature_info_(feature_info),
|
| + framebuffer_manager_(NULL),
|
| max_texture_size_(max_texture_size),
|
| max_cube_map_texture_size_(max_cube_map_texture_size),
|
| max_levels_(ComputeMipMapCount(max_texture_size,
|
| @@ -770,7 +867,7 @@ bool TextureManager::Initialize() {
|
| return true;
|
| }
|
|
|
| -scoped_refptr<Texture>
|
| +scoped_refptr<TextureRef>
|
| TextureManager::CreateDefaultAndBlackTextures(
|
| GLenum target,
|
| GLuint* black_texture) {
|
| @@ -800,10 +897,7 @@ scoped_refptr<Texture>
|
| }
|
| glBindTexture(target, 0);
|
|
|
| - // Since we are manually setting up these textures
|
| - // we need to manually manipulate some of the their bookkeeping.
|
| - ++num_unrenderable_textures_;
|
| - scoped_refptr<Texture> default_texture(new Texture(this, ids[1]));
|
| + scoped_refptr<TextureRef> default_texture(TextureRef::Create(this, ids[1]));
|
| SetTarget(default_texture, target);
|
| if (needs_faces) {
|
| for (int ii = 0; ii < GLES2Util::kNumFaces; ++ii) {
|
| @@ -846,90 +940,45 @@ bool TextureManager::ValidForTarget(
|
| (target != GL_TEXTURE_2D || (depth == 1));
|
| }
|
|
|
| -void TextureManager::SetTarget(Texture* texture, GLenum target) {
|
| - DCHECK(texture);
|
| - if (!texture->CanRender(feature_info_)) {
|
| - DCHECK_NE(0, num_unrenderable_textures_);
|
| - --num_unrenderable_textures_;
|
| - }
|
| - texture->SetTarget(feature_info_, target, MaxLevelsForTarget(target));
|
| - if (!texture->CanRender(feature_info_)) {
|
| - ++num_unrenderable_textures_;
|
| - }
|
| +void TextureManager::SetTarget(TextureRef* ref, GLenum target) {
|
| + DCHECK(ref);
|
| + ref->texture()->SetTarget(feature_info_, target, MaxLevelsForTarget(target));
|
| }
|
|
|
| -void TextureManager::SetStreamTexture(Texture* texture, bool stream_texture) {
|
| - DCHECK(texture);
|
| - if (!texture->CanRender(feature_info_)) {
|
| - DCHECK_NE(0, num_unrenderable_textures_);
|
| - --num_unrenderable_textures_;
|
| - }
|
| - texture->SetStreamTexture(stream_texture);
|
| - if (!texture->CanRender(feature_info_)) {
|
| - ++num_unrenderable_textures_;
|
| - }
|
| +void TextureManager::SetStreamTexture(TextureRef* ref, bool stream_texture) {
|
| + DCHECK(ref);
|
| + ref->texture()->SetStreamTexture(stream_texture);
|
| }
|
|
|
| -void TextureManager::SetLevelCleared(Texture* texture,
|
| +void TextureManager::SetLevelCleared(TextureRef* ref,
|
| GLenum target,
|
| GLint level,
|
| bool cleared) {
|
| - DCHECK(texture);
|
| - if (!texture->SafeToRenderFrom()) {
|
| - DCHECK_NE(0, num_unsafe_textures_);
|
| - --num_unsafe_textures_;
|
| - }
|
| - num_uncleared_mips_ -= texture->num_uncleared_mips();
|
| - DCHECK_GE(num_uncleared_mips_, 0);
|
| - texture->SetLevelCleared(target, level, cleared);
|
| - num_uncleared_mips_ += texture->num_uncleared_mips();
|
| - if (!texture->SafeToRenderFrom()) {
|
| - ++num_unsafe_textures_;
|
| - }
|
| + DCHECK(ref);
|
| + ref->texture()->SetLevelCleared(target, level, cleared);
|
| }
|
|
|
| bool TextureManager::ClearRenderableLevels(
|
| - GLES2Decoder* decoder,Texture* texture) {
|
| - DCHECK(texture);
|
| - if (texture->SafeToRenderFrom()) {
|
| - return true;
|
| - }
|
| - DCHECK_NE(0, num_unsafe_textures_);
|
| - --num_unsafe_textures_;
|
| - num_uncleared_mips_ -= texture->num_uncleared_mips();
|
| - DCHECK_GE(num_uncleared_mips_, 0);
|
| - bool result = texture->ClearRenderableLevels(decoder);
|
| - num_uncleared_mips_ += texture->num_uncleared_mips();
|
| - if (!texture->SafeToRenderFrom()) {
|
| - ++num_unsafe_textures_;
|
| - }
|
| - return result;
|
| + GLES2Decoder* decoder, TextureRef* ref) {
|
| + DCHECK(ref);
|
| + return ref->texture()->ClearRenderableLevels(decoder);
|
| }
|
|
|
| bool TextureManager::ClearTextureLevel(
|
| - GLES2Decoder* decoder,Texture* texture,
|
| + GLES2Decoder* decoder, TextureRef* ref,
|
| GLenum target, GLint level) {
|
| - DCHECK(texture);
|
| + DCHECK(ref);
|
| + Texture* texture = ref->texture();
|
| if (texture->num_uncleared_mips() == 0) {
|
| return true;
|
| }
|
| - num_uncleared_mips_ -= texture->num_uncleared_mips();
|
| - DCHECK_GE(num_uncleared_mips_, 0);
|
| - if (!texture->SafeToRenderFrom()) {
|
| - DCHECK_NE(0, num_unsafe_textures_);
|
| - --num_unsafe_textures_;
|
| - }
|
| bool result = texture->ClearLevel(decoder, target, level);
|
| texture->UpdateCleared();
|
| - num_uncleared_mips_ += texture->num_uncleared_mips();
|
| - if (!texture->SafeToRenderFrom()) {
|
| - ++num_unsafe_textures_;
|
| - }
|
| return result;
|
| }
|
|
|
| void TextureManager::SetLevelInfo(
|
| - Texture* texture,
|
| + TextureRef* ref,
|
| GLenum target,
|
| GLint level,
|
| GLenum internal_format,
|
| @@ -940,34 +989,19 @@ void TextureManager::SetLevelInfo(
|
| GLenum format,
|
| GLenum type,
|
| bool cleared) {
|
| - DCHECK(texture);
|
| - if (!texture->CanRender(feature_info_)) {
|
| - DCHECK_NE(0, num_unrenderable_textures_);
|
| - --num_unrenderable_textures_;
|
| - }
|
| - if (!texture->SafeToRenderFrom()) {
|
| - DCHECK_NE(0, num_unsafe_textures_);
|
| - --num_unsafe_textures_;
|
| - }
|
| - num_uncleared_mips_ -= texture->num_uncleared_mips();
|
| - DCHECK_GE(num_uncleared_mips_, 0);
|
| + DCHECK(ref);
|
| + Texture* texture = ref->texture();
|
|
|
| - GetMemTracker(texture->pool_)->TrackMemFree(texture->estimated_size());
|
| + texture->GetMemTracker()->TrackMemFree(texture->estimated_size());
|
| texture->SetLevelInfo(
|
| feature_info_, target, level, internal_format, width, height, depth,
|
| border, format, type, cleared);
|
| - GetMemTracker(texture->pool_)->TrackMemAlloc(texture->estimated_size());
|
| -
|
| - num_uncleared_mips_ += texture->num_uncleared_mips();
|
| - if (!texture->CanRender(feature_info_)) {
|
| - ++num_unrenderable_textures_;
|
| - }
|
| - if (!texture->SafeToRenderFrom()) {
|
| - ++num_unsafe_textures_;
|
| - }
|
| + texture->GetMemTracker()->TrackMemAlloc(texture->estimated_size());
|
| }
|
|
|
| -TextureDefinition* TextureManager::Save(Texture* texture) {
|
| +TextureDefinition* TextureManager::Save(TextureRef* ref) {
|
| + DCHECK(ref);
|
| + Texture* texture = ref->texture();
|
| DCHECK(texture->owned_);
|
|
|
| if (texture->IsAttachedToFramebuffer())
|
| @@ -993,7 +1027,7 @@ TextureDefinition* TextureManager::Save(Texture* texture) {
|
| level_info.type,
|
| level_info.cleared));
|
|
|
| - SetLevelInfo(texture,
|
| + SetLevelInfo(ref,
|
| target,
|
| level,
|
| GL_RGBA,
|
| @@ -1032,8 +1066,10 @@ TextureDefinition* TextureManager::Save(Texture* texture) {
|
| bool TextureManager::Restore(
|
| const char* function_name,
|
| GLES2Decoder* decoder,
|
| - Texture* texture,
|
| + TextureRef* ref,
|
| TextureDefinition* definition) {
|
| + DCHECK(ref);
|
| + Texture* texture = ref->texture();
|
| DCHECK(texture->owned_);
|
|
|
| scoped_ptr<TextureDefinition> scoped_definition(definition);
|
| @@ -1061,7 +1097,7 @@ bool TextureManager::Restore(
|
| const TextureDefinition::LevelInfo& level_info =
|
| level <= new_max_level ? definition->level_infos()[face][level]
|
| : TextureDefinition::LevelInfo();
|
| - SetLevelInfo(texture,
|
| + SetLevelInfo(ref,
|
| target,
|
| level,
|
| level_info.internal_format,
|
| @@ -1081,19 +1117,18 @@ bool TextureManager::Restore(
|
| glBindTexture(texture->target(), texture->service_id());
|
| texture->SetImmutable(definition->immutable());
|
| texture->SetStreamTexture(definition->stream_texture());
|
| -
|
| ErrorState* error_state = decoder->GetErrorState();
|
| - SetParameter(function_name, error_state, texture, GL_TEXTURE_MIN_FILTER,
|
| + SetParameter(function_name, error_state, ref, GL_TEXTURE_MIN_FILTER,
|
| definition->min_filter());
|
| - SetParameter(function_name, error_state, texture, GL_TEXTURE_MAG_FILTER,
|
| + SetParameter(function_name, error_state, ref, GL_TEXTURE_MAG_FILTER,
|
| definition->mag_filter());
|
| - SetParameter(function_name, error_state, texture, GL_TEXTURE_WRAP_S,
|
| + SetParameter(function_name, error_state, ref, GL_TEXTURE_WRAP_S,
|
| definition->wrap_s());
|
| - SetParameter(function_name, error_state, texture, GL_TEXTURE_WRAP_T,
|
| + SetParameter(function_name, error_state, ref, GL_TEXTURE_WRAP_T,
|
| definition->wrap_t());
|
| if (feature_info_->validators()->texture_parameter.IsValid(
|
| GL_TEXTURE_USAGE_ANGLE)) {
|
| - SetParameter(function_name, error_state, texture, GL_TEXTURE_USAGE_ANGLE,
|
| + SetParameter(function_name, error_state, ref, GL_TEXTURE_USAGE_ANGLE,
|
| definition->usage());
|
| }
|
|
|
| @@ -1102,17 +1137,10 @@ bool TextureManager::Restore(
|
|
|
| void TextureManager::SetParameter(
|
| const char* function_name, ErrorState* error_state,
|
| - Texture* texture, GLenum pname, GLint param) {
|
| + TextureRef* ref, GLenum pname, GLint param) {
|
| DCHECK(error_state);
|
| - DCHECK(texture);
|
| - if (!texture->CanRender(feature_info_)) {
|
| - DCHECK_NE(0, num_unrenderable_textures_);
|
| - --num_unrenderable_textures_;
|
| - }
|
| - if (!texture->SafeToRenderFrom()) {
|
| - DCHECK_NE(0, num_unsafe_textures_);
|
| - --num_unsafe_textures_;
|
| - }
|
| + DCHECK(ref);
|
| + Texture* texture = ref->texture();
|
| GLenum result = texture->SetParameter(feature_info_, pname, param);
|
| if (result != GL_NO_ERROR) {
|
| if (result == GL_INVALID_ENUM) {
|
| @@ -1129,59 +1157,28 @@ void TextureManager::SetParameter(
|
| glTexParameteri(texture->target(), pname, param);
|
| }
|
| }
|
| -
|
| - if (!texture->CanRender(feature_info_)) {
|
| - ++num_unrenderable_textures_;
|
| - }
|
| - if (!texture->SafeToRenderFrom()) {
|
| - ++num_unsafe_textures_;
|
| - }
|
| }
|
|
|
| -bool TextureManager::MarkMipmapsGenerated(Texture* texture) {
|
| - DCHECK(texture);
|
| - if (!texture->CanRender(feature_info_)) {
|
| - DCHECK_NE(0, num_unrenderable_textures_);
|
| - --num_unrenderable_textures_;
|
| - }
|
| - if (!texture->SafeToRenderFrom()) {
|
| - DCHECK_NE(0, num_unsafe_textures_);
|
| - --num_unsafe_textures_;
|
| - }
|
| - num_uncleared_mips_ -= texture->num_uncleared_mips();
|
| - DCHECK_GE(num_uncleared_mips_, 0);
|
| - GetMemTracker(texture->pool_)->TrackMemFree(texture->estimated_size());
|
| +bool TextureManager::MarkMipmapsGenerated(TextureRef* ref) {
|
| + DCHECK(ref);
|
| + Texture* texture = ref->texture();
|
| + texture->GetMemTracker()->TrackMemFree(texture->estimated_size());
|
| bool result = texture->MarkMipmapsGenerated(feature_info_);
|
| - GetMemTracker(texture->pool_)->TrackMemAlloc(texture->estimated_size());
|
| -
|
| - num_uncleared_mips_ += texture->num_uncleared_mips();
|
| - if (!texture->CanRender(feature_info_)) {
|
| - ++num_unrenderable_textures_;
|
| - }
|
| - if (!texture->SafeToRenderFrom()) {
|
| - ++num_unsafe_textures_;
|
| - }
|
| + texture->GetMemTracker()->TrackMemAlloc(texture->estimated_size());
|
| return result;
|
| }
|
|
|
| -Texture* TextureManager::CreateTexture(
|
| +TextureRef* TextureManager::CreateTexture(
|
| GLuint client_id, GLuint service_id) {
|
| DCHECK_NE(0u, service_id);
|
| - scoped_refptr<Texture> texture(new Texture(this, service_id));
|
| + scoped_refptr<TextureRef> ref(TextureRef::Create(this, service_id));
|
| std::pair<TextureMap::iterator, bool> result =
|
| - textures_.insert(std::make_pair(client_id, texture));
|
| + textures_.insert(std::make_pair(client_id, ref));
|
| DCHECK(result.second);
|
| - if (!texture->CanRender(feature_info_)) {
|
| - ++num_unrenderable_textures_;
|
| - }
|
| - if (!texture->SafeToRenderFrom()) {
|
| - ++num_unsafe_textures_;
|
| - }
|
| - num_uncleared_mips_ += texture->num_uncleared_mips();
|
| - return texture.get();
|
| + return ref.get();
|
| }
|
|
|
| -Texture* TextureManager::GetTexture(
|
| +TextureRef* TextureManager::GetTexture(
|
| GLuint client_id) const {
|
| TextureMap::const_iterator it = textures_.find(client_id);
|
| return it != textures_.end() ? it->second : NULL;
|
| @@ -1190,17 +1187,22 @@ Texture* TextureManager::GetTexture(
|
| void TextureManager::RemoveTexture(GLuint client_id) {
|
| TextureMap::iterator it = textures_.find(client_id);
|
| if (it != textures_.end()) {
|
| - Texture* texture = it->second;
|
| - texture->MarkAsDeleted();
|
| textures_.erase(it);
|
| }
|
| }
|
|
|
| -void TextureManager::StartTracking(Texture* /* texture */) {
|
| +void TextureManager::StartTracking(TextureRef* ref) {
|
| + Texture* texture = ref->texture();
|
| ++texture_count_;
|
| + num_uncleared_mips_ += texture->num_uncleared_mips();
|
| + if (!texture->SafeToRenderFrom())
|
| + ++num_unsafe_textures_;
|
| + if (!texture->CanRender(feature_info_))
|
| + ++num_unrenderable_textures_;
|
| }
|
|
|
| -void TextureManager::StopTracking(Texture* texture) {
|
| +void TextureManager::StopTracking(TextureRef* ref) {
|
| + Texture* texture = ref->texture();
|
| --texture_count_;
|
| if (!texture->CanRender(feature_info_)) {
|
| DCHECK_NE(0, num_unrenderable_textures_);
|
| @@ -1212,7 +1214,6 @@ void TextureManager::StopTracking(Texture* texture) {
|
| }
|
| num_uncleared_mips_ -= texture->num_uncleared_mips();
|
| DCHECK_GE(num_uncleared_mips_, 0);
|
| - GetMemTracker(texture->pool_)->TrackMemFree(texture->estimated_size());
|
| }
|
|
|
| MemoryTypeTracker* TextureManager::GetMemTracker(GLenum tracking_pool) {
|
| @@ -1234,7 +1235,7 @@ bool TextureManager::GetClientId(GLuint service_id, GLuint* client_id) const {
|
| // This doesn't need to be fast. It's only used during slow queries.
|
| for (TextureMap::const_iterator it = textures_.begin();
|
| it != textures_.end(); ++it) {
|
| - if (it->second->service_id() == service_id) {
|
| + if (it->second->texture()->service_id() == service_id) {
|
| *client_id = it->first;
|
| return true;
|
| }
|
| @@ -1248,34 +1249,51 @@ GLsizei TextureManager::ComputeMipMapCount(
|
| }
|
|
|
| void TextureManager::SetLevelImage(
|
| - Texture* texture,
|
| + TextureRef* ref,
|
| GLenum target,
|
| GLint level,
|
| gfx::GLImage* image) {
|
| - DCHECK(texture);
|
| - if (!texture->CanRender(feature_info_)) {
|
| - DCHECK_NE(0, num_unrenderable_textures_);
|
| - --num_unrenderable_textures_;
|
| - }
|
| - if (!texture->SafeToRenderFrom()) {
|
| - DCHECK_NE(0, num_unsafe_textures_);
|
| - --num_unsafe_textures_;
|
| - }
|
| - texture->SetLevelImage(feature_info_, target, level, image);
|
| - if (!texture->CanRender(feature_info_)) {
|
| - ++num_unrenderable_textures_;
|
| - }
|
| - if (!texture->SafeToRenderFrom()) {
|
| - ++num_unsafe_textures_;
|
| - }
|
| + DCHECK(ref);
|
| + ref->texture()->SetLevelImage(feature_info_, target, level, image);
|
| }
|
|
|
| void TextureManager::AddToSignature(
|
| - Texture* texture,
|
| + TextureRef* ref,
|
| GLenum target,
|
| GLint level,
|
| std::string* signature) const {
|
| - texture->AddToSignature(feature_info_.get(), target, level, signature);
|
| + ref->texture()->AddToSignature(feature_info_.get(), target, level, signature);
|
| +}
|
| +
|
| +void TextureManager::UpdateSafeToRenderFrom(int delta) {
|
| + num_unsafe_textures_ += delta;
|
| + DCHECK_GE(num_unsafe_textures_, 0);
|
| +}
|
| +
|
| +void TextureManager::UpdateUnclearedMips(int delta) {
|
| + num_uncleared_mips_ += 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::IncFramebufferStateChangeCount() {
|
| + if (framebuffer_manager_)
|
| + framebuffer_manager_->IncFramebufferStateChangeCount();
|
| +
|
| }
|
|
|
| } // namespace gles2
|
|
|