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 2333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2344 helper_->CompressedTexSubImage3DBucket( | 2344 helper_->CompressedTexSubImage3DBucket( |
2345 target, level, xoffset, yoffset, zoffset, width, height, depth, format, | 2345 target, level, xoffset, yoffset, zoffset, width, height, depth, format, |
2346 kResultBucketId); | 2346 kResultBucketId); |
2347 // Free the bucket. This is not required but it does free up the memory. | 2347 // Free the bucket. This is not required but it does free up the memory. |
2348 // and we don't have to wait for the result so from the client's perspective | 2348 // and we don't have to wait for the result so from the client's perspective |
2349 // it's cheap. | 2349 // it's cheap. |
2350 helper_->SetBucketSize(kResultBucketId, 0); | 2350 helper_->SetBucketSize(kResultBucketId, 0); |
2351 CheckGLError(); | 2351 CheckGLError(); |
2352 } | 2352 } |
2353 | 2353 |
| 2354 PixelStoreParams GLES2Implementation::GetUnpackParameters(Dimension dimension) { |
| 2355 PixelStoreParams params; |
| 2356 params.alignment = unpack_alignment_; |
| 2357 params.row_length = unpack_row_length_; |
| 2358 params.skip_pixels = unpack_skip_pixels_; |
| 2359 params.skip_rows = unpack_skip_rows_; |
| 2360 if (dimension == k3D) { |
| 2361 params.image_height = unpack_image_height_; |
| 2362 params.skip_images = unpack_skip_images_; |
| 2363 } |
| 2364 return params; |
| 2365 } |
| 2366 |
2354 void GLES2Implementation::TexImage2D( | 2367 void GLES2Implementation::TexImage2D( |
2355 GLenum target, GLint level, GLint internalformat, GLsizei width, | 2368 GLenum target, GLint level, GLint internalformat, GLsizei width, |
2356 GLsizei height, GLint border, GLenum format, GLenum type, | 2369 GLsizei height, GLint border, GLenum format, GLenum type, |
2357 const void* pixels) { | 2370 const void* pixels) { |
2358 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 2371 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
2359 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexImage2D(" | 2372 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexImage2D(" |
2360 << GLES2Util::GetStringTextureTarget(target) << ", " | 2373 << GLES2Util::GetStringTextureTarget(target) << ", " |
2361 << level << ", " | 2374 << level << ", " |
2362 << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " | 2375 << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " |
2363 << width << ", " << height << ", " << border << ", " | 2376 << width << ", " << height << ", " << border << ", " |
2364 << GLES2Util::GetStringTextureFormat(format) << ", " | 2377 << GLES2Util::GetStringTextureFormat(format) << ", " |
2365 << GLES2Util::GetStringPixelType(type) << ", " | 2378 << GLES2Util::GetStringPixelType(type) << ", " |
2366 << static_cast<const void*>(pixels) << ")"); | 2379 << static_cast<const void*>(pixels) << ")"); |
2367 if (level < 0 || height < 0 || width < 0) { | 2380 if (level < 0 || height < 0 || width < 0) { |
2368 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "dimension < 0"); | 2381 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "dimension < 0"); |
2369 return; | 2382 return; |
2370 } | 2383 } |
2371 if (border != 0) { | 2384 if (border != 0) { |
2372 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "border != 0"); | 2385 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "border != 0"); |
2373 return; | 2386 return; |
2374 } | 2387 } |
2375 uint32_t size; | 2388 uint32_t size; |
2376 uint32_t unpadded_row_size; | 2389 uint32_t unpadded_row_size; |
2377 uint32_t padded_row_size; | 2390 uint32_t padded_row_size; |
2378 if (!GLES2Util::ComputeImageDataSizes( | 2391 uint32_t skip_size; |
2379 width, height, 1, format, type, unpack_alignment_, &size, | 2392 PixelStoreParams params = GetUnpackParameters(k2D); |
2380 &unpadded_row_size, &padded_row_size)) { | 2393 if (!GLES2Util::ComputeImageDataSizesES3(width, height, 1, |
| 2394 format, type, |
| 2395 params, |
| 2396 &size, |
| 2397 &unpadded_row_size, |
| 2398 &padded_row_size, |
| 2399 &skip_size, |
| 2400 nullptr)) { |
2381 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); | 2401 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); |
2382 return; | 2402 return; |
2383 } | 2403 } |
2384 | 2404 |
| 2405 if (bound_pixel_unpack_buffer_) { |
| 2406 base::CheckedNumeric<uint32_t> offset = ToGLuint(pixels); |
| 2407 offset += skip_size; |
| 2408 if (!offset.IsValid()) { |
| 2409 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "skip size too large"); |
| 2410 return; |
| 2411 } |
| 2412 helper_->TexImage2D( |
| 2413 target, level, internalformat, width, height, format, type, |
| 2414 0, offset.ValueOrDefault(0)); |
| 2415 CheckGLError(); |
| 2416 return; |
| 2417 } |
| 2418 |
2385 // If there's a pixel unpack buffer bound use it when issuing TexImage2D. | 2419 // If there's a pixel unpack buffer bound use it when issuing TexImage2D. |
2386 if (bound_pixel_unpack_transfer_buffer_id_) { | 2420 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 2421 if (unpack_row_length_ > 0 || unpack_image_height_ > 0 || |
| 2422 unpack_skip_pixels_ > 0 || unpack_skip_rows_ > 0 || |
| 2423 unpack_skip_images_ > 0) { |
| 2424 SetGLError(GL_INVALID_OPERATION, "glTexImage2D", |
| 2425 "No ES3 pack parameters with pixel unpack transfer buffer."); |
| 2426 return; |
| 2427 } |
| 2428 DCHECK_EQ(0u, skip_size); |
2387 GLuint offset = ToGLuint(pixels); | 2429 GLuint offset = ToGLuint(pixels); |
2388 BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid( | 2430 BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid( |
2389 bound_pixel_unpack_transfer_buffer_id_, "glTexImage2D", offset, size); | 2431 bound_pixel_unpack_transfer_buffer_id_, "glTexImage2D", offset, size); |
2390 if (buffer && buffer->shm_id() != -1) { | 2432 if (buffer && buffer->shm_id() != -1) { |
2391 helper_->TexImage2D( | 2433 helper_->TexImage2D( |
2392 target, level, internalformat, width, height, format, type, | 2434 target, level, internalformat, width, height, format, type, |
2393 buffer->shm_id(), buffer->shm_offset() + offset); | 2435 buffer->shm_id(), buffer->shm_offset() + offset); |
2394 buffer->set_last_usage_token(helper_->InsertToken()); | 2436 buffer->set_last_usage_token(helper_->InsertToken()); |
2395 CheckGLError(); | 2437 CheckGLError(); |
2396 } | 2438 } |
2397 return; | 2439 return; |
2398 } | 2440 } |
2399 | 2441 |
2400 // If there's no data just issue TexImage2D | 2442 // If there's no data just issue TexImage2D |
2401 if (!pixels) { | 2443 if (!pixels || width == 0 || height == 0) { |
2402 helper_->TexImage2D( | 2444 helper_->TexImage2D( |
2403 target, level, internalformat, width, height, format, type, | 2445 target, level, internalformat, width, height, format, type, 0, 0); |
2404 0, 0); | |
2405 CheckGLError(); | 2446 CheckGLError(); |
2406 return; | 2447 return; |
2407 } | 2448 } |
2408 | 2449 |
2409 // compute the advance bytes per row for the src pixels | 2450 // Compute the advance bytes per row on the service side. |
2410 uint32_t src_padded_row_size; | 2451 // Note |size| is recomputed here if needed. |
2411 if (unpack_row_length_ > 0) { | 2452 uint32_t service_padded_row_size; |
2412 if (!GLES2Util::ComputeImagePaddedRowSize( | 2453 if (unpack_row_length_ > 0 && unpack_row_length_ != width) { |
2413 unpack_row_length_, format, type, unpack_alignment_, | 2454 // All parameters have been applied to the data that are sent to the |
2414 &src_padded_row_size)) { | 2455 // service side except UNPACK_ALIGNMENT. |
2415 SetGLError( | 2456 PixelStoreParams service_params; |
2416 GL_INVALID_VALUE, "glTexImage2D", "unpack row length too large"); | 2457 service_params.alignment = unpack_alignment_; |
| 2458 if (!GLES2Util::ComputeImageDataSizesES3(width, height, 1, |
| 2459 format, type, |
| 2460 service_params, |
| 2461 &size, |
| 2462 nullptr, |
| 2463 &service_padded_row_size, |
| 2464 nullptr, |
| 2465 nullptr)) { |
| 2466 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); |
2417 return; | 2467 return; |
2418 } | 2468 } |
2419 } else { | 2469 } else { |
2420 src_padded_row_size = padded_row_size; | 2470 service_padded_row_size = padded_row_size; |
2421 } | 2471 } |
2422 | 2472 |
2423 // advance pixels pointer past the skip rows and skip pixels | 2473 // advance pixels pointer past the skip rows and skip pixels |
2424 pixels = reinterpret_cast<const int8_t*>(pixels) + | 2474 pixels = reinterpret_cast<const int8_t*>(pixels) + skip_size; |
2425 unpack_skip_rows_ * src_padded_row_size; | |
2426 if (unpack_skip_pixels_) { | |
2427 uint32_t group_size = GLES2Util::ComputeImageGroupSize(format, type); | |
2428 pixels = reinterpret_cast<const int8_t*>(pixels) + | |
2429 unpack_skip_pixels_ * group_size; | |
2430 } | |
2431 | 2475 |
2432 // Check if we can send it all at once. | 2476 // Check if we can send it all at once. |
2433 int32_t shm_id = 0; | 2477 int32_t shm_id = 0; |
2434 uint32_t shm_offset = 0; | 2478 uint32_t shm_offset = 0; |
2435 void* buffer_pointer = nullptr; | 2479 void* buffer_pointer = nullptr; |
2436 | 2480 |
2437 ScopedTransferBufferPtr transfer_alloc(size, helper_, transfer_buffer_); | 2481 ScopedTransferBufferPtr transfer_alloc(size, helper_, transfer_buffer_); |
2438 ScopedMappedMemoryPtr mapped_alloc(0, helper_, mapped_memory_.get()); | 2482 ScopedMappedMemoryPtr mapped_alloc(0, helper_, mapped_memory_.get()); |
2439 | 2483 |
2440 if (transfer_alloc.valid() && transfer_alloc.size() >= size) { | 2484 if (transfer_alloc.valid() && transfer_alloc.size() >= size) { |
2441 shm_id = transfer_alloc.shm_id(); | 2485 shm_id = transfer_alloc.shm_id(); |
2442 shm_offset = transfer_alloc.offset(); | 2486 shm_offset = transfer_alloc.offset(); |
2443 buffer_pointer = transfer_alloc.address(); | 2487 buffer_pointer = transfer_alloc.address(); |
2444 } else if (size < max_extra_transfer_buffer_size_) { | 2488 } else if (size < max_extra_transfer_buffer_size_) { |
2445 mapped_alloc.Reset(size); | 2489 mapped_alloc.Reset(size); |
2446 if (mapped_alloc.valid()) { | 2490 if (mapped_alloc.valid()) { |
2447 transfer_alloc.Discard(); | 2491 transfer_alloc.Discard(); |
2448 | 2492 |
2449 mapped_alloc.SetFlushAfterRelease(true); | 2493 mapped_alloc.SetFlushAfterRelease(true); |
2450 shm_id = mapped_alloc.shm_id(); | 2494 shm_id = mapped_alloc.shm_id(); |
2451 shm_offset = mapped_alloc.offset(); | 2495 shm_offset = mapped_alloc.offset(); |
2452 buffer_pointer = mapped_alloc.address(); | 2496 buffer_pointer = mapped_alloc.address(); |
2453 } | 2497 } |
2454 } | 2498 } |
2455 | 2499 |
2456 if (buffer_pointer) { | 2500 if (buffer_pointer) { |
2457 CopyRectToBuffer( | 2501 CopyRectToBuffer( |
2458 pixels, height, unpadded_row_size, src_padded_row_size, | 2502 pixels, height, unpadded_row_size, padded_row_size, |
2459 buffer_pointer, padded_row_size); | 2503 buffer_pointer, service_padded_row_size); |
2460 helper_->TexImage2D( | 2504 helper_->TexImage2D( |
2461 target, level, internalformat, width, height, format, type, | 2505 target, level, internalformat, width, height, format, type, |
2462 shm_id, shm_offset); | 2506 shm_id, shm_offset); |
2463 CheckGLError(); | 2507 CheckGLError(); |
2464 return; | 2508 return; |
2465 } | 2509 } |
2466 | 2510 |
2467 // No, so send it using TexSubImage2D. | 2511 // No, so send it using TexSubImage2D. |
2468 helper_->TexImage2D( | 2512 helper_->TexImage2D( |
2469 target, level, internalformat, width, height, format, type, | 2513 target, level, internalformat, width, height, format, type, |
2470 0, 0); | 2514 0, 0); |
2471 TexSubImage2DImpl( | 2515 TexSubImage2DImpl( |
2472 target, level, 0, 0, width, height, format, type, unpadded_row_size, | 2516 target, level, 0, 0, width, height, format, type, unpadded_row_size, |
2473 pixels, src_padded_row_size, GL_TRUE, &transfer_alloc, padded_row_size); | 2517 pixels, padded_row_size, GL_TRUE, &transfer_alloc, |
| 2518 service_padded_row_size); |
2474 CheckGLError(); | 2519 CheckGLError(); |
2475 } | 2520 } |
2476 | 2521 |
2477 void GLES2Implementation::TexImage3D( | 2522 void GLES2Implementation::TexImage3D( |
2478 GLenum target, GLint level, GLint internalformat, GLsizei width, | 2523 GLenum target, GLint level, GLint internalformat, GLsizei width, |
2479 GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, | 2524 GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, |
2480 const void* pixels) { | 2525 const void* pixels) { |
2481 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 2526 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
2482 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexImage3D(" | 2527 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexImage3D(" |
2483 << GLES2Util::GetStringTextureTarget(target) << ", " | 2528 << GLES2Util::GetStringTextureTarget(target) << ", " |
2484 << level << ", " | 2529 << level << ", " |
2485 << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " | 2530 << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " |
2486 << width << ", " << height << ", " << depth << ", " << border << ", " | 2531 << width << ", " << height << ", " << depth << ", " << border << ", " |
2487 << GLES2Util::GetStringTextureFormat(format) << ", " | 2532 << GLES2Util::GetStringTextureFormat(format) << ", " |
2488 << GLES2Util::GetStringPixelType(type) << ", " | 2533 << GLES2Util::GetStringPixelType(type) << ", " |
2489 << static_cast<const void*>(pixels) << ")"); | 2534 << static_cast<const void*>(pixels) << ")"); |
2490 if (level < 0 || height < 0 || width < 0 || depth < 0) { | 2535 if (level < 0 || height < 0 || width < 0 || depth < 0) { |
2491 SetGLError(GL_INVALID_VALUE, "glTexImage3D", "dimension < 0"); | 2536 SetGLError(GL_INVALID_VALUE, "glTexImage3D", "dimension < 0"); |
2492 return; | 2537 return; |
2493 } | 2538 } |
2494 if (border != 0) { | 2539 if (border != 0) { |
2495 SetGLError(GL_INVALID_VALUE, "glTexImage3D", "border != 0"); | 2540 SetGLError(GL_INVALID_VALUE, "glTexImage3D", "border != 0"); |
2496 return; | 2541 return; |
2497 } | 2542 } |
| 2543 |
2498 uint32_t size; | 2544 uint32_t size; |
2499 uint32_t unpadded_row_size; | 2545 uint32_t unpadded_row_size; |
2500 uint32_t padded_row_size; | 2546 uint32_t padded_row_size; |
2501 if (!GLES2Util::ComputeImageDataSizes( | 2547 uint32_t skip_size; |
2502 width, height, depth, format, type, unpack_alignment_, &size, | 2548 PixelStoreParams params = GetUnpackParameters(k3D); |
2503 &unpadded_row_size, &padded_row_size)) { | 2549 if (!GLES2Util::ComputeImageDataSizesES3(width, height, depth, |
| 2550 format, type, |
| 2551 params, |
| 2552 &size, |
| 2553 &unpadded_row_size, |
| 2554 &padded_row_size, |
| 2555 &skip_size, |
| 2556 nullptr)) { |
2504 SetGLError(GL_INVALID_VALUE, "glTexImage3D", "image size too large"); | 2557 SetGLError(GL_INVALID_VALUE, "glTexImage3D", "image size too large"); |
2505 return; | 2558 return; |
2506 } | 2559 } |
2507 | 2560 |
| 2561 if (bound_pixel_unpack_buffer_) { |
| 2562 base::CheckedNumeric<uint32_t> offset = ToGLuint(pixels); |
| 2563 offset += skip_size; |
| 2564 if (!offset.IsValid()) { |
| 2565 SetGLError(GL_INVALID_VALUE, "glTexImage3D", "skip size too large"); |
| 2566 return; |
| 2567 } |
| 2568 helper_->TexImage3D( |
| 2569 target, level, internalformat, width, height, depth, format, type, |
| 2570 0, offset.ValueOrDefault(0)); |
| 2571 CheckGLError(); |
| 2572 return; |
| 2573 } |
| 2574 |
2508 // If there's a pixel unpack buffer bound use it when issuing TexImage3D. | 2575 // If there's a pixel unpack buffer bound use it when issuing TexImage3D. |
2509 if (bound_pixel_unpack_transfer_buffer_id_) { | 2576 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 2577 if (unpack_row_length_ > 0 || unpack_image_height_ > 0 || |
| 2578 unpack_skip_pixels_ > 0 || unpack_skip_rows_ > 0 || |
| 2579 unpack_skip_images_ > 0) { |
| 2580 SetGLError(GL_INVALID_OPERATION, "glTexImage3D", |
| 2581 "No ES3 pack parameters with pixel unpack transfer buffer."); |
| 2582 return; |
| 2583 } |
| 2584 DCHECK_EQ(0u, skip_size); |
2510 GLuint offset = ToGLuint(pixels); | 2585 GLuint offset = ToGLuint(pixels); |
2511 BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid( | 2586 BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid( |
2512 bound_pixel_unpack_transfer_buffer_id_, "glTexImage3D", offset, size); | 2587 bound_pixel_unpack_transfer_buffer_id_, "glTexImage3D", offset, size); |
2513 if (buffer && buffer->shm_id() != -1) { | 2588 if (buffer && buffer->shm_id() != -1) { |
2514 helper_->TexImage3D( | 2589 helper_->TexImage3D( |
2515 target, level, internalformat, width, height, depth, format, type, | 2590 target, level, internalformat, width, height, depth, format, type, |
2516 buffer->shm_id(), buffer->shm_offset() + offset); | 2591 buffer->shm_id(), buffer->shm_offset() + offset); |
2517 buffer->set_last_usage_token(helper_->InsertToken()); | 2592 buffer->set_last_usage_token(helper_->InsertToken()); |
2518 CheckGLError(); | 2593 CheckGLError(); |
2519 } | 2594 } |
2520 return; | 2595 return; |
2521 } | 2596 } |
2522 | 2597 |
2523 // If there's no data just issue TexImage3D | 2598 // If there's no data just issue TexImage3D |
2524 if (!pixels) { | 2599 if (!pixels || width == 0 || height == 0 || depth == 0) { |
2525 helper_->TexImage3D( | 2600 helper_->TexImage3D( |
2526 target, level, internalformat, width, height, depth, format, type, | 2601 target, level, internalformat, width, height, depth, format, type, |
2527 0, 0); | 2602 0, 0); |
2528 CheckGLError(); | 2603 CheckGLError(); |
2529 return; | 2604 return; |
2530 } | 2605 } |
2531 | 2606 |
2532 // compute the advance bytes per row for the src pixels | 2607 // Compute the advance bytes per row on the service side. |
2533 uint32_t src_padded_row_size; | 2608 // Note |size| is recomputed here if needed. |
2534 if (unpack_row_length_ > 0) { | 2609 uint32_t service_padded_row_size; |
2535 if (!GLES2Util::ComputeImagePaddedRowSize( | 2610 if ((unpack_row_length_ > 0 && unpack_row_length_ != width) || |
2536 unpack_row_length_, format, type, unpack_alignment_, | 2611 (unpack_image_height_ > 0 && unpack_image_height_ != height)) { |
2537 &src_padded_row_size)) { | 2612 // All parameters have been applied to the data that are sent to the |
2538 SetGLError( | 2613 // service side except UNPACK_ALIGNMENT. |
2539 GL_INVALID_VALUE, "glTexImage3D", "unpack row length too large"); | 2614 PixelStoreParams service_params; |
| 2615 service_params.alignment = unpack_alignment_; |
| 2616 if (!GLES2Util::ComputeImageDataSizesES3(width, height, depth, |
| 2617 format, type, |
| 2618 service_params, |
| 2619 &size, |
| 2620 nullptr, |
| 2621 &service_padded_row_size, |
| 2622 nullptr, |
| 2623 nullptr)) { |
| 2624 SetGLError(GL_INVALID_VALUE, "glTexImage3D", "image size too large"); |
2540 return; | 2625 return; |
2541 } | 2626 } |
2542 } else { | 2627 } else { |
2543 src_padded_row_size = padded_row_size; | 2628 service_padded_row_size = padded_row_size; |
2544 } | 2629 } |
2545 uint32_t src_height = | 2630 uint32_t src_height = |
2546 unpack_image_height_ > 0 ? unpack_image_height_ : height; | 2631 unpack_image_height_ > 0 ? unpack_image_height_ : height; |
2547 | 2632 |
2548 // advance pixels pointer past the skip images/rows/pixels | 2633 // advance pixels pointer past the skip images/rows/pixels |
2549 pixels = reinterpret_cast<const int8_t*>(pixels) + | 2634 pixels = reinterpret_cast<const int8_t*>(pixels) + skip_size; |
2550 unpack_skip_images_ * src_padded_row_size * src_height + | |
2551 unpack_skip_rows_ * src_padded_row_size; | |
2552 if (unpack_skip_pixels_) { | |
2553 uint32_t group_size = GLES2Util::ComputeImageGroupSize(format, type); | |
2554 pixels = reinterpret_cast<const int8_t*>(pixels) + | |
2555 unpack_skip_pixels_ * group_size; | |
2556 } | |
2557 | 2635 |
2558 // Check if we can send it all at once. | 2636 // Check if we can send it all at once. |
2559 int32_t shm_id = 0; | 2637 int32_t shm_id = 0; |
2560 uint32_t shm_offset = 0; | 2638 uint32_t shm_offset = 0; |
2561 void* buffer_pointer = nullptr; | 2639 void* buffer_pointer = nullptr; |
2562 | 2640 |
2563 ScopedTransferBufferPtr transfer_alloc(size, helper_, transfer_buffer_); | 2641 ScopedTransferBufferPtr transfer_alloc(size, helper_, transfer_buffer_); |
2564 ScopedMappedMemoryPtr mapped_alloc(0, helper_, mapped_memory_.get()); | 2642 ScopedMappedMemoryPtr mapped_alloc(0, helper_, mapped_memory_.get()); |
2565 | 2643 |
2566 if (transfer_alloc.valid() && transfer_alloc.size() >= size) { | 2644 if (transfer_alloc.valid() && transfer_alloc.size() >= size) { |
2567 shm_id = transfer_alloc.shm_id(); | 2645 shm_id = transfer_alloc.shm_id(); |
2568 shm_offset = transfer_alloc.offset(); | 2646 shm_offset = transfer_alloc.offset(); |
2569 buffer_pointer = transfer_alloc.address(); | 2647 buffer_pointer = transfer_alloc.address(); |
2570 } else if (size < max_extra_transfer_buffer_size_) { | 2648 } else if (size < max_extra_transfer_buffer_size_) { |
2571 mapped_alloc.Reset(size); | 2649 mapped_alloc.Reset(size); |
2572 if (mapped_alloc.valid()) { | 2650 if (mapped_alloc.valid()) { |
2573 transfer_alloc.Discard(); | 2651 transfer_alloc.Discard(); |
2574 | 2652 |
2575 mapped_alloc.SetFlushAfterRelease(true); | 2653 mapped_alloc.SetFlushAfterRelease(true); |
2576 shm_id = mapped_alloc.shm_id(); | 2654 shm_id = mapped_alloc.shm_id(); |
2577 shm_offset = mapped_alloc.offset(); | 2655 shm_offset = mapped_alloc.offset(); |
2578 buffer_pointer = mapped_alloc.address(); | 2656 buffer_pointer = mapped_alloc.address(); |
2579 } | 2657 } |
2580 } | 2658 } |
2581 | 2659 |
2582 if (buffer_pointer) { | 2660 if (buffer_pointer) { |
2583 for (GLsizei z = 0; z < depth; ++z) { | 2661 for (GLsizei z = 0; z < depth; ++z) { |
2584 // Only the last row of the last image is unpadded. | |
2585 uint32_t src_unpadded_row_size = | |
2586 (z == depth - 1) ? unpadded_row_size : src_padded_row_size; | |
2587 CopyRectToBuffer( | 2662 CopyRectToBuffer( |
2588 pixels, height, src_unpadded_row_size, src_padded_row_size, | 2663 pixels, height, unpadded_row_size, padded_row_size, |
2589 buffer_pointer, padded_row_size); | 2664 buffer_pointer, service_padded_row_size); |
2590 pixels = reinterpret_cast<const int8_t*>(pixels) + | 2665 pixels = reinterpret_cast<const int8_t*>(pixels) + |
2591 src_padded_row_size * src_height; | 2666 padded_row_size * src_height; |
2592 buffer_pointer = | 2667 buffer_pointer = reinterpret_cast<int8_t*>(buffer_pointer) + |
2593 reinterpret_cast<int8_t*>(buffer_pointer) + padded_row_size * height; | 2668 service_padded_row_size * height; |
2594 } | 2669 } |
2595 helper_->TexImage3D( | 2670 helper_->TexImage3D( |
2596 target, level, internalformat, width, height, depth, format, type, | 2671 target, level, internalformat, width, height, depth, format, type, |
2597 shm_id, shm_offset); | 2672 shm_id, shm_offset); |
2598 CheckGLError(); | 2673 CheckGLError(); |
2599 return; | 2674 return; |
2600 } | 2675 } |
2601 | 2676 |
2602 // No, so send it using TexSubImage3D. | 2677 // No, so send it using TexSubImage3D. |
2603 helper_->TexImage3D( | 2678 helper_->TexImage3D( |
2604 target, level, internalformat, width, height, depth, format, type, | 2679 target, level, internalformat, width, height, depth, format, type, |
2605 0, 0); | 2680 0, 0); |
2606 TexSubImage3DImpl( | 2681 TexSubImage3DImpl( |
2607 target, level, 0, 0, 0, width, height, depth, format, type, | 2682 target, level, 0, 0, 0, width, height, depth, format, type, |
2608 unpadded_row_size, pixels, src_padded_row_size, GL_TRUE, &transfer_alloc, | 2683 unpadded_row_size, pixels, padded_row_size, GL_TRUE, &transfer_alloc, |
2609 padded_row_size); | 2684 service_padded_row_size); |
2610 CheckGLError(); | 2685 CheckGLError(); |
2611 } | 2686 } |
2612 | 2687 |
2613 void GLES2Implementation::TexSubImage2D( | 2688 void GLES2Implementation::TexSubImage2D( |
2614 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, | 2689 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, |
2615 GLsizei height, GLenum format, GLenum type, const void* pixels) { | 2690 GLsizei height, GLenum format, GLenum type, const void* pixels) { |
2616 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 2691 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
2617 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexSubImage2D(" | 2692 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexSubImage2D(" |
2618 << GLES2Util::GetStringTextureTarget(target) << ", " | 2693 << GLES2Util::GetStringTextureTarget(target) << ", " |
2619 << level << ", " | 2694 << level << ", " |
2620 << xoffset << ", " << yoffset << ", " | 2695 << xoffset << ", " << yoffset << ", " |
2621 << width << ", " << height << ", " | 2696 << width << ", " << height << ", " |
2622 << GLES2Util::GetStringTextureFormat(format) << ", " | 2697 << GLES2Util::GetStringTextureFormat(format) << ", " |
2623 << GLES2Util::GetStringPixelType(type) << ", " | 2698 << GLES2Util::GetStringPixelType(type) << ", " |
2624 << static_cast<const void*>(pixels) << ")"); | 2699 << static_cast<const void*>(pixels) << ")"); |
2625 | 2700 |
2626 if (level < 0 || height < 0 || width < 0) { | 2701 if (level < 0 || height < 0 || width < 0 || xoffset < 0 || yoffset < 0) { |
2627 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "dimension < 0"); | 2702 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "dimension < 0"); |
2628 return; | 2703 return; |
2629 } | 2704 } |
2630 if (height == 0 || width == 0) { | 2705 |
| 2706 uint32_t size; |
| 2707 uint32_t unpadded_row_size; |
| 2708 uint32_t padded_row_size; |
| 2709 uint32_t skip_size; |
| 2710 PixelStoreParams params = GetUnpackParameters(k2D); |
| 2711 if (!GLES2Util::ComputeImageDataSizesES3(width, height, 1, |
| 2712 format, type, |
| 2713 params, |
| 2714 &size, |
| 2715 &unpadded_row_size, |
| 2716 &padded_row_size, |
| 2717 &skip_size, |
| 2718 nullptr)) { |
| 2719 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "image size to large"); |
2631 return; | 2720 return; |
2632 } | 2721 } |
2633 | 2722 |
2634 uint32_t temp_size; | 2723 if (bound_pixel_unpack_buffer_) { |
2635 uint32_t unpadded_row_size; | 2724 base::CheckedNumeric<uint32_t> offset = ToGLuint(pixels); |
2636 uint32_t padded_row_size; | 2725 offset += skip_size; |
2637 if (!GLES2Util::ComputeImageDataSizes( | 2726 if (!offset.IsValid()) { |
2638 width, height, 1, format, type, unpack_alignment_, &temp_size, | 2727 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "skip size too large"); |
2639 &unpadded_row_size, &padded_row_size)) { | 2728 return; |
2640 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "size to large"); | 2729 } |
| 2730 helper_->TexSubImage2D(target, level, xoffset, yoffset, width, height, |
| 2731 format, type, 0, offset.ValueOrDefault(0), false); |
| 2732 CheckGLError(); |
2641 return; | 2733 return; |
2642 } | 2734 } |
2643 | 2735 |
2644 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. | 2736 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. |
2645 if (bound_pixel_unpack_transfer_buffer_id_) { | 2737 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 2738 if (unpack_row_length_ > 0 || unpack_image_height_ > 0 || |
| 2739 unpack_skip_pixels_ > 0 || unpack_skip_rows_ > 0 || |
| 2740 unpack_skip_images_ > 0) { |
| 2741 SetGLError(GL_INVALID_OPERATION, "glTexSubImage2D", |
| 2742 "No ES3 pack parameters with pixel unpack transfer buffer."); |
| 2743 return; |
| 2744 } |
| 2745 DCHECK_EQ(0u, skip_size); |
2646 GLuint offset = ToGLuint(pixels); | 2746 GLuint offset = ToGLuint(pixels); |
2647 BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid( | 2747 BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid( |
2648 bound_pixel_unpack_transfer_buffer_id_, | 2748 bound_pixel_unpack_transfer_buffer_id_, |
2649 "glTexSubImage2D", offset, temp_size); | 2749 "glTexSubImage2D", offset, size); |
2650 if (buffer && buffer->shm_id() != -1) { | 2750 if (buffer && buffer->shm_id() != -1) { |
2651 helper_->TexSubImage2D( | 2751 helper_->TexSubImage2D( |
2652 target, level, xoffset, yoffset, width, height, format, type, | 2752 target, level, xoffset, yoffset, width, height, format, type, |
2653 buffer->shm_id(), buffer->shm_offset() + offset, false); | 2753 buffer->shm_id(), buffer->shm_offset() + offset, false); |
2654 buffer->set_last_usage_token(helper_->InsertToken()); | 2754 buffer->set_last_usage_token(helper_->InsertToken()); |
2655 CheckGLError(); | 2755 CheckGLError(); |
2656 } | 2756 } |
2657 return; | 2757 return; |
2658 } | 2758 } |
2659 | 2759 |
2660 // compute the advance bytes per row for the src pixels | 2760 if (width == 0 || height == 0) { |
2661 uint32_t src_padded_row_size; | 2761 // No need to worry about pixel data. |
2662 if (unpack_row_length_ > 0) { | 2762 helper_->TexSubImage2D(target, level, xoffset, yoffset, width, height, |
2663 if (!GLES2Util::ComputeImagePaddedRowSize( | 2763 format, type, 0, 0, false); |
2664 unpack_row_length_, format, type, unpack_alignment_, | 2764 CheckGLError(); |
2665 &src_padded_row_size)) { | 2765 return; |
2666 SetGLError( | 2766 } |
2667 GL_INVALID_VALUE, "glTexImage2D", "unpack row length too large"); | 2767 |
| 2768 // Compute the advance bytes per row on the service side. |
| 2769 // Note |size| is recomputed here if needed. |
| 2770 uint32_t service_padded_row_size; |
| 2771 if (unpack_row_length_ > 0 && unpack_row_length_ != width) { |
| 2772 // All parameters have been applied to the data that are sent to the |
| 2773 // service side except UNPACK_ALIGNMENT. |
| 2774 PixelStoreParams service_params; |
| 2775 service_params.alignment = unpack_alignment_; |
| 2776 if (!GLES2Util::ComputeImageDataSizesES3(width, height, 1, |
| 2777 format, type, |
| 2778 service_params, |
| 2779 &size, |
| 2780 nullptr, |
| 2781 &service_padded_row_size, |
| 2782 nullptr, |
| 2783 nullptr)) { |
| 2784 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "image size too large"); |
2668 return; | 2785 return; |
2669 } | 2786 } |
2670 } else { | 2787 } else { |
2671 src_padded_row_size = padded_row_size; | 2788 service_padded_row_size = padded_row_size; |
2672 } | 2789 } |
2673 | 2790 |
2674 // advance pixels pointer past the skip rows and skip pixels | 2791 // advance pixels pointer past the skip rows and skip pixels |
2675 pixels = reinterpret_cast<const int8_t*>(pixels) + | 2792 pixels = reinterpret_cast<const int8_t*>(pixels) + skip_size; |
2676 unpack_skip_rows_ * src_padded_row_size; | |
2677 if (unpack_skip_pixels_) { | |
2678 uint32_t group_size = GLES2Util::ComputeImageGroupSize(format, type); | |
2679 pixels = reinterpret_cast<const int8_t*>(pixels) + | |
2680 unpack_skip_pixels_ * group_size; | |
2681 } | |
2682 | 2793 |
2683 ScopedTransferBufferPtr buffer(temp_size, helper_, transfer_buffer_); | 2794 ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); |
2684 TexSubImage2DImpl( | 2795 TexSubImage2DImpl( |
2685 target, level, xoffset, yoffset, width, height, format, type, | 2796 target, level, xoffset, yoffset, width, height, format, type, |
2686 unpadded_row_size, pixels, src_padded_row_size, GL_FALSE, &buffer, | 2797 unpadded_row_size, pixels, padded_row_size, GL_FALSE, &buffer, |
2687 padded_row_size); | 2798 service_padded_row_size); |
2688 CheckGLError(); | 2799 CheckGLError(); |
2689 } | 2800 } |
2690 | 2801 |
2691 void GLES2Implementation::TexSubImage3D( | 2802 void GLES2Implementation::TexSubImage3D( |
2692 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, | 2803 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, |
2693 GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, | 2804 GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, |
2694 const void* pixels) { | 2805 const void* pixels) { |
2695 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 2806 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
2696 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexSubImage3D(" | 2807 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexSubImage3D(" |
2697 << GLES2Util::GetStringTextureTarget(target) << ", " | 2808 << GLES2Util::GetStringTextureTarget(target) << ", " |
2698 << level << ", " | 2809 << level << ", " |
2699 << xoffset << ", " << yoffset << ", " << zoffset << ", " | 2810 << xoffset << ", " << yoffset << ", " << zoffset << ", " |
2700 << width << ", " << height << ", " << depth << ", " | 2811 << width << ", " << height << ", " << depth << ", " |
2701 << GLES2Util::GetStringTextureFormat(format) << ", " | 2812 << GLES2Util::GetStringTextureFormat(format) << ", " |
2702 << GLES2Util::GetStringPixelType(type) << ", " | 2813 << GLES2Util::GetStringPixelType(type) << ", " |
2703 << static_cast<const void*>(pixels) << ")"); | 2814 << static_cast<const void*>(pixels) << ")"); |
2704 | 2815 |
2705 if (level < 0 || height < 0 || width < 0 || depth < 0) { | 2816 if (level < 0 || height < 0 || width < 0 || depth < 0 || |
| 2817 xoffset < 0 || yoffset < 0 || zoffset < 0) { |
2706 SetGLError(GL_INVALID_VALUE, "glTexSubImage3D", "dimension < 0"); | 2818 SetGLError(GL_INVALID_VALUE, "glTexSubImage3D", "dimension < 0"); |
2707 return; | 2819 return; |
2708 } | 2820 } |
2709 if (height == 0 || width == 0 || depth == 0) { | 2821 |
| 2822 uint32_t size; |
| 2823 uint32_t unpadded_row_size; |
| 2824 uint32_t padded_row_size; |
| 2825 uint32_t skip_size; |
| 2826 PixelStoreParams params = GetUnpackParameters(k3D); |
| 2827 if (!GLES2Util::ComputeImageDataSizesES3(width, height, depth, |
| 2828 format, type, |
| 2829 params, |
| 2830 &size, |
| 2831 &unpadded_row_size, |
| 2832 &padded_row_size, |
| 2833 &skip_size, |
| 2834 nullptr)) { |
| 2835 SetGLError(GL_INVALID_VALUE, "glTexSubImage3D", "image size to large"); |
2710 return; | 2836 return; |
2711 } | 2837 } |
2712 | 2838 |
2713 uint32_t temp_size; | 2839 if (bound_pixel_unpack_buffer_) { |
2714 uint32_t unpadded_row_size; | 2840 base::CheckedNumeric<uint32_t> offset = ToGLuint(pixels); |
2715 uint32_t padded_row_size; | 2841 offset += skip_size; |
2716 if (!GLES2Util::ComputeImageDataSizes( | 2842 if (!offset.IsValid()) { |
2717 width, height, depth, format, type, unpack_alignment_, &temp_size, | 2843 SetGLError(GL_INVALID_VALUE, "glTexSubImage3D", "skip size too large"); |
2718 &unpadded_row_size, &padded_row_size)) { | 2844 return; |
2719 SetGLError(GL_INVALID_VALUE, "glTexSubImage3D", "size to large"); | 2845 } |
| 2846 helper_->TexSubImage3D( |
| 2847 target, level, xoffset, yoffset, zoffset, width, height, depth, |
| 2848 format, type, 0, offset.ValueOrDefault(0), false); |
| 2849 CheckGLError(); |
2720 return; | 2850 return; |
2721 } | 2851 } |
2722 | 2852 |
2723 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. | 2853 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. |
2724 if (bound_pixel_unpack_transfer_buffer_id_) { | 2854 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 2855 if (unpack_row_length_ > 0 || unpack_image_height_ > 0 || |
| 2856 unpack_skip_pixels_ > 0 || unpack_skip_rows_ > 0 || |
| 2857 unpack_skip_images_ > 0) { |
| 2858 SetGLError(GL_INVALID_OPERATION, "glTexSubImage2D", |
| 2859 "No ES3 pack parameters with pixel unpack transfer buffer."); |
| 2860 return; |
| 2861 } |
| 2862 DCHECK_EQ(0u, skip_size); |
2725 GLuint offset = ToGLuint(pixels); | 2863 GLuint offset = ToGLuint(pixels); |
2726 BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid( | 2864 BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid( |
2727 bound_pixel_unpack_transfer_buffer_id_, | 2865 bound_pixel_unpack_transfer_buffer_id_, |
2728 "glTexSubImage3D", offset, temp_size); | 2866 "glTexSubImage3D", offset, size); |
2729 if (buffer && buffer->shm_id() != -1) { | 2867 if (buffer && buffer->shm_id() != -1) { |
2730 helper_->TexSubImage3D( | 2868 helper_->TexSubImage3D( |
2731 target, level, xoffset, yoffset, zoffset, width, height, depth, | 2869 target, level, xoffset, yoffset, zoffset, width, height, depth, |
2732 format, type, buffer->shm_id(), buffer->shm_offset() + offset, false); | 2870 format, type, buffer->shm_id(), buffer->shm_offset() + offset, false); |
2733 buffer->set_last_usage_token(helper_->InsertToken()); | 2871 buffer->set_last_usage_token(helper_->InsertToken()); |
2734 CheckGLError(); | 2872 CheckGLError(); |
2735 } | 2873 } |
2736 return; | 2874 return; |
2737 } | 2875 } |
2738 | 2876 |
2739 // compute the advance bytes per row for the src pixels | 2877 if (width == 0 || height == 0 || depth == 0) { |
2740 uint32_t src_padded_row_size; | 2878 // No need to worry about pixel data. |
2741 if (unpack_row_length_ > 0) { | 2879 helper_->TexSubImage3D(target, level, xoffset, yoffset, zoffset, |
2742 if (!GLES2Util::ComputeImagePaddedRowSize( | 2880 width, height, depth, format, type, 0, 0, false); |
2743 unpack_row_length_, format, type, unpack_alignment_, | 2881 CheckGLError(); |
2744 &src_padded_row_size)) { | 2882 return; |
2745 SetGLError( | 2883 } |
2746 GL_INVALID_VALUE, "glTexImage3D", "unpack row length too large"); | 2884 |
| 2885 // Compute the advance bytes per row on the service side |
| 2886 // Note |size| is recomputed here if needed. |
| 2887 uint32_t service_padded_row_size; |
| 2888 if ((unpack_row_length_ > 0 && unpack_row_length_ != width) || |
| 2889 (unpack_image_height_ > 0 && unpack_image_height_ != height)) { |
| 2890 PixelStoreParams service_params; |
| 2891 service_params.alignment = unpack_alignment_; |
| 2892 if (!GLES2Util::ComputeImageDataSizesES3(width, height, depth, |
| 2893 format, type, |
| 2894 service_params, |
| 2895 &size, |
| 2896 nullptr, |
| 2897 &service_padded_row_size, |
| 2898 nullptr, |
| 2899 nullptr)) { |
| 2900 SetGLError(GL_INVALID_VALUE, "glTexSubImage3D", "image size too large"); |
2747 return; | 2901 return; |
2748 } | 2902 } |
2749 } else { | 2903 } else { |
2750 src_padded_row_size = padded_row_size; | 2904 service_padded_row_size = padded_row_size; |
2751 } | 2905 } |
2752 uint32_t src_height = | |
2753 unpack_image_height_ > 0 ? unpack_image_height_ : height; | |
2754 | 2906 |
2755 // advance pixels pointer past the skip images/rows/pixels | 2907 // advance pixels pointer past the skip images/rows/pixels |
2756 pixels = reinterpret_cast<const int8_t*>(pixels) + | 2908 pixels = reinterpret_cast<const int8_t*>(pixels) + skip_size; |
2757 unpack_skip_images_ * src_padded_row_size * src_height + | |
2758 unpack_skip_rows_ * src_padded_row_size; | |
2759 if (unpack_skip_pixels_) { | |
2760 uint32_t group_size = GLES2Util::ComputeImageGroupSize(format, type); | |
2761 pixels = reinterpret_cast<const int8_t*>(pixels) + | |
2762 unpack_skip_pixels_ * group_size; | |
2763 } | |
2764 | 2909 |
2765 ScopedTransferBufferPtr buffer(temp_size, helper_, transfer_buffer_); | 2910 ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); |
2766 TexSubImage3DImpl( | 2911 TexSubImage3DImpl( |
2767 target, level, xoffset, yoffset, zoffset, width, height, depth, | 2912 target, level, xoffset, yoffset, zoffset, width, height, depth, |
2768 format, type, unpadded_row_size, pixels, src_padded_row_size, GL_FALSE, | 2913 format, type, unpadded_row_size, pixels, padded_row_size, GL_FALSE, |
2769 &buffer, padded_row_size); | 2914 &buffer, service_padded_row_size); |
2770 CheckGLError(); | 2915 CheckGLError(); |
2771 } | 2916 } |
2772 | 2917 |
2773 static GLint ComputeNumRowsThatFitInBuffer(uint32_t padded_row_size, | 2918 static GLint ComputeNumRowsThatFitInBuffer(uint32_t padded_row_size, |
2774 uint32_t unpadded_row_size, | 2919 uint32_t unpadded_row_size, |
2775 unsigned int size, | 2920 unsigned int size, |
2776 GLsizei remaining_rows) { | 2921 GLsizei remaining_rows) { |
2777 DCHECK_GE(unpadded_row_size, 0u); | 2922 DCHECK_GE(unpadded_row_size, 0u); |
2778 if (padded_row_size == 0) { | 2923 if (padded_row_size == 0) { |
2779 return 1; | 2924 return 1; |
(...skipping 17 matching lines...) Expand all Loading... |
2797 uint32_t unpadded_row_size, | 2942 uint32_t unpadded_row_size, |
2798 const void* pixels, | 2943 const void* pixels, |
2799 uint32_t pixels_padded_row_size, | 2944 uint32_t pixels_padded_row_size, |
2800 GLboolean internal, | 2945 GLboolean internal, |
2801 ScopedTransferBufferPtr* buffer, | 2946 ScopedTransferBufferPtr* buffer, |
2802 uint32_t buffer_padded_row_size) { | 2947 uint32_t buffer_padded_row_size) { |
2803 DCHECK(buffer); | 2948 DCHECK(buffer); |
2804 DCHECK_GE(level, 0); | 2949 DCHECK_GE(level, 0); |
2805 DCHECK_GT(height, 0); | 2950 DCHECK_GT(height, 0); |
2806 DCHECK_GT(width, 0); | 2951 DCHECK_GT(width, 0); |
| 2952 DCHECK_GE(xoffset, 0); |
| 2953 DCHECK_GE(yoffset, 0); |
2807 | 2954 |
2808 const int8_t* source = reinterpret_cast<const int8_t*>(pixels); | 2955 const int8_t* source = reinterpret_cast<const int8_t*>(pixels); |
2809 // Transfer by rows. | 2956 // Transfer by rows. |
2810 while (height) { | 2957 while (height) { |
2811 unsigned int desired_size = | 2958 unsigned int desired_size = |
2812 buffer_padded_row_size * (height - 1) + unpadded_row_size; | 2959 buffer_padded_row_size * (height - 1) + unpadded_row_size; |
2813 if (!buffer->valid() || buffer->size() == 0) { | 2960 if (!buffer->valid() || buffer->size() == 0) { |
2814 buffer->Reset(desired_size); | 2961 buffer->Reset(desired_size); |
2815 if (!buffer->valid()) { | 2962 if (!buffer->valid()) { |
2816 return; | 2963 return; |
(...skipping 27 matching lines...) Expand all Loading... |
2844 GLenum format, | 2991 GLenum format, |
2845 GLenum type, | 2992 GLenum type, |
2846 uint32_t unpadded_row_size, | 2993 uint32_t unpadded_row_size, |
2847 const void* pixels, | 2994 const void* pixels, |
2848 uint32_t pixels_padded_row_size, | 2995 uint32_t pixels_padded_row_size, |
2849 GLboolean internal, | 2996 GLboolean internal, |
2850 ScopedTransferBufferPtr* buffer, | 2997 ScopedTransferBufferPtr* buffer, |
2851 uint32_t buffer_padded_row_size) { | 2998 uint32_t buffer_padded_row_size) { |
2852 DCHECK(buffer); | 2999 DCHECK(buffer); |
2853 DCHECK_GE(level, 0); | 3000 DCHECK_GE(level, 0); |
| 3001 DCHECK_GT(width, 0); |
2854 DCHECK_GT(height, 0); | 3002 DCHECK_GT(height, 0); |
2855 DCHECK_GT(width, 0); | |
2856 DCHECK_GT(depth, 0); | 3003 DCHECK_GT(depth, 0); |
| 3004 DCHECK_GE(xoffset, 0); |
| 3005 DCHECK_GE(yoffset, 0); |
| 3006 DCHECK_GE(zoffset, 0); |
2857 const int8_t* source = reinterpret_cast<const int8_t*>(pixels); | 3007 const int8_t* source = reinterpret_cast<const int8_t*>(pixels); |
2858 GLsizei total_rows = height * depth; | 3008 GLsizei total_rows = height * depth; |
2859 GLint row_index = 0, depth_index = 0; | 3009 GLint row_index = 0, depth_index = 0; |
2860 while (total_rows) { | 3010 while (total_rows) { |
2861 // Each time, we either copy one or more images, or copy one or more rows | 3011 // Each time, we either copy one or more images, or copy one or more rows |
2862 // within a single image, depending on the buffer size limit. | 3012 // within a single image, depending on the buffer size limit. |
2863 GLsizei max_rows; | 3013 GLsizei max_rows; |
2864 unsigned int desired_size; | 3014 unsigned int desired_size; |
2865 if (row_index > 0) { | 3015 if (row_index > 0) { |
2866 // We are in the middle of an image. Send the remaining of the image. | 3016 // 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... |
2898 my_depth = 1; | 3048 my_depth = 1; |
2899 } | 3049 } |
2900 | 3050 |
2901 if (num_images > 0) { | 3051 if (num_images > 0) { |
2902 int8_t* buffer_pointer = reinterpret_cast<int8_t*>(buffer->address()); | 3052 int8_t* buffer_pointer = reinterpret_cast<int8_t*>(buffer->address()); |
2903 uint32_t src_height = | 3053 uint32_t src_height = |
2904 unpack_image_height_ > 0 ? unpack_image_height_ : height; | 3054 unpack_image_height_ > 0 ? unpack_image_height_ : height; |
2905 uint32_t image_size_dst = buffer_padded_row_size * height; | 3055 uint32_t image_size_dst = buffer_padded_row_size * height; |
2906 uint32_t image_size_src = pixels_padded_row_size * src_height; | 3056 uint32_t image_size_src = pixels_padded_row_size * src_height; |
2907 for (GLint ii = 0; ii < num_images; ++ii) { | 3057 for (GLint ii = 0; ii < num_images; ++ii) { |
2908 uint32_t my_unpadded_row_size; | |
2909 if (total_rows == num_rows && ii + 1 == num_images) | |
2910 my_unpadded_row_size = unpadded_row_size; | |
2911 else | |
2912 my_unpadded_row_size = pixels_padded_row_size; | |
2913 CopyRectToBuffer( | 3058 CopyRectToBuffer( |
2914 source + ii * image_size_src, my_height, my_unpadded_row_size, | 3059 source + ii * image_size_src, my_height, unpadded_row_size, |
2915 pixels_padded_row_size, buffer_pointer + ii * image_size_dst, | 3060 pixels_padded_row_size, buffer_pointer + ii * image_size_dst, |
2916 buffer_padded_row_size); | 3061 buffer_padded_row_size); |
2917 } | 3062 } |
2918 } else { | 3063 } else { |
2919 uint32_t my_unpadded_row_size; | |
2920 if (total_rows == num_rows) | |
2921 my_unpadded_row_size = unpadded_row_size; | |
2922 else | |
2923 my_unpadded_row_size = pixels_padded_row_size; | |
2924 CopyRectToBuffer( | 3064 CopyRectToBuffer( |
2925 source, my_height, my_unpadded_row_size, pixels_padded_row_size, | 3065 source, my_height, unpadded_row_size, pixels_padded_row_size, |
2926 buffer->address(), buffer_padded_row_size); | 3066 buffer->address(), buffer_padded_row_size); |
2927 } | 3067 } |
2928 helper_->TexSubImage3D( | 3068 helper_->TexSubImage3D( |
2929 target, level, xoffset, yoffset + row_index, zoffset + depth_index, | 3069 target, level, xoffset, yoffset + row_index, zoffset + depth_index, |
2930 width, my_height, my_depth, | 3070 width, my_height, my_depth, |
2931 format, type, buffer->shm_id(), buffer->offset(), internal); | 3071 format, type, buffer->shm_id(), buffer->offset(), internal); |
2932 buffer->Release(); | 3072 buffer->Release(); |
2933 | 3073 |
2934 total_rows -= num_rows; | 3074 total_rows -= num_rows; |
2935 if (total_rows > 0) { | 3075 if (total_rows > 0) { |
(...skipping 3729 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6665 cached_extensions_.clear(); | 6805 cached_extensions_.clear(); |
6666 } | 6806 } |
6667 | 6807 |
6668 // Include the auto-generated part of this file. We split this because it means | 6808 // Include the auto-generated part of this file. We split this because it means |
6669 // we can easily edit the non-auto generated parts right here in this file | 6809 // we can easily edit the non-auto generated parts right here in this file |
6670 // instead of having to edit some template or the code generator. | 6810 // instead of having to edit some template or the code generator. |
6671 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" | 6811 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" |
6672 | 6812 |
6673 } // namespace gles2 | 6813 } // namespace gles2 |
6674 } // namespace gpu | 6814 } // namespace gpu |
OLD | NEW |