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 <cmath> | 10 #include <cmath> |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 #include "gpu/command_buffer/service/gl_utils.h" | 42 #include "gpu/command_buffer/service/gl_utils.h" |
43 #include "gpu/command_buffer/service/gles2_cmd_clear_framebuffer.h" | 43 #include "gpu/command_buffer/service/gles2_cmd_clear_framebuffer.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/valuebuffer_manager.h" | 60 #include "gpu/command_buffer/service/valuebuffer_manager.h" |
60 #include "gpu/command_buffer/service/vertex_array_manager.h" | 61 #include "gpu/command_buffer/service/vertex_array_manager.h" |
61 #include "gpu/command_buffer/service/vertex_attrib_manager.h" | 62 #include "gpu/command_buffer/service/vertex_attrib_manager.h" |
(...skipping 721 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
783 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids); | 784 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids); |
784 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids); | 785 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids); |
785 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids); | 786 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids); |
786 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids); | 787 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids); |
787 bool GenValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* client_ids); | 788 bool GenValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* client_ids); |
788 void DeleteValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* client_ids); | 789 void DeleteValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* client_ids); |
789 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids); | 790 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids); |
790 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids); | 791 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids); |
791 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); | 792 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); |
792 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); | 793 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); |
| 794 bool GenPathsCHROMIUMHelper(GLuint first_client_id, GLsizei range); |
| 795 bool DeletePathsCHROMIUMHelper(GLuint first_client_id, GLsizei range); |
793 | 796 |
794 // Helper for async upload token completion notification callback. | 797 // Helper for async upload token completion notification callback. |
795 base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token, | 798 base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token, |
796 uint32 sync_data_shm_id, | 799 uint32 sync_data_shm_id, |
797 uint32 sync_data_shm_offset); | 800 uint32 sync_data_shm_offset); |
798 | 801 |
799 | 802 |
800 | 803 |
801 // Workarounds | 804 // Workarounds |
802 void OnFboChanged() const; | 805 void OnFboChanged() const; |
(...skipping 12 matching lines...) Expand all Loading... |
815 } | 818 } |
816 | 819 |
817 FramebufferManager* framebuffer_manager() { | 820 FramebufferManager* framebuffer_manager() { |
818 return group_->framebuffer_manager(); | 821 return group_->framebuffer_manager(); |
819 } | 822 } |
820 | 823 |
821 ValuebufferManager* valuebuffer_manager() { | 824 ValuebufferManager* valuebuffer_manager() { |
822 return group_->valuebuffer_manager(); | 825 return group_->valuebuffer_manager(); |
823 } | 826 } |
824 | 827 |
| 828 PathManager* path_manager() { return group_->path_manager(); } |
| 829 |
825 ProgramManager* program_manager() { | 830 ProgramManager* program_manager() { |
826 return group_->program_manager(); | 831 return group_->program_manager(); |
827 } | 832 } |
828 | 833 |
829 ShaderManager* shader_manager() { | 834 ShaderManager* shader_manager() { |
830 return group_->shader_manager(); | 835 return group_->shader_manager(); |
831 } | 836 } |
832 | 837 |
833 ShaderTranslatorCache* shader_translator_cache() { | 838 ShaderTranslatorCache* shader_translator_cache() { |
834 return group_->shader_translator_cache(); | 839 return group_->shader_translator_cache(); |
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1555 | 1560 |
1556 // Wrappers for glIsXXX functions. | 1561 // Wrappers for glIsXXX functions. |
1557 bool DoIsEnabled(GLenum cap); | 1562 bool DoIsEnabled(GLenum cap); |
1558 bool DoIsBuffer(GLuint client_id); | 1563 bool DoIsBuffer(GLuint client_id); |
1559 bool DoIsFramebuffer(GLuint client_id); | 1564 bool DoIsFramebuffer(GLuint client_id); |
1560 bool DoIsProgram(GLuint client_id); | 1565 bool DoIsProgram(GLuint client_id); |
1561 bool DoIsRenderbuffer(GLuint client_id); | 1566 bool DoIsRenderbuffer(GLuint client_id); |
1562 bool DoIsShader(GLuint client_id); | 1567 bool DoIsShader(GLuint client_id); |
1563 bool DoIsTexture(GLuint client_id); | 1568 bool DoIsTexture(GLuint client_id); |
1564 bool DoIsVertexArrayOES(GLuint client_id); | 1569 bool DoIsVertexArrayOES(GLuint client_id); |
| 1570 bool DoIsPathCHROMIUM(GLuint client_id); |
1565 | 1571 |
1566 // Wrapper for glLinkProgram | 1572 // Wrapper for glLinkProgram |
1567 void DoLinkProgram(GLuint program); | 1573 void DoLinkProgram(GLuint program); |
1568 | 1574 |
1569 // Wrapper for glRenderbufferStorage. | 1575 // Wrapper for glRenderbufferStorage. |
1570 void DoRenderbufferStorage( | 1576 void DoRenderbufferStorage( |
1571 GLenum target, GLenum internalformat, GLsizei width, GLsizei height); | 1577 GLenum target, GLenum internalformat, GLsizei width, GLsizei height); |
1572 | 1578 |
1573 // Handler for glRenderbufferStorageMultisampleCHROMIUM. | 1579 // Handler for glRenderbufferStorageMultisampleCHROMIUM. |
1574 void DoRenderbufferStorageMultisampleCHROMIUM( | 1580 void DoRenderbufferStorageMultisampleCHROMIUM( |
(...skipping 1763 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3338 } | 3344 } |
3339 } | 3345 } |
3340 scoped_ptr<GLuint[]> service_ids(new GLuint[n]); | 3346 scoped_ptr<GLuint[]> service_ids(new GLuint[n]); |
3341 glGenTextures(n, service_ids.get()); | 3347 glGenTextures(n, service_ids.get()); |
3342 for (GLsizei ii = 0; ii < n; ++ii) { | 3348 for (GLsizei ii = 0; ii < n; ++ii) { |
3343 CreateTexture(client_ids[ii], service_ids[ii]); | 3349 CreateTexture(client_ids[ii], service_ids[ii]); |
3344 } | 3350 } |
3345 return true; | 3351 return true; |
3346 } | 3352 } |
3347 | 3353 |
| 3354 bool GLES2DecoderImpl::GenPathsCHROMIUMHelper(GLuint first_client_id, |
| 3355 GLsizei range) { |
| 3356 GLuint last_client_id; |
| 3357 if (!SafeAddUint32(first_client_id, range - 1, &last_client_id)) |
| 3358 return false; |
| 3359 |
| 3360 if (path_manager()->HasPathsInRange(first_client_id, last_client_id)) |
| 3361 return false; |
| 3362 |
| 3363 GLuint first_service_id = glGenPathsNV(range); |
| 3364 if (first_service_id == 0) { |
| 3365 // We have to fail the connection here, because client has already |
| 3366 // succeeded in allocating the ids. This happens if we allocate |
| 3367 // the whole path id space (two allocations of 0x7FFFFFFF paths, for |
| 3368 // example). |
| 3369 return false; |
| 3370 } |
| 3371 // GenPathsNV does not wrap. |
| 3372 DCHECK(first_service_id + range - 1 >= first_service_id); |
| 3373 |
| 3374 path_manager()->CreatePathRange(first_client_id, last_client_id, |
| 3375 first_service_id); |
| 3376 |
| 3377 return true; |
| 3378 } |
| 3379 |
| 3380 bool GLES2DecoderImpl::DeletePathsCHROMIUMHelper(GLuint first_client_id, |
| 3381 GLsizei range) { |
| 3382 GLuint last_client_id; |
| 3383 if (!SafeAddUint32(first_client_id, range - 1, &last_client_id)) |
| 3384 return false; |
| 3385 |
| 3386 path_manager()->RemovePaths(first_client_id, last_client_id); |
| 3387 return true; |
| 3388 } |
| 3389 |
3348 void GLES2DecoderImpl::DeleteBuffersHelper( | 3390 void GLES2DecoderImpl::DeleteBuffersHelper( |
3349 GLsizei n, const GLuint* client_ids) { | 3391 GLsizei n, const GLuint* client_ids) { |
3350 for (GLsizei ii = 0; ii < n; ++ii) { | 3392 for (GLsizei ii = 0; ii < n; ++ii) { |
3351 Buffer* buffer = GetBuffer(client_ids[ii]); | 3393 Buffer* buffer = GetBuffer(client_ids[ii]); |
3352 if (buffer && !buffer->IsDeleted()) { | 3394 if (buffer && !buffer->IsDeleted()) { |
3353 buffer->RemoveMappedRange(); | 3395 buffer->RemoveMappedRange(); |
3354 state_.RemoveBoundBuffer(buffer); | 3396 state_.RemoveBoundBuffer(buffer); |
3355 RemoveBuffer(client_ids[ii]); | 3397 RemoveBuffer(client_ids[ii]); |
3356 } | 3398 } |
3357 } | 3399 } |
(...skipping 8362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11720 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, | 11762 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, |
11721 element_array_buffer ? element_array_buffer->service_id() : 0); | 11763 element_array_buffer ? element_array_buffer->service_id() : 0); |
11722 } | 11764 } |
11723 | 11765 |
11724 bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) { | 11766 bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) { |
11725 const VertexAttribManager* vao = | 11767 const VertexAttribManager* vao = |
11726 GetVertexAttribManager(client_id); | 11768 GetVertexAttribManager(client_id); |
11727 return vao && vao->IsValid() && !vao->IsDeleted(); | 11769 return vao && vao->IsValid() && !vao->IsDeleted(); |
11728 } | 11770 } |
11729 | 11771 |
| 11772 bool GLES2DecoderImpl::DoIsPathCHROMIUM(GLuint client_id) { |
| 11773 GLuint service_id = 0; |
| 11774 return path_manager()->GetPath(client_id, &service_id) && |
| 11775 glIsPathNV(service_id) == GL_TRUE; |
| 11776 } |
| 11777 |
11730 #if defined(OS_MACOSX) | 11778 #if defined(OS_MACOSX) |
11731 void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) { | 11779 void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) { |
11732 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find( | 11780 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find( |
11733 texture_id); | 11781 texture_id); |
11734 if (it != texture_to_io_surface_map_.end()) { | 11782 if (it != texture_to_io_surface_map_.end()) { |
11735 // Found a previous IOSurface bound to this texture; release it. | 11783 // Found a previous IOSurface bound to this texture; release it. |
11736 IOSurfaceRef surface = it->second; | 11784 IOSurfaceRef surface = it->second; |
11737 CFRelease(surface); | 11785 CFRelease(surface); |
11738 texture_to_io_surface_map_.erase(it); | 11786 texture_to_io_surface_map_.erase(it); |
11739 } | 11787 } |
(...skipping 1931 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13671 if (CheckResetStatus()) { | 13719 if (CheckResetStatus()) { |
13672 other = error::kUnknown; | 13720 other = error::kUnknown; |
13673 } else { | 13721 } else { |
13674 // Need to lose current context before broadcasting! | 13722 // Need to lose current context before broadcasting! |
13675 MarkContextLost(error::kOutOfMemory); | 13723 MarkContextLost(error::kOutOfMemory); |
13676 } | 13724 } |
13677 group_->LoseContexts(other); | 13725 group_->LoseContexts(other); |
13678 } | 13726 } |
13679 } | 13727 } |
13680 | 13728 |
| 13729 error::Error GLES2DecoderImpl::HandleGenPathsCHROMIUM( |
| 13730 uint32 immediate_data_size, |
| 13731 const void* cmd_data) { |
| 13732 static const char kFunctionName[] = "glGenPathsCHROMIUM"; |
| 13733 const gles2::cmds::GenPathsCHROMIUM& c = |
| 13734 *static_cast<const gles2::cmds::GenPathsCHROMIUM*>(cmd_data); |
| 13735 if (!features().chromium_path_rendering) { |
| 13736 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, |
| 13737 "function not available"); |
| 13738 return error::kNoError; |
| 13739 } |
| 13740 |
| 13741 GLsizei range = static_cast<GLsizei>(c.range); |
| 13742 if (range < 0) { |
| 13743 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "range < 0"); |
| 13744 return error::kNoError; |
| 13745 } |
| 13746 |
| 13747 GLuint first_client_id = static_cast<GLuint>(c.first_client_id); |
| 13748 if (first_client_id == 0) |
| 13749 return error::kInvalidArguments; |
| 13750 |
| 13751 if (range == 0) |
| 13752 return error::kNoError; |
| 13753 |
| 13754 if (!GenPathsCHROMIUMHelper(first_client_id, range)) |
| 13755 return error::kInvalidArguments; |
| 13756 |
| 13757 return error::kNoError; |
| 13758 } |
| 13759 error::Error GLES2DecoderImpl::HandleDeletePathsCHROMIUM( |
| 13760 uint32_t immediate_data_size, |
| 13761 const void* cmd_data) { |
| 13762 static const char kFunctionName[] = "glDeletePathsCHROMIUM"; |
| 13763 const gles2::cmds::DeletePathsCHROMIUM& c = |
| 13764 *static_cast<const gles2::cmds::DeletePathsCHROMIUM*>(cmd_data); |
| 13765 if (!features().chromium_path_rendering) { |
| 13766 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, |
| 13767 "function not available"); |
| 13768 return error::kNoError; |
| 13769 } |
| 13770 |
| 13771 GLsizei range = static_cast<GLsizei>(c.range); |
| 13772 if (range < 0) { |
| 13773 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "range < 0"); |
| 13774 return error::kNoError; |
| 13775 } |
| 13776 |
| 13777 if (range == 0) |
| 13778 return error::kNoError; |
| 13779 |
| 13780 GLuint first_client_id = c.first_client_id; |
| 13781 // first_client_id can be 0, because non-existing path ids are skipped. |
| 13782 |
| 13783 if (!DeletePathsCHROMIUMHelper(first_client_id, range)) |
| 13784 return error::kInvalidArguments; |
| 13785 |
| 13786 return error::kNoError; |
| 13787 } |
| 13788 |
| 13789 error::Error GLES2DecoderImpl::HandlePathCommandsCHROMIUM( |
| 13790 uint32 immediate_data_size, |
| 13791 const void* cmd_data) { |
| 13792 static const char kFunctionName[] = "glPathCommandsCHROMIUM"; |
| 13793 const gles2::cmds::PathCommandsCHROMIUM& c = |
| 13794 *static_cast<const gles2::cmds::PathCommandsCHROMIUM*>(cmd_data); |
| 13795 if (!features().chromium_path_rendering) { |
| 13796 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, |
| 13797 "function not available"); |
| 13798 return error::kNoError; |
| 13799 } |
| 13800 |
| 13801 GLuint service_id = 0; |
| 13802 if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) { |
| 13803 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, |
| 13804 "invalid path name"); |
| 13805 return error::kNoError; |
| 13806 } |
| 13807 |
| 13808 GLsizei num_commands = static_cast<GLsizei>(c.numCommands); |
| 13809 if (num_commands < 0) { |
| 13810 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "numCommands < 0"); |
| 13811 return error::kNoError; |
| 13812 } |
| 13813 |
| 13814 GLsizei num_coords = static_cast<uint32>(c.numCoords); |
| 13815 if (num_coords < 0) { |
| 13816 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "numCoords < 0"); |
| 13817 return error::kNoError; |
| 13818 } |
| 13819 |
| 13820 GLenum coord_type = static_cast<uint32>(c.coordType); |
| 13821 if (!validators_->path_coord_type.IsValid(static_cast<GLint>(coord_type))) { |
| 13822 LOCAL_SET_GL_ERROR(GL_INVALID_ENUM, kFunctionName, "invalid coordType"); |
| 13823 return error::kNoError; |
| 13824 } |
| 13825 |
| 13826 const GLubyte* commands = NULL; |
| 13827 base::CheckedNumeric<GLsizei> num_coords_expected = 0; |
| 13828 |
| 13829 if (num_commands > 0) { |
| 13830 uint32 commands_shm_id = static_cast<uint32>(c.commands_shm_id); |
| 13831 uint32 commands_shm_offset = static_cast<uint32>(c.commands_shm_offset); |
| 13832 if (commands_shm_id != 0 || commands_shm_offset != 0) |
| 13833 commands = GetSharedMemoryAs<const GLubyte*>( |
| 13834 commands_shm_id, commands_shm_offset, num_commands); |
| 13835 |
| 13836 if (!commands) |
| 13837 return error::kOutOfBounds; |
| 13838 |
| 13839 for (GLsizei i = 0; i < num_commands; ++i) { |
| 13840 switch (commands[i]) { |
| 13841 case GL_CLOSE_PATH_CHROMIUM: |
| 13842 // Close has no coords. |
| 13843 break; |
| 13844 case GL_MOVE_TO_CHROMIUM: |
| 13845 // Fallthrough. |
| 13846 case GL_LINE_TO_CHROMIUM: |
| 13847 num_coords_expected += 2; |
| 13848 break; |
| 13849 case GL_QUADRATIC_CURVE_TO_CHROMIUM: |
| 13850 num_coords_expected += 4; |
| 13851 break; |
| 13852 case GL_CUBIC_CURVE_TO_CHROMIUM: |
| 13853 num_coords_expected += 6; |
| 13854 break; |
| 13855 case GL_CONIC_CURVE_TO_CHROMIUM: |
| 13856 num_coords_expected += 5; |
| 13857 break; |
| 13858 default: |
| 13859 LOCAL_SET_GL_ERROR(GL_INVALID_ENUM, kFunctionName, "invalid command"); |
| 13860 return error::kNoError; |
| 13861 } |
| 13862 } |
| 13863 } |
| 13864 |
| 13865 if (!num_coords_expected.IsValid() || |
| 13866 num_coords != num_coords_expected.ValueOrDie()) { |
| 13867 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, |
| 13868 "numCoords does not match commands"); |
| 13869 return error::kNoError; |
| 13870 } |
| 13871 |
| 13872 const void* coords = NULL; |
| 13873 |
| 13874 if (num_coords > 0) { |
| 13875 uint32 coords_size = 0; |
| 13876 uint32 coord_type_size = |
| 13877 GLES2Util::GetGLTypeSizeForPathCoordType(coord_type); |
| 13878 if (!SafeMultiplyUint32(num_coords, coord_type_size, &coords_size)) |
| 13879 return error::kOutOfBounds; |
| 13880 |
| 13881 uint32 coords_shm_id = static_cast<uint32>(c.coords_shm_id); |
| 13882 uint32 coords_shm_offset = static_cast<uint32>(c.coords_shm_offset); |
| 13883 if (coords_shm_id != 0 || coords_shm_offset != 0) |
| 13884 coords = GetSharedMemoryAs<const void*>(coords_shm_id, coords_shm_offset, |
| 13885 coords_size); |
| 13886 |
| 13887 if (!coords) |
| 13888 return error::kOutOfBounds; |
| 13889 } |
| 13890 |
| 13891 glPathCommandsNV(service_id, num_commands, commands, num_coords, coord_type, |
| 13892 coords); |
| 13893 |
| 13894 return error::kNoError; |
| 13895 } |
| 13896 |
| 13897 error::Error GLES2DecoderImpl::HandlePathParameterfCHROMIUM( |
| 13898 uint32 immediate_data_size, |
| 13899 const void* cmd_data) { |
| 13900 static const char kFunctionName[] = "glPathParameterfCHROMIUM"; |
| 13901 const gles2::cmds::PathParameterfCHROMIUM& c = |
| 13902 *static_cast<const gles2::cmds::PathParameterfCHROMIUM*>(cmd_data); |
| 13903 if (!features().chromium_path_rendering) { |
| 13904 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, |
| 13905 "function not available"); |
| 13906 return error::kNoError; |
| 13907 } |
| 13908 GLuint service_id = 0; |
| 13909 if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) { |
| 13910 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, |
| 13911 "invalid path name"); |
| 13912 return error::kNoError; |
| 13913 } |
| 13914 |
| 13915 GLenum pname = static_cast<GLenum>(c.pname); |
| 13916 GLfloat value = static_cast<GLfloat>(c.value); |
| 13917 bool hasValueError = false; |
| 13918 |
| 13919 switch (pname) { |
| 13920 case GL_PATH_STROKE_WIDTH_CHROMIUM: |
| 13921 case GL_PATH_MITER_LIMIT_CHROMIUM: |
| 13922 hasValueError = std::isnan(value) || !std::isfinite(value) || value < 0; |
| 13923 break; |
| 13924 case GL_PATH_STROKE_BOUND_CHROMIUM: |
| 13925 value = std::max(std::min(1.0f, value), 0.0f); |
| 13926 break; |
| 13927 case GL_PATH_END_CAPS_CHROMIUM: |
| 13928 hasValueError = !validators_->path_parameter_cap_values.IsValid( |
| 13929 static_cast<GLint>(value)); |
| 13930 break; |
| 13931 case GL_PATH_JOIN_STYLE_CHROMIUM: |
| 13932 hasValueError = !validators_->path_parameter_join_values.IsValid( |
| 13933 static_cast<GLint>(value)); |
| 13934 break; |
| 13935 default: |
| 13936 DCHECK(!validators_->path_parameter.IsValid(pname)); |
| 13937 LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, pname, "pname"); |
| 13938 return error::kNoError; |
| 13939 } |
| 13940 DCHECK(validators_->path_parameter.IsValid(pname)); |
| 13941 |
| 13942 if (hasValueError) { |
| 13943 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "value not correct"); |
| 13944 return error::kNoError; |
| 13945 } |
| 13946 |
| 13947 glPathParameterfNV(service_id, pname, value); |
| 13948 return error::kNoError; |
| 13949 } |
| 13950 |
| 13951 error::Error GLES2DecoderImpl::HandlePathParameteriCHROMIUM( |
| 13952 uint32 immediate_data_size, |
| 13953 const void* cmd_data) { |
| 13954 static const char kFunctionName[] = "glPathParameteriCHROMIUM"; |
| 13955 const gles2::cmds::PathParameteriCHROMIUM& c = |
| 13956 *static_cast<const gles2::cmds::PathParameteriCHROMIUM*>(cmd_data); |
| 13957 if (!features().chromium_path_rendering) { |
| 13958 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, |
| 13959 "function not available"); |
| 13960 return error::kNoError; |
| 13961 } |
| 13962 GLuint service_id = 0; |
| 13963 if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) { |
| 13964 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, |
| 13965 "invalid path name"); |
| 13966 return error::kNoError; |
| 13967 } |
| 13968 |
| 13969 GLenum pname = static_cast<GLenum>(c.pname); |
| 13970 GLint value = static_cast<GLint>(c.value); |
| 13971 bool hasValueError = false; |
| 13972 |
| 13973 switch (pname) { |
| 13974 case GL_PATH_STROKE_WIDTH_CHROMIUM: |
| 13975 case GL_PATH_MITER_LIMIT_CHROMIUM: |
| 13976 hasValueError = value < 0; |
| 13977 break; |
| 13978 case GL_PATH_STROKE_BOUND_CHROMIUM: |
| 13979 value = std::max(std::min(1, value), 0); |
| 13980 break; |
| 13981 case GL_PATH_END_CAPS_CHROMIUM: |
| 13982 hasValueError = !validators_->path_parameter_cap_values.IsValid(value); |
| 13983 break; |
| 13984 case GL_PATH_JOIN_STYLE_CHROMIUM: |
| 13985 hasValueError = !validators_->path_parameter_join_values.IsValid(value); |
| 13986 break; |
| 13987 default: |
| 13988 DCHECK(!validators_->path_parameter.IsValid(pname)); |
| 13989 LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, pname, "pname"); |
| 13990 return error::kNoError; |
| 13991 } |
| 13992 DCHECK(validators_->path_parameter.IsValid(pname)); |
| 13993 |
| 13994 if (hasValueError) { |
| 13995 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "value not correct"); |
| 13996 return error::kNoError; |
| 13997 } |
| 13998 |
| 13999 glPathParameteriNV(service_id, pname, value); |
| 14000 return error::kNoError; |
| 14001 } |
| 14002 |
| 14003 error::Error GLES2DecoderImpl::HandleStencilFillPathCHROMIUM( |
| 14004 uint32 immediate_data_size, |
| 14005 const void* cmd_data) { |
| 14006 static const char kFunctionName[] = "glStencilFillPathCHROMIUM"; |
| 14007 const gles2::cmds::StencilFillPathCHROMIUM& c = |
| 14008 *static_cast<const gles2::cmds::StencilFillPathCHROMIUM*>(cmd_data); |
| 14009 if (!features().chromium_path_rendering) { |
| 14010 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, |
| 14011 "function not available"); |
| 14012 return error::kNoError; |
| 14013 } |
| 14014 GLenum fill_mode = static_cast<GLenum>(c.fillMode); |
| 14015 if (!validators_->path_fill_mode.IsValid(fill_mode)) { |
| 14016 LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, fill_mode, "fillMode"); |
| 14017 return error::kNoError; |
| 14018 } |
| 14019 GLuint mask = static_cast<GLuint>(c.mask); |
| 14020 if ((fill_mode == GL_COUNT_UP_CHROMIUM || |
| 14021 fill_mode == GL_COUNT_DOWN_CHROMIUM) && |
| 14022 GLES2Util::IsNPOT(mask + 1)) { |
| 14023 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, |
| 14024 "mask + 1 is not power of two"); |
| 14025 return error::kNoError; |
| 14026 } |
| 14027 GLuint service_id = 0; |
| 14028 if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) { |
| 14029 // "If /path/ does not name an existing path object, the command does |
| 14030 // nothing (and no error is generated)." |
| 14031 // This holds for other rendering functions, too. |
| 14032 return error::kNoError; |
| 14033 } |
| 14034 ApplyDirtyState(); |
| 14035 glStencilFillPathNV(service_id, fill_mode, mask); |
| 14036 return error::kNoError; |
| 14037 } |
| 14038 |
| 14039 error::Error GLES2DecoderImpl::HandleStencilStrokePathCHROMIUM( |
| 14040 uint32 immediate_data_size, |
| 14041 const void* cmd_data) { |
| 14042 static const char kFunctionName[] = "glStencilStrokePathCHROMIUM"; |
| 14043 const gles2::cmds::StencilStrokePathCHROMIUM& c = |
| 14044 *static_cast<const gles2::cmds::StencilStrokePathCHROMIUM*>(cmd_data); |
| 14045 if (!features().chromium_path_rendering) { |
| 14046 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, |
| 14047 "function not available"); |
| 14048 return error::kNoError; |
| 14049 } |
| 14050 GLuint service_id = 0; |
| 14051 if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) { |
| 14052 return error::kNoError; |
| 14053 } |
| 14054 GLint reference = static_cast<GLint>(c.reference); |
| 14055 GLuint mask = static_cast<GLuint>(c.mask); |
| 14056 ApplyDirtyState(); |
| 14057 glStencilStrokePathNV(service_id, reference, mask); |
| 14058 return error::kNoError; |
| 14059 } |
| 14060 |
| 14061 error::Error GLES2DecoderImpl::HandleCoverFillPathCHROMIUM( |
| 14062 uint32 immediate_data_size, |
| 14063 const void* cmd_data) { |
| 14064 static const char kFunctionName[] = "glCoverFillPathCHROMIUM"; |
| 14065 const gles2::cmds::CoverFillPathCHROMIUM& c = |
| 14066 *static_cast<const gles2::cmds::CoverFillPathCHROMIUM*>(cmd_data); |
| 14067 if (!features().chromium_path_rendering) { |
| 14068 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, |
| 14069 "function not available"); |
| 14070 return error::kNoError; |
| 14071 } |
| 14072 GLenum cover_mode = static_cast<GLenum>(c.coverMode); |
| 14073 if (!validators_->path_cover_mode.IsValid(cover_mode)) { |
| 14074 LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, cover_mode, "coverMode"); |
| 14075 return error::kNoError; |
| 14076 } |
| 14077 GLuint service_id = 0; |
| 14078 if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) |
| 14079 return error::kNoError; |
| 14080 |
| 14081 ApplyDirtyState(); |
| 14082 glCoverFillPathNV(service_id, cover_mode); |
| 14083 return error::kNoError; |
| 14084 } |
| 14085 |
| 14086 error::Error GLES2DecoderImpl::HandleCoverStrokePathCHROMIUM( |
| 14087 uint32 immediate_data_size, |
| 14088 const void* cmd_data) { |
| 14089 static const char kFunctionName[] = "glCoverStrokePathCHROMIUM"; |
| 14090 const gles2::cmds::CoverStrokePathCHROMIUM& c = |
| 14091 *static_cast<const gles2::cmds::CoverStrokePathCHROMIUM*>(cmd_data); |
| 14092 if (!features().chromium_path_rendering) { |
| 14093 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, |
| 14094 "function not available"); |
| 14095 return error::kNoError; |
| 14096 } |
| 14097 GLenum cover_mode = static_cast<GLenum>(c.coverMode); |
| 14098 if (!validators_->path_cover_mode.IsValid(cover_mode)) { |
| 14099 LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, cover_mode, "coverMode"); |
| 14100 return error::kNoError; |
| 14101 } |
| 14102 GLuint service_id = 0; |
| 14103 if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) |
| 14104 return error::kNoError; |
| 14105 |
| 14106 ApplyDirtyState(); |
| 14107 glCoverStrokePathNV(service_id, cover_mode); |
| 14108 return error::kNoError; |
| 14109 } |
| 14110 |
| 14111 error::Error GLES2DecoderImpl::HandleStencilThenCoverFillPathCHROMIUM( |
| 14112 uint32 immediate_data_size, |
| 14113 const void* cmd_data) { |
| 14114 static const char kFunctionName[] = "glStencilThenCoverFillPathCHROMIUM"; |
| 14115 const gles2::cmds::StencilThenCoverFillPathCHROMIUM& c = |
| 14116 *static_cast<const gles2::cmds::StencilThenCoverFillPathCHROMIUM*>( |
| 14117 cmd_data); |
| 14118 if (!features().chromium_path_rendering) { |
| 14119 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, |
| 14120 "function not available"); |
| 14121 return error::kNoError; |
| 14122 } |
| 14123 GLenum fill_mode = static_cast<GLenum>(c.fillMode); |
| 14124 if (!validators_->path_fill_mode.IsValid(fill_mode)) { |
| 14125 LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, fill_mode, "fillMode"); |
| 14126 return error::kNoError; |
| 14127 } |
| 14128 GLuint mask = static_cast<GLuint>(c.mask); |
| 14129 if ((fill_mode == GL_COUNT_UP_CHROMIUM || |
| 14130 fill_mode == GL_COUNT_DOWN_CHROMIUM) && |
| 14131 GLES2Util::IsNPOT(mask + 1)) { |
| 14132 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, |
| 14133 "mask + 1 is not power of two"); |
| 14134 return error::kNoError; |
| 14135 } |
| 14136 GLenum cover_mode = static_cast<GLenum>(c.coverMode); |
| 14137 if (!validators_->path_cover_mode.IsValid(cover_mode)) { |
| 14138 LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, cover_mode, "coverMode"); |
| 14139 return error::kNoError; |
| 14140 } |
| 14141 GLuint service_id = 0; |
| 14142 if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) |
| 14143 return error::kNoError; |
| 14144 |
| 14145 ApplyDirtyState(); |
| 14146 glStencilThenCoverFillPathNV(service_id, fill_mode, mask, cover_mode); |
| 14147 return error::kNoError; |
| 14148 } |
| 14149 |
| 14150 error::Error GLES2DecoderImpl::HandleStencilThenCoverStrokePathCHROMIUM( |
| 14151 uint32 immediate_data_size, |
| 14152 const void* cmd_data) { |
| 14153 static const char kFunctionName[] = "glStencilThenCoverStrokePathCHROMIUM"; |
| 14154 const gles2::cmds::StencilThenCoverStrokePathCHROMIUM& c = |
| 14155 *static_cast<const gles2::cmds::StencilThenCoverStrokePathCHROMIUM*>( |
| 14156 cmd_data); |
| 14157 if (!features().chromium_path_rendering) { |
| 14158 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, |
| 14159 "function not available"); |
| 14160 return error::kNoError; |
| 14161 } |
| 14162 GLenum cover_mode = static_cast<GLenum>(c.coverMode); |
| 14163 if (!validators_->path_cover_mode.IsValid(cover_mode)) { |
| 14164 LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, cover_mode, "coverMode"); |
| 14165 return error::kNoError; |
| 14166 } |
| 14167 GLuint service_id = 0; |
| 14168 if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) |
| 14169 return error::kNoError; |
| 14170 |
| 14171 GLint reference = static_cast<GLint>(c.reference); |
| 14172 GLuint mask = static_cast<GLuint>(c.mask); |
| 14173 ApplyDirtyState(); |
| 14174 glStencilThenCoverStrokePathNV(service_id, reference, mask, cover_mode); |
| 14175 return error::kNoError; |
| 14176 } |
| 14177 |
13681 // Include the auto-generated part of this file. We split this because it means | 14178 // Include the auto-generated part of this file. We split this because it means |
13682 // we can easily edit the non-auto generated parts right here in this file | 14179 // we can easily edit the non-auto generated parts right here in this file |
13683 // instead of having to edit some template or the code generator. | 14180 // instead of having to edit some template or the code generator. |
13684 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 14181 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
13685 | 14182 |
13686 } // namespace gles2 | 14183 } // namespace gles2 |
13687 } // namespace gpu | 14184 } // namespace gpu |
OLD | NEW |