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

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

Issue 633773002: Optimized Texture::Update() function. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 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 <utility> 8 #include <utility>
9 9
10 #include "base/bits.h" 10 #include "base/bits.h"
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 DCHECK_EQ(0u, memory_tracker_managed_->GetMemRepresented()); 121 DCHECK_EQ(0u, memory_tracker_managed_->GetMemRepresented());
122 DCHECK_EQ(0u, memory_tracker_unmanaged_->GetMemRepresented()); 122 DCHECK_EQ(0u, memory_tracker_unmanaged_->GetMemRepresented());
123 } 123 }
124 124
125 Texture::Texture(GLuint service_id) 125 Texture::Texture(GLuint service_id)
126 : mailbox_manager_(NULL), 126 : mailbox_manager_(NULL),
127 memory_tracking_ref_(NULL), 127 memory_tracking_ref_(NULL),
128 service_id_(service_id), 128 service_id_(service_id),
129 cleared_(true), 129 cleared_(true),
130 num_uncleared_mips_(0), 130 num_uncleared_mips_(0),
131 num_npot_faces_(0),
132 num_complete_faces_(0),
133 num_incomplete_mips_(0),
131 target_(0), 134 target_(0),
132 min_filter_(GL_NEAREST_MIPMAP_LINEAR), 135 min_filter_(GL_NEAREST_MIPMAP_LINEAR),
133 mag_filter_(GL_LINEAR), 136 mag_filter_(GL_LINEAR),
134 wrap_s_(GL_REPEAT), 137 wrap_s_(GL_REPEAT),
135 wrap_t_(GL_REPEAT), 138 wrap_t_(GL_REPEAT),
136 usage_(GL_NONE), 139 usage_(GL_NONE),
137 pool_(GL_TEXTURE_POOL_UNMANAGED_CHROMIUM), 140 pool_(GL_TEXTURE_POOL_UNMANAGED_CHROMIUM),
138 max_level_set_(-1), 141 max_level_set_(-1),
139 texture_complete_(false), 142 texture_complete_(false),
140 cube_complete_(false), 143 cube_complete_(false),
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 if (!CanGenerateMipmaps(feature_info)) { 325 if (!CanGenerateMipmaps(feature_info)) {
323 return false; 326 return false;
324 } 327 }
325 for (size_t ii = 0; ii < level_infos_.size(); ++ii) { 328 for (size_t ii = 0; ii < level_infos_.size(); ++ii) {
326 const Texture::LevelInfo& info1 = level_infos_[ii][0]; 329 const Texture::LevelInfo& info1 = level_infos_[ii][0];
327 GLsizei width = info1.width; 330 GLsizei width = info1.width;
328 GLsizei height = info1.height; 331 GLsizei height = info1.height;
329 GLsizei depth = info1.depth; 332 GLsizei depth = info1.depth;
330 GLenum target = target_ == GL_TEXTURE_2D ? GL_TEXTURE_2D : 333 GLenum target = target_ == GL_TEXTURE_2D ? GL_TEXTURE_2D :
331 GLES2Util::IndexToGLFaceTarget(ii); 334 GLES2Util::IndexToGLFaceTarget(ii);
332 int num_mips = 335
333 TextureManager::ComputeMipMapCount(target_, width, height, depth); 336 const int num_mips = num_mip_levels_[ii];
334 for (int level = 1; level < num_mips; ++level) { 337 for (int level = 1; level < num_mips; ++level) {
335 width = std::max(1, width >> 1); 338 width = std::max(1, width >> 1);
336 height = std::max(1, height >> 1); 339 height = std::max(1, height >> 1);
337 depth = std::max(1, depth >> 1); 340 depth = std::max(1, depth >> 1);
338 SetLevelInfo(feature_info, 341 SetLevelInfo(feature_info,
339 target, 342 target,
340 level, 343 level,
341 info1.internal_format, 344 info1.internal_format,
342 width, 345 width,
343 height, 346 height,
(...skipping 10 matching lines...) Expand all
354 357
355 void Texture::SetTarget( 358 void Texture::SetTarget(
356 const FeatureInfo* feature_info, GLenum target, GLint max_levels) { 359 const FeatureInfo* feature_info, GLenum target, GLint max_levels) {
357 DCHECK_EQ(0u, target_); // you can only set this once. 360 DCHECK_EQ(0u, target_); // you can only set this once.
358 target_ = target; 361 target_ = target;
359 size_t num_faces = (target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 362 size_t num_faces = (target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
360 level_infos_.resize(num_faces); 363 level_infos_.resize(num_faces);
361 for (size_t ii = 0; ii < num_faces; ++ii) { 364 for (size_t ii = 0; ii < num_faces; ++ii) {
362 level_infos_[ii].resize(max_levels); 365 level_infos_[ii].resize(max_levels);
363 } 366 }
367 num_mip_levels_.resize(num_faces);
364 368
365 if (target == GL_TEXTURE_EXTERNAL_OES || target == GL_TEXTURE_RECTANGLE_ARB) { 369 if (target == GL_TEXTURE_EXTERNAL_OES || target == GL_TEXTURE_RECTANGLE_ARB) {
366 min_filter_ = GL_LINEAR; 370 min_filter_ = GL_LINEAR;
367 wrap_s_ = wrap_t_ = GL_CLAMP_TO_EDGE; 371 wrap_s_ = wrap_t_ = GL_CLAMP_TO_EDGE;
368 } 372 }
369 373
370 if (target == GL_TEXTURE_EXTERNAL_OES) { 374 if (target == GL_TEXTURE_EXTERNAL_OES) {
371 immutable_ = true; 375 immutable_ = true;
372 } 376 }
373 Update(feature_info); 377 Update(feature_info);
(...skipping 26 matching lines...) Expand all
400 (info.type != first.type) || 404 (info.type != first.type) ||
401 feature_info->validators()->compressed_texture_format.IsValid( 405 feature_info->validators()->compressed_texture_format.IsValid(
402 info.internal_format) || 406 info.internal_format) ||
403 info.image.get()) { 407 info.image.get()) {
404 return false; 408 return false;
405 } 409 }
406 } 410 }
407 return true; 411 return true;
408 } 412 }
409 413
414 bool Texture::TextureIsNPOT(GLsizei width,
415 GLsizei height,
416 GLsizei depth) {
417 return (GLES2Util::IsNPOT(width) ||
418 GLES2Util::IsNPOT(height) ||
419 GLES2Util::IsNPOT(depth));
420 }
421
422 bool Texture::TextureFaceComplete(const Texture::LevelInfo& first_face,
423 size_t face_index,
424 GLenum target,
425 GLenum internal_format,
426 GLsizei width,
427 GLsizei height,
428 GLsizei depth,
429 GLenum format,
430 GLenum type) {
431 bool complete = (target != 0 && depth == 1);
432 if (face_index != 0) {
433 complete &= (width == first_face.width &&
434 height == first_face.height &&
435 internal_format == first_face.internal_format &&
436 format == first_face.format &&
437 type == first_face.type);
438 }
439 return complete;
440 }
441
442 bool Texture::TextureMipComplete(const Texture::LevelInfo& level0_face,
443 GLenum target,
444 GLint level,
445 GLenum internal_format,
446 GLsizei width,
447 GLsizei height,
448 GLsizei depth,
449 GLenum format,
450 GLenum type) {
451 bool complete = (target != 0);
452 if (level != 0) {
453 const GLsizei mip_width = std::max(1, level0_face.width >> level);
454 const GLsizei mip_height = std::max(1, level0_face.height >> level);
455 const GLsizei mip_depth = std::max(1, level0_face.depth >> level);
vmiura 2014/10/07 00:13:03 Do we need to handle the case of width/height/dept
David Yen 2014/10/09 20:20:16 That check is already done before this function is
456
457 complete &= (width == mip_width &&
458 height == mip_height &&
459 depth == mip_depth &&
460 internal_format == level0_face.internal_format &&
461 format == level0_face.format &&
462 type == level0_face.type);
463 }
464 return complete;
465 }
466
410 void Texture::SetLevelCleared(GLenum target, GLint level, bool cleared) { 467 void Texture::SetLevelCleared(GLenum target, GLint level, bool cleared) {
411 DCHECK_GE(level, 0); 468 DCHECK_GE(level, 0);
412 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); 469 size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
413 DCHECK_LT(static_cast<size_t>(face_index), 470 DCHECK_LT(static_cast<size_t>(face_index),
414 level_infos_.size()); 471 level_infos_.size());
415 DCHECK_LT(static_cast<size_t>(level), 472 DCHECK_LT(static_cast<size_t>(level),
416 level_infos_[face_index].size()); 473 level_infos_[face_index].size());
417 Texture::LevelInfo& info = 474 Texture::LevelInfo& info =
418 level_infos_[face_index][level]; 475 level_infos_[face_index][level];
419 UpdateMipCleared(&info, cleared); 476 UpdateMipCleared(&info, cleared);
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); 566 size_t face_index = GLES2Util::GLTargetToFaceIndex(target);
510 DCHECK_LT(static_cast<size_t>(face_index), 567 DCHECK_LT(static_cast<size_t>(face_index),
511 level_infos_.size()); 568 level_infos_.size());
512 DCHECK_LT(static_cast<size_t>(level), 569 DCHECK_LT(static_cast<size_t>(level),
513 level_infos_[face_index].size()); 570 level_infos_[face_index].size());
514 DCHECK_GE(width, 0); 571 DCHECK_GE(width, 0);
515 DCHECK_GE(height, 0); 572 DCHECK_GE(height, 0);
516 DCHECK_GE(depth, 0); 573 DCHECK_GE(depth, 0);
517 Texture::LevelInfo& info = 574 Texture::LevelInfo& info =
518 level_infos_[face_index][level]; 575 level_infos_[face_index][level];
576
577 // Update counters only if any attributes have changed. Counters are
578 // comparisons between the old and new values so it must be done before any
579 // assignment has been done to the LevelInfo.
580 if (info.target != target ||
581 info.internal_format != internal_format ||
582 info.width != width ||
583 info.height != height ||
584 info.depth != depth ||
585 info.format != format ||
586 info.type != type) {
587 if (level == 0) {
588 // Calculate the mip level count.
589 num_mip_levels_[face_index] = TextureManager::ComputeMipMapCount(
590 target_, width, height, depth);
591
592 // Update NPOT face count for the first level.
593 bool prev_npot = TextureIsNPOT(info.width, info.height, info.depth);
594 bool now_npot = TextureIsNPOT(width, height, depth);
595 if (prev_npot != now_npot)
596 num_npot_faces_ += now_npot ? 1 : -1;
597
598 // Update number of complete faces.
599 const Texture::LevelInfo& first_face = level_infos_[0][0];
600 for (size_t i = face_index; i < level_infos_.size(); ++i) {
vmiura 2014/10/07 00:13:03 I think this compares face 0 to itself, so I think
David Yen 2014/10/09 20:20:16 No longer relevant, using dirty bit now.
601 bool prev_face_status = TextureFaceComplete(first_face,
602 face_index,
603 info.target,
604 info.internal_format,
605 info.width,
606 info.height,
607 info.depth,
608 info.format,
609 info.type);
610 bool new_face_status = TextureFaceComplete(first_face,
611 face_index,
612 target,
613 internal_format,
614 width,
615 height,
616 depth,
617 format,
618 type);
619 if (prev_face_status != new_face_status)
620 num_complete_faces_ += new_face_status ? 1 : -1;
621
622 // Only need to validate all faces if the first face is changing.
623 if (face_index != 0)
624 break;
625 }
626 }
627
628 // Update incomplete mip counter.
629 const Texture::LevelInfo& level0_face = level_infos_[face_index][0];
630 const GLsizei num_mip_levels = num_mip_levels_[face_index];
vmiura 2014/10/07 00:13:03 If num_mip_levels changes, for example decreasing,
David Yen 2014/10/09 20:20:16 No longer relevant, using dirty bit now.
631 for (GLsizei i = static_cast<GLsizei>(level); i < num_mip_levels; ++i) {
632 bool prev_mip_status = TextureMipComplete(level0_face,
633 info.target,
634 i,
635 info.internal_format,
636 info.width,
637 info.height,
638 info.depth,
639 info.format,
640 info.type);
641 bool new_mip_status = TextureMipComplete(level0_face,
642 target,
643 i,
644 internal_format,
645 width,
646 height,
647 depth,
648 format,
649 type);
650 if (prev_mip_status != new_mip_status)
651 num_incomplete_mips_ += new_mip_status ? -1 : 1;
vmiura 2014/10/07 00:13:03 As above, I'm not sure we will count correctly whe
David Yen 2014/10/09 20:20:16 No longer relevant, using dirty bit now.
652
653 // Only need to validate all faces if the first face is changing.
654 if (face_index != 0)
655 break;
656 }
657 }
658
519 info.target = target; 659 info.target = target;
520 info.level = level; 660 info.level = level;
521 info.internal_format = internal_format; 661 info.internal_format = internal_format;
522 info.width = width; 662 info.width = width;
523 info.height = height; 663 info.height = height;
524 info.depth = depth; 664 info.depth = depth;
525 info.border = border; 665 info.border = border;
526 info.format = format; 666 info.format = format;
527 info.type = type; 667 info.type = type;
528 info.image = 0; 668 info.image = 0;
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 default: 833 default:
694 NOTREACHED(); 834 NOTREACHED();
695 return GL_INVALID_ENUM; 835 return GL_INVALID_ENUM;
696 } 836 }
697 return GL_NO_ERROR; 837 return GL_NO_ERROR;
698 } 838 }
699 839
700 void Texture::Update(const FeatureInfo* feature_info) { 840 void Texture::Update(const FeatureInfo* feature_info) {
701 // Update npot status. 841 // Update npot status.
702 // Assume GL_TEXTURE_EXTERNAL_OES textures are npot, all others 842 // Assume GL_TEXTURE_EXTERNAL_OES textures are npot, all others
703 npot_ = target_ == GL_TEXTURE_EXTERNAL_OES; 843 npot_ = (target_ == GL_TEXTURE_EXTERNAL_OES) || (num_npot_faces_ > 0);
704 844
705 if (level_infos_.empty()) { 845 if (level_infos_.empty()) {
706 texture_complete_ = false; 846 texture_complete_ = false;
707 cube_complete_ = false; 847 cube_complete_ = false;
708 return; 848 return;
709 } 849 }
710 850
711 // checks that the first mip of any face is npot.
712 for (size_t ii = 0; ii < level_infos_.size(); ++ii) {
713 const Texture::LevelInfo& info = level_infos_[ii][0];
714 if (GLES2Util::IsNPOT(info.width) ||
715 GLES2Util::IsNPOT(info.height) ||
716 GLES2Util::IsNPOT(info.depth)) {
717 npot_ = true;
718 break;
719 }
720 }
721
722 // Update texture_complete and cube_complete status. 851 // Update texture_complete and cube_complete status.
723 const Texture::LevelInfo& first_face = level_infos_[0][0]; 852 const Texture::LevelInfo& first_face = level_infos_[0][0];
724 int levels_needed = TextureManager::ComputeMipMapCount( 853 int levels_needed = num_mip_levels_[0];
725 target_, first_face.width, first_face.height, first_face.depth);
726 texture_complete_ = 854 texture_complete_ =
727 max_level_set_ >= (levels_needed - 1) && max_level_set_ >= 0; 855 max_level_set_ >= (levels_needed - 1) && max_level_set_ >= 0;
728 cube_complete_ = (level_infos_.size() == 6) && 856 cube_complete_ = (level_infos_.size() == 6) &&
729 (first_face.width == first_face.height); 857 (first_face.width == first_face.height) &&
858 (num_complete_faces_ == 6);
730 859
731 if (first_face.width == 0 || first_face.height == 0) { 860 if (first_face.width == 0 || first_face.height == 0) {
732 texture_complete_ = false; 861 texture_complete_ = false;
733 } 862 } else if (first_face.type == GL_FLOAT &&
734 if (first_face.type == GL_FLOAT && 863 !feature_info->feature_flags().enable_texture_float_linear &&
735 !feature_info->feature_flags().enable_texture_float_linear && 864 (min_filter_ != GL_NEAREST_MIPMAP_NEAREST ||
736 (min_filter_ != GL_NEAREST_MIPMAP_NEAREST || 865 mag_filter_ != GL_NEAREST)) {
737 mag_filter_ != GL_NEAREST)) {
738 texture_complete_ = false; 866 texture_complete_ = false;
739 } else if (first_face.type == GL_HALF_FLOAT_OES && 867 } else if (first_face.type == GL_HALF_FLOAT_OES &&
740 !feature_info->feature_flags().enable_texture_half_float_linear && 868 !feature_info->feature_flags().enable_texture_half_float_linear &&
741 (min_filter_ != GL_NEAREST_MIPMAP_NEAREST || 869 (min_filter_ != GL_NEAREST_MIPMAP_NEAREST ||
742 mag_filter_ != GL_NEAREST)) { 870 mag_filter_ != GL_NEAREST)) {
743 texture_complete_ = false; 871 texture_complete_ = false;
744 } 872 } else if (num_incomplete_mips_ > 0) {
745 for (size_t ii = 0; 873 texture_complete_ = false;
746 ii < level_infos_.size() && (cube_complete_ || texture_complete_);
747 ++ii) {
748 const Texture::LevelInfo& level0 = level_infos_[ii][0];
749 if (level0.target == 0 ||
750 level0.width != first_face.width ||
751 level0.height != first_face.height ||
752 level0.depth != 1 ||
753 level0.internal_format != first_face.internal_format ||
754 level0.format != first_face.format ||
755 level0.type != first_face.type) {
756 cube_complete_ = false;
757 }
758 // Get level0 dimensions
759 GLsizei width = level0.width;
760 GLsizei height = level0.height;
761 GLsizei depth = level0.depth;
762 for (GLint jj = 1; jj < levels_needed; ++jj) {
763 // compute required size for mip.
764 width = std::max(1, width >> 1);
765 height = std::max(1, height >> 1);
766 depth = std::max(1, depth >> 1);
767 const Texture::LevelInfo& info = level_infos_[ii][jj];
768 if (info.target == 0 ||
769 info.width != width ||
770 info.height != height ||
771 info.depth != depth ||
772 info.internal_format != level0.internal_format ||
773 info.format != level0.format ||
774 info.type != level0.type) {
775 texture_complete_ = false;
776 break;
777 }
778 }
779 } 874 }
780 } 875 }
781 876
782 bool Texture::ClearRenderableLevels(GLES2Decoder* decoder) { 877 bool Texture::ClearRenderableLevels(GLES2Decoder* decoder) {
783 DCHECK(decoder); 878 DCHECK(decoder);
784 if (cleared_) { 879 if (cleared_) {
785 return true; 880 return true;
786 } 881 }
787 882
788 const Texture::LevelInfo& first_face = level_infos_[0][0]; 883 const Texture::LevelInfo& first_face = level_infos_[0][0];
789 int levels_needed = TextureManager::ComputeMipMapCount( 884 int levels_needed = num_mip_levels_[0];
790 target_, first_face.width, first_face.height, first_face.depth);
791 885
792 for (size_t ii = 0; ii < level_infos_.size(); ++ii) { 886 for (size_t ii = 0; ii < level_infos_.size(); ++ii) {
793 for (GLint jj = 0; jj < levels_needed; ++jj) { 887 for (GLint jj = 0; jj < levels_needed; ++jj) {
794 Texture::LevelInfo& info = level_infos_[ii][jj]; 888 Texture::LevelInfo& info = level_infos_[ii][jj];
795 if (info.target != 0) { 889 if (info.target != 0) {
796 if (!ClearLevel(decoder, info.target, jj)) { 890 if (!ClearLevel(decoder, info.target, jj)) {
797 return false; 891 return false;
798 } 892 }
799 } 893 }
800 } 894 }
(...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after
1612 } 1706 }
1613 1707
1614 ScopedTextureUploadTimer::~ScopedTextureUploadTimer() { 1708 ScopedTextureUploadTimer::~ScopedTextureUploadTimer() {
1615 texture_state_->texture_upload_count++; 1709 texture_state_->texture_upload_count++;
1616 texture_state_->total_texture_upload_time += 1710 texture_state_->total_texture_upload_time +=
1617 base::TimeTicks::HighResNow() - begin_time_; 1711 base::TimeTicks::HighResNow() - begin_time_;
1618 } 1712 }
1619 1713
1620 } // namespace gles2 1714 } // namespace gles2
1621 } // namespace gpu 1715 } // namespace gpu
OLDNEW
« gpu/command_buffer/service/texture_manager.h ('K') | « gpu/command_buffer/service/texture_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698