Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(589)

Side by Side Diff: gpu/command_buffer/service/gles2_cmd_decoder.cc

Issue 2076213002: Decompress ETC texture data when there is no native support. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix formatting. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « gpu/command_buffer/service/feature_info.cc ('k') | gpu/gpu.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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);
piman 2016/07/11 20:18:18 Oh, something I missed... do we need to return nul
Geoff Lang 2016/07/11 20:50:00 Yep, should have checked this to be safe. Done.
11606 }
11607
11608 info.decompression_function(
11609 width, height, depth, static_cast<const uint8_t*>(input_data),
11610 GetCompressedFormatRowPitch(info, width),
11611 GetCompressedFormatDepthPitch(info, width, height),
11612 decompressed_data.get(), output_pixel_size * width,
11613 output_pixel_size * width * height);
11614
11615 if (state.bound_pixel_unpack_buffer) {
11616 if (glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER) != GL_TRUE) {
11617 LOG(ERROR) << "glUnmapBuffer unexpectedly returned GL_FALSE";
11618 return nullptr;
11619 }
11620 }
11621
11622 return decompressed_data;
11623 }
11624
11485 bool IsValidDXTSize(GLint level, GLsizei size) { 11625 bool IsValidDXTSize(GLint level, GLsizei size) {
11486 // TODO(zmo): Linux NVIDIA driver does allow size of 1 and 2 on level 0. 11626 // 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. 11627 // 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 11628 // 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. 11629 // as Linux NVIDIA, then we can remove this limitation.
11490 return (level && size == 1) || 11630 return (level && size == 1) ||
11491 (level && size == 2) || 11631 (level && size == 2) ||
11492 !(size % kS3TCBlockWidth); 11632 !(size % kS3TCBlockWidth);
11493 } 11633 }
11494 11634
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
11616 11756
11617 if (!bytes_required.IsValid()) { 11757 if (!bytes_required.IsValid()) {
11618 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "invalid size"); 11758 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "invalid size");
11619 return false; 11759 return false;
11620 } 11760 }
11621 11761
11622 *size_in_bytes = bytes_required.ValueOrDefault(0); 11762 *size_in_bytes = bytes_required.ValueOrDefault(0);
11623 return true; 11763 return true;
11624 } 11764 }
11625 11765
11626 bool GLES2DecoderImpl::ValidateCompressedTexFuncData( 11766 bool GLES2DecoderImpl::ValidateCompressedTexFuncData(const char* function_name,
11627 const char* function_name, GLsizei width, GLsizei height, GLsizei depth, 11767 GLsizei width,
11628 GLenum format, GLsizei size) { 11768 GLsizei height,
11769 GLsizei depth,
11770 GLenum format,
11771 GLsizei size,
11772 const GLvoid* data) {
11629 GLsizei bytes_required = 0; 11773 GLsizei bytes_required = 0;
11630 if (!GetCompressedTexSizeInBytes( 11774 if (!GetCompressedTexSizeInBytes(
11631 function_name, width, height, depth, format, &bytes_required)) { 11775 function_name, width, height, depth, format, &bytes_required)) {
11632 return false; 11776 return false;
11633 } 11777 }
11634 11778
11635 if (size != bytes_required) { 11779 if (size != bytes_required) {
11636 LOCAL_SET_GL_ERROR( 11780 LOCAL_SET_GL_ERROR(
11637 GL_INVALID_VALUE, function_name, "size is not correct for dimensions"); 11781 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
11638 return false; 11782 return false;
11639 } 11783 }
11640 11784
11785 if (state_.bound_pixel_unpack_buffer.get()) {
11786 if (state_.bound_pixel_unpack_buffer->GetMappedRange() != nullptr) {
11787 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
11788 "pixel unpack buffer is mapped");
11789 return false;
11790 }
11791
11792 base::CheckedNumeric<GLintptr> pbo_bytes_required(
11793 reinterpret_cast<GLintptr>(data));
11794 pbo_bytes_required += bytes_required;
11795 if (!pbo_bytes_required.IsValid() ||
11796 pbo_bytes_required.ValueOrDie() >
11797 state_.bound_pixel_unpack_buffer->size()) {
11798 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
11799 "pixel unpack buffer is not large enough");
11800 return false;
11801 }
11802 }
11803
11641 return true; 11804 return true;
11642 } 11805 }
11643 11806
11644 bool GLES2DecoderImpl::ValidateCompressedTexDimensions( 11807 bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
11645 const char* function_name, GLenum target, GLint level, 11808 const char* function_name, GLenum target, GLint level,
11646 GLsizei width, GLsizei height, GLsizei depth, GLenum format) { 11809 GLsizei width, GLsizei height, GLsizei depth, GLenum format) {
11647 switch (format) { 11810 switch (format) {
11648 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 11811 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
11649 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 11812 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
11650 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: 11813 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
11882 } 12045 }
11883 Texture* texture = texture_ref->texture(); 12046 Texture* texture = texture_ref->texture();
11884 if (texture->IsImmutable()) { 12047 if (texture->IsImmutable()) {
11885 LOCAL_SET_GL_ERROR( 12048 LOCAL_SET_GL_ERROR(
11886 GL_INVALID_OPERATION, 12049 GL_INVALID_OPERATION,
11887 "glCompressedTexImage2D", "texture is immutable"); 12050 "glCompressedTexImage2D", "texture is immutable");
11888 return error::kNoError; 12051 return error::kNoError;
11889 } 12052 }
11890 if (!ValidateCompressedTexDimensions("glCompressedTexImage2D", target, level, 12053 if (!ValidateCompressedTexDimensions("glCompressedTexImage2D", target, level,
11891 width, height, 1, internal_format) || 12054 width, height, 1, internal_format) ||
11892 !ValidateCompressedTexFuncData("glCompressedTexImage2D", width, height, 12055 !ValidateCompressedTexFuncData("glCompressedTexImage2D", width, height, 1,
11893 1, internal_format, image_size)) { 12056 internal_format, image_size, data)) {
11894 return error::kNoError; 12057 return error::kNoError;
11895 } 12058 }
11896 12059
11897 if (!EnsureGPUMemoryAvailable(image_size)) { 12060 if (!EnsureGPUMemoryAvailable(image_size)) {
11898 LOCAL_SET_GL_ERROR( 12061 LOCAL_SET_GL_ERROR(
11899 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory"); 12062 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
11900 return error::kNoError; 12063 return error::kNoError;
11901 } 12064 }
11902 12065
11903 if (texture->IsAttachedToFramebuffer()) { 12066 if (texture->IsAttachedToFramebuffer()) {
11904 framebuffer_state_.clear_state_dirty = true; 12067 framebuffer_state_.clear_state_dirty = true;
11905 } 12068 }
11906 12069
11907 std::unique_ptr<int8_t[]> zero; 12070 std::unique_ptr<int8_t[]> zero;
11908 if (!data) { 12071 if (!state_.bound_pixel_unpack_buffer && !data) {
11909 zero.reset(new int8_t[image_size]); 12072 zero.reset(new int8_t[image_size]);
11910 memset(zero.get(), 0, image_size); 12073 memset(zero.get(), 0, image_size);
11911 data = zero.get(); 12074 data = zero.get();
11912 } 12075 }
11913 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D"); 12076 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
11914 glCompressedTexImage2D( 12077
11915 target, level, internal_format, width, height, border, image_size, data); 12078 const CompressedFormatInfo* format_info =
12079 GetCompressedFormatInfo(internal_format);
12080 if (format_info != nullptr && !format_info->support_check(*feature_info_)) {
12081 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData(
12082 state_, *format_info, width, height, 1, image_size, data);
12083 if (!decompressed_data) {
12084 MarkContextLost(error::kGuilty);
12085 group_->LoseContexts(error::kInnocent);
12086 return error::kLostContext;
12087 }
12088 state_.PushTextureDecompressionUnpackState();
12089 glTexImage2D(target, level, format_info->decompressed_internal_format,
12090 width, height, border, format_info->decompressed_format,
12091 format_info->decompressed_type, decompressed_data.get());
12092 state_.RestoreUnpackState();
12093 } else {
12094 glCompressedTexImage2D(target, level, internal_format, width, height,
12095 border, image_size, data);
12096 }
11916 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D"); 12097 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
11917 if (error == GL_NO_ERROR) { 12098 if (error == GL_NO_ERROR) {
11918 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, 12099 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format,
11919 width, height, 1, border, 0, 0, 12100 width, height, 1, border, 0, 0,
11920 gfx::Rect(width, height)); 12101 gfx::Rect(width, height));
11921 } 12102 }
11922 12103
11923 // This may be a slow command. Exit command processing to allow for 12104 // This may be a slow command. Exit command processing to allow for
11924 // context preemption and GPU watchdog checks. 12105 // context preemption and GPU watchdog checks.
11925 ExitCommandProcessingEarly(); 12106 ExitCommandProcessingEarly();
(...skipping 29 matching lines...) Expand all
11955 if (texture->IsImmutable()) { 12136 if (texture->IsImmutable()) {
11956 LOCAL_SET_GL_ERROR( 12137 LOCAL_SET_GL_ERROR(
11957 GL_INVALID_OPERATION, 12138 GL_INVALID_OPERATION,
11958 "glCompressedTexImage3D", "texture is immutable"); 12139 "glCompressedTexImage3D", "texture is immutable");
11959 return error::kNoError; 12140 return error::kNoError;
11960 } 12141 }
11961 12142
11962 if (!ValidateCompressedTexDimensions("glCompressedTexImage3D", target, level, 12143 if (!ValidateCompressedTexDimensions("glCompressedTexImage3D", target, level,
11963 width, height, depth, internal_format) || 12144 width, height, depth, internal_format) ||
11964 !ValidateCompressedTexFuncData("glCompressedTexImage3D", width, height, 12145 !ValidateCompressedTexFuncData("glCompressedTexImage3D", width, height,
11965 depth, internal_format, image_size)) { 12146 depth, internal_format, image_size,
12147 data)) {
11966 return error::kNoError; 12148 return error::kNoError;
11967 } 12149 }
11968 12150
11969 if (!EnsureGPUMemoryAvailable(image_size)) { 12151 if (!EnsureGPUMemoryAvailable(image_size)) {
11970 LOCAL_SET_GL_ERROR( 12152 LOCAL_SET_GL_ERROR(
11971 GL_OUT_OF_MEMORY, "glCompressedTexImage3D", "out of memory"); 12153 GL_OUT_OF_MEMORY, "glCompressedTexImage3D", "out of memory");
11972 return error::kNoError; 12154 return error::kNoError;
11973 } 12155 }
11974 12156
11975 if (texture->IsAttachedToFramebuffer()) { 12157 if (texture->IsAttachedToFramebuffer()) {
11976 framebuffer_state_.clear_state_dirty = true; 12158 framebuffer_state_.clear_state_dirty = true;
11977 } 12159 }
11978 12160
11979 std::unique_ptr<int8_t[]> zero; 12161 std::unique_ptr<int8_t[]> zero;
11980 if (!data) { 12162 if (!state_.bound_pixel_unpack_buffer && !data) {
11981 zero.reset(new int8_t[image_size]); 12163 zero.reset(new int8_t[image_size]);
11982 memset(zero.get(), 0, image_size); 12164 memset(zero.get(), 0, image_size);
11983 data = zero.get(); 12165 data = zero.get();
11984 } 12166 }
11985 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage3D"); 12167 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage3D");
11986 glCompressedTexImage3D(target, level, internal_format, width, height, depth, 12168 const CompressedFormatInfo* format_info =
11987 border, image_size, data); 12169 GetCompressedFormatInfo(internal_format);
12170 if (format_info != nullptr && !format_info->support_check(*feature_info_)) {
12171 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData(
12172 state_, *format_info, width, height, depth, image_size, data);
12173 if (!decompressed_data) {
12174 MarkContextLost(error::kGuilty);
12175 group_->LoseContexts(error::kInnocent);
12176 return error::kLostContext;
12177 }
12178 state_.PushTextureDecompressionUnpackState();
12179 glTexImage3D(target, level, format_info->decompressed_internal_format,
12180 width, height, depth, border, format_info->decompressed_format,
12181 format_info->decompressed_type, decompressed_data.get());
12182 state_.RestoreUnpackState();
12183 } else {
12184 glCompressedTexImage3D(target, level, internal_format, width, height, depth,
12185 border, image_size, data);
12186 }
11988 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage3D"); 12187 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage3D");
11989 if (error == GL_NO_ERROR) { 12188 if (error == GL_NO_ERROR) {
11990 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, 12189 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format,
11991 width, height, depth, border, 0, 0, 12190 width, height, depth, border, 0, 0,
11992 gfx::Rect(width, height)); 12191 gfx::Rect(width, height));
11993 } 12192 }
11994 12193
11995 // This may be a slow command. Exit command processing to allow for 12194 // This may be a slow command. Exit command processing to allow for
11996 // context preemption and GPU watchdog checks. 12195 // context preemption and GPU watchdog checks.
11997 ExitCommandProcessingEarly(); 12196 ExitCommandProcessingEarly();
(...skipping 30 matching lines...) Expand all
12028 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCompressedTexSubImage3D", 12227 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCompressedTexSubImage3D",
12029 "format does not match internal format"); 12228 "format does not match internal format");
12030 return; 12229 return;
12031 } 12230 }
12032 if (!texture->ValidForTexture(target, level, xoffset, yoffset, zoffset, 12231 if (!texture->ValidForTexture(target, level, xoffset, yoffset, zoffset,
12033 width, height, depth)) { 12232 width, height, depth)) {
12034 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedTexSubImage3D", 12233 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedTexSubImage3D",
12035 "bad dimensions"); 12234 "bad dimensions");
12036 return; 12235 return;
12037 } 12236 }
12038 if (!ValidateCompressedTexFuncData("glCompressedTexSubImage3D", 12237 if (!ValidateCompressedTexFuncData("glCompressedTexSubImage3D", width, height,
12039 width, height, depth, format, 12238 depth, format, image_size, data) ||
12040 image_size) || 12239 !ValidateCompressedTexSubDimensions(
12041 !ValidateCompressedTexSubDimensions("glCompressedTexSubImage3D", 12240 "glCompressedTexSubImage3D", target, level, xoffset, yoffset, zoffset,
12042 target, level, xoffset, yoffset, 12241 width, height, depth, format, texture)) {
12043 zoffset, width, height, depth,
12044 format, texture)) {
12045 return; 12242 return;
12046 } 12243 }
12047 12244
12048 // Note: There is no need to deal with texture cleared tracking here 12245 // 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 12246 // because the validation above means you can only get here if the level
12050 // is already a matching compressed format and in that case 12247 // is already a matching compressed format and in that case
12051 // CompressedTexImage3D already cleared the texture. 12248 // CompressedTexImage3D already cleared the texture.
12052 glCompressedTexSubImage3D( 12249
12053 target, level, xoffset, yoffset, zoffset, width, height, depth, format, 12250 const CompressedFormatInfo* format_info =
12054 image_size, data); 12251 GetCompressedFormatInfo(internal_format);
12252 if (format_info != nullptr && !format_info->support_check(*feature_info_)) {
12253 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData(
12254 state_, *format_info, width, height, depth, image_size, data);
12255 if (!decompressed_data) {
12256 MarkContextLost(error::kGuilty);
12257 group_->LoseContexts(error::kInnocent);
12258 return;
12259 }
12260 state_.PushTextureDecompressionUnpackState();
12261 glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height,
12262 depth, format_info->decompressed_format,
12263 format_info->decompressed_type, decompressed_data.get());
12264 state_.RestoreUnpackState();
12265 } else {
12266 glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width,
12267 height, depth, format, image_size, data);
12268 }
12055 12269
12056 // This may be a slow command. Exit command processing to allow for 12270 // This may be a slow command. Exit command processing to allow for
12057 // context preemption and GPU watchdog checks. 12271 // context preemption and GPU watchdog checks.
12058 ExitCommandProcessingEarly(); 12272 ExitCommandProcessingEarly();
12059 } 12273 }
12060 12274
12061 error::Error GLES2DecoderImpl::HandleTexImage2D(uint32_t immediate_data_size, 12275 error::Error GLES2DecoderImpl::HandleTexImage2D(uint32_t immediate_data_size,
12062 const void* cmd_data) { 12276 const void* cmd_data) {
12063 const gles2::cmds::TexImage2D& c = 12277 const gles2::cmds::TexImage2D& c =
12064 *static_cast<const gles2::cmds::TexImage2D*>(cmd_data); 12278 *static_cast<const gles2::cmds::TexImage2D*>(cmd_data);
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
12267 "glCompressedTexSubImage2D", "format does not match internal format."); 12481 "glCompressedTexSubImage2D", "format does not match internal format.");
12268 return; 12482 return;
12269 } 12483 }
12270 if (!texture->ValidForTexture(target, level, xoffset, yoffset, 0, width, 12484 if (!texture->ValidForTexture(target, level, xoffset, yoffset, 0, width,
12271 height, 1)) { 12485 height, 1)) {
12272 LOCAL_SET_GL_ERROR( 12486 LOCAL_SET_GL_ERROR(
12273 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions."); 12487 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
12274 return; 12488 return;
12275 } 12489 }
12276 12490
12277 if (!ValidateCompressedTexFuncData("glCompressedTexSubImage2D", 12491 if (!ValidateCompressedTexFuncData("glCompressedTexSubImage2D", width, height,
12278 width, height, 1, format, image_size) || 12492 1, format, image_size, data) ||
12279 !ValidateCompressedTexSubDimensions("glCompressedTexSubImage2D", 12493 !ValidateCompressedTexSubDimensions("glCompressedTexSubImage2D", target,
12280 target, level, xoffset, yoffset, 0, 12494 level, xoffset, yoffset, 0, width,
12281 width, height, 1, format, texture)) { 12495 height, 1, format, texture)) {
12282 return; 12496 return;
12283 } 12497 }
12284 12498
12285 if (!texture->IsLevelCleared(target, level)) { 12499 if (!texture->IsLevelCleared(target, level)) {
12286 // This can only happen if the compressed texture was allocated 12500 // This can only happen if the compressed texture was allocated
12287 // using TexStorage2D. 12501 // using TexStorage2D.
12288 DCHECK(texture->IsImmutable()); 12502 DCHECK(texture->IsImmutable());
12289 GLsizei level_width = 0, level_height = 0; 12503 GLsizei level_width = 0, level_height = 0;
12290 bool success = texture->GetLevelSize( 12504 bool success = texture->GetLevelSize(
12291 target, level, &level_width, &level_height, nullptr); 12505 target, level, &level_width, &level_height, nullptr);
12292 DCHECK(success); 12506 DCHECK(success);
12293 // We can skip the clear if we're uploading the entire level. 12507 // We can skip the clear if we're uploading the entire level.
12294 if (xoffset == 0 && yoffset == 0 && 12508 if (xoffset == 0 && yoffset == 0 &&
12295 width == level_width && height == level_height) { 12509 width == level_width && height == level_height) {
12296 texture_manager()->SetLevelCleared(texture_ref, target, level, true); 12510 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
12297 } else { 12511 } else {
12298 texture_manager()->ClearTextureLevel(this, texture_ref, target, level); 12512 texture_manager()->ClearTextureLevel(this, texture_ref, target, level);
12299 } 12513 }
12300 DCHECK(texture->IsLevelCleared(target, level)); 12514 DCHECK(texture->IsLevelCleared(target, level));
12301 } 12515 }
12302 12516
12303 glCompressedTexSubImage2D( 12517 const CompressedFormatInfo* format_info =
12304 target, level, xoffset, yoffset, width, height, format, image_size, data); 12518 GetCompressedFormatInfo(internal_format);
12519 if (format_info != nullptr && !format_info->support_check(*feature_info_)) {
12520 std::unique_ptr<uint8_t[]> decompressed_data = DecompressTextureData(
12521 state_, *format_info, width, height, 1, image_size, data);
12522 if (!decompressed_data) {
12523 MarkContextLost(error::kGuilty);
12524 group_->LoseContexts(error::kInnocent);
12525 return;
12526 }
12527 state_.PushTextureDecompressionUnpackState();
12528 glTexSubImage2D(target, level, xoffset, yoffset, width, height,
12529 format_info->decompressed_format,
12530 format_info->decompressed_type, decompressed_data.get());
12531 state_.RestoreUnpackState();
12532 } else {
12533 glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height,
12534 format, image_size, data);
12535 }
12305 12536
12306 // This may be a slow command. Exit command processing to allow for 12537 // This may be a slow command. Exit command processing to allow for
12307 // context preemption and GPU watchdog checks. 12538 // context preemption and GPU watchdog checks.
12308 ExitCommandProcessingEarly(); 12539 ExitCommandProcessingEarly();
12309 } 12540 }
12310 12541
12311 static void Clip( 12542 static void Clip(
12312 GLint start, GLint range, GLint sourceRange, 12543 GLint start, GLint range, GLint sourceRange,
12313 GLint* out_start, GLint* out_range) { 12544 GLint* out_start, GLint* out_range) {
12314 DCHECK(out_start); 12545 DCHECK(out_start);
(...skipping 2776 matching lines...) Expand 10 before | Expand all | Expand 10 after
15091 if (target == GL_TEXTURE_3D) 15322 if (target == GL_TEXTURE_3D)
15092 level_depth = std::max(1, level_depth >> 1); 15323 level_depth = std::max(1, level_depth >> 1);
15093 } 15324 }
15094 if (!estimated_size.IsValid() || 15325 if (!estimated_size.IsValid() ||
15095 !EnsureGPUMemoryAvailable(estimated_size.ValueOrDefault(0))) { 15326 !EnsureGPUMemoryAvailable(estimated_size.ValueOrDefault(0))) {
15096 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "out of memory"); 15327 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "out of memory");
15097 return; 15328 return;
15098 } 15329 }
15099 } 15330 }
15100 15331
15332 GLenum compatibility_internal_format = internal_format;
15333 const CompressedFormatInfo* format_info =
15334 GetCompressedFormatInfo(internal_format);
15335 if (format_info != nullptr && !format_info->support_check(*feature_info_)) {
15336 compatibility_internal_format = format_info->decompressed_internal_format;
15337 }
15338
15101 // TODO(zmo): We might need to emulate TexStorage using TexImage or 15339 // TODO(zmo): We might need to emulate TexStorage using TexImage or
15102 // CompressedTexImage on Mac OSX where we expose ES3 APIs when the underlying 15340 // 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. 15341 // driver is lower than 4.2 and ARB_texture_storage extension doesn't exist.
15104 if (dimension == ContextState::k2D) { 15342 if (dimension == ContextState::k2D) {
15105 glTexStorage2DEXT(target, levels, internal_format, width, height); 15343 glTexStorage2DEXT(target, levels, compatibility_internal_format, width,
15344 height);
15106 } else { 15345 } else {
15107 glTexStorage3D(target, levels, internal_format, width, height, depth); 15346 glTexStorage3D(target, levels, compatibility_internal_format, width, height,
15347 depth);
15108 } 15348 }
15109 15349
15110 { 15350 {
15111 GLsizei level_width = width; 15351 GLsizei level_width = width;
15112 GLsizei level_height = height; 15352 GLsizei level_height = height;
15113 GLsizei level_depth = depth; 15353 GLsizei level_depth = depth;
15114 GLenum adjusted_format = 15354 GLenum adjusted_format =
15115 feature_info_->IsES3Enabled() ? internal_format : format; 15355 feature_info_->IsES3Enabled() ? internal_format : format;
15116 for (int ii = 0; ii < levels; ++ii) { 15356 for (int ii = 0; ii < levels; ++ii) {
15117 if (target == GL_TEXTURE_CUBE_MAP) { 15357 if (target == GL_TEXTURE_CUBE_MAP) {
(...skipping 1988 matching lines...) Expand 10 before | Expand all | Expand 10 after
17106 } 17346 }
17107 17347
17108 // Include the auto-generated part of this file. We split this because it means 17348 // 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 17349 // 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. 17350 // instead of having to edit some template or the code generator.
17111 #include "base/macros.h" 17351 #include "base/macros.h"
17112 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" 17352 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
17113 17353
17114 } // namespace gles2 17354 } // namespace gles2
17115 } // namespace gpu 17355 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/feature_info.cc ('k') | gpu/gpu.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698