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

Side by Side Diff: gpu/command_buffer/service/gles2_cmd_decoder.cc

Issue 11428140: gpu: Add async pixel transfer interface, stub and tests. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Added memory dup/mmap Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698