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

Unified Diff: gpu/command_buffer/service/gles2_cmd_decoder.cc

Issue 1309743005: command_buffer: Implement EXT_blend_func_extended (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@new-05-path-fragment-input-gen
Patch Set: address review comments Created 5 years, 3 months 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 7fe1db9fd18f38b4523de103e26375b2ee6fefdb..ae577b53a849baa4f37e9400024ee737f873af1b 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -325,13 +325,10 @@ static bool CharacterIsValidForGLES(unsigned char c) {
return false;
}
-static bool StringIsValidForGLES(const char* str) {
- for (; *str; ++str) {
- if (!CharacterIsValidForGLES(*str)) {
- return false;
- }
- }
- return true;
+static bool StringIsValidForGLES(const std::string& str) {
+ return str.length() == 0 ||
+ std::find_if_not(str.begin(), str.end(), CharacterIsValidForGLES) ==
+ str.end();
}
// This class prevents any GL errors that occur when it is in scope from
@@ -1272,9 +1269,22 @@ class GLES2DecoderImpl : public GLES2Decoder,
client_id, service_id, group_->max_vertex_attribs(), client_visible);
}
- void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
- void DoBindUniformLocationCHROMIUM(
- GLuint client_id, GLint location, const char* name);
+ void DoBindAttribLocation(GLuint client_id,
+ GLuint index,
+ const std::string& name);
+
+ error::Error DoBindFragDataLocation(GLuint program_id,
+ GLuint colorName,
+ const std::string& name);
+
+ error::Error DoBindFragDataLocationIndexed(GLuint program_id,
+ GLuint colorName,
+ GLuint index,
+ const std::string& name);
+
+ void DoBindUniformLocationCHROMIUM(GLuint client_id,
+ GLint location,
+ const std::string& name);
error::Error GetAttribLocationHelper(
GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
@@ -1288,6 +1298,11 @@ class GLES2DecoderImpl : public GLES2Decoder,
GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
const std::string& name_str);
+ error::Error GetFragDataIndexHelper(GLuint program_id,
+ uint32 index_shm_id,
+ uint32 index_shm_offset,
+ const std::string& name_str);
+
// Wrapper for glShaderSource.
void DoShaderSource(
GLuint client_id, GLsizei count, const char** data, const GLint* length);
@@ -1948,7 +1963,7 @@ class GLES2DecoderImpl : public GLES2Decoder,
void DoBindFragmentInputLocationCHROMIUM(GLuint program_id,
GLint location,
- const char* name);
+ const std::string& name);
// Generate a member function prototype for each command in an automated and
// typesafe way.
@@ -3265,6 +3280,7 @@ bool GLES2DecoderImpl::InitializeShaderTranslator() {
resources.MaxDrawBuffers = group_->max_draw_buffers();
resources.MaxExpressionComplexity = 256;
resources.MaxCallStackDepth = 256;
+ resources.MaxDualSourceDrawBuffers = group_->max_dual_source_draw_buffers();
GLint range[2] = { 0, 0 };
GLint precision = 0;
@@ -3297,6 +3313,8 @@ bool GLES2DecoderImpl::InitializeShaderTranslator() {
features().ext_shader_texture_lod ? 1 : 0;
resources.NV_draw_buffers =
features().nv_draw_buffers ? 1 : 0;
+ resources.EXT_blend_func_extended =
+ features().ext_blend_func_extended ? 1 : 0;
}
ShShaderSpec shader_spec;
@@ -5518,6 +5536,12 @@ bool GLES2DecoderImpl::GetHelper(
params[0] = group_->bind_generates_resource() ? 1 : 0;
}
return true;
+ case GL_MAX_DUAL_SOURCE_DRAW_BUFFERS:
Zhenyao Mo 2015/09/30 00:23:47 Use _EXT instead.
Kimmo Kinnunen 2015/10/08 13:18:12 Done.
+ *num_written = 1;
+ if (params) {
+ params[0] = group_->max_dual_source_draw_buffers();
+ }
+ return true;
default:
if (pname >= GL_DRAW_BUFFER0_ARB &&
pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
@@ -5647,14 +5671,15 @@ void GLES2DecoderImpl::DoGetBufferParameteriv(
&state_, target, pname, params);
}
-void GLES2DecoderImpl::DoBindAttribLocation(
- GLuint program_id, GLuint index, const char* name) {
+void GLES2DecoderImpl::DoBindAttribLocation(GLuint program_id,
+ GLuint index,
+ const std::string& name) {
if (!StringIsValidForGLES(name)) {
LOCAL_SET_GL_ERROR(
GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
return;
}
- if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
+ if (ProgramManager::HasBuiltInPrefix(name)) {
LOCAL_SET_GL_ERROR(
GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
return;
@@ -5676,7 +5701,7 @@ void GLES2DecoderImpl::DoBindAttribLocation(
// Program::ExecuteBindAttribLocationCalls() right before link.
program->SetAttribLocationBinding(name, static_cast<GLint>(index));
// TODO(zmo): Get rid of the following glBindAttribLocation call.
- glBindAttribLocation(program->service_id(), index, name);
+ glBindAttribLocation(program->service_id(), index, name.c_str());
}
error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
@@ -5694,19 +5719,123 @@ error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
if (!bucket->GetAsString(&name_str)) {
return error::kInvalidArguments;
}
- DoBindAttribLocation(program, index, name_str.c_str());
+ DoBindAttribLocation(program, index, name_str);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::DoBindFragDataLocation(GLuint program_id,
+ GLuint colorName,
+ const std::string& name) {
+ const char kFunctionName[] = "glBindFragDataLocationEXT";
+ if (!StringIsValidForGLES(name)) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "invalid character");
+ return error::kNoError;
+ }
+ if (ProgramManager::HasBuiltInPrefix(name)) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, "reserved prefix");
+ return error::kNoError;
+ }
+ if (colorName >= group_->max_draw_buffers()) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName,
+ "colorName out of range");
+ return error::kNoError;
+ }
+ Program* program = GetProgramInfoNotShader(program_id, kFunctionName);
+ if (!program) {
+ return error::kNoError;
+ }
+ if (!program->SetProgramOutputLocationBinding(name, colorName)) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, "invalid name");
+ return error::kNoError;
+ }
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleBindFragDataLocationEXTBucket(
+ uint32 immediate_data_size,
+ const void* cmd_data) {
+ if (!features().ext_blend_func_extended) {
+ return error::kUnknownCommand;
+ }
+ const gles2::cmds::BindFragDataLocationEXTBucket& c =
+ *static_cast<const gles2::cmds::BindFragDataLocationEXTBucket*>(cmd_data);
+ GLuint program = static_cast<GLuint>(c.program);
+ GLuint colorNumber = static_cast<GLint>(c.colorNumber);
Zhenyao Mo 2015/09/30 00:23:47 static_cast<GLuint>
Kimmo Kinnunen 2015/10/08 13:18:12 Done.
+ Bucket* bucket = GetBucket(c.name_bucket_id);
+ if (!bucket || bucket->size() == 0) {
+ return error::kInvalidArguments;
+ }
+ std::string name_str;
+ if (!bucket->GetAsString(&name_str)) {
+ return error::kInvalidArguments;
+ }
+ return DoBindFragDataLocation(program, colorNumber, name_str);
+}
+
+error::Error GLES2DecoderImpl::DoBindFragDataLocationIndexed(
+ GLuint program_id,
+ GLuint colorName,
+ GLuint index,
+ const std::string& name) {
+ const char kFunctionName[] = "glBindFragDataLocationIndexEXT";
+ if (!StringIsValidForGLES(name)) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "invalid character");
+ return error::kNoError;
+ }
+ if (ProgramManager::HasBuiltInPrefix(name)) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, "reserved prefix");
+ return error::kNoError;
+ }
+ if ((index == 0 && colorName >= group_->max_draw_buffers()) ||
Zhenyao Mo 2015/09/30 00:23:47 You should validate index == 0 || index == 1) firs
Kimmo Kinnunen 2015/10/08 13:18:12 Done.
+ (index == 1 && colorName >= group_->max_dual_source_draw_buffers())) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName,
+ "colorName out of range for the color index");
+ return error::kNoError;
+ }
+ Program* program = GetProgramInfoNotShader(program_id, kFunctionName);
+ if (!program) {
+ return error::kNoError;
+ }
+ if (!program->SetProgramOutputLocationBinding(name, colorName, index)) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, "invalid name");
+ return error::kNoError;
+ }
return error::kNoError;
}
-void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
- GLuint program_id, GLint location, const char* name) {
+error::Error GLES2DecoderImpl::HandleBindFragDataLocationIndexedEXTBucket(
+ uint32 immediate_data_size,
+ const void* cmd_data) {
+ if (!features().ext_blend_func_extended) {
+ return error::kUnknownCommand;
+ }
+ const gles2::cmds::BindFragDataLocationIndexedEXTBucket& c =
+ *static_cast<const gles2::cmds::BindFragDataLocationIndexedEXTBucket*>(
+ cmd_data);
+ GLuint program = static_cast<GLuint>(c.program);
+ GLuint colorNumber = static_cast<GLint>(c.colorNumber);
Zhenyao Mo 2015/09/30 00:23:47 GLuint
Kimmo Kinnunen 2015/10/08 13:18:12 Done.
+ GLuint index = static_cast<GLint>(c.index);
Zhenyao Mo 2015/09/30 00:23:47 GLuint
Kimmo Kinnunen 2015/10/08 13:18:12 Done.
+ Bucket* bucket = GetBucket(c.name_bucket_id);
+ if (!bucket || bucket->size() == 0) {
+ return error::kInvalidArguments;
+ }
+ std::string name_str;
+ if (!bucket->GetAsString(&name_str)) {
+ return error::kInvalidArguments;
+ }
+ return DoBindFragDataLocationIndexed(program, colorNumber, index, name_str);
+}
+
+void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(GLuint program_id,
+ GLint location,
+ const std::string& name) {
if (!StringIsValidForGLES(name)) {
LOCAL_SET_GL_ERROR(
GL_INVALID_VALUE,
"glBindUniformLocationCHROMIUM", "Invalid character");
return;
}
- if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
+ if (ProgramManager::HasBuiltInPrefix(name)) {
LOCAL_SET_GL_ERROR(
GL_INVALID_OPERATION,
"glBindUniformLocationCHROMIUM", "reserved prefix");
@@ -5748,7 +5877,7 @@ error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
if (!bucket->GetAsString(&name_str)) {
return error::kInvalidArguments;
}
- DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
+ DoBindUniformLocationCHROMIUM(program, location, name_str);
return error::kNoError;
}
@@ -9303,7 +9432,7 @@ error::Error GLES2DecoderImpl::HandleScheduleOverlayPlaneCHROMIUM(
error::Error GLES2DecoderImpl::GetAttribLocationHelper(
GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
const std::string& name_str) {
- if (!StringIsValidForGLES(name_str.c_str())) {
+ if (!StringIsValidForGLES(name_str)) {
LOCAL_SET_GL_ERROR(
GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
return error::kNoError;
@@ -9352,7 +9481,7 @@ error::Error GLES2DecoderImpl::HandleGetAttribLocation(
error::Error GLES2DecoderImpl::GetUniformLocationHelper(
GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
const std::string& name_str) {
- if (!StringIsValidForGLES(name_str.c_str())) {
+ if (!StringIsValidForGLES(name_str)) {
LOCAL_SET_GL_ERROR(
GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
return error::kNoError;
@@ -9453,6 +9582,7 @@ error::Error GLES2DecoderImpl::HandleGetUniformIndices(
error::Error GLES2DecoderImpl::GetFragDataLocationHelper(
GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
const std::string& name_str) {
+ const char kFunctionName[] = "glGetFragDataLocation";
GLint* location = GetSharedMemoryAs<GLint*>(
location_shm_id, location_shm_offset, sizeof(GLint));
if (!location) {
@@ -9463,12 +9593,17 @@ error::Error GLES2DecoderImpl::GetFragDataLocationHelper(
if (*location != -1) {
return error::kGenericError;
}
- Program* program = GetProgramInfoNotShader(
- client_id, "glGetFragDataLocation");
+ Program* program = GetProgramInfoNotShader(client_id, kFunctionName);
if (!program) {
return error::kNoError;
}
- *location = glGetFragDataLocation(program->service_id(), name_str.c_str());
+ if (!program->IsValid()) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName,
+ "program not linked");
+ return error::kNoError;
+ }
+
+ *location = program->GetFragDataLocation(name_str);
return error::kNoError;
}
@@ -9491,6 +9626,56 @@ error::Error GLES2DecoderImpl::HandleGetFragDataLocation(
c.program, c.location_shm_id, c.location_shm_offset, name_str);
}
+error::Error GLES2DecoderImpl::GetFragDataIndexHelper(
+ GLuint program_id,
+ uint32 index_shm_id,
+ uint32 index_shm_offset,
+ const std::string& name_str) {
+ const char kFunctionName[] = "glGetFragDataIndexEXT";
+ GLint* index =
+ GetSharedMemoryAs<GLint*>(index_shm_id, index_shm_offset, sizeof(GLint));
+ if (!index) {
+ return error::kOutOfBounds;
+ }
+ // Require the client to init this incase the context is lost and we are no
+ // longer executing commands.
+ if (*index != -1) {
+ return error::kGenericError;
Zhenyao Mo 2015/09/30 00:23:47 We return kInvalidArguments in such cases.
Kimmo Kinnunen 2015/10/08 13:18:12 Done.
+ }
+ Program* program = GetProgramInfoNotShader(program_id, kFunctionName);
+ if (!program) {
+ return error::kNoError;
+ }
+ if (!program->IsValid()) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName,
+ "program not linked");
+ return error::kNoError;
+ }
+
+ *index = program->GetFragDataIndex(name_str);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleGetFragDataIndexEXT(
+ uint32 immediate_data_size,
+ const void* cmd_data) {
+ if (!features().ext_blend_func_extended) {
+ return error::kUnknownCommand;
+ }
+ const gles2::cmds::GetFragDataIndexEXT& c =
+ *static_cast<const gles2::cmds::GetFragDataIndexEXT*>(cmd_data);
+ Bucket* bucket = GetBucket(c.name_bucket_id);
+ if (!bucket) {
+ return error::kInvalidArguments;
+ }
+ std::string name_str;
+ if (!bucket->GetAsString(&name_str)) {
+ return error::kInvalidArguments;
+ }
+ return GetFragDataIndexHelper(c.program, c.index_shm_id, c.index_shm_offset,
+ name_str);
+}
+
error::Error GLES2DecoderImpl::HandleGetUniformBlockIndex(
uint32 immediate_data_size, const void* cmd_data) {
if (!unsafe_es3_apis_enabled())
@@ -15642,23 +15827,24 @@ GLES2DecoderImpl::HandleStencilThenCoverStrokePathInstancedCHROMIUM(
return error::kNoError;
}
-void GLES2DecoderImpl::DoBindFragmentInputLocationCHROMIUM(GLuint program_id,
- GLint location,
- const char* name) {
+void GLES2DecoderImpl::DoBindFragmentInputLocationCHROMIUM(
+ GLuint program_id,
+ GLint location,
+ const std::string& name) {
static const char kFunctionName[] = "glBindFragmentInputLocationCHROMIUM";
- Program* program = GetProgram(program_id);
- if (!program || program->IsDeleted()) {
- LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, "invalid program");
- return;
- }
if (!StringIsValidForGLES(name)) {
LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "invalid character");
return;
}
- if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
+ if (ProgramManager::HasBuiltInPrefix(name)) {
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, "reserved prefix");
return;
}
+ Program* program = GetProgram(program_id);
+ if (!program || program->IsDeleted()) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, "invalid program");
+ return;
+ }
if (location < 0 ||
static_cast<uint32>(location) >= group_->max_varying_vectors() * 4) {
LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName,
@@ -15692,7 +15878,7 @@ error::Error GLES2DecoderImpl::HandleBindFragmentInputLocationCHROMIUMBucket(
if (!bucket->GetAsString(&name_str)) {
return error::kInvalidArguments;
}
- DoBindFragmentInputLocationCHROMIUM(program, location, name_str.c_str());
+ DoBindFragmentInputLocationCHROMIUM(program, location, name_str);
return error::kNoError;
}

Powered by Google App Engine
This is Rietveld 408576698