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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: gpu/command_buffer/service/gles2_cmd_decoder.cc
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index b1292f00e5ffbd6dce4b5cb19327644f76f251f0..4f7f4f42741344a2b2c2dc6fb8db60830353f1b4 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -55,6 +55,7 @@
#include "gpu/command_buffer/service/texture_manager.h"
#include "gpu/command_buffer/service/vertex_attrib_manager.h"
#include "gpu/command_buffer/service/vertex_array_manager.h"
+#include "ui/gl/async_pixel_transfer_delegate.h"
#include "ui/gl/gl_image.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_surface.h"
@@ -3506,10 +3507,32 @@ void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
"glBindTexture", "illegal target for stream texture.");
return;
}
- if (info->target() == 0) {
- texture_manager()->SetInfoTarget(info, target);
+
+ if (!info->IsAsyncTransferTexture()) {
+ if (info->target() == 0) {
+ texture_manager()->SetInfoTarget(info, target);
+ }
+ glBindTexture(target, info->service_id());
+ } else {
+ // If the texture has async transfers, they must be complete.
+ if (info->AsyncTransferIsInProgress()) {
+ SetGLError(GL_INVALID_OPERATION,
+ "glBindTexture", "async transfer already in progress");
+ return;
+ }
+
+ if (info->target() == 0) {
+ texture_manager()->SetInfoTarget(info, target);
+ }
+
+ // Bind the GL texture, and perform any custom binding.
+ info->BindAsyncTransferTexture(target);
+
+ // We now know the transfer texture is cleared.
+ texture_manager()->SetLevelCleared(info, target, 0);
}
- glBindTexture(target, info->service_id());
+
+
TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
unit.bind_target = target;
switch (target) {
@@ -9347,10 +9370,41 @@ error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
}
}
- // TODO(epenner): Do this via an async task.
- return DoTexImage2D(
- target, level, internal_format, width, height, border, format, type,
- pixels, pixels_size);
+ // We only support async uploads to 2D textures for now.
+ if (target != GL_TEXTURE_2D) {
+ SetGLErrorInvalidEnum("glTexSubImage2D", type, "type");
greggman 2012/12/06 06:52:00 "glAsyncTexImage2DCHROMIUM"
epenner 2012/12/08 03:15:04 Done.
+ return error::kNoError;
+ }
+
+ // We only support uploads to level zero for now.
+ if (level != 0) {
+ SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "level != 0");
greggman 2012/12/06 06:52:00 "glAsyncTexImage2DCHROMIUM"
epenner 2012/12/08 03:15:04 Done.
+ return error::kNoError;
+ }
+
+ // We only support one async transfer in progress.
+ TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
+ if (!info || info->AsyncTransferIsInProgress()) {
+ SetGLError(GL_INVALID_OPERATION,
+ "glAsyncTexImage2D", "transfer already in progress");
greggman 2012/12/06 06:52:00 "glAsyncTexImage2DCHROMIUM"
epenner 2012/12/08 03:15:04 Done.
+ }
+
+ // We know the memory/size is safe, so get the real shared
+ // memory since it might need to be duped to prevent
+ // use-after-free issues.
+ Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id);
+ base::SharedMemory* shared_memory = buffer.shared_memory;
+ uint32 shm_size = buffer.size;
+ uint32 shm_data_offset = c.pixels_shm_offset;
+ uint32 shm_data_size = pixels_size;
+
+ gfx::AsyncPixelTransferDelegate::Get()->AsyncTexImage2D(
+ info->AsyncTransferState(),
+ target, level, internal_format,
+ width, height, border, format, type,
+ shared_memory, shm_size, shm_data_offset, shm_data_size);
+
+ return error::kNoError;
}
error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
@@ -9395,13 +9449,64 @@ error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
SetGLErrorInvalidEnum("glTexSubImage2D", type, "type");
greggman 2012/12/06 06:52:00 "glAsyncTexImage2DCHROMIUM"
epenner 2012/12/08 03:15:04 Done.
return error::kNoError;
}
- if (pixels == NULL) {
+
+ // TexSubImage must have valid pixels.
+ if (pixels == NULL)
greggman 2012/12/06 06:52:00 "glAsyncTexImage2DCHROMIUM"
epenner 2012/12/08 03:15:04 Done.
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
+
+ // We only support async uploads to 2D textures for now.
+ if (target != GL_TEXTURE_2D) {
+ SetGLErrorInvalidEnum("glTexSubImage2D", type, "type");
greggman 2012/12/06 06:52:00 "glAsyncTexImage2DCHROMIUM"
epenner 2012/12/08 03:15:04 Done.
+ return error::kNoError;
}
- // TODO(epenner): Do this via an async task.
- DoTexSubImage2D(
- target, level, xoffset, yoffset, width, height, format, type, pixels);
+ // We only support uploads to level zero for now.
+ if (level != 0) {
+ SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "level != 0");
greggman 2012/12/06 06:52:00 "glAsyncTexImage2DCHROMIUM"
epenner 2012/12/08 03:15:04 Done.
+ return error::kNoError;
+ }
+
+ // We only support one async transfer in progress.
+ TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
+ if (!info || info->AsyncTransferIsInProgress()) {
+ SetGLError(GL_INVALID_OPERATION,
+ "glTexSubImage2D", "transfer already in progress");
greggman 2012/12/06 06:52:00 "glAsyncTexImage2DCHROMIUM"
epenner 2012/12/08 03:15:04 Done.
+ }
+
+ // It would be nice to do this async as well, but that way we can't
+ // be sure the texture is cleared after this call. So better to do it
+ // immediately (it's easy to avoid this penalty anyway).
+ GLsizei tex_width = 0;
+ GLsizei tex_height = 0;
+ bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height);
+ DCHECK(ok);
+ if (xoffset != 0 || yoffset != 0 ||
+ width != tex_width || height != tex_height) {
+ if (!texture_manager()->ClearTextureLevel(this, info, target, level)) {
+ 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.
+ return error::kNoError;
+ }
+ // The level is certainly cleared now. In the full update case
+ // we wait until the texture is used to mark it as cleared,
+ // since by then the async transfer must be complete.
+ texture_manager()->SetLevelCleared(info, target, level);
+ }
+
+ // We know the memory/size is safe, so get the real shared
+ // memory since it might need to be duped to prevent
+ // use-after-free issues.
+ Buffer buffer = GetSharedMemoryBuffer(c.data_shm_id);
+ base::SharedMemory* shared_memory = buffer.shared_memory;
+ uint32 shm_size = buffer.size;
+ uint32 shm_data_offset = c.data_shm_offset;
+ uint32 shm_data_size = data_size;
+
+ gfx::AsyncPixelTransferDelegate::Get()->AsyncTexSubImage2D(
+ info->AsyncTransferState(),
+ target, level, xoffset, yoffset,
+ width, height, format, type,
+ shared_memory, shm_size, shm_data_offset, shm_data_size);
+
return error::kNoError;
}

Powered by Google App Engine
This is Rietveld 408576698