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 1816 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1893 void MarkContextLost(error::ContextLostReason reason) override; | 1894 void MarkContextLost(error::ContextLostReason reason) override; |
1894 bool CheckResetStatus(); | 1895 bool CheckResetStatus(); |
1895 | 1896 |
1896 bool GetCompressedTexSizeInBytes( | 1897 bool GetCompressedTexSizeInBytes( |
1897 const char* function_name, GLsizei width, GLsizei height, GLsizei depth, | 1898 const char* function_name, GLsizei width, GLsizei height, GLsizei depth, |
1898 GLenum format, GLsizei* size_in_bytes); | 1899 GLenum format, GLsizei* size_in_bytes); |
1899 | 1900 |
1900 bool ValidateCompressedTexDimensions( | 1901 bool ValidateCompressedTexDimensions( |
1901 const char* function_name, GLenum target, GLint level, | 1902 const char* function_name, GLenum target, GLint level, |
1902 GLsizei width, GLsizei height, GLsizei depth, GLenum format); | 1903 GLsizei width, GLsizei height, GLsizei depth, GLenum format); |
1903 bool ValidateCompressedTexFuncData( | 1904 bool ValidateCompressedTexFuncData(const char* function_name, |
1904 const char* function_name, GLsizei width, GLsizei height, GLsizei depth, | 1905 GLsizei width, |
1905 GLenum format, GLsizei size); | 1906 GLsizei height, |
| 1907 GLsizei depth, |
| 1908 GLenum format, |
| 1909 GLsizei size, |
| 1910 const GLvoid* data); |
1906 bool ValidateCompressedTexSubDimensions( | 1911 bool ValidateCompressedTexSubDimensions( |
1907 const char* function_name, | 1912 const char* function_name, |
1908 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, | 1913 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, |
1909 GLsizei width, GLsizei height, GLsizei depth, GLenum format, | 1914 GLsizei width, GLsizei height, GLsizei depth, GLenum format, |
1910 Texture* texture); | 1915 Texture* texture); |
1911 bool ValidateCopyTextureCHROMIUMTextures(const char* function_name, | 1916 bool ValidateCopyTextureCHROMIUMTextures(const char* function_name, |
1912 TextureRef* source_texture_ref, | 1917 TextureRef* source_texture_ref, |
1913 TextureRef* dest_texture_ref); | 1918 TextureRef* dest_texture_ref); |
1914 bool ValidateCopyTextureCHROMIUMInternalFormats( | 1919 bool ValidateCopyTextureCHROMIUMInternalFormats( |
1915 const char* function_name, | 1920 const char* function_name, |
(...skipping 9559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11475 {8, 5}, | 11480 {8, 5}, |
11476 {8, 6}, | 11481 {8, 6}, |
11477 {8, 8}, | 11482 {8, 8}, |
11478 {10, 5}, | 11483 {10, 5}, |
11479 {10, 6}, | 11484 {10, 6}, |
11480 {10, 8}, | 11485 {10, 8}, |
11481 {10, 10}, | 11486 {10, 10}, |
11482 {12, 10}, | 11487 {12, 10}, |
11483 {12, 12}}; | 11488 {12, 12}}; |
11484 | 11489 |
| 11490 bool CheckETCFormatSupport(const FeatureInfo& featureInfo) { |
| 11491 const gl::GLVersionInfo& versionInfo = featureInfo.gl_version_info(); |
| 11492 return versionInfo.IsAtLeastGL(4, 3) || versionInfo.IsAtLeastGLES(3, 0) || |
| 11493 featureInfo.feature_flags().arb_es3_compatibility; |
| 11494 } |
| 11495 |
| 11496 using CompressedFormatSupportCheck = bool (*)(const FeatureInfo&); |
| 11497 using CompressedFormatDecompressionFunction = void (*)(size_t width, |
| 11498 size_t height, |
| 11499 size_t depth, |
| 11500 const uint8_t* input, |
| 11501 size_t inputRowPitch, |
| 11502 size_t inputDepthPitch, |
| 11503 uint8_t* output, |
| 11504 size_t outputRowPitch, |
| 11505 size_t outputDepthPitch); |
| 11506 |
| 11507 struct CompressedFormatInfo { |
| 11508 GLenum format; |
| 11509 uint32_t block_size; |
| 11510 uint32_t bytes_per_block; |
| 11511 CompressedFormatSupportCheck support_check; |
| 11512 CompressedFormatDecompressionFunction decompression_function; |
| 11513 GLenum decompressed_internal_format; |
| 11514 GLenum decompressed_format; |
| 11515 GLenum decompressed_type; |
| 11516 }; |
| 11517 |
| 11518 const CompressedFormatInfo kCompressedFormatInfoArray[] = { |
| 11519 { |
| 11520 GL_COMPRESSED_R11_EAC, 4, 8, CheckETCFormatSupport, |
| 11521 angle::LoadEACR11ToR8, GL_R8, GL_RED, GL_UNSIGNED_BYTE, |
| 11522 }, |
| 11523 { |
| 11524 GL_COMPRESSED_SIGNED_R11_EAC, 4, 8, CheckETCFormatSupport, |
| 11525 angle::LoadEACR11SToR8, GL_R8_SNORM, GL_RED, GL_BYTE, |
| 11526 }, |
| 11527 { |
| 11528 GL_COMPRESSED_RG11_EAC, 4, 16, CheckETCFormatSupport, |
| 11529 angle::LoadEACRG11ToRG8, GL_RG8, GL_RG, GL_UNSIGNED_BYTE, |
| 11530 }, |
| 11531 { |
| 11532 GL_COMPRESSED_SIGNED_RG11_EAC, 4, 16, CheckETCFormatSupport, |
| 11533 angle::LoadEACRG11SToRG8, GL_RG8_SNORM, GL_RG, GL_BYTE, |
| 11534 }, |
| 11535 { |
| 11536 GL_COMPRESSED_RGB8_ETC2, 4, 8, CheckETCFormatSupport, |
| 11537 angle::LoadETC2RGB8ToRGBA8, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, |
| 11538 }, |
| 11539 { |
| 11540 GL_COMPRESSED_SRGB8_ETC2, 4, 8, CheckETCFormatSupport, |
| 11541 angle::LoadETC2SRGB8ToRGBA8, GL_SRGB8_ALPHA8, GL_SRGB_ALPHA, |
| 11542 GL_UNSIGNED_BYTE, |
| 11543 }, |
| 11544 { |
| 11545 GL_COMPRESSED_RGBA8_ETC2_EAC, 4, 16, CheckETCFormatSupport, |
| 11546 angle::LoadETC2RGBA8ToRGBA8, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, |
| 11547 }, |
| 11548 { |
| 11549 GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, 4, 8, |
| 11550 CheckETCFormatSupport, angle::LoadETC2RGB8A1ToRGBA8, GL_RGBA8, GL_RGBA, |
| 11551 GL_UNSIGNED_BYTE, |
| 11552 }, |
| 11553 { |
| 11554 GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, 4, 16, CheckETCFormatSupport, |
| 11555 angle::LoadETC2SRGBA8ToSRGBA8, GL_SRGB8_ALPHA8, GL_SRGB_ALPHA, |
| 11556 GL_UNSIGNED_BYTE, |
| 11557 }, |
| 11558 { |
| 11559 GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, 4, 8, |
| 11560 CheckETCFormatSupport, angle::LoadETC2SRGB8A1ToRGBA8, GL_SRGB8_ALPHA8, |
| 11561 GL_SRGB_ALPHA, GL_UNSIGNED_BYTE, |
| 11562 }, |
| 11563 }; |
| 11564 |
| 11565 const CompressedFormatInfo* GetCompressedFormatInfo(GLenum format) { |
| 11566 for (size_t i = 0; i < arraysize(kCompressedFormatInfoArray); i++) { |
| 11567 if (kCompressedFormatInfoArray[i].format == format) { |
| 11568 return &kCompressedFormatInfoArray[i]; |
| 11569 } |
| 11570 } |
| 11571 return nullptr; |
| 11572 } |
| 11573 |
| 11574 uint32_t GetCompressedFormatRowPitch(const CompressedFormatInfo& info, |
| 11575 uint32_t width) { |
| 11576 uint32_t num_blocks_wide = (width + info.block_size - 1) / info.block_size; |
| 11577 return num_blocks_wide * info.bytes_per_block; |
| 11578 } |
| 11579 |
| 11580 uint32_t GetCompressedFormatDepthPitch(const CompressedFormatInfo& info, |
| 11581 uint32_t width, |
| 11582 uint32_t height) { |
| 11583 uint32_t num_blocks_high = (height + info.block_size - 1) / info.block_size; |
| 11584 return num_blocks_high * GetCompressedFormatRowPitch(info, width); |
| 11585 } |
| 11586 |
| 11587 std::unique_ptr<uint8_t[]> DecompressTextureData( |
| 11588 const ContextState& state, |
| 11589 const CompressedFormatInfo& info, |
| 11590 uint32_t width, |
| 11591 uint32_t height, |
| 11592 uint32_t depth, |
| 11593 GLsizei image_size, |
| 11594 const void* data) { |
| 11595 uint32_t output_pixel_size = GLES2Util::ComputeImageGroupSize( |
| 11596 info.decompressed_format, info.decompressed_type); |
| 11597 std::unique_ptr<uint8_t[]> decompressed_data( |
| 11598 new uint8_t[output_pixel_size * width * height]); |
| 11599 |
| 11600 // If a PBO is bound, map it to decompress the data. |
| 11601 const void* input_data = data; |
| 11602 if (state.bound_pixel_unpack_buffer) { |
| 11603 input_data = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, |
| 11604 reinterpret_cast<GLintptr>(data), image_size, |
| 11605 GL_MAP_READ_BIT); |
| 11606 if (input_data == nullptr) { |
| 11607 LOG(ERROR) << "Failed to map pixel unpack buffer."; |
| 11608 return nullptr; |
| 11609 } |
| 11610 } |
| 11611 |
| 11612 DCHECK_NE(input_data, nullptr); |
| 11613 info.decompression_function( |
| 11614 width, height, depth, static_cast<const uint8_t*>(input_data), |
| 11615 GetCompressedFormatRowPitch(info, width), |
| 11616 GetCompressedFormatDepthPitch(info, width, height), |
| 11617 decompressed_data.get(), output_pixel_size * width, |
| 11618 output_pixel_size * width * height); |
| 11619 |
| 11620 if (state.bound_pixel_unpack_buffer) { |
| 11621 if (glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER) != GL_TRUE) { |
| 11622 LOG(ERROR) << "glUnmapBuffer unexpectedly returned GL_FALSE"; |
| 11623 return nullptr; |
| 11624 } |
| 11625 } |
| 11626 |
| 11627 return decompressed_data; |
| 11628 } |
| 11629 |
11485 bool IsValidDXTSize(GLint level, GLsizei size) { | 11630 bool IsValidDXTSize(GLint level, GLsizei size) { |
11486 // TODO(zmo): Linux NVIDIA driver does allow size of 1 and 2 on level 0. | 11631 // 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. | 11632 // 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 | 11633 // 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. | 11634 // as Linux NVIDIA, then we can remove this limitation. |
11490 return (level && size == 1) || | 11635 return (level && size == 1) || |
11491 (level && size == 2) || | 11636 (level && size == 2) || |
11492 !(size % kS3TCBlockWidth); | 11637 !(size % kS3TCBlockWidth); |
11493 } | 11638 } |
11494 | 11639 |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11616 | 11761 |
11617 if (!bytes_required.IsValid()) { | 11762 if (!bytes_required.IsValid()) { |
11618 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "invalid size"); | 11763 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "invalid size"); |
11619 return false; | 11764 return false; |
11620 } | 11765 } |
11621 | 11766 |
11622 *size_in_bytes = bytes_required.ValueOrDefault(0); | 11767 *size_in_bytes = bytes_required.ValueOrDefault(0); |
11623 return true; | 11768 return true; |
11624 } | 11769 } |
11625 | 11770 |
11626 bool GLES2DecoderImpl::ValidateCompressedTexFuncData( | 11771 bool GLES2DecoderImpl::ValidateCompressedTexFuncData(const char* function_name, |
11627 const char* function_name, GLsizei width, GLsizei height, GLsizei depth, | 11772 GLsizei width, |
11628 GLenum format, GLsizei size) { | 11773 GLsizei height, |
| 11774 GLsizei depth, |
| 11775 GLenum format, |
| 11776 GLsizei size, |
| 11777 const GLvoid* data) { |
11629 GLsizei bytes_required = 0; | 11778 GLsizei bytes_required = 0; |
11630 if (!GetCompressedTexSizeInBytes( | 11779 if (!GetCompressedTexSizeInBytes( |
11631 function_name, width, height, depth, format, &bytes_required)) { | 11780 function_name, width, height, depth, format, &bytes_required)) { |
11632 return false; | 11781 return false; |
11633 } | 11782 } |
11634 | 11783 |
11635 if (size != bytes_required) { | 11784 if (size != bytes_required) { |
11636 LOCAL_SET_GL_ERROR( | 11785 LOCAL_SET_GL_ERROR( |
11637 GL_INVALID_VALUE, function_name, "size is not correct for dimensions"); | 11786 GL_INVALID_VALUE, function_name, "size is not correct for dimensions"); |
11638 return false; | 11787 return false; |
11639 } | 11788 } |
11640 | 11789 |
| 11790 if (state_.bound_pixel_unpack_buffer.get()) { |
| 11791 if (state_.bound_pixel_unpack_buffer->GetMappedRange() != nullptr) { |
| 11792 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, |
| 11793 "pixel unpack buffer is mapped"); |
| 11794 return false; |
| 11795 } |
| 11796 |
| 11797 base::CheckedNumeric<GLintptr> pbo_bytes_required( |
| 11798 reinterpret_cast<GLintptr>(data)); |
| 11799 pbo_bytes_required += bytes_required; |
| 11800 if (!pbo_bytes_required.IsValid() || |
| 11801 pbo_bytes_required.ValueOrDie() > |
| 11802 state_.bound_pixel_unpack_buffer->size()) { |
| 11803 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, |
| 11804 "pixel unpack buffer is not large enough"); |
| 11805 return false; |
| 11806 } |
| 11807 } |
| 11808 |
11641 return true; | 11809 return true; |
11642 } | 11810 } |
11643 | 11811 |
11644 bool GLES2DecoderImpl::ValidateCompressedTexDimensions( | 11812 bool GLES2DecoderImpl::ValidateCompressedTexDimensions( |
11645 const char* function_name, GLenum target, GLint level, | 11813 const char* function_name, GLenum target, GLint level, |
11646 GLsizei width, GLsizei height, GLsizei depth, GLenum format) { | 11814 GLsizei width, GLsizei height, GLsizei depth, GLenum format) { |
11647 switch (format) { | 11815 switch (format) { |
11648 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: | 11816 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: |
11649 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: | 11817 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: |
11650 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: | 11818 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11882 } | 12050 } |
11883 Texture* texture = texture_ref->texture(); | 12051 Texture* texture = texture_ref->texture(); |
11884 if (texture->IsImmutable()) { | 12052 if (texture->IsImmutable()) { |
11885 LOCAL_SET_GL_ERROR( | 12053 LOCAL_SET_GL_ERROR( |
11886 GL_INVALID_OPERATION, | 12054 GL_INVALID_OPERATION, |
11887 "glCompressedTexImage2D", "texture is immutable"); | 12055 "glCompressedTexImage2D", "texture is immutable"); |
11888 return error::kNoError; | 12056 return error::kNoError; |
11889 } | 12057 } |
11890 if (!ValidateCompressedTexDimensions("glCompressedTexImage2D", target, level, | 12058 if (!ValidateCompressedTexDimensions("glCompressedTexImage2D", target, level, |
11891 width, height, 1, internal_format) || | 12059 width, height, 1, internal_format) || |
11892 !ValidateCompressedTexFuncData("glCompressedTexImage2D", width, height, | 12060 !ValidateCompressedTexFuncData("glCompressedTexImage2D", width, height, 1, |
11893 1, internal_format, image_size)) { | 12061 internal_format, image_size, data)) { |
11894 return error::kNoError; | 12062 return error::kNoError; |
11895 } | 12063 } |
11896 | 12064 |
11897 if (!EnsureGPUMemoryAvailable(image_size)) { | 12065 if (!EnsureGPUMemoryAvailable(image_size)) { |
11898 LOCAL_SET_GL_ERROR( | 12066 LOCAL_SET_GL_ERROR( |
11899 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory"); | 12067 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory"); |
11900 return error::kNoError; | 12068 return error::kNoError; |
11901 } | 12069 } |
11902 | 12070 |
11903 if (texture->IsAttachedToFramebuffer()) { | 12071 if (texture->IsAttachedToFramebuffer()) { |
11904 framebuffer_state_.clear_state_dirty = true; | 12072 framebuffer_state_.clear_state_dirty = true; |
11905 } | 12073 } |
11906 | 12074 |
11907 std::unique_ptr<int8_t[]> zero; | 12075 std::unique_ptr<int8_t[]> zero; |
11908 if (!data) { | 12076 if (!state_.bound_pixel_unpack_buffer && !data) { |
11909 zero.reset(new int8_t[image_size]); | 12077 zero.reset(new int8_t[image_size]); |
11910 memset(zero.get(), 0, image_size); | 12078 memset(zero.get(), 0, image_size); |
11911 data = zero.get(); | 12079 data = zero.get(); |
11912 } | 12080 } |
11913 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D"); | 12081 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D"); |
11914 glCompressedTexImage2D( | 12082 |
11915 target, level, internal_format, width, height, border, image_size, data); | 12083 const CompressedFormatInfo* format_info = |
| 12084 GetCompressedFormatInfo(internal_format); |
| 12085 if (format_info != nullptr && !format_info->support_check(*feature_info_)) { |
| 12086 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData( |
| 12087 state_, *format_info, width, height, 1, image_size, data); |
| 12088 if (!decompressed_data) { |
| 12089 MarkContextLost(error::kGuilty); |
| 12090 group_->LoseContexts(error::kInnocent); |
| 12091 return error::kLostContext; |
| 12092 } |
| 12093 state_.PushTextureDecompressionUnpackState(); |
| 12094 glTexImage2D(target, level, format_info->decompressed_internal_format, |
| 12095 width, height, border, format_info->decompressed_format, |
| 12096 format_info->decompressed_type, decompressed_data.get()); |
| 12097 state_.RestoreUnpackState(); |
| 12098 } else { |
| 12099 glCompressedTexImage2D(target, level, internal_format, width, height, |
| 12100 border, image_size, data); |
| 12101 } |
11916 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D"); | 12102 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D"); |
11917 if (error == GL_NO_ERROR) { | 12103 if (error == GL_NO_ERROR) { |
11918 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, | 12104 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, |
11919 width, height, 1, border, 0, 0, | 12105 width, height, 1, border, 0, 0, |
11920 gfx::Rect(width, height)); | 12106 gfx::Rect(width, height)); |
11921 } | 12107 } |
11922 | 12108 |
11923 // This may be a slow command. Exit command processing to allow for | 12109 // This may be a slow command. Exit command processing to allow for |
11924 // context preemption and GPU watchdog checks. | 12110 // context preemption and GPU watchdog checks. |
11925 ExitCommandProcessingEarly(); | 12111 ExitCommandProcessingEarly(); |
(...skipping 29 matching lines...) Expand all Loading... |
11955 if (texture->IsImmutable()) { | 12141 if (texture->IsImmutable()) { |
11956 LOCAL_SET_GL_ERROR( | 12142 LOCAL_SET_GL_ERROR( |
11957 GL_INVALID_OPERATION, | 12143 GL_INVALID_OPERATION, |
11958 "glCompressedTexImage3D", "texture is immutable"); | 12144 "glCompressedTexImage3D", "texture is immutable"); |
11959 return error::kNoError; | 12145 return error::kNoError; |
11960 } | 12146 } |
11961 | 12147 |
11962 if (!ValidateCompressedTexDimensions("glCompressedTexImage3D", target, level, | 12148 if (!ValidateCompressedTexDimensions("glCompressedTexImage3D", target, level, |
11963 width, height, depth, internal_format) || | 12149 width, height, depth, internal_format) || |
11964 !ValidateCompressedTexFuncData("glCompressedTexImage3D", width, height, | 12150 !ValidateCompressedTexFuncData("glCompressedTexImage3D", width, height, |
11965 depth, internal_format, image_size)) { | 12151 depth, internal_format, image_size, |
| 12152 data)) { |
11966 return error::kNoError; | 12153 return error::kNoError; |
11967 } | 12154 } |
11968 | 12155 |
11969 if (!EnsureGPUMemoryAvailable(image_size)) { | 12156 if (!EnsureGPUMemoryAvailable(image_size)) { |
11970 LOCAL_SET_GL_ERROR( | 12157 LOCAL_SET_GL_ERROR( |
11971 GL_OUT_OF_MEMORY, "glCompressedTexImage3D", "out of memory"); | 12158 GL_OUT_OF_MEMORY, "glCompressedTexImage3D", "out of memory"); |
11972 return error::kNoError; | 12159 return error::kNoError; |
11973 } | 12160 } |
11974 | 12161 |
11975 if (texture->IsAttachedToFramebuffer()) { | 12162 if (texture->IsAttachedToFramebuffer()) { |
11976 framebuffer_state_.clear_state_dirty = true; | 12163 framebuffer_state_.clear_state_dirty = true; |
11977 } | 12164 } |
11978 | 12165 |
11979 std::unique_ptr<int8_t[]> zero; | 12166 std::unique_ptr<int8_t[]> zero; |
11980 if (!data) { | 12167 if (!state_.bound_pixel_unpack_buffer && !data) { |
11981 zero.reset(new int8_t[image_size]); | 12168 zero.reset(new int8_t[image_size]); |
11982 memset(zero.get(), 0, image_size); | 12169 memset(zero.get(), 0, image_size); |
11983 data = zero.get(); | 12170 data = zero.get(); |
11984 } | 12171 } |
11985 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage3D"); | 12172 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage3D"); |
11986 glCompressedTexImage3D(target, level, internal_format, width, height, depth, | 12173 const CompressedFormatInfo* format_info = |
11987 border, image_size, data); | 12174 GetCompressedFormatInfo(internal_format); |
| 12175 if (format_info != nullptr && !format_info->support_check(*feature_info_)) { |
| 12176 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData( |
| 12177 state_, *format_info, width, height, depth, image_size, data); |
| 12178 if (!decompressed_data) { |
| 12179 MarkContextLost(error::kGuilty); |
| 12180 group_->LoseContexts(error::kInnocent); |
| 12181 return error::kLostContext; |
| 12182 } |
| 12183 state_.PushTextureDecompressionUnpackState(); |
| 12184 glTexImage3D(target, level, format_info->decompressed_internal_format, |
| 12185 width, height, depth, border, format_info->decompressed_format, |
| 12186 format_info->decompressed_type, decompressed_data.get()); |
| 12187 state_.RestoreUnpackState(); |
| 12188 } else { |
| 12189 glCompressedTexImage3D(target, level, internal_format, width, height, depth, |
| 12190 border, image_size, data); |
| 12191 } |
11988 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage3D"); | 12192 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage3D"); |
11989 if (error == GL_NO_ERROR) { | 12193 if (error == GL_NO_ERROR) { |
11990 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, | 12194 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, |
11991 width, height, depth, border, 0, 0, | 12195 width, height, depth, border, 0, 0, |
11992 gfx::Rect(width, height)); | 12196 gfx::Rect(width, height)); |
11993 } | 12197 } |
11994 | 12198 |
11995 // This may be a slow command. Exit command processing to allow for | 12199 // This may be a slow command. Exit command processing to allow for |
11996 // context preemption and GPU watchdog checks. | 12200 // context preemption and GPU watchdog checks. |
11997 ExitCommandProcessingEarly(); | 12201 ExitCommandProcessingEarly(); |
(...skipping 30 matching lines...) Expand all Loading... |
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; |
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; |
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, | |
12044 format, texture)) { | |
12045 return; | 12247 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; |
| 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(); |
12059 } | 12278 } |
12060 | 12279 |
12061 error::Error GLES2DecoderImpl::HandleTexImage2D(uint32_t immediate_data_size, | 12280 error::Error GLES2DecoderImpl::HandleTexImage2D(uint32_t immediate_data_size, |
12062 const void* cmd_data) { | 12281 const void* cmd_data) { |
12063 const gles2::cmds::TexImage2D& c = | 12282 const gles2::cmds::TexImage2D& c = |
12064 *static_cast<const gles2::cmds::TexImage2D*>(cmd_data); | 12283 *static_cast<const gles2::cmds::TexImage2D*>(cmd_data); |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12267 "glCompressedTexSubImage2D", "format does not match internal format."); | 12486 "glCompressedTexSubImage2D", "format does not match internal format."); |
12268 return; | 12487 return; |
12269 } | 12488 } |
12270 if (!texture->ValidForTexture(target, level, xoffset, yoffset, 0, width, | 12489 if (!texture->ValidForTexture(target, level, xoffset, yoffset, 0, width, |
12271 height, 1)) { | 12490 height, 1)) { |
12272 LOCAL_SET_GL_ERROR( | 12491 LOCAL_SET_GL_ERROR( |
12273 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions."); | 12492 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions."); |
12274 return; | 12493 return; |
12275 } | 12494 } |
12276 | 12495 |
12277 if (!ValidateCompressedTexFuncData("glCompressedTexSubImage2D", | 12496 if (!ValidateCompressedTexFuncData("glCompressedTexSubImage2D", width, height, |
12278 width, height, 1, format, image_size) || | 12497 1, format, image_size, data) || |
12279 !ValidateCompressedTexSubDimensions("glCompressedTexSubImage2D", | 12498 !ValidateCompressedTexSubDimensions("glCompressedTexSubImage2D", target, |
12280 target, level, xoffset, yoffset, 0, | 12499 level, xoffset, yoffset, 0, width, |
12281 width, height, 1, format, texture)) { | 12500 height, 1, format, texture)) { |
12282 return; | 12501 return; |
12283 } | 12502 } |
12284 | 12503 |
12285 if (!texture->IsLevelCleared(target, level)) { | 12504 if (!texture->IsLevelCleared(target, level)) { |
12286 // This can only happen if the compressed texture was allocated | 12505 // This can only happen if the compressed texture was allocated |
12287 // using TexStorage2D. | 12506 // using TexStorage2D. |
12288 DCHECK(texture->IsImmutable()); | 12507 DCHECK(texture->IsImmutable()); |
12289 GLsizei level_width = 0, level_height = 0; | 12508 GLsizei level_width = 0, level_height = 0; |
12290 bool success = texture->GetLevelSize( | 12509 bool success = texture->GetLevelSize( |
12291 target, level, &level_width, &level_height, nullptr); | 12510 target, level, &level_width, &level_height, nullptr); |
12292 DCHECK(success); | 12511 DCHECK(success); |
12293 // We can skip the clear if we're uploading the entire level. | 12512 // We can skip the clear if we're uploading the entire level. |
12294 if (xoffset == 0 && yoffset == 0 && | 12513 if (xoffset == 0 && yoffset == 0 && |
12295 width == level_width && height == level_height) { | 12514 width == level_width && height == level_height) { |
12296 texture_manager()->SetLevelCleared(texture_ref, target, level, true); | 12515 texture_manager()->SetLevelCleared(texture_ref, target, level, true); |
12297 } else { | 12516 } else { |
12298 texture_manager()->ClearTextureLevel(this, texture_ref, target, level); | 12517 texture_manager()->ClearTextureLevel(this, texture_ref, target, level); |
12299 } | 12518 } |
12300 DCHECK(texture->IsLevelCleared(target, level)); | 12519 DCHECK(texture->IsLevelCleared(target, level)); |
12301 } | 12520 } |
12302 | 12521 |
12303 glCompressedTexSubImage2D( | 12522 const CompressedFormatInfo* format_info = |
12304 target, level, xoffset, yoffset, width, height, format, image_size, data); | 12523 GetCompressedFormatInfo(internal_format); |
| 12524 if (format_info != nullptr && !format_info->support_check(*feature_info_)) { |
| 12525 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData( |
| 12526 state_, *format_info, width, height, 1, image_size, data); |
| 12527 if (!decompressed_data) { |
| 12528 MarkContextLost(error::kGuilty); |
| 12529 group_->LoseContexts(error::kInnocent); |
| 12530 return; |
| 12531 } |
| 12532 state_.PushTextureDecompressionUnpackState(); |
| 12533 glTexSubImage2D(target, level, xoffset, yoffset, width, height, |
| 12534 format_info->decompressed_format, |
| 12535 format_info->decompressed_type, decompressed_data.get()); |
| 12536 state_.RestoreUnpackState(); |
| 12537 } else { |
| 12538 glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, |
| 12539 format, image_size, data); |
| 12540 } |
12305 | 12541 |
12306 // This may be a slow command. Exit command processing to allow for | 12542 // This may be a slow command. Exit command processing to allow for |
12307 // context preemption and GPU watchdog checks. | 12543 // context preemption and GPU watchdog checks. |
12308 ExitCommandProcessingEarly(); | 12544 ExitCommandProcessingEarly(); |
12309 } | 12545 } |
12310 | 12546 |
12311 static void Clip( | 12547 static void Clip( |
12312 GLint start, GLint range, GLint sourceRange, | 12548 GLint start, GLint range, GLint sourceRange, |
12313 GLint* out_start, GLint* out_range) { | 12549 GLint* out_start, GLint* out_range) { |
12314 DCHECK(out_start); | 12550 DCHECK(out_start); |
(...skipping 2776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15091 if (target == GL_TEXTURE_3D) | 15327 if (target == GL_TEXTURE_3D) |
15092 level_depth = std::max(1, level_depth >> 1); | 15328 level_depth = std::max(1, level_depth >> 1); |
15093 } | 15329 } |
15094 if (!estimated_size.IsValid() || | 15330 if (!estimated_size.IsValid() || |
15095 !EnsureGPUMemoryAvailable(estimated_size.ValueOrDefault(0))) { | 15331 !EnsureGPUMemoryAvailable(estimated_size.ValueOrDefault(0))) { |
15096 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "out of memory"); | 15332 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "out of memory"); |
15097 return; | 15333 return; |
15098 } | 15334 } |
15099 } | 15335 } |
15100 | 15336 |
| 15337 GLenum compatibility_internal_format = internal_format; |
| 15338 const CompressedFormatInfo* format_info = |
| 15339 GetCompressedFormatInfo(internal_format); |
| 15340 if (format_info != nullptr && !format_info->support_check(*feature_info_)) { |
| 15341 compatibility_internal_format = format_info->decompressed_internal_format; |
| 15342 } |
| 15343 |
15101 // TODO(zmo): We might need to emulate TexStorage using TexImage or | 15344 // TODO(zmo): We might need to emulate TexStorage using TexImage or |
15102 // CompressedTexImage on Mac OSX where we expose ES3 APIs when the underlying | 15345 // 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. | 15346 // driver is lower than 4.2 and ARB_texture_storage extension doesn't exist. |
15104 if (dimension == ContextState::k2D) { | 15347 if (dimension == ContextState::k2D) { |
15105 glTexStorage2DEXT(target, levels, internal_format, width, height); | 15348 glTexStorage2DEXT(target, levels, compatibility_internal_format, width, |
| 15349 height); |
15106 } else { | 15350 } else { |
15107 glTexStorage3D(target, levels, internal_format, width, height, depth); | 15351 glTexStorage3D(target, levels, compatibility_internal_format, width, height, |
| 15352 depth); |
15108 } | 15353 } |
15109 | 15354 |
15110 { | 15355 { |
15111 GLsizei level_width = width; | 15356 GLsizei level_width = width; |
15112 GLsizei level_height = height; | 15357 GLsizei level_height = height; |
15113 GLsizei level_depth = depth; | 15358 GLsizei level_depth = depth; |
15114 GLenum adjusted_format = | 15359 GLenum adjusted_format = |
15115 feature_info_->IsES3Enabled() ? internal_format : format; | 15360 feature_info_->IsES3Enabled() ? internal_format : format; |
15116 for (int ii = 0; ii < levels; ++ii) { | 15361 for (int ii = 0; ii < levels; ++ii) { |
15117 if (target == GL_TEXTURE_CUBE_MAP) { | 15362 if (target == GL_TEXTURE_CUBE_MAP) { |
(...skipping 1988 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17106 } | 17351 } |
17107 | 17352 |
17108 // Include the auto-generated part of this file. We split this because it means | 17353 // 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 | 17354 // 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. | 17355 // instead of having to edit some template or the code generator. |
17111 #include "base/macros.h" | 17356 #include "base/macros.h" |
17112 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 17357 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
17113 | 17358 |
17114 } // namespace gles2 | 17359 } // namespace gles2 |
17115 } // namespace gpu | 17360 } // namespace gpu |
OLD | NEW |