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

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

Issue 8404029: Strip comments from shader before checking for invalid characters (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/shader_manager.h" 5 #include "gpu/command_buffer/service/shader_manager.h"
6 #include "base/logging.h" 6 #include "base/logging.h"
7 #include "base/string_util.h"
7 8
8 namespace gpu { 9 namespace gpu {
9 namespace gles2 { 10 namespace gles2 {
10 11
11 ShaderManager::ShaderInfo::ShaderInfo(GLuint service_id, GLenum shader_type) 12 ShaderManager::ShaderInfo::ShaderInfo(GLuint service_id, GLenum shader_type)
12 : use_count_(0), 13 : use_count_(0),
13 service_id_(service_id), 14 service_id_(service_id),
14 shader_type_(shader_type), 15 shader_type_(shader_type),
15 valid_(false) { 16 valid_(false) {
16 } 17 }
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 info->IncUseCount(); 145 info->IncUseCount();
145 } 146 }
146 147
147 void ShaderManager::UnuseShader(ShaderManager::ShaderInfo* info) { 148 void ShaderManager::UnuseShader(ShaderManager::ShaderInfo* info) {
148 DCHECK(info); 149 DCHECK(info);
149 DCHECK(IsOwned(info)); 150 DCHECK(IsOwned(info));
150 info->DecUseCount(); 151 info->DecUseCount();
151 RemoveShaderInfoIfUnused(info); 152 RemoveShaderInfoIfUnused(info);
152 } 153 }
153 154
155 namespace {
156
157 // Strips comments from shader text. This allows non-ASCII characters
158 // to be used in comments without potentially breaking OpenGL
159 // implementations not expecting characters outside the GLSL ES set.
160 class Stripper {
161 public:
162 Stripper(const std::string& str)
163 : parse_state_(kBeginningOfLine)
164 , source_string_(str)
165 , length_(str.length())
166 , position_(0) {
167 Parse();
168 }
169
170 const std::string& result() {
171 return result_;
172 }
173
174 private:
175 bool HasMoreCharacters() {
176 return position_ < length_;
177 }
178
179 void Parse() {
180 while (HasMoreCharacters()) {
181 Process(Current());
182 // Process() might Advance the position.
183 if (HasMoreCharacters()) {
184 Advance();
185 }
186 }
187 }
188
189 void Process(char);
190
191 bool Peek(char* character) {
192 DCHECK(character);
193 if (position_ + 1 >= length_) {
194 return false;
195 }
196 *character = source_string_[position_ + 1];
197 return true;
198 }
199
200 char Current() {
201 DCHECK_LT(position_, length_);
202 return source_string_[position_];
203 }
204
205 void Advance() {
206 ++position_;
207 }
208
209 bool IsNewline(char character) {
210 // Don't attempt to canonicalize newline related characters.
211 return (character == '\n' || character == '\r');
212 }
213
214 void Emit(char character) {
215 result_.push_back(character);
216 }
217
218 enum ParseState {
219 // Have not seen an ASCII non-whitespace character yet on
220 // this line. Possible that we might see a preprocessor
221 // directive.
222 kBeginningOfLine,
223
224 // Have seen at least one ASCII non-whitespace character
225 // on this line.
226 kMiddleOfLine,
227
228 // Handling a preprocessor directive. Passes through all
229 // characters up to the end of the line. Disables comment
230 // processing.
231 kInPreprocessorDirective,
232
233 // Handling a single-line comment. The comment text is
234 // replaced with a single space.
235 kInSingleLineComment,
236
237 // Handling a multi-line comment. Newlines are passed
238 // through to preserve line numbers.
239 kInMultiLineComment
240 };
241
242 ParseState parse_state_;
243 std::string source_string_;
244 unsigned length_;
245 unsigned position_;
246 std::string result_;
247 };
248
249 void Stripper::Process(char c) {
250 if (IsNewline(c)) {
251 // No matter what state we are in, pass through newlines
252 // so we preserve line numbers.
253 Emit(c);
254
255 if (parse_state_ != kInMultiLineComment)
256 parse_state_ = kBeginningOfLine;
257
258 return;
259 }
260
261 char temp = 0;
262 switch (parse_state_) {
263 case kBeginningOfLine:
264 if (IsAsciiWhitespace(c)) {
265 Emit(c);
266 break;
267 }
268
269 if (c == '#') {
270 parse_state_ = kInPreprocessorDirective;
271 Emit(c);
272 break;
273 }
274
275 // Transition to normal state and re-handle character.
276 parse_state_ = kMiddleOfLine;
277 Process(c);
278 break;
279
280 case kMiddleOfLine:
281 if (c == '/' && Peek(&temp)) {
282 if (temp == '/') {
283 parse_state_ = kInSingleLineComment;
284 Emit(' ');
285 Advance();
286 break;
287 }
288
289 if (temp == '*') {
290 parse_state_ = kInMultiLineComment;
291 // Emit the comment start in case the user has
292 // an unclosed comment and we want to later
293 // signal an error.
294 Emit('/');
295 Emit('*');
296 Advance();
297 break;
298 }
299 }
300
301 Emit(c);
302 break;
303
304 case kInPreprocessorDirective:
305 // No matter what the character is, just pass it
306 // through. Do not Parse comments in this state. This
307 // might not be the right thing to do long term, but it
308 // should handle the #error preprocessor directive.
309 Emit(c);
310 break;
311
312 case kInSingleLineComment:
313 // The newline code at the top of this function takes care
314 // of resetting our state when we get out of the
315 // single-line comment. Swallow all other characters.
316 break;
317
318 case kInMultiLineComment:
319 if (c == '*' && Peek(&temp) && temp == '/') {
320 Emit('*');
321 Emit('/');
322 parse_state_ = kMiddleOfLine;
323 Advance();
324 break;
325 }
326
327 // Swallow all other characters. Unclear whether we may
328 // want or need to just Emit a space per character to try
329 // to preserve column numbers for debugging purposes.
330 break;
331 }
332 }
333
334 } // anonymous namespace
335
336 std::string ShaderManager::StripComments(const std::string source) {
337 Stripper stripper(source);
338 return stripper.result();
339 }
340
154 } // namespace gles2 341 } // namespace gles2
155 } // namespace gpu 342 } // namespace gpu
156 343
157 344
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698