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 // A class to emulate GLES2 over command buffers. | 5 // A class to emulate GLES2 over command buffers. |
6 | 6 |
7 #include "gpu/command_buffer/client/gles2_implementation.h" | 7 #include "gpu/command_buffer/client/gles2_implementation.h" |
8 | 8 |
9 #include <GLES2/gl2.h> | 9 #include <GLES2/gl2.h> |
10 #include <GLES2/gl2ext.h> | 10 #include <GLES2/gl2ext.h> |
(...skipping 940 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
951 case GL_MINOR_VERSION: | 951 case GL_MINOR_VERSION: |
952 *params = capabilities_.minor_version; | 952 *params = capabilities_.minor_version; |
953 return true; | 953 return true; |
954 case GL_NUM_EXTENSIONS: | 954 case GL_NUM_EXTENSIONS: |
955 UpdateCachedExtensionsIfNeeded(); | 955 UpdateCachedExtensionsIfNeeded(); |
956 *params = cached_extensions_.size(); | 956 *params = cached_extensions_.size(); |
957 return true; | 957 return true; |
958 case GL_NUM_PROGRAM_BINARY_FORMATS: | 958 case GL_NUM_PROGRAM_BINARY_FORMATS: |
959 *params = capabilities_.num_program_binary_formats; | 959 *params = capabilities_.num_program_binary_formats; |
960 return true; | 960 return true; |
| 961 case GL_PACK_SKIP_PIXELS: |
| 962 *params = pack_skip_pixels_; |
| 963 return true; |
| 964 case GL_PACK_SKIP_ROWS: |
| 965 *params = pack_skip_rows_; |
| 966 return true; |
961 case GL_PIXEL_PACK_BUFFER_BINDING: | 967 case GL_PIXEL_PACK_BUFFER_BINDING: |
962 *params = bound_pixel_pack_buffer_; | 968 *params = bound_pixel_pack_buffer_; |
963 return true; | 969 return true; |
964 case GL_PIXEL_UNPACK_BUFFER_BINDING: | 970 case GL_PIXEL_UNPACK_BUFFER_BINDING: |
965 *params = bound_pixel_unpack_buffer_; | 971 *params = bound_pixel_unpack_buffer_; |
966 return true; | 972 return true; |
967 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: | 973 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: |
968 *params = bound_transform_feedback_buffer_; | 974 *params = bound_transform_feedback_buffer_; |
969 return true; | 975 return true; |
970 case GL_UNIFORM_BUFFER_BINDING: | 976 case GL_UNIFORM_BUFFER_BINDING: |
971 *params = bound_uniform_buffer_; | 977 *params = bound_uniform_buffer_; |
972 return true; | 978 return true; |
973 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: | 979 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: |
974 *params = capabilities_.uniform_buffer_offset_alignment; | 980 *params = capabilities_.uniform_buffer_offset_alignment; |
975 return true; | 981 return true; |
| 982 case GL_UNPACK_SKIP_IMAGES: |
| 983 *params = unpack_skip_images_; |
| 984 return true; |
| 985 case GL_UNPACK_SKIP_PIXELS: |
| 986 *params = unpack_skip_pixels_; |
| 987 return true; |
| 988 case GL_UNPACK_SKIP_ROWS: |
| 989 *params = unpack_skip_rows_; |
| 990 return true; |
976 | 991 |
977 // Non-cached ES3 parameters. | 992 // Non-cached ES3 parameters. |
978 case GL_DRAW_BUFFER0: | 993 case GL_DRAW_BUFFER0: |
979 case GL_DRAW_BUFFER1: | 994 case GL_DRAW_BUFFER1: |
980 case GL_DRAW_BUFFER2: | 995 case GL_DRAW_BUFFER2: |
981 case GL_DRAW_BUFFER3: | 996 case GL_DRAW_BUFFER3: |
982 case GL_DRAW_BUFFER4: | 997 case GL_DRAW_BUFFER4: |
983 case GL_DRAW_BUFFER5: | 998 case GL_DRAW_BUFFER5: |
984 case GL_DRAW_BUFFER6: | 999 case GL_DRAW_BUFFER6: |
985 case GL_DRAW_BUFFER7: | 1000 case GL_DRAW_BUFFER7: |
986 case GL_DRAW_BUFFER8: | 1001 case GL_DRAW_BUFFER8: |
987 case GL_DRAW_BUFFER9: | 1002 case GL_DRAW_BUFFER9: |
988 case GL_DRAW_BUFFER10: | 1003 case GL_DRAW_BUFFER10: |
989 case GL_DRAW_BUFFER11: | 1004 case GL_DRAW_BUFFER11: |
990 case GL_DRAW_BUFFER12: | 1005 case GL_DRAW_BUFFER12: |
991 case GL_DRAW_BUFFER13: | 1006 case GL_DRAW_BUFFER13: |
992 case GL_DRAW_BUFFER14: | 1007 case GL_DRAW_BUFFER14: |
993 case GL_DRAW_BUFFER15: | 1008 case GL_DRAW_BUFFER15: |
994 case GL_DRAW_FRAMEBUFFER_BINDING: | 1009 case GL_DRAW_FRAMEBUFFER_BINDING: |
995 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT: | 1010 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT: |
996 case GL_PACK_ROW_LENGTH: | 1011 case GL_PACK_ROW_LENGTH: |
997 case GL_PACK_SKIP_PIXELS: | |
998 case GL_PACK_SKIP_ROWS: | |
999 case GL_PRIMITIVE_RESTART_FIXED_INDEX: | 1012 case GL_PRIMITIVE_RESTART_FIXED_INDEX: |
1000 case GL_PROGRAM_BINARY_FORMATS: | 1013 case GL_PROGRAM_BINARY_FORMATS: |
1001 case GL_RASTERIZER_DISCARD: | 1014 case GL_RASTERIZER_DISCARD: |
1002 case GL_READ_BUFFER: | 1015 case GL_READ_BUFFER: |
1003 case GL_READ_FRAMEBUFFER_BINDING: | 1016 case GL_READ_FRAMEBUFFER_BINDING: |
1004 case GL_SAMPLER_BINDING: | 1017 case GL_SAMPLER_BINDING: |
1005 case GL_TEXTURE_BINDING_2D_ARRAY: | 1018 case GL_TEXTURE_BINDING_2D_ARRAY: |
1006 case GL_TEXTURE_BINDING_3D: | 1019 case GL_TEXTURE_BINDING_3D: |
1007 case GL_TRANSFORM_FEEDBACK_BINDING: | 1020 case GL_TRANSFORM_FEEDBACK_BINDING: |
1008 case GL_TRANSFORM_FEEDBACK_ACTIVE: | 1021 case GL_TRANSFORM_FEEDBACK_ACTIVE: |
1009 case GL_TRANSFORM_FEEDBACK_PAUSED: | 1022 case GL_TRANSFORM_FEEDBACK_PAUSED: |
1010 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: | 1023 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: |
1011 case GL_TRANSFORM_FEEDBACK_BUFFER_START: | 1024 case GL_TRANSFORM_FEEDBACK_BUFFER_START: |
1012 case GL_UNIFORM_BUFFER_SIZE: | 1025 case GL_UNIFORM_BUFFER_SIZE: |
1013 case GL_UNIFORM_BUFFER_START: | 1026 case GL_UNIFORM_BUFFER_START: |
1014 case GL_UNPACK_IMAGE_HEIGHT: | 1027 case GL_UNPACK_IMAGE_HEIGHT: |
1015 case GL_UNPACK_ROW_LENGTH: | 1028 case GL_UNPACK_ROW_LENGTH: |
1016 case GL_UNPACK_SKIP_IMAGES: | |
1017 case GL_UNPACK_SKIP_PIXELS: | |
1018 case GL_UNPACK_SKIP_ROWS: | |
1019 case GL_VERTEX_ARRAY_BINDING: | 1029 case GL_VERTEX_ARRAY_BINDING: |
1020 return false; | 1030 return false; |
1021 default: | 1031 default: |
1022 return false; | 1032 return false; |
1023 } | 1033 } |
1024 } | 1034 } |
1025 | 1035 |
1026 bool GLES2Implementation::GetBooleanvHelper(GLenum pname, GLboolean* params) { | 1036 bool GLES2Implementation::GetBooleanvHelper(GLenum pname, GLboolean* params) { |
1027 // TODO(gman): Make this handle pnames that return more than 1 value. | 1037 // TODO(gman): Make this handle pnames that return more than 1 value. |
1028 GLint value; | 1038 GLint value; |
(...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1757 buffer.offset() + shader_id_size, | 1767 buffer.offset() + shader_id_size, |
1758 length); | 1768 length); |
1759 CheckGLError(); | 1769 CheckGLError(); |
1760 } | 1770 } |
1761 | 1771 |
1762 void GLES2Implementation::PixelStorei(GLenum pname, GLint param) { | 1772 void GLES2Implementation::PixelStorei(GLenum pname, GLint param) { |
1763 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1773 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
1764 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glPixelStorei(" | 1774 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glPixelStorei(" |
1765 << GLES2Util::GetStringPixelStore(pname) << ", " | 1775 << GLES2Util::GetStringPixelStore(pname) << ", " |
1766 << param << ")"); | 1776 << param << ")"); |
| 1777 // We have to validate before caching these parameters because we use them |
| 1778 // to compute image sizes on the client side. |
| 1779 switch (pname) { |
| 1780 case GL_PACK_ALIGNMENT: |
| 1781 case GL_UNPACK_ALIGNMENT: |
| 1782 if (param != 1 && param != 2 && param != 4 && param != 8) { |
| 1783 SetGLError(GL_INVALID_VALUE, "glPixelStorei", "invalid param"); |
| 1784 return; |
| 1785 } |
| 1786 break; |
| 1787 case GL_PACK_ROW_LENGTH: |
| 1788 case GL_PACK_SKIP_PIXELS: |
| 1789 case GL_PACK_SKIP_ROWS: |
| 1790 case GL_UNPACK_IMAGE_HEIGHT: |
| 1791 case GL_UNPACK_SKIP_IMAGES: |
| 1792 if (capabilities_.major_version < 3) { |
| 1793 SetGLError(GL_INVALID_ENUM, "glPixelStorei", "invalid pname"); |
| 1794 return; |
| 1795 } |
| 1796 if (param < 0) { |
| 1797 SetGLError(GL_INVALID_VALUE, "glPixelStorei", "invalid param"); |
| 1798 return; |
| 1799 } |
| 1800 break; |
| 1801 case GL_UNPACK_ROW_LENGTH: |
| 1802 case GL_UNPACK_SKIP_ROWS: |
| 1803 case GL_UNPACK_SKIP_PIXELS: |
| 1804 // These parameters are always enabled in ES2 by EXT_unpack_subimage. |
| 1805 if (param < 0) { |
| 1806 SetGLError(GL_INVALID_VALUE, "glPixelStorei", "invalid param"); |
| 1807 return; |
| 1808 } |
| 1809 break; |
| 1810 default: |
| 1811 SetGLError(GL_INVALID_ENUM, "glPixelStorei", "invalid pname"); |
| 1812 return; |
| 1813 } |
| 1814 // Do not send SKIP parameters to the service side. |
| 1815 // Handle them on the client side. |
1767 switch (pname) { | 1816 switch (pname) { |
1768 case GL_PACK_ALIGNMENT: | 1817 case GL_PACK_ALIGNMENT: |
1769 pack_alignment_ = param; | 1818 pack_alignment_ = param; |
1770 break; | 1819 break; |
1771 case GL_PACK_ROW_LENGTH: | 1820 case GL_PACK_ROW_LENGTH: |
1772 pack_row_length_ = param; | 1821 pack_row_length_ = param; |
1773 break; | 1822 break; |
1774 case GL_PACK_SKIP_PIXELS: | 1823 case GL_PACK_SKIP_PIXELS: |
1775 pack_skip_pixels_ = param; | 1824 pack_skip_pixels_ = param; |
1776 break; | 1825 return; |
1777 case GL_PACK_SKIP_ROWS: | 1826 case GL_PACK_SKIP_ROWS: |
1778 pack_skip_rows_ = param; | 1827 pack_skip_rows_ = param; |
1779 break; | 1828 return; |
1780 case GL_UNPACK_ALIGNMENT: | 1829 case GL_UNPACK_ALIGNMENT: |
1781 unpack_alignment_ = param; | 1830 unpack_alignment_ = param; |
1782 break; | 1831 break; |
1783 case GL_UNPACK_ROW_LENGTH_EXT: | 1832 case GL_UNPACK_ROW_LENGTH: |
1784 unpack_row_length_ = param; | 1833 unpack_row_length_ = param; |
| 1834 if (capabilities_.major_version < 3) { |
| 1835 // In ES2 with EXT_unpack_subimage, it's handled on the client side |
| 1836 // and there is no need to send it to the service side. |
| 1837 return; |
| 1838 } |
1785 break; | 1839 break; |
1786 case GL_UNPACK_IMAGE_HEIGHT: | 1840 case GL_UNPACK_IMAGE_HEIGHT: |
1787 unpack_image_height_ = param; | 1841 unpack_image_height_ = param; |
1788 break; | 1842 break; |
1789 case GL_UNPACK_SKIP_ROWS_EXT: | 1843 case GL_UNPACK_SKIP_ROWS: |
1790 unpack_skip_rows_ = param; | 1844 unpack_skip_rows_ = param; |
1791 break; | 1845 return; |
1792 case GL_UNPACK_SKIP_PIXELS_EXT: | 1846 case GL_UNPACK_SKIP_PIXELS: |
1793 unpack_skip_pixels_ = param; | 1847 unpack_skip_pixels_ = param; |
1794 break; | 1848 return; |
1795 case GL_UNPACK_SKIP_IMAGES: | 1849 case GL_UNPACK_SKIP_IMAGES: |
1796 unpack_skip_images_ = param; | 1850 unpack_skip_images_ = param; |
1797 break; | 1851 return; |
1798 default: | 1852 default: |
| 1853 NOTREACHED(); |
1799 break; | 1854 break; |
1800 } | 1855 } |
1801 helper_->PixelStorei(pname, param); | 1856 helper_->PixelStorei(pname, param); |
1802 CheckGLError(); | 1857 CheckGLError(); |
1803 } | 1858 } |
1804 | 1859 |
1805 void GLES2Implementation::VertexAttribIPointer( | 1860 void GLES2Implementation::VertexAttribIPointer( |
1806 GLuint index, GLint size, GLenum type, GLsizei stride, const void* ptr) { | 1861 GLuint index, GLint size, GLenum type, GLsizei stride, const void* ptr) { |
1807 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1862 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
1808 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribIPointer(" | 1863 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribIPointer(" |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2076 DCHECK(buffer_id); | 2131 DCHECK(buffer_id); |
2077 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); | 2132 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); |
2078 if (!buffer) { | 2133 if (!buffer) { |
2079 SetGLError(GL_INVALID_OPERATION, function_name, "invalid buffer"); | 2134 SetGLError(GL_INVALID_OPERATION, function_name, "invalid buffer"); |
2080 return NULL; | 2135 return NULL; |
2081 } | 2136 } |
2082 if (buffer->mapped()) { | 2137 if (buffer->mapped()) { |
2083 SetGLError(GL_INVALID_OPERATION, function_name, "buffer mapped"); | 2138 SetGLError(GL_INVALID_OPERATION, function_name, "buffer mapped"); |
2084 return NULL; | 2139 return NULL; |
2085 } | 2140 } |
2086 if ((buffer->size() - offset) < static_cast<GLuint>(size)) { | 2141 base::CheckedNumeric<uint32_t> buffer_offset = buffer->shm_offset(); |
| 2142 buffer_offset += offset; |
| 2143 if (!buffer_offset.IsValid()) { |
| 2144 SetGLError(GL_INVALID_VALUE, function_name, "offset to large"); |
| 2145 return NULL; |
| 2146 } |
| 2147 base::CheckedNumeric<uint32_t> required_size = offset; |
| 2148 required_size += size; |
| 2149 if (!required_size.IsValid() || |
| 2150 buffer->size() < required_size.ValueOrDefault(0)) { |
2087 SetGLError(GL_INVALID_VALUE, function_name, "unpack size to large"); | 2151 SetGLError(GL_INVALID_VALUE, function_name, "unpack size to large"); |
2088 return NULL; | 2152 return NULL; |
2089 } | 2153 } |
2090 return buffer; | 2154 return buffer; |
2091 } | 2155 } |
2092 | 2156 |
2093 void GLES2Implementation::CompressedTexImage2D( | 2157 void GLES2Implementation::CompressedTexImage2D( |
2094 GLenum target, GLint level, GLenum internalformat, GLsizei width, | 2158 GLenum target, GLint level, GLenum internalformat, GLsizei width, |
2095 GLsizei height, GLint border, GLsizei image_size, const void* data) { | 2159 GLsizei height, GLint border, GLsizei image_size, const void* data) { |
2096 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 2160 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2270 uint32_t height, | 2334 uint32_t height, |
2271 uint32_t unpadded_row_size, | 2335 uint32_t unpadded_row_size, |
2272 uint32_t pixels_padded_row_size, | 2336 uint32_t pixels_padded_row_size, |
2273 void* buffer, | 2337 void* buffer, |
2274 uint32_t buffer_padded_row_size) { | 2338 uint32_t buffer_padded_row_size) { |
2275 if (height == 0) | 2339 if (height == 0) |
2276 return; | 2340 return; |
2277 const int8_t* source = static_cast<const int8_t*>(pixels); | 2341 const int8_t* source = static_cast<const int8_t*>(pixels); |
2278 int8_t* dest = static_cast<int8_t*>(buffer); | 2342 int8_t* dest = static_cast<int8_t*>(buffer); |
2279 if (pixels_padded_row_size != buffer_padded_row_size) { | 2343 if (pixels_padded_row_size != buffer_padded_row_size) { |
2280 // the last row is copied unpadded at the end | 2344 for (uint32_t ii = 0; ii < height; ++ii) { |
2281 for (; height > 1; --height) { | 2345 memcpy(dest, source, unpadded_row_size); |
2282 memcpy(dest, source, buffer_padded_row_size); | |
2283 dest += buffer_padded_row_size; | 2346 dest += buffer_padded_row_size; |
2284 source += pixels_padded_row_size; | 2347 source += pixels_padded_row_size; |
2285 } | 2348 } |
2286 memcpy(dest, source, unpadded_row_size); | |
2287 } else { | 2349 } else { |
2288 uint32_t size = (height - 1) * pixels_padded_row_size + unpadded_row_size; | 2350 uint32_t size = (height - 1) * pixels_padded_row_size + unpadded_row_size; |
2289 memcpy(dest, source, size); | 2351 memcpy(dest, source, size); |
2290 } | 2352 } |
2291 } | 2353 } |
2292 | 2354 |
2293 } // anonymous namespace | 2355 } // anonymous namespace |
2294 | 2356 |
| 2357 PixelStoreParams GLES2Implementation::GetUnpackParameters(Dimension dimension) { |
| 2358 PixelStoreParams params; |
| 2359 params.alignment = unpack_alignment_; |
| 2360 params.row_length = unpack_row_length_; |
| 2361 params.skip_pixels = unpack_skip_pixels_; |
| 2362 params.skip_rows = unpack_skip_rows_; |
| 2363 if (dimension == k3D) { |
| 2364 params.image_height = unpack_image_height_; |
| 2365 params.skip_images = unpack_skip_images_; |
| 2366 } |
| 2367 return params; |
| 2368 } |
| 2369 |
2295 void GLES2Implementation::TexImage2D( | 2370 void GLES2Implementation::TexImage2D( |
2296 GLenum target, GLint level, GLint internalformat, GLsizei width, | 2371 GLenum target, GLint level, GLint internalformat, GLsizei width, |
2297 GLsizei height, GLint border, GLenum format, GLenum type, | 2372 GLsizei height, GLint border, GLenum format, GLenum type, |
2298 const void* pixels) { | 2373 const void* pixels) { |
2299 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 2374 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
2300 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexImage2D(" | 2375 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexImage2D(" |
2301 << GLES2Util::GetStringTextureTarget(target) << ", " | 2376 << GLES2Util::GetStringTextureTarget(target) << ", " |
2302 << level << ", " | 2377 << level << ", " |
2303 << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " | 2378 << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " |
2304 << width << ", " << height << ", " << border << ", " | 2379 << width << ", " << height << ", " << border << ", " |
2305 << GLES2Util::GetStringTextureFormat(format) << ", " | 2380 << GLES2Util::GetStringTextureFormat(format) << ", " |
2306 << GLES2Util::GetStringPixelType(type) << ", " | 2381 << GLES2Util::GetStringPixelType(type) << ", " |
2307 << static_cast<const void*>(pixels) << ")"); | 2382 << static_cast<const void*>(pixels) << ")"); |
2308 if (level < 0 || height < 0 || width < 0) { | 2383 if (level < 0 || height < 0 || width < 0) { |
2309 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "dimension < 0"); | 2384 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "dimension < 0"); |
2310 return; | 2385 return; |
2311 } | 2386 } |
2312 if (border != 0) { | 2387 if (border != 0) { |
2313 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "border != 0"); | 2388 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "border != 0"); |
2314 return; | 2389 return; |
2315 } | 2390 } |
2316 uint32_t size; | 2391 uint32_t size; |
2317 uint32_t unpadded_row_size; | 2392 uint32_t unpadded_row_size; |
2318 uint32_t padded_row_size; | 2393 uint32_t padded_row_size; |
2319 if (!GLES2Util::ComputeImageDataSizes( | 2394 uint32_t skip_size; |
2320 width, height, 1, format, type, unpack_alignment_, &size, | 2395 PixelStoreParams params = GetUnpackParameters(k2D); |
2321 &unpadded_row_size, &padded_row_size)) { | 2396 if (!GLES2Util::ComputeImageDataSizesES3(width, height, 1, |
| 2397 format, type, |
| 2398 params, |
| 2399 &size, |
| 2400 &unpadded_row_size, |
| 2401 &padded_row_size, |
| 2402 &skip_size, |
| 2403 nullptr)) { |
2322 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); | 2404 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); |
2323 return; | 2405 return; |
2324 } | 2406 } |
2325 | 2407 |
| 2408 if (bound_pixel_unpack_buffer_) { |
| 2409 base::CheckedNumeric<uint32_t> offset = ToGLuint(pixels); |
| 2410 offset += skip_size; |
| 2411 if (!offset.IsValid()) { |
| 2412 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "skip size too large"); |
| 2413 return; |
| 2414 } |
| 2415 helper_->TexImage2D( |
| 2416 target, level, internalformat, width, height, format, type, |
| 2417 0, offset.ValueOrDefault(0)); |
| 2418 CheckGLError(); |
| 2419 return; |
| 2420 } |
| 2421 |
2326 // If there's a pixel unpack buffer bound use it when issuing TexImage2D. | 2422 // If there's a pixel unpack buffer bound use it when issuing TexImage2D. |
2327 if (bound_pixel_unpack_transfer_buffer_id_) { | 2423 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 2424 if (unpack_row_length_ > 0 || unpack_image_height_ > 0 || |
| 2425 unpack_skip_pixels_ > 0 || unpack_skip_rows_ > 0 || |
| 2426 unpack_skip_images_ > 0) { |
| 2427 SetGLError(GL_INVALID_OPERATION, "glTexImage2D", |
| 2428 "No ES3 pack parameters with pixel unpack transfer buffer."); |
| 2429 return; |
| 2430 } |
| 2431 DCHECK_EQ(0u, skip_size); |
2328 GLuint offset = ToGLuint(pixels); | 2432 GLuint offset = ToGLuint(pixels); |
2329 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 2433 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
2330 bound_pixel_unpack_transfer_buffer_id_, | 2434 bound_pixel_unpack_transfer_buffer_id_, "glTexImage2D", offset, size); |
2331 "glTexImage2D", offset, size); | |
2332 if (buffer && buffer->shm_id() != -1) { | 2435 if (buffer && buffer->shm_id() != -1) { |
2333 helper_->TexImage2D( | 2436 helper_->TexImage2D( |
2334 target, level, internalformat, width, height, format, type, | 2437 target, level, internalformat, width, height, format, type, |
2335 buffer->shm_id(), buffer->shm_offset() + offset); | 2438 buffer->shm_id(), buffer->shm_offset() + offset); |
2336 buffer->set_last_usage_token(helper_->InsertToken()); | 2439 buffer->set_last_usage_token(helper_->InsertToken()); |
2337 CheckGLError(); | 2440 CheckGLError(); |
2338 } | 2441 } |
2339 return; | 2442 return; |
2340 } | 2443 } |
2341 | 2444 |
2342 // If there's no data just issue TexImage2D | 2445 // If there's no data just issue TexImage2D |
2343 if (!pixels) { | 2446 if (!pixels || width == 0 || height == 0) { |
2344 helper_->TexImage2D( | 2447 helper_->TexImage2D( |
2345 target, level, internalformat, width, height, format, type, | 2448 target, level, internalformat, width, height, format, type, 0, 0); |
2346 0, 0); | |
2347 CheckGLError(); | 2449 CheckGLError(); |
2348 return; | 2450 return; |
2349 } | 2451 } |
2350 | 2452 |
2351 // compute the advance bytes per row for the src pixels | 2453 // Compute the advance bytes per row on the service side. |
2352 uint32_t src_padded_row_size; | 2454 // Note |size| is recomputed here if needed. |
2353 if (unpack_row_length_ > 0) { | 2455 uint32_t service_padded_row_size; |
2354 if (!GLES2Util::ComputeImagePaddedRowSize( | 2456 if (unpack_row_length_ > 0 && unpack_row_length_ != width) { |
2355 unpack_row_length_, format, type, unpack_alignment_, | 2457 // All parameters have been applied to the data that are sent to the |
2356 &src_padded_row_size)) { | 2458 // service side except UNPACK_ALIGNMENT. |
2357 SetGLError( | 2459 PixelStoreParams service_params; |
2358 GL_INVALID_VALUE, "glTexImage2D", "unpack row length too large"); | 2460 service_params.alignment = unpack_alignment_; |
| 2461 if (!GLES2Util::ComputeImageDataSizesES3(width, height, 1, |
| 2462 format, type, |
| 2463 service_params, |
| 2464 &size, |
| 2465 nullptr, |
| 2466 &service_padded_row_size, |
| 2467 nullptr, |
| 2468 nullptr)) { |
| 2469 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); |
2359 return; | 2470 return; |
2360 } | 2471 } |
2361 } else { | 2472 } else { |
2362 src_padded_row_size = padded_row_size; | 2473 service_padded_row_size = padded_row_size; |
2363 } | 2474 } |
2364 | 2475 |
2365 // advance pixels pointer past the skip rows and skip pixels | 2476 // advance pixels pointer past the skip rows and skip pixels |
2366 pixels = reinterpret_cast<const int8_t*>(pixels) + | 2477 pixels = reinterpret_cast<const int8_t*>(pixels) + skip_size; |
2367 unpack_skip_rows_ * src_padded_row_size; | |
2368 if (unpack_skip_pixels_) { | |
2369 uint32_t group_size = GLES2Util::ComputeImageGroupSize(format, type); | |
2370 pixels = reinterpret_cast<const int8_t*>(pixels) + | |
2371 unpack_skip_pixels_ * group_size; | |
2372 } | |
2373 | 2478 |
2374 // Check if we can send it all at once. | 2479 // Check if we can send it all at once. |
2375 int32_t shm_id = 0; | 2480 int32_t shm_id = 0; |
2376 uint32_t shm_offset = 0; | 2481 uint32_t shm_offset = 0; |
2377 void* buffer_pointer = nullptr; | 2482 void* buffer_pointer = nullptr; |
2378 | 2483 |
2379 ScopedTransferBufferPtr transfer_alloc(size, helper_, transfer_buffer_); | 2484 ScopedTransferBufferPtr transfer_alloc(size, helper_, transfer_buffer_); |
2380 ScopedMappedMemoryPtr mapped_alloc(0, helper_, mapped_memory_.get()); | 2485 ScopedMappedMemoryPtr mapped_alloc(0, helper_, mapped_memory_.get()); |
2381 | 2486 |
2382 if (transfer_alloc.valid() && transfer_alloc.size() >= size) { | 2487 if (transfer_alloc.valid() && transfer_alloc.size() >= size) { |
2383 shm_id = transfer_alloc.shm_id(); | 2488 shm_id = transfer_alloc.shm_id(); |
2384 shm_offset = transfer_alloc.offset(); | 2489 shm_offset = transfer_alloc.offset(); |
2385 buffer_pointer = transfer_alloc.address(); | 2490 buffer_pointer = transfer_alloc.address(); |
2386 } else if (size < max_extra_transfer_buffer_size_) { | 2491 } else if (size < max_extra_transfer_buffer_size_) { |
2387 mapped_alloc.Reset(size); | 2492 mapped_alloc.Reset(size); |
2388 if (mapped_alloc.valid()) { | 2493 if (mapped_alloc.valid()) { |
2389 transfer_alloc.Discard(); | 2494 transfer_alloc.Discard(); |
2390 | 2495 |
2391 mapped_alloc.SetFlushAfterRelease(true); | 2496 mapped_alloc.SetFlushAfterRelease(true); |
2392 shm_id = mapped_alloc.shm_id(); | 2497 shm_id = mapped_alloc.shm_id(); |
2393 shm_offset = mapped_alloc.offset(); | 2498 shm_offset = mapped_alloc.offset(); |
2394 buffer_pointer = mapped_alloc.address(); | 2499 buffer_pointer = mapped_alloc.address(); |
2395 } | 2500 } |
2396 } | 2501 } |
2397 | 2502 |
2398 if (buffer_pointer) { | 2503 if (buffer_pointer) { |
2399 CopyRectToBuffer( | 2504 CopyRectToBuffer( |
2400 pixels, height, unpadded_row_size, src_padded_row_size, | 2505 pixels, height, unpadded_row_size, padded_row_size, |
2401 buffer_pointer, padded_row_size); | 2506 buffer_pointer, service_padded_row_size); |
2402 helper_->TexImage2D( | 2507 helper_->TexImage2D( |
2403 target, level, internalformat, width, height, format, type, | 2508 target, level, internalformat, width, height, format, type, |
2404 shm_id, shm_offset); | 2509 shm_id, shm_offset); |
2405 CheckGLError(); | 2510 CheckGLError(); |
2406 return; | 2511 return; |
2407 } | 2512 } |
2408 | 2513 |
2409 // No, so send it using TexSubImage2D. | 2514 // No, so send it using TexSubImage2D. |
2410 helper_->TexImage2D( | 2515 helper_->TexImage2D( |
2411 target, level, internalformat, width, height, format, type, | 2516 target, level, internalformat, width, height, format, type, |
2412 0, 0); | 2517 0, 0); |
2413 TexSubImage2DImpl( | 2518 TexSubImage2DImpl( |
2414 target, level, 0, 0, width, height, format, type, unpadded_row_size, | 2519 target, level, 0, 0, width, height, format, type, unpadded_row_size, |
2415 pixels, src_padded_row_size, GL_TRUE, &transfer_alloc, padded_row_size); | 2520 pixels, padded_row_size, GL_TRUE, &transfer_alloc, |
| 2521 service_padded_row_size); |
2416 CheckGLError(); | 2522 CheckGLError(); |
2417 } | 2523 } |
2418 | 2524 |
2419 void GLES2Implementation::TexImage3D( | 2525 void GLES2Implementation::TexImage3D( |
2420 GLenum target, GLint level, GLint internalformat, GLsizei width, | 2526 GLenum target, GLint level, GLint internalformat, GLsizei width, |
2421 GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, | 2527 GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, |
2422 const void* pixels) { | 2528 const void* pixels) { |
2423 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 2529 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
2424 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexImage3D(" | 2530 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexImage3D(" |
2425 << GLES2Util::GetStringTextureTarget(target) << ", " | 2531 << GLES2Util::GetStringTextureTarget(target) << ", " |
2426 << level << ", " | 2532 << level << ", " |
2427 << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " | 2533 << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " |
2428 << width << ", " << height << ", " << depth << ", " << border << ", " | 2534 << width << ", " << height << ", " << depth << ", " << border << ", " |
2429 << GLES2Util::GetStringTextureFormat(format) << ", " | 2535 << GLES2Util::GetStringTextureFormat(format) << ", " |
2430 << GLES2Util::GetStringPixelType(type) << ", " | 2536 << GLES2Util::GetStringPixelType(type) << ", " |
2431 << static_cast<const void*>(pixels) << ")"); | 2537 << static_cast<const void*>(pixels) << ")"); |
2432 if (level < 0 || height < 0 || width < 0 || depth < 0) { | 2538 if (level < 0 || height < 0 || width < 0 || depth < 0) { |
2433 SetGLError(GL_INVALID_VALUE, "glTexImage3D", "dimension < 0"); | 2539 SetGLError(GL_INVALID_VALUE, "glTexImage3D", "dimension < 0"); |
2434 return; | 2540 return; |
2435 } | 2541 } |
2436 if (border != 0) { | 2542 if (border != 0) { |
2437 SetGLError(GL_INVALID_VALUE, "glTexImage3D", "border != 0"); | 2543 SetGLError(GL_INVALID_VALUE, "glTexImage3D", "border != 0"); |
2438 return; | 2544 return; |
2439 } | 2545 } |
| 2546 |
2440 uint32_t size; | 2547 uint32_t size; |
2441 uint32_t unpadded_row_size; | 2548 uint32_t unpadded_row_size; |
2442 uint32_t padded_row_size; | 2549 uint32_t padded_row_size; |
2443 if (!GLES2Util::ComputeImageDataSizes( | 2550 uint32_t skip_size; |
2444 width, height, depth, format, type, unpack_alignment_, &size, | 2551 PixelStoreParams params = GetUnpackParameters(k3D); |
2445 &unpadded_row_size, &padded_row_size)) { | 2552 if (!GLES2Util::ComputeImageDataSizesES3(width, height, depth, |
| 2553 format, type, |
| 2554 params, |
| 2555 &size, |
| 2556 &unpadded_row_size, |
| 2557 &padded_row_size, |
| 2558 &skip_size, |
| 2559 nullptr)) { |
2446 SetGLError(GL_INVALID_VALUE, "glTexImage3D", "image size too large"); | 2560 SetGLError(GL_INVALID_VALUE, "glTexImage3D", "image size too large"); |
2447 return; | 2561 return; |
2448 } | 2562 } |
2449 | 2563 |
| 2564 if (bound_pixel_unpack_buffer_) { |
| 2565 base::CheckedNumeric<uint32_t> offset = ToGLuint(pixels); |
| 2566 offset += skip_size; |
| 2567 if (!offset.IsValid()) { |
| 2568 SetGLError(GL_INVALID_VALUE, "glTexImage3D", "skip size too large"); |
| 2569 return; |
| 2570 } |
| 2571 helper_->TexImage3D( |
| 2572 target, level, internalformat, width, height, depth, format, type, |
| 2573 0, offset.ValueOrDefault(0)); |
| 2574 CheckGLError(); |
| 2575 return; |
| 2576 } |
| 2577 |
2450 // If there's a pixel unpack buffer bound use it when issuing TexImage3D. | 2578 // If there's a pixel unpack buffer bound use it when issuing TexImage3D. |
2451 if (bound_pixel_unpack_transfer_buffer_id_) { | 2579 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 2580 if (unpack_row_length_ > 0 || unpack_image_height_ > 0 || |
| 2581 unpack_skip_pixels_ > 0 || unpack_skip_rows_ > 0 || |
| 2582 unpack_skip_images_ > 0) { |
| 2583 SetGLError(GL_INVALID_OPERATION, "glTexImage3D", |
| 2584 "No ES3 pack parameters with pixel unpack transfer buffer."); |
| 2585 return; |
| 2586 } |
| 2587 DCHECK_EQ(0u, skip_size); |
2452 GLuint offset = ToGLuint(pixels); | 2588 GLuint offset = ToGLuint(pixels); |
2453 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 2589 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
2454 bound_pixel_unpack_transfer_buffer_id_, | 2590 bound_pixel_unpack_transfer_buffer_id_, "glTexImage3D", offset, size); |
2455 "glTexImage3D", offset, size); | |
2456 if (buffer && buffer->shm_id() != -1) { | 2591 if (buffer && buffer->shm_id() != -1) { |
2457 helper_->TexImage3D( | 2592 helper_->TexImage3D( |
2458 target, level, internalformat, width, height, depth, format, type, | 2593 target, level, internalformat, width, height, depth, format, type, |
2459 buffer->shm_id(), buffer->shm_offset() + offset); | 2594 buffer->shm_id(), buffer->shm_offset() + offset); |
2460 buffer->set_last_usage_token(helper_->InsertToken()); | 2595 buffer->set_last_usage_token(helper_->InsertToken()); |
2461 CheckGLError(); | 2596 CheckGLError(); |
2462 } | 2597 } |
2463 return; | 2598 return; |
2464 } | 2599 } |
2465 | 2600 |
2466 // If there's no data just issue TexImage3D | 2601 // If there's no data just issue TexImage3D |
2467 if (!pixels) { | 2602 if (!pixels || width == 0 || height == 0 || depth == 0) { |
2468 helper_->TexImage3D( | 2603 helper_->TexImage3D( |
2469 target, level, internalformat, width, height, depth, format, type, | 2604 target, level, internalformat, width, height, depth, format, type, |
2470 0, 0); | 2605 0, 0); |
2471 CheckGLError(); | 2606 CheckGLError(); |
2472 return; | 2607 return; |
2473 } | 2608 } |
2474 | 2609 |
2475 // compute the advance bytes per row for the src pixels | 2610 // Compute the advance bytes per row on the service side. |
2476 uint32_t src_padded_row_size; | 2611 // Note |size| is recomputed here if needed. |
2477 if (unpack_row_length_ > 0) { | 2612 uint32_t service_padded_row_size; |
2478 if (!GLES2Util::ComputeImagePaddedRowSize( | 2613 if ((unpack_row_length_ > 0 && unpack_row_length_ != width) || |
2479 unpack_row_length_, format, type, unpack_alignment_, | 2614 (unpack_image_height_ > 0 && unpack_image_height_ != height)) { |
2480 &src_padded_row_size)) { | 2615 // All parameters have been applied to the data that are sent to the |
2481 SetGLError( | 2616 // service side except UNPACK_ALIGNMENT. |
2482 GL_INVALID_VALUE, "glTexImage3D", "unpack row length too large"); | 2617 PixelStoreParams service_params; |
| 2618 service_params.alignment = unpack_alignment_; |
| 2619 if (!GLES2Util::ComputeImageDataSizesES3(width, height, depth, |
| 2620 format, type, |
| 2621 service_params, |
| 2622 &size, |
| 2623 nullptr, |
| 2624 &service_padded_row_size, |
| 2625 nullptr, |
| 2626 nullptr)) { |
| 2627 SetGLError(GL_INVALID_VALUE, "glTexImage3D", "image size too large"); |
2483 return; | 2628 return; |
2484 } | 2629 } |
2485 } else { | 2630 } else { |
2486 src_padded_row_size = padded_row_size; | 2631 service_padded_row_size = padded_row_size; |
2487 } | 2632 } |
2488 uint32_t src_height = | 2633 uint32_t src_height = |
2489 unpack_image_height_ > 0 ? unpack_image_height_ : height; | 2634 unpack_image_height_ > 0 ? unpack_image_height_ : height; |
2490 | 2635 |
2491 // advance pixels pointer past the skip images/rows/pixels | 2636 // advance pixels pointer past the skip images/rows/pixels |
2492 pixels = reinterpret_cast<const int8_t*>(pixels) + | 2637 pixels = reinterpret_cast<const int8_t*>(pixels) + skip_size; |
2493 unpack_skip_images_ * src_padded_row_size * src_height + | |
2494 unpack_skip_rows_ * src_padded_row_size; | |
2495 if (unpack_skip_pixels_) { | |
2496 uint32_t group_size = GLES2Util::ComputeImageGroupSize(format, type); | |
2497 pixels = reinterpret_cast<const int8_t*>(pixels) + | |
2498 unpack_skip_pixels_ * group_size; | |
2499 } | |
2500 | 2638 |
2501 // Check if we can send it all at once. | 2639 // Check if we can send it all at once. |
2502 int32_t shm_id = 0; | 2640 int32_t shm_id = 0; |
2503 uint32_t shm_offset = 0; | 2641 uint32_t shm_offset = 0; |
2504 void* buffer_pointer = nullptr; | 2642 void* buffer_pointer = nullptr; |
2505 | 2643 |
2506 ScopedTransferBufferPtr transfer_alloc(size, helper_, transfer_buffer_); | 2644 ScopedTransferBufferPtr transfer_alloc(size, helper_, transfer_buffer_); |
2507 ScopedMappedMemoryPtr mapped_alloc(0, helper_, mapped_memory_.get()); | 2645 ScopedMappedMemoryPtr mapped_alloc(0, helper_, mapped_memory_.get()); |
2508 | 2646 |
2509 if (transfer_alloc.valid() && transfer_alloc.size() >= size) { | 2647 if (transfer_alloc.valid() && transfer_alloc.size() >= size) { |
2510 shm_id = transfer_alloc.shm_id(); | 2648 shm_id = transfer_alloc.shm_id(); |
2511 shm_offset = transfer_alloc.offset(); | 2649 shm_offset = transfer_alloc.offset(); |
2512 buffer_pointer = transfer_alloc.address(); | 2650 buffer_pointer = transfer_alloc.address(); |
2513 } else if (size < max_extra_transfer_buffer_size_) { | 2651 } else if (size < max_extra_transfer_buffer_size_) { |
2514 mapped_alloc.Reset(size); | 2652 mapped_alloc.Reset(size); |
2515 if (mapped_alloc.valid()) { | 2653 if (mapped_alloc.valid()) { |
2516 transfer_alloc.Discard(); | 2654 transfer_alloc.Discard(); |
2517 | 2655 |
2518 mapped_alloc.SetFlushAfterRelease(true); | 2656 mapped_alloc.SetFlushAfterRelease(true); |
2519 shm_id = mapped_alloc.shm_id(); | 2657 shm_id = mapped_alloc.shm_id(); |
2520 shm_offset = mapped_alloc.offset(); | 2658 shm_offset = mapped_alloc.offset(); |
2521 buffer_pointer = mapped_alloc.address(); | 2659 buffer_pointer = mapped_alloc.address(); |
2522 } | 2660 } |
2523 } | 2661 } |
2524 | 2662 |
2525 if (buffer_pointer) { | 2663 if (buffer_pointer) { |
2526 for (GLsizei z = 0; z < depth; ++z) { | 2664 for (GLsizei z = 0; z < depth; ++z) { |
2527 // Only the last row of the last image is unpadded. | |
2528 uint32_t src_unpadded_row_size = | |
2529 (z == depth - 1) ? unpadded_row_size : src_padded_row_size; | |
2530 CopyRectToBuffer( | 2665 CopyRectToBuffer( |
2531 pixels, height, src_unpadded_row_size, src_padded_row_size, | 2666 pixels, height, unpadded_row_size, padded_row_size, |
2532 buffer_pointer, padded_row_size); | 2667 buffer_pointer, service_padded_row_size); |
2533 pixels = reinterpret_cast<const int8_t*>(pixels) + | 2668 pixels = reinterpret_cast<const int8_t*>(pixels) + |
2534 src_padded_row_size * src_height; | 2669 padded_row_size * src_height; |
2535 buffer_pointer = | 2670 buffer_pointer = reinterpret_cast<int8_t*>(buffer_pointer) + |
2536 reinterpret_cast<int8_t*>(buffer_pointer) + padded_row_size * height; | 2671 service_padded_row_size * height; |
2537 } | 2672 } |
2538 helper_->TexImage3D( | 2673 helper_->TexImage3D( |
2539 target, level, internalformat, width, height, depth, format, type, | 2674 target, level, internalformat, width, height, depth, format, type, |
2540 shm_id, shm_offset); | 2675 shm_id, shm_offset); |
2541 CheckGLError(); | 2676 CheckGLError(); |
2542 return; | 2677 return; |
2543 } | 2678 } |
2544 | 2679 |
2545 // No, so send it using TexSubImage3D. | 2680 // No, so send it using TexSubImage3D. |
2546 helper_->TexImage3D( | 2681 helper_->TexImage3D( |
2547 target, level, internalformat, width, height, depth, format, type, | 2682 target, level, internalformat, width, height, depth, format, type, |
2548 0, 0); | 2683 0, 0); |
2549 TexSubImage3DImpl( | 2684 TexSubImage3DImpl( |
2550 target, level, 0, 0, 0, width, height, depth, format, type, | 2685 target, level, 0, 0, 0, width, height, depth, format, type, |
2551 unpadded_row_size, pixels, src_padded_row_size, GL_TRUE, &transfer_alloc, | 2686 unpadded_row_size, pixels, padded_row_size, GL_TRUE, &transfer_alloc, |
2552 padded_row_size); | 2687 service_padded_row_size); |
2553 CheckGLError(); | 2688 CheckGLError(); |
2554 } | 2689 } |
2555 | 2690 |
2556 void GLES2Implementation::TexSubImage2D( | 2691 void GLES2Implementation::TexSubImage2D( |
2557 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, | 2692 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, |
2558 GLsizei height, GLenum format, GLenum type, const void* pixels) { | 2693 GLsizei height, GLenum format, GLenum type, const void* pixels) { |
2559 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 2694 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
2560 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexSubImage2D(" | 2695 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexSubImage2D(" |
2561 << GLES2Util::GetStringTextureTarget(target) << ", " | 2696 << GLES2Util::GetStringTextureTarget(target) << ", " |
2562 << level << ", " | 2697 << level << ", " |
2563 << xoffset << ", " << yoffset << ", " | 2698 << xoffset << ", " << yoffset << ", " |
2564 << width << ", " << height << ", " | 2699 << width << ", " << height << ", " |
2565 << GLES2Util::GetStringTextureFormat(format) << ", " | 2700 << GLES2Util::GetStringTextureFormat(format) << ", " |
2566 << GLES2Util::GetStringPixelType(type) << ", " | 2701 << GLES2Util::GetStringPixelType(type) << ", " |
2567 << static_cast<const void*>(pixels) << ")"); | 2702 << static_cast<const void*>(pixels) << ")"); |
2568 | 2703 |
2569 if (level < 0 || height < 0 || width < 0) { | 2704 if (level < 0 || height < 0 || width < 0 || xoffset < 0 || yoffset < 0) { |
2570 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "dimension < 0"); | 2705 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "dimension < 0"); |
2571 return; | 2706 return; |
2572 } | 2707 } |
2573 if (height == 0 || width == 0) { | 2708 |
| 2709 uint32_t size; |
| 2710 uint32_t unpadded_row_size; |
| 2711 uint32_t padded_row_size; |
| 2712 uint32_t skip_size; |
| 2713 PixelStoreParams params = GetUnpackParameters(k2D); |
| 2714 if (!GLES2Util::ComputeImageDataSizesES3(width, height, 1, |
| 2715 format, type, |
| 2716 params, |
| 2717 &size, |
| 2718 &unpadded_row_size, |
| 2719 &padded_row_size, |
| 2720 &skip_size, |
| 2721 nullptr)) { |
| 2722 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "image size to large"); |
2574 return; | 2723 return; |
2575 } | 2724 } |
2576 | 2725 |
2577 uint32_t temp_size; | 2726 if (bound_pixel_unpack_buffer_) { |
2578 uint32_t unpadded_row_size; | 2727 base::CheckedNumeric<uint32_t> offset = ToGLuint(pixels); |
2579 uint32_t padded_row_size; | 2728 offset += skip_size; |
2580 if (!GLES2Util::ComputeImageDataSizes( | 2729 if (!offset.IsValid()) { |
2581 width, height, 1, format, type, unpack_alignment_, &temp_size, | 2730 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "skip size too large"); |
2582 &unpadded_row_size, &padded_row_size)) { | 2731 return; |
2583 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "size to large"); | 2732 } |
| 2733 helper_->TexSubImage2D(target, level, xoffset, yoffset, width, height, |
| 2734 format, type, 0, offset.ValueOrDefault(0), false); |
| 2735 CheckGLError(); |
2584 return; | 2736 return; |
2585 } | 2737 } |
2586 | 2738 |
2587 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. | 2739 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. |
2588 if (bound_pixel_unpack_transfer_buffer_id_) { | 2740 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 2741 if (unpack_row_length_ > 0 || unpack_image_height_ > 0 || |
| 2742 unpack_skip_pixels_ > 0 || unpack_skip_rows_ > 0 || |
| 2743 unpack_skip_images_ > 0) { |
| 2744 SetGLError(GL_INVALID_OPERATION, "glTexSubImage2D", |
| 2745 "No ES3 pack parameters with pixel unpack transfer buffer."); |
| 2746 return; |
| 2747 } |
| 2748 DCHECK_EQ(0u, skip_size); |
2589 GLuint offset = ToGLuint(pixels); | 2749 GLuint offset = ToGLuint(pixels); |
2590 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 2750 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
2591 bound_pixel_unpack_transfer_buffer_id_, | 2751 bound_pixel_unpack_transfer_buffer_id_, |
2592 "glTexSubImage2D", offset, temp_size); | 2752 "glTexSubImage2D", offset, size); |
2593 if (buffer && buffer->shm_id() != -1) { | 2753 if (buffer && buffer->shm_id() != -1) { |
2594 helper_->TexSubImage2D( | 2754 helper_->TexSubImage2D( |
2595 target, level, xoffset, yoffset, width, height, format, type, | 2755 target, level, xoffset, yoffset, width, height, format, type, |
2596 buffer->shm_id(), buffer->shm_offset() + offset, false); | 2756 buffer->shm_id(), buffer->shm_offset() + offset, false); |
2597 buffer->set_last_usage_token(helper_->InsertToken()); | 2757 buffer->set_last_usage_token(helper_->InsertToken()); |
2598 CheckGLError(); | 2758 CheckGLError(); |
2599 } | 2759 } |
2600 return; | 2760 return; |
2601 } | 2761 } |
2602 | 2762 |
2603 // compute the advance bytes per row for the src pixels | 2763 if (width == 0 || height == 0) { |
2604 uint32_t src_padded_row_size; | 2764 // No need to worry about pixel data. |
2605 if (unpack_row_length_ > 0) { | 2765 helper_->TexSubImage2D(target, level, xoffset, yoffset, width, height, |
2606 if (!GLES2Util::ComputeImagePaddedRowSize( | 2766 format, type, 0, 0, false); |
2607 unpack_row_length_, format, type, unpack_alignment_, | 2767 CheckGLError(); |
2608 &src_padded_row_size)) { | 2768 return; |
2609 SetGLError( | 2769 } |
2610 GL_INVALID_VALUE, "glTexImage2D", "unpack row length too large"); | 2770 |
| 2771 // Compute the advance bytes per row on the service side. |
| 2772 // Note |size| is recomputed here if needed. |
| 2773 uint32_t service_padded_row_size; |
| 2774 if (unpack_row_length_ > 0 && unpack_row_length_ != width) { |
| 2775 // All parameters have been applied to the data that are sent to the |
| 2776 // service side except UNPACK_ALIGNMENT. |
| 2777 PixelStoreParams service_params; |
| 2778 service_params.alignment = unpack_alignment_; |
| 2779 if (!GLES2Util::ComputeImageDataSizesES3(width, height, 1, |
| 2780 format, type, |
| 2781 service_params, |
| 2782 &size, |
| 2783 nullptr, |
| 2784 &service_padded_row_size, |
| 2785 nullptr, |
| 2786 nullptr)) { |
| 2787 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "image size too large"); |
2611 return; | 2788 return; |
2612 } | 2789 } |
2613 } else { | 2790 } else { |
2614 src_padded_row_size = padded_row_size; | 2791 service_padded_row_size = padded_row_size; |
2615 } | 2792 } |
2616 | 2793 |
2617 // advance pixels pointer past the skip rows and skip pixels | 2794 // advance pixels pointer past the skip rows and skip pixels |
2618 pixels = reinterpret_cast<const int8_t*>(pixels) + | 2795 pixels = reinterpret_cast<const int8_t*>(pixels) + skip_size; |
2619 unpack_skip_rows_ * src_padded_row_size; | |
2620 if (unpack_skip_pixels_) { | |
2621 uint32_t group_size = GLES2Util::ComputeImageGroupSize(format, type); | |
2622 pixels = reinterpret_cast<const int8_t*>(pixels) + | |
2623 unpack_skip_pixels_ * group_size; | |
2624 } | |
2625 | 2796 |
2626 ScopedTransferBufferPtr buffer(temp_size, helper_, transfer_buffer_); | 2797 ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); |
2627 TexSubImage2DImpl( | 2798 TexSubImage2DImpl( |
2628 target, level, xoffset, yoffset, width, height, format, type, | 2799 target, level, xoffset, yoffset, width, height, format, type, |
2629 unpadded_row_size, pixels, src_padded_row_size, GL_FALSE, &buffer, | 2800 unpadded_row_size, pixels, padded_row_size, GL_FALSE, &buffer, |
2630 padded_row_size); | 2801 service_padded_row_size); |
2631 CheckGLError(); | 2802 CheckGLError(); |
2632 } | 2803 } |
2633 | 2804 |
2634 void GLES2Implementation::TexSubImage3D( | 2805 void GLES2Implementation::TexSubImage3D( |
2635 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, | 2806 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, |
2636 GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, | 2807 GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, |
2637 const void* pixels) { | 2808 const void* pixels) { |
2638 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 2809 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
2639 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexSubImage3D(" | 2810 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexSubImage3D(" |
2640 << GLES2Util::GetStringTextureTarget(target) << ", " | 2811 << GLES2Util::GetStringTextureTarget(target) << ", " |
2641 << level << ", " | 2812 << level << ", " |
2642 << xoffset << ", " << yoffset << ", " << zoffset << ", " | 2813 << xoffset << ", " << yoffset << ", " << zoffset << ", " |
2643 << width << ", " << height << ", " << depth << ", " | 2814 << width << ", " << height << ", " << depth << ", " |
2644 << GLES2Util::GetStringTextureFormat(format) << ", " | 2815 << GLES2Util::GetStringTextureFormat(format) << ", " |
2645 << GLES2Util::GetStringPixelType(type) << ", " | 2816 << GLES2Util::GetStringPixelType(type) << ", " |
2646 << static_cast<const void*>(pixels) << ")"); | 2817 << static_cast<const void*>(pixels) << ")"); |
2647 | 2818 |
2648 if (level < 0 || height < 0 || width < 0 || depth < 0) { | 2819 if (level < 0 || height < 0 || width < 0 || depth < 0 || |
| 2820 xoffset < 0 || yoffset < 0 || zoffset < 0) { |
2649 SetGLError(GL_INVALID_VALUE, "glTexSubImage3D", "dimension < 0"); | 2821 SetGLError(GL_INVALID_VALUE, "glTexSubImage3D", "dimension < 0"); |
2650 return; | 2822 return; |
2651 } | 2823 } |
2652 if (height == 0 || width == 0 || depth == 0) { | 2824 |
| 2825 uint32_t size; |
| 2826 uint32_t unpadded_row_size; |
| 2827 uint32_t padded_row_size; |
| 2828 uint32_t skip_size; |
| 2829 PixelStoreParams params = GetUnpackParameters(k3D); |
| 2830 if (!GLES2Util::ComputeImageDataSizesES3(width, height, depth, |
| 2831 format, type, |
| 2832 params, |
| 2833 &size, |
| 2834 &unpadded_row_size, |
| 2835 &padded_row_size, |
| 2836 &skip_size, |
| 2837 nullptr)) { |
| 2838 SetGLError(GL_INVALID_VALUE, "glTexSubImage3D", "image size to large"); |
2653 return; | 2839 return; |
2654 } | 2840 } |
2655 | 2841 |
2656 uint32_t temp_size; | 2842 if (bound_pixel_unpack_buffer_) { |
2657 uint32_t unpadded_row_size; | 2843 base::CheckedNumeric<uint32_t> offset = ToGLuint(pixels); |
2658 uint32_t padded_row_size; | 2844 offset += skip_size; |
2659 if (!GLES2Util::ComputeImageDataSizes( | 2845 if (!offset.IsValid()) { |
2660 width, height, depth, format, type, unpack_alignment_, &temp_size, | 2846 SetGLError(GL_INVALID_VALUE, "glTexSubImage3D", "skip size too large"); |
2661 &unpadded_row_size, &padded_row_size)) { | 2847 return; |
2662 SetGLError(GL_INVALID_VALUE, "glTexSubImage3D", "size to large"); | 2848 } |
| 2849 helper_->TexSubImage3D( |
| 2850 target, level, xoffset, yoffset, zoffset, width, height, depth, |
| 2851 format, type, 0, offset.ValueOrDefault(0), false); |
| 2852 CheckGLError(); |
2663 return; | 2853 return; |
2664 } | 2854 } |
2665 | 2855 |
2666 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. | 2856 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. |
2667 if (bound_pixel_unpack_transfer_buffer_id_) { | 2857 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 2858 if (unpack_row_length_ > 0 || unpack_image_height_ > 0 || |
| 2859 unpack_skip_pixels_ > 0 || unpack_skip_rows_ > 0 || |
| 2860 unpack_skip_images_ > 0) { |
| 2861 SetGLError(GL_INVALID_OPERATION, "glTexSubImage2D", |
| 2862 "No ES3 pack parameters with pixel unpack transfer buffer."); |
| 2863 return; |
| 2864 } |
| 2865 DCHECK_EQ(0u, skip_size); |
2668 GLuint offset = ToGLuint(pixels); | 2866 GLuint offset = ToGLuint(pixels); |
2669 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 2867 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
2670 bound_pixel_unpack_transfer_buffer_id_, | 2868 bound_pixel_unpack_transfer_buffer_id_, |
2671 "glTexSubImage3D", offset, temp_size); | 2869 "glTexSubImage3D", offset, size); |
2672 if (buffer && buffer->shm_id() != -1) { | 2870 if (buffer && buffer->shm_id() != -1) { |
2673 helper_->TexSubImage3D( | 2871 helper_->TexSubImage3D( |
2674 target, level, xoffset, yoffset, zoffset, width, height, depth, | 2872 target, level, xoffset, yoffset, zoffset, width, height, depth, |
2675 format, type, buffer->shm_id(), buffer->shm_offset() + offset, false); | 2873 format, type, buffer->shm_id(), buffer->shm_offset() + offset, false); |
2676 buffer->set_last_usage_token(helper_->InsertToken()); | 2874 buffer->set_last_usage_token(helper_->InsertToken()); |
2677 CheckGLError(); | 2875 CheckGLError(); |
2678 } | 2876 } |
2679 return; | 2877 return; |
2680 } | 2878 } |
2681 | 2879 |
2682 // compute the advance bytes per row for the src pixels | 2880 if (width == 0 || height == 0 || height == 0) { |
2683 uint32_t src_padded_row_size; | 2881 // No need to worry about pixel data. |
2684 if (unpack_row_length_ > 0) { | 2882 helper_->TexSubImage2D(target, level, xoffset, yoffset, width, height, |
2685 if (!GLES2Util::ComputeImagePaddedRowSize( | 2883 format, type, 0, 0, false); |
2686 unpack_row_length_, format, type, unpack_alignment_, | 2884 CheckGLError(); |
2687 &src_padded_row_size)) { | 2885 return; |
2688 SetGLError( | 2886 } |
2689 GL_INVALID_VALUE, "glTexImage3D", "unpack row length too large"); | 2887 |
| 2888 // Compute the advance bytes per row on the service side |
| 2889 // Note |size| is recomputed here if needed. |
| 2890 uint32_t service_padded_row_size; |
| 2891 if ((unpack_row_length_ > 0 && unpack_row_length_ != width) || |
| 2892 (unpack_image_height_ > 0 && unpack_image_height_ != height)) { |
| 2893 PixelStoreParams service_params; |
| 2894 service_params.alignment = unpack_alignment_; |
| 2895 if (!GLES2Util::ComputeImageDataSizesES3(width, height, depth, |
| 2896 format, type, |
| 2897 service_params, |
| 2898 &size, |
| 2899 nullptr, |
| 2900 &service_padded_row_size, |
| 2901 nullptr, |
| 2902 nullptr)) { |
| 2903 SetGLError(GL_INVALID_VALUE, "glTexSubImage3D", "image size too large"); |
2690 return; | 2904 return; |
2691 } | 2905 } |
2692 } else { | 2906 } else { |
2693 src_padded_row_size = padded_row_size; | 2907 service_padded_row_size = padded_row_size; |
2694 } | 2908 } |
2695 uint32_t src_height = | |
2696 unpack_image_height_ > 0 ? unpack_image_height_ : height; | |
2697 | 2909 |
2698 // advance pixels pointer past the skip images/rows/pixels | 2910 // advance pixels pointer past the skip images/rows/pixels |
2699 pixels = reinterpret_cast<const int8_t*>(pixels) + | 2911 pixels = reinterpret_cast<const int8_t*>(pixels) + skip_size; |
2700 unpack_skip_images_ * src_padded_row_size * src_height + | |
2701 unpack_skip_rows_ * src_padded_row_size; | |
2702 if (unpack_skip_pixels_) { | |
2703 uint32_t group_size = GLES2Util::ComputeImageGroupSize(format, type); | |
2704 pixels = reinterpret_cast<const int8_t*>(pixels) + | |
2705 unpack_skip_pixels_ * group_size; | |
2706 } | |
2707 | 2912 |
2708 ScopedTransferBufferPtr buffer(temp_size, helper_, transfer_buffer_); | 2913 ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); |
2709 TexSubImage3DImpl( | 2914 TexSubImage3DImpl( |
2710 target, level, xoffset, yoffset, zoffset, width, height, depth, | 2915 target, level, xoffset, yoffset, zoffset, width, height, depth, |
2711 format, type, unpadded_row_size, pixels, src_padded_row_size, GL_FALSE, | 2916 format, type, unpadded_row_size, pixels, padded_row_size, GL_FALSE, |
2712 &buffer, padded_row_size); | 2917 &buffer, service_padded_row_size); |
2713 CheckGLError(); | 2918 CheckGLError(); |
2714 } | 2919 } |
2715 | 2920 |
2716 static GLint ComputeNumRowsThatFitInBuffer(uint32_t padded_row_size, | 2921 static GLint ComputeNumRowsThatFitInBuffer(uint32_t padded_row_size, |
2717 uint32_t unpadded_row_size, | 2922 uint32_t unpadded_row_size, |
2718 unsigned int size, | 2923 unsigned int size, |
2719 GLsizei remaining_rows) { | 2924 GLsizei remaining_rows) { |
2720 DCHECK_GE(unpadded_row_size, 0u); | 2925 DCHECK_GE(unpadded_row_size, 0u); |
2721 if (padded_row_size == 0) { | 2926 if (padded_row_size == 0) { |
2722 return 1; | 2927 return 1; |
(...skipping 17 matching lines...) Expand all Loading... |
2740 uint32_t unpadded_row_size, | 2945 uint32_t unpadded_row_size, |
2741 const void* pixels, | 2946 const void* pixels, |
2742 uint32_t pixels_padded_row_size, | 2947 uint32_t pixels_padded_row_size, |
2743 GLboolean internal, | 2948 GLboolean internal, |
2744 ScopedTransferBufferPtr* buffer, | 2949 ScopedTransferBufferPtr* buffer, |
2745 uint32_t buffer_padded_row_size) { | 2950 uint32_t buffer_padded_row_size) { |
2746 DCHECK(buffer); | 2951 DCHECK(buffer); |
2747 DCHECK_GE(level, 0); | 2952 DCHECK_GE(level, 0); |
2748 DCHECK_GT(height, 0); | 2953 DCHECK_GT(height, 0); |
2749 DCHECK_GT(width, 0); | 2954 DCHECK_GT(width, 0); |
| 2955 DCHECK_GE(xoffset, 0); |
| 2956 DCHECK_GE(yoffset, 0); |
2750 | 2957 |
2751 const int8_t* source = reinterpret_cast<const int8_t*>(pixels); | 2958 const int8_t* source = reinterpret_cast<const int8_t*>(pixels); |
2752 // Transfer by rows. | 2959 // Transfer by rows. |
2753 while (height) { | 2960 while (height) { |
2754 unsigned int desired_size = | 2961 unsigned int desired_size = |
2755 buffer_padded_row_size * (height - 1) + unpadded_row_size; | 2962 buffer_padded_row_size * (height - 1) + unpadded_row_size; |
2756 if (!buffer->valid() || buffer->size() == 0) { | 2963 if (!buffer->valid() || buffer->size() == 0) { |
2757 buffer->Reset(desired_size); | 2964 buffer->Reset(desired_size); |
2758 if (!buffer->valid()) { | 2965 if (!buffer->valid()) { |
2759 return; | 2966 return; |
(...skipping 27 matching lines...) Expand all Loading... |
2787 GLenum format, | 2994 GLenum format, |
2788 GLenum type, | 2995 GLenum type, |
2789 uint32_t unpadded_row_size, | 2996 uint32_t unpadded_row_size, |
2790 const void* pixels, | 2997 const void* pixels, |
2791 uint32_t pixels_padded_row_size, | 2998 uint32_t pixels_padded_row_size, |
2792 GLboolean internal, | 2999 GLboolean internal, |
2793 ScopedTransferBufferPtr* buffer, | 3000 ScopedTransferBufferPtr* buffer, |
2794 uint32_t buffer_padded_row_size) { | 3001 uint32_t buffer_padded_row_size) { |
2795 DCHECK(buffer); | 3002 DCHECK(buffer); |
2796 DCHECK_GE(level, 0); | 3003 DCHECK_GE(level, 0); |
| 3004 DCHECK_GT(width, 0); |
2797 DCHECK_GT(height, 0); | 3005 DCHECK_GT(height, 0); |
2798 DCHECK_GT(width, 0); | |
2799 DCHECK_GT(depth, 0); | 3006 DCHECK_GT(depth, 0); |
| 3007 DCHECK_GE(xoffset, 0); |
| 3008 DCHECK_GE(yoffset, 0); |
| 3009 DCHECK_GE(zoffset, 0); |
2800 const int8_t* source = reinterpret_cast<const int8_t*>(pixels); | 3010 const int8_t* source = reinterpret_cast<const int8_t*>(pixels); |
2801 GLsizei total_rows = height * depth; | 3011 GLsizei total_rows = height * depth; |
2802 GLint row_index = 0, depth_index = 0; | 3012 GLint row_index = 0, depth_index = 0; |
2803 while (total_rows) { | 3013 while (total_rows) { |
2804 // Each time, we either copy one or more images, or copy one or more rows | 3014 // Each time, we either copy one or more images, or copy one or more rows |
2805 // within a single image, depending on the buffer size limit. | 3015 // within a single image, depending on the buffer size limit. |
2806 GLsizei max_rows; | 3016 GLsizei max_rows; |
2807 unsigned int desired_size; | 3017 unsigned int desired_size; |
2808 if (row_index > 0) { | 3018 if (row_index > 0) { |
2809 // We are in the middle of an image. Send the remaining of the image. | 3019 // We are in the middle of an image. Send the remaining of the image. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2841 my_depth = 1; | 3051 my_depth = 1; |
2842 } | 3052 } |
2843 | 3053 |
2844 if (num_images > 0) { | 3054 if (num_images > 0) { |
2845 int8_t* buffer_pointer = reinterpret_cast<int8_t*>(buffer->address()); | 3055 int8_t* buffer_pointer = reinterpret_cast<int8_t*>(buffer->address()); |
2846 uint32_t src_height = | 3056 uint32_t src_height = |
2847 unpack_image_height_ > 0 ? unpack_image_height_ : height; | 3057 unpack_image_height_ > 0 ? unpack_image_height_ : height; |
2848 uint32_t image_size_dst = buffer_padded_row_size * height; | 3058 uint32_t image_size_dst = buffer_padded_row_size * height; |
2849 uint32_t image_size_src = pixels_padded_row_size * src_height; | 3059 uint32_t image_size_src = pixels_padded_row_size * src_height; |
2850 for (GLint ii = 0; ii < num_images; ++ii) { | 3060 for (GLint ii = 0; ii < num_images; ++ii) { |
2851 uint32_t my_unpadded_row_size; | |
2852 if (total_rows == num_rows && ii + 1 == num_images) | |
2853 my_unpadded_row_size = unpadded_row_size; | |
2854 else | |
2855 my_unpadded_row_size = pixels_padded_row_size; | |
2856 CopyRectToBuffer( | 3061 CopyRectToBuffer( |
2857 source + ii * image_size_src, my_height, my_unpadded_row_size, | 3062 source + ii * image_size_src, my_height, unpadded_row_size, |
2858 pixels_padded_row_size, buffer_pointer + ii * image_size_dst, | 3063 pixels_padded_row_size, buffer_pointer + ii * image_size_dst, |
2859 buffer_padded_row_size); | 3064 buffer_padded_row_size); |
2860 } | 3065 } |
2861 } else { | 3066 } else { |
2862 uint32_t my_unpadded_row_size; | |
2863 if (total_rows == num_rows) | |
2864 my_unpadded_row_size = unpadded_row_size; | |
2865 else | |
2866 my_unpadded_row_size = pixels_padded_row_size; | |
2867 CopyRectToBuffer( | 3067 CopyRectToBuffer( |
2868 source, my_height, my_unpadded_row_size, pixels_padded_row_size, | 3068 source, my_height, unpadded_row_size, pixels_padded_row_size, |
2869 buffer->address(), buffer_padded_row_size); | 3069 buffer->address(), buffer_padded_row_size); |
2870 } | 3070 } |
2871 helper_->TexSubImage3D( | 3071 helper_->TexSubImage3D( |
2872 target, level, xoffset, yoffset + row_index, zoffset + depth_index, | 3072 target, level, xoffset, yoffset + row_index, zoffset + depth_index, |
2873 width, my_height, my_depth, | 3073 width, my_height, my_depth, |
2874 format, type, buffer->shm_id(), buffer->offset(), internal); | 3074 format, type, buffer->shm_id(), buffer->offset(), internal); |
2875 buffer->Release(); | 3075 buffer->Release(); |
2876 | 3076 |
2877 total_rows -= num_rows; | 3077 total_rows -= num_rows; |
2878 if (total_rows > 0) { | 3078 if (total_rows > 0) { |
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3531 << xoffset << ", " << yoffset << ", " | 3731 << xoffset << ", " << yoffset << ", " |
3532 << width << ", " << height << ", " | 3732 << width << ", " << height << ", " |
3533 << GLES2Util::GetStringReadPixelFormat(format) << ", " | 3733 << GLES2Util::GetStringReadPixelFormat(format) << ", " |
3534 << GLES2Util::GetStringPixelType(type) << ", " | 3734 << GLES2Util::GetStringPixelType(type) << ", " |
3535 << static_cast<const void*>(pixels) << ")"); | 3735 << static_cast<const void*>(pixels) << ")"); |
3536 if (width < 0 || height < 0) { | 3736 if (width < 0 || height < 0) { |
3537 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0"); | 3737 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0"); |
3538 return; | 3738 return; |
3539 } | 3739 } |
3540 | 3740 |
3541 // glReadPixel pads the size of each row of pixels by an amount specified by | |
3542 // glPixelStorei. So, we have to take that into account both in the fact that | |
3543 // the pixels returned from the ReadPixel command will include that padding | |
3544 // and that when we copy the results to the user's buffer we need to not | |
3545 // write those padding bytes but leave them as they are. | |
3546 | |
3547 TRACE_EVENT0("gpu", "GLES2::ReadPixels"); | |
3548 typedef cmds::ReadPixels::Result Result; | |
3549 | |
3550 if (bound_pixel_pack_buffer_) { | |
3551 GLuint offset = ToGLuint(pixels); | |
3552 helper_->ReadPixels( | |
3553 xoffset, yoffset, width, height, format, type, 0, offset, 0, 0, false); | |
3554 CheckGLError(); | |
3555 return; | |
3556 } | |
3557 | |
3558 uint32_t size; | 3741 uint32_t size; |
3559 uint32_t unpadded_row_size; | 3742 uint32_t unpadded_row_size; |
3560 uint32_t padded_row_size; | 3743 uint32_t padded_row_size; |
3561 uint32_t skip_size; | 3744 uint32_t skip_size; |
3562 PixelStoreParams params; | 3745 PixelStoreParams params; |
3563 params.alignment = pack_alignment_; | 3746 params.alignment = pack_alignment_; |
3564 params.row_length = pack_row_length_; | 3747 params.row_length = pack_row_length_; |
3565 params.skip_pixels = pack_skip_pixels_; | 3748 params.skip_pixels = pack_skip_pixels_; |
3566 params.skip_rows = pack_skip_rows_; | 3749 params.skip_rows = pack_skip_rows_; |
3567 if (!GLES2Util::ComputeImageDataSizesES3(width, height, 1, | 3750 if (!GLES2Util::ComputeImageDataSizesES3(width, height, 1, |
3568 format, type, | 3751 format, type, |
3569 params, | 3752 params, |
3570 &size, | 3753 &size, |
3571 &unpadded_row_size, | 3754 &unpadded_row_size, |
3572 &padded_row_size, | 3755 &padded_row_size, |
3573 &skip_size, | 3756 &skip_size, |
3574 nullptr)) { | 3757 nullptr)) { |
3575 SetGLError(GL_INVALID_VALUE, "glReadPixels", "size too large."); | 3758 SetGLError(GL_INVALID_VALUE, "glReadPixels", "size too large."); |
3576 return; | 3759 return; |
3577 } | 3760 } |
| 3761 |
| 3762 // glReadPixel pads the size of each row of pixels by an amount specified by |
| 3763 // glPixelStorei. So, we have to take that into account both in the fact that |
| 3764 // the pixels returned from the ReadPixel command will include that padding |
| 3765 // and that when we copy the results to the user's buffer we need to not |
| 3766 // write those padding bytes but leave them as they are. |
| 3767 |
| 3768 TRACE_EVENT0("gpu", "GLES2::ReadPixels"); |
| 3769 typedef cmds::ReadPixels::Result Result; |
| 3770 |
| 3771 if (bound_pixel_pack_buffer_) { |
| 3772 base::CheckedNumeric<uint32_t> offset = ToGLuint(pixels); |
| 3773 offset += skip_size; |
| 3774 if (!offset.IsValid()) { |
| 3775 SetGLError(GL_INVALID_VALUE, "glReadPixels", "skip size too large."); |
| 3776 return; |
| 3777 } |
| 3778 helper_->ReadPixels( |
| 3779 xoffset, yoffset, width, height, format, type, 0, |
| 3780 offset.ValueOrDefault(0), 0, 0, false); |
| 3781 CheckGLError(); |
| 3782 return; |
| 3783 } |
| 3784 |
3578 uint32_t service_padded_row_size = 0; | 3785 uint32_t service_padded_row_size = 0; |
3579 if (pack_row_length_ > 0 && pack_row_length_ != width) { | 3786 if (pack_row_length_ > 0 && pack_row_length_ != width) { |
3580 if (!GLES2Util::ComputeImagePaddedRowSize(width, | 3787 if (!GLES2Util::ComputeImagePaddedRowSize(width, |
3581 format, type, | 3788 format, type, |
3582 pack_alignment_, | 3789 pack_alignment_, |
3583 &service_padded_row_size)) { | 3790 &service_padded_row_size)) { |
3584 SetGLError(GL_INVALID_VALUE, "glReadPixels", "size too large."); | 3791 SetGLError(GL_INVALID_VALUE, "glReadPixels", "size too large."); |
3585 return; | 3792 return; |
3586 } | 3793 } |
3587 } else { | 3794 } else { |
3588 service_padded_row_size = padded_row_size; | 3795 service_padded_row_size = padded_row_size; |
3589 } | 3796 } |
3590 | 3797 |
3591 if (bound_pixel_pack_transfer_buffer_id_) { | 3798 if (bound_pixel_pack_transfer_buffer_id_) { |
3592 if (pack_row_length_ > 0 || pack_skip_pixels_ > 0 || pack_skip_rows_ > 0) { | 3799 if (pack_row_length_ > 0 || pack_skip_pixels_ > 0 || pack_skip_rows_ > 0) { |
3593 SetGLError(GL_INVALID_OPERATION, "glReadPixels", | 3800 SetGLError(GL_INVALID_OPERATION, "glReadPixels", |
3594 "No ES3 pack parameters with pixel pack transfer buffer."); | 3801 "No ES3 pack parameters with pixel pack transfer buffer."); |
3595 return; | 3802 return; |
3596 } | 3803 } |
3597 DCHECK_EQ(0u, skip_size); | 3804 DCHECK_EQ(0u, skip_size); |
3598 GLuint offset = ToGLuint(pixels); | 3805 GLuint offset = ToGLuint(pixels); |
3599 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( | 3806 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
3600 bound_pixel_pack_transfer_buffer_id_, "glReadPixels", offset, size); | 3807 bound_pixel_pack_transfer_buffer_id_, "glReadPixels", offset, size); |
3601 if (buffer && buffer->shm_id() != -1) { | 3808 if (buffer && buffer->shm_id() != -1) { |
3602 helper_->ReadPixels(xoffset, yoffset, width, height, format, type, | 3809 helper_->ReadPixels(xoffset, yoffset, width, height, format, type, |
3603 buffer->shm_id(), buffer->shm_offset(), | 3810 buffer->shm_id(), buffer->shm_offset() + offset, |
3604 0, 0, true); | 3811 0, 0, true); |
3605 CheckGLError(); | 3812 CheckGLError(); |
3606 } | 3813 } |
3607 return; | 3814 return; |
3608 } | 3815 } |
3609 | 3816 |
3610 if (!pixels) { | 3817 if (!pixels) { |
3611 SetGLError(GL_INVALID_OPERATION, "glReadPixels", "pixels = NULL"); | 3818 SetGLError(GL_INVALID_OPERATION, "glReadPixels", "pixels = NULL"); |
3612 return; | 3819 return; |
3613 } | 3820 } |
(...skipping 2960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6574 cached_extensions_.clear(); | 6781 cached_extensions_.clear(); |
6575 } | 6782 } |
6576 | 6783 |
6577 // Include the auto-generated part of this file. We split this because it means | 6784 // Include the auto-generated part of this file. We split this because it means |
6578 // we can easily edit the non-auto generated parts right here in this file | 6785 // we can easily edit the non-auto generated parts right here in this file |
6579 // instead of having to edit some template or the code generator. | 6786 // instead of having to edit some template or the code generator. |
6580 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" | 6787 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" |
6581 | 6788 |
6582 } // namespace gles2 | 6789 } // namespace gles2 |
6583 } // namespace gpu | 6790 } // namespace gpu |
OLD | NEW |