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