OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/service/texture_manager.h" | 5 #include "gpu/command_buffer/service/texture_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bits.h" | 10 #include "base/bits.h" |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 DCHECK_EQ(0u, memory_tracker_managed_->GetMemRepresented()); | 121 DCHECK_EQ(0u, memory_tracker_managed_->GetMemRepresented()); |
122 DCHECK_EQ(0u, memory_tracker_unmanaged_->GetMemRepresented()); | 122 DCHECK_EQ(0u, memory_tracker_unmanaged_->GetMemRepresented()); |
123 } | 123 } |
124 | 124 |
125 Texture::Texture(GLuint service_id) | 125 Texture::Texture(GLuint service_id) |
126 : mailbox_manager_(NULL), | 126 : mailbox_manager_(NULL), |
127 memory_tracking_ref_(NULL), | 127 memory_tracking_ref_(NULL), |
128 service_id_(service_id), | 128 service_id_(service_id), |
129 cleared_(true), | 129 cleared_(true), |
130 num_uncleared_mips_(0), | 130 num_uncleared_mips_(0), |
| 131 num_npot_faces_(0), |
131 target_(0), | 132 target_(0), |
132 min_filter_(GL_NEAREST_MIPMAP_LINEAR), | 133 min_filter_(GL_NEAREST_MIPMAP_LINEAR), |
133 mag_filter_(GL_LINEAR), | 134 mag_filter_(GL_LINEAR), |
134 wrap_s_(GL_REPEAT), | 135 wrap_s_(GL_REPEAT), |
135 wrap_t_(GL_REPEAT), | 136 wrap_t_(GL_REPEAT), |
136 usage_(GL_NONE), | 137 usage_(GL_NONE), |
137 pool_(GL_TEXTURE_POOL_UNMANAGED_CHROMIUM), | 138 pool_(GL_TEXTURE_POOL_UNMANAGED_CHROMIUM), |
138 max_level_set_(-1), | 139 max_level_set_(-1), |
139 texture_complete_(false), | 140 texture_complete_(false), |
| 141 texture_mips_dirty_(false), |
| 142 texture_mips_complete_(false), |
140 cube_complete_(false), | 143 cube_complete_(false), |
| 144 texture_level0_dirty_(false), |
| 145 texture_level0_complete_(false), |
141 npot_(false), | 146 npot_(false), |
142 has_been_bound_(false), | 147 has_been_bound_(false), |
143 framebuffer_attachment_count_(0), | 148 framebuffer_attachment_count_(0), |
144 immutable_(false), | 149 immutable_(false), |
145 has_images_(false), | 150 has_images_(false), |
146 estimated_size_(0), | 151 estimated_size_(0), |
147 can_render_condition_(CAN_RENDER_ALWAYS), | 152 can_render_condition_(CAN_RENDER_ALWAYS), |
148 texture_max_anisotropy_initialized_(false) { | 153 texture_max_anisotropy_initialized_(false) { |
149 } | 154 } |
150 | 155 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 border(rhs.border), | 218 border(rhs.border), |
214 format(rhs.format), | 219 format(rhs.format), |
215 type(rhs.type), | 220 type(rhs.type), |
216 image(rhs.image), | 221 image(rhs.image), |
217 estimated_size(rhs.estimated_size) { | 222 estimated_size(rhs.estimated_size) { |
218 } | 223 } |
219 | 224 |
220 Texture::LevelInfo::~LevelInfo() { | 225 Texture::LevelInfo::~LevelInfo() { |
221 } | 226 } |
222 | 227 |
| 228 Texture::FaceInfo::FaceInfo() |
| 229 : num_mip_levels(0) { |
| 230 } |
| 231 |
| 232 Texture::FaceInfo::~FaceInfo() { |
| 233 } |
| 234 |
223 Texture::CanRenderCondition Texture::GetCanRenderCondition() const { | 235 Texture::CanRenderCondition Texture::GetCanRenderCondition() const { |
224 if (target_ == 0) | 236 if (target_ == 0) |
225 return CAN_RENDER_ALWAYS; | 237 return CAN_RENDER_ALWAYS; |
226 | 238 |
227 if (target_ != GL_TEXTURE_EXTERNAL_OES) { | 239 if (target_ != GL_TEXTURE_EXTERNAL_OES) { |
228 if (level_infos_.empty()) { | 240 if (face_infos_.empty()) { |
229 return CAN_RENDER_NEVER; | 241 return CAN_RENDER_NEVER; |
230 } | 242 } |
231 | 243 |
232 const Texture::LevelInfo& first_face = level_infos_[0][0]; | 244 const Texture::LevelInfo& first_face = face_infos_[0].level_infos[0]; |
233 if (first_face.width == 0 || | 245 if (first_face.width == 0 || |
234 first_face.height == 0 || | 246 first_face.height == 0 || |
235 first_face.depth == 0) { | 247 first_face.depth == 0) { |
236 return CAN_RENDER_NEVER; | 248 return CAN_RENDER_NEVER; |
237 } | 249 } |
238 } | 250 } |
239 | 251 |
240 bool needs_mips = NeedsMips(); | 252 bool needs_mips = NeedsMips(); |
241 if (needs_mips) { | 253 if (needs_mips) { |
242 if (!texture_complete()) | 254 if (!texture_complete()) |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 void Texture::AddToSignature( | 286 void Texture::AddToSignature( |
275 const FeatureInfo* feature_info, | 287 const FeatureInfo* feature_info, |
276 GLenum target, | 288 GLenum target, |
277 GLint level, | 289 GLint level, |
278 std::string* signature) const { | 290 std::string* signature) const { |
279 DCHECK(feature_info); | 291 DCHECK(feature_info); |
280 DCHECK(signature); | 292 DCHECK(signature); |
281 DCHECK_GE(level, 0); | 293 DCHECK_GE(level, 0); |
282 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); | 294 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); |
283 DCHECK_LT(static_cast<size_t>(face_index), | 295 DCHECK_LT(static_cast<size_t>(face_index), |
284 level_infos_.size()); | 296 face_infos_.size()); |
285 DCHECK_LT(static_cast<size_t>(level), | 297 DCHECK_LT(static_cast<size_t>(level), |
286 level_infos_[face_index].size()); | 298 face_infos_[face_index].level_infos.size()); |
287 | 299 |
288 const Texture::LevelInfo& info = | 300 const Texture::LevelInfo& info = |
289 level_infos_[face_index][level]; | 301 face_infos_[face_index].level_infos[level]; |
290 | 302 |
291 TextureSignature signature_data(target, | 303 TextureSignature signature_data(target, |
292 level, | 304 level, |
293 min_filter_, | 305 min_filter_, |
294 mag_filter_, | 306 mag_filter_, |
295 wrap_s_, | 307 wrap_s_, |
296 wrap_t_, | 308 wrap_t_, |
297 usage_, | 309 usage_, |
298 info.internal_format, | 310 info.internal_format, |
299 info.width, | 311 info.width, |
(...skipping 15 matching lines...) Expand all Loading... |
315 void Texture::SetMailboxManager(MailboxManager* mailbox_manager) { | 327 void Texture::SetMailboxManager(MailboxManager* mailbox_manager) { |
316 DCHECK(!mailbox_manager_ || mailbox_manager_ == mailbox_manager); | 328 DCHECK(!mailbox_manager_ || mailbox_manager_ == mailbox_manager); |
317 mailbox_manager_ = mailbox_manager; | 329 mailbox_manager_ = mailbox_manager; |
318 } | 330 } |
319 | 331 |
320 bool Texture::MarkMipmapsGenerated( | 332 bool Texture::MarkMipmapsGenerated( |
321 const FeatureInfo* feature_info) { | 333 const FeatureInfo* feature_info) { |
322 if (!CanGenerateMipmaps(feature_info)) { | 334 if (!CanGenerateMipmaps(feature_info)) { |
323 return false; | 335 return false; |
324 } | 336 } |
325 for (size_t ii = 0; ii < level_infos_.size(); ++ii) { | 337 for (size_t ii = 0; ii < face_infos_.size(); ++ii) { |
326 const Texture::LevelInfo& info1 = level_infos_[ii][0]; | 338 const Texture::FaceInfo& face_info = face_infos_[ii]; |
327 GLsizei width = info1.width; | 339 const Texture::LevelInfo& level0_info = face_info.level_infos[0]; |
328 GLsizei height = info1.height; | 340 GLsizei width = level0_info.width; |
329 GLsizei depth = info1.depth; | 341 GLsizei height = level0_info.height; |
| 342 GLsizei depth = level0_info.depth; |
330 GLenum target = target_ == GL_TEXTURE_2D ? GL_TEXTURE_2D : | 343 GLenum target = target_ == GL_TEXTURE_2D ? GL_TEXTURE_2D : |
331 GLES2Util::IndexToGLFaceTarget(ii); | 344 GLES2Util::IndexToGLFaceTarget(ii); |
332 int num_mips = | 345 |
333 TextureManager::ComputeMipMapCount(target_, width, height, depth); | 346 const GLsizei num_mips = face_info.num_mip_levels; |
334 for (int level = 1; level < num_mips; ++level) { | 347 for (GLsizei level = 1; level < num_mips; ++level) { |
335 width = std::max(1, width >> 1); | 348 width = std::max(1, width >> 1); |
336 height = std::max(1, height >> 1); | 349 height = std::max(1, height >> 1); |
337 depth = std::max(1, depth >> 1); | 350 depth = std::max(1, depth >> 1); |
338 SetLevelInfo(feature_info, | 351 SetLevelInfo(feature_info, |
339 target, | 352 target, |
340 level, | 353 level, |
341 info1.internal_format, | 354 level0_info.internal_format, |
342 width, | 355 width, |
343 height, | 356 height, |
344 depth, | 357 depth, |
345 info1.border, | 358 level0_info.border, |
346 info1.format, | 359 level0_info.format, |
347 info1.type, | 360 level0_info.type, |
348 true); | 361 true); |
349 } | 362 } |
350 } | 363 } |
351 | 364 |
352 return true; | 365 return true; |
353 } | 366 } |
354 | 367 |
355 void Texture::SetTarget( | 368 void Texture::SetTarget( |
356 const FeatureInfo* feature_info, GLenum target, GLint max_levels) { | 369 const FeatureInfo* feature_info, GLenum target, GLint max_levels) { |
357 DCHECK_EQ(0u, target_); // you can only set this once. | 370 DCHECK_EQ(0u, target_); // you can only set this once. |
358 target_ = target; | 371 target_ = target; |
359 size_t num_faces = (target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; | 372 size_t num_faces = (target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; |
360 level_infos_.resize(num_faces); | 373 face_infos_.resize(num_faces); |
361 for (size_t ii = 0; ii < num_faces; ++ii) { | 374 for (size_t ii = 0; ii < num_faces; ++ii) { |
362 level_infos_[ii].resize(max_levels); | 375 face_infos_[ii].level_infos.resize(max_levels); |
363 } | 376 } |
364 | 377 |
365 if (target == GL_TEXTURE_EXTERNAL_OES || target == GL_TEXTURE_RECTANGLE_ARB) { | 378 if (target == GL_TEXTURE_EXTERNAL_OES || target == GL_TEXTURE_RECTANGLE_ARB) { |
366 min_filter_ = GL_LINEAR; | 379 min_filter_ = GL_LINEAR; |
367 wrap_s_ = wrap_t_ = GL_CLAMP_TO_EDGE; | 380 wrap_s_ = wrap_t_ = GL_CLAMP_TO_EDGE; |
368 } | 381 } |
369 | 382 |
370 if (target == GL_TEXTURE_EXTERNAL_OES) { | 383 if (target == GL_TEXTURE_EXTERNAL_OES) { |
371 immutable_ = true; | 384 immutable_ = true; |
372 } | 385 } |
373 Update(feature_info); | 386 Update(feature_info); |
374 UpdateCanRenderCondition(); | 387 UpdateCanRenderCondition(); |
375 } | 388 } |
376 | 389 |
377 bool Texture::CanGenerateMipmaps( | 390 bool Texture::CanGenerateMipmaps( |
378 const FeatureInfo* feature_info) const { | 391 const FeatureInfo* feature_info) const { |
379 if ((npot() && !feature_info->feature_flags().npot_ok) || | 392 if ((npot() && !feature_info->feature_flags().npot_ok) || |
380 level_infos_.empty() || | 393 face_infos_.empty() || |
381 target_ == GL_TEXTURE_EXTERNAL_OES || | 394 target_ == GL_TEXTURE_EXTERNAL_OES || |
382 target_ == GL_TEXTURE_RECTANGLE_ARB) { | 395 target_ == GL_TEXTURE_RECTANGLE_ARB) { |
383 return false; | 396 return false; |
384 } | 397 } |
385 | 398 |
386 // Can't generate mips for depth or stencil textures. | 399 // Can't generate mips for depth or stencil textures. |
387 const Texture::LevelInfo& first = level_infos_[0][0]; | 400 const Texture::LevelInfo& first = face_infos_[0].level_infos[0]; |
388 uint32 channels = GLES2Util::GetChannelsForFormat(first.format); | 401 uint32 channels = GLES2Util::GetChannelsForFormat(first.format); |
389 if (channels & (GLES2Util::kDepth | GLES2Util::kStencil)) { | 402 if (channels & (GLES2Util::kDepth | GLES2Util::kStencil)) { |
390 return false; | 403 return false; |
391 } | 404 } |
392 | 405 |
393 // TODO(gman): Check internal_format, format and type. | 406 // TODO(gman): Check internal_format, format and type. |
394 for (size_t ii = 0; ii < level_infos_.size(); ++ii) { | 407 for (size_t ii = 0; ii < face_infos_.size(); ++ii) { |
395 const LevelInfo& info = level_infos_[ii][0]; | 408 const LevelInfo& info = face_infos_[ii].level_infos[0]; |
396 if ((info.target == 0) || (info.width != first.width) || | 409 if ((info.target == 0) || (info.width != first.width) || |
397 (info.height != first.height) || (info.depth != 1) || | 410 (info.height != first.height) || (info.depth != 1) || |
398 (info.format != first.format) || | 411 (info.format != first.format) || |
399 (info.internal_format != first.internal_format) || | 412 (info.internal_format != first.internal_format) || |
400 (info.type != first.type) || | 413 (info.type != first.type) || |
401 feature_info->validators()->compressed_texture_format.IsValid( | 414 feature_info->validators()->compressed_texture_format.IsValid( |
402 info.internal_format) || | 415 info.internal_format) || |
403 info.image.get()) { | 416 info.image.get()) { |
404 return false; | 417 return false; |
405 } | 418 } |
406 } | 419 } |
407 return true; | 420 return true; |
408 } | 421 } |
409 | 422 |
| 423 bool Texture::TextureIsNPOT(GLsizei width, |
| 424 GLsizei height, |
| 425 GLsizei depth) { |
| 426 return (GLES2Util::IsNPOT(width) || |
| 427 GLES2Util::IsNPOT(height) || |
| 428 GLES2Util::IsNPOT(depth)); |
| 429 } |
| 430 |
| 431 bool Texture::TextureFaceComplete(const Texture::LevelInfo& first_face, |
| 432 size_t face_index, |
| 433 GLenum target, |
| 434 GLenum internal_format, |
| 435 GLsizei width, |
| 436 GLsizei height, |
| 437 GLsizei depth, |
| 438 GLenum format, |
| 439 GLenum type) { |
| 440 bool complete = (target != 0 && depth == 1); |
| 441 if (face_index != 0) { |
| 442 complete &= (width == first_face.width && |
| 443 height == first_face.height && |
| 444 internal_format == first_face.internal_format && |
| 445 format == first_face.format && |
| 446 type == first_face.type); |
| 447 } |
| 448 return complete; |
| 449 } |
| 450 |
| 451 bool Texture::TextureMipComplete(const Texture::LevelInfo& level0_face, |
| 452 GLenum target, |
| 453 GLint level, |
| 454 GLenum internal_format, |
| 455 GLsizei width, |
| 456 GLsizei height, |
| 457 GLsizei depth, |
| 458 GLenum format, |
| 459 GLenum type) { |
| 460 bool complete = (target != 0); |
| 461 if (level != 0) { |
| 462 const GLsizei mip_width = std::max(1, level0_face.width >> level); |
| 463 const GLsizei mip_height = std::max(1, level0_face.height >> level); |
| 464 const GLsizei mip_depth = std::max(1, level0_face.depth >> level); |
| 465 |
| 466 complete &= (width == mip_width && |
| 467 height == mip_height && |
| 468 depth == mip_depth && |
| 469 internal_format == level0_face.internal_format && |
| 470 format == level0_face.format && |
| 471 type == level0_face.type); |
| 472 } |
| 473 return complete; |
| 474 } |
| 475 |
410 void Texture::SetLevelCleared(GLenum target, GLint level, bool cleared) { | 476 void Texture::SetLevelCleared(GLenum target, GLint level, bool cleared) { |
411 DCHECK_GE(level, 0); | 477 DCHECK_GE(level, 0); |
412 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); | 478 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); |
413 DCHECK_LT(static_cast<size_t>(face_index), | 479 DCHECK_LT(static_cast<size_t>(face_index), |
414 level_infos_.size()); | 480 face_infos_.size()); |
415 DCHECK_LT(static_cast<size_t>(level), | 481 DCHECK_LT(static_cast<size_t>(level), |
416 level_infos_[face_index].size()); | 482 face_infos_[face_index].level_infos.size()); |
417 Texture::LevelInfo& info = | 483 Texture::LevelInfo& info = |
418 level_infos_[face_index][level]; | 484 face_infos_[face_index].level_infos[level]; |
419 UpdateMipCleared(&info, cleared); | 485 UpdateMipCleared(&info, cleared); |
420 UpdateCleared(); | 486 UpdateCleared(); |
421 } | 487 } |
422 | 488 |
423 void Texture::UpdateCleared() { | 489 void Texture::UpdateCleared() { |
424 if (level_infos_.empty()) { | 490 if (face_infos_.empty()) { |
425 return; | 491 return; |
426 } | 492 } |
427 | 493 |
428 const bool cleared = (num_uncleared_mips_ == 0); | 494 const bool cleared = (num_uncleared_mips_ == 0); |
429 | 495 |
430 // If texture is uncleared and is attached to a framebuffer, | 496 // If texture is uncleared and is attached to a framebuffer, |
431 // that framebuffer must be marked possibly incomplete. | 497 // that framebuffer must be marked possibly incomplete. |
432 if (!cleared && IsAttachedToFramebuffer()) { | 498 if (!cleared && IsAttachedToFramebuffer()) { |
433 IncAllFramebufferStateChangeCount(); | 499 IncAllFramebufferStateChangeCount(); |
434 } | 500 } |
(...skipping 24 matching lines...) Expand all Loading... |
459 CanRenderCondition can_render_condition = GetCanRenderCondition(); | 525 CanRenderCondition can_render_condition = GetCanRenderCondition(); |
460 if (can_render_condition_ == can_render_condition) | 526 if (can_render_condition_ == can_render_condition) |
461 return; | 527 return; |
462 for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it) | 528 for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it) |
463 (*it)->manager()->UpdateCanRenderCondition(can_render_condition_, | 529 (*it)->manager()->UpdateCanRenderCondition(can_render_condition_, |
464 can_render_condition); | 530 can_render_condition); |
465 can_render_condition_ = can_render_condition; | 531 can_render_condition_ = can_render_condition; |
466 } | 532 } |
467 | 533 |
468 void Texture::UpdateHasImages() { | 534 void Texture::UpdateHasImages() { |
469 if (level_infos_.empty()) | 535 if (face_infos_.empty()) |
470 return; | 536 return; |
471 | 537 |
472 bool has_images = false; | 538 bool has_images = false; |
473 for (size_t ii = 0; ii < level_infos_.size(); ++ii) { | 539 for (size_t ii = 0; ii < face_infos_.size(); ++ii) { |
474 for (size_t jj = 0; jj < level_infos_[ii].size(); ++jj) { | 540 for (size_t jj = 0; jj < face_infos_[ii].level_infos.size(); ++jj) { |
475 const Texture::LevelInfo& info = level_infos_[ii][jj]; | 541 const Texture::LevelInfo& info = face_infos_[ii].level_infos[jj]; |
476 if (info.image.get() != NULL) { | 542 if (info.image.get() != NULL) { |
477 has_images = true; | 543 has_images = true; |
478 break; | 544 break; |
479 } | 545 } |
480 } | 546 } |
481 } | 547 } |
482 | 548 |
483 if (has_images_ == has_images) | 549 if (has_images_ == has_images) |
484 return; | 550 return; |
485 has_images_ = has_images; | 551 has_images_ = has_images; |
(...skipping 15 matching lines...) Expand all Loading... |
501 GLsizei width, | 567 GLsizei width, |
502 GLsizei height, | 568 GLsizei height, |
503 GLsizei depth, | 569 GLsizei depth, |
504 GLint border, | 570 GLint border, |
505 GLenum format, | 571 GLenum format, |
506 GLenum type, | 572 GLenum type, |
507 bool cleared) { | 573 bool cleared) { |
508 DCHECK_GE(level, 0); | 574 DCHECK_GE(level, 0); |
509 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); | 575 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); |
510 DCHECK_LT(static_cast<size_t>(face_index), | 576 DCHECK_LT(static_cast<size_t>(face_index), |
511 level_infos_.size()); | 577 face_infos_.size()); |
512 DCHECK_LT(static_cast<size_t>(level), | 578 DCHECK_LT(static_cast<size_t>(level), |
513 level_infos_[face_index].size()); | 579 face_infos_[face_index].level_infos.size()); |
514 DCHECK_GE(width, 0); | 580 DCHECK_GE(width, 0); |
515 DCHECK_GE(height, 0); | 581 DCHECK_GE(height, 0); |
516 DCHECK_GE(depth, 0); | 582 DCHECK_GE(depth, 0); |
517 Texture::LevelInfo& info = | 583 Texture::LevelInfo& info = |
518 level_infos_[face_index][level]; | 584 face_infos_[face_index].level_infos[level]; |
| 585 |
| 586 // Update counters only if any attributes have changed. Counters are |
| 587 // comparisons between the old and new values so it must be done before any |
| 588 // assignment has been done to the LevelInfo. |
| 589 if (info.target != target || |
| 590 info.internal_format != internal_format || |
| 591 info.width != width || |
| 592 info.height != height || |
| 593 info.depth != depth || |
| 594 info.format != format || |
| 595 info.type != type) { |
| 596 if (level == 0) { |
| 597 // Calculate the mip level count. |
| 598 face_infos_[face_index].num_mip_levels = |
| 599 TextureManager::ComputeMipMapCount(target_, width, height, depth); |
| 600 |
| 601 // Update NPOT face count for the first level. |
| 602 bool prev_npot = TextureIsNPOT(info.width, info.height, info.depth); |
| 603 bool now_npot = TextureIsNPOT(width, height, depth); |
| 604 if (prev_npot != now_npot) |
| 605 num_npot_faces_ += now_npot ? 1 : -1; |
| 606 |
| 607 // Signify that level 0 has been changed, so they need to be reverified. |
| 608 texture_level0_dirty_ = true; |
| 609 } |
| 610 |
| 611 // Signify that at least one of the mips has changed. |
| 612 texture_mips_dirty_ = true; |
| 613 } |
| 614 |
519 info.target = target; | 615 info.target = target; |
520 info.level = level; | 616 info.level = level; |
521 info.internal_format = internal_format; | 617 info.internal_format = internal_format; |
522 info.width = width; | 618 info.width = width; |
523 info.height = height; | 619 info.height = height; |
524 info.depth = depth; | 620 info.depth = depth; |
525 info.border = border; | 621 info.border = border; |
526 info.format = format; | 622 info.format = format; |
527 info.type = type; | 623 info.type = type; |
528 info.image = 0; | 624 info.image = 0; |
(...skipping 18 matching lines...) Expand all Loading... |
547 | 643 |
548 bool Texture::ValidForTexture( | 644 bool Texture::ValidForTexture( |
549 GLint target, | 645 GLint target, |
550 GLint level, | 646 GLint level, |
551 GLint xoffset, | 647 GLint xoffset, |
552 GLint yoffset, | 648 GLint yoffset, |
553 GLsizei width, | 649 GLsizei width, |
554 GLsizei height, | 650 GLsizei height, |
555 GLenum type) const { | 651 GLenum type) const { |
556 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); | 652 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); |
557 if (level >= 0 && face_index < level_infos_.size() && | 653 if (level >= 0 && face_index < face_infos_.size() && |
558 static_cast<size_t>(level) < level_infos_[face_index].size()) { | 654 static_cast<size_t>(level) < face_infos_[face_index].level_infos.size()) { |
559 const LevelInfo& info = level_infos_[face_index][level]; | 655 const LevelInfo& info = face_infos_[face_index].level_infos[level]; |
560 int32 right; | 656 int32 right; |
561 int32 top; | 657 int32 top; |
562 return SafeAddInt32(xoffset, width, &right) && | 658 return SafeAddInt32(xoffset, width, &right) && |
563 SafeAddInt32(yoffset, height, &top) && | 659 SafeAddInt32(yoffset, height, &top) && |
564 xoffset >= 0 && | 660 xoffset >= 0 && |
565 yoffset >= 0 && | 661 yoffset >= 0 && |
566 right <= info.width && | 662 right <= info.width && |
567 top <= info.height && | 663 top <= info.height && |
568 type == info.type; | 664 type == info.type; |
569 } | 665 } |
570 return false; | 666 return false; |
571 } | 667 } |
572 | 668 |
573 bool Texture::GetLevelSize( | 669 bool Texture::GetLevelSize( |
574 GLint target, GLint level, GLsizei* width, GLsizei* height) const { | 670 GLint target, GLint level, GLsizei* width, GLsizei* height) const { |
575 DCHECK(width); | 671 DCHECK(width); |
576 DCHECK(height); | 672 DCHECK(height); |
577 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); | 673 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); |
578 if (level >= 0 && face_index < level_infos_.size() && | 674 if (level >= 0 && face_index < face_infos_.size() && |
579 static_cast<size_t>(level) < level_infos_[face_index].size()) { | 675 static_cast<size_t>(level) < face_infos_[face_index].level_infos.size()) { |
580 const LevelInfo& info = level_infos_[face_index][level]; | 676 const LevelInfo& info = face_infos_[face_index].level_infos[level]; |
581 if (info.target != 0) { | 677 if (info.target != 0) { |
582 *width = info.width; | 678 *width = info.width; |
583 *height = info.height; | 679 *height = info.height; |
584 return true; | 680 return true; |
585 } | 681 } |
586 } | 682 } |
587 return false; | 683 return false; |
588 } | 684 } |
589 | 685 |
590 bool Texture::GetLevelType( | 686 bool Texture::GetLevelType( |
591 GLint target, GLint level, GLenum* type, GLenum* internal_format) const { | 687 GLint target, GLint level, GLenum* type, GLenum* internal_format) const { |
592 DCHECK(type); | 688 DCHECK(type); |
593 DCHECK(internal_format); | 689 DCHECK(internal_format); |
594 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); | 690 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); |
595 if (level >= 0 && face_index < level_infos_.size() && | 691 if (level >= 0 && face_index < face_infos_.size() && |
596 static_cast<size_t>(level) < level_infos_[face_index].size()) { | 692 static_cast<size_t>(level) < face_infos_[face_index].level_infos.size()) { |
597 const LevelInfo& info = level_infos_[face_index][level]; | 693 const LevelInfo& info = face_infos_[face_index].level_infos[level]; |
598 if (info.target != 0) { | 694 if (info.target != 0) { |
599 *type = info.type; | 695 *type = info.type; |
600 *internal_format = info.internal_format; | 696 *internal_format = info.internal_format; |
601 return true; | 697 return true; |
602 } | 698 } |
603 } | 699 } |
604 return false; | 700 return false; |
605 } | 701 } |
606 | 702 |
607 GLenum Texture::SetParameteri( | 703 GLenum Texture::SetParameteri( |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 default: | 789 default: |
694 NOTREACHED(); | 790 NOTREACHED(); |
695 return GL_INVALID_ENUM; | 791 return GL_INVALID_ENUM; |
696 } | 792 } |
697 return GL_NO_ERROR; | 793 return GL_NO_ERROR; |
698 } | 794 } |
699 | 795 |
700 void Texture::Update(const FeatureInfo* feature_info) { | 796 void Texture::Update(const FeatureInfo* feature_info) { |
701 // Update npot status. | 797 // Update npot status. |
702 // Assume GL_TEXTURE_EXTERNAL_OES textures are npot, all others | 798 // Assume GL_TEXTURE_EXTERNAL_OES textures are npot, all others |
703 npot_ = target_ == GL_TEXTURE_EXTERNAL_OES; | 799 npot_ = (target_ == GL_TEXTURE_EXTERNAL_OES) || (num_npot_faces_ > 0); |
704 | 800 |
705 if (level_infos_.empty()) { | 801 if (face_infos_.empty()) { |
706 texture_complete_ = false; | 802 texture_complete_ = false; |
707 cube_complete_ = false; | 803 cube_complete_ = false; |
708 return; | 804 return; |
709 } | 805 } |
710 | 806 |
711 // checks that the first mip of any face is npot. | 807 // Update texture_complete and cube_complete status. |
712 for (size_t ii = 0; ii < level_infos_.size(); ++ii) { | 808 const Texture::FaceInfo& first_face = face_infos_[0]; |
713 const Texture::LevelInfo& info = level_infos_[ii][0]; | 809 const Texture::LevelInfo& first_level = first_face.level_infos[0]; |
714 if (GLES2Util::IsNPOT(info.width) || | 810 const GLsizei levels_needed = first_face.num_mip_levels; |
715 GLES2Util::IsNPOT(info.height) || | |
716 GLES2Util::IsNPOT(info.depth)) { | |
717 npot_ = true; | |
718 break; | |
719 } | |
720 } | |
721 | 811 |
722 // Update texture_complete and cube_complete status. | |
723 const Texture::LevelInfo& first_face = level_infos_[0][0]; | |
724 int levels_needed = TextureManager::ComputeMipMapCount( | |
725 target_, first_face.width, first_face.height, first_face.depth); | |
726 texture_complete_ = | 812 texture_complete_ = |
727 max_level_set_ >= (levels_needed - 1) && max_level_set_ >= 0; | 813 max_level_set_ >= (levels_needed - 1) && max_level_set_ >= 0; |
728 cube_complete_ = (level_infos_.size() == 6) && | 814 cube_complete_ = (face_infos_.size() == 6) && |
729 (first_face.width == first_face.height); | 815 (first_level.width == first_level.height); |
730 | 816 |
731 if (first_face.width == 0 || first_face.height == 0) { | 817 if (first_level.width == 0 || first_level.height == 0) { |
732 texture_complete_ = false; | 818 texture_complete_ = false; |
733 } | 819 } else if (first_level.type == GL_FLOAT && |
734 if (first_face.type == GL_FLOAT && | |
735 !feature_info->feature_flags().enable_texture_float_linear && | 820 !feature_info->feature_flags().enable_texture_float_linear && |
736 (min_filter_ != GL_NEAREST_MIPMAP_NEAREST || | 821 (min_filter_ != GL_NEAREST_MIPMAP_NEAREST || |
737 mag_filter_ != GL_NEAREST)) { | 822 mag_filter_ != GL_NEAREST)) { |
738 texture_complete_ = false; | 823 texture_complete_ = false; |
739 } else if (first_face.type == GL_HALF_FLOAT_OES && | 824 } else if (first_level.type == GL_HALF_FLOAT_OES && |
740 !feature_info->feature_flags().enable_texture_half_float_linear && | 825 !feature_info->feature_flags().enable_texture_half_float_linear && |
741 (min_filter_ != GL_NEAREST_MIPMAP_NEAREST || | 826 (min_filter_ != GL_NEAREST_MIPMAP_NEAREST || |
742 mag_filter_ != GL_NEAREST)) { | 827 mag_filter_ != GL_NEAREST)) { |
743 texture_complete_ = false; | 828 texture_complete_ = false; |
744 } | 829 } |
745 for (size_t ii = 0; | 830 |
746 ii < level_infos_.size() && (cube_complete_ || texture_complete_); | 831 if (cube_complete_ && texture_level0_dirty_) { |
747 ++ii) { | 832 texture_level0_complete_ = true; |
748 const Texture::LevelInfo& level0 = level_infos_[ii][0]; | 833 for (size_t ii = 0; ii < face_infos_.size(); ++ii) { |
749 if (level0.target == 0 || | 834 const Texture::LevelInfo& level0 = face_infos_[ii].level_infos[0]; |
750 level0.width != first_face.width || | 835 if (!TextureFaceComplete(first_level, |
751 level0.height != first_face.height || | 836 ii, |
752 level0.depth != 1 || | 837 level0.target, |
753 level0.internal_format != first_face.internal_format || | 838 level0.internal_format, |
754 level0.format != first_face.format || | 839 level0.width, |
755 level0.type != first_face.type) { | 840 level0.height, |
756 cube_complete_ = false; | 841 level0.depth, |
757 } | 842 level0.format, |
758 // Get level0 dimensions | 843 level0.type)) { |
759 GLsizei width = level0.width; | 844 texture_level0_complete_ = false; |
760 GLsizei height = level0.height; | |
761 GLsizei depth = level0.depth; | |
762 for (GLint jj = 1; jj < levels_needed; ++jj) { | |
763 // compute required size for mip. | |
764 width = std::max(1, width >> 1); | |
765 height = std::max(1, height >> 1); | |
766 depth = std::max(1, depth >> 1); | |
767 const Texture::LevelInfo& info = level_infos_[ii][jj]; | |
768 if (info.target == 0 || | |
769 info.width != width || | |
770 info.height != height || | |
771 info.depth != depth || | |
772 info.internal_format != level0.internal_format || | |
773 info.format != level0.format || | |
774 info.type != level0.type) { | |
775 texture_complete_ = false; | |
776 break; | 845 break; |
777 } | 846 } |
778 } | 847 } |
| 848 texture_level0_dirty_ = false; |
779 } | 849 } |
| 850 cube_complete_ &= texture_level0_complete_; |
| 851 |
| 852 if (texture_complete_ && texture_mips_dirty_) { |
| 853 texture_mips_complete_ = true; |
| 854 for (size_t ii = 0; |
| 855 ii < face_infos_.size() && texture_mips_complete_; |
| 856 ++ii) { |
| 857 const Texture::FaceInfo& face_info = face_infos_[ii]; |
| 858 const Texture::LevelInfo& level0 = face_info.level_infos[0]; |
| 859 for (GLsizei jj = 1; jj < levels_needed; ++jj) { |
| 860 const Texture::LevelInfo& level_info = face_infos_[ii].level_infos[jj]; |
| 861 if (!TextureMipComplete(level0, |
| 862 level_info.target, |
| 863 jj, |
| 864 level_info.internal_format, |
| 865 level_info.width, |
| 866 level_info.height, |
| 867 level_info.depth, |
| 868 level_info.format, |
| 869 level_info.type)) { |
| 870 texture_mips_complete_ = false; |
| 871 break; |
| 872 } |
| 873 } |
| 874 } |
| 875 texture_mips_dirty_ = false; |
| 876 } |
| 877 texture_complete_ &= texture_mips_complete_; |
780 } | 878 } |
781 | 879 |
782 bool Texture::ClearRenderableLevels(GLES2Decoder* decoder) { | 880 bool Texture::ClearRenderableLevels(GLES2Decoder* decoder) { |
783 DCHECK(decoder); | 881 DCHECK(decoder); |
784 if (cleared_) { | 882 if (cleared_) { |
785 return true; | 883 return true; |
786 } | 884 } |
787 | 885 |
788 const Texture::LevelInfo& first_face = level_infos_[0][0]; | 886 for (size_t ii = 0; ii < face_infos_.size(); ++ii) { |
789 int levels_needed = TextureManager::ComputeMipMapCount( | 887 const Texture::FaceInfo& face_info = face_infos_[ii]; |
790 target_, first_face.width, first_face.height, first_face.depth); | 888 for (GLint jj = 0; jj < face_info.num_mip_levels; ++jj) { |
791 | 889 const Texture::LevelInfo& info = face_info.level_infos[jj]; |
792 for (size_t ii = 0; ii < level_infos_.size(); ++ii) { | |
793 for (GLint jj = 0; jj < levels_needed; ++jj) { | |
794 Texture::LevelInfo& info = level_infos_[ii][jj]; | |
795 if (info.target != 0) { | 890 if (info.target != 0) { |
796 if (!ClearLevel(decoder, info.target, jj)) { | 891 if (!ClearLevel(decoder, info.target, jj)) { |
797 return false; | 892 return false; |
798 } | 893 } |
799 } | 894 } |
800 } | 895 } |
801 } | 896 } |
802 UpdateSafeToRenderFrom(true); | 897 UpdateSafeToRenderFrom(true); |
803 return true; | 898 return true; |
804 } | 899 } |
805 | 900 |
806 bool Texture::IsLevelCleared(GLenum target, GLint level) const { | 901 bool Texture::IsLevelCleared(GLenum target, GLint level) const { |
807 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); | 902 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); |
808 if (face_index >= level_infos_.size() || | 903 if (face_index >= face_infos_.size() || |
809 level >= static_cast<GLint>(level_infos_[face_index].size())) { | 904 level >= static_cast<GLint>(face_infos_[face_index].level_infos.size())) { |
810 return true; | 905 return true; |
811 } | 906 } |
812 | 907 |
813 const Texture::LevelInfo& info = level_infos_[face_index][level]; | 908 const Texture::LevelInfo& info = face_infos_[face_index].level_infos[level]; |
814 | 909 |
815 return info.cleared; | 910 return info.cleared; |
816 } | 911 } |
817 | 912 |
818 void Texture::InitTextureMaxAnisotropyIfNeeded(GLenum target) { | 913 void Texture::InitTextureMaxAnisotropyIfNeeded(GLenum target) { |
819 if (texture_max_anisotropy_initialized_) | 914 if (texture_max_anisotropy_initialized_) |
820 return; | 915 return; |
821 texture_max_anisotropy_initialized_ = true; | 916 texture_max_anisotropy_initialized_ = true; |
822 GLfloat params[] = { 1.0f }; | 917 GLfloat params[] = { 1.0f }; |
823 glTexParameterfv(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, params); | 918 glTexParameterfv(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, params); |
824 } | 919 } |
825 | 920 |
826 bool Texture::ClearLevel( | 921 bool Texture::ClearLevel( |
827 GLES2Decoder* decoder, GLenum target, GLint level) { | 922 GLES2Decoder* decoder, GLenum target, GLint level) { |
828 DCHECK(decoder); | 923 DCHECK(decoder); |
829 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); | 924 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); |
830 if (face_index >= level_infos_.size() || | 925 if (face_index >= face_infos_.size() || |
831 level >= static_cast<GLint>(level_infos_[face_index].size())) { | 926 level >= static_cast<GLint>(face_infos_[face_index].level_infos.size())) { |
832 return true; | 927 return true; |
833 } | 928 } |
834 | 929 |
835 Texture::LevelInfo& info = level_infos_[face_index][level]; | 930 Texture::LevelInfo& info = face_infos_[face_index].level_infos[level]; |
836 | 931 |
837 DCHECK(target == info.target); | 932 DCHECK(target == info.target); |
838 | 933 |
839 if (info.target == 0 || | 934 if (info.target == 0 || |
840 info.cleared || | 935 info.cleared || |
841 info.width == 0 || | 936 info.width == 0 || |
842 info.height == 0 || | 937 info.height == 0 || |
843 info.depth == 0) { | 938 info.depth == 0) { |
844 return true; | 939 return true; |
845 } | 940 } |
846 | 941 |
847 // NOTE: It seems kind of gross to call back into the decoder for this | 942 // NOTE: It seems kind of gross to call back into the decoder for this |
848 // but only the decoder knows all the state (like unpack_alignment_) that's | 943 // but only the decoder knows all the state (like unpack_alignment_) that's |
849 // needed to be able to call GL correctly. | 944 // needed to be able to call GL correctly. |
850 bool cleared = decoder->ClearLevel( | 945 bool cleared = decoder->ClearLevel( |
851 service_id_, target_, info.target, info.level, info.internal_format, | 946 service_id_, target_, info.target, info.level, info.internal_format, |
852 info.format, info.type, info.width, info.height, immutable_); | 947 info.format, info.type, info.width, info.height, immutable_); |
853 UpdateMipCleared(&info, cleared); | 948 UpdateMipCleared(&info, cleared); |
854 return info.cleared; | 949 return info.cleared; |
855 } | 950 } |
856 | 951 |
857 void Texture::SetLevelImage( | 952 void Texture::SetLevelImage( |
858 const FeatureInfo* feature_info, | 953 const FeatureInfo* feature_info, |
859 GLenum target, | 954 GLenum target, |
860 GLint level, | 955 GLint level, |
861 gfx::GLImage* image) { | 956 gfx::GLImage* image) { |
862 DCHECK_GE(level, 0); | 957 DCHECK_GE(level, 0); |
863 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); | 958 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); |
864 DCHECK_LT(static_cast<size_t>(face_index), | 959 DCHECK_LT(static_cast<size_t>(face_index), |
865 level_infos_.size()); | 960 face_infos_.size()); |
866 DCHECK_LT(static_cast<size_t>(level), | 961 DCHECK_LT(static_cast<size_t>(level), |
867 level_infos_[face_index].size()); | 962 face_infos_[face_index].level_infos.size()); |
868 Texture::LevelInfo& info = | 963 Texture::LevelInfo& info = |
869 level_infos_[face_index][level]; | 964 face_infos_[face_index].level_infos[level]; |
870 DCHECK_EQ(info.target, target); | 965 DCHECK_EQ(info.target, target); |
871 DCHECK_EQ(info.level, level); | 966 DCHECK_EQ(info.level, level); |
872 info.image = image; | 967 info.image = image; |
873 UpdateCanRenderCondition(); | 968 UpdateCanRenderCondition(); |
874 UpdateHasImages(); | 969 UpdateHasImages(); |
875 } | 970 } |
876 | 971 |
877 gfx::GLImage* Texture::GetLevelImage(GLint target, GLint level) const { | 972 gfx::GLImage* Texture::GetLevelImage(GLint target, GLint level) const { |
878 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES && | 973 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES && |
879 target != GL_TEXTURE_RECTANGLE_ARB) { | 974 target != GL_TEXTURE_RECTANGLE_ARB) { |
880 return NULL; | 975 return NULL; |
881 } | 976 } |
882 | 977 |
883 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); | 978 size_t face_index = GLES2Util::GLTargetToFaceIndex(target); |
884 if (level >= 0 && face_index < level_infos_.size() && | 979 if (level >= 0 && face_index < face_infos_.size() && |
885 static_cast<size_t>(level) < level_infos_[face_index].size()) { | 980 static_cast<size_t>(level) < face_infos_[face_index].level_infos.size()) { |
886 const LevelInfo& info = level_infos_[face_index][level]; | 981 const LevelInfo& info = face_infos_[face_index].level_infos[level]; |
887 if (info.target != 0) { | 982 if (info.target != 0) { |
888 return info.image.get(); | 983 return info.image.get(); |
889 } | 984 } |
890 } | 985 } |
891 return NULL; | 986 return NULL; |
892 } | 987 } |
893 | 988 |
894 void Texture::OnWillModifyPixels() { | 989 void Texture::OnWillModifyPixels() { |
895 gfx::GLImage* image = GetLevelImage(target(), 0); | 990 gfx::GLImage* image = GetLevelImage(target(), 0); |
896 if (image) | 991 if (image) |
(...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1612 } | 1707 } |
1613 | 1708 |
1614 ScopedTextureUploadTimer::~ScopedTextureUploadTimer() { | 1709 ScopedTextureUploadTimer::~ScopedTextureUploadTimer() { |
1615 texture_state_->texture_upload_count++; | 1710 texture_state_->texture_upload_count++; |
1616 texture_state_->total_texture_upload_time += | 1711 texture_state_->total_texture_upload_time += |
1617 base::TimeTicks::HighResNow() - begin_time_; | 1712 base::TimeTicks::HighResNow() - begin_time_; |
1618 } | 1713 } |
1619 | 1714 |
1620 } // namespace gles2 | 1715 } // namespace gles2 |
1621 } // namespace gpu | 1716 } // namespace gpu |
OLD | NEW |