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 <limits.h> | 7 #include <limits.h> |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 #include <stdio.h> | 10 #include <stdio.h> |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 depth(_depth) {} | 159 depth(_depth) {} |
160 | 160 |
161 int xoffset; | 161 int xoffset; |
162 int yoffset; | 162 int yoffset; |
163 int zoffset; | 163 int zoffset; |
164 int width; | 164 int width; |
165 int height; | 165 int height; |
166 int depth; | 166 int depth; |
167 }; | 167 }; |
168 | 168 |
| 169 // Check if all |ref| bits are set in |bits|. |
| 170 bool AllBitsSet(GLbitfield bits, GLbitfield ref) { |
| 171 DCHECK_NE(0u, ref); |
| 172 return ((bits & ref) == ref); |
| 173 } |
| 174 |
| 175 // Check if any of |ref| bits are set in |bits|. |
| 176 bool AnyBitsSet(GLbitfield bits, GLbitfield ref) { |
| 177 DCHECK_NE(0u, ref); |
| 178 return ((bits & ref) != 0); |
| 179 } |
| 180 |
| 181 // Check if any bits are set in |bits| other than the bits in |ref|. |
| 182 bool AnyOtherBitsSet(GLbitfield bits, GLbitfield ref) { |
| 183 DCHECK_NE(0u, ref); |
| 184 GLbitfield mask = ~ref; |
| 185 return ((bits & mask) != 0); |
| 186 } |
| 187 |
169 } // namespace | 188 } // namespace |
170 | 189 |
171 class GLES2DecoderImpl; | 190 class GLES2DecoderImpl; |
172 | 191 |
173 // Local versions of the SET_GL_ERROR macros | 192 // Local versions of the SET_GL_ERROR macros |
174 #define LOCAL_SET_GL_ERROR(error, function_name, msg) \ | 193 #define LOCAL_SET_GL_ERROR(error, function_name, msg) \ |
175 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg) | 194 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg) |
176 #define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \ | 195 #define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \ |
177 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \ | 196 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \ |
178 function_name, value, label) | 197 function_name, value, label) |
(...skipping 848 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1027 void DoLoseContextCHROMIUM(GLenum current, GLenum other); | 1046 void DoLoseContextCHROMIUM(GLenum current, GLenum other); |
1028 | 1047 |
1029 void DoFlushDriverCachesCHROMIUM(void); | 1048 void DoFlushDriverCachesCHROMIUM(void); |
1030 | 1049 |
1031 void DoMatrixLoadfCHROMIUM(GLenum matrix_mode, | 1050 void DoMatrixLoadfCHROMIUM(GLenum matrix_mode, |
1032 const volatile GLfloat* matrix); | 1051 const volatile GLfloat* matrix); |
1033 void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode); | 1052 void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode); |
1034 void DoScheduleCALayerInUseQueryCHROMIUM(GLsizei count, | 1053 void DoScheduleCALayerInUseQueryCHROMIUM(GLsizei count, |
1035 const volatile GLuint* textures); | 1054 const volatile GLuint* textures); |
1036 | 1055 |
| 1056 void DoFlushMappedBufferRange( |
| 1057 GLenum target, GLintptr offset, GLsizeiptr size); |
| 1058 |
1037 // Creates a Program for the given program. | 1059 // Creates a Program for the given program. |
1038 Program* CreateProgram(GLuint client_id, GLuint service_id) { | 1060 Program* CreateProgram(GLuint client_id, GLuint service_id) { |
1039 return program_manager()->CreateProgram(client_id, service_id); | 1061 return program_manager()->CreateProgram(client_id, service_id); |
1040 } | 1062 } |
1041 | 1063 |
1042 // Gets the program info for the given program. Returns NULL if none exists. | 1064 // Gets the program info for the given program. Returns NULL if none exists. |
1043 Program* GetProgram(GLuint client_id) { | 1065 Program* GetProgram(GLuint client_id) { |
1044 return program_manager()->GetProgram(client_id); | 1066 return program_manager()->GetProgram(client_id); |
1045 } | 1067 } |
1046 | 1068 |
(...skipping 15777 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16824 typedef cmds::MapBufferRange::Result Result; | 16846 typedef cmds::MapBufferRange::Result Result; |
16825 Result* result = GetSharedMemoryAs<Result*>( | 16847 Result* result = GetSharedMemoryAs<Result*>( |
16826 c.result_shm_id, c.result_shm_offset, sizeof(*result)); | 16848 c.result_shm_id, c.result_shm_offset, sizeof(*result)); |
16827 if (!result) { | 16849 if (!result) { |
16828 return error::kOutOfBounds; | 16850 return error::kOutOfBounds; |
16829 } | 16851 } |
16830 if (*result != 0) { | 16852 if (*result != 0) { |
16831 *result = 0; | 16853 *result = 0; |
16832 return error::kInvalidArguments; | 16854 return error::kInvalidArguments; |
16833 } | 16855 } |
16834 int8_t* mem = | |
16835 GetSharedMemoryAs<int8_t*>(data_shm_id, data_shm_offset, size); | |
16836 if (!mem) { | |
16837 return error::kOutOfBounds; | |
16838 } | |
16839 | |
16840 if (!validators_->buffer_target.IsValid(target)) { | 16856 if (!validators_->buffer_target.IsValid(target)) { |
16841 LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target"); | 16857 LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target"); |
16842 return error::kNoError; | 16858 return error::kNoError; |
16843 } | 16859 } |
16844 | |
16845 GLbitfield mask = GL_MAP_INVALIDATE_BUFFER_BIT; | |
16846 if ((access & mask) == mask) { | |
16847 // TODO(zmo): To be on the safe side, always map | |
16848 // GL_MAP_INVALIDATE_BUFFER_BIT to GL_MAP_INVALIDATE_RANGE_BIT. | |
16849 access = (access & ~GL_MAP_INVALIDATE_BUFFER_BIT); | |
16850 access = (access | GL_MAP_INVALIDATE_RANGE_BIT); | |
16851 } | |
16852 // TODO(zmo): Always filter out GL_MAP_UNSYNCHRONIZED_BIT to get rid of | |
16853 // undefined behaviors. | |
16854 mask = GL_MAP_READ_BIT | GL_MAP_UNSYNCHRONIZED_BIT; | |
16855 if ((access & mask) == mask) { | |
16856 LOCAL_SET_GL_ERROR( | |
16857 GL_INVALID_OPERATION, func_name, "incompatible access bits"); | |
16858 return error::kNoError; | |
16859 } | |
16860 access = (access & ~GL_MAP_UNSYNCHRONIZED_BIT); | |
16861 if ((access & GL_MAP_WRITE_BIT) == GL_MAP_WRITE_BIT && | |
16862 (access & GL_MAP_INVALIDATE_RANGE_BIT) == 0) { | |
16863 access = (access | GL_MAP_READ_BIT); | |
16864 } | |
16865 Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target); | 16860 Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target); |
16866 if (!buffer) { | 16861 if (!buffer) { |
16867 LOCAL_SET_GL_ERROR( | 16862 LOCAL_SET_GL_ERROR( |
16868 GL_INVALID_OPERATION, func_name, "no buffer bound to target"); | 16863 GL_INVALID_OPERATION, func_name, "no buffer bound to target"); |
16869 return error::kNoError; | 16864 return error::kNoError; |
16870 } | 16865 } |
16871 if (buffer->GetMappedRange()) { | 16866 if (buffer->GetMappedRange()) { |
16872 LOCAL_SET_GL_ERROR( | 16867 LOCAL_SET_GL_ERROR( |
16873 GL_INVALID_OPERATION, func_name, "buffer is already mapped"); | 16868 GL_INVALID_OPERATION, func_name, "buffer is already mapped"); |
| 16869 return error::kNoError; |
| 16870 } |
| 16871 if (size == 0) { |
| 16872 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "size is zero"); |
| 16873 return error::kNoError; |
16874 } | 16874 } |
16875 if (!buffer->CheckRange(offset, size)) { | 16875 if (!buffer->CheckRange(offset, size)) { |
16876 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "invalid range"); | 16876 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "invalid range"); |
16877 return error::kNoError; | 16877 return error::kNoError; |
16878 } | 16878 } |
| 16879 int8_t* mem = |
| 16880 GetSharedMemoryAs<int8_t*>(data_shm_id, data_shm_offset, size); |
| 16881 if (!mem) { |
| 16882 return error::kOutOfBounds; |
| 16883 } |
| 16884 if (AnyOtherBitsSet(access, (GL_MAP_READ_BIT | |
| 16885 GL_MAP_WRITE_BIT | |
| 16886 GL_MAP_INVALIDATE_RANGE_BIT | |
| 16887 GL_MAP_INVALIDATE_BUFFER_BIT | |
| 16888 GL_MAP_FLUSH_EXPLICIT_BIT | |
| 16889 GL_MAP_UNSYNCHRONIZED_BIT))) { |
| 16890 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "invalid access bits"); |
| 16891 return error::kNoError; |
| 16892 } |
| 16893 if (!AnyBitsSet(access, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) { |
| 16894 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
| 16895 "neither MAP_READ_BIT nore MAP_WRITE_BIT is set"); |
| 16896 return error::kNoError; |
| 16897 } |
| 16898 if (AllBitsSet(access, GL_MAP_READ_BIT) && |
| 16899 AnyBitsSet(access, (GL_MAP_INVALIDATE_RANGE_BIT | |
| 16900 GL_MAP_INVALIDATE_BUFFER_BIT | |
| 16901 GL_MAP_UNSYNCHRONIZED_BIT))) { |
| 16902 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
| 16903 "Incompatible access bits with MAP_READ_BIT"); |
| 16904 return error::kNoError; |
| 16905 } |
| 16906 if (AllBitsSet(access, GL_MAP_FLUSH_EXPLICIT_BIT) && |
| 16907 !AllBitsSet(access, GL_MAP_WRITE_BIT)) { |
| 16908 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
| 16909 "MAP_FLUSH_EXPLICIT_BIT set without MAP_WRITE_BIT"); |
| 16910 return error::kNoError; |
| 16911 } |
| 16912 if (AllBitsSet(access, GL_MAP_INVALIDATE_BUFFER_BIT)) { |
| 16913 // To be on the safe side, always map GL_MAP_INVALIDATE_BUFFER_BIT to |
| 16914 // GL_MAP_INVALIDATE_RANGE_BIT. |
| 16915 access = (access & ~GL_MAP_INVALIDATE_BUFFER_BIT); |
| 16916 access = (access | GL_MAP_INVALIDATE_RANGE_BIT); |
| 16917 } |
| 16918 // Always filter out GL_MAP_UNSYNCHRONIZED_BIT to get rid of undefined |
| 16919 // behaviors. |
| 16920 access = (access & ~GL_MAP_UNSYNCHRONIZED_BIT); |
| 16921 if (AllBitsSet(access, GL_MAP_WRITE_BIT) && |
| 16922 !AllBitsSet(access, GL_MAP_INVALIDATE_RANGE_BIT)) { |
| 16923 access = (access | GL_MAP_READ_BIT); |
| 16924 } |
16879 void* ptr = glMapBufferRange(target, offset, size, access); | 16925 void* ptr = glMapBufferRange(target, offset, size, access); |
16880 if (ptr == nullptr) { | 16926 if (ptr == nullptr) { |
16881 return error::kNoError; | 16927 return error::kNoError; |
16882 } | 16928 } |
16883 buffer->SetMappedRange(offset, size, access, ptr, | 16929 buffer->SetMappedRange(offset, size, access, ptr, |
16884 GetSharedMemoryBuffer(data_shm_id), | 16930 GetSharedMemoryBuffer(data_shm_id), |
16885 static_cast<unsigned int>(data_shm_offset)); | 16931 static_cast<unsigned int>(data_shm_offset)); |
16886 if ((access & GL_MAP_INVALIDATE_RANGE_BIT) == 0) { | 16932 if ((access & GL_MAP_INVALIDATE_RANGE_BIT) == 0) { |
16887 memcpy(mem, ptr, size); | 16933 memcpy(mem, ptr, size); |
16888 } | 16934 } |
16889 *result = 1; | 16935 *result = 1; |
16890 return error::kNoError; | 16936 return error::kNoError; |
16891 } | 16937 } |
16892 | 16938 |
16893 error::Error GLES2DecoderImpl::HandleUnmapBuffer( | 16939 error::Error GLES2DecoderImpl::HandleUnmapBuffer( |
16894 uint32_t immediate_data_size, | 16940 uint32_t immediate_data_size, const volatile void* cmd_data) { |
16895 const volatile void* cmd_data) { | |
16896 if (!unsafe_es3_apis_enabled()) { | 16941 if (!unsafe_es3_apis_enabled()) { |
16897 return error::kUnknownCommand; | 16942 return error::kUnknownCommand; |
16898 } | 16943 } |
| 16944 const char* func_name = "glUnmapBuffer"; |
| 16945 |
16899 const volatile gles2::cmds::UnmapBuffer& c = | 16946 const volatile gles2::cmds::UnmapBuffer& c = |
16900 *static_cast<const volatile gles2::cmds::UnmapBuffer*>(cmd_data); | 16947 *static_cast<const volatile gles2::cmds::UnmapBuffer*>(cmd_data); |
16901 GLenum target = static_cast<GLenum>(c.target); | 16948 GLenum target = static_cast<GLenum>(c.target); |
16902 | 16949 |
16903 if (!validators_->buffer_target.IsValid(target)) { | 16950 if (!validators_->buffer_target.IsValid(target)) { |
16904 LOCAL_SET_GL_ERROR_INVALID_ENUM("glMapBufferRange", target, "target"); | 16951 LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target"); |
16905 return error::kNoError; | 16952 return error::kNoError; |
16906 } | 16953 } |
16907 | 16954 |
16908 Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target); | 16955 Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target); |
16909 if (!buffer) { | 16956 if (!buffer) { |
16910 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "UnmapBuffer", "no buffer bound"); | 16957 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "no buffer bound"); |
16911 return error::kNoError; | 16958 return error::kNoError; |
16912 } | 16959 } |
16913 const Buffer::MappedRange* mapped_range = buffer->GetMappedRange(); | 16960 const Buffer::MappedRange* mapped_range = buffer->GetMappedRange(); |
16914 if (!mapped_range) { | 16961 if (!mapped_range) { |
16915 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "UnmapBuffer", | 16962 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "buffer is unmapped"); |
16916 "buffer is unmapped"); | |
16917 return error::kNoError; | 16963 return error::kNoError; |
16918 } | 16964 } |
16919 if ((mapped_range->access & GL_MAP_WRITE_BIT) == 0 || | 16965 if (!AllBitsSet(mapped_range->access, GL_MAP_WRITE_BIT) || |
16920 (mapped_range->access & GL_MAP_FLUSH_EXPLICIT_BIT) == | 16966 AllBitsSet(mapped_range->access, GL_MAP_FLUSH_EXPLICIT_BIT)) { |
16921 GL_MAP_FLUSH_EXPLICIT_BIT) { | |
16922 // If we don't need to write back, or explict flush is required, no copying | 16967 // If we don't need to write back, or explict flush is required, no copying |
16923 // back is needed. | 16968 // back is needed. |
16924 } else { | 16969 } else { |
16925 void* mem = mapped_range->GetShmPointer(); | 16970 void* mem = mapped_range->GetShmPointer(); |
16926 if (!mem) { | 16971 DCHECK(mem); |
16927 return error::kOutOfBounds; | |
16928 } | |
16929 DCHECK(mapped_range->pointer); | 16972 DCHECK(mapped_range->pointer); |
16930 memcpy(mapped_range->pointer, mem, mapped_range->size); | 16973 memcpy(mapped_range->pointer, mem, mapped_range->size); |
16931 if (buffer->shadowed()) { | 16974 if (buffer->shadowed()) { |
16932 bool success = buffer->SetRange( | 16975 bool success = buffer->SetRange( |
16933 mapped_range->offset, mapped_range->size, mem); | 16976 mapped_range->offset, mapped_range->size, mem); |
16934 DCHECK(success); | 16977 DCHECK(success); |
16935 } | 16978 } |
16936 } | 16979 } |
16937 buffer->RemoveMappedRange(); | 16980 buffer->RemoveMappedRange(); |
16938 GLboolean rt = glUnmapBuffer(target); | 16981 GLboolean rt = glUnmapBuffer(target); |
16939 if (rt == GL_FALSE) { | 16982 if (rt == GL_FALSE) { |
16940 // At this point, we have already done the necessary validation, so | 16983 // At this point, we have already done the necessary validation, so |
16941 // GL_FALSE indicates data corruption. | 16984 // GL_FALSE indicates data corruption. |
16942 // TODO(zmo): We could redo the map / copy data / unmap to recover, but | 16985 // TODO(zmo): We could redo the map / copy data / unmap to recover, but |
16943 // the second unmap could still return GL_FALSE. For now, we simply lose | 16986 // the second unmap could still return GL_FALSE. For now, we simply lose |
16944 // the contexts in the share group. | 16987 // the contexts in the share group. |
16945 LOG(ERROR) << "glUnmapBuffer unexpectedly returned GL_FALSE"; | 16988 LOG(ERROR) << func_name << " unexpectedly returned GL_FALSE"; |
16946 // Need to lose current context before broadcasting! | 16989 // Need to lose current context before broadcasting! |
16947 MarkContextLost(error::kGuilty); | 16990 MarkContextLost(error::kGuilty); |
16948 group_->LoseContexts(error::kInnocent); | 16991 group_->LoseContexts(error::kInnocent); |
16949 return error::kLostContext; | 16992 return error::kLostContext; |
16950 } | 16993 } |
16951 return error::kNoError; | 16994 return error::kNoError; |
16952 } | 16995 } |
16953 | 16996 |
| 16997 void GLES2DecoderImpl::DoFlushMappedBufferRange( |
| 16998 GLenum target, GLintptr offset, GLsizeiptr size) { |
| 16999 const char* func_name = "glFlushMappedBufferRange"; |
| 17000 // |size| is validated in HandleFlushMappedBufferRange(). |
| 17001 if (offset < 0) { |
| 17002 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "offset < 0"); |
| 17003 return; |
| 17004 } |
| 17005 Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target); |
| 17006 if (!buffer) { |
| 17007 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "no buffer bound"); |
| 17008 return; |
| 17009 } |
| 17010 const Buffer::MappedRange* mapped_range = buffer->GetMappedRange(); |
| 17011 if (!mapped_range) { |
| 17012 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "buffer is unmapped"); |
| 17013 return; |
| 17014 } |
| 17015 if (!AllBitsSet(mapped_range->access, GL_MAP_FLUSH_EXPLICIT_BIT)) { |
| 17016 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
| 17017 "buffer is mapped without MAP_FLUSH_EXPLICIT_BIT flag"); |
| 17018 return; |
| 17019 } |
| 17020 base::CheckedNumeric<int32_t> range_size = size; |
| 17021 range_size += offset; |
| 17022 if (!range_size.IsValid() || |
| 17023 range_size.ValueOrDefault(0) > mapped_range->size) { |
| 17024 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, |
| 17025 "offset + size out of bounds"); |
| 17026 return; |
| 17027 } |
| 17028 char* client_data = reinterpret_cast<char*>(mapped_range->GetShmPointer()); |
| 17029 DCHECK(client_data); |
| 17030 char* gpu_data = reinterpret_cast<char*>(mapped_range->pointer); |
| 17031 DCHECK(gpu_data); |
| 17032 memcpy(gpu_data + offset, client_data + offset, size); |
| 17033 if (buffer->shadowed()) { |
| 17034 bool success = buffer->SetRange( |
| 17035 mapped_range->offset + offset, size, client_data + offset); |
| 17036 DCHECK(success); |
| 17037 } |
| 17038 glFlushMappedBufferRange(target, offset, size); |
| 17039 } |
| 17040 |
16954 // Note that GL_LOST_CONTEXT is specific to GLES. | 17041 // Note that GL_LOST_CONTEXT is specific to GLES. |
16955 // For desktop GL we have to query the reset status proactively. | 17042 // For desktop GL we have to query the reset status proactively. |
16956 void GLES2DecoderImpl::OnContextLostError() { | 17043 void GLES2DecoderImpl::OnContextLostError() { |
16957 if (!WasContextLost()) { | 17044 if (!WasContextLost()) { |
16958 // Need to lose current context before broadcasting! | 17045 // Need to lose current context before broadcasting! |
16959 CheckResetStatus(); | 17046 CheckResetStatus(); |
16960 group_->LoseContexts(error::kUnknown); | 17047 group_->LoseContexts(error::kUnknown); |
16961 reset_by_robustness_extension_ = true; | 17048 reset_by_robustness_extension_ = true; |
16962 } | 17049 } |
16963 } | 17050 } |
(...skipping 1180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
18144 } | 18231 } |
18145 | 18232 |
18146 // Include the auto-generated part of this file. We split this because it means | 18233 // Include the auto-generated part of this file. We split this because it means |
18147 // we can easily edit the non-auto generated parts right here in this file | 18234 // we can easily edit the non-auto generated parts right here in this file |
18148 // instead of having to edit some template or the code generator. | 18235 // instead of having to edit some template or the code generator. |
18149 #include "base/macros.h" | 18236 #include "base/macros.h" |
18150 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 18237 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
18151 | 18238 |
18152 } // namespace gles2 | 18239 } // namespace gles2 |
18153 } // namespace gpu | 18240 } // namespace gpu |
OLD | NEW |