Skip to content

Commit

Permalink
Cache OpenGL program info on the client side of the command buffer.
Browse files Browse the repository at this point in the history
For contexts not sharing resources this means the 3 to 30 calls
to get link status and attrib/uniform locations will go from
3-30 sync calls to 1 sync call.

TEST=unit tests and ran OpenGL ES 2.0 conformance tests
BUG=85966


Review URL: http://codereview.chromium.org/7358006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@95836 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
gman@chromium.org committed Aug 8, 2011
1 parent 4e601fc commit 9a14ae6
Show file tree
Hide file tree
Showing 11 changed files with 753 additions and 96 deletions.
22 changes: 13 additions & 9 deletions gpu/command_buffer/build_gles2_cmd_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1489,7 +1489,10 @@
'decoder_func': 'DoIsTexture',
'expectation': False,
},
'LinkProgram': {'decoder_func': 'DoLinkProgram'},
'LinkProgram': {
'decoder_func': 'DoLinkProgram',
'impl_func': False,
},
'MapBufferSubDataCHROMIUM': {
'gen_cmd': False,
'extension': True,
Expand Down Expand Up @@ -3068,7 +3071,7 @@ def WriteGLES2ImplementationHeader(self, func, file):
arg.WriteClientSideValidationCode(file, func)
file.Write(
" GPU_CLIENT_DCHECK(%s != 0);\n" % func.GetOriginalArgs()[-1].name)
file.Write(" program_and_shader_id_handler_->FreeIds(1, &%s);\n" %
file.Write(" DeleteProgramOrShaderHelper(%s);\n" %
func.GetOriginalArgs()[-1].name)
file.Write(" helper_->%s(%s);\n" %
(func.name, func.MakeCmdArgString("")))
Expand Down Expand Up @@ -4212,19 +4215,20 @@ def WriteGLES2ImplementationHeader(self, func, file):
<< static_cast<void*>(%(arg3)s) << ")");
helper_->SetBucketSize(kResultBucketId, 0);
helper_->%(func_name)s(%(id_name)s, kResultBucketId);
if (bufsize > 0) {
std::string str;
if (GetBucketAsString(kResultBucketId, &str)) {
GLsizei max_size =
std::string str;
GLsizei max_size = 0;
if (GetBucketAsString(kResultBucketId, &str)) {
if (bufsize > 0) {
max_size =
std::min(static_cast<size_t>(%(bufsize_name)s) - 1, str.size());
if (%(length_name)s != NULL) {
*%(length_name)s = max_size;
}
memcpy(%(dest_name)s, str.c_str(), max_size);
%(dest_name)s[max_size] = '\\0';
GPU_CLIENT_LOG("------\\n" << %(dest_name)s << "\\n------");
}
}
if (%(length_name)s != NULL) {
*%(length_name)s = max_size;
}
}
"""
args = func.GetOriginalArgs()
Expand Down
150 changes: 110 additions & 40 deletions gpu/command_buffer/client/gles2_implementation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <GLES2/gl2ext.h>
#include <GLES2/gles2_command_buffer.h>
#include "../client/mapped_memory.h"
#include "../client/program_info_manager.h"
#include "../common/gles2_cmd_utils.h"
#include "../common/id_allocator.h"
#include "../common/trace_event.h"
Expand Down Expand Up @@ -514,6 +515,9 @@ GLES2Implementation::GLES2Implementation(
texture_units_.reset(
new TextureUnit[gl_state_.max_combined_texture_image_units]);


program_info_manager_.reset(ProgramInfoManager::Create(sharing_resources_));

#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
buffer_id_handler_->MakeIds(
kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]);
Expand Down Expand Up @@ -949,28 +953,37 @@ void GLES2Implementation::GetVertexAttribPointerv(
});
}

GLint GLES2Implementation::GetAttribLocation(
void GLES2Implementation::DeleteProgramOrShaderHelper(
GLuint program_or_shader) {
program_and_shader_id_handler_->FreeIds(1, &program_or_shader);
program_info_manager_->DeleteInfo(program_or_shader);
}

GLint GLES2Implementation::GetAttribLocationHelper(
GLuint program, const char* name) {
GPU_CLIENT_LOG("[" << this << "] glGetAttribLocation(" << program
<< ", " << name << ")");
TRACE_EVENT0("gpu", "GLES2::GetAttribLocation");
typedef GetAttribLocationBucket::Result Result;
Result* result = GetResultAs<Result*>();
*result = -1;
SetBucketAsCString(kResultBucketId, name);
helper_->GetAttribLocationBucket(program, kResultBucketId,
result_shm_id(), result_shm_offset());
helper_->GetAttribLocationBucket(
program, kResultBucketId, result_shm_id(), result_shm_offset());
WaitForCmd();
helper_->SetBucketSize(kResultBucketId, 0);
GPU_CLIENT_LOG("returned " << *result);
return *result;
}

GLint GLES2Implementation::GetUniformLocation(
GLint GLES2Implementation::GetAttribLocation(
GLuint program, const char* name) {
GPU_CLIENT_LOG("[" << this << "] glGetUniformLocation(" << program
GPU_CLIENT_LOG("[" << this << "] glGetAttribLocation(" << program
<< ", " << name << ")");
TRACE_EVENT0("gpu", "GLES2::GetUniformLocation");
TRACE_EVENT0("gpu", "GLES2::GetAttribLocation");
GLint loc = program_info_manager_->GetAttribLocation(this, program, name);
GPU_CLIENT_LOG("returned " << loc);
return loc;
}

GLint GLES2Implementation::GetUniformLocationHelper(
GLuint program, const char* name) {
typedef GetUniformLocationBucket::Result Result;
Result* result = GetResultAs<Result*>();
*result = -1;
Expand All @@ -979,10 +992,29 @@ GLint GLES2Implementation::GetUniformLocation(
result_shm_id(), result_shm_offset());
WaitForCmd();
helper_->SetBucketSize(kResultBucketId, 0);
GPU_CLIENT_LOG("returned " << *result);
return *result;
}

GLint GLES2Implementation::GetUniformLocation(
GLuint program, const char* name) {
GPU_CLIENT_LOG("[" << this << "] glGetUniformLocation(" << program
<< ", " << name << ")");
TRACE_EVENT0("gpu", "GLES2::GetUniformLocation");
GLint loc = program_info_manager_->GetUniformLocation(this, program, name);
GPU_CLIENT_LOG("returned " << loc);
return loc;
}

bool GLES2Implementation::GetProgramivHelper(
GLuint program, GLenum pname, GLint* params) {
return program_info_manager_->GetProgramiv(this, program, pname, params);
}

void GLES2Implementation::LinkProgram(GLuint program) {
GPU_CLIENT_LOG("[" << this << "] glLinkProgram(" << program << ")");
helper_->LinkProgram(program);
program_info_manager_->CreateInfo(program);
}

void GLES2Implementation::ShaderBinary(
GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary,
Expand Down Expand Up @@ -1436,21 +1468,10 @@ void GLES2Implementation::TexSubImage2DImpl(
}
}

void GLES2Implementation::GetActiveAttrib(
bool GLES2Implementation::GetActiveAttribHelper(
GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size,
GLenum* type, char* name) {
GPU_CLIENT_LOG("[" << this << "] glGetActiveAttrib("
<< program << ", " << index << ", " << bufsize << ", "
<< static_cast<const void*>(length) << ", "
<< static_cast<const void*>(size) << ", "
<< static_cast<const void*>(type) << ", "
<< static_cast<const void*>(name) << ", ");
if (bufsize < 0) {
SetGLError(GL_INVALID_VALUE, "glGetActiveAttrib: bufsize < 0");
return;
}
TRACE_EVENT0("gpu", "GLES2::GetActiveAttrib");
// Clear the bucket so if we the command fails nothing will be in it.
// Clear the bucket so if the command fails nothing will be in it.
helper_->SetBucketSize(kResultBucketId, 0);
typedef gles2::GetActiveAttrib::Result Result;
Result* result = static_cast<Result*>(result_buffer_);
Expand All @@ -1462,11 +1483,9 @@ void GLES2Implementation::GetActiveAttrib(
if (result->success) {
if (size) {
*size = result->size;
GPU_CLIENT_LOG(" size: " << *size);
}
if (type) {
*type = result->type;
GPU_CLIENT_LOG(" type: " << GLES2Util::GetStringEnum(*type));
}
if (length || name) {
std::vector<int8> str;
Expand All @@ -1480,27 +1499,45 @@ void GLES2Implementation::GetActiveAttrib(
if (name && bufsize > 0) {
memcpy(name, &str[0], max_size);
name[max_size] = '\0';
GPU_CLIENT_LOG(" name: " << name);
}
}
}
return result->success != 0;
}

void GLES2Implementation::GetActiveUniform(
void GLES2Implementation::GetActiveAttrib(
GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size,
GLenum* type, char* name) {
GPU_CLIENT_LOG("[" << this << "] glGetActiveUniform("
GPU_CLIENT_LOG("[" << this << "] glGetActiveAttrib("
<< program << ", " << index << ", " << bufsize << ", "
<< static_cast<const void*>(length) << ", "
<< static_cast<const void*>(size) << ", "
<< static_cast<const void*>(type) << ", "
<< static_cast<const void*>(name) << ", ");
if (bufsize < 0) {
SetGLError(GL_INVALID_VALUE, "glGetActiveUniform: bufsize < 0");
SetGLError(GL_INVALID_VALUE, "glGetActiveAttrib: bufsize < 0");
return;
}
TRACE_EVENT0("gpu", "GLES2::GetActiveUniform");
// Clear the bucket so if we the command fails nothing will be in it.
TRACE_EVENT0("gpu", "GLES2::GetActiveAttrib");
bool success = program_info_manager_->GetActiveAttrib(
this, program, index, bufsize, length, size, type, name);
if (success) {
if (size) {
GPU_CLIENT_LOG(" size: " << *size);
}
if (type) {
GPU_CLIENT_LOG(" type: " << GLES2Util::GetStringEnum(*type));
}
if (name) {
GPU_CLIENT_LOG(" name: " << name);
}
}
}

bool GLES2Implementation::GetActiveUniformHelper(
GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size,
GLenum* type, char* name) {
// Clear the bucket so if the command fails nothing will be in it.
helper_->SetBucketSize(kResultBucketId, 0);
typedef gles2::GetActiveUniform::Result Result;
Result* result = static_cast<Result*>(result_buffer_);
Expand All @@ -1512,11 +1549,9 @@ void GLES2Implementation::GetActiveUniform(
if (result->success) {
if (size) {
*size = result->size;
GPU_CLIENT_LOG(" size: " << *size);
}
if (type) {
*type = result->type;
GPU_CLIENT_LOG(" type: " << GLES2Util::GetStringEnum(*type));
}
if (length || name) {
std::vector<int8> str;
Expand All @@ -1530,10 +1565,39 @@ void GLES2Implementation::GetActiveUniform(
if (name && bufsize > 0) {
memcpy(name, &str[0], max_size);
name[max_size] = '\0';
GPU_CLIENT_LOG(" name: " << name);
}
}
}
return result->success != 0;
}

void GLES2Implementation::GetActiveUniform(
GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size,
GLenum* type, char* name) {
GPU_CLIENT_LOG("[" << this << "] glGetActiveUniform("
<< program << ", " << index << ", " << bufsize << ", "
<< static_cast<const void*>(length) << ", "
<< static_cast<const void*>(size) << ", "
<< static_cast<const void*>(type) << ", "
<< static_cast<const void*>(name) << ", ");
if (bufsize < 0) {
SetGLError(GL_INVALID_VALUE, "glGetActiveUniform: bufsize < 0");
return;
}
TRACE_EVENT0("gpu", "GLES2::GetActiveUniform");
bool success = program_info_manager_->GetActiveUniform(
this, program, index, bufsize, length, size, type, name);
if (success) {
if (size) {
GPU_CLIENT_LOG(" size: " << *size);
}
if (type) {
GPU_CLIENT_LOG(" type: " << GLES2Util::GetStringEnum(*type));
}
if (name) {
GPU_CLIENT_LOG(" name: " << name);
}
}
}

void GLES2Implementation::GetAttachedShaders(
Expand Down Expand Up @@ -2332,6 +2396,15 @@ void GLES2Implementation::GetMultipleIntegervCHROMIUM(
});
}

void GLES2Implementation::GetProgramInfoCHROMIUMHelper(
GLuint program, std::vector<int8>* result) {
GPU_DCHECK(result);
// Clear the bucket so if the command fails nothing will be in it.
helper_->SetBucketSize(kResultBucketId, 0);
helper_->GetProgramInfoCHROMIUM(program, kResultBucketId);
GetBucketContents(kResultBucketId, result);
}

void GLES2Implementation::GetProgramInfoCHROMIUM(
GLuint program, GLsizei bufsize, GLsizei* size, void* info) {
if (bufsize < 0) {
Expand All @@ -2345,12 +2418,9 @@ void GLES2Implementation::GetProgramInfoCHROMIUM(
// Make sure they've set size to 0 else the value will be undefined on
// lost context.
GPU_DCHECK(*size == 0);
// Clear the bucket so if the command fails nothing will be in it.
helper_->SetBucketSize(kResultBucketId, 0);
helper_->GetProgramInfoCHROMIUM(program, kResultBucketId);
std::vector<int8> result;
GetBucketContents(kResultBucketId, &result);
if (result.size() == 0) {
GetProgramInfoCHROMIUMHelper(program, &result);
if (result.empty()) {
return;
}
*size = result.size();
Expand Down
19 changes: 14 additions & 5 deletions gpu/command_buffer/client/gles2_implementation.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class MappedMemoryManager;
namespace gles2 {

class ClientSideBufferHelper;
class ProgramInfoManager;

// Base class for IdHandlers
class IdHandlerInterface {
Expand Down Expand Up @@ -175,6 +176,17 @@ class GLES2Implementation {
void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params);
void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params);

void GetProgramInfoCHROMIUMHelper(GLuint program, std::vector<int8>* result);
void DeleteProgramOrShaderHelper(GLuint program_or_shader);
GLint GetAttribLocationHelper(GLuint program, const char* name);
GLint GetUniformLocationHelper(GLuint program, const char* name);
bool GetActiveAttribHelper(
GLuint program, GLuint index, GLsizei bufsize, GLsizei* length,
GLint* size, GLenum* type, char* name);
bool GetActiveUniformHelper(
GLuint program, GLuint index, GLsizei bufsize, GLsizei* length,
GLint* size, GLenum* type, char* name);

GLuint MakeTextureId() {
GLuint id;
texture_id_handler_->MakeIds(0, 1, &id);
Expand Down Expand Up @@ -479,6 +491,8 @@ class GLES2Implementation {

scoped_ptr<MappedMemoryManager> mapped_memory_;

scoped_ptr<ProgramInfoManager> program_info_manager_;

DISALLOW_COPY_AND_ASSIGN(GLES2Implementation);
};

Expand All @@ -495,11 +509,6 @@ inline bool GLES2Implementation::GetFramebufferAttachmentParameterivHelper(
return false;
}

inline bool GLES2Implementation::GetProgramivHelper(
GLuint /* program */, GLenum /* pname */, GLint* /* params */) {
return false;
}

inline bool GLES2Implementation::GetRenderbufferParameterivHelper(
GLenum /* target */, GLenum /* pname */, GLint* /* params */) {
return false;
Expand Down
Loading

0 comments on commit 9a14ae6

Please sign in to comment.