Chromium Code Reviews| Index: gpu/command_buffer/service/texture_manager.cc |
| diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc |
| index 0ab416a494992fb4217fb1430d632b767d676489..2a5ab34eaaa402eed62a7f5ca946ab4498f64233 100644 |
| --- a/gpu/command_buffer/service/texture_manager.cc |
| +++ b/gpu/command_buffer/service/texture_manager.cc |
| @@ -2545,6 +2545,39 @@ void TextureManager::ValidateAndDoTexImage( |
| } |
| } |
| + if (args.command_type == DoTexImageArguments::kTexImage3D && |
| + texture_state->unpack_image_height_workaround_with_unpack_buffer && |
| + buffer) { |
| + ContextState::Dimension dimension = ContextState::k3D; |
| + const PixelStoreParams unpack_params(state->GetUnpackParams(dimension)); |
| + if (unpack_params.image_height != 0 && |
| + unpack_params.image_height != args.height) { |
| + ReserveTexImageToBeFilled(texture_state, state, framebuffer_state, |
| + function_name, texture_ref, args); |
| + |
| + DoTexSubImageArguments sub_args = { |
| + args.target, |
| + args.level, |
| + 0, |
| + 0, |
| + 0, |
| + args.width, |
| + args.height, |
| + args.depth, |
| + args.format, |
| + args.type, |
| + args.pixels, |
| + args.pixels_size, |
| + args.padding, |
| + DoTexSubImageArguments::kTexSubImage3D}; |
| + DoTexSubImageLayerByLayerWorkaround(texture_state, state, sub_args, |
| + unpack_params); |
| + |
| + SetLevelCleared(texture_ref, args.target, args.level, true); |
| + return; |
| + } |
| + } |
| + |
| if (texture_state->unpack_alignment_workaround_with_unpack_buffer && buffer) { |
| uint32_t buffer_size = static_cast<uint32_t>(buffer->size()); |
| if (buffer_size - args.pixels_size - ToGLuint(args.pixels) < args.padding) { |
| @@ -2753,6 +2786,19 @@ void TextureManager::ValidateAndDoTexSubImage( |
| } |
| } |
| + if (args.command_type == DoTexSubImageArguments::kTexSubImage3D && |
| + texture_state->unpack_image_height_workaround_with_unpack_buffer && |
| + buffer) { |
| + ContextState::Dimension dimension = ContextState::k3D; |
| + const PixelStoreParams unpack_params(state->GetUnpackParams(dimension)); |
| + if (unpack_params.image_height != 0 && |
| + unpack_params.image_height != args.height) { |
| + DoTexSubImageLayerByLayerWorkaround(texture_state, state, args, |
| + unpack_params); |
| + return; |
| + } |
| + } |
| + |
| if (texture_state->unpack_alignment_workaround_with_unpack_buffer && buffer) { |
| uint32_t buffer_size = static_cast<uint32_t>(buffer->size()); |
| if (buffer_size - args.pixels_size - ToGLuint(args.pixels) < args.padding) { |
| @@ -2962,6 +3008,55 @@ void TextureManager::DoTexSubImageRowByRowWorkaround( |
| glPixelStorei(GL_UNPACK_ROW_LENGTH, unpack_params.row_length); |
| } |
| +void TextureManager::DoTexSubImageLayerByLayerWorkaround( |
| + DecoderTextureState* texture_state, |
| + ContextState* state, |
| + const DoTexSubImageArguments& args, |
| + const PixelStoreParams& unpack_params) { |
| + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0); |
| + |
| + GLenum format = AdjustTexFormat(feature_info_.get(), args.format); |
| + |
| + GLsizei row_length = |
| + unpack_params.row_length ? unpack_params.row_length : args.width; |
| + GLsizei row_bytes = |
| + row_length * GLES2Util::ComputeImageGroupSize(format, args.type); |
| + GLsizei alignment_diff = row_bytes % unpack_params.alignment; |
| + if (alignment_diff != 0) { |
| + row_bytes += unpack_params.alignment - alignment_diff; |
| + } |
| + DCHECK_EQ(0, row_bytes % unpack_params.alignment); |
| + |
| + // process the texture layer by layer |
| + GLsizei image_height = unpack_params.image_height; |
| + GLsizei image_bytes = row_bytes * image_height; |
| + for (GLsizei image = 0; image < args.depth - 1; ++image) { |
| + GLsizei image_byte_offset = image * image_bytes; |
| + const GLubyte* image_pixels = |
|
Zhenyao Mo
2016/10/14 21:29:09
You can move "const GLubyte* image_pixels = cast<c
jiajia.qin
2016/10/17 05:38:57
Done.
|
| + reinterpret_cast<const GLubyte*>(args.pixels) + image_byte_offset; |
| + glTexSubImage3D(args.target, args.level, args.xoffset, args.yoffset, |
| + image + args.zoffset, args.width, args.height, 1, format, |
| + args.type, image_pixels); |
| + } |
| + |
| + // Process the last image row by row |
| + GLsizei last_image_offset = (args.depth - 1) * image_bytes; |
| + const GLubyte* last_image_pixels = |
| + reinterpret_cast<const GLubyte*>(args.pixels) + last_image_offset; |
| + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
| + for (GLsizei row = 0; row < args.height; ++row) { |
| + GLsizei byte_offset = row * row_bytes; |
| + const GLubyte* row_pixels = last_image_pixels + byte_offset; |
|
Zhenyao Mo
2016/10/14 21:29:09
You can move "const GLubyte* row_pixels = image_pi
jiajia.qin
2016/10/17 05:38:57
Done.
|
| + glTexSubImage3D(args.target, args.level, args.xoffset, row + args.yoffset, |
| + args.depth - 1 + args.zoffset, args.width, 1, 1, format, |
| + args.type, row_pixels); |
| + } |
| + glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_params.alignment); |
| + |
| + // Restore unpack state |
| + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, unpack_params.image_height); |
| +} |
| + |
| // static |
| GLenum TextureManager::AdjustTexInternalFormat( |
| const gles2::FeatureInfo* feature_info, |