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

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

Issue 633773002: Optimized Texture::Update() function. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed issue with caching level0 and mip results Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « gpu/command_buffer/service/texture_manager.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "gpu/command_buffer/service/texture_manager.h" 5 #include "gpu/command_buffer/service/texture_manager.h"
6 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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/texture_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698