| 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 |