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

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: Recalculate texture/cube complete on dirty flag, added face structure 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),
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
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
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
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
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
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
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
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
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
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