Index: gpu/command_buffer/service/program_manager.cc |
diff --git a/gpu/command_buffer/service/program_manager.cc b/gpu/command_buffer/service/program_manager.cc |
index fa72a021534d23d6d2175f0c84ba7de32892d0fc..7d3c6cd771aab7801de975c7494e386d81dd8681 100644 |
--- a/gpu/command_buffer/service/program_manager.cc |
+++ b/gpu/command_buffer/service/program_manager.cc |
@@ -117,6 +117,29 @@ uint32_t ComputeOffset(const void* start, const void* position) { |
static_cast<const uint8_t*>(start); |
} |
+ShaderVariableBaseType FragmentOutputTypeToBaseType(GLenum type) { |
+ switch (type) { |
+ case GL_INT: |
+ case GL_INT_VEC2: |
+ case GL_INT_VEC3: |
+ case GL_INT_VEC4: |
+ return SHADER_VARIABLE_INT; |
+ case GL_UNSIGNED_INT: |
+ case GL_UNSIGNED_INT_VEC2: |
+ case GL_UNSIGNED_INT_VEC3: |
+ case GL_UNSIGNED_INT_VEC4: |
+ return SHADER_VARIABLE_UINT; |
+ case GL_FLOAT: |
+ case GL_FLOAT_VEC2: |
+ case GL_FLOAT_VEC3: |
+ case GL_FLOAT_VEC4: |
+ return SHADER_VARIABLE_FLOAT; |
+ default: |
+ NOTREACHED(); |
+ return SHADER_VARIABLE_UNDEFINED_TYPE; |
+ } |
+} |
+ |
} // anonymous namespace. |
Program::UniformInfo::UniformInfo() |
@@ -272,6 +295,9 @@ Program::Program(ProgramManager* manager, GLuint service_id) |
link_status_(false), |
uniforms_cleared_(false), |
transform_feedback_buffer_mode_(GL_NONE) { |
+ DCHECK(manager_); |
+ fragment_output_base_types_.resize(manager_->max_draw_buffers()); |
+ ResetFragmentOutputBaseTypes(); |
manager_->StartTracking(this); |
} |
@@ -288,6 +314,37 @@ void Program::Reset() { |
program_output_infos_.clear(); |
sampler_indices_.clear(); |
attrib_location_to_index_map_.clear(); |
+ ResetFragmentOutputBaseTypes(); |
+} |
+ |
+void Program::ResetFragmentOutputBaseTypes() { |
+ for (uint32_t ii = 0; ii < fragment_output_base_types_.size(); ++ii) { |
+ fragment_output_base_types_[ii] = SHADER_VARIABLE_UNDEFINED_TYPE; |
+ } |
+} |
+ |
+void Program::UpdateFragmentOutputBaseTypes() { |
+ ResetFragmentOutputBaseTypes(); |
+ Shader* fragment_shader = |
+ attached_shaders_[ShaderTypeToIndex(GL_FRAGMENT_SHADER)].get(); |
+ DCHECK(fragment_shader); |
+ for (auto const& output : fragment_shader->output_variable_list()) { |
+ DCHECK(output.location == -1 || |
+ (output.location >= 0 && |
+ output.location < static_cast<int>(manager_->max_draw_buffers()))); |
+ int draw_buffer = (output.location == -1 ? 0 : output.location); |
+ int count = static_cast<int>(output.arraySize == 0 ? 1 : output.arraySize); |
+ // TODO(zmo): Handle the special case in ES2 where gl_FragColor could |
+ // be broadcasting to all draw buffers. |
+ DCHECK_LE(draw_buffer + count, |
+ static_cast<int>(manager_->max_draw_buffers())); |
+ for (int ii = draw_buffer; ii < draw_buffer + count; ++ii) { |
+ DCHECK_EQ(SHADER_VARIABLE_UNDEFINED_TYPE, |
+ fragment_output_base_types_[ii]); |
+ fragment_output_base_types_[ii] = |
+ FragmentOutputTypeToBaseType(output.type); |
+ } |
+ } |
} |
std::string Program::ProcessLogInfo( |
@@ -523,6 +580,7 @@ void Program::Update() { |
UpdateFragmentInputs(); |
UpdateProgramOutputs(); |
+ UpdateFragmentOutputBaseTypes(); |
valid_ = true; |
} |
@@ -2250,6 +2308,7 @@ Program::~Program() { |
ProgramManager::ProgramManager( |
ProgramCache* program_cache, |
uint32_t max_varying_vectors, |
+ uint32_t max_draw_buffers, |
uint32_t max_dual_source_draw_buffers, |
const GpuPreferences& gpu_preferences, |
FeatureInfo* feature_info) |
@@ -2257,6 +2316,7 @@ ProgramManager::ProgramManager( |
have_context_(true), |
program_cache_(program_cache), |
max_varying_vectors_(max_varying_vectors), |
+ max_draw_buffers_(max_draw_buffers), |
max_dual_source_draw_buffers_(max_dual_source_draw_buffers), |
gpu_preferences_(gpu_preferences), |
feature_info_(feature_info) {} |