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

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

Issue 1412883002: Fix WebGL 2 texture renderability check. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: working Created 5 years, 1 month 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 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 } 418 }
419 419
420 Texture::FaceInfo::~FaceInfo() { 420 Texture::FaceInfo::~FaceInfo() {
421 } 421 }
422 422
423 Texture::CanRenderCondition Texture::GetCanRenderCondition() const { 423 Texture::CanRenderCondition Texture::GetCanRenderCondition() const {
424 if (target_ == 0) 424 if (target_ == 0)
425 return CAN_RENDER_ALWAYS; 425 return CAN_RENDER_ALWAYS;
426 426
427 if (target_ != GL_TEXTURE_EXTERNAL_OES) { 427 if (target_ != GL_TEXTURE_EXTERNAL_OES) {
428 if (face_infos_.empty()) { 428 if (face_infos_.empty() ||
429 static_cast<size_t>(base_level_) >= face_infos_[0].level_infos.size()) {
429 return CAN_RENDER_NEVER; 430 return CAN_RENDER_NEVER;
430 } 431 }
431 432 const Texture::LevelInfo& first_face =
432 const Texture::LevelInfo& first_face = face_infos_[0].level_infos[0]; 433 face_infos_[0].level_infos[base_level_];
433 if (first_face.width == 0 || 434 if (first_face.width == 0 ||
434 first_face.height == 0 || 435 first_face.height == 0 ||
435 first_face.depth == 0) { 436 first_face.depth == 0) {
436 return CAN_RENDER_NEVER; 437 return CAN_RENDER_NEVER;
437 } 438 }
438 } 439 }
439 440
440 bool needs_mips = NeedsMips(); 441 bool needs_mips = NeedsMips();
441 if (needs_mips) { 442 if (needs_mips) {
442 if (!texture_complete()) 443 if (!texture_complete())
(...skipping 29 matching lines...) Expand all
472 return feature_info->feature_flags().npot_ok; 473 return feature_info->feature_flags().npot_ok;
473 } 474 }
474 475
475 void Texture::AddToSignature( 476 void Texture::AddToSignature(
476 const FeatureInfo* feature_info, 477 const FeatureInfo* feature_info,
477 GLenum target, 478 GLenum target,
478 GLint level, 479 GLint level,
479 std::string* signature) const { 480 std::string* signature) const {
480 DCHECK(feature_info); 481 DCHECK(feature_info);
481 DCHECK(signature); 482 DCHECK(signature);
482 DCHECK_GE(level, 0); 483 DCHECK_GE(level, 0);
qiankun 2015/10/22 06:06:08 We should check for level >= base_level_ at here a
Zhenyao Mo 2015/10/26 21:05:24 Not really. You can specify a tex level for frame
483 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); 484 size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
484 DCHECK_LT(static_cast<size_t>(face_index), 485 DCHECK_LT(static_cast<size_t>(face_index),
485 face_infos_.size()); 486 face_infos_.size());
486 DCHECK_LT(static_cast<size_t>(level), 487 DCHECK_LT(static_cast<size_t>(level),
487 face_infos_[face_index].level_infos.size()); 488 face_infos_[face_index].level_infos.size());
488 489
489 const Texture::LevelInfo& info = 490 const Texture::LevelInfo& info =
490 face_infos_[face_index].level_infos[level]; 491 face_infos_[face_index].level_infos[level];
491 492
492 TextureSignature signature_data(target, 493 TextureSignature signature_data(target,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 mailbox_manager_ = mailbox_manager; 526 mailbox_manager_ = mailbox_manager;
526 } 527 }
527 528
528 bool Texture::MarkMipmapsGenerated( 529 bool Texture::MarkMipmapsGenerated(
529 const FeatureInfo* feature_info) { 530 const FeatureInfo* feature_info) {
530 if (!CanGenerateMipmaps(feature_info)) { 531 if (!CanGenerateMipmaps(feature_info)) {
531 return false; 532 return false;
532 } 533 }
533 for (size_t ii = 0; ii < face_infos_.size(); ++ii) { 534 for (size_t ii = 0; ii < face_infos_.size(); ++ii) {
534 const Texture::FaceInfo& face_info = face_infos_[ii]; 535 const Texture::FaceInfo& face_info = face_infos_[ii];
535 const Texture::LevelInfo& level0_info = face_info.level_infos[0]; 536 const Texture::LevelInfo& level0_info = face_info.level_infos[base_level_];
536 GLsizei width = level0_info.width; 537 GLsizei width = level0_info.width;
537 GLsizei height = level0_info.height; 538 GLsizei height = level0_info.height;
538 GLsizei depth = level0_info.depth; 539 GLsizei depth = level0_info.depth;
539 GLenum target = target_ == GL_TEXTURE_2D ? GL_TEXTURE_2D : 540 GLenum target = target_ == GL_TEXTURE_2D ? GL_TEXTURE_2D :
540 GLES2Util::IndexToGLFaceTarget(ii); 541 GLES2Util::IndexToGLFaceTarget(ii);
541 542
542 const GLsizei num_mips = face_info.num_mip_levels; 543 const GLsizei num_mips = face_info.num_mip_levels;
543 for (GLsizei level = 1; level < num_mips; ++level) { 544 for (GLsizei level = base_level_ + 1;
545 level < base_level_ + num_mips; ++level) {
544 width = std::max(1, width >> 1); 546 width = std::max(1, width >> 1);
545 height = std::max(1, height >> 1); 547 height = std::max(1, height >> 1);
546 depth = std::max(1, depth >> 1); 548 depth = std::max(1, depth >> 1);
547 SetLevelInfo(feature_info, target, level, level0_info.internal_format, 549 SetLevelInfo(feature_info, target, level, level0_info.internal_format,
548 width, height, depth, level0_info.border, level0_info.format, 550 width, height, depth, level0_info.border, level0_info.format,
549 level0_info.type, gfx::Rect(width, height)); 551 level0_info.type, gfx::Rect(width, height));
550 } 552 }
551 } 553 }
552 554
553 return true; 555 return true;
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 if (face_index != 0) { 635 if (face_index != 0) {
634 complete &= (width == first_face.width && 636 complete &= (width == first_face.width &&
635 height == first_face.height && 637 height == first_face.height &&
636 internal_format == first_face.internal_format && 638 internal_format == first_face.internal_format &&
637 format == first_face.format && 639 format == first_face.format &&
638 type == first_face.type); 640 type == first_face.type);
639 } 641 }
640 return complete; 642 return complete;
641 } 643 }
642 644
643 bool Texture::TextureMipComplete(const Texture::LevelInfo& level0_face, 645 bool Texture::TextureMipComplete(const Texture::LevelInfo& base_level_face,
644 GLenum target, 646 GLenum target,
645 GLint level, 647 GLint level_diff,
646 GLenum internal_format, 648 GLenum internal_format,
647 GLsizei width, 649 GLsizei width,
648 GLsizei height, 650 GLsizei height,
649 GLsizei depth, 651 GLsizei depth,
650 GLenum format, 652 GLenum format,
651 GLenum type) { 653 GLenum type) {
652 bool complete = (target != 0); 654 bool complete = (target != 0);
653 if (level != 0) { 655 if (level_diff > 0) {
654 const GLsizei mip_width = std::max(1, level0_face.width >> level); 656 const GLsizei mip_width = std::max(1, base_level_face.width >> level_diff);
655 const GLsizei mip_height = std::max(1, level0_face.height >> level); 657 const GLsizei mip_height =
656 const GLsizei mip_depth = std::max(1, level0_face.depth >> level); 658 std::max(1, base_level_face.height >> level_diff);
659 const GLsizei mip_depth = std::max(1, base_level_face.depth >> level_diff);
657 660
658 complete &= (width == mip_width && 661 complete &= (width == mip_width &&
659 height == mip_height && 662 height == mip_height &&
660 depth == mip_depth && 663 depth == mip_depth &&
661 internal_format == level0_face.internal_format && 664 internal_format == base_level_face.internal_format &&
662 format == level0_face.format && 665 format == base_level_face.format &&
663 type == level0_face.type); 666 type == base_level_face.type);
664 } 667 }
665 return complete; 668 return complete;
666 } 669 }
667 670
668 void Texture::SetLevelClearedRect(GLenum target, 671 void Texture::SetLevelClearedRect(GLenum target,
669 GLint level, 672 GLint level,
670 const gfx::Rect& cleared_rect) { 673 const gfx::Rect& cleared_rect) {
671 DCHECK_GE(level, 0); 674 DCHECK_GE(level, 0);
672 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); 675 size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
673 DCHECK_LT(static_cast<size_t>(face_index), 676 DCHECK_LT(static_cast<size_t>(face_index),
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 int delta = has_images ? +1 : -1; 768 int delta = has_images ? +1 : -1;
766 for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it) 769 for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it)
767 (*it)->manager()->UpdateNumImages(delta); 770 (*it)->manager()->UpdateNumImages(delta);
768 } 771 }
769 772
770 void Texture::IncAllFramebufferStateChangeCount() { 773 void Texture::IncAllFramebufferStateChangeCount() {
771 for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it) 774 for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it)
772 (*it)->manager()->IncFramebufferStateChangeCount(); 775 (*it)->manager()->IncFramebufferStateChangeCount();
773 } 776 }
774 777
778 void Texture::UpdateBaseLevel(GLint base_level) {
779 if (base_level_ == base_level)
780 return;
781 base_level_ = base_level;
782
783 UpdateNumMipLevels();
784 }
785
786 void Texture::UpdateMaxLevel(GLint max_level) {
787 if (max_level_ == max_level)
788 return;
789 max_level_ = max_level;
790
791 UpdateNumMipLevels();
792 }
793
794 void Texture::UpdateNumMipLevels() {
795 if (face_infos_.empty())
796 return;
797
798 for (size_t ii = 0; ii < face_infos_.size(); ++ii) {
799 Texture::FaceInfo& face_info = face_infos_[ii];
800 if (static_cast<size_t>(base_level_) >= face_info.level_infos.size())
801 continue;
802 const Texture::LevelInfo& info = face_info.level_infos[base_level_];
803 face_info.num_mip_levels = std::min(
804 std::max(0, max_level_ - base_level_ + 1),
805 TextureManager::ComputeMipMapCount(
806 target_, info.width, info.height, info.depth));
807 }
808
809 // mipmap-completeness needs to be re-evaluated.
810 texture_mips_dirty_ = true;
811 }
812
775 void Texture::SetLevelInfo(const FeatureInfo* feature_info, 813 void Texture::SetLevelInfo(const FeatureInfo* feature_info,
776 GLenum target, 814 GLenum target,
777 GLint level, 815 GLint level,
778 GLenum internal_format, 816 GLenum internal_format,
779 GLsizei width, 817 GLsizei width,
780 GLsizei height, 818 GLsizei height,
781 GLsizei depth, 819 GLsizei depth,
782 GLint border, 820 GLint border,
783 GLenum format, 821 GLenum format,
784 GLenum type, 822 GLenum type,
(...skipping 13 matching lines...) Expand all
798 // Update counters only if any attributes have changed. Counters are 836 // Update counters only if any attributes have changed. Counters are
799 // comparisons between the old and new values so it must be done before any 837 // comparisons between the old and new values so it must be done before any
800 // assignment has been done to the LevelInfo. 838 // assignment has been done to the LevelInfo.
801 if (info.target != target || 839 if (info.target != target ||
802 info.internal_format != internal_format || 840 info.internal_format != internal_format ||
803 info.width != width || 841 info.width != width ||
804 info.height != height || 842 info.height != height ||
805 info.depth != depth || 843 info.depth != depth ||
806 info.format != format || 844 info.format != format ||
807 info.type != type) { 845 info.type != type) {
808 if (level == 0) { 846 if (level == base_level_) {
809 // Calculate the mip level count. 847 // Calculate the mip level count.
810 face_infos_[face_index].num_mip_levels = 848 face_infos_[face_index].num_mip_levels = std::min(
811 TextureManager::ComputeMipMapCount(target_, width, height, depth); 849 std::max(0, max_level_ - base_level_ + 1),
850 TextureManager::ComputeMipMapCount(target_, width, height, depth));
812 851
813 // Update NPOT face count for the first level. 852 // Update NPOT face count for the first level.
814 bool prev_npot = TextureIsNPOT(info.width, info.height, info.depth); 853 bool prev_npot = TextureIsNPOT(info.width, info.height, info.depth);
815 bool now_npot = TextureIsNPOT(width, height, depth); 854 bool now_npot = TextureIsNPOT(width, height, depth);
816 if (prev_npot != now_npot) 855 if (prev_npot != now_npot)
817 num_npot_faces_ += now_npot ? 1 : -1; 856 num_npot_faces_ += now_npot ? 1 : -1;
818 857
819 // Signify that level 0 has been changed, so they need to be reverified. 858 // Signify that level 0 has been changed, so they need to be reverified.
820 texture_level0_dirty_ = true; 859 texture_level0_dirty_ = true;
821 } 860 }
822 861
823 // Signify that at least one of the mips has changed. 862 // Signify that at least one of the mips has changed.
824 texture_mips_dirty_ = true; 863 texture_mips_dirty_ = true;
825 } 864 }
826 865
827 info.target = target; 866 info.target = target;
828 info.level = level; 867 info.level = level;
829 info.internal_format = internal_format; 868 info.internal_format = internal_format;
830 info.depth = depth; 869 info.depth = depth;
831 info.border = border; 870 info.border = border;
832 info.format = format; 871 info.format = format;
833 info.type = type; 872 info.type = type;
834 info.image = 0; 873 info.image = 0;
835 874
836 UpdateMipCleared(&info, width, height, cleared_rect); 875 UpdateMipCleared(&info, width, height, cleared_rect);
837 876
838 estimated_size_ -= info.estimated_size; 877 estimated_size_ -= info.estimated_size;
839 GLES2Util::ComputeImageDataSizes( 878 GLES2Util::ComputeImageDataSizes(
840 width, height, 1, format, type, 4, &info.estimated_size, NULL, NULL); 879 width, height, depth, format, type, 4, &info.estimated_size, NULL, NULL);
841 estimated_size_ += info.estimated_size; 880 estimated_size_ += info.estimated_size;
842 881
843 max_level_set_ = std::max(max_level_set_, level); 882 max_level_set_ = std::max(max_level_set_, level);
844 Update(feature_info); 883 Update(feature_info);
845 UpdateCleared(); 884 UpdateCleared();
846 UpdateCanRenderCondition(); 885 UpdateCanRenderCondition();
847 UpdateHasImages(); 886 UpdateHasImages();
848 if (IsAttachedToFramebuffer()) { 887 if (IsAttachedToFramebuffer()) {
849 // TODO(gman): If textures tracked which framebuffers they were attached to 888 // TODO(gman): If textures tracked which framebuffers they were attached to
850 // we could just mark those framebuffers as not complete. 889 // we could just mark those framebuffers as not complete.
851 IncAllFramebufferStateChangeCount(); 890 IncAllFramebufferStateChangeCount();
852 } 891 }
853 } 892 }
854 893
855 bool Texture::ValidForTexture( 894 bool Texture::ValidForTexture(
856 GLint target, 895 GLint target,
857 GLint level, 896 GLint level,
858 GLint xoffset, 897 GLint xoffset,
859 GLint yoffset, 898 GLint yoffset,
860 GLint zoffset, 899 GLint zoffset,
861 GLsizei width, 900 GLsizei width,
862 GLsizei height, 901 GLsizei height,
863 GLsizei depth) const { 902 GLsizei depth) const {
864 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); 903 size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
865 if (level >= 0 && face_index < face_infos_.size() && 904 if (level >= 0 && face_index < face_infos_.size() &&
qiankun 2015/10/22 06:06:08 Should be level >= base_level_?
866 static_cast<size_t>(level) < face_infos_[face_index].level_infos.size()) { 905 static_cast<size_t>(level) < face_infos_[face_index].level_infos.size()) {
867 const LevelInfo& info = face_infos_[face_index].level_infos[level]; 906 const LevelInfo& info = face_infos_[face_index].level_infos[level];
868 int32 max_x; 907 int32 max_x;
869 int32 max_y; 908 int32 max_y;
870 int32 max_z; 909 int32 max_z;
871 return SafeAddInt32(xoffset, width, &max_x) && 910 return SafeAddInt32(xoffset, width, &max_x) &&
872 SafeAddInt32(yoffset, height, &max_y) && 911 SafeAddInt32(yoffset, height, &max_y) &&
873 SafeAddInt32(zoffset, depth, &max_z) && 912 SafeAddInt32(zoffset, depth, &max_z) &&
874 xoffset >= 0 && 913 xoffset >= 0 &&
875 yoffset >= 0 && 914 yoffset >= 0 &&
876 zoffset >= 0 && 915 zoffset >= 0 &&
877 max_x <= info.width && 916 max_x <= info.width &&
878 max_y <= info.height && 917 max_y <= info.height &&
879 max_z <= info.depth; 918 max_z <= info.depth;
880 } 919 }
881 return false; 920 return false;
882 } 921 }
883 922
884 bool Texture::GetLevelSize( 923 bool Texture::GetLevelSize(
885 GLint target, GLint level, 924 GLint target, GLint level,
886 GLsizei* width, GLsizei* height, GLsizei* depth) const { 925 GLsizei* width, GLsizei* height, GLsizei* depth) const {
887 DCHECK(width); 926 DCHECK(width);
888 DCHECK(height); 927 DCHECK(height);
889 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); 928 size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
890 if (level >= 0 && face_index < face_infos_.size() && 929 if (level >= 0 && face_index < face_infos_.size() &&
qiankun 2015/10/22 06:06:08 Same here.
Zhenyao Mo 2015/10/26 21:05:24 Same here, you can specify texture at any level. I
891 static_cast<size_t>(level) < face_infos_[face_index].level_infos.size()) { 930 static_cast<size_t>(level) < face_infos_[face_index].level_infos.size()) {
892 const LevelInfo& info = face_infos_[face_index].level_infos[level]; 931 const LevelInfo& info = face_infos_[face_index].level_infos[level];
893 if (info.target != 0) { 932 if (info.target != 0) {
894 *width = info.width; 933 *width = info.width;
895 *height = info.height; 934 *height = info.height;
896 if (depth) 935 if (depth)
897 *depth = info.depth; 936 *depth = info.depth;
898 return true; 937 return true;
899 } 938 }
900 } 939 }
901 return false; 940 return false;
902 } 941 }
903 942
904 bool Texture::GetLevelType( 943 bool Texture::GetLevelType(
905 GLint target, GLint level, GLenum* type, GLenum* internal_format) const { 944 GLint target, GLint level, GLenum* type, GLenum* internal_format) const {
906 DCHECK(type); 945 DCHECK(type);
907 DCHECK(internal_format); 946 DCHECK(internal_format);
908 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); 947 size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
909 if (level >= 0 && face_index < face_infos_.size() && 948 if (level >= 0 && face_index < face_infos_.size() &&
qiankun 2015/10/22 06:06:08 Same here.
Zhenyao Mo 2015/10/26 21:05:24 Same answer
910 static_cast<size_t>(level) < face_infos_[face_index].level_infos.size()) { 949 static_cast<size_t>(level) < face_infos_[face_index].level_infos.size()) {
911 const LevelInfo& info = face_infos_[face_index].level_infos[level]; 950 const LevelInfo& info = face_infos_[face_index].level_infos[level];
912 if (info.target != 0) { 951 if (info.target != 0) {
913 *type = info.type; 952 *type = info.type;
914 *internal_format = info.internal_format; 953 *internal_format = info.internal_format;
915 return true; 954 return true;
916 } 955 }
917 } 956 }
918 return false; 957 return false;
919 } 958 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
978 case GL_TEXTURE_COMPARE_MODE: 1017 case GL_TEXTURE_COMPARE_MODE:
979 if (!feature_info->validators()->texture_compare_mode.IsValid(param)) { 1018 if (!feature_info->validators()->texture_compare_mode.IsValid(param)) {
980 return GL_INVALID_ENUM; 1019 return GL_INVALID_ENUM;
981 } 1020 }
982 compare_mode_ = param; 1021 compare_mode_ = param;
983 break; 1022 break;
984 case GL_TEXTURE_BASE_LEVEL: 1023 case GL_TEXTURE_BASE_LEVEL:
985 if (param < 0) { 1024 if (param < 0) {
986 return GL_INVALID_VALUE; 1025 return GL_INVALID_VALUE;
987 } 1026 }
988 base_level_ = param; 1027 UpdateBaseLevel(param);
989 break; 1028 break;
990 case GL_TEXTURE_MAX_LEVEL: 1029 case GL_TEXTURE_MAX_LEVEL:
991 if (param < 0) { 1030 if (param < 0) {
992 return GL_INVALID_VALUE; 1031 return GL_INVALID_VALUE;
993 } 1032 }
994 max_level_ = param; 1033 UpdateMaxLevel(param);
995 break; 1034 break;
996 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1035 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
997 if (param < 1) { 1036 if (param < 1) {
998 return GL_INVALID_VALUE; 1037 return GL_INVALID_VALUE;
999 } 1038 }
1000 break; 1039 break;
1001 case GL_TEXTURE_USAGE_ANGLE: 1040 case GL_TEXTURE_USAGE_ANGLE:
1002 if (!feature_info->validators()->texture_usage.IsValid(param)) { 1041 if (!feature_info->validators()->texture_usage.IsValid(param)) {
1003 return GL_INVALID_ENUM; 1042 return GL_INVALID_ENUM;
1004 } 1043 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1047 return GL_INVALID_ENUM; 1086 return GL_INVALID_ENUM;
1048 } 1087 }
1049 return GL_NO_ERROR; 1088 return GL_NO_ERROR;
1050 } 1089 }
1051 1090
1052 void Texture::Update(const FeatureInfo* feature_info) { 1091 void Texture::Update(const FeatureInfo* feature_info) {
1053 // Update npot status. 1092 // Update npot status.
1054 // Assume GL_TEXTURE_EXTERNAL_OES textures are npot, all others 1093 // Assume GL_TEXTURE_EXTERNAL_OES textures are npot, all others
1055 npot_ = (target_ == GL_TEXTURE_EXTERNAL_OES) || (num_npot_faces_ > 0); 1094 npot_ = (target_ == GL_TEXTURE_EXTERNAL_OES) || (num_npot_faces_ > 0);
1056 1095
1057 if (face_infos_.empty()) { 1096 if (face_infos_.empty() ||
1097 static_cast<size_t>(base_level_) >= face_infos_[0].level_infos.size()) {
1058 texture_complete_ = false; 1098 texture_complete_ = false;
1059 cube_complete_ = false; 1099 cube_complete_ = false;
1060 return; 1100 return;
1061 } 1101 }
1062 1102
1063 // Update texture_complete and cube_complete status. 1103 // Update texture_complete and cube_complete status.
1064 const Texture::FaceInfo& first_face = face_infos_[0]; 1104 const Texture::FaceInfo& first_face = face_infos_[0];
1065 const Texture::LevelInfo& first_level = first_face.level_infos[0]; 1105 const Texture::LevelInfo& first_level = first_face.level_infos[base_level_];
1066 const GLsizei levels_needed = first_face.num_mip_levels; 1106 const GLsizei levels_needed = first_face.num_mip_levels;
1067 1107
1068 texture_complete_ = 1108 texture_complete_ =
1069 max_level_set_ >= (levels_needed - 1) && max_level_set_ >= 0; 1109 max_level_set_ >= (levels_needed - 1) && max_level_set_ >= 0;
1070 cube_complete_ = (face_infos_.size() == 6) && 1110 cube_complete_ = (face_infos_.size() == 6) &&
1071 (first_level.width == first_level.height); 1111 (first_level.width == first_level.height);
1072 1112
1073 if (first_level.width == 0 || first_level.height == 0) { 1113 if (first_level.width == 0 || first_level.height == 0) {
1074 texture_complete_ = false; 1114 texture_complete_ = false;
1075 } else if (first_level.type == GL_FLOAT && 1115 } else if (first_level.type == GL_FLOAT &&
1076 !feature_info->feature_flags().enable_texture_float_linear && 1116 !feature_info->feature_flags().enable_texture_float_linear &&
1077 (min_filter_ != GL_NEAREST_MIPMAP_NEAREST || 1117 (min_filter_ != GL_NEAREST_MIPMAP_NEAREST ||
1078 mag_filter_ != GL_NEAREST)) { 1118 mag_filter_ != GL_NEAREST)) {
1079 texture_complete_ = false; 1119 texture_complete_ = false;
1080 } else if (first_level.type == GL_HALF_FLOAT_OES && 1120 } else if (first_level.type == GL_HALF_FLOAT_OES &&
1081 !feature_info->feature_flags().enable_texture_half_float_linear && 1121 !feature_info->feature_flags().enable_texture_half_float_linear &&
1082 (min_filter_ != GL_NEAREST_MIPMAP_NEAREST || 1122 (min_filter_ != GL_NEAREST_MIPMAP_NEAREST ||
1083 mag_filter_ != GL_NEAREST)) { 1123 mag_filter_ != GL_NEAREST)) {
1084 texture_complete_ = false; 1124 texture_complete_ = false;
1085 } 1125 }
1086 1126
1087 if (cube_complete_ && texture_level0_dirty_) { 1127 if (cube_complete_ && texture_level0_dirty_) {
1088 texture_level0_complete_ = true; 1128 texture_level0_complete_ = true;
1089 for (size_t ii = 0; ii < face_infos_.size(); ++ii) { 1129 for (size_t ii = 0; ii < face_infos_.size(); ++ii) {
1090 const Texture::LevelInfo& level0 = face_infos_[ii].level_infos[0]; 1130 const Texture::LevelInfo& face_base_level =
1131 face_infos_[ii].level_infos[base_level_];
1091 if (!TextureFaceComplete(first_level, 1132 if (!TextureFaceComplete(first_level,
1092 ii, 1133 ii,
1093 level0.target, 1134 face_base_level.target,
1094 level0.internal_format, 1135 face_base_level.internal_format,
1095 level0.width, 1136 face_base_level.width,
1096 level0.height, 1137 face_base_level.height,
1097 level0.depth, 1138 face_base_level.depth,
1098 level0.format, 1139 face_base_level.format,
1099 level0.type)) { 1140 face_base_level.type)) {
1100 texture_level0_complete_ = false; 1141 texture_level0_complete_ = false;
1101 break; 1142 break;
1102 } 1143 }
1103 } 1144 }
1104 texture_level0_dirty_ = false; 1145 texture_level0_dirty_ = false;
1105 } 1146 }
1106 cube_complete_ &= texture_level0_complete_; 1147 cube_complete_ &= texture_level0_complete_;
1107 1148
1108 if (texture_complete_ && texture_mips_dirty_) { 1149 if (texture_complete_ && texture_mips_dirty_) {
1109 texture_mips_complete_ = true; 1150 texture_mips_complete_ = true;
1110 for (size_t ii = 0; 1151 for (size_t ii = 0;
1111 ii < face_infos_.size() && texture_mips_complete_; 1152 ii < face_infos_.size() && texture_mips_complete_;
1112 ++ii) { 1153 ++ii) {
1113 const Texture::FaceInfo& face_info = face_infos_[ii]; 1154 const Texture::FaceInfo& face_info = face_infos_[ii];
1114 const Texture::LevelInfo& level0 = face_info.level_infos[0]; 1155 const Texture::LevelInfo& base_level_info =
1156 face_info.level_infos[base_level_];
1115 for (GLsizei jj = 1; jj < levels_needed; ++jj) { 1157 for (GLsizei jj = 1; jj < levels_needed; ++jj) {
1116 const Texture::LevelInfo& level_info = face_infos_[ii].level_infos[jj]; 1158 const Texture::LevelInfo& level_info =
1117 if (!TextureMipComplete(level0, 1159 face_infos_[ii].level_infos[base_level_ + jj];
1160 if (!TextureMipComplete(base_level_info,
1118 level_info.target, 1161 level_info.target,
1119 jj, 1162 jj, // level - base_level_
1120 level_info.internal_format, 1163 level_info.internal_format,
1121 level_info.width, 1164 level_info.width,
1122 level_info.height, 1165 level_info.height,
1123 level_info.depth, 1166 level_info.depth,
1124 level_info.format, 1167 level_info.format,
1125 level_info.type)) { 1168 level_info.type)) {
1126 texture_mips_complete_ = false; 1169 texture_mips_complete_ = false;
1127 break; 1170 break;
1128 } 1171 }
1129 } 1172 }
1130 } 1173 }
1131 texture_mips_dirty_ = false; 1174 texture_mips_dirty_ = false;
1132 } 1175 }
1133 texture_complete_ &= texture_mips_complete_; 1176 texture_complete_ &= texture_mips_complete_;
1134 } 1177 }
1135 1178
1136 bool Texture::ClearRenderableLevels(GLES2Decoder* decoder) { 1179 bool Texture::ClearRenderableLevels(GLES2Decoder* decoder) {
1137 DCHECK(decoder); 1180 DCHECK(decoder);
1138 if (cleared_) { 1181 if (cleared_) {
1139 return true; 1182 return true;
1140 } 1183 }
1141 1184
1142 for (size_t ii = 0; ii < face_infos_.size(); ++ii) { 1185 for (size_t ii = 0; ii < face_infos_.size(); ++ii) {
1143 const Texture::FaceInfo& face_info = face_infos_[ii]; 1186 const Texture::FaceInfo& face_info = face_infos_[ii];
1144 for (GLint jj = 0; jj < face_info.num_mip_levels; ++jj) { 1187 for (GLint jj = base_level_;
1188 jj < base_level_ + face_info.num_mip_levels; ++jj) {
1145 const Texture::LevelInfo& info = face_info.level_infos[jj]; 1189 const Texture::LevelInfo& info = face_info.level_infos[jj];
1146 if (info.target != 0) { 1190 if (info.target != 0) {
1147 if (!ClearLevel(decoder, info.target, jj)) { 1191 if (!ClearLevel(decoder, info.target, jj)) {
1148 return false; 1192 return false;
1149 } 1193 }
1150 } 1194 }
1151 } 1195 }
1152 } 1196 }
1153 UpdateSafeToRenderFrom(true); 1197 UpdateSafeToRenderFrom(true);
1154 return true; 1198 return true;
1155 } 1199 }
1156 1200
1157 gfx::Rect Texture::GetLevelClearedRect(GLenum target, GLint level) const { 1201 gfx::Rect Texture::GetLevelClearedRect(GLenum target, GLint level) const {
1158 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); 1202 size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
1159 if (face_index >= face_infos_.size() || 1203 if (face_index >= face_infos_.size() ||
1160 level >= static_cast<GLint>(face_infos_[face_index].level_infos.size())) { 1204 level >= static_cast<GLint>(face_infos_[face_index].level_infos.size())) {
1161 return gfx::Rect(); 1205 return gfx::Rect();
1162 } 1206 }
1163 1207
1164 const Texture::LevelInfo& info = face_infos_[face_index].level_infos[level]; 1208 const Texture::LevelInfo& info = face_infos_[face_index].level_infos[level];
1165 1209
1166 return info.cleared_rect; 1210 return info.cleared_rect;
1167 } 1211 }
1168 1212
1169 bool Texture::IsLevelCleared(GLenum target, GLint level) const { 1213 bool Texture::IsLevelCleared(GLenum target, GLint level) const {
1170 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); 1214 size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
1171 if (face_index >= face_infos_.size() || 1215 if (face_index >= face_infos_.size() ||
1216 level < base_level_ ||
1172 level >= static_cast<GLint>(face_infos_[face_index].level_infos.size())) { 1217 level >= static_cast<GLint>(face_infos_[face_index].level_infos.size())) {
1173 return true; 1218 return true;
1174 } 1219 }
1175 1220
1176 const Texture::LevelInfo& info = face_infos_[face_index].level_infos[level]; 1221 const Texture::LevelInfo& info = face_infos_[face_index].level_infos[level];
1177 1222
1178 return info.cleared_rect == gfx::Rect(info.width, info.height); 1223 return info.cleared_rect == gfx::Rect(info.width, info.height);
1179 } 1224 }
1180 1225
1181 void Texture::InitTextureMaxAnisotropyIfNeeded(GLenum target) { 1226 void Texture::InitTextureMaxAnisotropyIfNeeded(GLenum target) {
1182 if (texture_max_anisotropy_initialized_) 1227 if (texture_max_anisotropy_initialized_)
1183 return; 1228 return;
1184 texture_max_anisotropy_initialized_ = true; 1229 texture_max_anisotropy_initialized_ = true;
1185 GLfloat params[] = { 1.0f }; 1230 GLfloat params[] = { 1.0f };
1186 glTexParameterfv(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, params); 1231 glTexParameterfv(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, params);
1187 } 1232 }
1188 1233
1189 bool Texture::ClearLevel( 1234 bool Texture::ClearLevel(
1190 GLES2Decoder* decoder, GLenum target, GLint level) { 1235 GLES2Decoder* decoder, GLenum target, GLint level) {
1191 DCHECK(decoder); 1236 DCHECK(decoder);
1192 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); 1237 size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
1193 if (face_index >= face_infos_.size() || 1238 if (face_index >= face_infos_.size() ||
1239 level < base_level_ ||
1194 level >= static_cast<GLint>(face_infos_[face_index].level_infos.size())) { 1240 level >= static_cast<GLint>(face_infos_[face_index].level_infos.size())) {
1195 return true; 1241 return true;
1196 } 1242 }
1197 1243
1198 Texture::LevelInfo& info = face_infos_[face_index].level_infos[level]; 1244 Texture::LevelInfo& info = face_infos_[face_index].level_infos[level];
1199 1245
1200 DCHECK(target == info.target); 1246 DCHECK(target == info.target);
1201 1247
1202 if (info.target == 0 || 1248 if (info.target == 0 ||
1203 info.cleared_rect == gfx::Rect(info.width, info.height) || 1249 info.cleared_rect == gfx::Rect(info.width, info.height) ||
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1261 // based on the new GLImage. crbug.com/526298 1307 // based on the new GLImage. crbug.com/526298
1262 } 1308 }
1263 1309
1264 gfx::GLImage* Texture::GetLevelImage(GLint target, GLint level) const { 1310 gfx::GLImage* Texture::GetLevelImage(GLint target, GLint level) const {
1265 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES && 1311 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES &&
1266 target != GL_TEXTURE_RECTANGLE_ARB) { 1312 target != GL_TEXTURE_RECTANGLE_ARB) {
1267 return NULL; 1313 return NULL;
1268 } 1314 }
1269 1315
1270 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); 1316 size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
1271 if (level >= 0 && face_index < face_infos_.size() && 1317 if (level >= 0 && face_index < face_infos_.size() &&
qiankun 2015/10/22 06:06:08 Same here.
Zhenyao Mo 2015/10/26 21:05:24 I think except for mipmaping/texture-completeness/
qiankun 2015/10/27 06:32:50 Thanks for explanation! That's right. BTW, when
1272 static_cast<size_t>(level) < face_infos_[face_index].level_infos.size()) { 1318 static_cast<size_t>(level) < face_infos_[face_index].level_infos.size()) {
1273 const LevelInfo& info = face_infos_[face_index].level_infos[level]; 1319 const LevelInfo& info = face_infos_[face_index].level_infos[level];
1274 if (info.target != 0) { 1320 if (info.target != 0) {
1275 return info.image.get(); 1321 return info.image.get();
1276 } 1322 }
1277 } 1323 }
1278 return NULL; 1324 return NULL;
1279 } 1325 }
1280 1326
1281 void Texture::OnWillModifyPixels() { 1327 void Texture::OnWillModifyPixels() {
(...skipping 884 matching lines...) Expand 10 before | Expand all | Expand 10 after
2166 pmd->AddOwnershipEdge(client_guid, service_guid, importance); 2212 pmd->AddOwnershipEdge(client_guid, service_guid, importance);
2167 2213
2168 // Dump all sub-levels held by the texture. They will appear below the main 2214 // Dump all sub-levels held by the texture. They will appear below the main
2169 // gl/textures/client_X/texture_Y dump. 2215 // gl/textures/client_X/texture_Y dump.
2170 ref->texture()->DumpLevelMemory(pmd, memory_tracker_->ClientTracingId(), 2216 ref->texture()->DumpLevelMemory(pmd, memory_tracker_->ClientTracingId(),
2171 dump_name); 2217 dump_name);
2172 } 2218 }
2173 2219
2174 } // namespace gles2 2220 } // namespace gles2
2175 } // namespace gpu 2221 } // 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