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 3430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3498 if (info->target() != 0 && info->target() != target) { | 3499 if (info->target() != 0 && info->target() != target) { |
3499 SetGLError(GL_INVALID_OPERATION, | 3500 SetGLError(GL_INVALID_OPERATION, |
3500 "glBindTexture", "texture bound to more than 1 target."); | 3501 "glBindTexture", "texture bound to more than 1 target."); |
3501 return; | 3502 return; |
3502 } | 3503 } |
3503 if (info->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) { | 3504 if (info->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) { |
3504 SetGLError(GL_INVALID_OPERATION, | 3505 SetGLError(GL_INVALID_OPERATION, |
3505 "glBindTexture", "illegal target for stream texture."); | 3506 "glBindTexture", "illegal target for stream texture."); |
3506 return; | 3507 return; |
3507 } | 3508 } |
3508 if (info->target() == 0) { | 3509 |
3509 texture_manager()->SetInfoTarget(info, target); | 3510 if (!info->IsAsyncTransferTexture()) { |
3511 if (info->target() == 0) { | |
3512 texture_manager()->SetInfoTarget(info, target); | |
3513 } | |
3514 glBindTexture(target, info->service_id()); | |
3515 } else { | |
3516 // If the texture has async transfers, they must be complete. | |
3517 if (info->AsyncTransferIsInProgress()) { | |
greggman
2012/12/05 02:23:42
Why is this needed? Binding a texture should not b
epenner
2012/12/05 04:01:54
Good point! I was trying to preserve the 'level cl
epenner
2012/12/08 03:15:04
Done.
| |
3518 SetGLError(GL_INVALID_OPERATION, | |
3519 "glBindTexture", "async transfer already in progress"); | |
3520 return; | |
3521 } | |
3522 | |
3523 if (info->target() == 0) { | |
3524 texture_manager()->SetInfoTarget(info, target); | |
3525 } | |
3526 | |
3527 // Bind the GL texture, and perform any custom binding. | |
3528 info->BindAsyncTransferTexture(target); | |
3529 | |
3530 // We now know the transfer texture is cleared. | |
3531 texture_manager()->SetLevelCleared(info, target, 0); | |
3510 } | 3532 } |
3511 glBindTexture(target, info->service_id()); | 3533 |
3534 | |
3512 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; | 3535 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; |
3513 unit.bind_target = target; | 3536 unit.bind_target = target; |
3514 switch (target) { | 3537 switch (target) { |
3515 case GL_TEXTURE_2D: | 3538 case GL_TEXTURE_2D: |
3516 unit.bound_texture_2d = info; | 3539 unit.bound_texture_2d = info; |
3517 break; | 3540 break; |
3518 case GL_TEXTURE_CUBE_MAP: | 3541 case GL_TEXTURE_CUBE_MAP: |
3519 unit.bound_texture_cube_map = info; | 3542 unit.bound_texture_cube_map = info; |
3520 break; | 3543 break; |
3521 case GL_TEXTURE_EXTERNAL_OES: | 3544 case GL_TEXTURE_EXTERNAL_OES: |
(...skipping 5818 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"); |
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"); | |
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->AsyncTransferState()->TransferIsInProgress()) { | |
9388 SetGLError(GL_INVALID_OPERATION, | |
9389 "glAsyncTexImage2D", "transfer already in progress"); | |
9390 } | |
9391 | |
9392 // TODO(epenner): Fix the use-after-free vulnerability here | |
9393 // by referencing the shared memory for "pixels" until completion. | |
9394 gfx::AsyncPixelTransferDelegate::Get()->AsyncTexImage2D( | |
9395 info->AsyncTransferState(), target, level, internal_format, | |
9396 width, height, border, format, type, pixels); | |
9397 return error::kNoError; | |
9354 } | 9398 } |
9355 | 9399 |
9356 error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM( | 9400 error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM( |
9357 uint32 immediate_data_size, const gles2::AsyncTexSubImage2DCHROMIUM& c) { | 9401 uint32 immediate_data_size, const gles2::AsyncTexSubImage2DCHROMIUM& c) { |
9358 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM"); | 9402 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM"); |
9359 | 9403 |
9360 // TODO: This is a copy of HandleTexSubImage2D validation. Merge | 9404 // TODO: This is a copy of HandleTexSubImage2D validation. Merge |
9361 // as much of it as possible. | 9405 // as much of it as possible. |
9362 GLenum target = static_cast<GLenum>(c.target); | 9406 GLenum target = static_cast<GLenum>(c.target); |
9363 GLint level = static_cast<GLint>(c.level); | 9407 GLint level = static_cast<GLint>(c.level); |
(...skipping 24 matching lines...) Expand all Loading... | |
9388 return error::kNoError; | 9432 return error::kNoError; |
9389 } | 9433 } |
9390 if (!validators_->texture_format.IsValid(format)) { | 9434 if (!validators_->texture_format.IsValid(format)) { |
9391 SetGLErrorInvalidEnum("glTexSubImage2D", format, "format"); | 9435 SetGLErrorInvalidEnum("glTexSubImage2D", format, "format"); |
9392 return error::kNoError; | 9436 return error::kNoError; |
9393 } | 9437 } |
9394 if (!validators_->pixel_type.IsValid(type)) { | 9438 if (!validators_->pixel_type.IsValid(type)) { |
9395 SetGLErrorInvalidEnum("glTexSubImage2D", type, "type"); | 9439 SetGLErrorInvalidEnum("glTexSubImage2D", type, "type"); |
9396 return error::kNoError; | 9440 return error::kNoError; |
9397 } | 9441 } |
9398 if (pixels == NULL) { | 9442 |
9399 return error::kOutOfBounds; | 9443 // We only support async uploads to 2D textures for now. |
9444 if (target != GL_TEXTURE_2D) { | |
9445 SetGLErrorInvalidEnum("glTexSubImage2D", type, "type"); | |
9446 return error::kNoError; | |
9400 } | 9447 } |
9401 | 9448 |
9402 // TODO(epenner): Do this via an async task. | 9449 // We only support uploads to level zero for now. |
9403 DoTexSubImage2D( | 9450 if (level != 0) { |
9404 target, level, xoffset, yoffset, width, height, format, type, pixels); | 9451 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "level != 0"); |
9452 return error::kNoError; | |
9453 } | |
9454 | |
9455 // We only support one async transfer in progress. | |
9456 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); | |
9457 if (!info || info->AsyncTransferState()->TransferIsInProgress()) { | |
9458 SetGLError(GL_INVALID_OPERATION, | |
9459 "glTexSubImage2D", "transfer already in progress"); | |
9460 } | |
9461 | |
9462 // It would be nice to do this async as well, but that way we can't | |
9463 // be sure the texture is cleared after this call. So better to do it | |
9464 // immediately (it's easy to avoid this penalty anyway). | |
9465 GLsizei tex_width = 0; | |
9466 GLsizei tex_height = 0; | |
9467 bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height); | |
9468 DCHECK(ok); | |
9469 if (xoffset != 0 || yoffset != 0 || | |
9470 width != tex_width || height != tex_height) { | |
9471 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) { | |
9472 SetGLError(GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big"); | |
9473 return error::kNoError; | |
9474 } | |
9475 // The level is certainly cleared now. In the full update case | |
9476 // we wait until the texture is used to mark it as cleared. | |
9477 texture_manager()->SetLevelCleared(info, target, level); | |
9478 } | |
9479 | |
9480 // TODO(epenner): Fix the use-after-free vulnerability here | |
9481 // by referencing the shared memory for "pixels" until completion. | |
9482 gfx::AsyncPixelTransferDelegate::Get()->AsyncTexSubImage2D( | |
9483 info->AsyncTransferState(), target, level, xoffset, yoffset, | |
9484 width, height, format, type, pixels); | |
9405 return error::kNoError; | 9485 return error::kNoError; |
9406 } | 9486 } |
9407 | 9487 |
9408 // Include the auto-generated part of this file. We split this because it means | 9488 // 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 | 9489 // 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. | 9490 // instead of having to edit some template or the code generator. |
9411 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 9491 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
9412 | 9492 |
9413 } // namespace gles2 | 9493 } // namespace gles2 |
9414 } // namespace gpu | 9494 } // namespace gpu |
OLD | NEW |