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