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

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: Check MapBuffer result. 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);
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
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
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
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
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
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
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
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
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