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

Side by Side Diff: gpu/command_buffer/service/gles2_cmd_decoder.cc

Issue 566019: Implements glGetUniformiv and glGetUniformfv. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 10 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
6 6
7 #include <stdio.h> 7 #include <stdio.h>
8 8
9 #include <vector> 9 #include <vector>
10 #include <string> 10 #include <string>
(...skipping 17 matching lines...) Expand all
28 // Check that certain assumptions the code makes are true. There are places in 28 // Check that certain assumptions the code makes are true. There are places in
29 // the code where shared memory is passed direclty to GL. Example, glUniformiv, 29 // the code where shared memory is passed direclty to GL. Example, glUniformiv,
30 // glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe 30 // glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
31 // a few others) are 32bits. If they are not 32bits the code will have to change 31 // a few others) are 32bits. If they are not 32bits the code will have to change
32 // to call those GL functions with service side memory and then copy the results 32 // to call those GL functions with service side memory and then copy the results
33 // to shared memory, converting the sizes. 33 // to shared memory, converting the sizes.
34 COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT 34 COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT
35 GLint_not_same_size_as_uint32); 35 GLint_not_same_size_as_uint32);
36 COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT 36 COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT
37 GLint_not_same_size_as_uint32); 37 GLint_not_same_size_as_uint32);
38 COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT
39 GLfloat_not_same_size_as_float);
38 40
39 namespace { 41 namespace {
40 42
41 size_t GetGLTypeSize(GLenum type) { 43 size_t GetGLTypeSize(GLenum type) {
42 switch (type) { 44 switch (type) {
43 case GL_BYTE: 45 case GL_BYTE:
44 return sizeof(GLbyte); // NOLINT 46 return sizeof(GLbyte); // NOLINT
45 case GL_UNSIGNED_BYTE: 47 case GL_UNSIGNED_BYTE:
46 return sizeof(GLubyte); // NOLINT 48 return sizeof(GLubyte); // NOLINT
47 case GL_SHORT: 49 case GL_SHORT:
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 // 304 //
303 // NOTE: To support shared resources an instance of this class will 305 // NOTE: To support shared resources an instance of this class will
304 // need to be shared by multiple GLES2Decoders. 306 // need to be shared by multiple GLES2Decoders.
305 class ProgramManager { 307 class ProgramManager {
306 public: 308 public:
307 // This is used to track which attributes a particular program needs 309 // This is used to track which attributes a particular program needs
308 // so we can verify at glDrawXXX time that every attribute is either disabled 310 // so we can verify at glDrawXXX time that every attribute is either disabled
309 // or if enabled that it points to a valid source. 311 // or if enabled that it points to a valid source.
310 class ProgramInfo { 312 class ProgramInfo {
311 public: 313 public:
314 struct UniformInfo {
315 GLsizei GetSizeInBytes() const;
316
317 GLsizei size;
318 GLenum type;
319 GLint location;
320 };
321
322 typedef std::vector<UniformInfo> UniformInfoVector;
312 typedef std::vector<GLuint> AttribLocationVector; 323 typedef std::vector<GLuint> AttribLocationVector;
313 324
314 ProgramInfo() { 325 ProgramInfo() {
315 } 326 }
316 327
317 void SetNumAttributes(int num_attribs) { 328 void SetNumAttributes(int num_attribs) {
318 attrib_locations_.resize(num_attribs); 329 attrib_locations_.resize(num_attribs);
319 } 330 }
320 331
321 void SetAttributeLocation(GLuint index, int location) { 332 void SetAttributeLocation(GLuint index, int location) {
322 DCHECK(index < attrib_locations_.size()); 333 DCHECK(index < attrib_locations_.size());
323 attrib_locations_[index] = location; 334 attrib_locations_[index] = location;
324 } 335 }
325 336
326 const AttribLocationVector& GetAttribLocations() const { 337 const AttribLocationVector& GetAttribLocations() const {
327 return attrib_locations_; 338 return attrib_locations_;
328 } 339 }
340
341 void SetNumUniforms(int num_uniforms) {
342 uniform_infos_.resize(num_uniforms);
343 }
344
345 void SetUniformInfo(
346 GLint index, GLsizei size, GLenum type, GLint location) {
347 UniformInfo& info = uniform_infos_[index];
348 info.size = size;
349 info.type = type;
350 info.location = location;
351 }
352
353 const UniformInfo* GetUniformInfoByLocation(GLint location) {
354 for (GLuint ii = 0; ii < uniform_infos_.size(); ++ii) {
355 if (uniform_infos_[ii].location == location) {
356 return &uniform_infos_[ii];
357 }
358 }
359 return NULL;
360 }
361
362
329 private: 363 private:
330 AttribLocationVector attrib_locations_; 364 AttribLocationVector attrib_locations_;
365
366 // Uniform info by info.
367 UniformInfoVector uniform_infos_;
331 }; 368 };
332 369
333 ProgramInfo* GetProgramInfo(GLuint program); 370 ProgramInfo* GetProgramInfo(GLuint program);
334 371
335 // Updates the program info for the given program. 372 // Updates the program info for the given program.
336 void UpdateProgramInfo(GLuint program); 373 void UpdateProgramInfo(GLuint program);
337 374
338 // Deletes the program info for the given program. 375 // Deletes the program info for the given program.
339 void RemoveProgramInfo(GLuint program); 376 void RemoveProgramInfo(GLuint program);
340 377
341 private: 378 private:
342 // Info for each "successfully linked" program by service side program Id. 379 // Info for each "successfully linked" program by service side program Id.
343 // TODO(gman): Choose a faster container. 380 // TODO(gman): Choose a faster container.
344 typedef std::map<GLuint, ProgramInfo> ProgramInfoMap; 381 typedef std::map<GLuint, ProgramInfo> ProgramInfoMap;
345 ProgramInfoMap program_infos_; 382 ProgramInfoMap program_infos_;
346 }; 383 };
347 384
385 GLsizei ProgramManager::ProgramInfo::UniformInfo::GetSizeInBytes() const {
386 return GLES2Util::GetGLDataTypeSize(type) * size;
387 }
388
348 ProgramManager::ProgramInfo* ProgramManager::GetProgramInfo(GLuint program) { 389 ProgramManager::ProgramInfo* ProgramManager::GetProgramInfo(GLuint program) {
349 ProgramInfoMap::iterator it = program_infos_.find(program); 390 ProgramInfoMap::iterator it = program_infos_.find(program);
350 return it != program_infos_.end() ? &it->second : NULL; 391 return it != program_infos_.end() ? &it->second : NULL;
351 } 392 }
352 393
353 void ProgramManager::UpdateProgramInfo(GLuint program) { 394 void ProgramManager::UpdateProgramInfo(GLuint program) {
354 ProgramInfo* info = GetProgramInfo(program); 395 ProgramInfo* info = GetProgramInfo(program);
355 if (!info) { 396 if (!info) {
356 std::pair<ProgramInfoMap::iterator, bool> result = 397 std::pair<ProgramInfoMap::iterator, bool> result =
357 program_infos_.insert(std::make_pair(program, ProgramInfo())); 398 program_infos_.insert(std::make_pair(program, ProgramInfo()));
358 DCHECK(result.second); 399 DCHECK(result.second);
359 info = &result.first->second; 400 info = &result.first->second;
360 } 401 }
361 GLint num_attribs = 0; 402 GLint num_attribs = 0;
362 GLint max_len = 0; 403 GLint max_len = 0;
363 glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &num_attribs); 404 glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &num_attribs);
364 info->SetNumAttributes(num_attribs); 405 info->SetNumAttributes(num_attribs);
365 glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_len); 406 glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_len);
366 // TODO(gman): Should we check for error? 407 // TODO(gman): Should we check for error?
367 scoped_array<char> name_buffer(new char[max_len + 1]); 408 scoped_array<char> name_buffer(new char[max_len]);
368 for (GLint ii = 0; ii < num_attribs; ++ii) { 409 for (GLint ii = 0; ii < num_attribs; ++ii) {
369 GLsizei length; 410 GLsizei length;
370 GLsizei size; 411 GLsizei size;
371 GLenum type; 412 GLenum type;
372 glGetActiveAttrib( 413 glGetActiveAttrib(
373 program, ii, max_len + 1, &length, &size, &type, name_buffer.get()); 414 program, ii, max_len, &length, &size, &type, name_buffer.get());
374 // TODO(gman): Should we check for error? 415 // TODO(gman): Should we check for error?
375 GLint location = glGetAttribLocation(program, name_buffer.get()); 416 GLint location = glGetAttribLocation(program, name_buffer.get());
376 info->SetAttributeLocation(ii, location); 417 info->SetAttributeLocation(ii, location);
377 } 418 }
419 GLint num_uniforms;
420 glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &num_uniforms);
421 info->SetNumUniforms(num_uniforms);
422 glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_len);
423 name_buffer.reset(new char[max_len]);
424 for (GLint ii = 0; ii < num_uniforms; ++ii) {
425 GLsizei length;
426 GLsizei size;
427 GLenum type;
428 glGetActiveUniform(
429 program, ii, max_len, &length, &size, &type, name_buffer.get());
430 // TODO(gman): Should we check for error?
431 GLint location = glGetUniformLocation(program, name_buffer.get());
432 info->SetUniformInfo(ii, size, type, location);
433 }
378 } 434 }
379 435
380 void ProgramManager::RemoveProgramInfo(GLuint program) { 436 void ProgramManager::RemoveProgramInfo(GLuint program) {
381 ProgramInfoMap::iterator it = program_infos_.find(program); 437 ProgramInfoMap::iterator it = program_infos_.find(program);
382 if (it != program_infos_.end()) { 438 if (it != program_infos_.end()) {
383 program_infos_.erase(it); 439 program_infos_.erase(it);
384 } 440 }
385 } 441 }
386 442
387 // This class implements GLES2Decoder so we don't have to expose all the GLES2 443 // This class implements GLES2Decoder so we don't have to expose all the GLES2
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 // Checks if the current program and vertex attributes are valid for drawing. 662 // Checks if the current program and vertex attributes are valid for drawing.
607 bool IsDrawValid(GLuint max_vertex_accessed); 663 bool IsDrawValid(GLuint max_vertex_accessed);
608 664
609 // Gets the buffer id for a given target. 665 // Gets the buffer id for a given target.
610 GLuint GetBufferForTarget(GLenum target) { 666 GLuint GetBufferForTarget(GLenum target) {
611 DCHECK(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER); 667 DCHECK(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER);
612 return target == GL_ARRAY_BUFFER ? bound_array_buffer_ : 668 return target == GL_ARRAY_BUFFER ? bound_array_buffer_ :
613 bound_element_array_buffer_; 669 bound_element_array_buffer_;
614 } 670 }
615 671
672 // Validates the program and location for a glGetUniform call and returns
673 // a SizeResult setup to receive the result. Returns true if glGetUniform
674 // should be called.
675 bool GetUniformSetup(
676 GLuint program, GLint location,
677 uint32 shm_id, uint32 shm_offset,
678 error::Error* error, GLuint* service_id, SizedResult** result);
679
616 // Generate a member function prototype for each command in an automated and 680 // Generate a member function prototype for each command in an automated and
617 // typesafe way. 681 // typesafe way.
618 #define GLES2_CMD_OP(name) \ 682 #define GLES2_CMD_OP(name) \
619 Error Handle ## name( \ 683 Error Handle ## name( \
620 uint32 immediate_data_size, \ 684 uint32 immediate_data_size, \
621 const gles2::name& args); \ 685 const gles2::name& args); \
622 686
623 GLES2_COMMAND_LIST(GLES2_CMD_OP) 687 GLES2_COMMAND_LIST(GLES2_CMD_OP)
624 688
625 #undef GLES2_CMD_OP 689 #undef GLES2_CMD_OP
(...skipping 1230 matching lines...) Expand 10 before | Expand all | Expand 10 after
1856 } 1920 }
1857 if (index >= max_vertex_attribs_) { 1921 if (index >= max_vertex_attribs_) {
1858 SetGLError(GL_INVALID_VALUE); 1922 SetGLError(GL_INVALID_VALUE);
1859 return error::kNoError; 1923 return error::kNoError;
1860 } 1924 }
1861 result->size = sizeof(GLuint); 1925 result->size = sizeof(GLuint);
1862 *result->GetDataAs<GLuint*>() = vertex_attrib_infos_[index].offset(); 1926 *result->GetDataAs<GLuint*>() = vertex_attrib_infos_[index].offset();
1863 return error::kNoError; 1927 return error::kNoError;
1864 } 1928 }
1865 1929
1930 bool GLES2DecoderImpl::GetUniformSetup(
1931 GLuint program, GLint location,
1932 uint32 shm_id, uint32 shm_offset,
1933 error::Error* error, GLuint* service_id, SizedResult** result) {
1934 *error = error::kNoError;
1935 // Make sure we have enough room for the result on failure.
1936 *result = GetSharedMemoryAs<SizedResult*>(
1937 shm_id, shm_offset, SizedResult::GetSize(0));
1938 if (!*result) {
1939 *error = error::kOutOfBounds;
1940 return false;
1941 }
1942 // Set the result size to 0 so the client does not have to check for success.
1943 (*result)->size = 0;
1944 if (!id_manager_->GetServiceId(program, service_id)) {
1945 SetGLError(GL_INVALID_VALUE);
1946 return error::kNoError;
1947 }
1948 ProgramManager::ProgramInfo* info = GetProgramInfo(*service_id);
1949 if (!info) {
1950 // Program was not linked successfully. (ie, glLinkProgram)
1951 SetGLError(GL_INVALID_OPERATION);
1952 return false;
1953 }
1954 const ProgramManager::ProgramInfo::UniformInfo* uniform_info =
1955 info->GetUniformInfoByLocation(location);
1956 if (!uniform_info) {
1957 // No such location.
1958 SetGLError(GL_INVALID_OPERATION);
1959 return false;
1960 }
1961 GLsizei size = uniform_info->GetSizeInBytes();
1962 if (size == 0) {
1963 SetGLError(GL_INVALID_OPERATION);
1964 return false;
1965 }
1966 *result = GetSharedMemoryAs<SizedResult*>(
1967 shm_id, shm_offset, SizedResult::GetSize(size));
1968 if (!*result) {
1969 *error = error::kOutOfBounds;
1970 return false;
1971 }
1972 (*result)->size = size;
1973 return true;
1974 }
1975
1866 error::Error GLES2DecoderImpl::HandleGetUniformiv( 1976 error::Error GLES2DecoderImpl::HandleGetUniformiv(
1867 uint32 immediate_data_size, const gles2::GetUniformiv& c) { 1977 uint32 immediate_data_size, const gles2::GetUniformiv& c) {
1868 // TODO(gman): Implement. 1978 GLuint program = c.program;
1869 NOTREACHED(); 1979 GLint location = c.location;
1870 return error::kNoError; 1980 GLuint service_id;
1981 Error error;
1982 SizedResult* result;
1983 if (GetUniformSetup(
1984 program, location, c.params_shm_id, c.params_shm_offset,
1985 &error, &service_id, &result)) {
1986 glGetUniformiv(service_id, location, result->GetDataAs<GLint*>());
1987 }
1988 return error;
1871 } 1989 }
1872 1990
1873 error::Error GLES2DecoderImpl::HandleGetUniformfv( 1991 error::Error GLES2DecoderImpl::HandleGetUniformfv(
1874 uint32 immediate_data_size, const gles2::GetUniformfv& c) { 1992 uint32 immediate_data_size, const gles2::GetUniformfv& c) {
1875 // TODO(gman): Implement. 1993 GLuint program = c.program;
1876 NOTREACHED(); 1994 GLint location = c.location;
1877 return error::kNoError; 1995 GLuint service_id;
1996 Error error;
1997 SizedResult* result;
1998 if (GetUniformSetup(
1999 program, location, c.params_shm_id, c.params_shm_offset,
2000 &error, &service_id, &result)) {
2001 glGetUniformfv(service_id, location, result->GetDataAs<GLfloat*>());
2002 }
2003 return error;
1878 } 2004 }
1879 2005
1880 error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat( 2006 error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
1881 uint32 immediate_data_size, const gles2::GetShaderPrecisionFormat& c) { 2007 uint32 immediate_data_size, const gles2::GetShaderPrecisionFormat& c) {
1882 // TODO(gman): Implement. 2008 // TODO(gman): Implement.
1883 NOTREACHED(); 2009 NOTREACHED();
1884 return error::kNoError; 2010 return error::kNoError;
1885 } 2011 }
1886 2012
1887 error::Error GLES2DecoderImpl::HandleGetAttachedShaders( 2013 error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
(...skipping 17 matching lines...) Expand all
1905 return error::kNoError; 2031 return error::kNoError;
1906 } 2032 }
1907 2033
1908 // Include the auto-generated part of this file. We split this because it means 2034 // Include the auto-generated part of this file. We split this because it means
1909 // we can easily edit the non-auto generated parts right here in this file 2035 // we can easily edit the non-auto generated parts right here in this file
1910 // instead of having to edit some template or the code generator. 2036 // instead of having to edit some template or the code generator.
1911 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" 2037 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
1912 2038
1913 } // namespace gles2 2039 } // namespace gles2
1914 } // namespace gpu 2040 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/common/gles2_cmd_utils.cc ('k') | gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698