| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 2376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2387 memset(zero.get(), 0, args.pixels_size); | 2387 memset(zero.get(), 0, args.pixels_size); |
| 2388 for (GLenum face : undefined_faces) { | 2388 for (GLenum face : undefined_faces) { |
| 2389 new_args.target = face; | 2389 new_args.target = face; |
| 2390 new_args.pixels = zero.get(); | 2390 new_args.pixels = zero.get(); |
| 2391 DoTexImage(texture_state, state, framebuffer_state, | 2391 DoTexImage(texture_state, state, framebuffer_state, |
| 2392 function_name, texture_ref, new_args); | 2392 function_name, texture_ref, new_args); |
| 2393 texture->MarkLevelAsInternalWorkaround(face, args.level); | 2393 texture->MarkLevelAsInternalWorkaround(face, args.level); |
| 2394 } | 2394 } |
| 2395 } | 2395 } |
| 2396 | 2396 |
| 2397 if (texture_state->unpack_overlapping_rows_separately_unpack_buffer && |
| 2398 buffer) { |
| 2399 ContextState::Dimension dimension = |
| 2400 (args.command_type == DoTexImageArguments::kTexImage3D) |
| 2401 ? ContextState::k3D |
| 2402 : ContextState::k2D; |
| 2403 const PixelStoreParams unpack_params(state->GetUnpackParams(dimension)); |
| 2404 if (unpack_params.row_length != 0 && |
| 2405 unpack_params.row_length < args.width) { |
| 2406 // The rows overlap in unpack memory. Upload the texture row by row to |
| 2407 // work around driver bug. |
| 2408 |
| 2409 ReserveTexImageToBeFilled(texture_state, state, framebuffer_state, |
| 2410 function_name, texture_ref, args); |
| 2411 |
| 2412 DoTexSubImageArguments sub_args = { |
| 2413 args.target, args.level, 0, 0, 0, args.width, args.height, args.depth, |
| 2414 args.format, args.type, args.pixels, args.pixels_size, args.padding, |
| 2415 args.command_type == DoTexImageArguments::kTexImage3D |
| 2416 ? DoTexSubImageArguments::kTexSubImage3D |
| 2417 : DoTexSubImageArguments::kTexSubImage2D}; |
| 2418 DoTexSubImageRowByRowWorkaround(texture_state, state, sub_args, |
| 2419 unpack_params); |
| 2420 |
| 2421 SetLevelCleared(texture_ref, args.target, args.level, true); |
| 2422 return; |
| 2423 } |
| 2424 } |
| 2425 |
| 2397 if (texture_state->unpack_alignment_workaround_with_unpack_buffer && buffer) { | 2426 if (texture_state->unpack_alignment_workaround_with_unpack_buffer && buffer) { |
| 2398 uint32_t buffer_size = static_cast<uint32_t>(buffer->size()); | 2427 uint32_t buffer_size = static_cast<uint32_t>(buffer->size()); |
| 2399 if (buffer_size - args.pixels_size - ToGLuint(args.pixels) < args.padding) { | 2428 if (buffer_size - args.pixels_size - ToGLuint(args.pixels) < args.padding) { |
| 2400 // In ValidateTexImage(), we already made sure buffer size is no less | 2429 // In ValidateTexImage(), we already made sure buffer size is no less |
| 2401 // than offset + pixels_size. | 2430 // than offset + pixels_size. |
| 2402 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); | 2431 ReserveTexImageToBeFilled(texture_state, state, framebuffer_state, |
| 2403 state->SetBoundBuffer(GL_PIXEL_UNPACK_BUFFER, nullptr); | 2432 function_name, texture_ref, args); |
| 2404 DoTexImageArguments new_args = args; | |
| 2405 new_args.pixels = nullptr; | |
| 2406 // pixels_size might be incorrect, but it's not used in this case. | |
| 2407 DoTexImage(texture_state, state, framebuffer_state, function_name, | |
| 2408 texture_ref, new_args); | |
| 2409 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer->service_id()); | |
| 2410 state->SetBoundBuffer(GL_PIXEL_UNPACK_BUFFER, buffer); | |
| 2411 | 2433 |
| 2412 DoTexSubImageArguments sub_args = { | 2434 DoTexSubImageArguments sub_args = { |
| 2413 args.target, args.level, 0, 0, 0, args.width, args.height, args.depth, | 2435 args.target, args.level, 0, 0, 0, args.width, args.height, args.depth, |
| 2414 args.format, args.type, args.pixels, args.pixels_size, args.padding, | 2436 args.format, args.type, args.pixels, args.pixels_size, args.padding, |
| 2415 args.command_type == DoTexImageArguments::kTexImage3D ? | 2437 args.command_type == DoTexImageArguments::kTexImage3D ? |
| 2416 DoTexSubImageArguments::kTexSubImage3D : | 2438 DoTexSubImageArguments::kTexSubImage3D : |
| 2417 DoTexSubImageArguments::kTexSubImage2D}; | 2439 DoTexSubImageArguments::kTexSubImage2D}; |
| 2418 DoTexSubImageWithAlignmentWorkaround(texture_state, state, sub_args); | 2440 DoTexSubImageWithAlignmentWorkaround(texture_state, state, sub_args); |
| 2419 | 2441 |
| 2420 SetLevelCleared(texture_ref, args.target, args.level, true); | 2442 SetLevelCleared(texture_ref, args.target, args.level, true); |
| 2421 return; | 2443 return; |
| 2422 } | 2444 } |
| 2423 } | 2445 } |
| 2424 DoTexImage(texture_state, state, framebuffer_state, | 2446 DoTexImage(texture_state, state, framebuffer_state, |
| 2425 function_name, texture_ref, args); | 2447 function_name, texture_ref, args); |
| 2426 } | 2448 } |
| 2427 | 2449 |
| 2450 void TextureManager::ReserveTexImageToBeFilled( |
| 2451 DecoderTextureState* texture_state, |
| 2452 ContextState* state, |
| 2453 DecoderFramebufferState* framebuffer_state, |
| 2454 const char* function_name, |
| 2455 TextureRef* texture_ref, |
| 2456 const DoTexImageArguments& args) { |
| 2457 Buffer* buffer = state->bound_pixel_unpack_buffer.get(); |
| 2458 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); |
| 2459 state->SetBoundBuffer(GL_PIXEL_UNPACK_BUFFER, nullptr); |
| 2460 DoTexImageArguments new_args = args; |
| 2461 new_args.pixels = nullptr; |
| 2462 // pixels_size might be incorrect, but it's not used in this case. |
| 2463 DoTexImage(texture_state, state, framebuffer_state, function_name, |
| 2464 texture_ref, new_args); |
| 2465 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer->service_id()); |
| 2466 state->SetBoundBuffer(GL_PIXEL_UNPACK_BUFFER, buffer); |
| 2467 } |
| 2468 |
| 2428 bool TextureManager::ValidateTexSubImage(ContextState* state, | 2469 bool TextureManager::ValidateTexSubImage(ContextState* state, |
| 2429 const char* function_name, | 2470 const char* function_name, |
| 2430 const DoTexSubImageArguments& args, | 2471 const DoTexSubImageArguments& args, |
| 2431 TextureRef** texture_ref) { | 2472 TextureRef** texture_ref) { |
| 2432 ErrorState* error_state = state->GetErrorState(); | 2473 ErrorState* error_state = state->GetErrorState(); |
| 2433 const Validators* validators = feature_info_->validators(); | 2474 const Validators* validators = feature_info_->validators(); |
| 2434 | 2475 |
| 2435 if ((args.command_type == DoTexSubImageArguments::kTexSubImage2D && | 2476 if ((args.command_type == DoTexSubImageArguments::kTexSubImage2D && |
| 2436 !validators->texture_target.IsValid(args.target)) || | 2477 !validators->texture_target.IsValid(args.target)) || |
| 2437 (args.command_type == DoTexSubImageArguments::kTexSubImage3D && | 2478 (args.command_type == DoTexSubImageArguments::kTexSubImage3D && |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2565 return; | 2606 return; |
| 2566 } | 2607 } |
| 2567 } | 2608 } |
| 2568 full_image = false; | 2609 full_image = false; |
| 2569 } else { | 2610 } else { |
| 2570 SetLevelCleared(texture_ref, args.target, args.level, true); | 2611 SetLevelCleared(texture_ref, args.target, args.level, true); |
| 2571 full_image = true; | 2612 full_image = true; |
| 2572 } | 2613 } |
| 2573 | 2614 |
| 2574 Buffer* buffer = state->bound_pixel_unpack_buffer.get(); | 2615 Buffer* buffer = state->bound_pixel_unpack_buffer.get(); |
| 2616 |
| 2617 if (texture_state->unpack_overlapping_rows_separately_unpack_buffer && |
| 2618 buffer) { |
| 2619 ContextState::Dimension dimension = |
| 2620 (args.command_type == DoTexSubImageArguments::kTexSubImage3D) |
| 2621 ? ContextState::k3D |
| 2622 : ContextState::k2D; |
| 2623 const PixelStoreParams unpack_params(state->GetUnpackParams(dimension)); |
| 2624 if (unpack_params.row_length != 0 && |
| 2625 unpack_params.row_length < args.width) { |
| 2626 // The rows overlap in unpack memory. Upload the texture row by row to |
| 2627 // work around driver bug. |
| 2628 DoTexSubImageRowByRowWorkaround(texture_state, state, args, |
| 2629 unpack_params); |
| 2630 return; |
| 2631 } |
| 2632 } |
| 2633 |
| 2575 if (texture_state->unpack_alignment_workaround_with_unpack_buffer && buffer) { | 2634 if (texture_state->unpack_alignment_workaround_with_unpack_buffer && buffer) { |
| 2576 uint32_t buffer_size = static_cast<uint32_t>(buffer->size()); | 2635 uint32_t buffer_size = static_cast<uint32_t>(buffer->size()); |
| 2577 if (buffer_size - args.pixels_size - ToGLuint(args.pixels) < args.padding) { | 2636 if (buffer_size - args.pixels_size - ToGLuint(args.pixels) < args.padding) { |
| 2578 DoTexSubImageWithAlignmentWorkaround(texture_state, state, args); | 2637 DoTexSubImageWithAlignmentWorkaround(texture_state, state, args); |
| 2579 return; | 2638 return; |
| 2580 } | 2639 } |
| 2581 } | 2640 } |
| 2582 | 2641 |
| 2583 if (full_image && !texture_state->texsubimage_faster_than_teximage && | 2642 if (full_image && !texture_state->texsubimage_faster_than_teximage && |
| 2584 !texture->IsImmutable() && !texture->HasImages()) { | 2643 !texture->IsImmutable() && !texture->HasImages()) { |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2712 args.format, args.type, | 2771 args.format, args.type, |
| 2713 params, | 2772 params, |
| 2714 &size, | 2773 &size, |
| 2715 nullptr, nullptr, nullptr, nullptr); | 2774 nullptr, nullptr, nullptr, nullptr); |
| 2716 offset += size; | 2775 offset += size; |
| 2717 } | 2776 } |
| 2718 } | 2777 } |
| 2719 DCHECK_EQ(ToGLuint(args.pixels) + args.pixels_size, offset); | 2778 DCHECK_EQ(ToGLuint(args.pixels) + args.pixels_size, offset); |
| 2720 } | 2779 } |
| 2721 | 2780 |
| 2781 void TextureManager::DoTexSubImageRowByRowWorkaround( |
| 2782 DecoderTextureState* texture_state, |
| 2783 ContextState* state, |
| 2784 const DoTexSubImageArguments& args, |
| 2785 const PixelStoreParams& unpack_params) { |
| 2786 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
| 2787 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
| 2788 DCHECK_EQ(0, state->unpack_skip_pixels); |
| 2789 DCHECK_EQ(0, state->unpack_skip_rows); |
| 2790 DCHECK_EQ(0, state->unpack_skip_images); |
| 2791 |
| 2792 GLenum format = AdjustTexFormat(args.format); |
| 2793 |
| 2794 GLsizei row_bytes = unpack_params.row_length * |
| 2795 GLES2Util::ComputeImageGroupSize(format, args.type); |
| 2796 GLsizei alignment_diff = row_bytes % unpack_params.alignment; |
| 2797 if (alignment_diff != 0) { |
| 2798 row_bytes += unpack_params.alignment - alignment_diff; |
| 2799 } |
| 2800 DCHECK_EQ(0, row_bytes % unpack_params.alignment); |
| 2801 if (args.command_type == DoTexSubImageArguments::kTexSubImage3D) { |
| 2802 GLsizei image_height = args.height; |
| 2803 if (unpack_params.image_height != 0) { |
| 2804 image_height = unpack_params.image_height; |
| 2805 } |
| 2806 GLsizei image_bytes = row_bytes * image_height; |
| 2807 for (GLsizei image = 0; image < args.depth; ++image) { |
| 2808 GLsizei image_byte_offset = image * image_bytes; |
| 2809 for (GLsizei row = 0; row < args.height; ++row) { |
| 2810 GLsizei byte_offset = image_byte_offset + row * row_bytes; |
| 2811 const GLubyte* row_pixels = |
| 2812 reinterpret_cast<const GLubyte*>(args.pixels) + byte_offset; |
| 2813 glTexSubImage3D(args.target, args.level, args.xoffset, |
| 2814 row + args.yoffset, image + args.zoffset, args.width, 1, |
| 2815 1, format, args.type, row_pixels); |
| 2816 } |
| 2817 } |
| 2818 } else { |
| 2819 for (GLsizei row = 0; row < args.height; ++row) { |
| 2820 GLsizei byte_offset = row * row_bytes; |
| 2821 const GLubyte* row_pixels = |
| 2822 reinterpret_cast<const GLubyte*>(args.pixels) + byte_offset; |
| 2823 glTexSubImage2D(args.target, args.level, args.xoffset, row + args.yoffset, |
| 2824 args.width, 1, format, args.type, row_pixels); |
| 2825 } |
| 2826 } |
| 2827 |
| 2828 // Restore unpack state |
| 2829 glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_params.alignment); |
| 2830 glPixelStorei(GL_UNPACK_ROW_LENGTH, unpack_params.row_length); |
| 2831 } |
| 2832 |
| 2722 GLenum TextureManager::AdjustTexInternalFormat(GLenum format) const { | 2833 GLenum TextureManager::AdjustTexInternalFormat(GLenum format) const { |
| 2723 if (feature_info_->gl_version_info().is_desktop_core_profile) { | 2834 if (feature_info_->gl_version_info().is_desktop_core_profile) { |
| 2724 const Texture::CompatibilitySwizzle* swizzle = | 2835 const Texture::CompatibilitySwizzle* swizzle = |
| 2725 GetCompatibilitySwizzle(format); | 2836 GetCompatibilitySwizzle(format); |
| 2726 if (swizzle) | 2837 if (swizzle) |
| 2727 return swizzle->dest_format; | 2838 return swizzle->dest_format; |
| 2728 } | 2839 } |
| 2729 return format; | 2840 return format; |
| 2730 } | 2841 } |
| 2731 | 2842 |
| (...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3198 uint32_t TextureManager::GetServiceIdGeneration() const { | 3309 uint32_t TextureManager::GetServiceIdGeneration() const { |
| 3199 return current_service_id_generation_; | 3310 return current_service_id_generation_; |
| 3200 } | 3311 } |
| 3201 | 3312 |
| 3202 void TextureManager::IncrementServiceIdGeneration() { | 3313 void TextureManager::IncrementServiceIdGeneration() { |
| 3203 current_service_id_generation_++; | 3314 current_service_id_generation_++; |
| 3204 } | 3315 } |
| 3205 | 3316 |
| 3206 } // namespace gles2 | 3317 } // namespace gles2 |
| 3207 } // namespace gpu | 3318 } // namespace gpu |
| OLD | NEW |