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