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

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

Issue 8680002: Added minimal support to command buffer for GL_ARB_texture_rectangle (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 #include "base/bits.h" 6 #include "base/bits.h"
7 #include "gpu/command_buffer/common/gles2_cmd_utils.h" 7 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
8 #include "gpu/command_buffer/service/feature_info.h" 8 #include "gpu/command_buffer/service/feature_info.h"
9 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 9 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
10 10
11 namespace gpu { 11 namespace gpu {
12 namespace gles2 { 12 namespace gles2 {
13 13
14 static GLsizei ComputeMipMapCount( 14 static GLsizei ComputeMipMapCount(
15 GLsizei width, GLsizei height, GLsizei depth) { 15 GLsizei width, GLsizei height, GLsizei depth) {
16 return 1 + base::bits::Log2Floor(std::max(std::max(width, height), depth)); 16 return 1 + base::bits::Log2Floor(std::max(std::max(width, height), depth));
17 } 17 }
18 18
19 static size_t GLTargetToFaceIndex(GLenum target) { 19 static size_t GLTargetToFaceIndex(GLenum target) {
20 switch (target) { 20 switch (target) {
21 case GL_TEXTURE_2D: 21 case GL_TEXTURE_2D:
22 case GL_TEXTURE_EXTERNAL_OES: 22 case GL_TEXTURE_EXTERNAL_OES:
23 case GL_TEXTURE_RECTANGLE_ARB:
23 return 0; 24 return 0;
24 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 25 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
25 return 0; 26 return 0;
26 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 27 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
27 return 1; 28 return 1;
28 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 29 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
29 return 2; 30 return 2;
30 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 31 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
31 return 3; 32 return 3;
32 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 33 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 glDeleteTextures(arraysize(ids), ids); 86 glDeleteTextures(arraysize(ids), ids);
86 } 87 }
87 } 88 }
88 89
89 bool TextureManager::TextureInfo::CanRender( 90 bool TextureManager::TextureInfo::CanRender(
90 const FeatureInfo* feature_info) const { 91 const FeatureInfo* feature_info) const {
91 if (target_ == 0) { 92 if (target_ == 0) {
92 return false; 93 return false;
93 } 94 }
94 bool needs_mips = NeedsMips(); 95 bool needs_mips = NeedsMips();
95 if (npot() && !feature_info->feature_flags().npot_ok) { 96 if ((npot() && !feature_info->feature_flags().npot_ok) ||
97 (target_ == GL_TEXTURE_RECTANGLE_ARB)) {
96 return !needs_mips && 98 return !needs_mips &&
97 wrap_s_ == GL_CLAMP_TO_EDGE && 99 wrap_s_ == GL_CLAMP_TO_EDGE &&
98 wrap_t_ == GL_CLAMP_TO_EDGE; 100 wrap_t_ == GL_CLAMP_TO_EDGE;
99 } 101 }
100 if (needs_mips) { 102 if (needs_mips) {
101 if (target_ == GL_TEXTURE_2D) { 103 if (target_ == GL_TEXTURE_2D) {
102 return texture_complete(); 104 return texture_complete();
103 } else { 105 } else {
104 return texture_complete() && cube_complete(); 106 return texture_complete() && cube_complete();
105 } 107 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 146
145 void TextureManager::TextureInfo::SetTarget(GLenum target, GLint max_levels) { 147 void TextureManager::TextureInfo::SetTarget(GLenum target, GLint max_levels) {
146 DCHECK_EQ(0u, target_); // you can only set this once. 148 DCHECK_EQ(0u, target_); // you can only set this once.
147 target_ = target; 149 target_ = target;
148 size_t num_faces = (target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 150 size_t num_faces = (target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
149 level_infos_.resize(num_faces); 151 level_infos_.resize(num_faces);
150 for (size_t ii = 0; ii < num_faces; ++ii) { 152 for (size_t ii = 0; ii < num_faces; ++ii) {
151 level_infos_[ii].resize(max_levels); 153 level_infos_[ii].resize(max_levels);
152 } 154 }
153 155
154 if (target == GL_TEXTURE_EXTERNAL_OES) { 156 if (target == GL_TEXTURE_EXTERNAL_OES || target == GL_TEXTURE_RECTANGLE_ARB) {
155 min_filter_ = GL_LINEAR; 157 min_filter_ = GL_LINEAR;
156 wrap_s_ = wrap_t_ = GL_CLAMP_TO_EDGE; 158 wrap_s_ = wrap_t_ = GL_CLAMP_TO_EDGE;
157 } 159 }
158 } 160 }
159 161
160 bool TextureManager::TextureInfo::CanGenerateMipmaps( 162 bool TextureManager::TextureInfo::CanGenerateMipmaps(
161 const FeatureInfo* feature_info) const { 163 const FeatureInfo* feature_info) const {
162 if ((npot() && !feature_info->feature_flags().npot_ok) || 164 if ((npot() && !feature_info->feature_flags().npot_ok) ||
163 level_infos_.empty() || 165 level_infos_.empty() ||
164 target_ == GL_TEXTURE_EXTERNAL_OES) { 166 target_ == GL_TEXTURE_EXTERNAL_OES ||
167 target_ == GL_TEXTURE_RECTANGLE_ARB) {
165 return false; 168 return false;
166 } 169 }
167 const TextureInfo::LevelInfo& first = level_infos_[0][0]; 170 const TextureInfo::LevelInfo& first = level_infos_[0][0];
168 // TODO(gman): Check internal_format, format and type. 171 // TODO(gman): Check internal_format, format and type.
169 for (size_t ii = 0; ii < level_infos_.size(); ++ii) { 172 for (size_t ii = 0; ii < level_infos_.size(); ++ii) {
170 const LevelInfo& info = level_infos_[ii][0]; 173 const LevelInfo& info = level_infos_[ii][0];
171 if ((info.target == 0) || 174 if ((info.target == 0) ||
172 (info.width != first.width) || 175 (info.width != first.width) ||
173 (info.height != first.height) || 176 (info.height != first.height) ||
174 (info.depth != 1) || 177 (info.depth != 1) ||
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 return true; 323 return true;
321 } 324 }
322 } 325 }
323 return false; 326 return false;
324 } 327 }
325 328
326 bool TextureManager::TextureInfo::SetParameter( 329 bool TextureManager::TextureInfo::SetParameter(
327 const FeatureInfo* feature_info, GLenum pname, GLint param) { 330 const FeatureInfo* feature_info, GLenum pname, GLint param) {
328 DCHECK(feature_info); 331 DCHECK(feature_info);
329 332
330 if (target_ == GL_TEXTURE_EXTERNAL_OES) { 333 if (target_ == GL_TEXTURE_EXTERNAL_OES ||
334 target_ == GL_TEXTURE_RECTANGLE_ARB) {
331 if (pname == GL_TEXTURE_MIN_FILTER && 335 if (pname == GL_TEXTURE_MIN_FILTER &&
332 (param != GL_NEAREST && param != GL_LINEAR)) 336 (param != GL_NEAREST && param != GL_LINEAR))
333 return false; 337 return false;
334 if ((pname == GL_TEXTURE_WRAP_S || pname == GL_TEXTURE_WRAP_T) && 338 if ((pname == GL_TEXTURE_WRAP_S || pname == GL_TEXTURE_WRAP_T) &&
335 param != GL_CLAMP_TO_EDGE) 339 param != GL_CLAMP_TO_EDGE)
336 return false; 340 return false;
337 } 341 }
338 342
339 switch (pname) { 343 switch (pname) {
340 case GL_TEXTURE_MIN_FILTER: 344 case GL_TEXTURE_MIN_FILTER:
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 max_levels_(ComputeMipMapCount(max_texture_size, 537 max_levels_(ComputeMipMapCount(max_texture_size,
534 max_texture_size, 538 max_texture_size,
535 max_texture_size)), 539 max_texture_size)),
536 max_cube_map_levels_(ComputeMipMapCount(max_cube_map_texture_size, 540 max_cube_map_levels_(ComputeMipMapCount(max_cube_map_texture_size,
537 max_cube_map_texture_size, 541 max_cube_map_texture_size,
538 max_cube_map_texture_size)), 542 max_cube_map_texture_size)),
539 num_unrenderable_textures_(0), 543 num_unrenderable_textures_(0),
540 num_unsafe_textures_(0), 544 num_unsafe_textures_(0),
541 num_uncleared_mips_(0), 545 num_uncleared_mips_(0),
542 black_2d_texture_id_(0), 546 black_2d_texture_id_(0),
543 black_cube_texture_id_(0) { 547 black_cube_texture_id_(0),
548 black_oes_external_texture_id_(0),
549 black_arb_texture_rectangle_id_(0) {
544 } 550 }
545 551
546 bool TextureManager::Initialize(const FeatureInfo* feature_info) { 552 bool TextureManager::Initialize(const FeatureInfo* feature_info) {
547 // TODO(gman): The default textures have to be real textures, not the 0 553 // TODO(gman): The default textures have to be real textures, not the 0
548 // texture because we simulate non shared resources on top of shared 554 // texture because we simulate non shared resources on top of shared
549 // resources and all contexts that share resource share the same default 555 // resources and all contexts that share resource share the same default
550 // texture. 556 // texture.
551 557
552 // Make default textures and texture for replacing non-renderable textures. 558 default_texture_2d_ = CreateDefaultAndBlackTextures(
553 GLuint ids[4]; 559 feature_info, GL_TEXTURE_2D, &black_2d_texture_id_);
554 glGenTextures(arraysize(ids), ids); 560 default_texture_cube_map_ = CreateDefaultAndBlackTextures(
555 static uint8 black[] = {0, 0, 0, 255}; 561 feature_info, GL_TEXTURE_CUBE_MAP, &black_cube_texture_id_);
556 for (int ii = 0; ii < 2; ++ii) {
557 glBindTexture(GL_TEXTURE_2D, ids[ii]);
558 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
559 GL_UNSIGNED_BYTE, black);
560 glBindTexture(GL_TEXTURE_CUBE_MAP, ids[2 + ii]);
561 for (int ii = 0; ii < GLES2Util::kNumFaces; ++ii) {
562 glTexImage2D(GLES2Util::IndexToGLFaceTarget(ii), 0, GL_RGBA, 1, 1, 0,
563 GL_RGBA, GL_UNSIGNED_BYTE, black);
564 }
565 }
566 glBindTexture(GL_TEXTURE_2D, 0);
567 glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
568 562
569 // Since we are manually setting up these textures 563 if (feature_info->feature_flags().oes_egl_image_external) {
570 // we need to manually manipulate some of the their bookkeeping. 564 default_texture_external_oes_ = CreateDefaultAndBlackTextures(
571 num_unrenderable_textures_ += 2; 565 feature_info, GL_TEXTURE_EXTERNAL_OES,
572 FeatureInfo temp_feature_info; 566 &black_oes_external_texture_id_);
573 default_texture_2d_ = TextureInfo::Ref(new TextureInfo(ids[1]));
574 SetInfoTarget(feature_info, default_texture_2d_, GL_TEXTURE_2D);
575 SetLevelInfo(&temp_feature_info, default_texture_2d_,
576 GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true);
577 default_texture_cube_map_ = TextureInfo::Ref(new TextureInfo(ids[3]));
578 SetInfoTarget(feature_info, default_texture_cube_map_, GL_TEXTURE_CUBE_MAP);
579 for (int ii = 0; ii < GLES2Util::kNumFaces; ++ii) {
580 SetLevelInfo(
581 &temp_feature_info, default_texture_cube_map_,
582 GLES2Util::IndexToGLFaceTarget(ii),
583 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true);
584 } 567 }
585 568
586 black_2d_texture_id_ = ids[0]; 569 if (feature_info->feature_flags().arb_texture_rectangle) {
587 black_cube_texture_id_ = ids[2]; 570 default_texture_rectangle_arb_ = CreateDefaultAndBlackTextures(
588 571 feature_info, GL_TEXTURE_RECTANGLE_ARB,
589 if (feature_info->feature_flags().oes_egl_image_external) { 572 &black_arb_texture_rectangle_id_);
590 // Since we are manually setting up these textures
591 // we need to manually manipulate some of the their bookkeeping.
592 num_unrenderable_textures_ += 1;
593 GLuint external_ids[2];
594 glGenTextures(arraysize(external_ids), external_ids);
595 glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
596 default_texture_external_oes_ = TextureInfo::Ref(
597 new TextureInfo(external_ids[0]));
598 SetInfoTarget(feature_info,
599 default_texture_external_oes_,
600 GL_TEXTURE_EXTERNAL_OES);
601 default_texture_external_oes_->SetLevelInfo(
602 &temp_feature_info, GL_TEXTURE_EXTERNAL_OES, 0,
603 GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true);
604
605 // Sampling a texture not associated with any EGLImage sibling will return
606 // black values according to the spec.
607 black_oes_external_texture_id_ = external_ids[1];
608 } 573 }
609 574
610 return true; 575 return true;
611 } 576 }
612 577
578 TextureManager::TextureInfo::Ref TextureManager::CreateDefaultAndBlackTextures(
579 const FeatureInfo* feature_info,
580 GLenum target,
581 GLuint* black_texture) {
582 static uint8 black[] = {0, 0, 0, 255};
583
584 // Sampling a texture not associated with any EGLImage sibling will return
585 // black values according to the spec.
586 bool needs_initialization = (target != GL_TEXTURE_EXTERNAL_OES);
587 bool needs_faces = (target == GL_TEXTURE_CUBE_MAP);
588
589 // Make default textures and texture for replacing non-renderable textures.
590 GLuint ids[2];
591 glGenTextures(arraysize(ids), ids);
592 for (unsigned long ii = 0; ii < arraysize(ids); ++ii) {
593 glBindTexture(target, ids[ii]);
594 if (needs_initialization) {
595 if (needs_faces) {
596 for (int jj = 0; jj < GLES2Util::kNumFaces; ++jj) {
597 glTexImage2D(GLES2Util::IndexToGLFaceTarget(jj), 0, GL_RGBA, 1, 1, 0,
598 GL_RGBA, GL_UNSIGNED_BYTE, black);
599 }
600 } else {
601 glTexImage2D(target, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
602 GL_UNSIGNED_BYTE, black);
603 }
604 }
605 }
606 glBindTexture(target, 0);
607
608 // Since we are manually setting up these textures
609 // we need to manually manipulate some of the their bookkeeping.
610 ++num_unrenderable_textures_;
611 TextureInfo::Ref default_texture = TextureInfo::Ref(new TextureInfo(ids[1]));
612 SetInfoTarget(feature_info, default_texture, target);
613 FeatureInfo temp_feature_info;
614 if (needs_faces) {
615 for (int ii = 0; ii < GLES2Util::kNumFaces; ++ii) {
616 SetLevelInfo(
617 &temp_feature_info, default_texture,
618 GLES2Util::IndexToGLFaceTarget(ii),
619 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true);
620 }
621 } else {
622 // TODO(kbr): previous code called SetLevelInfo directly on the
623 // TextureInfo object for the GL_TEXTURE_EXTERNAL_OES case.
624 // Unclear whether this was deliberate.
625 if (needs_initialization) {
626 SetLevelInfo(&temp_feature_info, default_texture,
627 GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0,
628 GL_RGBA, GL_UNSIGNED_BYTE, true);
629 } else {
630 default_texture->SetLevelInfo(
631 &temp_feature_info, GL_TEXTURE_EXTERNAL_OES, 0,
632 GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true);
633 }
634 }
635
636 *black_texture = ids[0];
637 return default_texture;
638 }
639
613 bool TextureManager::ValidForTarget( 640 bool TextureManager::ValidForTarget(
614 const FeatureInfo* feature_info, 641 const FeatureInfo* feature_info,
615 GLenum target, GLint level, 642 GLenum target, GLint level,
616 GLsizei width, GLsizei height, GLsizei depth) { 643 GLsizei width, GLsizei height, GLsizei depth) {
617 GLsizei max_size = MaxSizeForTarget(target); 644 GLsizei max_size = MaxSizeForTarget(target);
618 return level >= 0 && 645 return level >= 0 &&
619 width >= 0 && 646 width >= 0 &&
620 height >= 0 && 647 height >= 0 &&
621 depth >= 0 && 648 depth >= 0 &&
622 level < MaxLevelsForTarget(target) && 649 level < MaxLevelsForTarget(target) &&
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
837 return true; 864 return true;
838 } 865 }
839 } 866 }
840 return false; 867 return false;
841 } 868 }
842 869
843 } // namespace gles2 870 } // namespace gles2
844 } // namespace gpu 871 } // namespace gpu
845 872
846 873
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698