Chromium Code Reviews| 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 #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 Loading... | |
| 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 Loading... | |
| 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 |
| 186 Texture::CanRenderCondition Texture::GetCanRenderCondition() const { | |
|
piman
2013/05/14 01:34:50
Note: this function should encode the logic that w
| |
| 187 if (target_ == 0) | |
| 188 return CAN_RENDER_NEVER; | |
| 189 | |
| 190 bool needs_mips = NeedsMips(); | |
| 191 if (needs_mips) { | |
| 192 if (!texture_complete()) | |
| 193 return CAN_RENDER_NEVER; | |
| 194 if (target_ == GL_TEXTURE_CUBE_MAP && !cube_complete()) | |
| 195 return CAN_RENDER_NEVER; | |
| 196 } | |
| 197 | |
| 198 bool is_npot_compatible = !needs_mips && | |
| 199 wrap_s_ == GL_CLAMP_TO_EDGE && | |
| 200 wrap_t_ == GL_CLAMP_TO_EDGE; | |
| 201 | |
| 202 if (!is_npot_compatible) { | |
| 203 if (target_ == GL_TEXTURE_RECTANGLE_ARB) | |
| 204 return CAN_RENDER_NEVER; | |
| 205 else if (npot()) | |
| 206 return CAN_RENDER_ONLY_IF_NPOT; | |
| 207 } | |
| 208 | |
| 209 return CAN_RENDER_ALWAYS; | |
| 210 } | |
| 211 | |
| 162 bool Texture::CanRender(const FeatureInfo* feature_info) const { | 212 bool Texture::CanRender(const FeatureInfo* feature_info) const { |
| 163 if (target_ == 0) { | 213 switch (can_render_condition_) { |
| 164 return false; | 214 case CAN_RENDER_ALWAYS: |
| 215 return true; | |
| 216 case CAN_RENDER_NEVER: | |
| 217 return false; | |
| 218 case CAN_RENDER_ONLY_IF_NPOT: | |
| 219 break; | |
| 165 } | 220 } |
| 166 bool needs_mips = NeedsMips(); | 221 return feature_info->feature_flags().npot_ok; |
| 167 if ((npot() && !feature_info->feature_flags().npot_ok) || | |
| 168 (target_ == GL_TEXTURE_RECTANGLE_ARB)) { | |
| 169 return !needs_mips && | |
| 170 wrap_s_ == GL_CLAMP_TO_EDGE && | |
| 171 wrap_t_ == GL_CLAMP_TO_EDGE; | |
| 172 } | |
| 173 if (needs_mips) { | |
| 174 if (target_ == GL_TEXTURE_2D) { | |
| 175 return texture_complete(); | |
| 176 } else { | |
| 177 return texture_complete() && cube_complete(); | |
| 178 } | |
| 179 } else { | |
| 180 return true; | |
| 181 } | |
| 182 } | 222 } |
| 183 | 223 |
| 184 void Texture::AddToSignature( | 224 void Texture::AddToSignature( |
| 185 const FeatureInfo* feature_info, | 225 const FeatureInfo* feature_info, |
| 186 GLenum target, | 226 GLenum target, |
| 187 GLint level, | 227 GLint level, |
| 188 std::string* signature) const { | 228 std::string* signature) const { |
| 189 DCHECK(feature_info); | 229 DCHECK(feature_info); |
| 190 DCHECK(signature); | 230 DCHECK(signature); |
| 191 DCHECK_GE(level, 0); | 231 DCHECK_GE(level, 0); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 253 } | 293 } |
| 254 | 294 |
| 255 if (target == GL_TEXTURE_EXTERNAL_OES || target == GL_TEXTURE_RECTANGLE_ARB) { | 295 if (target == GL_TEXTURE_EXTERNAL_OES || target == GL_TEXTURE_RECTANGLE_ARB) { |
| 256 min_filter_ = GL_LINEAR; | 296 min_filter_ = GL_LINEAR; |
| 257 wrap_s_ = wrap_t_ = GL_CLAMP_TO_EDGE; | 297 wrap_s_ = wrap_t_ = GL_CLAMP_TO_EDGE; |
| 258 } | 298 } |
| 259 | 299 |
| 260 if (target == GL_TEXTURE_EXTERNAL_OES) { | 300 if (target == GL_TEXTURE_EXTERNAL_OES) { |
| 261 immutable_ = true; | 301 immutable_ = true; |
| 262 } | 302 } |
| 303 UpdateCanRenderCondition(); | |
| 263 } | 304 } |
| 264 | 305 |
| 265 bool Texture::CanGenerateMipmaps( | 306 bool Texture::CanGenerateMipmaps( |
| 266 const FeatureInfo* feature_info) const { | 307 const FeatureInfo* feature_info) const { |
| 267 if ((npot() && !feature_info->feature_flags().npot_ok) || | 308 if ((npot() && !feature_info->feature_flags().npot_ok) || |
| 268 level_infos_.empty() || | 309 level_infos_.empty() || |
| 269 target_ == GL_TEXTURE_EXTERNAL_OES || | 310 target_ == GL_TEXTURE_EXTERNAL_OES || |
| 270 target_ == GL_TEXTURE_RECTANGLE_ARB) { | 311 target_ == GL_TEXTURE_RECTANGLE_ARB) { |
| 271 return false; | 312 return false; |
| 272 } | 313 } |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 298 } | 339 } |
| 299 | 340 |
| 300 void Texture::SetLevelCleared(GLenum target, GLint level, bool cleared) { | 341 void Texture::SetLevelCleared(GLenum target, GLint level, bool cleared) { |
| 301 DCHECK_GE(level, 0); | 342 DCHECK_GE(level, 0); |
| 302 DCHECK_LT(static_cast<size_t>(GLTargetToFaceIndex(target)), | 343 DCHECK_LT(static_cast<size_t>(GLTargetToFaceIndex(target)), |
| 303 level_infos_.size()); | 344 level_infos_.size()); |
| 304 DCHECK_LT(static_cast<size_t>(level), | 345 DCHECK_LT(static_cast<size_t>(level), |
| 305 level_infos_[GLTargetToFaceIndex(target)].size()); | 346 level_infos_[GLTargetToFaceIndex(target)].size()); |
| 306 Texture::LevelInfo& info = | 347 Texture::LevelInfo& info = |
| 307 level_infos_[GLTargetToFaceIndex(target)][level]; | 348 level_infos_[GLTargetToFaceIndex(target)][level]; |
| 308 if (!info.cleared) { | 349 UpdateMipCleared(&info, cleared); |
| 309 DCHECK_NE(0, num_uncleared_mips_); | |
| 310 --num_uncleared_mips_; | |
| 311 } else { | |
| 312 ++num_uncleared_mips_; | |
| 313 } | |
| 314 info.cleared = cleared; | |
| 315 UpdateCleared(); | 350 UpdateCleared(); |
| 316 } | 351 } |
| 317 | 352 |
| 318 void Texture::UpdateCleared() { | 353 void Texture::UpdateCleared() { |
| 319 if (level_infos_.empty()) { | 354 if (level_infos_.empty()) { |
| 320 return; | 355 return; |
| 321 } | 356 } |
| 322 | 357 |
| 323 const Texture::LevelInfo& first_face = level_infos_[0][0]; | 358 const Texture::LevelInfo& first_face = level_infos_[0][0]; |
| 324 int levels_needed = TextureManager::ComputeMipMapCount( | 359 int levels_needed = TextureManager::ComputeMipMapCount( |
| 325 first_face.width, first_face.height, first_face.depth); | 360 first_face.width, first_face.height, first_face.depth); |
| 326 cleared_ = true; | 361 bool cleared = true; |
| 327 for (size_t ii = 0; ii < level_infos_.size(); ++ii) { | 362 for (size_t ii = 0; ii < level_infos_.size(); ++ii) { |
| 328 for (GLint jj = 0; jj < levels_needed; ++jj) { | 363 for (GLint jj = 0; jj < levels_needed; ++jj) { |
| 329 const Texture::LevelInfo& info = level_infos_[ii][jj]; | 364 const Texture::LevelInfo& info = level_infos_[ii][jj]; |
| 330 if (info.width > 0 && info.height > 0 && info.depth > 0 && | 365 if (info.width > 0 && info.height > 0 && info.depth > 0 && |
| 331 !info.cleared) { | 366 !info.cleared) { |
| 332 cleared_ = false; | 367 cleared = false; |
| 333 return; | 368 break; |
| 334 } | 369 } |
| 335 } | 370 } |
| 336 } | 371 } |
| 372 UpdateSafeToRenderFrom(cleared); | |
| 373 } | |
| 374 | |
| 375 void Texture::UpdateSafeToRenderFrom(bool cleared) { | |
| 376 if (cleared_ == cleared) | |
| 377 return; | |
| 378 cleared_ = cleared; | |
| 379 int delta = cleared ? -1 : +1; | |
| 380 for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it) | |
| 381 (*it)->manager()->UpdateSafeToRenderFrom(delta); | |
| 382 } | |
| 383 | |
| 384 void Texture::UpdateMipCleared(LevelInfo* info, bool cleared) { | |
| 385 if (info->cleared == cleared) | |
| 386 return; | |
| 387 info->cleared = cleared; | |
| 388 int delta = cleared ? -1 : +1; | |
| 389 num_uncleared_mips_ += delta; | |
| 390 for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it) | |
| 391 (*it)->manager()->UpdateUnclearedMips(delta); | |
| 392 } | |
| 393 | |
| 394 void Texture::UpdateCanRenderCondition() { | |
| 395 CanRenderCondition can_render_condition = GetCanRenderCondition(); | |
| 396 if (can_render_condition_ == can_render_condition) | |
| 397 return; | |
| 398 for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it) | |
| 399 (*it)->manager()->UpdateCanRenderCondition(can_render_condition_, | |
| 400 can_render_condition); | |
| 401 can_render_condition_ = can_render_condition; | |
| 402 } | |
| 403 | |
| 404 void Texture::IncAllFramebufferStateChangeCount() { | |
| 405 for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it) | |
| 406 (*it)->manager()->IncFramebufferStateChangeCount(); | |
| 407 } | |
| 408 | |
| 409 AsyncPixelTransferState* Texture::GetAsyncTransferState() const { | |
| 410 for (RefSet::const_iterator it = refs_.begin(); it != refs_.end(); ++it) { | |
| 411 AsyncPixelTransferState* state = (*it)->async_transfer_state(); | |
| 412 if (state) | |
| 413 return state; | |
| 414 } | |
| 415 return NULL; | |
| 337 } | 416 } |
| 338 | 417 |
| 339 void Texture::SetLevelInfo( | 418 void Texture::SetLevelInfo( |
| 340 const FeatureInfo* feature_info, | 419 const FeatureInfo* feature_info, |
| 341 GLenum target, | 420 GLenum target, |
| 342 GLint level, | 421 GLint level, |
| 343 GLenum internal_format, | 422 GLenum internal_format, |
| 344 GLsizei width, | 423 GLsizei width, |
| 345 GLsizei height, | 424 GLsizei height, |
| 346 GLsizei depth, | 425 GLsizei depth, |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 367 info.border = border; | 446 info.border = border; |
| 368 info.format = format; | 447 info.format = format; |
| 369 info.type = type; | 448 info.type = type; |
| 370 info.image = 0; | 449 info.image = 0; |
| 371 | 450 |
| 372 estimated_size_ -= info.estimated_size; | 451 estimated_size_ -= info.estimated_size; |
| 373 GLES2Util::ComputeImageDataSizes( | 452 GLES2Util::ComputeImageDataSizes( |
| 374 width, height, format, type, 4, &info.estimated_size, NULL, NULL); | 453 width, height, format, type, 4, &info.estimated_size, NULL, NULL); |
| 375 estimated_size_ += info.estimated_size; | 454 estimated_size_ += info.estimated_size; |
| 376 | 455 |
| 377 if (!info.cleared) { | 456 UpdateMipCleared(&info, cleared); |
| 378 DCHECK_NE(0, num_uncleared_mips_); | |
| 379 --num_uncleared_mips_; | |
| 380 } | |
| 381 info.cleared = cleared; | |
| 382 if (!info.cleared) { | |
| 383 ++num_uncleared_mips_; | |
| 384 } | |
| 385 max_level_set_ = std::max(max_level_set_, level); | 457 max_level_set_ = std::max(max_level_set_, level); |
| 386 Update(feature_info); | 458 Update(feature_info); |
| 387 UpdateCleared(); | 459 UpdateCleared(); |
| 460 UpdateCanRenderCondition(); | |
| 461 if (IsAttachedToFramebuffer()) { | |
| 462 // TODO(gman): If textures tracked which framebuffers they were attached to | |
| 463 // we could just mark those framebuffers as not complete. | |
| 464 IncAllFramebufferStateChangeCount(); | |
| 465 } | |
| 388 } | 466 } |
| 389 | 467 |
| 390 bool Texture::ValidForTexture( | 468 bool Texture::ValidForTexture( |
| 391 GLint target, | 469 GLint target, |
| 392 GLint level, | 470 GLint level, |
| 393 GLint xoffset, | 471 GLint xoffset, |
| 394 GLint yoffset, | 472 GLint yoffset, |
| 395 GLsizei width, | 473 GLsizei width, |
| 396 GLsizei height, | 474 GLsizei height, |
| 397 GLenum format, | 475 GLenum format, |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 472 case GL_TEXTURE_MAG_FILTER: | 550 case GL_TEXTURE_MAG_FILTER: |
| 473 if (!feature_info->validators()->texture_mag_filter_mode.IsValid(param)) { | 551 if (!feature_info->validators()->texture_mag_filter_mode.IsValid(param)) { |
| 474 return GL_INVALID_ENUM; | 552 return GL_INVALID_ENUM; |
| 475 } | 553 } |
| 476 mag_filter_ = param; | 554 mag_filter_ = param; |
| 477 break; | 555 break; |
| 478 case GL_TEXTURE_POOL_CHROMIUM: | 556 case GL_TEXTURE_POOL_CHROMIUM: |
| 479 if (!feature_info->validators()->texture_pool.IsValid(param)) { | 557 if (!feature_info->validators()->texture_pool.IsValid(param)) { |
| 480 return GL_INVALID_ENUM; | 558 return GL_INVALID_ENUM; |
| 481 } | 559 } |
| 482 manager_->GetMemTracker(pool_)->TrackMemFree(estimated_size()); | 560 GetMemTracker()->TrackMemFree(estimated_size()); |
| 483 pool_ = param; | 561 pool_ = param; |
| 484 manager_->GetMemTracker(pool_)->TrackMemAlloc(estimated_size()); | 562 GetMemTracker()->TrackMemAlloc(estimated_size()); |
| 485 break; | 563 break; |
| 486 case GL_TEXTURE_WRAP_S: | 564 case GL_TEXTURE_WRAP_S: |
| 487 if (!feature_info->validators()->texture_wrap_mode.IsValid(param)) { | 565 if (!feature_info->validators()->texture_wrap_mode.IsValid(param)) { |
| 488 return GL_INVALID_ENUM; | 566 return GL_INVALID_ENUM; |
| 489 } | 567 } |
| 490 wrap_s_ = param; | 568 wrap_s_ = param; |
| 491 break; | 569 break; |
| 492 case GL_TEXTURE_WRAP_T: | 570 case GL_TEXTURE_WRAP_T: |
| 493 if (!feature_info->validators()->texture_wrap_mode.IsValid(param)) { | 571 if (!feature_info->validators()->texture_wrap_mode.IsValid(param)) { |
| 494 return GL_INVALID_ENUM; | 572 return GL_INVALID_ENUM; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 505 return GL_INVALID_ENUM; | 583 return GL_INVALID_ENUM; |
| 506 } | 584 } |
| 507 usage_ = param; | 585 usage_ = param; |
| 508 break; | 586 break; |
| 509 default: | 587 default: |
| 510 NOTREACHED(); | 588 NOTREACHED(); |
| 511 return GL_INVALID_ENUM; | 589 return GL_INVALID_ENUM; |
| 512 } | 590 } |
| 513 Update(feature_info); | 591 Update(feature_info); |
| 514 UpdateCleared(); | 592 UpdateCleared(); |
| 593 UpdateCanRenderCondition(); | |
| 515 return GL_NO_ERROR; | 594 return GL_NO_ERROR; |
| 516 } | 595 } |
| 517 | 596 |
| 518 void Texture::Update(const FeatureInfo* feature_info) { | 597 void Texture::Update(const FeatureInfo* feature_info) { |
| 519 // Update npot status. | 598 // Update npot status. |
| 520 npot_ = false; | 599 npot_ = false; |
| 521 | 600 |
| 522 if (level_infos_.empty()) { | 601 if (level_infos_.empty()) { |
| 523 texture_complete_ = false; | 602 texture_complete_ = false; |
| 524 cube_complete_ = false; | 603 cube_complete_ = false; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 591 info.type != level0.type) { | 670 info.type != level0.type) { |
| 592 texture_complete_ = false; | 671 texture_complete_ = false; |
| 593 break; | 672 break; |
| 594 } | 673 } |
| 595 } | 674 } |
| 596 } | 675 } |
| 597 } | 676 } |
| 598 | 677 |
| 599 bool Texture::ClearRenderableLevels(GLES2Decoder* decoder) { | 678 bool Texture::ClearRenderableLevels(GLES2Decoder* decoder) { |
| 600 DCHECK(decoder); | 679 DCHECK(decoder); |
| 601 if (SafeToRenderFrom()) { | 680 if (cleared_) { |
| 602 return true; | 681 return true; |
| 603 } | 682 } |
| 604 | 683 |
| 605 const Texture::LevelInfo& first_face = level_infos_[0][0]; | 684 const Texture::LevelInfo& first_face = level_infos_[0][0]; |
| 606 int levels_needed = TextureManager::ComputeMipMapCount( | 685 int levels_needed = TextureManager::ComputeMipMapCount( |
| 607 first_face.width, first_face.height, first_face.depth); | 686 first_face.width, first_face.height, first_face.depth); |
| 608 | 687 |
| 609 for (size_t ii = 0; ii < level_infos_.size(); ++ii) { | 688 for (size_t ii = 0; ii < level_infos_.size(); ++ii) { |
| 610 for (GLint jj = 0; jj < levels_needed; ++jj) { | 689 for (GLint jj = 0; jj < levels_needed; ++jj) { |
| 611 Texture::LevelInfo& info = level_infos_[ii][jj]; | 690 Texture::LevelInfo& info = level_infos_[ii][jj]; |
| 612 if (info.target != 0) { | 691 if (info.target != 0) { |
| 613 if (!ClearLevel(decoder, info.target, jj)) { | 692 if (!ClearLevel(decoder, info.target, jj)) { |
| 614 return false; | 693 return false; |
| 615 } | 694 } |
| 616 } | 695 } |
| 617 } | 696 } |
| 618 } | 697 } |
| 619 cleared_ = true; | 698 UpdateSafeToRenderFrom(true); |
| 620 return true; | 699 return true; |
| 621 } | 700 } |
| 622 | 701 |
| 623 bool Texture::IsLevelCleared(GLenum target, GLint level) const { | 702 bool Texture::IsLevelCleared(GLenum target, GLint level) const { |
| 624 size_t face_index = GLTargetToFaceIndex(target); | 703 size_t face_index = GLTargetToFaceIndex(target); |
| 625 if (face_index >= level_infos_.size() || | 704 if (face_index >= level_infos_.size() || |
| 626 level >= static_cast<GLint>(level_infos_[face_index].size())) { | 705 level >= static_cast<GLint>(level_infos_[face_index].size())) { |
| 627 return true; | 706 return true; |
| 628 } | 707 } |
| 629 | 708 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 646 DCHECK(target == info.target); | 725 DCHECK(target == info.target); |
| 647 | 726 |
| 648 if (info.target == 0 || | 727 if (info.target == 0 || |
| 649 info.cleared || | 728 info.cleared || |
| 650 info.width == 0 || | 729 info.width == 0 || |
| 651 info.height == 0 || | 730 info.height == 0 || |
| 652 info.depth == 0) { | 731 info.depth == 0) { |
| 653 return true; | 732 return true; |
| 654 } | 733 } |
| 655 | 734 |
| 656 DCHECK_NE(0, num_uncleared_mips_); | |
| 657 --num_uncleared_mips_; | |
| 658 | |
| 659 // NOTE: It seems kind of gross to call back into the decoder for this | 735 // NOTE: It seems kind of gross to call back into the decoder for this |
| 660 // but only the decoder knows all the state (like unpack_alignment_) that's | 736 // but only the decoder knows all the state (like unpack_alignment_) that's |
| 661 // needed to be able to call GL correctly. | 737 // needed to be able to call GL correctly. |
| 662 info.cleared = decoder->ClearLevel( | 738 bool cleared = decoder->ClearLevel( |
| 663 service_id_, target_, info.target, info.level, info.format, info.type, | 739 service_id_, target_, info.target, info.level, info.format, info.type, |
| 664 info.width, info.height, immutable_); | 740 info.width, info.height, immutable_); |
| 665 if (!info.cleared) { | 741 UpdateMipCleared(&info, cleared); |
| 666 ++num_uncleared_mips_; | |
| 667 } | |
| 668 return info.cleared; | 742 return info.cleared; |
| 669 } | 743 } |
| 670 | 744 |
| 671 void Texture::SetLevelImage( | 745 void Texture::SetLevelImage( |
| 672 const FeatureInfo* feature_info, | 746 const FeatureInfo* feature_info, |
| 673 GLenum target, | 747 GLenum target, |
| 674 GLint level, | 748 GLint level, |
| 675 gfx::GLImage* image) { | 749 gfx::GLImage* image) { |
| 676 DCHECK_GE(level, 0); | 750 DCHECK_GE(level, 0); |
| 677 DCHECK_LT(static_cast<size_t>(GLTargetToFaceIndex(target)), | 751 DCHECK_LT(static_cast<size_t>(GLTargetToFaceIndex(target)), |
| 678 level_infos_.size()); | 752 level_infos_.size()); |
| 679 DCHECK_LT(static_cast<size_t>(level), | 753 DCHECK_LT(static_cast<size_t>(level), |
| 680 level_infos_[GLTargetToFaceIndex(target)].size()); | 754 level_infos_[GLTargetToFaceIndex(target)].size()); |
| 681 Texture::LevelInfo& info = | 755 Texture::LevelInfo& info = |
| 682 level_infos_[GLTargetToFaceIndex(target)][level]; | 756 level_infos_[GLTargetToFaceIndex(target)][level]; |
| 683 DCHECK_EQ(info.target, target); | 757 DCHECK_EQ(info.target, target); |
| 684 DCHECK_EQ(info.level, level); | 758 DCHECK_EQ(info.level, level); |
| 685 info.image = image; | 759 info.image = image; |
| 760 UpdateCanRenderCondition(); | |
| 686 } | 761 } |
| 687 | 762 |
| 688 gfx::GLImage* Texture::GetLevelImage( | 763 gfx::GLImage* Texture::GetLevelImage( |
| 689 GLint target, GLint level) const { | 764 GLint target, GLint level) const { |
| 690 size_t face_index = GLTargetToFaceIndex(target); | 765 size_t face_index = GLTargetToFaceIndex(target); |
| 691 if (level >= 0 && face_index < level_infos_.size() && | 766 if (level >= 0 && face_index < level_infos_.size() && |
| 692 static_cast<size_t>(level) < level_infos_[face_index].size()) { | 767 static_cast<size_t>(level) < level_infos_[face_index].size()) { |
| 693 const LevelInfo& info = level_infos_[GLTargetToFaceIndex(target)][level]; | 768 const LevelInfo& info = level_infos_[GLTargetToFaceIndex(target)][level]; |
| 694 if (info.target != 0) { | 769 if (info.target != 0) { |
| 695 return info.image; | 770 return info.image; |
| 696 } | 771 } |
| 697 } | 772 } |
| 698 return 0; | 773 return 0; |
| 699 } | 774 } |
| 700 | 775 |
| 776 | |
| 777 TextureRef::TextureRef(TextureManager* manager, Texture* texture) | |
| 778 : manager_(manager), | |
| 779 texture_(texture) { | |
| 780 DCHECK(manager_); | |
| 781 DCHECK(texture_); | |
| 782 texture_->AddTextureRef(this); | |
| 783 manager_->StartTracking(this); | |
| 784 } | |
| 785 | |
| 786 scoped_refptr<TextureRef> TextureRef::Create(TextureManager* manager, | |
| 787 GLuint service_id) { | |
| 788 return new TextureRef(manager, new Texture(service_id)); | |
| 789 } | |
| 790 | |
| 791 TextureRef::~TextureRef() { | |
| 792 manager_->StopTracking(this); | |
| 793 texture_->RemoveTextureRef(this, manager_->have_context_); | |
| 794 manager_ = NULL; | |
| 795 } | |
| 796 | |
| 797 | |
| 701 TextureManager::TextureManager( | 798 TextureManager::TextureManager( |
| 702 MemoryTracker* memory_tracker, | 799 MemoryTracker* memory_tracker, |
| 703 FeatureInfo* feature_info, | 800 FeatureInfo* feature_info, |
| 704 GLint max_texture_size, | 801 GLint max_texture_size, |
| 705 GLint max_cube_map_texture_size) | 802 GLint max_cube_map_texture_size) |
| 706 : memory_tracker_managed_( | 803 : memory_tracker_managed_( |
| 707 new MemoryTypeTracker(memory_tracker, MemoryTracker::kManaged)), | 804 new MemoryTypeTracker(memory_tracker, MemoryTracker::kManaged)), |
| 708 memory_tracker_unmanaged_( | 805 memory_tracker_unmanaged_( |
| 709 new MemoryTypeTracker(memory_tracker, MemoryTracker::kUnmanaged)), | 806 new MemoryTypeTracker(memory_tracker, MemoryTracker::kUnmanaged)), |
| 710 feature_info_(feature_info), | 807 feature_info_(feature_info), |
| 808 framebuffer_manager_(NULL), | |
| 711 max_texture_size_(max_texture_size), | 809 max_texture_size_(max_texture_size), |
| 712 max_cube_map_texture_size_(max_cube_map_texture_size), | 810 max_cube_map_texture_size_(max_cube_map_texture_size), |
| 713 max_levels_(ComputeMipMapCount(max_texture_size, | 811 max_levels_(ComputeMipMapCount(max_texture_size, |
| 714 max_texture_size, | 812 max_texture_size, |
| 715 max_texture_size)), | 813 max_texture_size)), |
| 716 max_cube_map_levels_(ComputeMipMapCount(max_cube_map_texture_size, | 814 max_cube_map_levels_(ComputeMipMapCount(max_cube_map_texture_size, |
| 717 max_cube_map_texture_size, | 815 max_cube_map_texture_size, |
| 718 max_cube_map_texture_size)), | 816 max_cube_map_texture_size)), |
| 719 num_unrenderable_textures_(0), | 817 num_unrenderable_textures_(0), |
| 720 num_unsafe_textures_(0), | 818 num_unsafe_textures_(0), |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 742 } | 840 } |
| 743 | 841 |
| 744 if (feature_info_->feature_flags().arb_texture_rectangle) { | 842 if (feature_info_->feature_flags().arb_texture_rectangle) { |
| 745 default_textures_[kRectangleARB] = CreateDefaultAndBlackTextures( | 843 default_textures_[kRectangleARB] = CreateDefaultAndBlackTextures( |
| 746 GL_TEXTURE_RECTANGLE_ARB, &black_texture_ids_[kRectangleARB]); | 844 GL_TEXTURE_RECTANGLE_ARB, &black_texture_ids_[kRectangleARB]); |
| 747 } | 845 } |
| 748 | 846 |
| 749 return true; | 847 return true; |
| 750 } | 848 } |
| 751 | 849 |
| 752 scoped_refptr<Texture> | 850 scoped_refptr<TextureRef> |
| 753 TextureManager::CreateDefaultAndBlackTextures( | 851 TextureManager::CreateDefaultAndBlackTextures( |
| 754 GLenum target, | 852 GLenum target, |
| 755 GLuint* black_texture) { | 853 GLuint* black_texture) { |
| 756 static uint8 black[] = {0, 0, 0, 255}; | 854 static uint8 black[] = {0, 0, 0, 255}; |
| 757 | 855 |
| 758 // Sampling a texture not associated with any EGLImage sibling will return | 856 // Sampling a texture not associated with any EGLImage sibling will return |
| 759 // black values according to the spec. | 857 // black values according to the spec. |
| 760 bool needs_initialization = (target != GL_TEXTURE_EXTERNAL_OES); | 858 bool needs_initialization = (target != GL_TEXTURE_EXTERNAL_OES); |
| 761 bool needs_faces = (target == GL_TEXTURE_CUBE_MAP); | 859 bool needs_faces = (target == GL_TEXTURE_CUBE_MAP); |
| 762 | 860 |
| 763 // Make default textures and texture for replacing non-renderable textures. | 861 // Make default textures and texture for replacing non-renderable textures. |
| 764 GLuint ids[2]; | 862 GLuint ids[2]; |
| 765 glGenTextures(arraysize(ids), ids); | 863 glGenTextures(arraysize(ids), ids); |
| 766 for (unsigned long ii = 0; ii < arraysize(ids); ++ii) { | 864 for (unsigned long ii = 0; ii < arraysize(ids); ++ii) { |
| 767 glBindTexture(target, ids[ii]); | 865 glBindTexture(target, ids[ii]); |
| 768 if (needs_initialization) { | 866 if (needs_initialization) { |
| 769 if (needs_faces) { | 867 if (needs_faces) { |
| 770 for (int jj = 0; jj < GLES2Util::kNumFaces; ++jj) { | 868 for (int jj = 0; jj < GLES2Util::kNumFaces; ++jj) { |
| 771 glTexImage2D(GLES2Util::IndexToGLFaceTarget(jj), 0, GL_RGBA, 1, 1, 0, | 869 glTexImage2D(GLES2Util::IndexToGLFaceTarget(jj), 0, GL_RGBA, 1, 1, 0, |
| 772 GL_RGBA, GL_UNSIGNED_BYTE, black); | 870 GL_RGBA, GL_UNSIGNED_BYTE, black); |
| 773 } | 871 } |
| 774 } else { | 872 } else { |
| 775 glTexImage2D(target, 0, GL_RGBA, 1, 1, 0, GL_RGBA, | 873 glTexImage2D(target, 0, GL_RGBA, 1, 1, 0, GL_RGBA, |
| 776 GL_UNSIGNED_BYTE, black); | 874 GL_UNSIGNED_BYTE, black); |
| 777 } | 875 } |
| 778 } | 876 } |
| 779 } | 877 } |
| 780 glBindTexture(target, 0); | 878 glBindTexture(target, 0); |
| 781 | 879 |
| 782 // Since we are manually setting up these textures | 880 scoped_refptr<TextureRef> default_texture(TextureRef::Create(this, ids[1])); |
| 783 // we need to manually manipulate some of the their bookkeeping. | |
| 784 ++num_unrenderable_textures_; | |
| 785 scoped_refptr<Texture> default_texture(new Texture(this, ids[1])); | |
| 786 SetTarget(default_texture, target); | 881 SetTarget(default_texture, target); |
| 787 if (needs_faces) { | 882 if (needs_faces) { |
| 788 for (int ii = 0; ii < GLES2Util::kNumFaces; ++ii) { | 883 for (int ii = 0; ii < GLES2Util::kNumFaces; ++ii) { |
| 789 SetLevelInfo( | 884 SetLevelInfo( |
| 790 default_texture, GLES2Util::IndexToGLFaceTarget(ii), | 885 default_texture, GLES2Util::IndexToGLFaceTarget(ii), |
| 791 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); | 886 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); |
| 792 } | 887 } |
| 793 } else { | 888 } else { |
| 794 if (needs_initialization) { | 889 if (needs_initialization) { |
| 795 SetLevelInfo(default_texture, | 890 SetLevelInfo(default_texture, |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 818 height <= max_size && | 913 height <= max_size && |
| 819 depth <= max_size && | 914 depth <= max_size && |
| 820 (level == 0 || feature_info_->feature_flags().npot_ok || | 915 (level == 0 || feature_info_->feature_flags().npot_ok || |
| 821 (!GLES2Util::IsNPOT(width) && | 916 (!GLES2Util::IsNPOT(width) && |
| 822 !GLES2Util::IsNPOT(height) && | 917 !GLES2Util::IsNPOT(height) && |
| 823 !GLES2Util::IsNPOT(depth))) && | 918 !GLES2Util::IsNPOT(depth))) && |
| 824 (target != GL_TEXTURE_CUBE_MAP || (width == height && depth == 1)) && | 919 (target != GL_TEXTURE_CUBE_MAP || (width == height && depth == 1)) && |
| 825 (target != GL_TEXTURE_2D || (depth == 1)); | 920 (target != GL_TEXTURE_2D || (depth == 1)); |
| 826 } | 921 } |
| 827 | 922 |
| 828 void TextureManager::SetTarget(Texture* texture, GLenum target) { | 923 void TextureManager::SetTarget(TextureRef* ref, GLenum target) { |
| 829 DCHECK(texture); | 924 DCHECK(ref); |
| 830 if (!texture->CanRender(feature_info_)) { | 925 ref->texture()->SetTarget(target, MaxLevelsForTarget(target)); |
| 831 DCHECK_NE(0, num_unrenderable_textures_); | |
| 832 --num_unrenderable_textures_; | |
| 833 } | |
| 834 texture->SetTarget(target, MaxLevelsForTarget(target)); | |
| 835 if (!texture->CanRender(feature_info_)) { | |
| 836 ++num_unrenderable_textures_; | |
| 837 } | |
| 838 } | 926 } |
| 839 | 927 |
| 840 void TextureManager::SetLevelCleared(Texture* texture, | 928 void TextureManager::SetLevelCleared(TextureRef* ref, |
| 841 GLenum target, | 929 GLenum target, |
| 842 GLint level, | 930 GLint level, |
| 843 bool cleared) { | 931 bool cleared) { |
| 844 DCHECK(texture); | 932 DCHECK(ref); |
| 845 if (!texture->SafeToRenderFrom()) { | 933 ref->texture()->SetLevelCleared(target, level, cleared); |
| 846 DCHECK_NE(0, num_unsafe_textures_); | |
| 847 --num_unsafe_textures_; | |
| 848 } | |
| 849 num_uncleared_mips_ -= texture->num_uncleared_mips(); | |
| 850 DCHECK_GE(num_uncleared_mips_, 0); | |
| 851 texture->SetLevelCleared(target, level, cleared); | |
| 852 num_uncleared_mips_ += texture->num_uncleared_mips(); | |
| 853 if (!texture->SafeToRenderFrom()) { | |
| 854 ++num_unsafe_textures_; | |
| 855 } | |
| 856 } | 934 } |
| 857 | 935 |
| 858 bool TextureManager::ClearRenderableLevels( | 936 bool TextureManager::ClearRenderableLevels( |
| 859 GLES2Decoder* decoder,Texture* texture) { | 937 GLES2Decoder* decoder, TextureRef* ref) { |
| 860 DCHECK(texture); | 938 DCHECK(ref); |
| 861 if (texture->SafeToRenderFrom()) { | 939 return ref->texture()->ClearRenderableLevels(decoder); |
| 862 return true; | |
| 863 } | |
| 864 DCHECK_NE(0, num_unsafe_textures_); | |
| 865 --num_unsafe_textures_; | |
| 866 num_uncleared_mips_ -= texture->num_uncleared_mips(); | |
| 867 DCHECK_GE(num_uncleared_mips_, 0); | |
| 868 bool result = texture->ClearRenderableLevels(decoder); | |
| 869 num_uncleared_mips_ += texture->num_uncleared_mips(); | |
| 870 if (!texture->SafeToRenderFrom()) { | |
| 871 ++num_unsafe_textures_; | |
| 872 } | |
| 873 return result; | |
| 874 } | 940 } |
| 875 | 941 |
| 876 bool TextureManager::ClearTextureLevel( | 942 bool TextureManager::ClearTextureLevel( |
| 877 GLES2Decoder* decoder,Texture* texture, | 943 GLES2Decoder* decoder, TextureRef* ref, |
| 878 GLenum target, GLint level) { | 944 GLenum target, GLint level) { |
| 879 DCHECK(texture); | 945 DCHECK(ref); |
| 946 Texture* texture = ref->texture(); | |
| 880 if (texture->num_uncleared_mips() == 0) { | 947 if (texture->num_uncleared_mips() == 0) { |
| 881 return true; | 948 return true; |
| 882 } | 949 } |
| 883 num_uncleared_mips_ -= texture->num_uncleared_mips(); | |
| 884 DCHECK_GE(num_uncleared_mips_, 0); | |
| 885 if (!texture->SafeToRenderFrom()) { | |
| 886 DCHECK_NE(0, num_unsafe_textures_); | |
| 887 --num_unsafe_textures_; | |
| 888 } | |
| 889 bool result = texture->ClearLevel(decoder, target, level); | 950 bool result = texture->ClearLevel(decoder, target, level); |
| 890 texture->UpdateCleared(); | 951 texture->UpdateCleared(); |
| 891 num_uncleared_mips_ += texture->num_uncleared_mips(); | |
| 892 if (!texture->SafeToRenderFrom()) { | |
| 893 ++num_unsafe_textures_; | |
| 894 } | |
| 895 return result; | 952 return result; |
| 896 } | 953 } |
| 897 | 954 |
| 898 void TextureManager::SetLevelInfo( | 955 void TextureManager::SetLevelInfo( |
| 899 Texture* texture, | 956 TextureRef* ref, |
| 900 GLenum target, | 957 GLenum target, |
| 901 GLint level, | 958 GLint level, |
| 902 GLenum internal_format, | 959 GLenum internal_format, |
| 903 GLsizei width, | 960 GLsizei width, |
| 904 GLsizei height, | 961 GLsizei height, |
| 905 GLsizei depth, | 962 GLsizei depth, |
| 906 GLint border, | 963 GLint border, |
| 907 GLenum format, | 964 GLenum format, |
| 908 GLenum type, | 965 GLenum type, |
| 909 bool cleared) { | 966 bool cleared) { |
| 910 DCHECK(texture); | 967 DCHECK(ref); |
| 911 if (!texture->CanRender(feature_info_)) { | 968 Texture* texture = ref->texture(); |
| 912 DCHECK_NE(0, num_unrenderable_textures_); | |
| 913 --num_unrenderable_textures_; | |
| 914 } | |
| 915 if (!texture->SafeToRenderFrom()) { | |
| 916 DCHECK_NE(0, num_unsafe_textures_); | |
| 917 --num_unsafe_textures_; | |
| 918 } | |
| 919 num_uncleared_mips_ -= texture->num_uncleared_mips(); | |
| 920 DCHECK_GE(num_uncleared_mips_, 0); | |
| 921 | 969 |
| 922 GetMemTracker(texture->pool_)->TrackMemFree(texture->estimated_size()); | 970 texture->GetMemTracker()->TrackMemFree(texture->estimated_size()); |
| 923 texture->SetLevelInfo( | 971 texture->SetLevelInfo( |
| 924 feature_info_, target, level, internal_format, width, height, depth, | 972 feature_info_, target, level, internal_format, width, height, depth, |
| 925 border, format, type, cleared); | 973 border, format, type, cleared); |
| 926 GetMemTracker(texture->pool_)->TrackMemAlloc(texture->estimated_size()); | 974 texture->GetMemTracker()->TrackMemAlloc(texture->estimated_size()); |
| 927 | |
| 928 num_uncleared_mips_ += texture->num_uncleared_mips(); | |
| 929 if (!texture->CanRender(feature_info_)) { | |
| 930 ++num_unrenderable_textures_; | |
| 931 } | |
| 932 if (!texture->SafeToRenderFrom()) { | |
| 933 ++num_unsafe_textures_; | |
| 934 } | |
| 935 } | 975 } |
| 936 | 976 |
| 937 TextureDefinition* TextureManager::Save(Texture* texture) { | 977 TextureDefinition* TextureManager::Save(TextureRef* ref) { |
| 978 DCHECK(ref); | |
| 979 Texture* texture = ref->texture(); | |
| 938 DCHECK(texture->owned_); | 980 DCHECK(texture->owned_); |
| 939 | 981 |
| 940 if (texture->IsAttachedToFramebuffer()) | 982 if (texture->IsAttachedToFramebuffer()) |
| 941 return NULL; | 983 return NULL; |
| 942 | 984 |
| 943 TextureDefinition::LevelInfos level_infos(texture->level_infos_.size()); | 985 TextureDefinition::LevelInfos level_infos(texture->level_infos_.size()); |
| 944 for (size_t face = 0; face < level_infos.size(); ++face) { | 986 for (size_t face = 0; face < level_infos.size(); ++face) { |
| 945 GLenum target = | 987 GLenum target = |
| 946 texture->target() == GL_TEXTURE_CUBE_MAP ? FaceIndexToGLTarget(face) | 988 texture->target() == GL_TEXTURE_CUBE_MAP ? FaceIndexToGLTarget(face) |
| 947 : texture->target(); | 989 : texture->target(); |
| 948 for (GLint level = 0; level <= texture->max_level_set_; ++level) { | 990 for (GLint level = 0; level <= texture->max_level_set_; ++level) { |
| 949 const Texture::LevelInfo& level_info = | 991 const Texture::LevelInfo& level_info = |
| 950 texture->level_infos_[face][level]; | 992 texture->level_infos_[face][level]; |
| 951 | 993 |
| 952 level_infos[face].push_back( | 994 level_infos[face].push_back( |
| 953 TextureDefinition::LevelInfo(target, | 995 TextureDefinition::LevelInfo(target, |
| 954 level_info.internal_format, | 996 level_info.internal_format, |
| 955 level_info.width, | 997 level_info.width, |
| 956 level_info.height, | 998 level_info.height, |
| 957 level_info.depth, | 999 level_info.depth, |
| 958 level_info.border, | 1000 level_info.border, |
| 959 level_info.format, | 1001 level_info.format, |
| 960 level_info.type, | 1002 level_info.type, |
| 961 level_info.cleared)); | 1003 level_info.cleared)); |
| 962 | 1004 |
| 963 SetLevelInfo(texture, | 1005 SetLevelInfo(ref, |
| 964 target, | 1006 target, |
| 965 level, | 1007 level, |
| 966 GL_RGBA, | 1008 GL_RGBA, |
| 967 0, | 1009 0, |
| 968 0, | 1010 0, |
| 969 0, | 1011 0, |
| 970 0, | 1012 0, |
| 971 GL_RGBA, | 1013 GL_RGBA, |
| 972 GL_UNSIGNED_BYTE, | 1014 GL_UNSIGNED_BYTE, |
| 973 true); | 1015 true); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 992 texture->wrap_t(), | 1034 texture->wrap_t(), |
| 993 texture->usage(), | 1035 texture->usage(), |
| 994 immutable, | 1036 immutable, |
| 995 stream_texture, | 1037 stream_texture, |
| 996 level_infos); | 1038 level_infos); |
| 997 } | 1039 } |
| 998 | 1040 |
| 999 bool TextureManager::Restore( | 1041 bool TextureManager::Restore( |
| 1000 const char* function_name, | 1042 const char* function_name, |
| 1001 GLES2Decoder* decoder, | 1043 GLES2Decoder* decoder, |
| 1002 Texture* texture, | 1044 TextureRef* ref, |
| 1003 TextureDefinition* definition) { | 1045 TextureDefinition* definition) { |
| 1046 DCHECK(ref); | |
| 1047 Texture* texture = ref->texture(); | |
| 1004 DCHECK(texture->owned_); | 1048 DCHECK(texture->owned_); |
| 1005 | 1049 |
| 1006 scoped_ptr<TextureDefinition> scoped_definition(definition); | 1050 scoped_ptr<TextureDefinition> scoped_definition(definition); |
| 1007 | 1051 |
| 1008 if (texture->IsAttachedToFramebuffer()) | 1052 if (texture->IsAttachedToFramebuffer()) |
| 1009 return false; | 1053 return false; |
| 1010 | 1054 |
| 1011 if (texture->target() != definition->target()) | 1055 if (texture->target() != definition->target()) |
| 1012 return false; | 1056 return false; |
| 1013 | 1057 |
| 1014 if (texture->level_infos_.size() < definition->level_infos().size()) | 1058 if (texture->level_infos_.size() < definition->level_infos().size()) |
| 1015 return false; | 1059 return false; |
| 1016 | 1060 |
| 1017 if (texture->level_infos_[0].size() < definition->level_infos()[0].size()) | 1061 if (texture->level_infos_[0].size() < definition->level_infos()[0].size()) |
| 1018 return false; | 1062 return false; |
| 1019 | 1063 |
| 1020 for (size_t face = 0; face < definition->level_infos().size(); ++face) { | 1064 for (size_t face = 0; face < definition->level_infos().size(); ++face) { |
| 1021 GLenum target = | 1065 GLenum target = |
| 1022 texture->target() == GL_TEXTURE_CUBE_MAP ? FaceIndexToGLTarget(face) | 1066 texture->target() == GL_TEXTURE_CUBE_MAP ? FaceIndexToGLTarget(face) |
| 1023 : texture->target(); | 1067 : texture->target(); |
| 1024 GLint new_max_level = definition->level_infos()[face].size() - 1; | 1068 GLint new_max_level = definition->level_infos()[face].size() - 1; |
| 1025 for (GLint level = 0; | 1069 for (GLint level = 0; |
| 1026 level <= std::max(texture->max_level_set_, new_max_level); | 1070 level <= std::max(texture->max_level_set_, new_max_level); |
| 1027 ++level) { | 1071 ++level) { |
| 1028 const TextureDefinition::LevelInfo& level_info = | 1072 const TextureDefinition::LevelInfo& level_info = |
| 1029 level <= new_max_level ? definition->level_infos()[face][level] | 1073 level <= new_max_level ? definition->level_infos()[face][level] |
| 1030 : TextureDefinition::LevelInfo(); | 1074 : TextureDefinition::LevelInfo(); |
| 1031 SetLevelInfo(texture, | 1075 SetLevelInfo(ref, |
| 1032 target, | 1076 target, |
| 1033 level, | 1077 level, |
| 1034 level_info.internal_format, | 1078 level_info.internal_format, |
| 1035 level_info.width, | 1079 level_info.width, |
| 1036 level_info.height, | 1080 level_info.height, |
| 1037 level_info.depth, | 1081 level_info.depth, |
| 1038 level_info.border, | 1082 level_info.border, |
| 1039 level_info.format, | 1083 level_info.format, |
| 1040 level_info.type, | 1084 level_info.type, |
| 1041 level_info.cleared); | 1085 level_info.cleared); |
| 1042 } | 1086 } |
| 1043 } | 1087 } |
| 1044 | 1088 |
| 1045 GLuint old_service_id = texture->service_id(); | 1089 GLuint old_service_id = texture->service_id(); |
| 1046 glDeleteTextures(1, &old_service_id); | 1090 glDeleteTextures(1, &old_service_id); |
| 1047 texture->SetServiceId(definition->ReleaseServiceId()); | 1091 texture->SetServiceId(definition->ReleaseServiceId()); |
| 1048 glBindTexture(texture->target(), texture->service_id()); | 1092 glBindTexture(texture->target(), texture->service_id()); |
| 1049 texture->SetImmutable(definition->immutable()); | 1093 texture->SetImmutable(definition->immutable()); |
| 1050 texture->SetStreamTexture(definition->stream_texture()); | 1094 texture->SetStreamTexture(definition->stream_texture()); |
| 1051 | |
| 1052 ErrorState* error_state = decoder->GetErrorState(); | 1095 ErrorState* error_state = decoder->GetErrorState(); |
| 1053 SetParameter(function_name, error_state, texture, GL_TEXTURE_MIN_FILTER, | 1096 SetParameter(function_name, error_state, ref, GL_TEXTURE_MIN_FILTER, |
| 1054 definition->min_filter()); | 1097 definition->min_filter()); |
| 1055 SetParameter(function_name, error_state, texture, GL_TEXTURE_MAG_FILTER, | 1098 SetParameter(function_name, error_state, ref, GL_TEXTURE_MAG_FILTER, |
| 1056 definition->mag_filter()); | 1099 definition->mag_filter()); |
| 1057 SetParameter(function_name, error_state, texture, GL_TEXTURE_WRAP_S, | 1100 SetParameter(function_name, error_state, ref, GL_TEXTURE_WRAP_S, |
| 1058 definition->wrap_s()); | 1101 definition->wrap_s()); |
| 1059 SetParameter(function_name, error_state, texture, GL_TEXTURE_WRAP_T, | 1102 SetParameter(function_name, error_state, ref, GL_TEXTURE_WRAP_T, |
| 1060 definition->wrap_t()); | 1103 definition->wrap_t()); |
| 1061 if (feature_info_->validators()->texture_parameter.IsValid( | 1104 if (feature_info_->validators()->texture_parameter.IsValid( |
| 1062 GL_TEXTURE_USAGE_ANGLE)) { | 1105 GL_TEXTURE_USAGE_ANGLE)) { |
| 1063 SetParameter(function_name, error_state, texture, GL_TEXTURE_USAGE_ANGLE, | 1106 SetParameter(function_name, error_state, ref, GL_TEXTURE_USAGE_ANGLE, |
| 1064 definition->usage()); | 1107 definition->usage()); |
| 1065 } | 1108 } |
| 1066 | 1109 |
| 1067 return true; | 1110 return true; |
| 1068 } | 1111 } |
| 1069 | 1112 |
| 1070 void TextureManager::SetParameter( | 1113 void TextureManager::SetParameter( |
| 1071 const char* function_name, ErrorState* error_state, | 1114 const char* function_name, ErrorState* error_state, |
| 1072 Texture* texture, GLenum pname, GLint param) { | 1115 TextureRef* ref, GLenum pname, GLint param) { |
| 1073 DCHECK(error_state); | 1116 DCHECK(error_state); |
| 1074 DCHECK(texture); | 1117 DCHECK(ref); |
| 1075 if (!texture->CanRender(feature_info_)) { | 1118 Texture* texture = ref->texture(); |
| 1076 DCHECK_NE(0, num_unrenderable_textures_); | |
| 1077 --num_unrenderable_textures_; | |
| 1078 } | |
| 1079 if (!texture->SafeToRenderFrom()) { | |
| 1080 DCHECK_NE(0, num_unsafe_textures_); | |
| 1081 --num_unsafe_textures_; | |
| 1082 } | |
| 1083 GLenum result = texture->SetParameter(feature_info_, pname, param); | 1119 GLenum result = texture->SetParameter(feature_info_, pname, param); |
| 1084 if (result != GL_NO_ERROR) { | 1120 if (result != GL_NO_ERROR) { |
| 1085 if (result == GL_INVALID_ENUM) { | 1121 if (result == GL_INVALID_ENUM) { |
| 1086 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM( | 1122 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM( |
| 1087 error_state, function_name, param, "param"); | 1123 error_state, function_name, param, "param"); |
| 1088 } else { | 1124 } else { |
| 1089 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM( | 1125 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM( |
| 1090 error_state, result, function_name, pname, static_cast<GLint>(param)); | 1126 error_state, result, function_name, pname, static_cast<GLint>(param)); |
| 1091 } | 1127 } |
| 1092 } else { | 1128 } else { |
| 1093 // Texture tracking pools exist only for the command decoder, so | 1129 // Texture tracking pools exist only for the command decoder, so |
| 1094 // do not pass them on to the native GL implementation. | 1130 // do not pass them on to the native GL implementation. |
| 1095 if (pname != GL_TEXTURE_POOL_CHROMIUM) { | 1131 if (pname != GL_TEXTURE_POOL_CHROMIUM) { |
| 1096 glTexParameteri(texture->target(), pname, param); | 1132 glTexParameteri(texture->target(), pname, param); |
| 1097 } | 1133 } |
| 1098 } | 1134 } |
| 1099 | |
| 1100 if (!texture->CanRender(feature_info_)) { | |
| 1101 ++num_unrenderable_textures_; | |
| 1102 } | |
| 1103 if (!texture->SafeToRenderFrom()) { | |
| 1104 ++num_unsafe_textures_; | |
| 1105 } | |
| 1106 } | 1135 } |
| 1107 | 1136 |
| 1108 bool TextureManager::MarkMipmapsGenerated(Texture* texture) { | 1137 bool TextureManager::MarkMipmapsGenerated(TextureRef* ref) { |
| 1109 DCHECK(texture); | 1138 DCHECK(ref); |
| 1110 if (!texture->CanRender(feature_info_)) { | 1139 Texture* texture = ref->texture(); |
| 1111 DCHECK_NE(0, num_unrenderable_textures_); | 1140 texture->GetMemTracker()->TrackMemFree(texture->estimated_size()); |
| 1112 --num_unrenderable_textures_; | |
| 1113 } | |
| 1114 if (!texture->SafeToRenderFrom()) { | |
| 1115 DCHECK_NE(0, num_unsafe_textures_); | |
| 1116 --num_unsafe_textures_; | |
| 1117 } | |
| 1118 num_uncleared_mips_ -= texture->num_uncleared_mips(); | |
| 1119 DCHECK_GE(num_uncleared_mips_, 0); | |
| 1120 GetMemTracker(texture->pool_)->TrackMemFree(texture->estimated_size()); | |
| 1121 bool result = texture->MarkMipmapsGenerated(feature_info_); | 1141 bool result = texture->MarkMipmapsGenerated(feature_info_); |
| 1122 GetMemTracker(texture->pool_)->TrackMemAlloc(texture->estimated_size()); | 1142 texture->GetMemTracker()->TrackMemAlloc(texture->estimated_size()); |
| 1123 | |
| 1124 num_uncleared_mips_ += texture->num_uncleared_mips(); | |
| 1125 if (!texture->CanRender(feature_info_)) { | |
| 1126 ++num_unrenderable_textures_; | |
| 1127 } | |
| 1128 if (!texture->SafeToRenderFrom()) { | |
| 1129 ++num_unsafe_textures_; | |
| 1130 } | |
| 1131 return result; | 1143 return result; |
| 1132 } | 1144 } |
| 1133 | 1145 |
| 1134 Texture* TextureManager::CreateTexture( | 1146 TextureRef* TextureManager::CreateTexture( |
| 1135 GLuint client_id, GLuint service_id) { | 1147 GLuint client_id, GLuint service_id) { |
| 1136 DCHECK_NE(0u, service_id); | 1148 DCHECK_NE(0u, service_id); |
| 1137 scoped_refptr<Texture> texture(new Texture(this, service_id)); | 1149 scoped_refptr<TextureRef> ref(TextureRef::Create(this, service_id)); |
| 1138 std::pair<TextureMap::iterator, bool> result = | 1150 std::pair<TextureMap::iterator, bool> result = |
| 1139 textures_.insert(std::make_pair(client_id, texture)); | 1151 textures_.insert(std::make_pair(client_id, ref)); |
| 1140 DCHECK(result.second); | 1152 DCHECK(result.second); |
| 1141 if (!texture->CanRender(feature_info_)) { | 1153 return ref.get(); |
| 1142 ++num_unrenderable_textures_; | |
| 1143 } | |
| 1144 if (!texture->SafeToRenderFrom()) { | |
| 1145 ++num_unsafe_textures_; | |
| 1146 } | |
| 1147 num_uncleared_mips_ += texture->num_uncleared_mips(); | |
| 1148 return texture.get(); | |
| 1149 } | 1154 } |
| 1150 | 1155 |
| 1151 Texture* TextureManager::GetTexture( | 1156 TextureRef* TextureManager::GetTexture( |
| 1152 GLuint client_id) const { | 1157 GLuint client_id) const { |
| 1153 TextureMap::const_iterator it = textures_.find(client_id); | 1158 TextureMap::const_iterator it = textures_.find(client_id); |
| 1154 return it != textures_.end() ? it->second : NULL; | 1159 return it != textures_.end() ? it->second : NULL; |
| 1155 } | 1160 } |
| 1156 | 1161 |
| 1157 void TextureManager::RemoveTexture(GLuint client_id) { | 1162 void TextureManager::RemoveTexture(GLuint client_id) { |
| 1158 TextureMap::iterator it = textures_.find(client_id); | 1163 TextureMap::iterator it = textures_.find(client_id); |
| 1159 if (it != textures_.end()) { | 1164 if (it != textures_.end()) { |
| 1160 Texture* texture = it->second; | |
| 1161 texture->MarkAsDeleted(); | |
| 1162 textures_.erase(it); | 1165 textures_.erase(it); |
| 1163 } | 1166 } |
| 1164 } | 1167 } |
| 1165 | 1168 |
| 1166 void TextureManager::StartTracking(Texture* /* texture */) { | 1169 void TextureManager::StartTracking(TextureRef* ref) { |
| 1170 Texture* texture = ref->texture(); | |
| 1167 ++texture_count_; | 1171 ++texture_count_; |
| 1172 num_uncleared_mips_ += texture->num_uncleared_mips(); | |
| 1173 if (!texture->SafeToRenderFrom()) { | |
| 1174 DCHECK_NE(0, num_unsafe_textures_); | |
| 1175 ++num_unsafe_textures_; | |
| 1176 } | |
| 1177 if (!texture->CanRender(feature_info_)) | |
| 1178 ++num_unrenderable_textures_; | |
| 1168 } | 1179 } |
| 1169 | 1180 |
| 1170 void TextureManager::StopTracking(Texture* texture) { | 1181 void TextureManager::StopTracking(TextureRef* ref) { |
| 1182 Texture* texture = ref->texture(); | |
| 1171 --texture_count_; | 1183 --texture_count_; |
| 1172 if (!texture->CanRender(feature_info_)) { | 1184 if (!texture->CanRender(feature_info_)) { |
| 1173 DCHECK_NE(0, num_unrenderable_textures_); | 1185 DCHECK_NE(0, num_unrenderable_textures_); |
| 1174 --num_unrenderable_textures_; | 1186 --num_unrenderable_textures_; |
| 1175 } | 1187 } |
| 1176 if (!texture->SafeToRenderFrom()) { | 1188 if (!texture->SafeToRenderFrom()) { |
| 1177 DCHECK_NE(0, num_unsafe_textures_); | 1189 DCHECK_NE(0, num_unsafe_textures_); |
| 1178 --num_unsafe_textures_; | 1190 --num_unsafe_textures_; |
| 1179 } | 1191 } |
| 1180 num_uncleared_mips_ -= texture->num_uncleared_mips(); | 1192 num_uncleared_mips_ -= texture->num_uncleared_mips(); |
| 1181 DCHECK_GE(num_uncleared_mips_, 0); | 1193 DCHECK_GE(num_uncleared_mips_, 0); |
| 1182 GetMemTracker(texture->pool_)->TrackMemFree(texture->estimated_size()); | |
| 1183 } | 1194 } |
| 1184 | 1195 |
| 1185 MemoryTypeTracker* TextureManager::GetMemTracker(GLenum tracking_pool) { | 1196 MemoryTypeTracker* TextureManager::GetMemTracker(GLenum tracking_pool) { |
| 1186 switch(tracking_pool) { | 1197 switch(tracking_pool) { |
| 1187 case GL_TEXTURE_POOL_MANAGED_CHROMIUM: | 1198 case GL_TEXTURE_POOL_MANAGED_CHROMIUM: |
| 1188 return memory_tracker_managed_.get(); | 1199 return memory_tracker_managed_.get(); |
| 1189 break; | 1200 break; |
| 1190 case GL_TEXTURE_POOL_UNMANAGED_CHROMIUM: | 1201 case GL_TEXTURE_POOL_UNMANAGED_CHROMIUM: |
| 1191 return memory_tracker_unmanaged_.get(); | 1202 return memory_tracker_unmanaged_.get(); |
| 1192 break; | 1203 break; |
| 1193 default: | 1204 default: |
| 1194 break; | 1205 break; |
| 1195 } | 1206 } |
| 1196 NOTREACHED(); | 1207 NOTREACHED(); |
| 1197 return NULL; | 1208 return NULL; |
| 1198 } | 1209 } |
| 1199 | 1210 |
| 1200 bool TextureManager::GetClientId(GLuint service_id, GLuint* client_id) const { | 1211 bool TextureManager::GetClientId(GLuint service_id, GLuint* client_id) const { |
| 1201 // This doesn't need to be fast. It's only used during slow queries. | 1212 // This doesn't need to be fast. It's only used during slow queries. |
| 1202 for (TextureMap::const_iterator it = textures_.begin(); | 1213 for (TextureMap::const_iterator it = textures_.begin(); |
| 1203 it != textures_.end(); ++it) { | 1214 it != textures_.end(); ++it) { |
| 1204 if (it->second->service_id() == service_id) { | 1215 if (it->second->texture()->service_id() == service_id) { |
| 1205 *client_id = it->first; | 1216 *client_id = it->first; |
| 1206 return true; | 1217 return true; |
| 1207 } | 1218 } |
| 1208 } | 1219 } |
| 1209 return false; | 1220 return false; |
| 1210 } | 1221 } |
| 1211 | 1222 |
| 1212 GLsizei TextureManager::ComputeMipMapCount( | 1223 GLsizei TextureManager::ComputeMipMapCount( |
| 1213 GLsizei width, GLsizei height, GLsizei depth) { | 1224 GLsizei width, GLsizei height, GLsizei depth) { |
| 1214 return 1 + base::bits::Log2Floor(std::max(std::max(width, height), depth)); | 1225 return 1 + base::bits::Log2Floor(std::max(std::max(width, height), depth)); |
| 1215 } | 1226 } |
| 1216 | 1227 |
| 1217 void TextureManager::SetLevelImage( | 1228 void TextureManager::SetLevelImage( |
| 1218 Texture* texture, | 1229 TextureRef* ref, |
| 1219 GLenum target, | 1230 GLenum target, |
| 1220 GLint level, | 1231 GLint level, |
| 1221 gfx::GLImage* image) { | 1232 gfx::GLImage* image) { |
| 1222 DCHECK(texture); | 1233 DCHECK(ref); |
| 1223 if (!texture->CanRender(feature_info_)) { | 1234 ref->texture()->SetLevelImage(feature_info_, target, level, image); |
| 1224 DCHECK_NE(0, num_unrenderable_textures_); | |
| 1225 --num_unrenderable_textures_; | |
| 1226 } | |
| 1227 if (!texture->SafeToRenderFrom()) { | |
| 1228 DCHECK_NE(0, num_unsafe_textures_); | |
| 1229 --num_unsafe_textures_; | |
| 1230 } | |
| 1231 texture->SetLevelImage(feature_info_, target, level, image); | |
| 1232 if (!texture->CanRender(feature_info_)) { | |
| 1233 ++num_unrenderable_textures_; | |
| 1234 } | |
| 1235 if (!texture->SafeToRenderFrom()) { | |
| 1236 ++num_unsafe_textures_; | |
| 1237 } | |
| 1238 } | 1235 } |
| 1239 | 1236 |
| 1240 void TextureManager::AddToSignature( | 1237 void TextureManager::AddToSignature( |
| 1241 Texture* texture, | 1238 TextureRef* ref, |
| 1242 GLenum target, | 1239 GLenum target, |
| 1243 GLint level, | 1240 GLint level, |
| 1244 std::string* signature) const { | 1241 std::string* signature) const { |
| 1245 texture->AddToSignature(feature_info_.get(), target, level, signature); | 1242 ref->texture()->AddToSignature(feature_info_.get(), target, level, signature); |
| 1243 } | |
| 1244 | |
| 1245 void TextureManager::UpdateSafeToRenderFrom(int delta) { | |
| 1246 num_unsafe_textures_ += delta; | |
| 1247 DCHECK_GE(num_unsafe_textures_, 0); | |
| 1248 } | |
| 1249 | |
| 1250 void TextureManager::UpdateUnclearedMips(int delta) { | |
| 1251 num_uncleared_mips_ += delta; | |
| 1252 DCHECK_GE(num_uncleared_mips_, 0); | |
| 1253 } | |
| 1254 | |
| 1255 void TextureManager::UpdateCanRenderCondition( | |
| 1256 Texture::CanRenderCondition old_condition, | |
| 1257 Texture::CanRenderCondition new_condition) { | |
| 1258 if (old_condition == Texture::CAN_RENDER_NEVER || | |
| 1259 (old_condition == Texture::CAN_RENDER_ONLY_IF_NPOT && | |
| 1260 !feature_info_->feature_flags().npot_ok)) { | |
| 1261 DCHECK_GT(num_unrenderable_textures_, 0); | |
| 1262 --num_unrenderable_textures_; | |
| 1263 } | |
| 1264 if (new_condition == Texture::CAN_RENDER_NEVER || | |
| 1265 (new_condition == Texture::CAN_RENDER_ONLY_IF_NPOT && | |
| 1266 !feature_info_->feature_flags().npot_ok)) | |
| 1267 ++num_unrenderable_textures_; | |
| 1268 } | |
| 1269 | |
| 1270 void TextureManager::IncFramebufferStateChangeCount() { | |
| 1271 if (framebuffer_manager_) | |
| 1272 framebuffer_manager_->IncFramebufferStateChangeCount(); | |
| 1273 | |
| 1246 } | 1274 } |
| 1247 | 1275 |
| 1248 } // namespace gles2 | 1276 } // namespace gles2 |
| 1249 } // namespace gpu | 1277 } // namespace gpu |
| OLD | NEW |