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/gles2_cmd_decoder.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
6 | 6 |
7 #include <limits.h> | 7 #include <limits.h> |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 #include <stdio.h> | 10 #include <stdio.h> |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
57 #include "gpu/command_buffer/service/program_manager.h" | 57 #include "gpu/command_buffer/service/program_manager.h" |
58 #include "gpu/command_buffer/service/query_manager.h" | 58 #include "gpu/command_buffer/service/query_manager.h" |
59 #include "gpu/command_buffer/service/renderbuffer_manager.h" | 59 #include "gpu/command_buffer/service/renderbuffer_manager.h" |
60 #include "gpu/command_buffer/service/sampler_manager.h" | 60 #include "gpu/command_buffer/service/sampler_manager.h" |
61 #include "gpu/command_buffer/service/shader_manager.h" | 61 #include "gpu/command_buffer/service/shader_manager.h" |
62 #include "gpu/command_buffer/service/shader_translator.h" | 62 #include "gpu/command_buffer/service/shader_translator.h" |
63 #include "gpu/command_buffer/service/texture_manager.h" | 63 #include "gpu/command_buffer/service/texture_manager.h" |
64 #include "gpu/command_buffer/service/transform_feedback_manager.h" | 64 #include "gpu/command_buffer/service/transform_feedback_manager.h" |
65 #include "gpu/command_buffer/service/vertex_array_manager.h" | 65 #include "gpu/command_buffer/service/vertex_array_manager.h" |
66 #include "gpu/command_buffer/service/vertex_attrib_manager.h" | 66 #include "gpu/command_buffer/service/vertex_attrib_manager.h" |
67 #include "third_party/angle/src/image_util/loadimage.h" | |
67 #include "third_party/smhasher/src/City.h" | 68 #include "third_party/smhasher/src/City.h" |
68 #include "ui/gfx/buffer_types.h" | 69 #include "ui/gfx/buffer_types.h" |
69 #include "ui/gfx/geometry/point.h" | 70 #include "ui/gfx/geometry/point.h" |
70 #include "ui/gfx/geometry/rect.h" | 71 #include "ui/gfx/geometry/rect.h" |
71 #include "ui/gfx/geometry/rect_conversions.h" | 72 #include "ui/gfx/geometry/rect_conversions.h" |
72 #include "ui/gfx/geometry/size.h" | 73 #include "ui/gfx/geometry/size.h" |
73 #include "ui/gfx/gpu_memory_buffer.h" | 74 #include "ui/gfx/gpu_memory_buffer.h" |
74 #include "ui/gfx/overlay_transform.h" | 75 #include "ui/gfx/overlay_transform.h" |
75 #include "ui/gfx/transform.h" | 76 #include "ui/gfx/transform.h" |
76 #include "ui/gl/ca_renderer_layer_params.h" | 77 #include "ui/gl/ca_renderer_layer_params.h" |
(...skipping 11398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11475 {8, 5}, | 11476 {8, 5}, |
11476 {8, 6}, | 11477 {8, 6}, |
11477 {8, 8}, | 11478 {8, 8}, |
11478 {10, 5}, | 11479 {10, 5}, |
11479 {10, 6}, | 11480 {10, 6}, |
11480 {10, 8}, | 11481 {10, 8}, |
11481 {10, 10}, | 11482 {10, 10}, |
11482 {12, 10}, | 11483 {12, 10}, |
11483 {12, 12}}; | 11484 {12, 12}}; |
11484 | 11485 |
11486 bool CheckETCFormatSupport(const FeatureInfo& featureInfo) { | |
11487 const gl::GLVersionInfo& versionInfo = featureInfo.gl_version_info(); | |
11488 return versionInfo.IsAtLeastGL(4, 3) || versionInfo.IsAtLeastGLES(3, 0) || | |
11489 featureInfo.feature_flags().arb_es3_compatibility; | |
11490 } | |
11491 | |
11492 using CompressedFormatSupportCheck = bool (*)(const FeatureInfo&); | |
11493 using CompressedFormatDecompressionFunction = void (*)(size_t width, | |
11494 size_t height, | |
11495 size_t depth, | |
11496 const uint8_t* input, | |
11497 size_t inputRowPitch, | |
11498 size_t inputDepthPitch, | |
11499 uint8_t* output, | |
11500 size_t outputRowPitch, | |
11501 size_t outputDepthPitch); | |
11502 | |
11503 struct CompressedFormatInfo { | |
11504 GLenum format; | |
11505 uint32_t block_size; | |
11506 uint32_t bytes_per_block; | |
11507 CompressedFormatSupportCheck support_check; | |
11508 CompressedFormatDecompressionFunction decompression_function; | |
11509 GLenum decompressed_internal_format; | |
11510 GLenum decompressed_format; | |
11511 GLenum decompressed_type; | |
11512 }; | |
11513 | |
11514 const CompressedFormatInfo kCompressedFormatInfoArray[] = { | |
11515 { | |
11516 GL_COMPRESSED_R11_EAC, 4, 8, CheckETCFormatSupport, | |
11517 angle::LoadEACR11ToR8, GL_R8, GL_RED, GL_UNSIGNED_BYTE, | |
11518 }, | |
11519 { | |
11520 GL_COMPRESSED_SIGNED_R11_EAC, 4, 8, CheckETCFormatSupport, | |
11521 angle::LoadEACR11SToR8, GL_R8_SNORM, GL_RED, GL_BYTE, | |
11522 }, | |
11523 { | |
11524 GL_COMPRESSED_RG11_EAC, 4, 16, CheckETCFormatSupport, | |
11525 angle::LoadEACRG11ToRG8, GL_RG8, GL_RG, GL_UNSIGNED_BYTE, | |
11526 }, | |
11527 { | |
11528 GL_COMPRESSED_SIGNED_RG11_EAC, 4, 16, CheckETCFormatSupport, | |
11529 angle::LoadEACRG11SToRG8, GL_RG8_SNORM, GL_RG, GL_BYTE, | |
11530 }, | |
11531 { | |
11532 GL_COMPRESSED_RGB8_ETC2, 4, 8, CheckETCFormatSupport, | |
11533 angle::LoadETC2RGB8ToRGBA8, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, | |
11534 }, | |
11535 { | |
11536 GL_COMPRESSED_SRGB8_ETC2, 4, 8, CheckETCFormatSupport, | |
11537 angle::LoadETC2SRGB8ToRGBA8, GL_SRGB8_ALPHA8, GL_SRGB_ALPHA, | |
11538 GL_UNSIGNED_BYTE, | |
11539 }, | |
11540 { | |
11541 GL_COMPRESSED_RGBA8_ETC2_EAC, 4, 16, CheckETCFormatSupport, | |
11542 angle::LoadETC2RGBA8ToRGBA8, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, | |
11543 }, | |
11544 { | |
11545 GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, 4, 8, | |
11546 CheckETCFormatSupport, angle::LoadETC2RGB8A1ToRGBA8, GL_RGBA8, GL_RGBA, | |
11547 GL_UNSIGNED_BYTE, | |
11548 }, | |
11549 { | |
11550 GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, 4, 16, CheckETCFormatSupport, | |
11551 angle::LoadETC2SRGBA8ToSRGBA8, GL_SRGB8_ALPHA8, GL_SRGB_ALPHA, | |
11552 GL_UNSIGNED_BYTE, | |
11553 }, | |
11554 { | |
11555 GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, 4, 8, | |
11556 CheckETCFormatSupport, angle::LoadETC2SRGB8A1ToRGBA8, GL_SRGB8_ALPHA8, | |
11557 GL_SRGB_ALPHA, GL_UNSIGNED_BYTE, | |
11558 }, | |
11559 }; | |
11560 | |
11561 const CompressedFormatInfo* GetCompressedFormatInfo(GLenum format) { | |
11562 for (size_t i = 0; i < arraysize(kCompressedFormatInfoArray); i++) { | |
11563 if (kCompressedFormatInfoArray[i].format == format) { | |
11564 return &kCompressedFormatInfoArray[i]; | |
11565 } | |
11566 } | |
11567 return nullptr; | |
11568 } | |
11569 | |
11570 uint32_t GetCompressedFormatRowPitch(const CompressedFormatInfo& info, | |
11571 uint32_t width) { | |
11572 uint32_t num_blocks_wide = (width + info.block_size - 1) / info.block_size; | |
11573 return num_blocks_wide * info.bytes_per_block; | |
11574 } | |
11575 | |
11576 uint32_t GetCompressedFormatDepthPitch(const CompressedFormatInfo& info, | |
11577 uint32_t width, | |
11578 uint32_t height) { | |
11579 uint32_t num_blocks_high = ((height + info.block_size - 1) / info.block_size); | |
piman
2016/07/08 19:30:39
nit: no need for the outer set of parens.
Geoff Lang
2016/07/11 19:19:07
Done.
| |
11580 return num_blocks_high * GetCompressedFormatRowPitch(info, width); | |
11581 } | |
11582 | |
11583 std::unique_ptr<uint8_t[]> DecompressTextureData( | |
11584 const ContextState& state, | |
11585 const CompressedFormatInfo& info, | |
11586 uint32_t width, | |
11587 uint32_t height, | |
11588 uint32_t depth, | |
11589 GLsizei image_size, | |
11590 const void* data) { | |
11591 uint32_t output_pixel_size = GLES2Util::ComputeImageGroupSize( | |
11592 info.decompressed_format, info.decompressed_type); | |
11593 std::unique_ptr<uint8_t[]> decompressed_data( | |
11594 new uint8_t[output_pixel_size * width * height]); | |
11595 | |
11596 // If a PBO is bound, map it to decompress the data. | |
11597 const void* input_data = data; | |
11598 if (state.bound_pixel_unpack_buffer) { | |
11599 input_data = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, | |
piman
2016/07/08 19:30:39
The buffer might already be mapped, in which case
Geoff Lang
2016/07/11 19:19:08
I updated the validation code to cover these cases
| |
11600 reinterpret_cast<GLintptr>(data), image_size, | |
11601 GL_MAP_READ_BIT); | |
11602 } | |
11603 | |
11604 info.decompression_function( | |
11605 width, height, depth, reinterpret_cast<const uint8_t*>(input_data), | |
piman
2016/07/08 19:30:39
nit: static_cast instead of reinterpret_cast
Geoff Lang
2016/07/11 19:19:08
Done.
| |
11606 GetCompressedFormatRowPitch(info, width), | |
11607 GetCompressedFormatDepthPitch(info, width, height), | |
11608 decompressed_data.get(), output_pixel_size * width, | |
11609 output_pixel_size * width * height); | |
11610 | |
11611 if (state.bound_pixel_unpack_buffer) { | |
11612 glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); | |
piman
2016/07/08 19:30:39
glUnmapBuffer is allowed to fail, corrupting the d
Geoff Lang
2016/07/11 19:19:08
Done, I had to modify the command buffer generatio
| |
11613 } | |
11614 | |
11615 return decompressed_data; | |
11616 } | |
11617 | |
11618 void PushDecompressedTextureUnpackState() { | |
11619 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | |
11620 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); | |
11621 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0); | |
11622 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); | |
Zhenyao Mo
2016/07/08 22:40:29
nit: the above three lines can be put inside the c
Geoff Lang
2016/07/11 19:19:08
Done, moved all the logic into ContextState.
| |
11623 } | |
11624 | |
11625 void PopDecompressedTextureUnpackState(const ContextState& state) { | |
11626 state.RestoreUnpackState(); | |
11627 } | |
11628 | |
11485 bool IsValidDXTSize(GLint level, GLsizei size) { | 11629 bool IsValidDXTSize(GLint level, GLsizei size) { |
11486 // TODO(zmo): Linux NVIDIA driver does allow size of 1 and 2 on level 0. | 11630 // TODO(zmo): Linux NVIDIA driver does allow size of 1 and 2 on level 0. |
11487 // However, the WebGL conformance test and blink side code forbid it. | 11631 // However, the WebGL conformance test and blink side code forbid it. |
11488 // For now, let's be on the cautious side. If all drivers behaves the same | 11632 // For now, let's be on the cautious side. If all drivers behaves the same |
11489 // as Linux NVIDIA, then we can remove this limitation. | 11633 // as Linux NVIDIA, then we can remove this limitation. |
11490 return (level && size == 1) || | 11634 return (level && size == 1) || |
11491 (level && size == 2) || | 11635 (level && size == 2) || |
11492 !(size % kS3TCBlockWidth); | 11636 !(size % kS3TCBlockWidth); |
11493 } | 11637 } |
11494 | 11638 |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11898 LOCAL_SET_GL_ERROR( | 12042 LOCAL_SET_GL_ERROR( |
11899 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory"); | 12043 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory"); |
11900 return error::kNoError; | 12044 return error::kNoError; |
11901 } | 12045 } |
11902 | 12046 |
11903 if (texture->IsAttachedToFramebuffer()) { | 12047 if (texture->IsAttachedToFramebuffer()) { |
11904 framebuffer_state_.clear_state_dirty = true; | 12048 framebuffer_state_.clear_state_dirty = true; |
11905 } | 12049 } |
11906 | 12050 |
11907 std::unique_ptr<int8_t[]> zero; | 12051 std::unique_ptr<int8_t[]> zero; |
11908 if (!data) { | 12052 if (!state_.bound_pixel_unpack_buffer && !data) { |
11909 zero.reset(new int8_t[image_size]); | 12053 zero.reset(new int8_t[image_size]); |
11910 memset(zero.get(), 0, image_size); | 12054 memset(zero.get(), 0, image_size); |
11911 data = zero.get(); | 12055 data = zero.get(); |
11912 } | 12056 } |
11913 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D"); | 12057 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D"); |
11914 glCompressedTexImage2D( | 12058 |
11915 target, level, internal_format, width, height, border, image_size, data); | 12059 const CompressedFormatInfo* format_info = |
12060 GetCompressedFormatInfo(internal_format); | |
12061 if (format_info != nullptr && !format_info->support_check(*feature_info_)) { | |
12062 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData( | |
12063 state_, *format_info, width, height, 1, image_size, data); | |
12064 PushDecompressedTextureUnpackState(); | |
12065 glTexImage2D(target, level, format_info->decompressed_internal_format, | |
12066 width, height, border, format_info->decompressed_format, | |
12067 format_info->decompressed_type, decompressed_data.get()); | |
12068 PopDecompressedTextureUnpackState(state_); | |
12069 } else { | |
12070 glCompressedTexImage2D(target, level, internal_format, width, height, | |
12071 border, image_size, data); | |
12072 } | |
11916 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D"); | 12073 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D"); |
11917 if (error == GL_NO_ERROR) { | 12074 if (error == GL_NO_ERROR) { |
11918 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, | 12075 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, |
11919 width, height, 1, border, 0, 0, | 12076 width, height, 1, border, 0, 0, |
11920 gfx::Rect(width, height)); | 12077 gfx::Rect(width, height)); |
11921 } | 12078 } |
11922 | 12079 |
11923 // This may be a slow command. Exit command processing to allow for | 12080 // This may be a slow command. Exit command processing to allow for |
11924 // context preemption and GPU watchdog checks. | 12081 // context preemption and GPU watchdog checks. |
11925 ExitCommandProcessingEarly(); | 12082 ExitCommandProcessingEarly(); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11970 LOCAL_SET_GL_ERROR( | 12127 LOCAL_SET_GL_ERROR( |
11971 GL_OUT_OF_MEMORY, "glCompressedTexImage3D", "out of memory"); | 12128 GL_OUT_OF_MEMORY, "glCompressedTexImage3D", "out of memory"); |
11972 return error::kNoError; | 12129 return error::kNoError; |
11973 } | 12130 } |
11974 | 12131 |
11975 if (texture->IsAttachedToFramebuffer()) { | 12132 if (texture->IsAttachedToFramebuffer()) { |
11976 framebuffer_state_.clear_state_dirty = true; | 12133 framebuffer_state_.clear_state_dirty = true; |
11977 } | 12134 } |
11978 | 12135 |
11979 std::unique_ptr<int8_t[]> zero; | 12136 std::unique_ptr<int8_t[]> zero; |
11980 if (!data) { | 12137 if (!state_.bound_pixel_unpack_buffer && !data) { |
11981 zero.reset(new int8_t[image_size]); | 12138 zero.reset(new int8_t[image_size]); |
11982 memset(zero.get(), 0, image_size); | 12139 memset(zero.get(), 0, image_size); |
11983 data = zero.get(); | 12140 data = zero.get(); |
11984 } | 12141 } |
11985 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage3D"); | 12142 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage3D"); |
11986 glCompressedTexImage3D(target, level, internal_format, width, height, depth, | 12143 const CompressedFormatInfo* format_info = |
11987 border, image_size, data); | 12144 GetCompressedFormatInfo(internal_format); |
12145 if (format_info != nullptr && !format_info->support_check(*feature_info_)) { | |
12146 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData( | |
12147 state_, *format_info, width, height, depth, image_size, data); | |
12148 PushDecompressedTextureUnpackState(); | |
12149 glTexImage3D(target, level, format_info->decompressed_internal_format, | |
12150 width, height, depth, border, format_info->decompressed_format, | |
12151 format_info->decompressed_type, decompressed_data.get()); | |
12152 PopDecompressedTextureUnpackState(state_); | |
12153 } else { | |
12154 glCompressedTexImage3D(target, level, internal_format, width, height, depth, | |
12155 border, image_size, data); | |
12156 } | |
11988 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage3D"); | 12157 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage3D"); |
11989 if (error == GL_NO_ERROR) { | 12158 if (error == GL_NO_ERROR) { |
11990 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, | 12159 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, |
11991 width, height, depth, border, 0, 0, | 12160 width, height, depth, border, 0, 0, |
11992 gfx::Rect(width, height)); | 12161 gfx::Rect(width, height)); |
11993 } | 12162 } |
11994 | 12163 |
11995 // This may be a slow command. Exit command processing to allow for | 12164 // This may be a slow command. Exit command processing to allow for |
11996 // context preemption and GPU watchdog checks. | 12165 // context preemption and GPU watchdog checks. |
11997 ExitCommandProcessingEarly(); | 12166 ExitCommandProcessingEarly(); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12042 target, level, xoffset, yoffset, | 12211 target, level, xoffset, yoffset, |
12043 zoffset, width, height, depth, | 12212 zoffset, width, height, depth, |
12044 format, texture)) { | 12213 format, texture)) { |
12045 return; | 12214 return; |
12046 } | 12215 } |
12047 | 12216 |
12048 // Note: There is no need to deal with texture cleared tracking here | 12217 // Note: There is no need to deal with texture cleared tracking here |
12049 // because the validation above means you can only get here if the level | 12218 // because the validation above means you can only get here if the level |
12050 // is already a matching compressed format and in that case | 12219 // is already a matching compressed format and in that case |
12051 // CompressedTexImage3D already cleared the texture. | 12220 // CompressedTexImage3D already cleared the texture. |
12052 glCompressedTexSubImage3D( | 12221 |
12053 target, level, xoffset, yoffset, zoffset, width, height, depth, format, | 12222 const CompressedFormatInfo* format_info = |
12054 image_size, data); | 12223 GetCompressedFormatInfo(internal_format); |
12224 if (format_info != nullptr && !format_info->support_check(*feature_info_)) { | |
12225 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData( | |
12226 state_, *format_info, width, height, depth, image_size, data); | |
12227 PushDecompressedTextureUnpackState(); | |
12228 glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, | |
12229 depth, format_info->decompressed_format, | |
12230 format_info->decompressed_type, decompressed_data.get()); | |
12231 PopDecompressedTextureUnpackState(state_); | |
12232 } else { | |
12233 glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, | |
12234 height, depth, format, image_size, data); | |
12235 } | |
12055 | 12236 |
12056 // This may be a slow command. Exit command processing to allow for | 12237 // This may be a slow command. Exit command processing to allow for |
12057 // context preemption and GPU watchdog checks. | 12238 // context preemption and GPU watchdog checks. |
12058 ExitCommandProcessingEarly(); | 12239 ExitCommandProcessingEarly(); |
12059 } | 12240 } |
12060 | 12241 |
12061 error::Error GLES2DecoderImpl::HandleTexImage2D(uint32_t immediate_data_size, | 12242 error::Error GLES2DecoderImpl::HandleTexImage2D(uint32_t immediate_data_size, |
12062 const void* cmd_data) { | 12243 const void* cmd_data) { |
12063 const gles2::cmds::TexImage2D& c = | 12244 const gles2::cmds::TexImage2D& c = |
12064 *static_cast<const gles2::cmds::TexImage2D*>(cmd_data); | 12245 *static_cast<const gles2::cmds::TexImage2D*>(cmd_data); |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12293 // We can skip the clear if we're uploading the entire level. | 12474 // We can skip the clear if we're uploading the entire level. |
12294 if (xoffset == 0 && yoffset == 0 && | 12475 if (xoffset == 0 && yoffset == 0 && |
12295 width == level_width && height == level_height) { | 12476 width == level_width && height == level_height) { |
12296 texture_manager()->SetLevelCleared(texture_ref, target, level, true); | 12477 texture_manager()->SetLevelCleared(texture_ref, target, level, true); |
12297 } else { | 12478 } else { |
12298 texture_manager()->ClearTextureLevel(this, texture_ref, target, level); | 12479 texture_manager()->ClearTextureLevel(this, texture_ref, target, level); |
12299 } | 12480 } |
12300 DCHECK(texture->IsLevelCleared(target, level)); | 12481 DCHECK(texture->IsLevelCleared(target, level)); |
12301 } | 12482 } |
12302 | 12483 |
12303 glCompressedTexSubImage2D( | 12484 const CompressedFormatInfo* format_info = |
12304 target, level, xoffset, yoffset, width, height, format, image_size, data); | 12485 GetCompressedFormatInfo(internal_format); |
12486 if (format_info != nullptr && !format_info->support_check(*feature_info_)) { | |
12487 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData( | |
12488 state_, *format_info, width, height, 1, image_size, data); | |
12489 PushDecompressedTextureUnpackState(); | |
12490 glTexSubImage2D(target, level, xoffset, yoffset, width, height, | |
12491 format_info->decompressed_format, | |
12492 format_info->decompressed_type, decompressed_data.get()); | |
12493 PopDecompressedTextureUnpackState(state_); | |
12494 } else { | |
12495 glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, | |
12496 format, image_size, data); | |
12497 } | |
12305 | 12498 |
12306 // This may be a slow command. Exit command processing to allow for | 12499 // This may be a slow command. Exit command processing to allow for |
12307 // context preemption and GPU watchdog checks. | 12500 // context preemption and GPU watchdog checks. |
12308 ExitCommandProcessingEarly(); | 12501 ExitCommandProcessingEarly(); |
12309 } | 12502 } |
12310 | 12503 |
12311 static void Clip( | 12504 static void Clip( |
12312 GLint start, GLint range, GLint sourceRange, | 12505 GLint start, GLint range, GLint sourceRange, |
12313 GLint* out_start, GLint* out_range) { | 12506 GLint* out_start, GLint* out_range) { |
12314 DCHECK(out_start); | 12507 DCHECK(out_start); |
(...skipping 2776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
15091 if (target == GL_TEXTURE_3D) | 15284 if (target == GL_TEXTURE_3D) |
15092 level_depth = std::max(1, level_depth >> 1); | 15285 level_depth = std::max(1, level_depth >> 1); |
15093 } | 15286 } |
15094 if (!estimated_size.IsValid() || | 15287 if (!estimated_size.IsValid() || |
15095 !EnsureGPUMemoryAvailable(estimated_size.ValueOrDefault(0))) { | 15288 !EnsureGPUMemoryAvailable(estimated_size.ValueOrDefault(0))) { |
15096 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "out of memory"); | 15289 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "out of memory"); |
15097 return; | 15290 return; |
15098 } | 15291 } |
15099 } | 15292 } |
15100 | 15293 |
15294 GLenum compatibility_internal_format = internal_format; | |
15295 const CompressedFormatInfo* format_info = | |
15296 GetCompressedFormatInfo(internal_format); | |
15297 if (format_info != nullptr && !format_info->support_check(*feature_info_)) { | |
15298 compatibility_internal_format = format_info->decompressed_internal_format; | |
15299 } | |
15300 | |
15101 // TODO(zmo): We might need to emulate TexStorage using TexImage or | 15301 // TODO(zmo): We might need to emulate TexStorage using TexImage or |
15102 // CompressedTexImage on Mac OSX where we expose ES3 APIs when the underlying | 15302 // CompressedTexImage on Mac OSX where we expose ES3 APIs when the underlying |
15103 // driver is lower than 4.2 and ARB_texture_storage extension doesn't exist. | 15303 // driver is lower than 4.2 and ARB_texture_storage extension doesn't exist. |
15104 if (dimension == ContextState::k2D) { | 15304 if (dimension == ContextState::k2D) { |
15105 glTexStorage2DEXT(target, levels, internal_format, width, height); | 15305 glTexStorage2DEXT(target, levels, compatibility_internal_format, width, |
15306 height); | |
15106 } else { | 15307 } else { |
15107 glTexStorage3D(target, levels, internal_format, width, height, depth); | 15308 glTexStorage3D(target, levels, compatibility_internal_format, width, height, |
15309 depth); | |
15108 } | 15310 } |
15109 | 15311 |
15110 { | 15312 { |
15111 GLsizei level_width = width; | 15313 GLsizei level_width = width; |
15112 GLsizei level_height = height; | 15314 GLsizei level_height = height; |
15113 GLsizei level_depth = depth; | 15315 GLsizei level_depth = depth; |
15114 GLenum adjusted_format = | 15316 GLenum adjusted_format = |
15115 feature_info_->IsES3Enabled() ? internal_format : format; | 15317 feature_info_->IsES3Enabled() ? internal_format : format; |
15116 for (int ii = 0; ii < levels; ++ii) { | 15318 for (int ii = 0; ii < levels; ++ii) { |
15117 if (target == GL_TEXTURE_CUBE_MAP) { | 15319 if (target == GL_TEXTURE_CUBE_MAP) { |
(...skipping 1988 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
17106 } | 17308 } |
17107 | 17309 |
17108 // Include the auto-generated part of this file. We split this because it means | 17310 // Include the auto-generated part of this file. We split this because it means |
17109 // we can easily edit the non-auto generated parts right here in this file | 17311 // we can easily edit the non-auto generated parts right here in this file |
17110 // instead of having to edit some template or the code generator. | 17312 // instead of having to edit some template or the code generator. |
17111 #include "base/macros.h" | 17313 #include "base/macros.h" |
17112 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 17314 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
17113 | 17315 |
17114 } // namespace gles2 | 17316 } // namespace gles2 |
17115 } // namespace gpu | 17317 } // namespace gpu |
OLD | NEW |