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

Side by Side Diff: gpu/command_buffer/client/gles2_implementation.cc

Issue 1750123002: Upgrade Tex{Sub}Image{2|3}D to handle ES3 unpack parameters. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // 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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698