OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |