Chromium Code Reviews| 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 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
| 6 | 6 |
| 7 #include <stdio.h> | 7 #include <stdio.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <list> | 10 #include <list> |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 48 #include "gpu/command_buffer/service/renderbuffer_manager.h" | 48 #include "gpu/command_buffer/service/renderbuffer_manager.h" |
| 49 #include "gpu/command_buffer/service/shader_manager.h" | 49 #include "gpu/command_buffer/service/shader_manager.h" |
| 50 #include "gpu/command_buffer/service/shader_translator.h" | 50 #include "gpu/command_buffer/service/shader_translator.h" |
| 51 #include "gpu/command_buffer/service/shader_translator_cache.h" | 51 #include "gpu/command_buffer/service/shader_translator_cache.h" |
| 52 #include "gpu/command_buffer/service/stream_texture.h" | 52 #include "gpu/command_buffer/service/stream_texture.h" |
| 53 #include "gpu/command_buffer/service/stream_texture_manager.h" | 53 #include "gpu/command_buffer/service/stream_texture_manager.h" |
| 54 #include "gpu/command_buffer/service/texture_definition.h" | 54 #include "gpu/command_buffer/service/texture_definition.h" |
| 55 #include "gpu/command_buffer/service/texture_manager.h" | 55 #include "gpu/command_buffer/service/texture_manager.h" |
| 56 #include "gpu/command_buffer/service/vertex_attrib_manager.h" | 56 #include "gpu/command_buffer/service/vertex_attrib_manager.h" |
| 57 #include "gpu/command_buffer/service/vertex_array_manager.h" | 57 #include "gpu/command_buffer/service/vertex_array_manager.h" |
| 58 #include "ui/gl/async_pixel_transfer_delegate.h" | |
| 58 #include "ui/gl/gl_image.h" | 59 #include "ui/gl/gl_image.h" |
| 59 #include "ui/gl/gl_implementation.h" | 60 #include "ui/gl/gl_implementation.h" |
| 60 #include "ui/gl/gl_surface.h" | 61 #include "ui/gl/gl_surface.h" |
| 61 #if defined(OS_MACOSX) | 62 #if defined(OS_MACOSX) |
| 62 #include "ui/surface/io_surface_support_mac.h" | 63 #include "ui/surface/io_surface_support_mac.h" |
| 63 #endif | 64 #endif |
| 64 | 65 |
| 65 #if !defined(GL_DEPTH24_STENCIL8) | 66 #if !defined(GL_DEPTH24_STENCIL8) |
| 66 #define GL_DEPTH24_STENCIL8 0x88F0 | 67 #define GL_DEPTH24_STENCIL8 0x88F0 |
| 67 #endif | 68 #endif |
| (...skipping 3431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3499 if (info->target() != 0 && info->target() != target) { | 3500 if (info->target() != 0 && info->target() != target) { |
| 3500 SetGLError(GL_INVALID_OPERATION, | 3501 SetGLError(GL_INVALID_OPERATION, |
| 3501 "glBindTexture", "texture bound to more than 1 target."); | 3502 "glBindTexture", "texture bound to more than 1 target."); |
| 3502 return; | 3503 return; |
| 3503 } | 3504 } |
| 3504 if (info->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) { | 3505 if (info->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) { |
| 3505 SetGLError(GL_INVALID_OPERATION, | 3506 SetGLError(GL_INVALID_OPERATION, |
| 3506 "glBindTexture", "illegal target for stream texture."); | 3507 "glBindTexture", "illegal target for stream texture."); |
| 3507 return; | 3508 return; |
| 3508 } | 3509 } |
| 3509 if (info->target() == 0) { | 3510 |
| 3510 texture_manager()->SetInfoTarget(info, target); | 3511 if (!info->IsAsyncTransferTexture()) { |
| 3512 if (info->target() == 0) { | |
| 3513 texture_manager()->SetInfoTarget(info, target); | |
| 3514 } | |
| 3515 glBindTexture(target, info->service_id()); | |
| 3516 } else { | |
| 3517 // If the texture has async transfers, they must be complete. | |
| 3518 if (info->AsyncTransferIsInProgress()) { | |
| 3519 SetGLError(GL_INVALID_OPERATION, | |
| 3520 "glBindTexture", "async transfer already in progress"); | |
| 3521 return; | |
| 3522 } | |
| 3523 | |
| 3524 if (info->target() == 0) { | |
| 3525 texture_manager()->SetInfoTarget(info, target); | |
| 3526 } | |
| 3527 | |
| 3528 // Bind the GL texture, and perform any custom binding. | |
| 3529 info->BindAsyncTransferTexture(target); | |
| 3530 | |
| 3531 // We now know the transfer texture is cleared. | |
| 3532 texture_manager()->SetLevelCleared(info, target, 0); | |
| 3511 } | 3533 } |
| 3512 glBindTexture(target, info->service_id()); | 3534 |
| 3535 | |
| 3513 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; | 3536 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; |
| 3514 unit.bind_target = target; | 3537 unit.bind_target = target; |
| 3515 switch (target) { | 3538 switch (target) { |
| 3516 case GL_TEXTURE_2D: | 3539 case GL_TEXTURE_2D: |
| 3517 unit.bound_texture_2d = info; | 3540 unit.bound_texture_2d = info; |
| 3518 break; | 3541 break; |
| 3519 case GL_TEXTURE_CUBE_MAP: | 3542 case GL_TEXTURE_CUBE_MAP: |
| 3520 unit.bound_texture_cube_map = info; | 3543 unit.bound_texture_cube_map = info; |
| 3521 break; | 3544 break; |
| 3522 case GL_TEXTURE_EXTERNAL_OES: | 3545 case GL_TEXTURE_EXTERNAL_OES: |
| (...skipping 5817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9340 } | 9363 } |
| 9341 const void* pixels = NULL; | 9364 const void* pixels = NULL; |
| 9342 if (pixels_shm_id != 0 || pixels_shm_offset != 0) { | 9365 if (pixels_shm_id != 0 || pixels_shm_offset != 0) { |
| 9343 pixels = GetSharedMemoryAs<const void*>( | 9366 pixels = GetSharedMemoryAs<const void*>( |
| 9344 pixels_shm_id, pixels_shm_offset, pixels_size); | 9367 pixels_shm_id, pixels_shm_offset, pixels_size); |
| 9345 if (!pixels) { | 9368 if (!pixels) { |
| 9346 return error::kOutOfBounds; | 9369 return error::kOutOfBounds; |
| 9347 } | 9370 } |
| 9348 } | 9371 } |
| 9349 | 9372 |
| 9350 // TODO(epenner): Do this via an async task. | 9373 // We only support async uploads to 2D textures for now. |
| 9351 return DoTexImage2D( | 9374 if (target != GL_TEXTURE_2D) { |
| 9352 target, level, internal_format, width, height, border, format, type, | 9375 SetGLErrorInvalidEnum("glTexSubImage2D", type, "type"); |
|
greggman
2012/12/06 06:52:00
"glAsyncTexImage2DCHROMIUM"
epenner
2012/12/08 03:15:04
Done.
| |
| 9353 pixels, pixels_size); | 9376 return error::kNoError; |
| 9377 } | |
| 9378 | |
| 9379 // We only support uploads to level zero for now. | |
| 9380 if (level != 0) { | |
| 9381 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "level != 0"); | |
|
greggman
2012/12/06 06:52:00
"glAsyncTexImage2DCHROMIUM"
epenner
2012/12/08 03:15:04
Done.
| |
| 9382 return error::kNoError; | |
| 9383 } | |
| 9384 | |
| 9385 // We only support one async transfer in progress. | |
| 9386 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); | |
| 9387 if (!info || info->AsyncTransferIsInProgress()) { | |
| 9388 SetGLError(GL_INVALID_OPERATION, | |
| 9389 "glAsyncTexImage2D", "transfer already in progress"); | |
|
greggman
2012/12/06 06:52:00
"glAsyncTexImage2DCHROMIUM"
epenner
2012/12/08 03:15:04
Done.
| |
| 9390 } | |
| 9391 | |
| 9392 // We know the memory/size is safe, so get the real shared | |
| 9393 // memory since it might need to be duped to prevent | |
| 9394 // use-after-free issues. | |
| 9395 Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id); | |
| 9396 base::SharedMemory* shared_memory = buffer.shared_memory; | |
| 9397 uint32 shm_size = buffer.size; | |
| 9398 uint32 shm_data_offset = c.pixels_shm_offset; | |
| 9399 uint32 shm_data_size = pixels_size; | |
| 9400 | |
| 9401 gfx::AsyncPixelTransferDelegate::Get()->AsyncTexImage2D( | |
| 9402 info->AsyncTransferState(), | |
| 9403 target, level, internal_format, | |
| 9404 width, height, border, format, type, | |
| 9405 shared_memory, shm_size, shm_data_offset, shm_data_size); | |
| 9406 | |
| 9407 return error::kNoError; | |
| 9354 } | 9408 } |
| 9355 | 9409 |
| 9356 error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM( | 9410 error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM( |
| 9357 uint32 immediate_data_size, const gles2::AsyncTexSubImage2DCHROMIUM& c) { | 9411 uint32 immediate_data_size, const gles2::AsyncTexSubImage2DCHROMIUM& c) { |
| 9358 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM"); | 9412 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM"); |
| 9359 | 9413 |
| 9360 // TODO: This is a copy of HandleTexSubImage2D validation. Merge | 9414 // TODO: This is a copy of HandleTexSubImage2D validation. Merge |
| 9361 // as much of it as possible. | 9415 // as much of it as possible. |
| 9362 GLenum target = static_cast<GLenum>(c.target); | 9416 GLenum target = static_cast<GLenum>(c.target); |
| 9363 GLint level = static_cast<GLint>(c.level); | 9417 GLint level = static_cast<GLint>(c.level); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 9381 } | 9435 } |
| 9382 if (width < 0) { | 9436 if (width < 0) { |
| 9383 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "width < 0"); | 9437 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "width < 0"); |
| 9384 return error::kNoError; | 9438 return error::kNoError; |
| 9385 } | 9439 } |
| 9386 if (height < 0) { | 9440 if (height < 0) { |
| 9387 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "height < 0"); | 9441 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "height < 0"); |
| 9388 return error::kNoError; | 9442 return error::kNoError; |
| 9389 } | 9443 } |
| 9390 if (!validators_->texture_format.IsValid(format)) { | 9444 if (!validators_->texture_format.IsValid(format)) { |
| 9391 SetGLErrorInvalidEnum("glTexSubImage2D", format, "format"); | 9445 SetGLErrorInvalidEnum("glTexSubImage2D", format, "format"); |
|
greggman
2012/12/06 06:52:00
"glAsyncTexSubImage2DCHROMIUM"
| |
| 9392 return error::kNoError; | 9446 return error::kNoError; |
| 9393 } | 9447 } |
| 9394 if (!validators_->pixel_type.IsValid(type)) { | 9448 if (!validators_->pixel_type.IsValid(type)) { |
| 9395 SetGLErrorInvalidEnum("glTexSubImage2D", type, "type"); | 9449 SetGLErrorInvalidEnum("glTexSubImage2D", type, "type"); |
|
greggman
2012/12/06 06:52:00
"glAsyncTexImage2DCHROMIUM"
epenner
2012/12/08 03:15:04
Done.
| |
| 9396 return error::kNoError; | 9450 return error::kNoError; |
| 9397 } | 9451 } |
| 9398 if (pixels == NULL) { | 9452 |
| 9453 // TexSubImage must have valid pixels. | |
| 9454 if (pixels == NULL) | |
|
greggman
2012/12/06 06:52:00
"glAsyncTexImage2DCHROMIUM"
epenner
2012/12/08 03:15:04
Done.
| |
| 9399 return error::kOutOfBounds; | 9455 return error::kOutOfBounds; |
|
greggman
2012/12/06 06:52:00
Does this need to be death or should it be SetGLEr
epenner
2012/12/08 03:15:04
It's an SetGLError now when no transfer buffer is
| |
| 9456 | |
| 9457 // We only support async uploads to 2D textures for now. | |
| 9458 if (target != GL_TEXTURE_2D) { | |
| 9459 SetGLErrorInvalidEnum("glTexSubImage2D", type, "type"); | |
|
greggman
2012/12/06 06:52:00
"glAsyncTexImage2DCHROMIUM"
epenner
2012/12/08 03:15:04
Done.
| |
| 9460 return error::kNoError; | |
| 9400 } | 9461 } |
| 9401 | 9462 |
| 9402 // TODO(epenner): Do this via an async task. | 9463 // We only support uploads to level zero for now. |
| 9403 DoTexSubImage2D( | 9464 if (level != 0) { |
| 9404 target, level, xoffset, yoffset, width, height, format, type, pixels); | 9465 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "level != 0"); |
|
greggman
2012/12/06 06:52:00
"glAsyncTexImage2DCHROMIUM"
epenner
2012/12/08 03:15:04
Done.
| |
| 9466 return error::kNoError; | |
| 9467 } | |
| 9468 | |
| 9469 // We only support one async transfer in progress. | |
| 9470 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); | |
| 9471 if (!info || info->AsyncTransferIsInProgress()) { | |
| 9472 SetGLError(GL_INVALID_OPERATION, | |
| 9473 "glTexSubImage2D", "transfer already in progress"); | |
|
greggman
2012/12/06 06:52:00
"glAsyncTexImage2DCHROMIUM"
epenner
2012/12/08 03:15:04
Done.
| |
| 9474 } | |
| 9475 | |
| 9476 // It would be nice to do this async as well, but that way we can't | |
| 9477 // be sure the texture is cleared after this call. So better to do it | |
| 9478 // immediately (it's easy to avoid this penalty anyway). | |
| 9479 GLsizei tex_width = 0; | |
| 9480 GLsizei tex_height = 0; | |
| 9481 bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height); | |
| 9482 DCHECK(ok); | |
| 9483 if (xoffset != 0 || yoffset != 0 || | |
| 9484 width != tex_width || height != tex_height) { | |
| 9485 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) { | |
| 9486 SetGLError(GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big"); | |
|
greggman
2012/12/06 06:52:00
"glAsyncTexImage2DCHROMIUM"
epenner
2012/12/08 03:15:04
Done.
| |
| 9487 return error::kNoError; | |
| 9488 } | |
| 9489 // The level is certainly cleared now. In the full update case | |
| 9490 // we wait until the texture is used to mark it as cleared, | |
| 9491 // since by then the async transfer must be complete. | |
| 9492 texture_manager()->SetLevelCleared(info, target, level); | |
| 9493 } | |
| 9494 | |
| 9495 // We know the memory/size is safe, so get the real shared | |
| 9496 // memory since it might need to be duped to prevent | |
| 9497 // use-after-free issues. | |
| 9498 Buffer buffer = GetSharedMemoryBuffer(c.data_shm_id); | |
| 9499 base::SharedMemory* shared_memory = buffer.shared_memory; | |
| 9500 uint32 shm_size = buffer.size; | |
| 9501 uint32 shm_data_offset = c.data_shm_offset; | |
| 9502 uint32 shm_data_size = data_size; | |
| 9503 | |
| 9504 gfx::AsyncPixelTransferDelegate::Get()->AsyncTexSubImage2D( | |
| 9505 info->AsyncTransferState(), | |
| 9506 target, level, xoffset, yoffset, | |
| 9507 width, height, format, type, | |
| 9508 shared_memory, shm_size, shm_data_offset, shm_data_size); | |
| 9509 | |
| 9405 return error::kNoError; | 9510 return error::kNoError; |
| 9406 } | 9511 } |
| 9407 | 9512 |
| 9408 // Include the auto-generated part of this file. We split this because it means | 9513 // Include the auto-generated part of this file. We split this because it means |
| 9409 // we can easily edit the non-auto generated parts right here in this file | 9514 // we can easily edit the non-auto generated parts right here in this file |
| 9410 // instead of having to edit some template or the code generator. | 9515 // instead of having to edit some template or the code generator. |
| 9411 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 9516 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
| 9412 | 9517 |
| 9413 } // namespace gles2 | 9518 } // namespace gles2 |
| 9414 } // namespace gpu | 9519 } // namespace gpu |
| OLD | NEW |