OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <algorithm> | 9 #include <algorithm> |
10 #include <list> | 10 #include <list> |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 #include "gpu/command_buffer/service/framebuffer_manager.h" | 42 #include "gpu/command_buffer/service/framebuffer_manager.h" |
43 #include "gpu/command_buffer/service/gl_utils.h" | 43 #include "gpu/command_buffer/service/gl_utils.h" |
44 #include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" | 44 #include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" |
45 #include "gpu/command_buffer/service/gles2_cmd_validation.h" | 45 #include "gpu/command_buffer/service/gles2_cmd_validation.h" |
46 #include "gpu/command_buffer/service/gpu_state_tracer.h" | 46 #include "gpu/command_buffer/service/gpu_state_tracer.h" |
47 #include "gpu/command_buffer/service/gpu_switches.h" | 47 #include "gpu/command_buffer/service/gpu_switches.h" |
48 #include "gpu/command_buffer/service/gpu_tracer.h" | 48 #include "gpu/command_buffer/service/gpu_tracer.h" |
49 #include "gpu/command_buffer/service/image_manager.h" | 49 #include "gpu/command_buffer/service/image_manager.h" |
50 #include "gpu/command_buffer/service/mailbox_manager.h" | 50 #include "gpu/command_buffer/service/mailbox_manager.h" |
51 #include "gpu/command_buffer/service/memory_tracking.h" | 51 #include "gpu/command_buffer/service/memory_tracking.h" |
| 52 #include "gpu/command_buffer/service/path_manager.h" |
52 #include "gpu/command_buffer/service/program_manager.h" | 53 #include "gpu/command_buffer/service/program_manager.h" |
53 #include "gpu/command_buffer/service/query_manager.h" | 54 #include "gpu/command_buffer/service/query_manager.h" |
54 #include "gpu/command_buffer/service/renderbuffer_manager.h" | 55 #include "gpu/command_buffer/service/renderbuffer_manager.h" |
55 #include "gpu/command_buffer/service/shader_manager.h" | 56 #include "gpu/command_buffer/service/shader_manager.h" |
56 #include "gpu/command_buffer/service/shader_translator.h" | 57 #include "gpu/command_buffer/service/shader_translator.h" |
57 #include "gpu/command_buffer/service/shader_translator_cache.h" | 58 #include "gpu/command_buffer/service/shader_translator_cache.h" |
58 #include "gpu/command_buffer/service/texture_manager.h" | 59 #include "gpu/command_buffer/service/texture_manager.h" |
59 #include "gpu/command_buffer/service/vertex_array_manager.h" | 60 #include "gpu/command_buffer/service/vertex_array_manager.h" |
60 #include "gpu/command_buffer/service/vertex_attrib_manager.h" | 61 #include "gpu/command_buffer/service/vertex_attrib_manager.h" |
61 #include "third_party/smhasher/src/City.h" | 62 #include "third_party/smhasher/src/City.h" |
(...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
738 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids); | 739 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids); |
739 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids); | 740 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids); |
740 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids); | 741 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids); |
741 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids); | 742 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids); |
742 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids); | 743 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids); |
743 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids); | 744 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids); |
744 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids); | 745 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids); |
745 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids); | 746 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids); |
746 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); | 747 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); |
747 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); | 748 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); |
| 749 bool GenPathsCHROMIUMHelper(GLuint first_client_id, GLsizei range); |
| 750 bool DeletePathsCHROMIUMHelper(GLuint first_client_id, GLsizei range); |
748 | 751 |
749 // Helper for async upload token completion notification callback. | 752 // Helper for async upload token completion notification callback. |
750 base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token, | 753 base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token, |
751 uint32 sync_data_shm_id, | 754 uint32 sync_data_shm_id, |
752 uint32 sync_data_shm_offset); | 755 uint32 sync_data_shm_offset); |
753 | 756 |
754 | 757 |
755 | 758 |
756 // Workarounds | 759 // Workarounds |
757 void OnFboChanged() const; | 760 void OnFboChanged() const; |
758 void OnUseFramebuffer() const; | 761 void OnUseFramebuffer() const; |
759 | 762 |
760 // TODO(gman): Cache these pointers? | 763 // TODO(gman): Cache these pointers? |
761 BufferManager* buffer_manager() { | 764 BufferManager* buffer_manager() { |
762 return group_->buffer_manager(); | 765 return group_->buffer_manager(); |
763 } | 766 } |
764 | 767 |
765 RenderbufferManager* renderbuffer_manager() { | 768 RenderbufferManager* renderbuffer_manager() { |
766 return group_->renderbuffer_manager(); | 769 return group_->renderbuffer_manager(); |
767 } | 770 } |
768 | 771 |
769 FramebufferManager* framebuffer_manager() { | 772 FramebufferManager* framebuffer_manager() { |
770 return group_->framebuffer_manager(); | 773 return group_->framebuffer_manager(); |
771 } | 774 } |
772 | 775 |
| 776 PathManager* path_manager() { return group_->path_manager(); } |
| 777 |
773 ProgramManager* program_manager() { | 778 ProgramManager* program_manager() { |
774 return group_->program_manager(); | 779 return group_->program_manager(); |
775 } | 780 } |
776 | 781 |
777 ShaderManager* shader_manager() { | 782 ShaderManager* shader_manager() { |
778 return group_->shader_manager(); | 783 return group_->shader_manager(); |
779 } | 784 } |
780 | 785 |
781 ShaderTranslatorCache* shader_translator_cache() { | 786 ShaderTranslatorCache* shader_translator_cache() { |
782 return group_->shader_translator_cache(); | 787 return group_->shader_translator_cache(); |
(...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1368 | 1373 |
1369 // Wrappers for glIsXXX functions. | 1374 // Wrappers for glIsXXX functions. |
1370 bool DoIsEnabled(GLenum cap); | 1375 bool DoIsEnabled(GLenum cap); |
1371 bool DoIsBuffer(GLuint client_id); | 1376 bool DoIsBuffer(GLuint client_id); |
1372 bool DoIsFramebuffer(GLuint client_id); | 1377 bool DoIsFramebuffer(GLuint client_id); |
1373 bool DoIsProgram(GLuint client_id); | 1378 bool DoIsProgram(GLuint client_id); |
1374 bool DoIsRenderbuffer(GLuint client_id); | 1379 bool DoIsRenderbuffer(GLuint client_id); |
1375 bool DoIsShader(GLuint client_id); | 1380 bool DoIsShader(GLuint client_id); |
1376 bool DoIsTexture(GLuint client_id); | 1381 bool DoIsTexture(GLuint client_id); |
1377 bool DoIsVertexArrayOES(GLuint client_id); | 1382 bool DoIsVertexArrayOES(GLuint client_id); |
| 1383 bool DoIsPathCHROMIUM(GLuint client_id); |
1378 | 1384 |
1379 // Wrapper for glLinkProgram | 1385 // Wrapper for glLinkProgram |
1380 void DoLinkProgram(GLuint program); | 1386 void DoLinkProgram(GLuint program); |
1381 | 1387 |
1382 // Wrapper for glRenderbufferStorage. | 1388 // Wrapper for glRenderbufferStorage. |
1383 void DoRenderbufferStorage( | 1389 void DoRenderbufferStorage( |
1384 GLenum target, GLenum internalformat, GLsizei width, GLsizei height); | 1390 GLenum target, GLenum internalformat, GLsizei width, GLsizei height); |
1385 | 1391 |
1386 // Handler for glRenderbufferStorageMultisampleCHROMIUM. | 1392 // Handler for glRenderbufferStorageMultisampleCHROMIUM. |
1387 void DoRenderbufferStorageMultisampleCHROMIUM( | 1393 void DoRenderbufferStorageMultisampleCHROMIUM( |
(...skipping 1521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2909 } | 2915 } |
2910 } | 2916 } |
2911 scoped_ptr<GLuint[]> service_ids(new GLuint[n]); | 2917 scoped_ptr<GLuint[]> service_ids(new GLuint[n]); |
2912 glGenTextures(n, service_ids.get()); | 2918 glGenTextures(n, service_ids.get()); |
2913 for (GLsizei ii = 0; ii < n; ++ii) { | 2919 for (GLsizei ii = 0; ii < n; ++ii) { |
2914 CreateTexture(client_ids[ii], service_ids[ii]); | 2920 CreateTexture(client_ids[ii], service_ids[ii]); |
2915 } | 2921 } |
2916 return true; | 2922 return true; |
2917 } | 2923 } |
2918 | 2924 |
| 2925 bool GLES2DecoderImpl::GenPathsCHROMIUMHelper(GLuint first_client_id, |
| 2926 GLsizei range) { |
| 2927 GLuint last_client_id; |
| 2928 if (!SafeAddUint32(first_client_id, range - 1, &last_client_id)) { |
| 2929 return false; |
| 2930 } |
| 2931 |
| 2932 if (path_manager()->HasPathsInRange(first_client_id, last_client_id)) { |
| 2933 return false; |
| 2934 } |
| 2935 |
| 2936 GLuint first_service_id = glGenPathsNV(range); |
| 2937 if (first_service_id == 0) { |
| 2938 // We have to fail the connection here, because client has already |
| 2939 // succeeded in allocating the ids. This happens if we allocate |
| 2940 // the whole path id space (two allocations of 0x7FFFFFFF paths, for |
| 2941 // example). Currently so many allocations hang the client-side |
| 2942 // id allocator, so this should not be a practical issue. |
| 2943 return false; |
| 2944 } |
| 2945 |
| 2946 path_manager()->CreatePathRange( |
| 2947 first_client_id, last_client_id, first_service_id); |
| 2948 |
| 2949 return true; |
| 2950 } |
| 2951 |
| 2952 bool GLES2DecoderImpl::DeletePathsCHROMIUMHelper(GLuint first_client_id, |
| 2953 GLsizei range) { |
| 2954 GLuint last_client_id; |
| 2955 if (!SafeAddUint32(first_client_id, range - 1, &last_client_id)) { |
| 2956 return false; |
| 2957 } |
| 2958 |
| 2959 path_manager()->RemovePaths(first_client_id, last_client_id); |
| 2960 return true; |
| 2961 } |
| 2962 |
2919 void GLES2DecoderImpl::DeleteBuffersHelper( | 2963 void GLES2DecoderImpl::DeleteBuffersHelper( |
2920 GLsizei n, const GLuint* client_ids) { | 2964 GLsizei n, const GLuint* client_ids) { |
2921 for (GLsizei ii = 0; ii < n; ++ii) { | 2965 for (GLsizei ii = 0; ii < n; ++ii) { |
2922 Buffer* buffer = GetBuffer(client_ids[ii]); | 2966 Buffer* buffer = GetBuffer(client_ids[ii]); |
2923 if (buffer && !buffer->IsDeleted()) { | 2967 if (buffer && !buffer->IsDeleted()) { |
2924 state_.vertex_attrib_manager->Unbind(buffer); | 2968 state_.vertex_attrib_manager->Unbind(buffer); |
2925 if (state_.bound_array_buffer.get() == buffer) { | 2969 if (state_.bound_array_buffer.get() == buffer) { |
2926 state_.bound_array_buffer = NULL; | 2970 state_.bound_array_buffer = NULL; |
2927 } | 2971 } |
2928 RemoveBuffer(client_ids[ii]); | 2972 RemoveBuffer(client_ids[ii]); |
(...skipping 7010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9939 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, | 9983 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, |
9940 element_array_buffer ? element_array_buffer->service_id() : 0); | 9984 element_array_buffer ? element_array_buffer->service_id() : 0); |
9941 } | 9985 } |
9942 | 9986 |
9943 bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) { | 9987 bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) { |
9944 const VertexAttribManager* vao = | 9988 const VertexAttribManager* vao = |
9945 GetVertexAttribManager(client_id); | 9989 GetVertexAttribManager(client_id); |
9946 return vao && vao->IsValid() && !vao->IsDeleted(); | 9990 return vao && vao->IsValid() && !vao->IsDeleted(); |
9947 } | 9991 } |
9948 | 9992 |
| 9993 bool GLES2DecoderImpl::DoIsPathCHROMIUM(GLuint client_id) { |
| 9994 GLuint service_id = 0; |
| 9995 if (!path_manager()->GetPath(client_id, &service_id)) { |
| 9996 return false; |
| 9997 } |
| 9998 |
| 9999 return glIsPathNV(service_id); |
| 10000 } |
| 10001 |
9949 #if defined(OS_MACOSX) | 10002 #if defined(OS_MACOSX) |
9950 void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) { | 10003 void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) { |
9951 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find( | 10004 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find( |
9952 texture_id); | 10005 texture_id); |
9953 if (it != texture_to_io_surface_map_.end()) { | 10006 if (it != texture_to_io_surface_map_.end()) { |
9954 // Found a previous IOSurface bound to this texture; release it. | 10007 // Found a previous IOSurface bound to this texture; release it. |
9955 IOSurfaceRef surface = it->second; | 10008 IOSurfaceRef surface = it->second; |
9956 CFRelease(surface); | 10009 CFRelease(surface); |
9957 texture_to_io_surface_map_.erase(it); | 10010 texture_to_io_surface_map_.erase(it); |
9958 } | 10011 } |
(...skipping 1178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11137 DoDidUseTexImageIfNeeded(texture, texture->target()); | 11190 DoDidUseTexImageIfNeeded(texture, texture->target()); |
11138 } | 11191 } |
11139 | 11192 |
11140 void GLES2DecoderImpl::OnOutOfMemoryError() { | 11193 void GLES2DecoderImpl::OnOutOfMemoryError() { |
11141 if (lose_context_when_out_of_memory_) { | 11194 if (lose_context_when_out_of_memory_) { |
11142 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB); | 11195 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB); |
11143 LoseContext(GL_GUILTY_CONTEXT_RESET_ARB); | 11196 LoseContext(GL_GUILTY_CONTEXT_RESET_ARB); |
11144 } | 11197 } |
11145 } | 11198 } |
11146 | 11199 |
| 11200 error::Error GLES2DecoderImpl::HandleGenPathsCHROMIUM( |
| 11201 uint32 immediate_data_size, |
| 11202 const void* cmd_data) { |
| 11203 const gles2::cmds::GenPathsCHROMIUM& c = |
| 11204 *static_cast<const gles2::cmds::GenPathsCHROMIUM*>(cmd_data); |
| 11205 if (!features().chromium_path_rendering) { |
| 11206 LOCAL_SET_GL_ERROR( |
| 11207 GL_INVALID_OPERATION, "glGenPathsCHROMIUM", "function not available"); |
| 11208 return error::kNoError; |
| 11209 } |
| 11210 |
| 11211 GLsizei range = static_cast<GLsizei>(c.range); |
| 11212 if (range < 0) { |
| 11213 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glGenPathsCHROMIUM", "range < 0"); |
| 11214 return error::kNoError; |
| 11215 } |
| 11216 |
| 11217 GLuint first_client_id = static_cast<GLuint>(c.first_client_id); |
| 11218 if (first_client_id == 0) { |
| 11219 return error::kInvalidArguments; |
| 11220 } |
| 11221 |
| 11222 if (range == 0) { |
| 11223 return error::kNoError; |
| 11224 } |
| 11225 |
| 11226 if (!GenPathsCHROMIUMHelper(first_client_id, range)) { |
| 11227 return error::kInvalidArguments; |
| 11228 } |
| 11229 |
| 11230 return error::kNoError; |
| 11231 } |
| 11232 error::Error GLES2DecoderImpl::HandleDeletePathsCHROMIUM( |
| 11233 uint32_t immediate_data_size, |
| 11234 const void* cmd_data) { |
| 11235 const gles2::cmds::DeletePathsCHROMIUM& c = |
| 11236 *static_cast<const gles2::cmds::DeletePathsCHROMIUM*>(cmd_data); |
| 11237 if (!features().chromium_path_rendering) { |
| 11238 LOCAL_SET_GL_ERROR( |
| 11239 GL_INVALID_OPERATION, "glGenPathsCHROMIUM", "function not available"); |
| 11240 return error::kNoError; |
| 11241 } |
| 11242 |
| 11243 GLsizei range = static_cast<GLsizei>(c.range); |
| 11244 if (range < 0) { |
| 11245 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeletePathsCHROMIUM", "range < 0"); |
| 11246 return error::kNoError; |
| 11247 } |
| 11248 |
| 11249 if (range == 0) { |
| 11250 return error::kNoError; |
| 11251 } |
| 11252 |
| 11253 GLuint first_client_id = c.first_client_id; |
| 11254 // first_client_id can be 0, because non-existing path ids are skipped. |
| 11255 |
| 11256 if (!DeletePathsCHROMIUMHelper(first_client_id, range)) { |
| 11257 return error::kInvalidArguments; |
| 11258 } |
| 11259 return error::kNoError; |
| 11260 } |
| 11261 |
| 11262 error::Error GLES2DecoderImpl::HandlePathCommandsCHROMIUM( |
| 11263 uint32 immediate_data_size, |
| 11264 const void* cmd_data) { |
| 11265 const gles2::cmds::PathCommandsCHROMIUM& c = |
| 11266 *static_cast<const gles2::cmds::PathCommandsCHROMIUM*>(cmd_data); |
| 11267 if (!features().chromium_path_rendering) { |
| 11268 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, |
| 11269 "glPathCommandsCHROMIUM", |
| 11270 "function not available"); |
| 11271 return error::kNoError; |
| 11272 } |
| 11273 |
| 11274 GLuint service_id = 0; |
| 11275 if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) { |
| 11276 LOCAL_SET_GL_ERROR( |
| 11277 GL_INVALID_OPERATION, "glPathCommandsCHROMIUM", "invalid path name"); |
| 11278 return error::kNoError; |
| 11279 } |
| 11280 |
| 11281 GLsizei num_commands = static_cast<GLsizei>(c.numCommands); |
| 11282 if (num_commands < 0) { |
| 11283 LOCAL_SET_GL_ERROR( |
| 11284 GL_INVALID_VALUE, "glPathCommandsCHROMIUM", "numCommands < 0"); |
| 11285 return error::kNoError; |
| 11286 } |
| 11287 |
| 11288 GLsizei num_coords = static_cast<uint32>(c.numCoords); |
| 11289 if (num_coords < 0) { |
| 11290 LOCAL_SET_GL_ERROR( |
| 11291 GL_INVALID_VALUE, "glPathCommandsCHROMIUM", "numCoords < 0"); |
| 11292 return error::kNoError; |
| 11293 } |
| 11294 uint32 coords_size = 0; |
| 11295 if (!SafeMultiplyUint32(num_coords, sizeof(GLfloat), &coords_size)) { |
| 11296 return error::kOutOfBounds; |
| 11297 } |
| 11298 |
| 11299 uint32 commands_shm_id = static_cast<uint32>(c.commands_shm_id); |
| 11300 uint32 commands_shm_offset = static_cast<uint32>(c.commands_shm_offset); |
| 11301 |
| 11302 const GLubyte* commands = NULL; |
| 11303 if (commands_shm_id != 0 || commands_shm_offset != 0) { |
| 11304 commands = GetSharedMemoryAs<const GLubyte*>( |
| 11305 commands_shm_id, commands_shm_offset, num_commands); |
| 11306 if (!commands) { |
| 11307 return error::kOutOfBounds; |
| 11308 } |
| 11309 } |
| 11310 |
| 11311 if (num_commands && !commands) { |
| 11312 LOCAL_SET_GL_ERROR( |
| 11313 GL_INVALID_OPERATION, "glPathCommandsCHROMIUM", "missing commands"); |
| 11314 return error::kNoError; |
| 11315 } |
| 11316 |
| 11317 GLsizei num_coords_expected = 0; |
| 11318 for (GLsizei i = 0; i < num_commands; ++i) { |
| 11319 switch (commands[i]) { |
| 11320 case GL_CLOSE_PATH_CHROMIUM: |
| 11321 // Close has no coords. |
| 11322 break; |
| 11323 case GL_MOVE_TO_CHROMIUM: |
| 11324 // Fallthrough. |
| 11325 case GL_LINE_TO_CHROMIUM: |
| 11326 num_coords_expected += 2; |
| 11327 break; |
| 11328 case GL_QUADRATIC_CURVE_TO_CHROMIUM: |
| 11329 num_coords_expected += 4; |
| 11330 break; |
| 11331 case GL_CUBIC_CURVE_TO_CHROMIUM: |
| 11332 num_coords_expected += 6; |
| 11333 break; |
| 11334 default: |
| 11335 LOCAL_SET_GL_ERROR( |
| 11336 GL_INVALID_ENUM, "glPathCommandsCHROMIUM", "invalid command"); |
| 11337 return error::kNoError; |
| 11338 } |
| 11339 } |
| 11340 |
| 11341 if (num_coords != num_coords_expected) { |
| 11342 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, |
| 11343 "glPathCommandsCHROMIUM", |
| 11344 "numCoords does not match commands"); |
| 11345 return error::kNoError; |
| 11346 } |
| 11347 |
| 11348 uint32 coords_shm_id = static_cast<uint32>(c.coords_shm_id); |
| 11349 uint32 coords_shm_offset = static_cast<uint32>(c.coords_shm_offset); |
| 11350 |
| 11351 const void* coords = NULL; |
| 11352 if (coords_shm_id != 0 || coords_shm_offset != 0) { |
| 11353 coords = GetSharedMemoryAs<const void*>( |
| 11354 coords_shm_id, coords_shm_offset, coords_size); |
| 11355 if (!coords) { |
| 11356 return error::kOutOfBounds; |
| 11357 } |
| 11358 } |
| 11359 |
| 11360 if (num_coords && !coords) { |
| 11361 LOCAL_SET_GL_ERROR( |
| 11362 GL_INVALID_OPERATION, "glPathCommandsCHROMIUM", "missing coords"); |
| 11363 return error::kNoError; |
| 11364 } |
| 11365 |
| 11366 glPathCommandsNV( |
| 11367 service_id, num_commands, commands, num_coords, GL_FLOAT, coords); |
| 11368 |
| 11369 return error::kNoError; |
| 11370 } |
| 11371 |
| 11372 error::Error GLES2DecoderImpl::HandlePathParameterfCHROMIUM( |
| 11373 uint32 immediate_data_size, |
| 11374 const void* cmd_data) { |
| 11375 const gles2::cmds::PathParameterfCHROMIUM& c = |
| 11376 *static_cast<const gles2::cmds::PathParameterfCHROMIUM*>(cmd_data); |
| 11377 if (!features().chromium_path_rendering) { |
| 11378 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, |
| 11379 "glPathParameterfCHROMIUM", |
| 11380 "function not available"); |
| 11381 return error::kNoError; |
| 11382 } |
| 11383 GLuint service_id = 0; |
| 11384 if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) { |
| 11385 LOCAL_SET_GL_ERROR( |
| 11386 GL_INVALID_OPERATION, "glPathParameterfCHROMIUM", "invalid path name"); |
| 11387 return error::kNoError; |
| 11388 } |
| 11389 |
| 11390 GLenum pname = static_cast<GLenum>(c.pname); |
| 11391 GLfloat value = static_cast<GLfloat>(c.value); |
| 11392 bool hasValueError = false; |
| 11393 |
| 11394 switch (pname) { |
| 11395 case GL_PATH_STROKE_WIDTH_CHROMIUM: |
| 11396 case GL_PATH_MITER_LIMIT_CHROMIUM: |
| 11397 hasValueError = base::IsNaN(value) || !base::IsFinite(value) || value < 0; |
| 11398 break; |
| 11399 case GL_PATH_INITIAL_END_CAP_CHROMIUM: |
| 11400 case GL_PATH_TERMINAL_END_CAP_CHROMIUM: |
| 11401 hasValueError = !validators_->path_parameter_cap_values.IsValid( |
| 11402 static_cast<GLint>(value)); |
| 11403 break; |
| 11404 case GL_PATH_JOIN_STYLE_CHROMIUM: |
| 11405 hasValueError = !validators_->path_parameter_join_values.IsValid( |
| 11406 static_cast<GLint>(value)); |
| 11407 break; |
| 11408 default: |
| 11409 DCHECK(!validators_->path_parameter.IsValid(pname)); |
| 11410 LOCAL_SET_GL_ERROR_INVALID_ENUM( |
| 11411 "glPathParameterfCHROMIUM", pname, "pname"); |
| 11412 return error::kNoError; |
| 11413 } |
| 11414 DCHECK(validators_->path_parameter.IsValid(pname)); |
| 11415 |
| 11416 if (hasValueError) { |
| 11417 LOCAL_SET_GL_ERROR( |
| 11418 GL_INVALID_VALUE, "glPathParameterfCHROMIUM", "value not correct"); |
| 11419 return error::kNoError; |
| 11420 } |
| 11421 |
| 11422 glPathParameterfNV(service_id, pname, value); |
| 11423 return error::kNoError; |
| 11424 } |
| 11425 |
| 11426 error::Error GLES2DecoderImpl::HandlePathParameteriCHROMIUM( |
| 11427 uint32 immediate_data_size, |
| 11428 const void* cmd_data) { |
| 11429 const gles2::cmds::PathParameteriCHROMIUM& c = |
| 11430 *static_cast<const gles2::cmds::PathParameteriCHROMIUM*>(cmd_data); |
| 11431 if (!features().chromium_path_rendering) { |
| 11432 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, |
| 11433 "glPathParameteriCHROMIUM", |
| 11434 "function not available"); |
| 11435 return error::kNoError; |
| 11436 } |
| 11437 GLuint service_id = 0; |
| 11438 if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) { |
| 11439 LOCAL_SET_GL_ERROR( |
| 11440 GL_INVALID_OPERATION, "glPathParameteriCHROMIUM", "invalid path name"); |
| 11441 return error::kNoError; |
| 11442 } |
| 11443 |
| 11444 GLenum pname = static_cast<GLenum>(c.pname); |
| 11445 GLint value = static_cast<GLint>(c.value); |
| 11446 bool hasValueError = false; |
| 11447 |
| 11448 switch (pname) { |
| 11449 case GL_PATH_STROKE_WIDTH_CHROMIUM: |
| 11450 case GL_PATH_MITER_LIMIT_CHROMIUM: |
| 11451 hasValueError = value < 0; |
| 11452 break; |
| 11453 case GL_PATH_INITIAL_END_CAP_CHROMIUM: |
| 11454 case GL_PATH_TERMINAL_END_CAP_CHROMIUM: |
| 11455 hasValueError = !validators_->path_parameter_cap_values.IsValid(value); |
| 11456 break; |
| 11457 case GL_PATH_JOIN_STYLE_CHROMIUM: |
| 11458 hasValueError = !validators_->path_parameter_join_values.IsValid(value); |
| 11459 break; |
| 11460 default: |
| 11461 DCHECK(!validators_->path_parameter.IsValid(pname)); |
| 11462 LOCAL_SET_GL_ERROR_INVALID_ENUM( |
| 11463 "glPathParameteriCHROMIUM", pname, "pname"); |
| 11464 return error::kNoError; |
| 11465 } |
| 11466 DCHECK(validators_->path_parameter.IsValid(pname)); |
| 11467 |
| 11468 if (hasValueError) { |
| 11469 LOCAL_SET_GL_ERROR( |
| 11470 GL_INVALID_VALUE, "glPathParameteriCHROMIUM", "value not correct"); |
| 11471 return error::kNoError; |
| 11472 } |
| 11473 |
| 11474 glPathParameteriNV(service_id, pname, value); |
| 11475 return error::kNoError; |
| 11476 } |
| 11477 |
| 11478 error::Error GLES2DecoderImpl::HandleStencilFillPathCHROMIUM( |
| 11479 uint32 immediate_data_size, |
| 11480 const void* cmd_data) { |
| 11481 const gles2::cmds::StencilFillPathCHROMIUM& c = |
| 11482 *static_cast<const gles2::cmds::StencilFillPathCHROMIUM*>(cmd_data); |
| 11483 if (!features().chromium_path_rendering) { |
| 11484 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, |
| 11485 "glStencilFillPathCHROMIUM", |
| 11486 "function not available"); |
| 11487 return error::kNoError; |
| 11488 } |
| 11489 GLenum fill_mode = static_cast<GLenum>(c.fillMode); |
| 11490 if (!validators_->path_fill_mode.IsValid(fill_mode)) { |
| 11491 LOCAL_SET_GL_ERROR_INVALID_ENUM( |
| 11492 "glStencilFillPathCHROMIUM", fill_mode, "fillMode"); |
| 11493 return error::kNoError; |
| 11494 } |
| 11495 GLuint mask = static_cast<GLuint>(c.mask); |
| 11496 if ((fill_mode == GL_COUNT_UP_CHROMIUM || |
| 11497 fill_mode == GL_COUNT_DOWN_CHROMIUM) && |
| 11498 GLES2Util::IsNPOT(mask + 1)) { |
| 11499 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, |
| 11500 "glStencilFillPathCHROMIUM", |
| 11501 "mask is not power of two"); |
| 11502 return error::kNoError; |
| 11503 } |
| 11504 GLuint service_id = 0; |
| 11505 if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) { |
| 11506 // "If /path/ does not name an existing path object, the command does |
| 11507 // nothing (and no error is generated)." |
| 11508 // This holds for other rendering functions, too. |
| 11509 return error::kNoError; |
| 11510 } |
| 11511 ApplyDirtyState(); |
| 11512 glStencilFillPathNV(service_id, fill_mode, mask); |
| 11513 return error::kNoError; |
| 11514 } |
| 11515 |
| 11516 error::Error GLES2DecoderImpl::HandleStencilStrokePathCHROMIUM( |
| 11517 uint32 immediate_data_size, |
| 11518 const void* cmd_data) { |
| 11519 const gles2::cmds::StencilStrokePathCHROMIUM& c = |
| 11520 *static_cast<const gles2::cmds::StencilStrokePathCHROMIUM*>(cmd_data); |
| 11521 if (!features().chromium_path_rendering) { |
| 11522 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, |
| 11523 "glStencilStrokePathCHROMIUM", |
| 11524 "function not available"); |
| 11525 return error::kNoError; |
| 11526 } |
| 11527 GLuint service_id = 0; |
| 11528 if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) { |
| 11529 return error::kNoError; |
| 11530 } |
| 11531 GLint reference = static_cast<GLint>(c.reference); |
| 11532 GLuint mask = static_cast<GLuint>(c.mask); |
| 11533 ApplyDirtyState(); |
| 11534 glStencilStrokePathNV(service_id, reference, mask); |
| 11535 return error::kNoError; |
| 11536 } |
| 11537 |
| 11538 error::Error GLES2DecoderImpl::HandleCoverFillPathCHROMIUM( |
| 11539 uint32 immediate_data_size, |
| 11540 const void* cmd_data) { |
| 11541 const gles2::cmds::CoverFillPathCHROMIUM& c = |
| 11542 *static_cast<const gles2::cmds::CoverFillPathCHROMIUM*>(cmd_data); |
| 11543 if (!features().chromium_path_rendering) { |
| 11544 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, |
| 11545 "glCoverFillPathCHROMIUM", |
| 11546 "function not available"); |
| 11547 return error::kNoError; |
| 11548 } |
| 11549 GLuint service_id = 0; |
| 11550 if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) { |
| 11551 return error::kNoError; |
| 11552 } |
| 11553 |
| 11554 ApplyDirtyState(); |
| 11555 glCoverFillPathNV(service_id, GL_BOUNDING_BOX_NV); |
| 11556 return error::kNoError; |
| 11557 } |
| 11558 |
| 11559 error::Error GLES2DecoderImpl::HandleCoverStrokePathCHROMIUM( |
| 11560 uint32 immediate_data_size, |
| 11561 const void* cmd_data) { |
| 11562 const gles2::cmds::CoverStrokePathCHROMIUM& c = |
| 11563 *static_cast<const gles2::cmds::CoverStrokePathCHROMIUM*>(cmd_data); |
| 11564 if (!features().chromium_path_rendering) { |
| 11565 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, |
| 11566 "glCoverStrokePathCHROMIUM", |
| 11567 "function not available"); |
| 11568 return error::kNoError; |
| 11569 } |
| 11570 GLuint service_id = 0; |
| 11571 if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) { |
| 11572 return error::kNoError; |
| 11573 } |
| 11574 |
| 11575 ApplyDirtyState(); |
| 11576 glCoverStrokePathNV(service_id, GL_BOUNDING_BOX_NV); |
| 11577 return error::kNoError; |
| 11578 } |
| 11579 |
| 11580 error::Error GLES2DecoderImpl::HandleStencilThenCoverFillPathCHROMIUM( |
| 11581 uint32 immediate_data_size, |
| 11582 const void* cmd_data) { |
| 11583 const gles2::cmds::StencilThenCoverFillPathCHROMIUM& c = |
| 11584 *static_cast<const gles2::cmds::StencilThenCoverFillPathCHROMIUM*>( |
| 11585 cmd_data); |
| 11586 if (!features().chromium_path_rendering) { |
| 11587 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, |
| 11588 "glStencilThenCoverFillPathCHROMIUM", |
| 11589 "function not available"); |
| 11590 return error::kNoError; |
| 11591 } |
| 11592 GLenum fill_mode = static_cast<GLenum>(c.fillMode); |
| 11593 if (!validators_->path_fill_mode.IsValid(fill_mode)) { |
| 11594 LOCAL_SET_GL_ERROR_INVALID_ENUM( |
| 11595 "glStencilThenCoverFillPathCHROMIUM", fill_mode, "fillMode"); |
| 11596 return error::kNoError; |
| 11597 } |
| 11598 GLuint mask = static_cast<GLuint>(c.mask); |
| 11599 if ((fill_mode == GL_COUNT_UP_CHROMIUM || |
| 11600 fill_mode == GL_COUNT_DOWN_CHROMIUM) && |
| 11601 GLES2Util::IsNPOT(mask + 1)) { |
| 11602 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, |
| 11603 "glStencilThenCoverFillPathCHROMIUM", |
| 11604 "mask is not power of two"); |
| 11605 return error::kNoError; |
| 11606 } |
| 11607 GLuint service_id = 0; |
| 11608 if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) { |
| 11609 return error::kNoError; |
| 11610 } |
| 11611 ApplyDirtyState(); |
| 11612 glStencilThenCoverFillPathNV(service_id, fill_mode, mask, GL_BOUNDING_BOX_NV); |
| 11613 return error::kNoError; |
| 11614 } |
| 11615 |
| 11616 error::Error GLES2DecoderImpl::HandleStencilThenCoverStrokePathCHROMIUM( |
| 11617 uint32 immediate_data_size, |
| 11618 const void* cmd_data) { |
| 11619 const gles2::cmds::StencilThenCoverStrokePathCHROMIUM& c = |
| 11620 *static_cast<const gles2::cmds::StencilThenCoverStrokePathCHROMIUM*>( |
| 11621 cmd_data); |
| 11622 if (!features().chromium_path_rendering) { |
| 11623 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, |
| 11624 "glStencilThenCoverStrokePathCHROMIUM", |
| 11625 "function not available"); |
| 11626 return error::kNoError; |
| 11627 } |
| 11628 GLuint service_id = 0; |
| 11629 if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) { |
| 11630 return error::kNoError; |
| 11631 } |
| 11632 |
| 11633 GLint reference = static_cast<GLint>(c.reference); |
| 11634 GLuint mask = static_cast<GLuint>(c.mask); |
| 11635 ApplyDirtyState(); |
| 11636 glStencilThenCoverStrokePathNV( |
| 11637 service_id, reference, mask, GL_BOUNDING_BOX_NV); |
| 11638 return error::kNoError; |
| 11639 } |
| 11640 |
11147 // Include the auto-generated part of this file. We split this because it means | 11641 // Include the auto-generated part of this file. We split this because it means |
11148 // we can easily edit the non-auto generated parts right here in this file | 11642 // we can easily edit the non-auto generated parts right here in this file |
11149 // instead of having to edit some template or the code generator. | 11643 // instead of having to edit some template or the code generator. |
11150 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 11644 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
11151 | 11645 |
11152 } // namespace gles2 | 11646 } // namespace gles2 |
11153 } // namespace gpu | 11647 } // namespace gpu |
OLD | NEW |