Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: gpu/command_buffer/service/texture_manager.cc

Issue 1154053002: gpu: Use a rectangle to keep track of the cleared area of each texture level. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: v2 Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "gpu/command_buffer/service/texture_manager.h" 5 #include "gpu/command_buffer/service/texture_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 destruction_observers_[i]->OnTextureManagerDestroying(this); 274 destruction_observers_[i]->OnTextureManagerDestroying(this);
275 275
276 DCHECK(textures_.empty()); 276 DCHECK(textures_.empty());
277 277
278 // If this triggers, that means something is keeping a reference to 278 // If this triggers, that means something is keeping a reference to
279 // a Texture belonging to this. 279 // a Texture belonging to this.
280 CHECK_EQ(texture_count_, 0u); 280 CHECK_EQ(texture_count_, 0u);
281 281
282 DCHECK_EQ(0, num_unrenderable_textures_); 282 DCHECK_EQ(0, num_unrenderable_textures_);
283 DCHECK_EQ(0, num_unsafe_textures_); 283 DCHECK_EQ(0, num_unsafe_textures_);
284 DCHECK_EQ(0, num_uncleared_mips_);
285 DCHECK_EQ(0, num_images_); 284 DCHECK_EQ(0, num_images_);
286 } 285 }
287 286
288 void TextureManager::Destroy(bool have_context) { 287 void TextureManager::Destroy(bool have_context) {
289 have_context_ = have_context; 288 have_context_ = have_context;
290 textures_.clear(); 289 textures_.clear();
291 for (int ii = 0; ii < kNumDefaultTextures; ++ii) { 290 for (int ii = 0; ii < kNumDefaultTextures; ++ii) {
292 default_textures_[ii] = NULL; 291 default_textures_[ii] = NULL;
293 } 292 }
294 293
295 if (have_context) { 294 if (have_context) {
296 glDeleteTextures(arraysize(black_texture_ids_), black_texture_ids_); 295 glDeleteTextures(arraysize(black_texture_ids_), black_texture_ids_);
297 } 296 }
298 297
299 DCHECK_EQ(0u, memory_tracker_managed_->GetMemRepresented()); 298 DCHECK_EQ(0u, memory_tracker_managed_->GetMemRepresented());
300 DCHECK_EQ(0u, memory_tracker_unmanaged_->GetMemRepresented()); 299 DCHECK_EQ(0u, memory_tracker_unmanaged_->GetMemRepresented());
301 } 300 }
302 301
303 Texture::Texture(GLuint service_id) 302 Texture::Texture(GLuint service_id)
304 : mailbox_manager_(NULL), 303 : mailbox_manager_(NULL),
305 memory_tracking_ref_(NULL), 304 memory_tracking_ref_(NULL),
306 service_id_(service_id), 305 service_id_(service_id),
307 cleared_(true), 306 cleared_(true),
308 num_uncleared_mips_(0),
309 num_npot_faces_(0), 307 num_npot_faces_(0),
310 target_(0), 308 target_(0),
311 min_filter_(GL_NEAREST_MIPMAP_LINEAR), 309 min_filter_(GL_NEAREST_MIPMAP_LINEAR),
312 mag_filter_(GL_LINEAR), 310 mag_filter_(GL_LINEAR),
313 wrap_r_(GL_REPEAT), 311 wrap_r_(GL_REPEAT),
314 wrap_s_(GL_REPEAT), 312 wrap_s_(GL_REPEAT),
315 wrap_t_(GL_REPEAT), 313 wrap_t_(GL_REPEAT),
316 usage_(GL_NONE), 314 usage_(GL_NONE),
317 pool_(GL_TEXTURE_POOL_UNMANAGED_CHROMIUM), 315 pool_(GL_TEXTURE_POOL_UNMANAGED_CHROMIUM),
318 compare_func_(GL_LEQUAL), 316 compare_func_(GL_LEQUAL),
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 GetMemTracker()->TrackMemAlloc(estimated_size()); 370 GetMemTracker()->TrackMemAlloc(estimated_size());
373 } 371 }
374 } 372 }
375 373
376 MemoryTypeTracker* Texture::GetMemTracker() { 374 MemoryTypeTracker* Texture::GetMemTracker() {
377 DCHECK(memory_tracking_ref_); 375 DCHECK(memory_tracking_ref_);
378 return memory_tracking_ref_->manager()->GetMemTracker(pool_); 376 return memory_tracking_ref_->manager()->GetMemTracker(pool_);
379 } 377 }
380 378
381 Texture::LevelInfo::LevelInfo() 379 Texture::LevelInfo::LevelInfo()
382 : cleared(true), 380 : target(0),
383 target(0),
384 level(-1), 381 level(-1),
385 internal_format(0), 382 internal_format(0),
386 width(0), 383 width(0),
387 height(0), 384 height(0),
388 depth(0), 385 depth(0),
389 border(0), 386 border(0),
390 format(0), 387 format(0),
391 type(0), 388 type(0),
392 estimated_size(0) { 389 estimated_size(0) {
393 } 390 }
394 391
395 Texture::LevelInfo::LevelInfo(const LevelInfo& rhs) 392 Texture::LevelInfo::LevelInfo(const LevelInfo& rhs)
396 : cleared(rhs.cleared), 393 : cleared_rect(rhs.cleared_rect),
397 target(rhs.target), 394 target(rhs.target),
398 level(rhs.level), 395 level(rhs.level),
399 internal_format(rhs.internal_format), 396 internal_format(rhs.internal_format),
400 width(rhs.width), 397 width(rhs.width),
401 height(rhs.height), 398 height(rhs.height),
402 depth(rhs.depth), 399 depth(rhs.depth),
403 border(rhs.border), 400 border(rhs.border),
404 format(rhs.format), 401 format(rhs.format),
405 type(rhs.type), 402 type(rhs.type),
406 image(rhs.image), 403 image(rhs.image),
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 GLsizei height = level0_info.height; 530 GLsizei height = level0_info.height;
534 GLsizei depth = level0_info.depth; 531 GLsizei depth = level0_info.depth;
535 GLenum target = target_ == GL_TEXTURE_2D ? GL_TEXTURE_2D : 532 GLenum target = target_ == GL_TEXTURE_2D ? GL_TEXTURE_2D :
536 GLES2Util::IndexToGLFaceTarget(ii); 533 GLES2Util::IndexToGLFaceTarget(ii);
537 534
538 const GLsizei num_mips = face_info.num_mip_levels; 535 const GLsizei num_mips = face_info.num_mip_levels;
539 for (GLsizei level = 1; level < num_mips; ++level) { 536 for (GLsizei level = 1; level < num_mips; ++level) {
540 width = std::max(1, width >> 1); 537 width = std::max(1, width >> 1);
541 height = std::max(1, height >> 1); 538 height = std::max(1, height >> 1);
542 depth = std::max(1, depth >> 1); 539 depth = std::max(1, depth >> 1);
543 SetLevelInfo(feature_info, 540 SetLevelInfo(feature_info, target, level, level0_info.internal_format,
544 target, 541 width, height, depth, level0_info.border, level0_info.format,
545 level, 542 level0_info.type, gfx::Rect(width, height));
546 level0_info.internal_format,
547 width,
548 height,
549 depth,
550 level0_info.border,
551 level0_info.format,
552 level0_info.type,
553 true);
554 } 543 }
555 } 544 }
556 545
557 return true; 546 return true;
558 } 547 }
559 548
560 void Texture::SetTarget( 549 void Texture::SetTarget(
561 const FeatureInfo* feature_info, GLenum target, GLint max_levels) { 550 const FeatureInfo* feature_info, GLenum target, GLint max_levels) {
562 DCHECK_EQ(0u, target_); // you can only set this once. 551 DCHECK_EQ(0u, target_); // you can only set this once.
563 target_ = target; 552 target_ = target;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 complete &= (width == mip_width && 647 complete &= (width == mip_width &&
659 height == mip_height && 648 height == mip_height &&
660 depth == mip_depth && 649 depth == mip_depth &&
661 internal_format == level0_face.internal_format && 650 internal_format == level0_face.internal_format &&
662 format == level0_face.format && 651 format == level0_face.format &&
663 type == level0_face.type); 652 type == level0_face.type);
664 } 653 }
665 return complete; 654 return complete;
666 } 655 }
667 656
668 void Texture::SetLevelCleared(GLenum target, GLint level, bool cleared) { 657 void Texture::SetLevelClearedRect(GLenum target,
658 GLint level,
659 const gfx::Rect& cleared_rect) {
669 DCHECK_GE(level, 0); 660 DCHECK_GE(level, 0);
670 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); 661 size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
671 DCHECK_LT(static_cast<size_t>(face_index), 662 DCHECK_LT(static_cast<size_t>(face_index),
672 face_infos_.size()); 663 face_infos_.size());
673 DCHECK_LT(static_cast<size_t>(level), 664 DCHECK_LT(static_cast<size_t>(level),
674 face_infos_[face_index].level_infos.size()); 665 face_infos_[face_index].level_infos.size());
675 Texture::LevelInfo& info = 666 Texture::LevelInfo& info =
676 face_infos_[face_index].level_infos[level]; 667 face_infos_[face_index].level_infos[level];
677 UpdateMipCleared(&info, cleared); 668 info.cleared_rect = cleared_rect;
piman 2015/05/27 20:50:17 nit: could we have a DCHECK that cleared_rect only
reveman 2015/06/03 22:40:04 Done. By adding DCHECKs to the caller as we can't
678 UpdateCleared(); 669 UpdateSafeToRenderFrom();
679 } 670 }
680 671
681 void Texture::UpdateCleared() { 672 void Texture::SetLevelCleared(GLenum target, GLint level, bool cleared) {
682 if (face_infos_.empty()) { 673 DCHECK_GE(level, 0);
683 return; 674 size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
675 DCHECK_LT(static_cast<size_t>(face_index), face_infos_.size());
676 DCHECK_LT(static_cast<size_t>(level),
677 face_infos_[face_index].level_infos.size());
678 Texture::LevelInfo& info = face_infos_[face_index].level_infos[level];
679 info.cleared_rect =
680 cleared ? gfx::Rect(info.width, info.height) : gfx::Rect();
681 UpdateSafeToRenderFrom();
682 }
683
684 void Texture::UpdateSafeToRenderFrom() {
685 bool cleared = true;
686 for (size_t ii = 0; ii < face_infos_.size(); ++ii) {
687 for (size_t jj = 0; jj < face_infos_[ii].level_infos.size(); ++jj) {
688 const Texture::LevelInfo& info = face_infos_[ii].level_infos[jj];
689 if (!info.cleared_rect.Contains(gfx::Rect(info.width, info.height))) {
690 cleared = false;
691 break;
692 }
693 }
684 } 694 }
piman 2015/05/27 20:50:17 I worry about the extra tracking cost here. This i
reveman 2015/06/03 22:40:04 Done. However, this is a bit more complicated than
685 695
686 const bool cleared = (num_uncleared_mips_ == 0);
687
688 // If texture is uncleared and is attached to a framebuffer,
689 // that framebuffer must be marked possibly incomplete.
690 if (!cleared && IsAttachedToFramebuffer()) {
691 IncAllFramebufferStateChangeCount();
692 }
693
694 UpdateSafeToRenderFrom(cleared);
695 }
696
697 void Texture::UpdateSafeToRenderFrom(bool cleared) {
698 if (cleared_ == cleared) 696 if (cleared_ == cleared)
699 return; 697 return;
700 cleared_ = cleared; 698 cleared_ = cleared;
701 int delta = cleared ? -1 : +1; 699 int delta = cleared ? -1 : +1;
702 for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it) 700 for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it)
703 (*it)->manager()->UpdateSafeToRenderFrom(delta); 701 (*it)->manager()->UpdateSafeToRenderFrom(delta);
704 }
705 702
706 void Texture::UpdateMipCleared(LevelInfo* info, bool cleared) { 703 // If texture is uncleared and is attached to a framebuffer,
707 if (info->cleared == cleared) 704 // that framebuffer must be marked possibly incomplete.
708 return; 705 if (!cleared && IsAttachedToFramebuffer())
709 info->cleared = cleared; 706 IncAllFramebufferStateChangeCount();
710 int delta = cleared ? -1 : +1;
711 num_uncleared_mips_ += delta;
712 for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it)
713 (*it)->manager()->UpdateUnclearedMips(delta);
714 } 707 }
715 708
716 void Texture::UpdateCanRenderCondition() { 709 void Texture::UpdateCanRenderCondition() {
717 CanRenderCondition can_render_condition = GetCanRenderCondition(); 710 CanRenderCondition can_render_condition = GetCanRenderCondition();
718 if (can_render_condition_ == can_render_condition) 711 if (can_render_condition_ == can_render_condition)
719 return; 712 return;
720 for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it) 713 for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it)
721 (*it)->manager()->UpdateCanRenderCondition(can_render_condition_, 714 (*it)->manager()->UpdateCanRenderCondition(can_render_condition_,
722 can_render_condition); 715 can_render_condition);
723 can_render_condition_ = can_render_condition; 716 can_render_condition_ = can_render_condition;
(...skipping 20 matching lines...) Expand all
744 int delta = has_images ? +1 : -1; 737 int delta = has_images ? +1 : -1;
745 for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it) 738 for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it)
746 (*it)->manager()->UpdateNumImages(delta); 739 (*it)->manager()->UpdateNumImages(delta);
747 } 740 }
748 741
749 void Texture::IncAllFramebufferStateChangeCount() { 742 void Texture::IncAllFramebufferStateChangeCount() {
750 for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it) 743 for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it)
751 (*it)->manager()->IncFramebufferStateChangeCount(); 744 (*it)->manager()->IncFramebufferStateChangeCount();
752 } 745 }
753 746
754 void Texture::SetLevelInfo( 747 void Texture::SetLevelInfo(const FeatureInfo* feature_info,
755 const FeatureInfo* feature_info, 748 GLenum target,
756 GLenum target, 749 GLint level,
757 GLint level, 750 GLenum internal_format,
758 GLenum internal_format, 751 GLsizei width,
759 GLsizei width, 752 GLsizei height,
760 GLsizei height, 753 GLsizei depth,
761 GLsizei depth, 754 GLint border,
762 GLint border, 755 GLenum format,
763 GLenum format, 756 GLenum type,
764 GLenum type, 757 const gfx::Rect& cleared_rect) {
765 bool cleared) {
766 DCHECK_GE(level, 0); 758 DCHECK_GE(level, 0);
767 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); 759 size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
768 DCHECK_LT(static_cast<size_t>(face_index), 760 DCHECK_LT(static_cast<size_t>(face_index),
769 face_infos_.size()); 761 face_infos_.size());
770 DCHECK_LT(static_cast<size_t>(level), 762 DCHECK_LT(static_cast<size_t>(level),
771 face_infos_[face_index].level_infos.size()); 763 face_infos_[face_index].level_infos.size());
772 DCHECK_GE(width, 0); 764 DCHECK_GE(width, 0);
773 DCHECK_GE(height, 0); 765 DCHECK_GE(height, 0);
774 DCHECK_GE(depth, 0); 766 DCHECK_GE(depth, 0);
775 Texture::LevelInfo& info = 767 Texture::LevelInfo& info =
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 info.border = border; 805 info.border = border;
814 info.format = format; 806 info.format = format;
815 info.type = type; 807 info.type = type;
816 info.image = 0; 808 info.image = 0;
817 809
818 estimated_size_ -= info.estimated_size; 810 estimated_size_ -= info.estimated_size;
819 GLES2Util::ComputeImageDataSizes( 811 GLES2Util::ComputeImageDataSizes(
820 width, height, 1, format, type, 4, &info.estimated_size, NULL, NULL); 812 width, height, 1, format, type, 4, &info.estimated_size, NULL, NULL);
821 estimated_size_ += info.estimated_size; 813 estimated_size_ += info.estimated_size;
822 814
823 UpdateMipCleared(&info, cleared); 815 info.cleared_rect = cleared_rect;
824 max_level_set_ = std::max(max_level_set_, level); 816 max_level_set_ = std::max(max_level_set_, level);
825 Update(feature_info); 817 Update(feature_info);
826 UpdateCleared(); 818 UpdateSafeToRenderFrom();
827 UpdateCanRenderCondition(); 819 UpdateCanRenderCondition();
828 UpdateHasImages(); 820 UpdateHasImages();
829 if (IsAttachedToFramebuffer()) { 821 if (IsAttachedToFramebuffer()) {
830 // TODO(gman): If textures tracked which framebuffers they were attached to 822 // TODO(gman): If textures tracked which framebuffers they were attached to
831 // we could just mark those framebuffers as not complete. 823 // we could just mark those framebuffers as not complete.
832 IncAllFramebufferStateChangeCount(); 824 IncAllFramebufferStateChangeCount();
833 } 825 }
834 } 826 }
835 827
836 bool Texture::ValidForTexture( 828 bool Texture::ValidForTexture(
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 if (!feature_info->validators()->texture_usage.IsValid(param)) { 985 if (!feature_info->validators()->texture_usage.IsValid(param)) {
994 return GL_INVALID_ENUM; 986 return GL_INVALID_ENUM;
995 } 987 }
996 usage_ = param; 988 usage_ = param;
997 break; 989 break;
998 default: 990 default:
999 NOTREACHED(); 991 NOTREACHED();
1000 return GL_INVALID_ENUM; 992 return GL_INVALID_ENUM;
1001 } 993 }
1002 Update(feature_info); 994 Update(feature_info);
1003 UpdateCleared(); 995 UpdateSafeToRenderFrom();
1004 UpdateCanRenderCondition(); 996 UpdateCanRenderCondition();
1005 return GL_NO_ERROR; 997 return GL_NO_ERROR;
1006 } 998 }
1007 999
1008 GLenum Texture::SetParameterf( 1000 GLenum Texture::SetParameterf(
1009 const FeatureInfo* feature_info, GLenum pname, GLfloat param) { 1001 const FeatureInfo* feature_info, GLenum pname, GLfloat param) {
1010 switch (pname) { 1002 switch (pname) {
1011 case GL_TEXTURE_MIN_FILTER: 1003 case GL_TEXTURE_MIN_FILTER:
1012 case GL_TEXTURE_MAG_FILTER: 1004 case GL_TEXTURE_MAG_FILTER:
1013 case GL_TEXTURE_POOL_CHROMIUM: 1005 case GL_TEXTURE_POOL_CHROMIUM:
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
1135 const Texture::FaceInfo& face_info = face_infos_[ii]; 1127 const Texture::FaceInfo& face_info = face_infos_[ii];
1136 for (GLint jj = 0; jj < face_info.num_mip_levels; ++jj) { 1128 for (GLint jj = 0; jj < face_info.num_mip_levels; ++jj) {
1137 const Texture::LevelInfo& info = face_info.level_infos[jj]; 1129 const Texture::LevelInfo& info = face_info.level_infos[jj];
1138 if (info.target != 0) { 1130 if (info.target != 0) {
1139 if (!ClearLevel(decoder, info.target, jj)) { 1131 if (!ClearLevel(decoder, info.target, jj)) {
1140 return false; 1132 return false;
1141 } 1133 }
1142 } 1134 }
1143 } 1135 }
1144 } 1136 }
1145 UpdateSafeToRenderFrom(true); 1137 UpdateSafeToRenderFrom();
1146 return true; 1138 return true;
1147 } 1139 }
1148 1140
1141 gfx::Rect Texture::GetLevelClearedRect(GLenum target, GLint level) const {
1142 size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
1143 if (face_index >= face_infos_.size() ||
1144 level >= static_cast<GLint>(face_infos_[face_index].level_infos.size())) {
1145 return gfx::Rect();
1146 }
1147
1148 const Texture::LevelInfo& info = face_infos_[face_index].level_infos[level];
1149
1150 return info.cleared_rect;
1151 }
1152
1149 bool Texture::IsLevelCleared(GLenum target, GLint level) const { 1153 bool Texture::IsLevelCleared(GLenum target, GLint level) const {
1150 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); 1154 size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
1151 if (face_index >= face_infos_.size() || 1155 if (face_index >= face_infos_.size() ||
1152 level >= static_cast<GLint>(face_infos_[face_index].level_infos.size())) { 1156 level >= static_cast<GLint>(face_infos_[face_index].level_infos.size())) {
1153 return true; 1157 return true;
1154 } 1158 }
1155 1159
1156 const Texture::LevelInfo& info = face_infos_[face_index].level_infos[level]; 1160 const Texture::LevelInfo& info = face_infos_[face_index].level_infos[level];
1157 1161
1158 return info.cleared; 1162 return info.cleared_rect.Contains(gfx::Rect(info.width, info.height));
1159 } 1163 }
1160 1164
1161 void Texture::InitTextureMaxAnisotropyIfNeeded(GLenum target) { 1165 void Texture::InitTextureMaxAnisotropyIfNeeded(GLenum target) {
1162 if (texture_max_anisotropy_initialized_) 1166 if (texture_max_anisotropy_initialized_)
1163 return; 1167 return;
1164 texture_max_anisotropy_initialized_ = true; 1168 texture_max_anisotropy_initialized_ = true;
1165 GLfloat params[] = { 1.0f }; 1169 GLfloat params[] = { 1.0f };
1166 glTexParameterfv(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, params); 1170 glTexParameterfv(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, params);
1167 } 1171 }
1168 1172
1169 bool Texture::ClearLevel( 1173 bool Texture::ClearLevel(
1170 GLES2Decoder* decoder, GLenum target, GLint level) { 1174 GLES2Decoder* decoder, GLenum target, GLint level) {
1171 DCHECK(decoder); 1175 DCHECK(decoder);
1172 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); 1176 size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
1173 if (face_index >= face_infos_.size() || 1177 if (face_index >= face_infos_.size() ||
1174 level >= static_cast<GLint>(face_infos_[face_index].level_infos.size())) { 1178 level >= static_cast<GLint>(face_infos_[face_index].level_infos.size())) {
1175 return true; 1179 return true;
1176 } 1180 }
1177 1181
1178 Texture::LevelInfo& info = face_infos_[face_index].level_infos[level]; 1182 Texture::LevelInfo& info = face_infos_[face_index].level_infos[level];
1179 1183
1180 DCHECK(target == info.target); 1184 DCHECK(target == info.target);
1181 1185
1182 if (info.target == 0 || 1186 if (info.target == 0 ||
1183 info.cleared || 1187 info.cleared_rect.Contains(gfx::Rect(info.width, info.height)) ||
1184 info.width == 0 || 1188 info.width == 0 || info.height == 0 || info.depth == 0) {
1185 info.height == 0 ||
1186 info.depth == 0) {
1187 return true; 1189 return true;
1188 } 1190 }
1189 1191
1190 // NOTE: It seems kind of gross to call back into the decoder for this 1192 // Clear all remaining sub regions.
1191 // but only the decoder knows all the state (like unpack_alignment_) that's 1193 const int x[] = {
1192 // needed to be able to call GL correctly. 1194 0, info.cleared_rect.x(), info.cleared_rect.right(), info.width};
1193 bool cleared = decoder->ClearLevel( 1195 const int y[] = {
1194 this, info.target, info.level, info.internal_format, info.format, 1196 0, info.cleared_rect.y(), info.cleared_rect.bottom(), info.height};
1195 info.type, info.width, info.height, immutable_); 1197
1196 UpdateMipCleared(&info, cleared); 1198 for (size_t j = 0; j < 3; ++j) {
1197 return info.cleared; 1199 for (size_t i = 0; i < 3; ++i) {
1200 // Center of nine patch is already cleared.
1201 if (j == 1 && i == 1)
1202 continue;
1203
1204 gfx::Rect rect(x[i], y[j], x[i + 1] - x[i], y[j + 1] - y[j]);
1205 if (rect.IsEmpty())
1206 continue;
1207
1208 // NOTE: It seems kind of gross to call back into the decoder for this
1209 // but only the decoder knows all the state (like unpack_alignment_)
1210 // that's needed to be able to call GL correctly.
1211 bool cleared = decoder->ClearLevel(this, info.target, info.level,
1212 info.format, info.type, rect.x(),
1213 rect.y(), rect.width(), rect.height());
1214 if (!cleared)
1215 return false;
1216 }
1217 }
1218
1219 info.cleared_rect = gfx::Rect(info.width, info.height);
1220 return true;
1198 } 1221 }
1199 1222
1200 void Texture::SetLevelImage( 1223 void Texture::SetLevelImage(
1201 const FeatureInfo* feature_info, 1224 const FeatureInfo* feature_info,
1202 GLenum target, 1225 GLenum target,
1203 GLint level, 1226 GLint level,
1204 gfx::GLImage* image) { 1227 gfx::GLImage* image) {
1205 DCHECK_GE(level, 0); 1228 DCHECK_GE(level, 0);
1206 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); 1229 size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
1207 DCHECK_LT(static_cast<size_t>(face_index), 1230 DCHECK_LT(static_cast<size_t>(face_index),
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1297 max_cube_map_texture_size, 1320 max_cube_map_texture_size,
1298 max_cube_map_texture_size)), 1321 max_cube_map_texture_size)),
1299 max_3d_levels_(ComputeMipMapCount(GL_TEXTURE_3D, 1322 max_3d_levels_(ComputeMipMapCount(GL_TEXTURE_3D,
1300 // Same as GL_TEXTURE_2D_ARRAY 1323 // Same as GL_TEXTURE_2D_ARRAY
1301 max_3d_texture_size, 1324 max_3d_texture_size,
1302 max_3d_texture_size, 1325 max_3d_texture_size,
1303 max_3d_texture_size)), 1326 max_3d_texture_size)),
1304 use_default_textures_(use_default_textures), 1327 use_default_textures_(use_default_textures),
1305 num_unrenderable_textures_(0), 1328 num_unrenderable_textures_(0),
1306 num_unsafe_textures_(0), 1329 num_unsafe_textures_(0),
1307 num_uncleared_mips_(0),
1308 num_images_(0), 1330 num_images_(0),
1309 texture_count_(0), 1331 texture_count_(0),
1310 have_context_(true) { 1332 have_context_(true) {
1311 for (int ii = 0; ii < kNumDefaultTextures; ++ii) { 1333 for (int ii = 0; ii < kNumDefaultTextures; ++ii) {
1312 black_texture_ids_[ii] = 0; 1334 black_texture_ids_[ii] = 0;
1313 } 1335 }
1314 } 1336 }
1315 1337
1316 bool TextureManager::Initialize() { 1338 bool TextureManager::Initialize() {
1317 // TODO(gman): The default textures have to be real textures, not the 0 1339 // TODO(gman): The default textures have to be real textures, not the 0
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1366 } 1388 }
1367 } 1389 }
1368 glBindTexture(target, 0); 1390 glBindTexture(target, 0);
1369 1391
1370 scoped_refptr<TextureRef> default_texture; 1392 scoped_refptr<TextureRef> default_texture;
1371 if (use_default_textures_) { 1393 if (use_default_textures_) {
1372 default_texture = TextureRef::Create(this, 0, ids[1]); 1394 default_texture = TextureRef::Create(this, 0, ids[1]);
1373 SetTarget(default_texture.get(), target); 1395 SetTarget(default_texture.get(), target);
1374 if (needs_faces) { 1396 if (needs_faces) {
1375 for (int ii = 0; ii < GLES2Util::kNumFaces; ++ii) { 1397 for (int ii = 0; ii < GLES2Util::kNumFaces; ++ii) {
1376 SetLevelInfo(default_texture.get(), 1398 SetLevelInfo(default_texture.get(), GLES2Util::IndexToGLFaceTarget(ii),
1377 GLES2Util::IndexToGLFaceTarget(ii), 1399 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1378 0, 1400 gfx::Rect(1, 1));
1379 GL_RGBA,
1380 1,
1381 1,
1382 1,
1383 0,
1384 GL_RGBA,
1385 GL_UNSIGNED_BYTE,
1386 true);
1387 } 1401 }
1388 } else { 1402 } else {
1389 if (needs_initialization) { 1403 if (needs_initialization) {
1390 SetLevelInfo(default_texture.get(), 1404 SetLevelInfo(default_texture.get(), GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1,
1391 GL_TEXTURE_2D, 1405 0, GL_RGBA, GL_UNSIGNED_BYTE, gfx::Rect(1, 1));
1392 0,
1393 GL_RGBA,
1394 1,
1395 1,
1396 1,
1397 0,
1398 GL_RGBA,
1399 GL_UNSIGNED_BYTE,
1400 true);
1401 } else { 1406 } else {
1402 SetLevelInfo(default_texture.get(), 1407 SetLevelInfo(default_texture.get(), GL_TEXTURE_EXTERNAL_OES, 0, GL_RGBA,
1403 GL_TEXTURE_EXTERNAL_OES, 1408 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, gfx::Rect(1, 1));
1404 0,
1405 GL_RGBA,
1406 1,
1407 1,
1408 1,
1409 0,
1410 GL_RGBA,
1411 GL_UNSIGNED_BYTE,
1412 true);
1413 } 1409 }
1414 } 1410 }
1415 } 1411 }
1416 1412
1417 *black_texture = ids[0]; 1413 *black_texture = ids[0];
1418 return default_texture; 1414 return default_texture;
1419 } 1415 }
1420 1416
1421 bool TextureManager::ValidForTarget( 1417 bool TextureManager::ValidForTarget(
1422 GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth) { 1418 GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth) {
(...skipping 13 matching lines...) Expand all
1436 (target != GL_TEXTURE_CUBE_MAP || (width == height && depth == 1)) && 1432 (target != GL_TEXTURE_CUBE_MAP || (width == height && depth == 1)) &&
1437 (target != GL_TEXTURE_2D || (depth == 1)); 1433 (target != GL_TEXTURE_2D || (depth == 1));
1438 } 1434 }
1439 1435
1440 void TextureManager::SetTarget(TextureRef* ref, GLenum target) { 1436 void TextureManager::SetTarget(TextureRef* ref, GLenum target) {
1441 DCHECK(ref); 1437 DCHECK(ref);
1442 ref->texture() 1438 ref->texture()
1443 ->SetTarget(feature_info_.get(), target, MaxLevelsForTarget(target)); 1439 ->SetTarget(feature_info_.get(), target, MaxLevelsForTarget(target));
1444 } 1440 }
1445 1441
1442 void TextureManager::SetLevelClearedRect(TextureRef* ref,
1443 GLenum target,
1444 GLint level,
1445 const gfx::Rect& cleared_rect) {
1446 DCHECK(ref);
1447 ref->texture()->SetLevelClearedRect(target, level, cleared_rect);
1448 }
1449
1446 void TextureManager::SetLevelCleared(TextureRef* ref, 1450 void TextureManager::SetLevelCleared(TextureRef* ref,
1447 GLenum target, 1451 GLenum target,
1448 GLint level, 1452 GLint level,
1449 bool cleared) { 1453 bool cleared) {
1450 DCHECK(ref); 1454 DCHECK(ref);
1451 ref->texture()->SetLevelCleared(target, level, cleared); 1455 ref->texture()->SetLevelCleared(target, level, cleared);
1452 } 1456 }
1453 1457
1454 bool TextureManager::ClearRenderableLevels( 1458 bool TextureManager::ClearRenderableLevels(
1455 GLES2Decoder* decoder, TextureRef* ref) { 1459 GLES2Decoder* decoder, TextureRef* ref) {
1456 DCHECK(ref); 1460 DCHECK(ref);
1457 return ref->texture()->ClearRenderableLevels(decoder); 1461 return ref->texture()->ClearRenderableLevels(decoder);
1458 } 1462 }
1459 1463
1460 bool TextureManager::ClearTextureLevel( 1464 bool TextureManager::ClearTextureLevel(
1461 GLES2Decoder* decoder, TextureRef* ref, 1465 GLES2Decoder* decoder, TextureRef* ref,
1462 GLenum target, GLint level) { 1466 GLenum target, GLint level) {
1463 DCHECK(ref); 1467 DCHECK(ref);
1464 Texture* texture = ref->texture(); 1468 Texture* texture = ref->texture();
1465 if (texture->num_uncleared_mips() == 0) { 1469 if (texture->SafeToRenderFrom()) {
1466 return true; 1470 return true;
1467 } 1471 }
1468 bool result = texture->ClearLevel(decoder, target, level); 1472 bool result = texture->ClearLevel(decoder, target, level);
1469 texture->UpdateCleared(); 1473 texture->UpdateSafeToRenderFrom();
1470 return result; 1474 return result;
1471 } 1475 }
1472 1476
1473 void TextureManager::SetLevelInfo( 1477 void TextureManager::SetLevelInfo(TextureRef* ref,
1474 TextureRef* ref, 1478 GLenum target,
1475 GLenum target, 1479 GLint level,
1476 GLint level, 1480 GLenum internal_format,
1477 GLenum internal_format, 1481 GLsizei width,
1478 GLsizei width, 1482 GLsizei height,
1479 GLsizei height, 1483 GLsizei depth,
1480 GLsizei depth, 1484 GLint border,
1481 GLint border, 1485 GLenum format,
1482 GLenum format, 1486 GLenum type,
1483 GLenum type, 1487 const gfx::Rect& cleared_rect) {
1484 bool cleared) { 1488 DCHECK(gfx::Rect(width, height).Contains(cleared_rect));
1485 DCHECK(ref); 1489 DCHECK(ref);
1486 Texture* texture = ref->texture(); 1490 Texture* texture = ref->texture();
1487 1491
1488 texture->GetMemTracker()->TrackMemFree(texture->estimated_size()); 1492 texture->GetMemTracker()->TrackMemFree(texture->estimated_size());
1489 texture->SetLevelInfo(feature_info_.get(), 1493 texture->SetLevelInfo(feature_info_.get(), target, level, internal_format,
1490 target, 1494 width, height, depth, border, format, type,
1491 level, 1495 cleared_rect);
1492 internal_format,
1493 width,
1494 height,
1495 depth,
1496 border,
1497 format,
1498 type,
1499 cleared);
1500 texture->GetMemTracker()->TrackMemAlloc(texture->estimated_size()); 1496 texture->GetMemTracker()->TrackMemAlloc(texture->estimated_size());
1501 } 1497 }
1502 1498
1503 Texture* TextureManager::Produce(TextureRef* ref) { 1499 Texture* TextureManager::Produce(TextureRef* ref) {
1504 DCHECK(ref); 1500 DCHECK(ref);
1505 return ref->texture(); 1501 return ref->texture();
1506 } 1502 }
1507 1503
1508 TextureRef* TextureManager::Consume( 1504 TextureRef* TextureManager::Consume(
1509 GLuint client_id, 1505 GLuint client_id,
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1593 TextureMap::iterator it = textures_.find(client_id); 1589 TextureMap::iterator it = textures_.find(client_id);
1594 if (it != textures_.end()) { 1590 if (it != textures_.end()) {
1595 it->second->reset_client_id(); 1591 it->second->reset_client_id();
1596 textures_.erase(it); 1592 textures_.erase(it);
1597 } 1593 }
1598 } 1594 }
1599 1595
1600 void TextureManager::StartTracking(TextureRef* ref) { 1596 void TextureManager::StartTracking(TextureRef* ref) {
1601 Texture* texture = ref->texture(); 1597 Texture* texture = ref->texture();
1602 ++texture_count_; 1598 ++texture_count_;
1603 num_uncleared_mips_ += texture->num_uncleared_mips();
1604 if (!texture->SafeToRenderFrom()) 1599 if (!texture->SafeToRenderFrom())
1605 ++num_unsafe_textures_; 1600 ++num_unsafe_textures_;
1606 if (!texture->CanRender(feature_info_.get())) 1601 if (!texture->CanRender(feature_info_.get()))
1607 ++num_unrenderable_textures_; 1602 ++num_unrenderable_textures_;
1608 if (texture->HasImages()) 1603 if (texture->HasImages())
1609 ++num_images_; 1604 ++num_images_;
1610 } 1605 }
1611 1606
1612 void TextureManager::StopTracking(TextureRef* ref) { 1607 void TextureManager::StopTracking(TextureRef* ref) {
1613 if (ref->num_observers()) { 1608 if (ref->num_observers()) {
(...skipping 11 matching lines...) Expand all
1625 --num_images_; 1620 --num_images_;
1626 } 1621 }
1627 if (!texture->CanRender(feature_info_.get())) { 1622 if (!texture->CanRender(feature_info_.get())) {
1628 DCHECK_NE(0, num_unrenderable_textures_); 1623 DCHECK_NE(0, num_unrenderable_textures_);
1629 --num_unrenderable_textures_; 1624 --num_unrenderable_textures_;
1630 } 1625 }
1631 if (!texture->SafeToRenderFrom()) { 1626 if (!texture->SafeToRenderFrom()) {
1632 DCHECK_NE(0, num_unsafe_textures_); 1627 DCHECK_NE(0, num_unsafe_textures_);
1633 --num_unsafe_textures_; 1628 --num_unsafe_textures_;
1634 } 1629 }
1635 num_uncleared_mips_ -= texture->num_uncleared_mips();
1636 DCHECK_GE(num_uncleared_mips_, 0);
1637 } 1630 }
1638 1631
1639 MemoryTypeTracker* TextureManager::GetMemTracker(GLenum tracking_pool) { 1632 MemoryTypeTracker* TextureManager::GetMemTracker(GLenum tracking_pool) {
1640 switch (tracking_pool) { 1633 switch (tracking_pool) {
1641 case GL_TEXTURE_POOL_MANAGED_CHROMIUM: 1634 case GL_TEXTURE_POOL_MANAGED_CHROMIUM:
1642 return memory_tracker_managed_.get(); 1635 return memory_tracker_managed_.get();
1643 break; 1636 break;
1644 case GL_TEXTURE_POOL_UNMANAGED_CHROMIUM: 1637 case GL_TEXTURE_POOL_UNMANAGED_CHROMIUM:
1645 return memory_tracker_unmanaged_.get(); 1638 return memory_tracker_unmanaged_.get();
1646 break; 1639 break;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1694 GLint level, 1687 GLint level,
1695 std::string* signature) const { 1688 std::string* signature) const {
1696 ref->texture()->AddToSignature(feature_info_.get(), target, level, signature); 1689 ref->texture()->AddToSignature(feature_info_.get(), target, level, signature);
1697 } 1690 }
1698 1691
1699 void TextureManager::UpdateSafeToRenderFrom(int delta) { 1692 void TextureManager::UpdateSafeToRenderFrom(int delta) {
1700 num_unsafe_textures_ += delta; 1693 num_unsafe_textures_ += delta;
1701 DCHECK_GE(num_unsafe_textures_, 0); 1694 DCHECK_GE(num_unsafe_textures_, 0);
1702 } 1695 }
1703 1696
1704 void TextureManager::UpdateUnclearedMips(int delta) {
1705 num_uncleared_mips_ += delta;
1706 DCHECK_GE(num_uncleared_mips_, 0);
1707 }
1708
1709 void TextureManager::UpdateCanRenderCondition( 1697 void TextureManager::UpdateCanRenderCondition(
1710 Texture::CanRenderCondition old_condition, 1698 Texture::CanRenderCondition old_condition,
1711 Texture::CanRenderCondition new_condition) { 1699 Texture::CanRenderCondition new_condition) {
1712 if (old_condition == Texture::CAN_RENDER_NEVER || 1700 if (old_condition == Texture::CAN_RENDER_NEVER ||
1713 (old_condition == Texture::CAN_RENDER_ONLY_IF_NPOT && 1701 (old_condition == Texture::CAN_RENDER_ONLY_IF_NPOT &&
1714 !feature_info_->feature_flags().npot_ok)) { 1702 !feature_info_->feature_flags().npot_ok)) {
1715 DCHECK_GT(num_unrenderable_textures_, 0); 1703 DCHECK_GT(num_unrenderable_textures_, 0);
1716 --num_unrenderable_textures_; 1704 --num_unrenderable_textures_;
1717 } 1705 }
1718 if (new_condition == Texture::CAN_RENDER_NEVER || 1706 if (new_condition == Texture::CAN_RENDER_NEVER ||
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
1933 GLenum tex_format = 0; 1921 GLenum tex_format = 0;
1934 bool level_is_same = 1922 bool level_is_same =
1935 texture->GetLevelSize( 1923 texture->GetLevelSize(
1936 args.target, args.level, &tex_width, &tex_height, nullptr) && 1924 args.target, args.level, &tex_width, &tex_height, nullptr) &&
1937 texture->GetLevelType(args.target, args.level, &tex_type, &tex_format) && 1925 texture->GetLevelType(args.target, args.level, &tex_type, &tex_format) &&
1938 args.width == tex_width && args.height == tex_height && 1926 args.width == tex_width && args.height == tex_height &&
1939 args.type == tex_type && args.format == tex_format; 1927 args.type == tex_type && args.format == tex_format;
1940 1928
1941 if (level_is_same && !args.pixels) { 1929 if (level_is_same && !args.pixels) {
1942 // Just set the level texture but mark the texture as uncleared. 1930 // Just set the level texture but mark the texture as uncleared.
1943 SetLevelInfo( 1931 SetLevelInfo(texture_ref, args.target, args.level, args.internal_format,
1944 texture_ref, 1932 args.width, args.height, 1, args.border, args.format,
1945 args.target, args.level, args.internal_format, args.width, args.height, 1933 args.type, gfx::Rect());
1946 1, args.border, args.format, args.type, false);
1947 texture_state->tex_image_2d_failed = false; 1934 texture_state->tex_image_2d_failed = false;
1948 return; 1935 return;
1949 } 1936 }
1950 1937
1951 if (texture->IsAttachedToFramebuffer()) { 1938 if (texture->IsAttachedToFramebuffer()) {
1952 framebuffer_state->clear_state_dirty = true; 1939 framebuffer_state->clear_state_dirty = true;
1953 } 1940 }
1954 1941
1955 if (texture_state->texsubimage2d_faster_than_teximage2d && 1942 if (texture_state->texsubimage2d_faster_than_teximage2d &&
1956 level_is_same && args.pixels) { 1943 level_is_same && args.pixels) {
(...skipping 10 matching lines...) Expand all
1967 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state, "glTexImage2D"); 1954 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state, "glTexImage2D");
1968 { 1955 {
1969 ScopedTextureUploadTimer timer(texture_state); 1956 ScopedTextureUploadTimer timer(texture_state);
1970 glTexImage2D( 1957 glTexImage2D(
1971 args.target, args.level, args.internal_format, args.width, args.height, 1958 args.target, args.level, args.internal_format, args.width, args.height,
1972 args.border, AdjustTexFormat(args.format), args.type, args.pixels); 1959 args.border, AdjustTexFormat(args.format), args.type, args.pixels);
1973 } 1960 }
1974 GLenum error = ERRORSTATE_PEEK_GL_ERROR(error_state, "glTexImage2D"); 1961 GLenum error = ERRORSTATE_PEEK_GL_ERROR(error_state, "glTexImage2D");
1975 if (error == GL_NO_ERROR) { 1962 if (error == GL_NO_ERROR) {
1976 SetLevelInfo( 1963 SetLevelInfo(
1977 texture_ref, 1964 texture_ref, args.target, args.level, args.internal_format, args.width,
1978 args.target, args.level, args.internal_format, args.width, args.height, 1965 args.height, 1, args.border, args.format, args.type,
1979 1, args.border, args.format, args.type, args.pixels != NULL); 1966 args.pixels != NULL ? gfx::Rect(args.width, args.height) : gfx::Rect());
1980 texture_state->tex_image_2d_failed = false; 1967 texture_state->tex_image_2d_failed = false;
1981 } 1968 }
1982 } 1969 }
1983 1970
1984 ScopedTextureUploadTimer::ScopedTextureUploadTimer( 1971 ScopedTextureUploadTimer::ScopedTextureUploadTimer(
1985 DecoderTextureState* texture_state) 1972 DecoderTextureState* texture_state)
1986 : texture_state_(texture_state), 1973 : texture_state_(texture_state),
1987 begin_time_(base::TimeTicks::Now()) { 1974 begin_time_(base::TimeTicks::Now()) {
1988 } 1975 }
1989 1976
1990 ScopedTextureUploadTimer::~ScopedTextureUploadTimer() { 1977 ScopedTextureUploadTimer::~ScopedTextureUploadTimer() {
1991 texture_state_->texture_upload_count++; 1978 texture_state_->texture_upload_count++;
1992 texture_state_->total_texture_upload_time += 1979 texture_state_->total_texture_upload_time +=
1993 base::TimeTicks::Now() - begin_time_; 1980 base::TimeTicks::Now() - begin_time_;
1994 } 1981 }
1995 1982
1996 } // namespace gles2 1983 } // namespace gles2
1997 } // namespace gpu 1984 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/texture_manager.h ('k') | gpu/command_buffer/service/texture_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698