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/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 852 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 929 GLint level, | 930 GLint level, |
| 930 GLenum internal_format, | 931 GLenum internal_format, |
| 931 GLsizei width, | 932 GLsizei width, |
| 932 GLsizei height, | 933 GLsizei height, |
| 933 GLsizei depth, | 934 GLsizei depth, |
| 934 GLint border, | 935 GLint border, |
| 935 GLsizei image_size, | 936 GLsizei image_size, |
| 936 const void* data); | 937 const void* data); |
| 937 | 938 |
| 938 // Wrapper for CompressedTexSubImage2D. | 939 // Wrapper for CompressedTexSubImage2D. |
| 939 void DoCompressedTexSubImage2D( | 940 error::Error DoCompressedTexSubImage2D(GLenum target, |
| 940 GLenum target, | 941 GLint level, |
| 941 GLint level, | 942 GLint xoffset, |
| 942 GLint xoffset, | 943 GLint yoffset, |
| 943 GLint yoffset, | 944 GLsizei width, |
| 944 GLsizei width, | 945 GLsizei height, |
| 945 GLsizei height, | 946 GLenum format, |
| 946 GLenum format, | 947 GLsizei imageSize, |
| 947 GLsizei imageSize, | 948 const void* data); |
| 948 const void* data); | |
| 949 | 949 |
| 950 // Wrapper for CompressedTexSubImage3D. | 950 // Wrapper for CompressedTexSubImage3D. |
| 951 void DoCompressedTexSubImage3D( | 951 error::Error DoCompressedTexSubImage3D(GLenum target, |
| 952 GLenum target, | 952 GLint level, |
| 953 GLint level, | 953 GLint xoffset, |
| 954 GLint xoffset, | 954 GLint yoffset, |
| 955 GLint yoffset, | 955 GLint zoffset, |
| 956 GLint zoffset, | 956 GLsizei width, |
| 957 GLsizei width, | 957 GLsizei height, |
| 958 GLsizei height, | 958 GLsizei depth, |
| 959 GLsizei depth, | 959 GLenum format, |
| 960 GLenum format, | 960 GLsizei image_size, |
| 961 GLsizei image_size, | 961 const void* data); |
| 962 const void* data); | |
| 963 | 962 |
| 964 // Validate if |format| is valid for CopyTex{Sub}Image functions. | 963 // Validate if |format| is valid for CopyTex{Sub}Image functions. |
| 965 // If not, generate a GL error and return false. | 964 // If not, generate a GL error and return false. |
| 966 bool ValidateCopyTexFormat(const char* func_name, GLenum internal_format, | 965 bool ValidateCopyTexFormat(const char* func_name, GLenum internal_format, |
| 967 GLenum read_format, GLenum read_type); | 966 GLenum read_format, GLenum read_type); |
| 968 | 967 |
| 969 // Wrapper for CopyTexImage2D. | 968 // Wrapper for CopyTexImage2D. |
| 970 void DoCopyTexImage2D( | 969 void DoCopyTexImage2D( |
| 971 GLenum target, | 970 GLenum target, |
| 972 GLint level, | 971 GLint level, |
| (...skipping 920 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1893 void MarkContextLost(error::ContextLostReason reason) override; | 1892 void MarkContextLost(error::ContextLostReason reason) override; |
| 1894 bool CheckResetStatus(); | 1893 bool CheckResetStatus(); |
| 1895 | 1894 |
| 1896 bool GetCompressedTexSizeInBytes( | 1895 bool GetCompressedTexSizeInBytes( |
| 1897 const char* function_name, GLsizei width, GLsizei height, GLsizei depth, | 1896 const char* function_name, GLsizei width, GLsizei height, GLsizei depth, |
| 1898 GLenum format, GLsizei* size_in_bytes); | 1897 GLenum format, GLsizei* size_in_bytes); |
| 1899 | 1898 |
| 1900 bool ValidateCompressedTexDimensions( | 1899 bool ValidateCompressedTexDimensions( |
| 1901 const char* function_name, GLenum target, GLint level, | 1900 const char* function_name, GLenum target, GLint level, |
| 1902 GLsizei width, GLsizei height, GLsizei depth, GLenum format); | 1901 GLsizei width, GLsizei height, GLsizei depth, GLenum format); |
| 1903 bool ValidateCompressedTexFuncData( | 1902 bool ValidateCompressedTexFuncData(const char* function_name, |
| 1904 const char* function_name, GLsizei width, GLsizei height, GLsizei depth, | 1903 GLsizei width, |
| 1905 GLenum format, GLsizei size); | 1904 GLsizei height, |
| 1905 GLsizei depth, | |
| 1906 GLenum format, | |
| 1907 GLsizei size, | |
| 1908 const GLvoid* data); | |
| 1906 bool ValidateCompressedTexSubDimensions( | 1909 bool ValidateCompressedTexSubDimensions( |
| 1907 const char* function_name, | 1910 const char* function_name, |
| 1908 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, | 1911 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, |
| 1909 GLsizei width, GLsizei height, GLsizei depth, GLenum format, | 1912 GLsizei width, GLsizei height, GLsizei depth, GLenum format, |
| 1910 Texture* texture); | 1913 Texture* texture); |
| 1911 bool ValidateCopyTextureCHROMIUMTextures(const char* function_name, | 1914 bool ValidateCopyTextureCHROMIUMTextures(const char* function_name, |
| 1912 TextureRef* source_texture_ref, | 1915 TextureRef* source_texture_ref, |
| 1913 TextureRef* dest_texture_ref); | 1916 TextureRef* dest_texture_ref); |
| 1914 bool ValidateCopyTextureCHROMIUMInternalFormats( | 1917 bool ValidateCopyTextureCHROMIUMInternalFormats( |
| 1915 const char* function_name, | 1918 const char* function_name, |
| (...skipping 9559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11475 {8, 5}, | 11478 {8, 5}, |
| 11476 {8, 6}, | 11479 {8, 6}, |
| 11477 {8, 8}, | 11480 {8, 8}, |
| 11478 {10, 5}, | 11481 {10, 5}, |
| 11479 {10, 6}, | 11482 {10, 6}, |
| 11480 {10, 8}, | 11483 {10, 8}, |
| 11481 {10, 10}, | 11484 {10, 10}, |
| 11482 {12, 10}, | 11485 {12, 10}, |
| 11483 {12, 12}}; | 11486 {12, 12}}; |
| 11484 | 11487 |
| 11488 bool CheckETCFormatSupport(const FeatureInfo& featureInfo) { | |
| 11489 const gl::GLVersionInfo& versionInfo = featureInfo.gl_version_info(); | |
| 11490 return versionInfo.IsAtLeastGL(4, 3) || versionInfo.IsAtLeastGLES(3, 0) || | |
| 11491 featureInfo.feature_flags().arb_es3_compatibility; | |
| 11492 } | |
| 11493 | |
| 11494 using CompressedFormatSupportCheck = bool (*)(const FeatureInfo&); | |
| 11495 using CompressedFormatDecompressionFunction = void (*)(size_t width, | |
| 11496 size_t height, | |
| 11497 size_t depth, | |
| 11498 const uint8_t* input, | |
| 11499 size_t inputRowPitch, | |
| 11500 size_t inputDepthPitch, | |
| 11501 uint8_t* output, | |
| 11502 size_t outputRowPitch, | |
| 11503 size_t outputDepthPitch); | |
| 11504 | |
| 11505 struct CompressedFormatInfo { | |
| 11506 GLenum format; | |
| 11507 uint32_t block_size; | |
| 11508 uint32_t bytes_per_block; | |
| 11509 CompressedFormatSupportCheck support_check; | |
| 11510 CompressedFormatDecompressionFunction decompression_function; | |
| 11511 GLenum decompressed_internal_format; | |
| 11512 GLenum decompressed_format; | |
| 11513 GLenum decompressed_type; | |
| 11514 }; | |
| 11515 | |
| 11516 const CompressedFormatInfo kCompressedFormatInfoArray[] = { | |
| 11517 { | |
| 11518 GL_COMPRESSED_R11_EAC, 4, 8, CheckETCFormatSupport, | |
| 11519 angle::LoadEACR11ToR8, GL_R8, GL_RED, GL_UNSIGNED_BYTE, | |
| 11520 }, | |
| 11521 { | |
| 11522 GL_COMPRESSED_SIGNED_R11_EAC, 4, 8, CheckETCFormatSupport, | |
| 11523 angle::LoadEACR11SToR8, GL_R8_SNORM, GL_RED, GL_BYTE, | |
| 11524 }, | |
| 11525 { | |
| 11526 GL_COMPRESSED_RG11_EAC, 4, 16, CheckETCFormatSupport, | |
| 11527 angle::LoadEACRG11ToRG8, GL_RG8, GL_RG, GL_UNSIGNED_BYTE, | |
| 11528 }, | |
| 11529 { | |
| 11530 GL_COMPRESSED_SIGNED_RG11_EAC, 4, 16, CheckETCFormatSupport, | |
| 11531 angle::LoadEACRG11SToRG8, GL_RG8_SNORM, GL_RG, GL_BYTE, | |
| 11532 }, | |
| 11533 { | |
| 11534 GL_COMPRESSED_RGB8_ETC2, 4, 8, CheckETCFormatSupport, | |
| 11535 angle::LoadETC2RGB8ToRGBA8, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, | |
| 11536 }, | |
| 11537 { | |
| 11538 GL_COMPRESSED_SRGB8_ETC2, 4, 8, CheckETCFormatSupport, | |
| 11539 angle::LoadETC2SRGB8ToRGBA8, GL_SRGB8_ALPHA8, GL_SRGB_ALPHA, | |
| 11540 GL_UNSIGNED_BYTE, | |
| 11541 }, | |
| 11542 { | |
| 11543 GL_COMPRESSED_RGBA8_ETC2_EAC, 4, 16, CheckETCFormatSupport, | |
| 11544 angle::LoadETC2RGBA8ToRGBA8, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, | |
| 11545 }, | |
| 11546 { | |
| 11547 GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, 4, 8, | |
| 11548 CheckETCFormatSupport, angle::LoadETC2RGB8A1ToRGBA8, GL_RGBA8, GL_RGBA, | |
| 11549 GL_UNSIGNED_BYTE, | |
| 11550 }, | |
| 11551 { | |
| 11552 GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, 4, 16, CheckETCFormatSupport, | |
| 11553 angle::LoadETC2SRGBA8ToSRGBA8, GL_SRGB8_ALPHA8, GL_SRGB_ALPHA, | |
| 11554 GL_UNSIGNED_BYTE, | |
| 11555 }, | |
| 11556 { | |
| 11557 GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, 4, 8, | |
| 11558 CheckETCFormatSupport, angle::LoadETC2SRGB8A1ToRGBA8, GL_SRGB8_ALPHA8, | |
| 11559 GL_SRGB_ALPHA, GL_UNSIGNED_BYTE, | |
| 11560 }, | |
| 11561 }; | |
| 11562 | |
| 11563 const CompressedFormatInfo* GetCompressedFormatInfo(GLenum format) { | |
| 11564 for (size_t i = 0; i < arraysize(kCompressedFormatInfoArray); i++) { | |
| 11565 if (kCompressedFormatInfoArray[i].format == format) { | |
| 11566 return &kCompressedFormatInfoArray[i]; | |
| 11567 } | |
| 11568 } | |
| 11569 return nullptr; | |
| 11570 } | |
| 11571 | |
| 11572 uint32_t GetCompressedFormatRowPitch(const CompressedFormatInfo& info, | |
| 11573 uint32_t width) { | |
| 11574 uint32_t num_blocks_wide = (width + info.block_size - 1) / info.block_size; | |
| 11575 return num_blocks_wide * info.bytes_per_block; | |
| 11576 } | |
| 11577 | |
| 11578 uint32_t GetCompressedFormatDepthPitch(const CompressedFormatInfo& info, | |
| 11579 uint32_t width, | |
| 11580 uint32_t height) { | |
| 11581 uint32_t num_blocks_high = (height + info.block_size - 1) / info.block_size; | |
| 11582 return num_blocks_high * GetCompressedFormatRowPitch(info, width); | |
| 11583 } | |
| 11584 | |
| 11585 std::unique_ptr<uint8_t[]> DecompressTextureData( | |
| 11586 const ContextState& state, | |
| 11587 const CompressedFormatInfo& info, | |
| 11588 uint32_t width, | |
| 11589 uint32_t height, | |
| 11590 uint32_t depth, | |
| 11591 GLsizei image_size, | |
| 11592 const void* data) { | |
| 11593 uint32_t output_pixel_size = GLES2Util::ComputeImageGroupSize( | |
| 11594 info.decompressed_format, info.decompressed_type); | |
| 11595 std::unique_ptr<uint8_t[]> decompressed_data( | |
| 11596 new uint8_t[output_pixel_size * width * height]); | |
| 11597 | |
| 11598 // If a PBO is bound, map it to decompress the data. | |
| 11599 const void* input_data = data; | |
| 11600 if (state.bound_pixel_unpack_buffer) { | |
| 11601 input_data = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, | |
| 11602 reinterpret_cast<GLintptr>(data), image_size, | |
| 11603 GL_MAP_READ_BIT); | |
| 11604 } | |
| 11605 | |
| 11606 info.decompression_function( | |
| 11607 width, height, depth, static_cast<const uint8_t*>(input_data), | |
| 11608 GetCompressedFormatRowPitch(info, width), | |
| 11609 GetCompressedFormatDepthPitch(info, width, height), | |
| 11610 decompressed_data.get(), output_pixel_size * width, | |
| 11611 output_pixel_size * width * height); | |
| 11612 | |
| 11613 if (state.bound_pixel_unpack_buffer) { | |
| 11614 if (glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER) != GL_TRUE) { | |
| 11615 LOG(ERROR) << "glUnmapBuffer unexpectedly returned GL_FALSE"; | |
| 11616 return nullptr; | |
| 11617 } | |
| 11618 } | |
| 11619 | |
| 11620 return decompressed_data; | |
| 11621 } | |
| 11622 | |
| 11485 bool IsValidDXTSize(GLint level, GLsizei size) { | 11623 bool IsValidDXTSize(GLint level, GLsizei size) { |
| 11486 // TODO(zmo): Linux NVIDIA driver does allow size of 1 and 2 on level 0. | 11624 // 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. | 11625 // 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 | 11626 // 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. | 11627 // as Linux NVIDIA, then we can remove this limitation. |
| 11490 return (level && size == 1) || | 11628 return (level && size == 1) || |
| 11491 (level && size == 2) || | 11629 (level && size == 2) || |
| 11492 !(size % kS3TCBlockWidth); | 11630 !(size % kS3TCBlockWidth); |
| 11493 } | 11631 } |
| 11494 | 11632 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11616 | 11754 |
| 11617 if (!bytes_required.IsValid()) { | 11755 if (!bytes_required.IsValid()) { |
| 11618 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "invalid size"); | 11756 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "invalid size"); |
| 11619 return false; | 11757 return false; |
| 11620 } | 11758 } |
| 11621 | 11759 |
| 11622 *size_in_bytes = bytes_required.ValueOrDefault(0); | 11760 *size_in_bytes = bytes_required.ValueOrDefault(0); |
| 11623 return true; | 11761 return true; |
| 11624 } | 11762 } |
| 11625 | 11763 |
| 11626 bool GLES2DecoderImpl::ValidateCompressedTexFuncData( | 11764 bool GLES2DecoderImpl::ValidateCompressedTexFuncData(const char* function_name, |
| 11627 const char* function_name, GLsizei width, GLsizei height, GLsizei depth, | 11765 GLsizei width, |
| 11628 GLenum format, GLsizei size) { | 11766 GLsizei height, |
| 11767 GLsizei depth, | |
| 11768 GLenum format, | |
| 11769 GLsizei size, | |
| 11770 const GLvoid* data) { | |
| 11629 GLsizei bytes_required = 0; | 11771 GLsizei bytes_required = 0; |
| 11630 if (!GetCompressedTexSizeInBytes( | 11772 if (!GetCompressedTexSizeInBytes( |
| 11631 function_name, width, height, depth, format, &bytes_required)) { | 11773 function_name, width, height, depth, format, &bytes_required)) { |
| 11632 return false; | 11774 return false; |
| 11633 } | 11775 } |
| 11634 | 11776 |
| 11635 if (size != bytes_required) { | 11777 if (size != bytes_required) { |
| 11636 LOCAL_SET_GL_ERROR( | 11778 LOCAL_SET_GL_ERROR( |
| 11637 GL_INVALID_VALUE, function_name, "size is not correct for dimensions"); | 11779 GL_INVALID_VALUE, function_name, "size is not correct for dimensions"); |
| 11638 return false; | 11780 return false; |
| 11639 } | 11781 } |
| 11640 | 11782 |
| 11783 if (state_.bound_pixel_unpack_buffer.get()) { | |
| 11784 if (state_.bound_pixel_unpack_buffer->GetMappedRange() != nullptr) { | |
| 11785 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, | |
| 11786 "pixel unpack buffer is mapped"); | |
| 11787 return false; | |
| 11788 } | |
| 11789 | |
| 11790 base::CheckedNumeric<GLintptr> pbo_bytes_required( | |
| 11791 reinterpret_cast<GLintptr>(data)); | |
| 11792 pbo_bytes_required += bytes_required; | |
| 11793 if (!pbo_bytes_required.IsValid() || | |
| 11794 pbo_bytes_required.ValueOrDie() > | |
| 11795 state_.bound_pixel_unpack_buffer->size()) { | |
| 11796 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, | |
| 11797 "pixel unpack buffer is not large enough"); | |
| 11798 return false; | |
| 11799 } | |
| 11800 } | |
| 11801 | |
| 11641 return true; | 11802 return true; |
| 11642 } | 11803 } |
| 11643 | 11804 |
| 11644 bool GLES2DecoderImpl::ValidateCompressedTexDimensions( | 11805 bool GLES2DecoderImpl::ValidateCompressedTexDimensions( |
| 11645 const char* function_name, GLenum target, GLint level, | 11806 const char* function_name, GLenum target, GLint level, |
| 11646 GLsizei width, GLsizei height, GLsizei depth, GLenum format) { | 11807 GLsizei width, GLsizei height, GLsizei depth, GLenum format) { |
| 11647 switch (format) { | 11808 switch (format) { |
| 11648 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: | 11809 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: |
| 11649 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: | 11810 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: |
| 11650 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: | 11811 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11882 } | 12043 } |
| 11883 Texture* texture = texture_ref->texture(); | 12044 Texture* texture = texture_ref->texture(); |
| 11884 if (texture->IsImmutable()) { | 12045 if (texture->IsImmutable()) { |
| 11885 LOCAL_SET_GL_ERROR( | 12046 LOCAL_SET_GL_ERROR( |
| 11886 GL_INVALID_OPERATION, | 12047 GL_INVALID_OPERATION, |
| 11887 "glCompressedTexImage2D", "texture is immutable"); | 12048 "glCompressedTexImage2D", "texture is immutable"); |
| 11888 return error::kNoError; | 12049 return error::kNoError; |
| 11889 } | 12050 } |
| 11890 if (!ValidateCompressedTexDimensions("glCompressedTexImage2D", target, level, | 12051 if (!ValidateCompressedTexDimensions("glCompressedTexImage2D", target, level, |
| 11891 width, height, 1, internal_format) || | 12052 width, height, 1, internal_format) || |
| 11892 !ValidateCompressedTexFuncData("glCompressedTexImage2D", width, height, | 12053 !ValidateCompressedTexFuncData("glCompressedTexImage2D", width, height, 1, |
| 11893 1, internal_format, image_size)) { | 12054 internal_format, image_size, data)) { |
| 11894 return error::kNoError; | 12055 return error::kNoError; |
| 11895 } | 12056 } |
| 11896 | 12057 |
| 11897 if (!EnsureGPUMemoryAvailable(image_size)) { | 12058 if (!EnsureGPUMemoryAvailable(image_size)) { |
| 11898 LOCAL_SET_GL_ERROR( | 12059 LOCAL_SET_GL_ERROR( |
| 11899 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory"); | 12060 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory"); |
| 11900 return error::kNoError; | 12061 return error::kNoError; |
| 11901 } | 12062 } |
| 11902 | 12063 |
| 11903 if (texture->IsAttachedToFramebuffer()) { | 12064 if (texture->IsAttachedToFramebuffer()) { |
| 11904 framebuffer_state_.clear_state_dirty = true; | 12065 framebuffer_state_.clear_state_dirty = true; |
| 11905 } | 12066 } |
| 11906 | 12067 |
| 11907 std::unique_ptr<int8_t[]> zero; | 12068 std::unique_ptr<int8_t[]> zero; |
| 11908 if (!data) { | 12069 if (!state_.bound_pixel_unpack_buffer && !data) { |
| 11909 zero.reset(new int8_t[image_size]); | 12070 zero.reset(new int8_t[image_size]); |
| 11910 memset(zero.get(), 0, image_size); | 12071 memset(zero.get(), 0, image_size); |
| 11911 data = zero.get(); | 12072 data = zero.get(); |
| 11912 } | 12073 } |
| 11913 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D"); | 12074 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D"); |
| 11914 glCompressedTexImage2D( | 12075 |
| 11915 target, level, internal_format, width, height, border, image_size, data); | 12076 const CompressedFormatInfo* format_info = |
| 12077 GetCompressedFormatInfo(internal_format); | |
| 12078 if (format_info != nullptr && !format_info->support_check(*feature_info_)) { | |
| 12079 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData( | |
| 12080 state_, *format_info, width, height, 1, image_size, data); | |
| 12081 if (!decompressed_data) { | |
| 12082 MarkContextLost(error::kGuilty); | |
| 12083 group_->LoseContexts(error::kInnocent); | |
| 12084 return error::kLostContext; | |
|
piman
2016/07/11 19:38:45
You don't really need to return kLostContext here,
Geoff Lang
2016/07/11 20:08:36
Done.
| |
| 12085 } | |
| 12086 state_.PushTextureDecompressionUnpackState(); | |
| 12087 glTexImage2D(target, level, format_info->decompressed_internal_format, | |
| 12088 width, height, border, format_info->decompressed_format, | |
| 12089 format_info->decompressed_type, decompressed_data.get()); | |
| 12090 state_.RestoreUnpackState(); | |
| 12091 } else { | |
| 12092 glCompressedTexImage2D(target, level, internal_format, width, height, | |
| 12093 border, image_size, data); | |
| 12094 } | |
| 11916 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D"); | 12095 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D"); |
| 11917 if (error == GL_NO_ERROR) { | 12096 if (error == GL_NO_ERROR) { |
| 11918 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, | 12097 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, |
| 11919 width, height, 1, border, 0, 0, | 12098 width, height, 1, border, 0, 0, |
| 11920 gfx::Rect(width, height)); | 12099 gfx::Rect(width, height)); |
| 11921 } | 12100 } |
| 11922 | 12101 |
| 11923 // This may be a slow command. Exit command processing to allow for | 12102 // This may be a slow command. Exit command processing to allow for |
| 11924 // context preemption and GPU watchdog checks. | 12103 // context preemption and GPU watchdog checks. |
| 11925 ExitCommandProcessingEarly(); | 12104 ExitCommandProcessingEarly(); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 11955 if (texture->IsImmutable()) { | 12134 if (texture->IsImmutable()) { |
| 11956 LOCAL_SET_GL_ERROR( | 12135 LOCAL_SET_GL_ERROR( |
| 11957 GL_INVALID_OPERATION, | 12136 GL_INVALID_OPERATION, |
| 11958 "glCompressedTexImage3D", "texture is immutable"); | 12137 "glCompressedTexImage3D", "texture is immutable"); |
| 11959 return error::kNoError; | 12138 return error::kNoError; |
| 11960 } | 12139 } |
| 11961 | 12140 |
| 11962 if (!ValidateCompressedTexDimensions("glCompressedTexImage3D", target, level, | 12141 if (!ValidateCompressedTexDimensions("glCompressedTexImage3D", target, level, |
| 11963 width, height, depth, internal_format) || | 12142 width, height, depth, internal_format) || |
| 11964 !ValidateCompressedTexFuncData("glCompressedTexImage3D", width, height, | 12143 !ValidateCompressedTexFuncData("glCompressedTexImage3D", width, height, |
| 11965 depth, internal_format, image_size)) { | 12144 depth, internal_format, image_size, |
| 12145 data)) { | |
| 11966 return error::kNoError; | 12146 return error::kNoError; |
| 11967 } | 12147 } |
| 11968 | 12148 |
| 11969 if (!EnsureGPUMemoryAvailable(image_size)) { | 12149 if (!EnsureGPUMemoryAvailable(image_size)) { |
| 11970 LOCAL_SET_GL_ERROR( | 12150 LOCAL_SET_GL_ERROR( |
| 11971 GL_OUT_OF_MEMORY, "glCompressedTexImage3D", "out of memory"); | 12151 GL_OUT_OF_MEMORY, "glCompressedTexImage3D", "out of memory"); |
| 11972 return error::kNoError; | 12152 return error::kNoError; |
| 11973 } | 12153 } |
| 11974 | 12154 |
| 11975 if (texture->IsAttachedToFramebuffer()) { | 12155 if (texture->IsAttachedToFramebuffer()) { |
| 11976 framebuffer_state_.clear_state_dirty = true; | 12156 framebuffer_state_.clear_state_dirty = true; |
| 11977 } | 12157 } |
| 11978 | 12158 |
| 11979 std::unique_ptr<int8_t[]> zero; | 12159 std::unique_ptr<int8_t[]> zero; |
| 11980 if (!data) { | 12160 if (!state_.bound_pixel_unpack_buffer && !data) { |
| 11981 zero.reset(new int8_t[image_size]); | 12161 zero.reset(new int8_t[image_size]); |
| 11982 memset(zero.get(), 0, image_size); | 12162 memset(zero.get(), 0, image_size); |
| 11983 data = zero.get(); | 12163 data = zero.get(); |
| 11984 } | 12164 } |
| 11985 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage3D"); | 12165 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage3D"); |
| 11986 glCompressedTexImage3D(target, level, internal_format, width, height, depth, | 12166 const CompressedFormatInfo* format_info = |
| 11987 border, image_size, data); | 12167 GetCompressedFormatInfo(internal_format); |
| 12168 if (format_info != nullptr && !format_info->support_check(*feature_info_)) { | |
| 12169 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData( | |
| 12170 state_, *format_info, width, height, depth, image_size, data); | |
| 12171 if (!decompressed_data) { | |
| 12172 MarkContextLost(error::kGuilty); | |
| 12173 group_->LoseContexts(error::kInnocent); | |
| 12174 return error::kLostContext; | |
| 12175 } | |
| 12176 state_.PushTextureDecompressionUnpackState(); | |
| 12177 glTexImage3D(target, level, format_info->decompressed_internal_format, | |
| 12178 width, height, depth, border, format_info->decompressed_format, | |
| 12179 format_info->decompressed_type, decompressed_data.get()); | |
| 12180 state_.RestoreUnpackState(); | |
| 12181 } else { | |
| 12182 glCompressedTexImage3D(target, level, internal_format, width, height, depth, | |
| 12183 border, image_size, data); | |
| 12184 } | |
| 11988 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage3D"); | 12185 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage3D"); |
| 11989 if (error == GL_NO_ERROR) { | 12186 if (error == GL_NO_ERROR) { |
| 11990 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, | 12187 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, |
| 11991 width, height, depth, border, 0, 0, | 12188 width, height, depth, border, 0, 0, |
| 11992 gfx::Rect(width, height)); | 12189 gfx::Rect(width, height)); |
| 11993 } | 12190 } |
| 11994 | 12191 |
| 11995 // This may be a slow command. Exit command processing to allow for | 12192 // This may be a slow command. Exit command processing to allow for |
| 11996 // context preemption and GPU watchdog checks. | 12193 // context preemption and GPU watchdog checks. |
| 11997 ExitCommandProcessingEarly(); | 12194 ExitCommandProcessingEarly(); |
| 11998 return error::kNoError; | 12195 return error::kNoError; |
| 11999 } | 12196 } |
| 12000 | 12197 |
| 12001 void GLES2DecoderImpl::DoCompressedTexSubImage3D( | 12198 error::Error GLES2DecoderImpl::DoCompressedTexSubImage3D(GLenum target, |
| 12002 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, | 12199 GLint level, |
| 12003 GLsizei width, GLsizei height, GLsizei depth, GLenum format, | 12200 GLint xoffset, |
| 12004 GLsizei image_size, const void* data) { | 12201 GLint yoffset, |
| 12202 GLint zoffset, | |
| 12203 GLsizei width, | |
| 12204 GLsizei height, | |
| 12205 GLsizei depth, | |
| 12206 GLenum format, | |
| 12207 GLsizei image_size, | |
| 12208 const void* data) { | |
| 12005 if (!texture_manager()->ValidForTarget(target, level, width, height, depth)) { | 12209 if (!texture_manager()->ValidForTarget(target, level, width, height, depth)) { |
| 12006 LOCAL_SET_GL_ERROR( | 12210 LOCAL_SET_GL_ERROR( |
| 12007 GL_INVALID_VALUE, | 12211 GL_INVALID_VALUE, |
| 12008 "glCompressedTexSubImage3D", "dimensions out of range"); | 12212 "glCompressedTexSubImage3D", "dimensions out of range"); |
| 12009 return; | 12213 return error::kNoError; |
| 12010 } | 12214 } |
| 12011 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( | 12215 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( |
| 12012 &state_, target); | 12216 &state_, target); |
| 12013 if (!texture_ref) { | 12217 if (!texture_ref) { |
| 12014 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCompressedTexSubImage3D", | 12218 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCompressedTexSubImage3D", |
| 12015 "unknown texture for target"); | 12219 "unknown texture for target"); |
| 12016 return; | 12220 return error::kNoError; |
| 12017 } | 12221 } |
| 12018 Texture* texture = texture_ref->texture(); | 12222 Texture* texture = texture_ref->texture(); |
| 12019 GLenum type = 0, internal_format = 0; | 12223 GLenum type = 0, internal_format = 0; |
| 12020 if (!texture->GetLevelType(target, level, &type, &internal_format)) { | 12224 if (!texture->GetLevelType(target, level, &type, &internal_format)) { |
| 12021 std::string msg = base::StringPrintf( | 12225 std::string msg = base::StringPrintf( |
| 12022 "level %d does not exist", level); | 12226 "level %d does not exist", level); |
| 12023 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCompressedTexSubImage3D", | 12227 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCompressedTexSubImage3D", |
| 12024 msg.c_str()); | 12228 msg.c_str()); |
| 12025 return; | 12229 return error::kNoError; |
| 12026 } | 12230 } |
| 12027 if (internal_format != format) { | 12231 if (internal_format != format) { |
| 12028 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCompressedTexSubImage3D", | 12232 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCompressedTexSubImage3D", |
| 12029 "format does not match internal format"); | 12233 "format does not match internal format"); |
| 12030 return; | 12234 return error::kNoError; |
| 12031 } | 12235 } |
| 12032 if (!texture->ValidForTexture(target, level, xoffset, yoffset, zoffset, | 12236 if (!texture->ValidForTexture(target, level, xoffset, yoffset, zoffset, |
| 12033 width, height, depth)) { | 12237 width, height, depth)) { |
| 12034 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedTexSubImage3D", | 12238 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedTexSubImage3D", |
| 12035 "bad dimensions"); | 12239 "bad dimensions"); |
| 12036 return; | 12240 return error::kNoError; |
| 12037 } | 12241 } |
| 12038 if (!ValidateCompressedTexFuncData("glCompressedTexSubImage3D", | 12242 if (!ValidateCompressedTexFuncData("glCompressedTexSubImage3D", width, height, |
| 12039 width, height, depth, format, | 12243 depth, format, image_size, data) || |
| 12040 image_size) || | 12244 !ValidateCompressedTexSubDimensions( |
| 12041 !ValidateCompressedTexSubDimensions("glCompressedTexSubImage3D", | 12245 "glCompressedTexSubImage3D", target, level, xoffset, yoffset, zoffset, |
| 12042 target, level, xoffset, yoffset, | 12246 width, height, depth, format, texture)) { |
| 12043 zoffset, width, height, depth, | 12247 return error::kNoError; |
| 12044 format, texture)) { | |
| 12045 return; | |
| 12046 } | 12248 } |
| 12047 | 12249 |
| 12048 // Note: There is no need to deal with texture cleared tracking here | 12250 // 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 | 12251 // because the validation above means you can only get here if the level |
| 12050 // is already a matching compressed format and in that case | 12252 // is already a matching compressed format and in that case |
| 12051 // CompressedTexImage3D already cleared the texture. | 12253 // CompressedTexImage3D already cleared the texture. |
| 12052 glCompressedTexSubImage3D( | 12254 |
| 12053 target, level, xoffset, yoffset, zoffset, width, height, depth, format, | 12255 const CompressedFormatInfo* format_info = |
| 12054 image_size, data); | 12256 GetCompressedFormatInfo(internal_format); |
| 12257 if (format_info != nullptr && !format_info->support_check(*feature_info_)) { | |
| 12258 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData( | |
| 12259 state_, *format_info, width, height, depth, image_size, data); | |
| 12260 if (!decompressed_data) { | |
| 12261 MarkContextLost(error::kGuilty); | |
| 12262 group_->LoseContexts(error::kInnocent); | |
| 12263 return error::kLostContext; | |
| 12264 } | |
| 12265 state_.PushTextureDecompressionUnpackState(); | |
| 12266 glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, | |
| 12267 depth, format_info->decompressed_format, | |
| 12268 format_info->decompressed_type, decompressed_data.get()); | |
| 12269 state_.RestoreUnpackState(); | |
| 12270 } else { | |
| 12271 glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, | |
| 12272 height, depth, format, image_size, data); | |
| 12273 } | |
| 12055 | 12274 |
| 12056 // This may be a slow command. Exit command processing to allow for | 12275 // This may be a slow command. Exit command processing to allow for |
| 12057 // context preemption and GPU watchdog checks. | 12276 // context preemption and GPU watchdog checks. |
| 12058 ExitCommandProcessingEarly(); | 12277 ExitCommandProcessingEarly(); |
| 12278 return error::kNoError; | |
| 12059 } | 12279 } |
| 12060 | 12280 |
| 12061 error::Error GLES2DecoderImpl::HandleTexImage2D(uint32_t immediate_data_size, | 12281 error::Error GLES2DecoderImpl::HandleTexImage2D(uint32_t immediate_data_size, |
| 12062 const void* cmd_data) { | 12282 const void* cmd_data) { |
| 12063 const gles2::cmds::TexImage2D& c = | 12283 const gles2::cmds::TexImage2D& c = |
| 12064 *static_cast<const gles2::cmds::TexImage2D*>(cmd_data); | 12284 *static_cast<const gles2::cmds::TexImage2D*>(cmd_data); |
| 12065 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D", | 12285 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D", |
| 12066 "width", c.width, "height", c.height); | 12286 "width", c.width, "height", c.height); |
| 12067 // Set as failed for now, but if it successed, this will be set to not failed. | 12287 // Set as failed for now, but if it successed, this will be set to not failed. |
| 12068 texture_state_.tex_image_failed = true; | 12288 texture_state_.tex_image_failed = true; |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 12227 TextureManager::DoTexImageArguments::kTexImage3D }; | 12447 TextureManager::DoTexImageArguments::kTexImage3D }; |
| 12228 texture_manager()->ValidateAndDoTexImage( | 12448 texture_manager()->ValidateAndDoTexImage( |
| 12229 &texture_state_, &state_, &framebuffer_state_, "glTexImage3D", args); | 12449 &texture_state_, &state_, &framebuffer_state_, "glTexImage3D", args); |
| 12230 | 12450 |
| 12231 // This may be a slow command. Exit command processing to allow for | 12451 // This may be a slow command. Exit command processing to allow for |
| 12232 // context preemption and GPU watchdog checks. | 12452 // context preemption and GPU watchdog checks. |
| 12233 ExitCommandProcessingEarly(); | 12453 ExitCommandProcessingEarly(); |
| 12234 return error::kNoError; | 12454 return error::kNoError; |
| 12235 } | 12455 } |
| 12236 | 12456 |
| 12237 void GLES2DecoderImpl::DoCompressedTexSubImage2D( | 12457 error::Error GLES2DecoderImpl::DoCompressedTexSubImage2D(GLenum target, |
| 12238 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, | 12458 GLint level, |
| 12239 GLsizei height, GLenum format, GLsizei image_size, const void * data) { | 12459 GLint xoffset, |
| 12460 GLint yoffset, | |
| 12461 GLsizei width, | |
| 12462 GLsizei height, | |
| 12463 GLenum format, | |
| 12464 GLsizei image_size, | |
| 12465 const void* data) { | |
| 12240 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( | 12466 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( |
| 12241 &state_, target); | 12467 &state_, target); |
| 12242 if (!texture_ref) { | 12468 if (!texture_ref) { |
| 12243 LOCAL_SET_GL_ERROR( | 12469 LOCAL_SET_GL_ERROR( |
| 12244 GL_INVALID_OPERATION, | 12470 GL_INVALID_OPERATION, |
| 12245 "glCompressedTexSubImage2D", "unknown texture for target"); | 12471 "glCompressedTexSubImage2D", "unknown texture for target"); |
| 12246 return; | 12472 return error::kNoError; |
| 12247 } | 12473 } |
| 12248 if (!texture_manager()->ValidForTarget(target, level, width, height, 1)) { | 12474 if (!texture_manager()->ValidForTarget(target, level, width, height, 1)) { |
| 12249 LOCAL_SET_GL_ERROR( | 12475 LOCAL_SET_GL_ERROR( |
| 12250 GL_INVALID_VALUE, | 12476 GL_INVALID_VALUE, |
| 12251 "glCompressedTexSubImage2D", "dimensions out of range"); | 12477 "glCompressedTexSubImage2D", "dimensions out of range"); |
| 12252 return; | 12478 return error::kNoError; |
| 12253 } | 12479 } |
| 12254 Texture* texture = texture_ref->texture(); | 12480 Texture* texture = texture_ref->texture(); |
| 12255 GLenum type = 0; | 12481 GLenum type = 0; |
| 12256 GLenum internal_format = 0; | 12482 GLenum internal_format = 0; |
| 12257 if (!texture->GetLevelType(target, level, &type, &internal_format)) { | 12483 if (!texture->GetLevelType(target, level, &type, &internal_format)) { |
| 12258 std::string msg = base::StringPrintf( | 12484 std::string msg = base::StringPrintf( |
| 12259 "level %d does not exist", level); | 12485 "level %d does not exist", level); |
| 12260 LOCAL_SET_GL_ERROR( | 12486 LOCAL_SET_GL_ERROR( |
| 12261 GL_INVALID_OPERATION, "glCompressedTexSubImage2D", msg.c_str()); | 12487 GL_INVALID_OPERATION, "glCompressedTexSubImage2D", msg.c_str()); |
| 12262 return; | 12488 return error::kNoError; |
| 12263 } | 12489 } |
| 12264 if (internal_format != format) { | 12490 if (internal_format != format) { |
| 12265 LOCAL_SET_GL_ERROR( | 12491 LOCAL_SET_GL_ERROR( |
| 12266 GL_INVALID_OPERATION, | 12492 GL_INVALID_OPERATION, |
| 12267 "glCompressedTexSubImage2D", "format does not match internal format."); | 12493 "glCompressedTexSubImage2D", "format does not match internal format."); |
| 12268 return; | 12494 return error::kNoError; |
| 12269 } | 12495 } |
| 12270 if (!texture->ValidForTexture(target, level, xoffset, yoffset, 0, width, | 12496 if (!texture->ValidForTexture(target, level, xoffset, yoffset, 0, width, |
| 12271 height, 1)) { | 12497 height, 1)) { |
| 12272 LOCAL_SET_GL_ERROR( | 12498 LOCAL_SET_GL_ERROR( |
| 12273 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions."); | 12499 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions."); |
| 12274 return; | 12500 return error::kNoError; |
| 12275 } | 12501 } |
| 12276 | 12502 |
| 12277 if (!ValidateCompressedTexFuncData("glCompressedTexSubImage2D", | 12503 if (!ValidateCompressedTexFuncData("glCompressedTexSubImage2D", width, height, |
| 12278 width, height, 1, format, image_size) || | 12504 1, format, image_size, data) || |
| 12279 !ValidateCompressedTexSubDimensions("glCompressedTexSubImage2D", | 12505 !ValidateCompressedTexSubDimensions("glCompressedTexSubImage2D", target, |
| 12280 target, level, xoffset, yoffset, 0, | 12506 level, xoffset, yoffset, 0, width, |
| 12281 width, height, 1, format, texture)) { | 12507 height, 1, format, texture)) { |
| 12282 return; | 12508 return error::kNoError; |
| 12283 } | 12509 } |
| 12284 | 12510 |
| 12285 if (!texture->IsLevelCleared(target, level)) { | 12511 if (!texture->IsLevelCleared(target, level)) { |
| 12286 // This can only happen if the compressed texture was allocated | 12512 // This can only happen if the compressed texture was allocated |
| 12287 // using TexStorage2D. | 12513 // using TexStorage2D. |
| 12288 DCHECK(texture->IsImmutable()); | 12514 DCHECK(texture->IsImmutable()); |
| 12289 GLsizei level_width = 0, level_height = 0; | 12515 GLsizei level_width = 0, level_height = 0; |
| 12290 bool success = texture->GetLevelSize( | 12516 bool success = texture->GetLevelSize( |
| 12291 target, level, &level_width, &level_height, nullptr); | 12517 target, level, &level_width, &level_height, nullptr); |
| 12292 DCHECK(success); | 12518 DCHECK(success); |
| 12293 // We can skip the clear if we're uploading the entire level. | 12519 // We can skip the clear if we're uploading the entire level. |
| 12294 if (xoffset == 0 && yoffset == 0 && | 12520 if (xoffset == 0 && yoffset == 0 && |
| 12295 width == level_width && height == level_height) { | 12521 width == level_width && height == level_height) { |
| 12296 texture_manager()->SetLevelCleared(texture_ref, target, level, true); | 12522 texture_manager()->SetLevelCleared(texture_ref, target, level, true); |
| 12297 } else { | 12523 } else { |
| 12298 texture_manager()->ClearTextureLevel(this, texture_ref, target, level); | 12524 texture_manager()->ClearTextureLevel(this, texture_ref, target, level); |
| 12299 } | 12525 } |
| 12300 DCHECK(texture->IsLevelCleared(target, level)); | 12526 DCHECK(texture->IsLevelCleared(target, level)); |
| 12301 } | 12527 } |
| 12302 | 12528 |
| 12303 glCompressedTexSubImage2D( | 12529 const CompressedFormatInfo* format_info = |
| 12304 target, level, xoffset, yoffset, width, height, format, image_size, data); | 12530 GetCompressedFormatInfo(internal_format); |
| 12531 if (format_info != nullptr && !format_info->support_check(*feature_info_)) { | |
| 12532 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData( | |
| 12533 state_, *format_info, width, height, 1, image_size, data); | |
| 12534 if (!decompressed_data) { | |
| 12535 MarkContextLost(error::kGuilty); | |
| 12536 group_->LoseContexts(error::kInnocent); | |
| 12537 return error::kLostContext; | |
| 12538 } | |
| 12539 state_.PushTextureDecompressionUnpackState(); | |
| 12540 glTexSubImage2D(target, level, xoffset, yoffset, width, height, | |
| 12541 format_info->decompressed_format, | |
| 12542 format_info->decompressed_type, decompressed_data.get()); | |
| 12543 state_.RestoreUnpackState(); | |
| 12544 } else { | |
| 12545 glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, | |
| 12546 format, image_size, data); | |
| 12547 } | |
| 12305 | 12548 |
| 12306 // This may be a slow command. Exit command processing to allow for | 12549 // This may be a slow command. Exit command processing to allow for |
| 12307 // context preemption and GPU watchdog checks. | 12550 // context preemption and GPU watchdog checks. |
| 12308 ExitCommandProcessingEarly(); | 12551 ExitCommandProcessingEarly(); |
| 12552 return error::kNoError; | |
| 12309 } | 12553 } |
| 12310 | 12554 |
| 12311 static void Clip( | 12555 static void Clip( |
| 12312 GLint start, GLint range, GLint sourceRange, | 12556 GLint start, GLint range, GLint sourceRange, |
| 12313 GLint* out_start, GLint* out_range) { | 12557 GLint* out_start, GLint* out_range) { |
| 12314 DCHECK(out_start); | 12558 DCHECK(out_start); |
| 12315 DCHECK(out_range); | 12559 DCHECK(out_range); |
| 12316 if (start < 0) { | 12560 if (start < 0) { |
| 12317 range += start; | 12561 range += start; |
| 12318 start = 0; | 12562 start = 0; |
| (...skipping 2772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 15091 if (target == GL_TEXTURE_3D) | 15335 if (target == GL_TEXTURE_3D) |
| 15092 level_depth = std::max(1, level_depth >> 1); | 15336 level_depth = std::max(1, level_depth >> 1); |
| 15093 } | 15337 } |
| 15094 if (!estimated_size.IsValid() || | 15338 if (!estimated_size.IsValid() || |
| 15095 !EnsureGPUMemoryAvailable(estimated_size.ValueOrDefault(0))) { | 15339 !EnsureGPUMemoryAvailable(estimated_size.ValueOrDefault(0))) { |
| 15096 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "out of memory"); | 15340 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "out of memory"); |
| 15097 return; | 15341 return; |
| 15098 } | 15342 } |
| 15099 } | 15343 } |
| 15100 | 15344 |
| 15345 GLenum compatibility_internal_format = internal_format; | |
| 15346 const CompressedFormatInfo* format_info = | |
| 15347 GetCompressedFormatInfo(internal_format); | |
| 15348 if (format_info != nullptr && !format_info->support_check(*feature_info_)) { | |
| 15349 compatibility_internal_format = format_info->decompressed_internal_format; | |
| 15350 } | |
| 15351 | |
| 15101 // TODO(zmo): We might need to emulate TexStorage using TexImage or | 15352 // TODO(zmo): We might need to emulate TexStorage using TexImage or |
| 15102 // CompressedTexImage on Mac OSX where we expose ES3 APIs when the underlying | 15353 // 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. | 15354 // driver is lower than 4.2 and ARB_texture_storage extension doesn't exist. |
| 15104 if (dimension == ContextState::k2D) { | 15355 if (dimension == ContextState::k2D) { |
| 15105 glTexStorage2DEXT(target, levels, internal_format, width, height); | 15356 glTexStorage2DEXT(target, levels, compatibility_internal_format, width, |
| 15357 height); | |
| 15106 } else { | 15358 } else { |
| 15107 glTexStorage3D(target, levels, internal_format, width, height, depth); | 15359 glTexStorage3D(target, levels, compatibility_internal_format, width, height, |
| 15360 depth); | |
| 15108 } | 15361 } |
| 15109 | 15362 |
| 15110 { | 15363 { |
| 15111 GLsizei level_width = width; | 15364 GLsizei level_width = width; |
| 15112 GLsizei level_height = height; | 15365 GLsizei level_height = height; |
| 15113 GLsizei level_depth = depth; | 15366 GLsizei level_depth = depth; |
| 15114 GLenum adjusted_format = | 15367 GLenum adjusted_format = |
| 15115 feature_info_->IsES3Enabled() ? internal_format : format; | 15368 feature_info_->IsES3Enabled() ? internal_format : format; |
| 15116 for (int ii = 0; ii < levels; ++ii) { | 15369 for (int ii = 0; ii < levels; ++ii) { |
| 15117 if (target == GL_TEXTURE_CUBE_MAP) { | 15370 if (target == GL_TEXTURE_CUBE_MAP) { |
| (...skipping 1988 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 17106 } | 17359 } |
| 17107 | 17360 |
| 17108 // Include the auto-generated part of this file. We split this because it means | 17361 // 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 | 17362 // 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. | 17363 // instead of having to edit some template or the code generator. |
| 17111 #include "base/macros.h" | 17364 #include "base/macros.h" |
| 17112 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 17365 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
| 17113 | 17366 |
| 17114 } // namespace gles2 | 17367 } // namespace gles2 |
| 17115 } // namespace gpu | 17368 } // namespace gpu |
| OLD | NEW |