Chromium Code Reviews| 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 // Reserve memory for the texture and set its attributes so it can be | |
| 2410 // filled with TexSubImage. | |
|
oetuaho-nv
2016/05/09 14:22:30
This part here could maybe be refactored into a co
| |
| 2411 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); | |
| 2412 state->SetBoundBuffer(GL_PIXEL_UNPACK_BUFFER, nullptr); | |
| 2413 DoTexImageArguments new_args = args; | |
| 2414 new_args.pixels = nullptr; | |
| 2415 // pixels_size might be incorrect, but it's not used in this case. | |
| 2416 DoTexImage(texture_state, state, framebuffer_state, function_name, | |
| 2417 texture_ref, new_args); | |
| 2418 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer->service_id()); | |
| 2419 state->SetBoundBuffer(GL_PIXEL_UNPACK_BUFFER, buffer); | |
| 2420 | |
| 2421 DoTexSubImageArguments sub_args = { | |
| 2422 args.target, args.level, 0, 0, 0, args.width, args.height, args.depth, | |
| 2423 args.format, args.type, args.pixels, args.pixels_size, args.padding, | |
| 2424 args.command_type == DoTexImageArguments::kTexImage3D | |
| 2425 ? DoTexSubImageArguments::kTexSubImage3D | |
| 2426 : DoTexSubImageArguments::kTexSubImage2D}; | |
| 2427 DoTexSubImageRowByRowWorkaround(texture_state, state, sub_args, | |
| 2428 unpack_params); | |
| 2429 | |
| 2430 SetLevelCleared(texture_ref, args.target, args.level, true); | |
| 2431 return; | |
| 2432 } | |
| 2433 } | |
| 2434 | |
| 2397 if (texture_state->unpack_alignment_workaround_with_unpack_buffer && buffer) { | 2435 if (texture_state->unpack_alignment_workaround_with_unpack_buffer && buffer) { |
| 2398 uint32_t buffer_size = static_cast<uint32_t>(buffer->size()); | 2436 uint32_t buffer_size = static_cast<uint32_t>(buffer->size()); |
| 2399 if (buffer_size - args.pixels_size - ToGLuint(args.pixels) < args.padding) { | 2437 if (buffer_size - args.pixels_size - ToGLuint(args.pixels) < args.padding) { |
| 2400 // In ValidateTexImage(), we already made sure buffer size is no less | 2438 // In ValidateTexImage(), we already made sure buffer size is no less |
| 2401 // than offset + pixels_size. | 2439 // than offset + pixels_size. |
| 2402 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); | 2440 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); |
| 2403 state->SetBoundBuffer(GL_PIXEL_UNPACK_BUFFER, nullptr); | 2441 state->SetBoundBuffer(GL_PIXEL_UNPACK_BUFFER, nullptr); |
| 2404 DoTexImageArguments new_args = args; | 2442 DoTexImageArguments new_args = args; |
| 2405 new_args.pixels = nullptr; | 2443 new_args.pixels = nullptr; |
| 2406 // pixels_size might be incorrect, but it's not used in this case. | 2444 // pixels_size might be incorrect, but it's not used in this case. |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2565 return; | 2603 return; |
| 2566 } | 2604 } |
| 2567 } | 2605 } |
| 2568 full_image = false; | 2606 full_image = false; |
| 2569 } else { | 2607 } else { |
| 2570 SetLevelCleared(texture_ref, args.target, args.level, true); | 2608 SetLevelCleared(texture_ref, args.target, args.level, true); |
| 2571 full_image = true; | 2609 full_image = true; |
| 2572 } | 2610 } |
| 2573 | 2611 |
| 2574 Buffer* buffer = state->bound_pixel_unpack_buffer.get(); | 2612 Buffer* buffer = state->bound_pixel_unpack_buffer.get(); |
| 2613 | |
| 2614 if (texture_state->unpack_overlapping_rows_separately_unpack_buffer && | |
| 2615 buffer) { | |
| 2616 ContextState::Dimension dimension = | |
| 2617 (args.command_type == DoTexSubImageArguments::kTexSubImage3D) | |
| 2618 ? ContextState::k3D | |
| 2619 : ContextState::k2D; | |
| 2620 const PixelStoreParams unpack_params(state->GetUnpackParams(dimension)); | |
| 2621 if (unpack_params.row_length != 0 && | |
| 2622 unpack_params.row_length < args.width) { | |
| 2623 // The rows overlap in unpack memory. Upload the texture row by row to | |
| 2624 // work around driver bug. | |
| 2625 DoTexSubImageRowByRowWorkaround(texture_state, state, args, | |
| 2626 unpack_params); | |
| 2627 return; | |
| 2628 } | |
| 2629 } | |
| 2630 | |
| 2575 if (texture_state->unpack_alignment_workaround_with_unpack_buffer && buffer) { | 2631 if (texture_state->unpack_alignment_workaround_with_unpack_buffer && buffer) { |
| 2576 uint32_t buffer_size = static_cast<uint32_t>(buffer->size()); | 2632 uint32_t buffer_size = static_cast<uint32_t>(buffer->size()); |
| 2577 if (buffer_size - args.pixels_size - ToGLuint(args.pixels) < args.padding) { | 2633 if (buffer_size - args.pixels_size - ToGLuint(args.pixels) < args.padding) { |
| 2578 DoTexSubImageWithAlignmentWorkaround(texture_state, state, args); | 2634 DoTexSubImageWithAlignmentWorkaround(texture_state, state, args); |
| 2579 return; | 2635 return; |
| 2580 } | 2636 } |
| 2581 } | 2637 } |
| 2582 | 2638 |
| 2583 if (full_image && !texture_state->texsubimage_faster_than_teximage && | 2639 if (full_image && !texture_state->texsubimage_faster_than_teximage && |
| 2584 !texture->IsImmutable() && !texture->HasImages()) { | 2640 !texture->IsImmutable() && !texture->HasImages()) { |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2712 args.format, args.type, | 2768 args.format, args.type, |
| 2713 params, | 2769 params, |
| 2714 &size, | 2770 &size, |
| 2715 nullptr, nullptr, nullptr, nullptr); | 2771 nullptr, nullptr, nullptr, nullptr); |
| 2716 offset += size; | 2772 offset += size; |
| 2717 } | 2773 } |
| 2718 } | 2774 } |
| 2719 DCHECK_EQ(ToGLuint(args.pixels) + args.pixels_size, offset); | 2775 DCHECK_EQ(ToGLuint(args.pixels) + args.pixels_size, offset); |
| 2720 } | 2776 } |
| 2721 | 2777 |
| 2778 void TextureManager::DoTexSubImageRowByRowWorkaround( | |
| 2779 DecoderTextureState* texture_state, | |
| 2780 ContextState* state, | |
| 2781 const DoTexSubImageArguments& args, | |
| 2782 const PixelStoreParams& unpack_params) { | |
| 2783 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | |
| 2784 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); | |
| 2785 DCHECK_EQ(0, state->unpack_skip_pixels); | |
| 2786 DCHECK_EQ(0, state->unpack_skip_rows); | |
| 2787 DCHECK_EQ(0, state->unpack_skip_images); | |
| 2788 | |
| 2789 GLenum format = AdjustTexFormat(args.format); | |
| 2790 | |
| 2791 GLsizei row_bytes = unpack_params.row_length * | |
| 2792 GLES2Util::ComputeImageGroupSize(format, args.type); | |
| 2793 GLsizei alignment_diff = row_bytes % unpack_params.alignment; | |
| 2794 if (alignment_diff != 0) { | |
| 2795 row_bytes += unpack_params.alignment - alignment_diff; | |
| 2796 } | |
| 2797 DCHECK_EQ(0, row_bytes % unpack_params.alignment); | |
| 2798 if (args.command_type == DoTexSubImageArguments::kTexSubImage3D) { | |
| 2799 GLsizei image_height = args.height; | |
| 2800 if (unpack_params.image_height != 0) { | |
| 2801 image_height = unpack_params.image_height; | |
| 2802 } | |
| 2803 GLsizei image_bytes = row_bytes * image_height; | |
| 2804 for (GLsizei image = 0; image < args.depth; ++image) { | |
| 2805 GLsizei image_byte_offset = image * image_bytes; | |
| 2806 for (GLsizei row = 0; row < args.height; ++row) { | |
| 2807 GLsizei byte_offset = image_byte_offset + row * row_bytes; | |
| 2808 const GLubyte* row_pixels = | |
| 2809 reinterpret_cast<const GLubyte*>(args.pixels) + byte_offset; | |
| 2810 glTexSubImage3D(args.target, args.level, args.xoffset, | |
| 2811 row + args.yoffset, image + args.zoffset, args.width, 1, | |
| 2812 1, format, args.type, row_pixels); | |
| 2813 } | |
| 2814 } | |
| 2815 } else { | |
| 2816 for (GLsizei row = 0; row < args.height; ++row) { | |
| 2817 GLsizei byte_offset = row * row_bytes; | |
| 2818 const GLubyte* row_pixels = | |
| 2819 reinterpret_cast<const GLubyte*>(args.pixels) + byte_offset; | |
| 2820 glTexSubImage2D(args.target, args.level, args.xoffset, row + args.yoffset, | |
| 2821 args.width, 1, format, args.type, row_pixels); | |
| 2822 } | |
| 2823 } | |
| 2824 | |
| 2825 // Restore unpack state | |
| 2826 glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_params.alignment); | |
| 2827 glPixelStorei(GL_UNPACK_ROW_LENGTH, unpack_params.row_length); | |
| 2828 } | |
| 2829 | |
| 2722 GLenum TextureManager::AdjustTexInternalFormat(GLenum format) const { | 2830 GLenum TextureManager::AdjustTexInternalFormat(GLenum format) const { |
| 2723 if (feature_info_->gl_version_info().is_desktop_core_profile) { | 2831 if (feature_info_->gl_version_info().is_desktop_core_profile) { |
| 2724 const Texture::CompatibilitySwizzle* swizzle = | 2832 const Texture::CompatibilitySwizzle* swizzle = |
| 2725 GetCompatibilitySwizzle(format); | 2833 GetCompatibilitySwizzle(format); |
| 2726 if (swizzle) | 2834 if (swizzle) |
| 2727 return swizzle->dest_format; | 2835 return swizzle->dest_format; |
| 2728 } | 2836 } |
| 2729 return format; | 2837 return format; |
| 2730 } | 2838 } |
| 2731 | 2839 |
| (...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3198 uint32_t TextureManager::GetServiceIdGeneration() const { | 3306 uint32_t TextureManager::GetServiceIdGeneration() const { |
| 3199 return current_service_id_generation_; | 3307 return current_service_id_generation_; |
| 3200 } | 3308 } |
| 3201 | 3309 |
| 3202 void TextureManager::IncrementServiceIdGeneration() { | 3310 void TextureManager::IncrementServiceIdGeneration() { |
| 3203 current_service_id_generation_++; | 3311 current_service_id_generation_++; |
| 3204 } | 3312 } |
| 3205 | 3313 |
| 3206 } // namespace gles2 | 3314 } // namespace gles2 |
| 3207 } // namespace gpu | 3315 } // namespace gpu |
| OLD | NEW |