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

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

Issue 14844004: gpu: Refactor to support cross-channel shared textures (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix accidentally reverted behavior Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
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 #include "base/bits.h" 6 #include "base/bits.h"
7 #include "base/stringprintf.h" 7 #include "base/stringprintf.h"
8 #include "gpu/command_buffer/common/gles2_cmd_utils.h" 8 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
9 #include "gpu/command_buffer/service/error_state.h" 9 #include "gpu/command_buffer/service/error_state.h"
10 #include "gpu/command_buffer/service/feature_info.h" 10 #include "gpu/command_buffer/service/feature_info.h"
11 #include "gpu/command_buffer/service/framebuffer_manager.h"
11 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 12 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
12 #include "gpu/command_buffer/service/mailbox_manager.h" 13 #include "gpu/command_buffer/service/mailbox_manager.h"
13 #include "gpu/command_buffer/service/memory_tracking.h" 14 #include "gpu/command_buffer/service/memory_tracking.h"
14 #include "gpu/command_buffer/service/texture_definition.h" 15 #include "gpu/command_buffer/service/texture_definition.h"
15 16
16 namespace gpu { 17 namespace gpu {
17 namespace gles2 { 18 namespace gles2 {
18 19
19 static size_t GLTargetToFaceIndex(GLenum target) { 20 static size_t GLTargetToFaceIndex(GLenum target) {
20 switch (target) { 21 switch (target) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 } 81 }
81 82
82 if (have_context) { 83 if (have_context) {
83 glDeleteTextures(arraysize(black_texture_ids_), black_texture_ids_); 84 glDeleteTextures(arraysize(black_texture_ids_), black_texture_ids_);
84 } 85 }
85 86
86 DCHECK_EQ(0u, memory_tracker_managed_->GetMemRepresented()); 87 DCHECK_EQ(0u, memory_tracker_managed_->GetMemRepresented());
87 DCHECK_EQ(0u, memory_tracker_unmanaged_->GetMemRepresented()); 88 DCHECK_EQ(0u, memory_tracker_unmanaged_->GetMemRepresented());
88 } 89 }
89 90
90 Texture::Texture(TextureManager* manager, GLuint service_id) 91 Texture::Texture(GLuint service_id)
91 : manager_(manager), 92 : memory_tracking_ref_(NULL),
92 service_id_(service_id), 93 service_id_(service_id),
93 deleted_(false),
94 cleared_(true), 94 cleared_(true),
95 num_uncleared_mips_(0), 95 num_uncleared_mips_(0),
96 target_(0), 96 target_(0),
97 min_filter_(GL_NEAREST_MIPMAP_LINEAR), 97 min_filter_(GL_NEAREST_MIPMAP_LINEAR),
98 mag_filter_(GL_LINEAR), 98 mag_filter_(GL_LINEAR),
99 wrap_s_(GL_REPEAT), 99 wrap_s_(GL_REPEAT),
100 wrap_t_(GL_REPEAT), 100 wrap_t_(GL_REPEAT),
101 usage_(GL_NONE), 101 usage_(GL_NONE),
102 pool_(GL_TEXTURE_POOL_UNMANAGED_CHROMIUM), 102 pool_(GL_TEXTURE_POOL_UNMANAGED_CHROMIUM),
103 max_level_set_(-1), 103 max_level_set_(-1),
104 texture_complete_(false), 104 texture_complete_(false),
105 cube_complete_(false), 105 cube_complete_(false),
106 npot_(false), 106 npot_(false),
107 has_been_bound_(false), 107 has_been_bound_(false),
108 framebuffer_attachment_count_(0), 108 framebuffer_attachment_count_(0),
109 owned_(true), 109 owned_(true),
110 stream_texture_(false), 110 stream_texture_(false),
111 immutable_(false), 111 immutable_(false),
112 estimated_size_(0) { 112 estimated_size_(0),
113 if (manager_) { 113 can_render_condition_(CAN_RENDER_NEVER) {
114 manager_->StartTracking(this); 114 }
115
116 Texture::~Texture() {
117 }
118
119 void Texture::AddTextureRef(TextureRef* ref) {
120 DCHECK(refs_.find(ref) == refs_.end());
121 refs_.insert(ref);
122 if (!memory_tracking_ref_) {
123 memory_tracking_ref_ = ref;
124 GetMemTracker()->TrackMemAlloc(estimated_size());
115 } 125 }
116 } 126 }
117 127
118 Texture::~Texture() { 128 void Texture::RemoveTextureRef(TextureRef* ref, bool have_context) {
119 if (manager_) { 129 if (memory_tracking_ref_ == ref) {
120 if (owned_ && manager_->have_context_) { 130 GetMemTracker()->TrackMemFree(estimated_size());
131 memory_tracking_ref_ = NULL;
132 }
133 size_t result = refs_.erase(ref);
134 DCHECK_EQ(result, 1u);
135 if (refs_.empty()) {
136 if (owned_ && have_context) {
121 GLuint id = service_id(); 137 GLuint id = service_id();
122 glDeleteTextures(1, &id); 138 glDeleteTextures(1, &id);
123 } 139 }
124 MarkAsDeleted(); 140 delete this;
125 manager_->StopTracking(this); 141 } else if (memory_tracking_ref_ == NULL) {
126 manager_ = NULL; 142 // TODO(piman): tune ownership semantics for cross-context group shared
143 // textures.
144 memory_tracking_ref_ = *refs_.begin();
145 GetMemTracker()->TrackMemAlloc(estimated_size());
127 } 146 }
128 } 147 }
129 148
149 MemoryTypeTracker* Texture::GetMemTracker() {
150 DCHECK(memory_tracking_ref_);
151 return memory_tracking_ref_->manager()->GetMemTracker(pool_);
152 }
153
130 Texture::LevelInfo::LevelInfo() 154 Texture::LevelInfo::LevelInfo()
131 : cleared(true), 155 : cleared(true),
132 target(0), 156 target(0),
133 level(-1), 157 level(-1),
134 internal_format(0), 158 internal_format(0),
135 width(0), 159 width(0),
136 height(0), 160 height(0),
137 depth(0), 161 depth(0),
138 border(0), 162 border(0),
139 format(0), 163 format(0),
(...skipping 12 matching lines...) Expand all
152 border(rhs.border), 176 border(rhs.border),
153 format(rhs.format), 177 format(rhs.format),
154 type(rhs.type), 178 type(rhs.type),
155 image(rhs.image), 179 image(rhs.image),
156 estimated_size(rhs.estimated_size) { 180 estimated_size(rhs.estimated_size) {
157 } 181 }
158 182
159 Texture::LevelInfo::~LevelInfo() { 183 Texture::LevelInfo::~LevelInfo() {
160 } 184 }
161 185
162 bool Texture::CanRender(const FeatureInfo* feature_info) const { 186 Texture::CanRenderCondition Texture::GetCanRenderCondition() const {
163 if (target_ == 0) { 187 if (target_ == 0)
164 return false; 188 return CAN_RENDER_NEVER;
165 }
166 189
167 if (target_ == GL_TEXTURE_EXTERNAL_OES) { 190 if (target_ == GL_TEXTURE_EXTERNAL_OES) {
168 if (!IsStreamTexture()) { 191 if (!IsStreamTexture()) {
169 return false; 192 return CAN_RENDER_NEVER;
170 } 193 }
171 } else { 194 } else {
172 if (level_infos_.empty()) { 195 if (level_infos_.empty()) {
173 return false; 196 return CAN_RENDER_NEVER;
174 } 197 }
175 198
176 const Texture::LevelInfo& first_face = level_infos_[0][0]; 199 const Texture::LevelInfo& first_face = level_infos_[0][0];
177 if (first_face.width == 0 || 200 if (first_face.width == 0 ||
178 first_face.height == 0 || 201 first_face.height == 0 ||
179 first_face.depth == 0) { 202 first_face.depth == 0) {
180 return false; 203 return CAN_RENDER_NEVER;
181 } 204 }
182 } 205 }
183 206
184 bool needs_mips = NeedsMips(); 207 bool needs_mips = NeedsMips();
185 if ((npot() && !feature_info->feature_flags().npot_ok) || 208 if (needs_mips) {
186 (target_ == GL_TEXTURE_RECTANGLE_ARB)) { 209 if (!texture_complete())
187 return !needs_mips && 210 return CAN_RENDER_NEVER;
188 wrap_s_ == GL_CLAMP_TO_EDGE && 211 if (target_ == GL_TEXTURE_CUBE_MAP && !cube_complete())
189 wrap_t_ == GL_CLAMP_TO_EDGE; 212 return CAN_RENDER_NEVER;
190 } 213 }
191 if (needs_mips) { 214
192 if (target_ == GL_TEXTURE_2D) { 215 bool is_npot_compatible = !needs_mips &&
193 return texture_complete(); 216 wrap_s_ == GL_CLAMP_TO_EDGE &&
194 } else { 217 wrap_t_ == GL_CLAMP_TO_EDGE;
195 return texture_complete() && cube_complete(); 218
196 } 219 if (!is_npot_compatible) {
197 } else { 220 if (target_ == GL_TEXTURE_RECTANGLE_ARB)
198 return true; 221 return CAN_RENDER_NEVER;
222 else if (npot())
223 return CAN_RENDER_ONLY_IF_NPOT;
199 } 224 }
225
226 return CAN_RENDER_ALWAYS;
227 }
228
229 bool Texture::CanRender(const FeatureInfo* feature_info) const {
230 switch (can_render_condition_) {
231 case CAN_RENDER_ALWAYS:
232 return true;
233 case CAN_RENDER_NEVER:
234 return false;
235 case CAN_RENDER_ONLY_IF_NPOT:
236 break;
237 }
238 return feature_info->feature_flags().npot_ok;
200 } 239 }
201 240
202 void Texture::AddToSignature( 241 void Texture::AddToSignature(
203 const FeatureInfo* feature_info, 242 const FeatureInfo* feature_info,
204 GLenum target, 243 GLenum target,
205 GLint level, 244 GLint level,
206 std::string* signature) const { 245 std::string* signature) const {
207 DCHECK(feature_info); 246 DCHECK(feature_info);
208 DCHECK(signature); 247 DCHECK(signature);
209 DCHECK_GE(level, 0); 248 DCHECK_GE(level, 0);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 312
274 if (target == GL_TEXTURE_EXTERNAL_OES || target == GL_TEXTURE_RECTANGLE_ARB) { 313 if (target == GL_TEXTURE_EXTERNAL_OES || target == GL_TEXTURE_RECTANGLE_ARB) {
275 min_filter_ = GL_LINEAR; 314 min_filter_ = GL_LINEAR;
276 wrap_s_ = wrap_t_ = GL_CLAMP_TO_EDGE; 315 wrap_s_ = wrap_t_ = GL_CLAMP_TO_EDGE;
277 } 316 }
278 317
279 if (target == GL_TEXTURE_EXTERNAL_OES) { 318 if (target == GL_TEXTURE_EXTERNAL_OES) {
280 immutable_ = true; 319 immutable_ = true;
281 } 320 }
282 Update(feature_info); 321 Update(feature_info);
322 UpdateCanRenderCondition();
283 } 323 }
284 324
285 bool Texture::CanGenerateMipmaps( 325 bool Texture::CanGenerateMipmaps(
286 const FeatureInfo* feature_info) const { 326 const FeatureInfo* feature_info) const {
287 if ((npot() && !feature_info->feature_flags().npot_ok) || 327 if ((npot() && !feature_info->feature_flags().npot_ok) ||
288 level_infos_.empty() || 328 level_infos_.empty() ||
289 target_ == GL_TEXTURE_EXTERNAL_OES || 329 target_ == GL_TEXTURE_EXTERNAL_OES ||
290 target_ == GL_TEXTURE_RECTANGLE_ARB) { 330 target_ == GL_TEXTURE_RECTANGLE_ARB) {
291 return false; 331 return false;
292 } 332 }
(...skipping 25 matching lines...) Expand all
318 } 358 }
319 359
320 void Texture::SetLevelCleared(GLenum target, GLint level, bool cleared) { 360 void Texture::SetLevelCleared(GLenum target, GLint level, bool cleared) {
321 DCHECK_GE(level, 0); 361 DCHECK_GE(level, 0);
322 DCHECK_LT(static_cast<size_t>(GLTargetToFaceIndex(target)), 362 DCHECK_LT(static_cast<size_t>(GLTargetToFaceIndex(target)),
323 level_infos_.size()); 363 level_infos_.size());
324 DCHECK_LT(static_cast<size_t>(level), 364 DCHECK_LT(static_cast<size_t>(level),
325 level_infos_[GLTargetToFaceIndex(target)].size()); 365 level_infos_[GLTargetToFaceIndex(target)].size());
326 Texture::LevelInfo& info = 366 Texture::LevelInfo& info =
327 level_infos_[GLTargetToFaceIndex(target)][level]; 367 level_infos_[GLTargetToFaceIndex(target)][level];
328 if (!info.cleared) { 368 UpdateMipCleared(&info, cleared);
329 DCHECK_NE(0, num_uncleared_mips_);
330 --num_uncleared_mips_;
331 } else {
332 ++num_uncleared_mips_;
333 }
334 info.cleared = cleared;
335 UpdateCleared(); 369 UpdateCleared();
336 } 370 }
337 371
338 void Texture::UpdateCleared() { 372 void Texture::UpdateCleared() {
339 if (level_infos_.empty()) { 373 if (level_infos_.empty()) {
340 return; 374 return;
341 } 375 }
342 376
343 const Texture::LevelInfo& first_face = level_infos_[0][0]; 377 const Texture::LevelInfo& first_face = level_infos_[0][0];
344 int levels_needed = TextureManager::ComputeMipMapCount( 378 int levels_needed = TextureManager::ComputeMipMapCount(
345 first_face.width, first_face.height, first_face.depth); 379 first_face.width, first_face.height, first_face.depth);
346 cleared_ = true; 380 bool cleared = true;
347 for (size_t ii = 0; ii < level_infos_.size(); ++ii) { 381 for (size_t ii = 0; ii < level_infos_.size(); ++ii) {
348 for (GLint jj = 0; jj < levels_needed; ++jj) { 382 for (GLint jj = 0; jj < levels_needed; ++jj) {
349 const Texture::LevelInfo& info = level_infos_[ii][jj]; 383 const Texture::LevelInfo& info = level_infos_[ii][jj];
350 if (info.width > 0 && info.height > 0 && info.depth > 0 && 384 if (info.width > 0 && info.height > 0 && info.depth > 0 &&
351 !info.cleared) { 385 !info.cleared) {
352 cleared_ = false; 386 cleared = false;
353 return; 387 break;
354 } 388 }
355 } 389 }
356 } 390 }
391 UpdateSafeToRenderFrom(cleared);
392 }
393
394 void Texture::UpdateSafeToRenderFrom(bool cleared) {
395 if (cleared_ == cleared)
396 return;
397 cleared_ = cleared;
398 int delta = cleared ? -1 : +1;
399 for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it)
400 (*it)->manager()->UpdateSafeToRenderFrom(delta);
401 }
402
403 void Texture::UpdateMipCleared(LevelInfo* info, bool cleared) {
404 if (info->cleared == cleared)
405 return;
406 info->cleared = cleared;
407 int delta = cleared ? -1 : +1;
408 num_uncleared_mips_ += delta;
409 for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it)
410 (*it)->manager()->UpdateUnclearedMips(delta);
411 }
412
413 void Texture::UpdateCanRenderCondition() {
414 CanRenderCondition can_render_condition = GetCanRenderCondition();
415 if (can_render_condition_ == can_render_condition)
416 return;
417 for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it)
418 (*it)->manager()->UpdateCanRenderCondition(can_render_condition_,
419 can_render_condition);
420 can_render_condition_ = can_render_condition;
421 }
422
423 void Texture::IncAllFramebufferStateChangeCount() {
424 for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it)
425 (*it)->manager()->IncFramebufferStateChangeCount();
426 }
427
428 AsyncPixelTransferState* Texture::GetAsyncTransferState() const {
429 for (RefSet::const_iterator it = refs_.begin(); it != refs_.end(); ++it) {
430 AsyncPixelTransferState* state = (*it)->async_transfer_state();
431 if (state)
432 return state;
433 }
434 return NULL;
357 } 435 }
358 436
359 void Texture::SetLevelInfo( 437 void Texture::SetLevelInfo(
360 const FeatureInfo* feature_info, 438 const FeatureInfo* feature_info,
361 GLenum target, 439 GLenum target,
362 GLint level, 440 GLint level,
363 GLenum internal_format, 441 GLenum internal_format,
364 GLsizei width, 442 GLsizei width,
365 GLsizei height, 443 GLsizei height,
366 GLsizei depth, 444 GLsizei depth,
(...skipping 20 matching lines...) Expand all
387 info.border = border; 465 info.border = border;
388 info.format = format; 466 info.format = format;
389 info.type = type; 467 info.type = type;
390 info.image = 0; 468 info.image = 0;
391 469
392 estimated_size_ -= info.estimated_size; 470 estimated_size_ -= info.estimated_size;
393 GLES2Util::ComputeImageDataSizes( 471 GLES2Util::ComputeImageDataSizes(
394 width, height, format, type, 4, &info.estimated_size, NULL, NULL); 472 width, height, format, type, 4, &info.estimated_size, NULL, NULL);
395 estimated_size_ += info.estimated_size; 473 estimated_size_ += info.estimated_size;
396 474
397 if (!info.cleared) { 475 UpdateMipCleared(&info, cleared);
398 DCHECK_NE(0, num_uncleared_mips_);
399 --num_uncleared_mips_;
400 }
401 info.cleared = cleared;
402 if (!info.cleared) {
403 ++num_uncleared_mips_;
404 }
405 max_level_set_ = std::max(max_level_set_, level); 476 max_level_set_ = std::max(max_level_set_, level);
406 Update(feature_info); 477 Update(feature_info);
407 UpdateCleared(); 478 UpdateCleared();
479 UpdateCanRenderCondition();
480 if (IsAttachedToFramebuffer()) {
481 // TODO(gman): If textures tracked which framebuffers they were attached to
482 // we could just mark those framebuffers as not complete.
483 IncAllFramebufferStateChangeCount();
484 }
408 } 485 }
409 486
410 bool Texture::ValidForTexture( 487 bool Texture::ValidForTexture(
411 GLint target, 488 GLint target,
412 GLint level, 489 GLint level,
413 GLint xoffset, 490 GLint xoffset,
414 GLint yoffset, 491 GLint yoffset,
415 GLsizei width, 492 GLsizei width,
416 GLsizei height, 493 GLsizei height,
417 GLenum format, 494 GLenum format,
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 case GL_TEXTURE_MAG_FILTER: 569 case GL_TEXTURE_MAG_FILTER:
493 if (!feature_info->validators()->texture_mag_filter_mode.IsValid(param)) { 570 if (!feature_info->validators()->texture_mag_filter_mode.IsValid(param)) {
494 return GL_INVALID_ENUM; 571 return GL_INVALID_ENUM;
495 } 572 }
496 mag_filter_ = param; 573 mag_filter_ = param;
497 break; 574 break;
498 case GL_TEXTURE_POOL_CHROMIUM: 575 case GL_TEXTURE_POOL_CHROMIUM:
499 if (!feature_info->validators()->texture_pool.IsValid(param)) { 576 if (!feature_info->validators()->texture_pool.IsValid(param)) {
500 return GL_INVALID_ENUM; 577 return GL_INVALID_ENUM;
501 } 578 }
502 manager_->GetMemTracker(pool_)->TrackMemFree(estimated_size()); 579 GetMemTracker()->TrackMemFree(estimated_size());
503 pool_ = param; 580 pool_ = param;
504 manager_->GetMemTracker(pool_)->TrackMemAlloc(estimated_size()); 581 GetMemTracker()->TrackMemAlloc(estimated_size());
505 break; 582 break;
506 case GL_TEXTURE_WRAP_S: 583 case GL_TEXTURE_WRAP_S:
507 if (!feature_info->validators()->texture_wrap_mode.IsValid(param)) { 584 if (!feature_info->validators()->texture_wrap_mode.IsValid(param)) {
508 return GL_INVALID_ENUM; 585 return GL_INVALID_ENUM;
509 } 586 }
510 wrap_s_ = param; 587 wrap_s_ = param;
511 break; 588 break;
512 case GL_TEXTURE_WRAP_T: 589 case GL_TEXTURE_WRAP_T:
513 if (!feature_info->validators()->texture_wrap_mode.IsValid(param)) { 590 if (!feature_info->validators()->texture_wrap_mode.IsValid(param)) {
514 return GL_INVALID_ENUM; 591 return GL_INVALID_ENUM;
(...skipping 10 matching lines...) Expand all
525 return GL_INVALID_ENUM; 602 return GL_INVALID_ENUM;
526 } 603 }
527 usage_ = param; 604 usage_ = param;
528 break; 605 break;
529 default: 606 default:
530 NOTREACHED(); 607 NOTREACHED();
531 return GL_INVALID_ENUM; 608 return GL_INVALID_ENUM;
532 } 609 }
533 Update(feature_info); 610 Update(feature_info);
534 UpdateCleared(); 611 UpdateCleared();
612 UpdateCanRenderCondition();
535 return GL_NO_ERROR; 613 return GL_NO_ERROR;
536 } 614 }
537 615
538 void Texture::Update(const FeatureInfo* feature_info) { 616 void Texture::Update(const FeatureInfo* feature_info) {
539 // Update npot status. 617 // Update npot status.
540 // Assume GL_TEXTURE_EXTERNAL_OES textures are npot, all others 618 // Assume GL_TEXTURE_EXTERNAL_OES textures are npot, all others
541 npot_ = target_ == GL_TEXTURE_EXTERNAL_OES; 619 npot_ = target_ == GL_TEXTURE_EXTERNAL_OES;
542 620
543 if (level_infos_.empty()) { 621 if (level_infos_.empty()) {
544 texture_complete_ = false; 622 texture_complete_ = false;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 info.type != level0.type) { 690 info.type != level0.type) {
613 texture_complete_ = false; 691 texture_complete_ = false;
614 break; 692 break;
615 } 693 }
616 } 694 }
617 } 695 }
618 } 696 }
619 697
620 bool Texture::ClearRenderableLevels(GLES2Decoder* decoder) { 698 bool Texture::ClearRenderableLevels(GLES2Decoder* decoder) {
621 DCHECK(decoder); 699 DCHECK(decoder);
622 if (SafeToRenderFrom()) { 700 if (cleared_) {
623 return true; 701 return true;
624 } 702 }
625 703
626 const Texture::LevelInfo& first_face = level_infos_[0][0]; 704 const Texture::LevelInfo& first_face = level_infos_[0][0];
627 int levels_needed = TextureManager::ComputeMipMapCount( 705 int levels_needed = TextureManager::ComputeMipMapCount(
628 first_face.width, first_face.height, first_face.depth); 706 first_face.width, first_face.height, first_face.depth);
629 707
630 for (size_t ii = 0; ii < level_infos_.size(); ++ii) { 708 for (size_t ii = 0; ii < level_infos_.size(); ++ii) {
631 for (GLint jj = 0; jj < levels_needed; ++jj) { 709 for (GLint jj = 0; jj < levels_needed; ++jj) {
632 Texture::LevelInfo& info = level_infos_[ii][jj]; 710 Texture::LevelInfo& info = level_infos_[ii][jj];
633 if (info.target != 0) { 711 if (info.target != 0) {
634 if (!ClearLevel(decoder, info.target, jj)) { 712 if (!ClearLevel(decoder, info.target, jj)) {
635 return false; 713 return false;
636 } 714 }
637 } 715 }
638 } 716 }
639 } 717 }
640 cleared_ = true; 718 UpdateSafeToRenderFrom(true);
641 return true; 719 return true;
642 } 720 }
643 721
644 bool Texture::IsLevelCleared(GLenum target, GLint level) const { 722 bool Texture::IsLevelCleared(GLenum target, GLint level) const {
645 size_t face_index = GLTargetToFaceIndex(target); 723 size_t face_index = GLTargetToFaceIndex(target);
646 if (face_index >= level_infos_.size() || 724 if (face_index >= level_infos_.size() ||
647 level >= static_cast<GLint>(level_infos_[face_index].size())) { 725 level >= static_cast<GLint>(level_infos_[face_index].size())) {
648 return true; 726 return true;
649 } 727 }
650 728
(...skipping 16 matching lines...) Expand all
667 DCHECK(target == info.target); 745 DCHECK(target == info.target);
668 746
669 if (info.target == 0 || 747 if (info.target == 0 ||
670 info.cleared || 748 info.cleared ||
671 info.width == 0 || 749 info.width == 0 ||
672 info.height == 0 || 750 info.height == 0 ||
673 info.depth == 0) { 751 info.depth == 0) {
674 return true; 752 return true;
675 } 753 }
676 754
677 DCHECK_NE(0, num_uncleared_mips_);
678 --num_uncleared_mips_;
679
680 // NOTE: It seems kind of gross to call back into the decoder for this 755 // NOTE: It seems kind of gross to call back into the decoder for this
681 // but only the decoder knows all the state (like unpack_alignment_) that's 756 // but only the decoder knows all the state (like unpack_alignment_) that's
682 // needed to be able to call GL correctly. 757 // needed to be able to call GL correctly.
683 info.cleared = decoder->ClearLevel( 758 bool cleared = decoder->ClearLevel(
684 service_id_, target_, info.target, info.level, info.format, info.type, 759 service_id_, target_, info.target, info.level, info.format, info.type,
685 info.width, info.height, immutable_); 760 info.width, info.height, immutable_);
686 if (!info.cleared) { 761 UpdateMipCleared(&info, cleared);
687 ++num_uncleared_mips_;
688 }
689 return info.cleared; 762 return info.cleared;
690 } 763 }
691 764
692 void Texture::SetLevelImage( 765 void Texture::SetLevelImage(
693 const FeatureInfo* feature_info, 766 const FeatureInfo* feature_info,
694 GLenum target, 767 GLenum target,
695 GLint level, 768 GLint level,
696 gfx::GLImage* image) { 769 gfx::GLImage* image) {
697 DCHECK_GE(level, 0); 770 DCHECK_GE(level, 0);
698 DCHECK_LT(static_cast<size_t>(GLTargetToFaceIndex(target)), 771 DCHECK_LT(static_cast<size_t>(GLTargetToFaceIndex(target)),
699 level_infos_.size()); 772 level_infos_.size());
700 DCHECK_LT(static_cast<size_t>(level), 773 DCHECK_LT(static_cast<size_t>(level),
701 level_infos_[GLTargetToFaceIndex(target)].size()); 774 level_infos_[GLTargetToFaceIndex(target)].size());
702 Texture::LevelInfo& info = 775 Texture::LevelInfo& info =
703 level_infos_[GLTargetToFaceIndex(target)][level]; 776 level_infos_[GLTargetToFaceIndex(target)][level];
704 DCHECK_EQ(info.target, target); 777 DCHECK_EQ(info.target, target);
705 DCHECK_EQ(info.level, level); 778 DCHECK_EQ(info.level, level);
706 info.image = image; 779 info.image = image;
780 UpdateCanRenderCondition();
707 } 781 }
708 782
709 gfx::GLImage* Texture::GetLevelImage( 783 gfx::GLImage* Texture::GetLevelImage(
710 GLint target, GLint level) const { 784 GLint target, GLint level) const {
711 size_t face_index = GLTargetToFaceIndex(target); 785 size_t face_index = GLTargetToFaceIndex(target);
712 if (level >= 0 && face_index < level_infos_.size() && 786 if (level >= 0 && face_index < level_infos_.size() &&
713 static_cast<size_t>(level) < level_infos_[face_index].size()) { 787 static_cast<size_t>(level) < level_infos_[face_index].size()) {
714 const LevelInfo& info = level_infos_[GLTargetToFaceIndex(target)][level]; 788 const LevelInfo& info = level_infos_[GLTargetToFaceIndex(target)][level];
715 if (info.target != 0) { 789 if (info.target != 0) {
716 return info.image; 790 return info.image;
717 } 791 }
718 } 792 }
719 return 0; 793 return 0;
720 } 794 }
721 795
796
797 TextureRef::TextureRef(TextureManager* manager, Texture* texture)
798 : manager_(manager),
799 texture_(texture) {
800 DCHECK(manager_);
801 DCHECK(texture_);
802 texture_->AddTextureRef(this);
803 manager_->StartTracking(this);
804 }
805
806 scoped_refptr<TextureRef> TextureRef::Create(TextureManager* manager,
807 GLuint service_id) {
808 return new TextureRef(manager, new Texture(service_id));
809 }
810
811 TextureRef::~TextureRef() {
812 manager_->StopTracking(this);
813 texture_->RemoveTextureRef(this, manager_->have_context_);
814 manager_ = NULL;
815 }
816
817
722 TextureManager::TextureManager( 818 TextureManager::TextureManager(
723 MemoryTracker* memory_tracker, 819 MemoryTracker* memory_tracker,
724 FeatureInfo* feature_info, 820 FeatureInfo* feature_info,
725 GLint max_texture_size, 821 GLint max_texture_size,
726 GLint max_cube_map_texture_size) 822 GLint max_cube_map_texture_size)
727 : memory_tracker_managed_( 823 : memory_tracker_managed_(
728 new MemoryTypeTracker(memory_tracker, MemoryTracker::kManaged)), 824 new MemoryTypeTracker(memory_tracker, MemoryTracker::kManaged)),
729 memory_tracker_unmanaged_( 825 memory_tracker_unmanaged_(
730 new MemoryTypeTracker(memory_tracker, MemoryTracker::kUnmanaged)), 826 new MemoryTypeTracker(memory_tracker, MemoryTracker::kUnmanaged)),
731 feature_info_(feature_info), 827 feature_info_(feature_info),
828 framebuffer_manager_(NULL),
732 max_texture_size_(max_texture_size), 829 max_texture_size_(max_texture_size),
733 max_cube_map_texture_size_(max_cube_map_texture_size), 830 max_cube_map_texture_size_(max_cube_map_texture_size),
734 max_levels_(ComputeMipMapCount(max_texture_size, 831 max_levels_(ComputeMipMapCount(max_texture_size,
735 max_texture_size, 832 max_texture_size,
736 max_texture_size)), 833 max_texture_size)),
737 max_cube_map_levels_(ComputeMipMapCount(max_cube_map_texture_size, 834 max_cube_map_levels_(ComputeMipMapCount(max_cube_map_texture_size,
738 max_cube_map_texture_size, 835 max_cube_map_texture_size,
739 max_cube_map_texture_size)), 836 max_cube_map_texture_size)),
740 num_unrenderable_textures_(0), 837 num_unrenderable_textures_(0),
741 num_unsafe_textures_(0), 838 num_unsafe_textures_(0),
(...skipping 21 matching lines...) Expand all
763 } 860 }
764 861
765 if (feature_info_->feature_flags().arb_texture_rectangle) { 862 if (feature_info_->feature_flags().arb_texture_rectangle) {
766 default_textures_[kRectangleARB] = CreateDefaultAndBlackTextures( 863 default_textures_[kRectangleARB] = CreateDefaultAndBlackTextures(
767 GL_TEXTURE_RECTANGLE_ARB, &black_texture_ids_[kRectangleARB]); 864 GL_TEXTURE_RECTANGLE_ARB, &black_texture_ids_[kRectangleARB]);
768 } 865 }
769 866
770 return true; 867 return true;
771 } 868 }
772 869
773 scoped_refptr<Texture> 870 scoped_refptr<TextureRef>
774 TextureManager::CreateDefaultAndBlackTextures( 871 TextureManager::CreateDefaultAndBlackTextures(
775 GLenum target, 872 GLenum target,
776 GLuint* black_texture) { 873 GLuint* black_texture) {
777 static uint8 black[] = {0, 0, 0, 255}; 874 static uint8 black[] = {0, 0, 0, 255};
778 875
779 // Sampling a texture not associated with any EGLImage sibling will return 876 // Sampling a texture not associated with any EGLImage sibling will return
780 // black values according to the spec. 877 // black values according to the spec.
781 bool needs_initialization = (target != GL_TEXTURE_EXTERNAL_OES); 878 bool needs_initialization = (target != GL_TEXTURE_EXTERNAL_OES);
782 bool needs_faces = (target == GL_TEXTURE_CUBE_MAP); 879 bool needs_faces = (target == GL_TEXTURE_CUBE_MAP);
783 880
784 // Make default textures and texture for replacing non-renderable textures. 881 // Make default textures and texture for replacing non-renderable textures.
785 GLuint ids[2]; 882 GLuint ids[2];
786 glGenTextures(arraysize(ids), ids); 883 glGenTextures(arraysize(ids), ids);
787 for (unsigned long ii = 0; ii < arraysize(ids); ++ii) { 884 for (unsigned long ii = 0; ii < arraysize(ids); ++ii) {
788 glBindTexture(target, ids[ii]); 885 glBindTexture(target, ids[ii]);
789 if (needs_initialization) { 886 if (needs_initialization) {
790 if (needs_faces) { 887 if (needs_faces) {
791 for (int jj = 0; jj < GLES2Util::kNumFaces; ++jj) { 888 for (int jj = 0; jj < GLES2Util::kNumFaces; ++jj) {
792 glTexImage2D(GLES2Util::IndexToGLFaceTarget(jj), 0, GL_RGBA, 1, 1, 0, 889 glTexImage2D(GLES2Util::IndexToGLFaceTarget(jj), 0, GL_RGBA, 1, 1, 0,
793 GL_RGBA, GL_UNSIGNED_BYTE, black); 890 GL_RGBA, GL_UNSIGNED_BYTE, black);
794 } 891 }
795 } else { 892 } else {
796 glTexImage2D(target, 0, GL_RGBA, 1, 1, 0, GL_RGBA, 893 glTexImage2D(target, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
797 GL_UNSIGNED_BYTE, black); 894 GL_UNSIGNED_BYTE, black);
798 } 895 }
799 } 896 }
800 } 897 }
801 glBindTexture(target, 0); 898 glBindTexture(target, 0);
802 899
803 // Since we are manually setting up these textures 900 scoped_refptr<TextureRef> default_texture(TextureRef::Create(this, ids[1]));
804 // we need to manually manipulate some of the their bookkeeping.
805 ++num_unrenderable_textures_;
806 scoped_refptr<Texture> default_texture(new Texture(this, ids[1]));
807 SetTarget(default_texture, target); 901 SetTarget(default_texture, target);
808 if (needs_faces) { 902 if (needs_faces) {
809 for (int ii = 0; ii < GLES2Util::kNumFaces; ++ii) { 903 for (int ii = 0; ii < GLES2Util::kNumFaces; ++ii) {
810 SetLevelInfo( 904 SetLevelInfo(
811 default_texture, GLES2Util::IndexToGLFaceTarget(ii), 905 default_texture, GLES2Util::IndexToGLFaceTarget(ii),
812 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); 906 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true);
813 } 907 }
814 } else { 908 } else {
815 if (needs_initialization) { 909 if (needs_initialization) {
816 SetLevelInfo(default_texture, 910 SetLevelInfo(default_texture,
(...skipping 22 matching lines...) Expand all
839 height <= max_size && 933 height <= max_size &&
840 depth <= max_size && 934 depth <= max_size &&
841 (level == 0 || feature_info_->feature_flags().npot_ok || 935 (level == 0 || feature_info_->feature_flags().npot_ok ||
842 (!GLES2Util::IsNPOT(width) && 936 (!GLES2Util::IsNPOT(width) &&
843 !GLES2Util::IsNPOT(height) && 937 !GLES2Util::IsNPOT(height) &&
844 !GLES2Util::IsNPOT(depth))) && 938 !GLES2Util::IsNPOT(depth))) &&
845 (target != GL_TEXTURE_CUBE_MAP || (width == height && depth == 1)) && 939 (target != GL_TEXTURE_CUBE_MAP || (width == height && depth == 1)) &&
846 (target != GL_TEXTURE_2D || (depth == 1)); 940 (target != GL_TEXTURE_2D || (depth == 1));
847 } 941 }
848 942
849 void TextureManager::SetTarget(Texture* texture, GLenum target) { 943 void TextureManager::SetTarget(TextureRef* ref, GLenum target) {
850 DCHECK(texture); 944 DCHECK(ref);
851 if (!texture->CanRender(feature_info_)) { 945 ref->texture()->SetTarget(feature_info_, target, MaxLevelsForTarget(target));
852 DCHECK_NE(0, num_unrenderable_textures_);
853 --num_unrenderable_textures_;
854 }
855 texture->SetTarget(feature_info_, target, MaxLevelsForTarget(target));
856 if (!texture->CanRender(feature_info_)) {
857 ++num_unrenderable_textures_;
858 }
859 } 946 }
860 947
861 void TextureManager::SetStreamTexture(Texture* texture, bool stream_texture) { 948 void TextureManager::SetStreamTexture(TextureRef* ref, bool stream_texture) {
862 DCHECK(texture); 949 DCHECK(ref);
863 if (!texture->CanRender(feature_info_)) { 950 ref->texture()->SetStreamTexture(stream_texture);
864 DCHECK_NE(0, num_unrenderable_textures_);
865 --num_unrenderable_textures_;
866 }
867 texture->SetStreamTexture(stream_texture);
868 if (!texture->CanRender(feature_info_)) {
869 ++num_unrenderable_textures_;
870 }
871 } 951 }
872 952
873 void TextureManager::SetLevelCleared(Texture* texture, 953 void TextureManager::SetLevelCleared(TextureRef* ref,
874 GLenum target, 954 GLenum target,
875 GLint level, 955 GLint level,
876 bool cleared) { 956 bool cleared) {
877 DCHECK(texture); 957 DCHECK(ref);
878 if (!texture->SafeToRenderFrom()) { 958 ref->texture()->SetLevelCleared(target, level, cleared);
879 DCHECK_NE(0, num_unsafe_textures_);
880 --num_unsafe_textures_;
881 }
882 num_uncleared_mips_ -= texture->num_uncleared_mips();
883 DCHECK_GE(num_uncleared_mips_, 0);
884 texture->SetLevelCleared(target, level, cleared);
885 num_uncleared_mips_ += texture->num_uncleared_mips();
886 if (!texture->SafeToRenderFrom()) {
887 ++num_unsafe_textures_;
888 }
889 } 959 }
890 960
891 bool TextureManager::ClearRenderableLevels( 961 bool TextureManager::ClearRenderableLevels(
892 GLES2Decoder* decoder,Texture* texture) { 962 GLES2Decoder* decoder, TextureRef* ref) {
893 DCHECK(texture); 963 DCHECK(ref);
894 if (texture->SafeToRenderFrom()) { 964 return ref->texture()->ClearRenderableLevels(decoder);
895 return true;
896 }
897 DCHECK_NE(0, num_unsafe_textures_);
898 --num_unsafe_textures_;
899 num_uncleared_mips_ -= texture->num_uncleared_mips();
900 DCHECK_GE(num_uncleared_mips_, 0);
901 bool result = texture->ClearRenderableLevels(decoder);
902 num_uncleared_mips_ += texture->num_uncleared_mips();
903 if (!texture->SafeToRenderFrom()) {
904 ++num_unsafe_textures_;
905 }
906 return result;
907 } 965 }
908 966
909 bool TextureManager::ClearTextureLevel( 967 bool TextureManager::ClearTextureLevel(
910 GLES2Decoder* decoder,Texture* texture, 968 GLES2Decoder* decoder, TextureRef* ref,
911 GLenum target, GLint level) { 969 GLenum target, GLint level) {
912 DCHECK(texture); 970 DCHECK(ref);
971 Texture* texture = ref->texture();
913 if (texture->num_uncleared_mips() == 0) { 972 if (texture->num_uncleared_mips() == 0) {
914 return true; 973 return true;
915 } 974 }
916 num_uncleared_mips_ -= texture->num_uncleared_mips();
917 DCHECK_GE(num_uncleared_mips_, 0);
918 if (!texture->SafeToRenderFrom()) {
919 DCHECK_NE(0, num_unsafe_textures_);
920 --num_unsafe_textures_;
921 }
922 bool result = texture->ClearLevel(decoder, target, level); 975 bool result = texture->ClearLevel(decoder, target, level);
923 texture->UpdateCleared(); 976 texture->UpdateCleared();
924 num_uncleared_mips_ += texture->num_uncleared_mips();
925 if (!texture->SafeToRenderFrom()) {
926 ++num_unsafe_textures_;
927 }
928 return result; 977 return result;
929 } 978 }
930 979
931 void TextureManager::SetLevelInfo( 980 void TextureManager::SetLevelInfo(
932 Texture* texture, 981 TextureRef* ref,
933 GLenum target, 982 GLenum target,
934 GLint level, 983 GLint level,
935 GLenum internal_format, 984 GLenum internal_format,
936 GLsizei width, 985 GLsizei width,
937 GLsizei height, 986 GLsizei height,
938 GLsizei depth, 987 GLsizei depth,
939 GLint border, 988 GLint border,
940 GLenum format, 989 GLenum format,
941 GLenum type, 990 GLenum type,
942 bool cleared) { 991 bool cleared) {
943 DCHECK(texture); 992 DCHECK(ref);
944 if (!texture->CanRender(feature_info_)) { 993 Texture* texture = ref->texture();
945 DCHECK_NE(0, num_unrenderable_textures_);
946 --num_unrenderable_textures_;
947 }
948 if (!texture->SafeToRenderFrom()) {
949 DCHECK_NE(0, num_unsafe_textures_);
950 --num_unsafe_textures_;
951 }
952 num_uncleared_mips_ -= texture->num_uncleared_mips();
953 DCHECK_GE(num_uncleared_mips_, 0);
954 994
955 GetMemTracker(texture->pool_)->TrackMemFree(texture->estimated_size()); 995 texture->GetMemTracker()->TrackMemFree(texture->estimated_size());
956 texture->SetLevelInfo( 996 texture->SetLevelInfo(
957 feature_info_, target, level, internal_format, width, height, depth, 997 feature_info_, target, level, internal_format, width, height, depth,
958 border, format, type, cleared); 998 border, format, type, cleared);
959 GetMemTracker(texture->pool_)->TrackMemAlloc(texture->estimated_size()); 999 texture->GetMemTracker()->TrackMemAlloc(texture->estimated_size());
960
961 num_uncleared_mips_ += texture->num_uncleared_mips();
962 if (!texture->CanRender(feature_info_)) {
963 ++num_unrenderable_textures_;
964 }
965 if (!texture->SafeToRenderFrom()) {
966 ++num_unsafe_textures_;
967 }
968 } 1000 }
969 1001
970 TextureDefinition* TextureManager::Save(Texture* texture) { 1002 TextureDefinition* TextureManager::Save(TextureRef* ref) {
1003 DCHECK(ref);
1004 Texture* texture = ref->texture();
971 DCHECK(texture->owned_); 1005 DCHECK(texture->owned_);
972 1006
973 if (texture->IsAttachedToFramebuffer()) 1007 if (texture->IsAttachedToFramebuffer())
974 return NULL; 1008 return NULL;
975 1009
976 TextureDefinition::LevelInfos level_infos(texture->level_infos_.size()); 1010 TextureDefinition::LevelInfos level_infos(texture->level_infos_.size());
977 for (size_t face = 0; face < level_infos.size(); ++face) { 1011 for (size_t face = 0; face < level_infos.size(); ++face) {
978 GLenum target = 1012 GLenum target =
979 texture->target() == GL_TEXTURE_CUBE_MAP ? FaceIndexToGLTarget(face) 1013 texture->target() == GL_TEXTURE_CUBE_MAP ? FaceIndexToGLTarget(face)
980 : texture->target(); 1014 : texture->target();
981 for (GLint level = 0; level <= texture->max_level_set_; ++level) { 1015 for (GLint level = 0; level <= texture->max_level_set_; ++level) {
982 const Texture::LevelInfo& level_info = 1016 const Texture::LevelInfo& level_info =
983 texture->level_infos_[face][level]; 1017 texture->level_infos_[face][level];
984 1018
985 level_infos[face].push_back( 1019 level_infos[face].push_back(
986 TextureDefinition::LevelInfo(target, 1020 TextureDefinition::LevelInfo(target,
987 level_info.internal_format, 1021 level_info.internal_format,
988 level_info.width, 1022 level_info.width,
989 level_info.height, 1023 level_info.height,
990 level_info.depth, 1024 level_info.depth,
991 level_info.border, 1025 level_info.border,
992 level_info.format, 1026 level_info.format,
993 level_info.type, 1027 level_info.type,
994 level_info.cleared)); 1028 level_info.cleared));
995 1029
996 SetLevelInfo(texture, 1030 SetLevelInfo(ref,
997 target, 1031 target,
998 level, 1032 level,
999 GL_RGBA, 1033 GL_RGBA,
1000 0, 1034 0,
1001 0, 1035 0,
1002 0, 1036 0,
1003 0, 1037 0,
1004 GL_RGBA, 1038 GL_RGBA,
1005 GL_UNSIGNED_BYTE, 1039 GL_UNSIGNED_BYTE,
1006 true); 1040 true);
(...skipping 18 matching lines...) Expand all
1025 texture->wrap_t(), 1059 texture->wrap_t(),
1026 texture->usage(), 1060 texture->usage(),
1027 immutable, 1061 immutable,
1028 stream_texture, 1062 stream_texture,
1029 level_infos); 1063 level_infos);
1030 } 1064 }
1031 1065
1032 bool TextureManager::Restore( 1066 bool TextureManager::Restore(
1033 const char* function_name, 1067 const char* function_name,
1034 GLES2Decoder* decoder, 1068 GLES2Decoder* decoder,
1035 Texture* texture, 1069 TextureRef* ref,
1036 TextureDefinition* definition) { 1070 TextureDefinition* definition) {
1071 DCHECK(ref);
1072 Texture* texture = ref->texture();
1037 DCHECK(texture->owned_); 1073 DCHECK(texture->owned_);
1038 1074
1039 scoped_ptr<TextureDefinition> scoped_definition(definition); 1075 scoped_ptr<TextureDefinition> scoped_definition(definition);
1040 1076
1041 if (texture->IsAttachedToFramebuffer()) 1077 if (texture->IsAttachedToFramebuffer())
1042 return false; 1078 return false;
1043 1079
1044 if (texture->target() != definition->target()) 1080 if (texture->target() != definition->target())
1045 return false; 1081 return false;
1046 1082
1047 if (texture->level_infos_.size() < definition->level_infos().size()) 1083 if (texture->level_infos_.size() < definition->level_infos().size())
1048 return false; 1084 return false;
1049 1085
1050 if (texture->level_infos_[0].size() < definition->level_infos()[0].size()) 1086 if (texture->level_infos_[0].size() < definition->level_infos()[0].size())
1051 return false; 1087 return false;
1052 1088
1053 for (size_t face = 0; face < definition->level_infos().size(); ++face) { 1089 for (size_t face = 0; face < definition->level_infos().size(); ++face) {
1054 GLenum target = 1090 GLenum target =
1055 texture->target() == GL_TEXTURE_CUBE_MAP ? FaceIndexToGLTarget(face) 1091 texture->target() == GL_TEXTURE_CUBE_MAP ? FaceIndexToGLTarget(face)
1056 : texture->target(); 1092 : texture->target();
1057 GLint new_max_level = definition->level_infos()[face].size() - 1; 1093 GLint new_max_level = definition->level_infos()[face].size() - 1;
1058 for (GLint level = 0; 1094 for (GLint level = 0;
1059 level <= std::max(texture->max_level_set_, new_max_level); 1095 level <= std::max(texture->max_level_set_, new_max_level);
1060 ++level) { 1096 ++level) {
1061 const TextureDefinition::LevelInfo& level_info = 1097 const TextureDefinition::LevelInfo& level_info =
1062 level <= new_max_level ? definition->level_infos()[face][level] 1098 level <= new_max_level ? definition->level_infos()[face][level]
1063 : TextureDefinition::LevelInfo(); 1099 : TextureDefinition::LevelInfo();
1064 SetLevelInfo(texture, 1100 SetLevelInfo(ref,
1065 target, 1101 target,
1066 level, 1102 level,
1067 level_info.internal_format, 1103 level_info.internal_format,
1068 level_info.width, 1104 level_info.width,
1069 level_info.height, 1105 level_info.height,
1070 level_info.depth, 1106 level_info.depth,
1071 level_info.border, 1107 level_info.border,
1072 level_info.format, 1108 level_info.format,
1073 level_info.type, 1109 level_info.type,
1074 level_info.cleared); 1110 level_info.cleared);
1075 } 1111 }
1076 } 1112 }
1077 1113
1078 GLuint old_service_id = texture->service_id(); 1114 GLuint old_service_id = texture->service_id();
1079 glDeleteTextures(1, &old_service_id); 1115 glDeleteTextures(1, &old_service_id);
1080 texture->SetServiceId(definition->ReleaseServiceId()); 1116 texture->SetServiceId(definition->ReleaseServiceId());
1081 glBindTexture(texture->target(), texture->service_id()); 1117 glBindTexture(texture->target(), texture->service_id());
1082 texture->SetImmutable(definition->immutable()); 1118 texture->SetImmutable(definition->immutable());
1083 texture->SetStreamTexture(definition->stream_texture()); 1119 texture->SetStreamTexture(definition->stream_texture());
1084
1085 ErrorState* error_state = decoder->GetErrorState(); 1120 ErrorState* error_state = decoder->GetErrorState();
1086 SetParameter(function_name, error_state, texture, GL_TEXTURE_MIN_FILTER, 1121 SetParameter(function_name, error_state, ref, GL_TEXTURE_MIN_FILTER,
1087 definition->min_filter()); 1122 definition->min_filter());
1088 SetParameter(function_name, error_state, texture, GL_TEXTURE_MAG_FILTER, 1123 SetParameter(function_name, error_state, ref, GL_TEXTURE_MAG_FILTER,
1089 definition->mag_filter()); 1124 definition->mag_filter());
1090 SetParameter(function_name, error_state, texture, GL_TEXTURE_WRAP_S, 1125 SetParameter(function_name, error_state, ref, GL_TEXTURE_WRAP_S,
1091 definition->wrap_s()); 1126 definition->wrap_s());
1092 SetParameter(function_name, error_state, texture, GL_TEXTURE_WRAP_T, 1127 SetParameter(function_name, error_state, ref, GL_TEXTURE_WRAP_T,
1093 definition->wrap_t()); 1128 definition->wrap_t());
1094 if (feature_info_->validators()->texture_parameter.IsValid( 1129 if (feature_info_->validators()->texture_parameter.IsValid(
1095 GL_TEXTURE_USAGE_ANGLE)) { 1130 GL_TEXTURE_USAGE_ANGLE)) {
1096 SetParameter(function_name, error_state, texture, GL_TEXTURE_USAGE_ANGLE, 1131 SetParameter(function_name, error_state, ref, GL_TEXTURE_USAGE_ANGLE,
1097 definition->usage()); 1132 definition->usage());
1098 } 1133 }
1099 1134
1100 return true; 1135 return true;
1101 } 1136 }
1102 1137
1103 void TextureManager::SetParameter( 1138 void TextureManager::SetParameter(
1104 const char* function_name, ErrorState* error_state, 1139 const char* function_name, ErrorState* error_state,
1105 Texture* texture, GLenum pname, GLint param) { 1140 TextureRef* ref, GLenum pname, GLint param) {
1106 DCHECK(error_state); 1141 DCHECK(error_state);
1107 DCHECK(texture); 1142 DCHECK(ref);
1108 if (!texture->CanRender(feature_info_)) { 1143 Texture* texture = ref->texture();
1109 DCHECK_NE(0, num_unrenderable_textures_);
1110 --num_unrenderable_textures_;
1111 }
1112 if (!texture->SafeToRenderFrom()) {
1113 DCHECK_NE(0, num_unsafe_textures_);
1114 --num_unsafe_textures_;
1115 }
1116 GLenum result = texture->SetParameter(feature_info_, pname, param); 1144 GLenum result = texture->SetParameter(feature_info_, pname, param);
1117 if (result != GL_NO_ERROR) { 1145 if (result != GL_NO_ERROR) {
1118 if (result == GL_INVALID_ENUM) { 1146 if (result == GL_INVALID_ENUM) {
1119 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM( 1147 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(
1120 error_state, function_name, param, "param"); 1148 error_state, function_name, param, "param");
1121 } else { 1149 } else {
1122 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM( 1150 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(
1123 error_state, result, function_name, pname, static_cast<GLint>(param)); 1151 error_state, result, function_name, pname, static_cast<GLint>(param));
1124 } 1152 }
1125 } else { 1153 } else {
1126 // Texture tracking pools exist only for the command decoder, so 1154 // Texture tracking pools exist only for the command decoder, so
1127 // do not pass them on to the native GL implementation. 1155 // do not pass them on to the native GL implementation.
1128 if (pname != GL_TEXTURE_POOL_CHROMIUM) { 1156 if (pname != GL_TEXTURE_POOL_CHROMIUM) {
1129 glTexParameteri(texture->target(), pname, param); 1157 glTexParameteri(texture->target(), pname, param);
1130 } 1158 }
1131 } 1159 }
1132
1133 if (!texture->CanRender(feature_info_)) {
1134 ++num_unrenderable_textures_;
1135 }
1136 if (!texture->SafeToRenderFrom()) {
1137 ++num_unsafe_textures_;
1138 }
1139 } 1160 }
1140 1161
1141 bool TextureManager::MarkMipmapsGenerated(Texture* texture) { 1162 bool TextureManager::MarkMipmapsGenerated(TextureRef* ref) {
1142 DCHECK(texture); 1163 DCHECK(ref);
1143 if (!texture->CanRender(feature_info_)) { 1164 Texture* texture = ref->texture();
1144 DCHECK_NE(0, num_unrenderable_textures_); 1165 texture->GetMemTracker()->TrackMemFree(texture->estimated_size());
1145 --num_unrenderable_textures_;
1146 }
1147 if (!texture->SafeToRenderFrom()) {
1148 DCHECK_NE(0, num_unsafe_textures_);
1149 --num_unsafe_textures_;
1150 }
1151 num_uncleared_mips_ -= texture->num_uncleared_mips();
1152 DCHECK_GE(num_uncleared_mips_, 0);
1153 GetMemTracker(texture->pool_)->TrackMemFree(texture->estimated_size());
1154 bool result = texture->MarkMipmapsGenerated(feature_info_); 1166 bool result = texture->MarkMipmapsGenerated(feature_info_);
1155 GetMemTracker(texture->pool_)->TrackMemAlloc(texture->estimated_size()); 1167 texture->GetMemTracker()->TrackMemAlloc(texture->estimated_size());
1156
1157 num_uncleared_mips_ += texture->num_uncleared_mips();
1158 if (!texture->CanRender(feature_info_)) {
1159 ++num_unrenderable_textures_;
1160 }
1161 if (!texture->SafeToRenderFrom()) {
1162 ++num_unsafe_textures_;
1163 }
1164 return result; 1168 return result;
1165 } 1169 }
1166 1170
1167 Texture* TextureManager::CreateTexture( 1171 TextureRef* TextureManager::CreateTexture(
1168 GLuint client_id, GLuint service_id) { 1172 GLuint client_id, GLuint service_id) {
1169 DCHECK_NE(0u, service_id); 1173 DCHECK_NE(0u, service_id);
1170 scoped_refptr<Texture> texture(new Texture(this, service_id)); 1174 scoped_refptr<TextureRef> ref(TextureRef::Create(this, service_id));
1171 std::pair<TextureMap::iterator, bool> result = 1175 std::pair<TextureMap::iterator, bool> result =
1172 textures_.insert(std::make_pair(client_id, texture)); 1176 textures_.insert(std::make_pair(client_id, ref));
1173 DCHECK(result.second); 1177 DCHECK(result.second);
1174 if (!texture->CanRender(feature_info_)) { 1178 return ref.get();
1175 ++num_unrenderable_textures_;
1176 }
1177 if (!texture->SafeToRenderFrom()) {
1178 ++num_unsafe_textures_;
1179 }
1180 num_uncleared_mips_ += texture->num_uncleared_mips();
1181 return texture.get();
1182 } 1179 }
1183 1180
1184 Texture* TextureManager::GetTexture( 1181 TextureRef* TextureManager::GetTexture(
1185 GLuint client_id) const { 1182 GLuint client_id) const {
1186 TextureMap::const_iterator it = textures_.find(client_id); 1183 TextureMap::const_iterator it = textures_.find(client_id);
1187 return it != textures_.end() ? it->second : NULL; 1184 return it != textures_.end() ? it->second : NULL;
1188 } 1185 }
1189 1186
1190 void TextureManager::RemoveTexture(GLuint client_id) { 1187 void TextureManager::RemoveTexture(GLuint client_id) {
1191 TextureMap::iterator it = textures_.find(client_id); 1188 TextureMap::iterator it = textures_.find(client_id);
1192 if (it != textures_.end()) { 1189 if (it != textures_.end()) {
1193 Texture* texture = it->second;
1194 texture->MarkAsDeleted();
1195 textures_.erase(it); 1190 textures_.erase(it);
1196 } 1191 }
1197 } 1192 }
1198 1193
1199 void TextureManager::StartTracking(Texture* /* texture */) { 1194 void TextureManager::StartTracking(TextureRef* ref) {
1195 Texture* texture = ref->texture();
1200 ++texture_count_; 1196 ++texture_count_;
1197 num_uncleared_mips_ += texture->num_uncleared_mips();
1198 if (!texture->SafeToRenderFrom())
1199 ++num_unsafe_textures_;
1200 if (!texture->CanRender(feature_info_))
1201 ++num_unrenderable_textures_;
1201 } 1202 }
1202 1203
1203 void TextureManager::StopTracking(Texture* texture) { 1204 void TextureManager::StopTracking(TextureRef* ref) {
1205 Texture* texture = ref->texture();
1204 --texture_count_; 1206 --texture_count_;
1205 if (!texture->CanRender(feature_info_)) { 1207 if (!texture->CanRender(feature_info_)) {
1206 DCHECK_NE(0, num_unrenderable_textures_); 1208 DCHECK_NE(0, num_unrenderable_textures_);
1207 --num_unrenderable_textures_; 1209 --num_unrenderable_textures_;
1208 } 1210 }
1209 if (!texture->SafeToRenderFrom()) { 1211 if (!texture->SafeToRenderFrom()) {
1210 DCHECK_NE(0, num_unsafe_textures_); 1212 DCHECK_NE(0, num_unsafe_textures_);
1211 --num_unsafe_textures_; 1213 --num_unsafe_textures_;
1212 } 1214 }
1213 num_uncleared_mips_ -= texture->num_uncleared_mips(); 1215 num_uncleared_mips_ -= texture->num_uncleared_mips();
1214 DCHECK_GE(num_uncleared_mips_, 0); 1216 DCHECK_GE(num_uncleared_mips_, 0);
1215 GetMemTracker(texture->pool_)->TrackMemFree(texture->estimated_size());
1216 } 1217 }
1217 1218
1218 MemoryTypeTracker* TextureManager::GetMemTracker(GLenum tracking_pool) { 1219 MemoryTypeTracker* TextureManager::GetMemTracker(GLenum tracking_pool) {
1219 switch(tracking_pool) { 1220 switch(tracking_pool) {
1220 case GL_TEXTURE_POOL_MANAGED_CHROMIUM: 1221 case GL_TEXTURE_POOL_MANAGED_CHROMIUM:
1221 return memory_tracker_managed_.get(); 1222 return memory_tracker_managed_.get();
1222 break; 1223 break;
1223 case GL_TEXTURE_POOL_UNMANAGED_CHROMIUM: 1224 case GL_TEXTURE_POOL_UNMANAGED_CHROMIUM:
1224 return memory_tracker_unmanaged_.get(); 1225 return memory_tracker_unmanaged_.get();
1225 break; 1226 break;
1226 default: 1227 default:
1227 break; 1228 break;
1228 } 1229 }
1229 NOTREACHED(); 1230 NOTREACHED();
1230 return NULL; 1231 return NULL;
1231 } 1232 }
1232 1233
1233 bool TextureManager::GetClientId(GLuint service_id, GLuint* client_id) const { 1234 bool TextureManager::GetClientId(GLuint service_id, GLuint* client_id) const {
1234 // This doesn't need to be fast. It's only used during slow queries. 1235 // This doesn't need to be fast. It's only used during slow queries.
1235 for (TextureMap::const_iterator it = textures_.begin(); 1236 for (TextureMap::const_iterator it = textures_.begin();
1236 it != textures_.end(); ++it) { 1237 it != textures_.end(); ++it) {
1237 if (it->second->service_id() == service_id) { 1238 if (it->second->texture()->service_id() == service_id) {
1238 *client_id = it->first; 1239 *client_id = it->first;
1239 return true; 1240 return true;
1240 } 1241 }
1241 } 1242 }
1242 return false; 1243 return false;
1243 } 1244 }
1244 1245
1245 GLsizei TextureManager::ComputeMipMapCount( 1246 GLsizei TextureManager::ComputeMipMapCount(
1246 GLsizei width, GLsizei height, GLsizei depth) { 1247 GLsizei width, GLsizei height, GLsizei depth) {
1247 return 1 + base::bits::Log2Floor(std::max(std::max(width, height), depth)); 1248 return 1 + base::bits::Log2Floor(std::max(std::max(width, height), depth));
1248 } 1249 }
1249 1250
1250 void TextureManager::SetLevelImage( 1251 void TextureManager::SetLevelImage(
1251 Texture* texture, 1252 TextureRef* ref,
1252 GLenum target, 1253 GLenum target,
1253 GLint level, 1254 GLint level,
1254 gfx::GLImage* image) { 1255 gfx::GLImage* image) {
1255 DCHECK(texture); 1256 DCHECK(ref);
1256 if (!texture->CanRender(feature_info_)) { 1257 ref->texture()->SetLevelImage(feature_info_, target, level, image);
1257 DCHECK_NE(0, num_unrenderable_textures_);
1258 --num_unrenderable_textures_;
1259 }
1260 if (!texture->SafeToRenderFrom()) {
1261 DCHECK_NE(0, num_unsafe_textures_);
1262 --num_unsafe_textures_;
1263 }
1264 texture->SetLevelImage(feature_info_, target, level, image);
1265 if (!texture->CanRender(feature_info_)) {
1266 ++num_unrenderable_textures_;
1267 }
1268 if (!texture->SafeToRenderFrom()) {
1269 ++num_unsafe_textures_;
1270 }
1271 } 1258 }
1272 1259
1273 void TextureManager::AddToSignature( 1260 void TextureManager::AddToSignature(
1274 Texture* texture, 1261 TextureRef* ref,
1275 GLenum target, 1262 GLenum target,
1276 GLint level, 1263 GLint level,
1277 std::string* signature) const { 1264 std::string* signature) const {
1278 texture->AddToSignature(feature_info_.get(), target, level, signature); 1265 ref->texture()->AddToSignature(feature_info_.get(), target, level, signature);
1266 }
1267
1268 void TextureManager::UpdateSafeToRenderFrom(int delta) {
1269 num_unsafe_textures_ += delta;
1270 DCHECK_GE(num_unsafe_textures_, 0);
1271 }
1272
1273 void TextureManager::UpdateUnclearedMips(int delta) {
1274 num_uncleared_mips_ += delta;
1275 DCHECK_GE(num_uncleared_mips_, 0);
1276 }
1277
1278 void TextureManager::UpdateCanRenderCondition(
1279 Texture::CanRenderCondition old_condition,
1280 Texture::CanRenderCondition new_condition) {
1281 if (old_condition == Texture::CAN_RENDER_NEVER ||
1282 (old_condition == Texture::CAN_RENDER_ONLY_IF_NPOT &&
1283 !feature_info_->feature_flags().npot_ok)) {
1284 DCHECK_GT(num_unrenderable_textures_, 0);
1285 --num_unrenderable_textures_;
1286 }
1287 if (new_condition == Texture::CAN_RENDER_NEVER ||
1288 (new_condition == Texture::CAN_RENDER_ONLY_IF_NPOT &&
1289 !feature_info_->feature_flags().npot_ok))
1290 ++num_unrenderable_textures_;
1291 }
1292
1293 void TextureManager::IncFramebufferStateChangeCount() {
1294 if (framebuffer_manager_)
1295 framebuffer_manager_->IncFramebufferStateChangeCount();
1296
1279 } 1297 }
1280 1298
1281 } // namespace gles2 1299 } // namespace gles2
1282 } // namespace gpu 1300 } // 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