summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer/client
diff options
context:
space:
mode:
authorapatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-25 19:13:19 +0000
committerapatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-25 19:13:19 +0000
commitb9849abfc2e081a1d85bd5eda2c5c1d2fd9e35a5 (patch)
tree6d191fbaf63c019cf01f2c53598c8756cd2f75df /gpu/command_buffer/client
parent76180ea4287b9458d97f8d547daf785bf136fba1 (diff)
downloadchromium_src-b9849abfc2e081a1d85bd5eda2c5c1d2fd9e35a5.zip
chromium_src-b9849abfc2e081a1d85bd5eda2c5c1d2fd9e35a5.tar.gz
chromium_src-b9849abfc2e081a1d85bd5eda2c5c1d2fd9e35a5.tar.bz2
Merged in recent changes to command buffer code.
TEST=none BUG=none Review URL: http://codereview.chromium.org/434063 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@33095 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu/command_buffer/client')
-rw-r--r--gpu/command_buffer/client/gles2_c_lib_autogen.h4
-rw-r--r--gpu/command_buffer/client/gles2_cmd_helper.h40
-rw-r--r--gpu/command_buffer/client/gles2_cmd_helper_autogen.h29
-rw-r--r--gpu/command_buffer/client/gles2_demo.cc10
-rw-r--r--gpu/command_buffer/client/gles2_demo_c.c2
-rw-r--r--gpu/command_buffer/client/gles2_demo_cc.cc187
-rw-r--r--gpu/command_buffer/client/gles2_implementation.cc213
-rw-r--r--gpu/command_buffer/client/gles2_implementation.h64
-rw-r--r--gpu/command_buffer/client/gles2_implementation_autogen.h193
9 files changed, 497 insertions, 245 deletions
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h
index c03a350..76f0973 100644
--- a/gpu/command_buffer/client/gles2_c_lib_autogen.h
+++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -214,7 +214,7 @@ void GLES2GetAttachedShaders(
GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) {
gles2::GetGLContext()->GetAttachedShaders(program, maxcount, count, shaders);
}
-int GLES2GetAttribLocation(GLuint program, const char* name) {
+GLint GLES2GetAttribLocation(GLuint program, const char* name) {
return gles2::GetGLContext()->GetAttribLocation(program, name);
}
void GLES2GetBooleanv(GLenum pname, GLboolean* params) {
@@ -280,7 +280,7 @@ void GLES2GetUniformfv(GLuint program, GLint location, GLfloat* params) {
void GLES2GetUniformiv(GLuint program, GLint location, GLint* params) {
gles2::GetGLContext()->GetUniformiv(program, location, params);
}
-int GLES2GetUniformLocation(GLuint program, const char* name) {
+GLint GLES2GetUniformLocation(GLuint program, const char* name) {
return gles2::GetGLContext()->GetUniformLocation(program, name);
}
void GLES2GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) {
diff --git a/gpu/command_buffer/client/gles2_cmd_helper.h b/gpu/command_buffer/client/gles2_cmd_helper.h
index 9a1a741..fbb1ce1 100644
--- a/gpu/command_buffer/client/gles2_cmd_helper.h
+++ b/gpu/command_buffer/client/gles2_cmd_helper.h
@@ -25,6 +25,46 @@ class GLES2CmdHelper : public CommandBufferHelper {
// file instead of having to edit some template or the code generator.
#include "gpu/command_buffer/client/gles2_cmd_helper_autogen.h"
+ // Helpers that could not be auto-generated.
+ // TODO(gman): Auto generate these.
+
+ void GetAttribLocation(
+ GLuint program, uint32 name_shm_id, uint32 name_shm_offset,
+ uint32 location_shm_id, uint32 location_shm_offset, uint32 data_size) {
+ gles2::GetAttribLocation& c = GetCmdSpace<gles2::GetAttribLocation>();
+ c.Init(
+ program, name_shm_id, name_shm_offset, location_shm_id,
+ location_shm_offset, data_size);
+ }
+
+ void GetAttribLocationImmediate(
+ GLuint program, const char* name,
+ uint32 location_shm_id, uint32 location_shm_offset) {
+ const uint32 size = gles2::GetAttribLocationImmediate::ComputeSize(name);
+ gles2::GetAttribLocationImmediate& c =
+ GetImmediateCmdSpaceTotalSize<gles2::GetAttribLocationImmediate>(size);
+ c.Init(program, name, location_shm_id, location_shm_offset);
+ }
+
+ void GetUniformLocation(
+ GLuint program, uint32 name_shm_id, uint32 name_shm_offset,
+ uint32 location_shm_id, uint32 location_shm_offset, uint32 data_size) {
+ gles2::GetUniformLocation& c = GetCmdSpace<gles2::GetUniformLocation>();
+ c.Init(
+ program, name_shm_id, name_shm_offset, location_shm_id,
+ location_shm_offset, data_size);
+ }
+
+ void GetUniformLocationImmediate(
+ GLuint program, const char* name,
+ uint32 location_shm_id, uint32 location_shm_offset) {
+ const uint32 size = gles2::GetUniformLocationImmediate::ComputeSize(name);
+ gles2::GetUniformLocationImmediate& c =
+ GetImmediateCmdSpaceTotalSize<gles2::GetUniformLocationImmediate>(size);
+ c.Init(program, name, location_shm_id, location_shm_offset);
+ }
+
+
private:
DISALLOW_COPY_AND_ASSIGN(GLES2CmdHelper);
};
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
index 1cfee5b..f05c14b 100644
--- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
+++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -450,20 +450,6 @@
shaders_shm_offset);
}
- void GetAttribLocation(
- GLuint program, uint32 name_shm_id, uint32 name_shm_offset,
- uint32 data_size) {
- gles2::GetAttribLocation& c = GetCmdSpace<gles2::GetAttribLocation>();
- c.Init(program, name_shm_id, name_shm_offset, data_size);
- }
-
- void GetAttribLocationImmediate(GLuint program, const char* name) {
- const uint32 size = gles2::GetAttribLocationImmediate::ComputeSize(name);
- gles2::GetAttribLocationImmediate& c =
- GetImmediateCmdSpaceTotalSize<gles2::GetAttribLocationImmediate>(size);
- c.Init(program, name);
- }
-
void GetBooleanv(
GLenum pname, uint32 params_shm_id, uint32 params_shm_offset) {
gles2::GetBooleanv& c = GetCmdSpace<gles2::GetBooleanv>();
@@ -599,21 +585,6 @@
c.Init(program, location, params_shm_id, params_shm_offset);
}
- void GetUniformLocation(
- GLuint program, uint32 name_shm_id, uint32 name_shm_offset,
- uint32 data_size) {
- gles2::GetUniformLocation& c = GetCmdSpace<gles2::GetUniformLocation>();
- c.Init(program, name_shm_id, name_shm_offset, data_size);
- }
-
- void GetUniformLocationImmediate(GLuint program, const char* name) {
- const uint32 size = gles2::GetUniformLocationImmediate::ComputeSize(name);
- gles2::GetUniformLocationImmediate& c =
- GetImmediateCmdSpaceTotalSize<gles2::GetUniformLocationImmediate>(
- size);
- c.Init(program, name);
- }
-
void GetVertexAttribfv(
GLuint index, GLenum pname, uint32 params_shm_id,
uint32 params_shm_offset) {
diff --git a/gpu/command_buffer/client/gles2_demo.cc b/gpu/command_buffer/client/gles2_demo.cc
index 04419c3..1595ea3 100644
--- a/gpu/command_buffer/client/gles2_demo.cc
+++ b/gpu/command_buffer/client/gles2_demo.cc
@@ -73,10 +73,18 @@ bool GLES2Demo::Setup(NPP npp, void* hwnd, int32 size) {
size_t transfer_buffer_size = 512 * 1024;
int32 transfer_buffer_id =
command_buffer->CreateTransferBuffer(transfer_buffer_size);
- void* transfer_buffer =
+ ::base::SharedMemory* shared_memory =
command_buffer->GetTransferBuffer(transfer_buffer_id);
+ if (!shared_memory->Map(transfer_buffer_size)) {
+ return false;
+ }
+ void* transfer_buffer = shared_memory->memory();
+ if (!transfer_buffer) {
+ return false;
+ }
gles2::g_gl_impl = new GLES2Implementation(helper,
+ transfer_buffer_size,
transfer_buffer,
transfer_buffer_id);
diff --git a/gpu/command_buffer/client/gles2_demo_c.c b/gpu/command_buffer/client/gles2_demo_c.c
index 44b2c57..2f54bd1 100644
--- a/gpu/command_buffer/client/gles2_demo_c.c
+++ b/gpu/command_buffer/client/gles2_demo_c.c
@@ -9,7 +9,7 @@
#include "gpu/command_buffer/client/gles2_demo_c.h"
void GLFromCTestFunction() {
- glClear(GL_COLOR_BUFFER_BIT);
+ // glClear(GL_COLOR_BUFFER_BIT);
}
diff --git a/gpu/command_buffer/client/gles2_demo_cc.cc b/gpu/command_buffer/client/gles2_demo_cc.cc
index d7a023c..ba5e618 100644
--- a/gpu/command_buffer/client/gles2_demo_cc.cc
+++ b/gpu/command_buffer/client/gles2_demo_cc.cc
@@ -8,14 +8,187 @@
#include <GLES2/gl2.h>
#include "gpu/command_buffer/client/gles2_demo_cc.h"
+namespace {
+
+int g_width = 512;
+int g_height = 512;
+GLuint g_texture = 0;
+int g_textureLoc = -1;
+GLuint g_programObject = 0;
+GLuint g_vbo = 0;
+GLsizei g_texCoordOffset = 0;
+
+void CheckGLError() {
+ GLenum error = glGetError();
+ if (error != GL_NO_ERROR) {
+ DLOG(ERROR) << "GL Error: " << error;
+ }
+}
+
+GLuint LoadShader(GLenum type, const char* shaderSrc) {
+ GLuint shader = glCreateShader(type);
+ if (shader == 0) {
+ return 0;
+ }
+ // Load the shader source
+ glShaderSource(shader, 1, &shaderSrc, NULL);
+ // Compile the shader
+ glCompileShader(shader);
+ // Check the compile status
+ GLint value;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &value);
+ if (value == 0) {
+ char buffer[1024];
+ GLsizei length;
+ glGetShaderInfoLog(shader, sizeof(buffer), &length, buffer);
+ std::string log(buffer, length);
+ DLOG(ERROR) << "Error compiling shader:" << log;
+ glDeleteShader(shader);
+ return 0;
+ }
+ return shader;
+}
+
+void InitShaders() {
+ static const char* vShaderStr =
+ "attribute vec3 g_Position;\n"
+ "attribute vec2 g_TexCoord0;\n"
+ "varying vec2 texCoord;\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(g_Position.x, g_Position.y, g_Position.z, 1.0);\n"
+ " texCoord = g_TexCoord0;\n"
+ "}\n";
+ static const char* fShaderStr =
+ "uniform sampler2D tex;\n"
+ "varying vec2 texCoord;\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = texture2D(tex, texCoord);\n"
+ "}\n";
+
+ GLuint vertexShader = LoadShader(GL_VERTEX_SHADER, vShaderStr);
+ GLuint fragmentShader = LoadShader(GL_FRAGMENT_SHADER, fShaderStr);
+ // Create the program object
+ GLuint programObject = glCreateProgram();
+ if (programObject == 0) {
+ DLOG(ERROR) << "Creating program failed";
+ return;
+ }
+ glAttachShader(programObject, vertexShader);
+ glAttachShader(programObject, fragmentShader);
+ // Bind g_Position to attribute 0
+ // Bind g_TexCoord0 to attribute 1
+ glBindAttribLocation(programObject, 0, "g_Position");
+ glBindAttribLocation(programObject, 1, "g_TexCoord0");
+ // Link the program
+ glLinkProgram(programObject);
+ // Check the link status
+ GLint linked;
+ glGetProgramiv(programObject, GL_LINK_STATUS, &linked);
+ if (linked == 0) {
+ char buffer[1024];
+ GLsizei length;
+ glGetProgramInfoLog(programObject, sizeof(buffer), &length, buffer);
+ std::string log(buffer, length);
+ DLOG(ERROR) << "Error linking program:" << log;
+ glDeleteProgram(programObject);
+ return;
+ }
+ g_programObject = programObject;
+ g_textureLoc = glGetUniformLocation(g_programObject, "tex");
+ glGenBuffers(1, &g_vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, g_vbo);
+ static float vertices[] = {
+ 0.25, 0.75, 0.0,
+ -0.75, 0.75, 0.0,
+ -0.75, -0.25, 0.0,
+ 0.25, 0.75, 0.0,
+ -0.75, -0.25, 0.0,
+ 0.25, -0.25, 0.0,
+ };
+ static float texCoords[] = {
+ 1.0, 1.0,
+ 0.0, 1.0,
+ 0.0, 0.0,
+ 1.0, 1.0,
+ 0.0, 0.0,
+ 1.0, 0.0,
+ };
+ g_texCoordOffset = sizeof(vertices);
+ glBufferData(GL_ARRAY_BUFFER,
+ sizeof(vertices) + sizeof(texCoords),
+ NULL,
+ GL_STATIC_DRAW);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
+ glBufferSubData(GL_ARRAY_BUFFER, g_texCoordOffset,
+ sizeof(texCoords), texCoords);
+ CheckGLError();
+}
+
+void Draw() {
+ // Note: the viewport is automatically set up to cover the entire Canvas.
+ // Clear the color buffer
+ glClear(GL_COLOR_BUFFER_BIT);
+ CheckGLError();
+ // Use the program object
+ glUseProgram(g_programObject);
+ CheckGLError();
+ // Load the vertex data
+ glBindBuffer(GL_ARRAY_BUFFER, g_vbo);
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
+ glEnableVertexAttribArray(1);
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0,
+ reinterpret_cast<const void*>(g_texCoordOffset));
+ CheckGLError();
+ // Bind the texture to texture unit 0
+ glBindTexture(GL_TEXTURE_2D, g_texture);
+ CheckGLError();
+ // Point the uniform sampler to texture unit 0
+ glUniform1i(g_textureLoc, 0);
+ CheckGLError();
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+ CheckGLError();
+ glFlush();
+}
+
+GLuint CreateCheckerboardTexture() {
+ static unsigned char pixels[] = {
+ 255, 255, 255,
+ 0, 0, 0,
+ 0, 0, 0,
+ 255, 255, 255,
+ };
+ GLuint texture;
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE,
+ pixels);
+ return texture;
+}
+
+void Init() {
+ glClearColor(0.f, 0.f, .7f, 1.f);
+ g_texture = CreateCheckerboardTexture();
+ InitShaders();
+}
+
+} // anonymous namespace.
+
void GLFromCPPTestFunction() {
- static bool foo = true;
- foo = !foo;
- glClearColor(
- foo ? 1.0f : 0.0f,
- foo ? 0.0f : 1.0f,
- 1.0f,
- 1.0f);
+ static bool initialized = false;
+ if (!initialized) {
+ initialized = true;
+ Init();
+ }
+ Draw();
}
+
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index e60e68b..1208a57 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -14,13 +14,21 @@ namespace gles2 {
GLES2Implementation::GLES2Implementation(
GLES2CmdHelper* helper,
+ size_t transfer_buffer_size,
void* transfer_buffer,
- int transfer_buffer_id)
+ int32 transfer_buffer_id)
: util_(0), // TODO(gman): Get real number of compressed texture formats.
helper_(helper),
- shared_memory_(transfer_buffer, transfer_buffer_id),
+ transfer_buffer_(transfer_buffer_size, helper, transfer_buffer),
+ transfer_buffer_id_(transfer_buffer_id),
pack_alignment_(4),
unpack_alignment_(4) {
+ // Eat 1 id so we start at 1 instead of 0.
+ GLuint eat;
+ MakeIds(1, &eat);
+ // Allocate space for simple GL results.
+ result_buffer_ = transfer_buffer_.Alloc(kMaxSizeOfSimpleResult);
+ result_shm_offset_ = transfer_buffer_.GetOffset(result_buffer_);
}
void GLES2Implementation::MakeIds(GLsizei n, GLuint* ids) {
@@ -35,11 +43,47 @@ void GLES2Implementation::FreeIds(GLsizei n, const GLuint* ids) {
}
}
+void GLES2Implementation::WaitForCmd() {
+ int32 token = helper_->InsertToken();
+ helper_->WaitForToken(token);
+}
+
void GLES2Implementation::DrawElements(
GLenum mode, GLsizei count, GLenum type, const void* indices) {
helper_->DrawElements(mode, count, type, reinterpret_cast<GLuint>(indices));
}
+GLint GLES2Implementation::GetAttribLocation(
+ GLuint program, const char* name) {
+ helper_->GetAttribLocationImmediate(
+ program, name, result_shm_id(), result_shm_offset());
+ WaitForCmd();
+ return GetResultAs<GLint>();
+}
+
+GLint GLES2Implementation::GetUniformLocation(
+ GLuint program, const char* name) {
+ helper_->GetUniformLocationImmediate(
+ program, name, result_shm_id(), result_shm_offset());
+ WaitForCmd();
+ return GetResultAs<GLint>();
+}
+
+void GLES2Implementation::PixelStorei(GLenum pname, GLint param) {
+ switch (pname) {
+ case GL_PACK_ALIGNMENT:
+ pack_alignment_ = param;
+ break;
+ case GL_UNPACK_ALIGNMENT:
+ unpack_alignment_ = param;
+ break;
+ default:
+ break;
+ }
+ helper_->PixelStorei(pname, param);
+}
+
+
void GLES2Implementation::VertexAttribPointer(
GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride,
const void* ptr) {
@@ -48,103 +92,158 @@ void GLES2Implementation::VertexAttribPointer(
}
void GLES2Implementation::ShaderSource(
- GLuint shader, GLsizei count, const char** string, const GLint* length) {
+ GLuint shader, GLsizei count, const char** source, const GLint* length) {
// TODO(gman): change to use buckets and check that there is enough room.
- uint32* offsets = shared_memory_.GetAddressAs<uint32*>(0);
- char* strings = reinterpret_cast<char*>(offsets + count);
+ // Compute the total size.
+ uint32 total_size = count * sizeof(total_size);
+ for (GLsizei ii = 0; ii < count; ++ii) {
+ total_size += length ? length[ii] : strlen(source[ii]);
+ }
+
+ // Create string table in transfer buffer.
+ char* strings = transfer_buffer_.AllocTyped<char>(total_size);
+ uint32* offsets = reinterpret_cast<uint32*>(strings);
uint32 offset = count * sizeof(*offsets);
for (GLsizei ii = 0; ii < count; ++ii) {
- uint32 len = length ? length[ii] : strlen(string[ii]);
- memcpy(strings + offset, string[ii], len);
+ uint32 len = length ? length[ii] : strlen(source[ii]);
+ memcpy(strings + offset, source[ii], len);
offset += len;
offsets[ii] = offset;
}
- helper_->ShaderSource(shader, count, shared_memory_.GetId(), 0, offset);
- // TODO(gman): Should insert token but not wait until we need shared memory
- // again. Really, I should implement a shared memory manager that puts
- // things in the next unused part of shared memory and only blocks
- // when it needs more memory.
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
+ helper_->ShaderSource(shader, count,
+ transfer_buffer_id_,
+ transfer_buffer_.GetOffset(strings), offset);
+ transfer_buffer_.FreePendingToken(strings, helper_->InsertToken());
}
void GLES2Implementation::BufferData(
GLenum target, GLsizeiptr size, const void* data, GLenum usage) {
- // TODO(gman): Switch to use buckets alwayst or at least if no room in shared
- // memory.
- memcpy(shared_memory_.GetAddress(0), data, size);
- helper_->BufferData(target, size, shared_memory_.GetId(), 0, usage);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
+ // NOTE: Should this be optimized for the case where we can call BufferData
+ // with the actual data in the case of our transfer buffer being big
+ // enough?
+ helper_->BufferData(target, size, 0, 0, usage);
+ if (data != NULL) {
+ BufferSubData(target, 0, size, data);
+ }
}
void GLES2Implementation::BufferSubData(
GLenum target, GLintptr offset, GLsizeiptr size, const void* data) {
- // TODO(gman): Switch to use buckets alwayst or at least if no room in shared
- // memory.
- memcpy(shared_memory_.GetAddress(0), data, size);
- helper_->BufferSubData(target, offset, size, shared_memory_.GetId(), 0);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
+ const int8* source = static_cast<const int8*>(data);
+ GLsizeiptr max_size = transfer_buffer_.GetLargestFreeOrPendingSize();
+ while (size) {
+ GLsizeiptr part_size = std::min(size, max_size);
+ void* buffer = transfer_buffer_.Alloc(part_size);
+ memcpy(buffer, source, part_size);
+ helper_->BufferSubData(target, offset, part_size,
+ transfer_buffer_id_,
+ transfer_buffer_.GetOffset(buffer));
+ transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken());
+ offset += part_size;
+ source += part_size;
+ size -= part_size;
+ }
}
void GLES2Implementation::CompressedTexImage2D(
GLenum target, GLint level, GLenum internalformat, GLsizei width,
- GLsizei height, GLint border, GLsizei imageSize, const void* data) {
+ GLsizei height, GLint border, GLsizei image_size, const void* data) {
// TODO(gman): Switch to use buckets alwayst or at least if no room in shared
// memory.
- memcpy(shared_memory_.GetAddress(0), data, imageSize);
+ DCHECK_LE(image_size,
+ static_cast<GLsizei>(
+ transfer_buffer_.GetLargestFreeOrPendingSize()));
+ void* buffer = transfer_buffer_.Alloc(image_size);
+ memcpy(buffer, data, image_size);
helper_->CompressedTexImage2D(
- target, level, internalformat, width, height, border, imageSize,
- shared_memory_.GetId(), 0);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
+ target, level, internalformat, width, height, border, image_size,
+ transfer_buffer_id_, transfer_buffer_.GetOffset(buffer));
+ transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken());
}
void GLES2Implementation::CompressedTexSubImage2D(
GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
- GLsizei height, GLenum format, GLsizei imageSize, const void* data) {
+ GLsizei height, GLenum format, GLsizei image_size, const void* data) {
// TODO(gman): Switch to use buckets alwayst or at least if no room in shared
// memory.
- memcpy(shared_memory_.GetAddress(0), data, imageSize);
+ DCHECK_LE(image_size,
+ static_cast<GLsizei>(
+ transfer_buffer_.GetLargestFreeOrPendingSize()));
+ void* buffer = transfer_buffer_.Alloc(image_size);
+ memcpy(buffer, data, image_size);
helper_->CompressedTexSubImage2D(
- target, level, xoffset, yoffset, width, height, format, imageSize,
- shared_memory_.GetId(), 0);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
+ target, level, xoffset, yoffset, width, height, format, image_size,
+ transfer_buffer_id_, transfer_buffer_.GetOffset(buffer));
+ transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken());
}
void GLES2Implementation::TexImage2D(
GLenum target, GLint level, GLint internalformat, GLsizei width,
GLsizei height, GLint border, GLenum format, GLenum type,
const void* pixels) {
- // TODO(gman): Switch to use buckets alwayst or at least if no room in shared
- // memory.
- uint32 pixels_size = GLES2Util::ComputeImageDataSize(
- width, height, format, type, unpack_alignment_);
- memcpy(shared_memory_.GetAddress(0), pixels, pixels_size);
helper_->TexImage2D(
- target, level, internalformat, width, height, border, format, type,
- shared_memory_.GetId(), 0);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
+ target, level, internalformat, width, height, border, format, type, 0, 0);
+ if (pixels) {
+ TexSubImage2D(target, level, 0, 0, width, height, format, type, pixels);
+ }
}
void GLES2Implementation::TexSubImage2D(
GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
GLsizei height, GLenum format, GLenum type, const void* pixels) {
- // TODO(gman): Switch to use buckets alwayst or at least if no room in shared
- // memory.
- uint32 pixels_size = GLES2Util::ComputeImageDataSize(
- width, height, format, type, unpack_alignment_);
- memcpy(shared_memory_.GetAddress(0), pixels, pixels_size);
- helper_->TexSubImage2D(
- target, level, xoffset, yoffset, width, height, format, type,
- shared_memory_.GetId(), 0);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
+ const int8* source = static_cast<const int8*>(pixels);
+ GLsizeiptr max_size = transfer_buffer_.GetLargestFreeOrPendingSize();
+
+ GLsizeiptr unpadded_row_size = GLES2Util::ComputeImageDataSize(
+ width, 1, format, type, unpack_alignment_);
+ GLsizeiptr padded_row_size = GLES2Util::ComputeImageDataSize(
+ width, 2, format, type, unpack_alignment_) - unpadded_row_size;
+
+ if (padded_row_size <= max_size) {
+ // Transfer by rows.
+ GLint max_rows = max_size / padded_row_size;
+ while (height) {
+ GLint num_rows = std::min(height, max_rows);
+ GLsizeiptr part_size = num_rows * padded_row_size;
+ void* buffer = transfer_buffer_.Alloc(part_size);
+ memcpy(buffer, source, part_size);
+ helper_->TexSubImage2D(
+ target, level, xoffset, yoffset, width, num_rows, format, type,
+ transfer_buffer_id_, transfer_buffer_.GetOffset(buffer));
+ transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken());
+ yoffset += num_rows;
+ source += part_size;
+ height -= num_rows;
+ }
+ } else {
+ // Transfer by sub rows. Beacuse GL has no maximum texture dimensions.
+ GLsizeiptr element_size = GLES2Util::ComputeImageDataSize(
+ 1, 1, format, type, unpack_alignment_);
+ max_size -= max_size % element_size;
+ GLint max_sub_row_pixels = max_size / element_size;
+ for (; height; --height) {
+ GLint temp_width = width;
+ GLint temp_xoffset = xoffset;
+ const int8* row_source = source;
+ while (temp_width) {
+ GLint num_pixels = std::min(width, max_sub_row_pixels);
+ GLsizeiptr part_size = num_pixels * element_size;
+ void* buffer = transfer_buffer_.Alloc(part_size);
+ memcpy(buffer, row_source, part_size);
+ helper_->TexSubImage2D(
+ target, level, temp_xoffset, yoffset, temp_width, 1, format, type,
+ transfer_buffer_id_, transfer_buffer_.GetOffset(buffer));
+ transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken());
+ row_source += part_size;
+ temp_xoffset += num_pixels;
+ temp_width -= num_pixels;
+ }
+ ++yoffset;
+ source += padded_row_size;
+ }
+ }
}
diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h
index 2df52ca..fec3de9 100644
--- a/gpu/command_buffer/client/gles2_implementation.h
+++ b/gpu/command_buffer/client/gles2_implementation.h
@@ -9,43 +9,11 @@
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "gpu/command_buffer/client/gles2_cmd_helper.h"
#include "gpu/command_buffer/client/id_allocator.h"
+#include "gpu/command_buffer/client/fenced_allocator.h"
namespace command_buffer {
namespace gles2 {
-// A class to help with shared memory.
-class SharedMemoryHelper {
- public:
- SharedMemoryHelper(void* address, int id)
- : address_(address),
- id_(id) {
- }
-
- unsigned int GetOffset(void* address) const {
- return static_cast<int8*>(address) -
- static_cast<int8*>(address_);
- }
-
- void* GetAddress(unsigned int offset) const {
- return static_cast<int8*>(address_) + offset;
- }
-
- template <typename T>
- T GetAddressAs(unsigned int offset) const {
- return static_cast<T>(GetAddress(offset));
- }
-
- unsigned int GetId() const {
- return id_;
- }
-
- private:
- void* address_;
- int id_;
-
- DISALLOW_COPY_AND_ASSIGN(SharedMemoryHelper);
-};
-
// This class emulates GLES2 over command buffers. It can be used by a client
// program so that the program does not need deal with shared memory and command
// buffer management. See gl2_lib.h. Note that there is a performance gain to
@@ -56,8 +24,9 @@ class GLES2Implementation {
public:
GLES2Implementation(
GLES2CmdHelper* helper,
+ size_t transfer_buffer_size,
void* transfer_buffer,
- int transfer_buffer_id); // TODO: add size.
+ int32 transfer_buffer_id);
// Include the auto-generated part of this class. We split this because
// it means we can easily edit the non-auto generated parts right here in
@@ -71,10 +40,35 @@ class GLES2Implementation {
// Frees a set of Ids for glDelete___ functions.
void FreeIds(GLsizei n, const GLuint* ids);
+ // Gets the shared memory id for the result buffer.
+ uint32 result_shm_id() const {
+ return transfer_buffer_id_;
+ }
+
+ // Gets the shared memory offset for the result buffer.
+ uint32 result_shm_offset() const {
+ return result_shm_offset_;
+ }
+
+ // Gets the value of the result.
+ template <typename T>
+ T GetResultAs() const {
+ return *static_cast<T*>(result_buffer_);
+ }
+
+ // Waits for all commands to execute.
+ void WaitForCmd();
+
+ // The maxiumum result size from simple GL get commands.
+ static const size_t kMaxSizeOfSimpleResult = 4 * sizeof(uint32); // NOLINT.
+
GLES2Util util_;
GLES2CmdHelper* helper_;
IdAllocator id_allocator_;
- SharedMemoryHelper shared_memory_; // TODO(gman): rename transfer_buffer_.
+ FencedAllocatorWrapper transfer_buffer_;
+ int transfer_buffer_id_;
+ void* result_buffer_;
+ uint32 result_shm_offset_;
// pack alignment as last set by glPixelStorei
GLint pack_alignment_;
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h
index 940454b..c4b34b9 100644
--- a/gpu/command_buffer/client/gles2_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -252,77 +252,63 @@ void GetActiveUniform(
void GetAttachedShaders(
GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
-int GetAttribLocation(GLuint program, const char* name) {
- // TODO(gman): This needs to change to use SendString.
- GLint* result = shared_memory_.GetAddressAs<GLint*>(0);
- DCHECK(false); // pass in shared memory
- helper_->GetAttribLocationImmediate(program, name);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
- return *result;
-}
+GLint GetAttribLocation(GLuint program, const char* name);
void GetBooleanv(GLenum pname, GLboolean* params) {
- helper_->GetBooleanv(pname, shared_memory_.GetId(), 0);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
+ helper_->GetBooleanv(pname, result_shm_id(), result_shm_offset());
+ WaitForCmd();
GLsizei num_values = util_.GLGetNumValuesReturned(pname);
- memcpy(params, shared_memory_.GetAddress(0),
- num_values * sizeof(*params));
+ DCHECK_LE(num_values * sizeof(*params), kMaxSizeOfSimpleResult);
+ memcpy(params, result_buffer_, num_values * sizeof(*params));
}
void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params) {
- helper_->GetBufferParameteriv(target, pname, shared_memory_.GetId(), 0);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
+ helper_->GetBufferParameteriv(
+ target, pname, result_shm_id(), result_shm_offset());
+ WaitForCmd();
GLsizei num_values = util_.GLGetNumValuesReturned(pname);
- memcpy(params, shared_memory_.GetAddress(0),
- num_values * sizeof(*params));
+ DCHECK_LE(num_values * sizeof(*params), kMaxSizeOfSimpleResult);
+ memcpy(params, result_buffer_, num_values * sizeof(*params));
}
GLenum GetError() {
- helper_->GetError(shared_memory_.GetId(), 0);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
- return *shared_memory_.GetAddressAs<GLenum*>(0);
+ helper_->GetError(result_shm_id(), result_shm_offset());
+ WaitForCmd();
+ return GetResultAs<GLenum>();
}
void GetFloatv(GLenum pname, GLfloat* params) {
- helper_->GetFloatv(pname, shared_memory_.GetId(), 0);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
+ helper_->GetFloatv(pname, result_shm_id(), result_shm_offset());
+ WaitForCmd();
GLsizei num_values = util_.GLGetNumValuesReturned(pname);
- memcpy(params, shared_memory_.GetAddress(0),
- num_values * sizeof(*params));
+ DCHECK_LE(num_values * sizeof(*params), kMaxSizeOfSimpleResult);
+ memcpy(params, result_buffer_, num_values * sizeof(*params));
}
void GetFramebufferAttachmentParameteriv(
GLenum target, GLenum attachment, GLenum pname, GLint* params) {
helper_->GetFramebufferAttachmentParameteriv(
- target, attachment, pname, shared_memory_.GetId(), 0);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
+ target, attachment, pname, result_shm_id(), result_shm_offset());
+ WaitForCmd();
GLsizei num_values = util_.GLGetNumValuesReturned(pname);
- memcpy(params, shared_memory_.GetAddress(0),
- num_values * sizeof(*params));
+ DCHECK_LE(num_values * sizeof(*params), kMaxSizeOfSimpleResult);
+ memcpy(params, result_buffer_, num_values * sizeof(*params));
}
void GetIntegerv(GLenum pname, GLint* params) {
- helper_->GetIntegerv(pname, shared_memory_.GetId(), 0);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
+ helper_->GetIntegerv(pname, result_shm_id(), result_shm_offset());
+ WaitForCmd();
GLsizei num_values = util_.GLGetNumValuesReturned(pname);
- memcpy(params, shared_memory_.GetAddress(0),
- num_values * sizeof(*params));
+ DCHECK_LE(num_values * sizeof(*params), kMaxSizeOfSimpleResult);
+ memcpy(params, result_buffer_, num_values * sizeof(*params));
}
void GetProgramiv(GLuint program, GLenum pname, GLint* params) {
- helper_->GetProgramiv(program, pname, shared_memory_.GetId(), 0);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
+ helper_->GetProgramiv(program, pname, result_shm_id(), result_shm_offset());
+ WaitForCmd();
GLsizei num_values = util_.GLGetNumValuesReturned(pname);
- memcpy(params, shared_memory_.GetAddress(0),
- num_values * sizeof(*params));
+ DCHECK_LE(num_values * sizeof(*params), kMaxSizeOfSimpleResult);
+ memcpy(params, result_buffer_, num_values * sizeof(*params));
}
// TODO(gman): Implement this
@@ -331,21 +317,19 @@ void GetProgramInfoLog(
void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) {
helper_->GetRenderbufferParameteriv(
- target, pname, shared_memory_.GetId(), 0);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
+ target, pname, result_shm_id(), result_shm_offset());
+ WaitForCmd();
GLsizei num_values = util_.GLGetNumValuesReturned(pname);
- memcpy(params, shared_memory_.GetAddress(0),
- num_values * sizeof(*params));
+ DCHECK_LE(num_values * sizeof(*params), kMaxSizeOfSimpleResult);
+ memcpy(params, result_buffer_, num_values * sizeof(*params));
}
void GetShaderiv(GLuint shader, GLenum pname, GLint* params) {
- helper_->GetShaderiv(shader, pname, shared_memory_.GetId(), 0);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
+ helper_->GetShaderiv(shader, pname, result_shm_id(), result_shm_offset());
+ WaitForCmd();
GLsizei num_values = util_.GLGetNumValuesReturned(pname);
- memcpy(params, shared_memory_.GetAddress(0),
- num_values * sizeof(*params));
+ DCHECK_LE(num_values * sizeof(*params), kMaxSizeOfSimpleResult);
+ memcpy(params, result_buffer_, num_values * sizeof(*params));
}
// TODO(gman): Implement this
@@ -362,53 +346,45 @@ void GetShaderSource(
const GLubyte* GetString(GLenum name);
void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) {
- helper_->GetTexParameterfv(target, pname, shared_memory_.GetId(), 0);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
+ helper_->GetTexParameterfv(
+ target, pname, result_shm_id(), result_shm_offset());
+ WaitForCmd();
GLsizei num_values = util_.GLGetNumValuesReturned(pname);
- memcpy(params, shared_memory_.GetAddress(0),
- num_values * sizeof(*params));
+ DCHECK_LE(num_values * sizeof(*params), kMaxSizeOfSimpleResult);
+ memcpy(params, result_buffer_, num_values * sizeof(*params));
}
void GetTexParameteriv(GLenum target, GLenum pname, GLint* params) {
- helper_->GetTexParameteriv(target, pname, shared_memory_.GetId(), 0);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
+ helper_->GetTexParameteriv(
+ target, pname, result_shm_id(), result_shm_offset());
+ WaitForCmd();
GLsizei num_values = util_.GLGetNumValuesReturned(pname);
- memcpy(params, shared_memory_.GetAddress(0),
- num_values * sizeof(*params));
+ DCHECK_LE(num_values * sizeof(*params), kMaxSizeOfSimpleResult);
+ memcpy(params, result_buffer_, num_values * sizeof(*params));
}
void GetUniformfv(GLuint program, GLint location, GLfloat* params);
void GetUniformiv(GLuint program, GLint location, GLint* params);
-int GetUniformLocation(GLuint program, const char* name) {
- // TODO(gman): This needs to change to use SendString.
- GLint* result = shared_memory_.GetAddressAs<GLint*>(0);
- DCHECK(false); // pass in shared memory
- helper_->GetUniformLocationImmediate(program, name);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
- return *result;
-}
+GLint GetUniformLocation(GLuint program, const char* name);
void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) {
- helper_->GetVertexAttribfv(index, pname, shared_memory_.GetId(), 0);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
+ helper_->GetVertexAttribfv(
+ index, pname, result_shm_id(), result_shm_offset());
+ WaitForCmd();
GLsizei num_values = util_.GLGetNumValuesReturned(pname);
- memcpy(params, shared_memory_.GetAddress(0),
- num_values * sizeof(*params));
+ DCHECK_LE(num_values * sizeof(*params), kMaxSizeOfSimpleResult);
+ memcpy(params, result_buffer_, num_values * sizeof(*params));
}
void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params) {
- helper_->GetVertexAttribiv(index, pname, shared_memory_.GetId(), 0);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
+ helper_->GetVertexAttribiv(
+ index, pname, result_shm_id(), result_shm_offset());
+ WaitForCmd();
GLsizei num_values = util_.GLGetNumValuesReturned(pname);
- memcpy(params, shared_memory_.GetAddress(0),
- num_values * sizeof(*params));
+ DCHECK_LE(num_values * sizeof(*params), kMaxSizeOfSimpleResult);
+ memcpy(params, result_buffer_, num_values * sizeof(*params));
}
void GetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer);
@@ -418,52 +394,45 @@ void Hint(GLenum target, GLenum mode) {
}
GLboolean IsBuffer(GLuint buffer) {
- helper_->IsBuffer(buffer, shared_memory_.GetId(), 0);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
- return *shared_memory_.GetAddressAs<GLboolean*>(0);
+ helper_->IsBuffer(buffer, result_shm_id(), result_shm_offset());
+ WaitForCmd();
+ return GetResultAs<GLboolean>();
}
GLboolean IsEnabled(GLenum cap) {
- helper_->IsEnabled(cap, shared_memory_.GetId(), 0);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
- return *shared_memory_.GetAddressAs<GLboolean*>(0);
+ helper_->IsEnabled(cap, result_shm_id(), result_shm_offset());
+ WaitForCmd();
+ return GetResultAs<GLboolean>();
}
GLboolean IsFramebuffer(GLuint framebuffer) {
- helper_->IsFramebuffer(framebuffer, shared_memory_.GetId(), 0);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
- return *shared_memory_.GetAddressAs<GLboolean*>(0);
+ helper_->IsFramebuffer(framebuffer, result_shm_id(), result_shm_offset());
+ WaitForCmd();
+ return GetResultAs<GLboolean>();
}
GLboolean IsProgram(GLuint program) {
- helper_->IsProgram(program, shared_memory_.GetId(), 0);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
- return *shared_memory_.GetAddressAs<GLboolean*>(0);
+ helper_->IsProgram(program, result_shm_id(), result_shm_offset());
+ WaitForCmd();
+ return GetResultAs<GLboolean>();
}
GLboolean IsRenderbuffer(GLuint renderbuffer) {
- helper_->IsRenderbuffer(renderbuffer, shared_memory_.GetId(), 0);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
- return *shared_memory_.GetAddressAs<GLboolean*>(0);
+ helper_->IsRenderbuffer(renderbuffer, result_shm_id(), result_shm_offset());
+ WaitForCmd();
+ return GetResultAs<GLboolean>();
}
GLboolean IsShader(GLuint shader) {
- helper_->IsShader(shader, shared_memory_.GetId(), 0);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
- return *shared_memory_.GetAddressAs<GLboolean*>(0);
+ helper_->IsShader(shader, result_shm_id(), result_shm_offset());
+ WaitForCmd();
+ return GetResultAs<GLboolean>();
}
GLboolean IsTexture(GLuint texture) {
- helper_->IsTexture(texture, shared_memory_.GetId(), 0);
- int32 token = helper_->InsertToken();
- helper_->WaitForToken(token);
- return *shared_memory_.GetAddressAs<GLboolean*>(0);
+ helper_->IsTexture(texture, result_shm_id(), result_shm_offset());
+ WaitForCmd();
+ return GetResultAs<GLboolean>();
}
void LineWidth(GLfloat width) {
@@ -474,9 +443,7 @@ void LinkProgram(GLuint program) {
helper_->LinkProgram(program);
}
-void PixelStorei(GLenum pname, GLint param) {
- helper_->PixelStorei(pname, param);
-}
+void PixelStorei(GLenum pname, GLint param);
void PolygonOffset(GLfloat factor, GLfloat units) {
helper_->PolygonOffset(factor, units);