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

Side by Side Diff: gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h

Issue 189133004: WebGL TexParameterf and GetTexParameterf needs to handle float param correctly (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 months 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) 2014 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2014 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 // This file is auto-generated from 5 // This file is auto-generated from
6 // gpu/command_buffer/build_gles2_cmd_buffer.py 6 // gpu/command_buffer/build_gles2_cmd_buffer.py
7 // It's formatted by clang-format using chromium coding style: 7 // It's formatted by clang-format using chromium coding style:
8 // clang-format -i -style=chromium filename 8 // clang-format -i -style=chromium filename
9 // DO NOT EDIT! 9 // DO NOT EDIT!
10 10
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 SpecializedSetup<cmds::StencilOpSeparate, 0>(true); 228 SpecializedSetup<cmds::StencilOpSeparate, 0>(true);
229 cmds::StencilOpSeparate cmd; 229 cmds::StencilOpSeparate cmd;
230 cmd.Init(GL_FRONT, GL_INCR, GL_KEEP, GL_KEEP); 230 cmd.Init(GL_FRONT, GL_INCR, GL_KEEP, GL_KEEP);
231 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 231 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
232 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 232 EXPECT_EQ(GL_NO_ERROR, GetGLError());
233 } 233 }
234 // TODO(gman): TexImage2D 234 // TODO(gman): TexImage2D
235 235
236 TEST_F(GLES2DecoderTest2, TexParameterfValidArgs) { 236 TEST_F(GLES2DecoderTest2, TexParameterfValidArgs) {
237 EXPECT_CALL(*gl_, 237 EXPECT_CALL(*gl_,
238 TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); 238 TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
239 SpecializedSetup<cmds::TexParameterf, 0>(true); 239 SpecializedSetup<cmds::TexParameterf, 0>(true);
240 cmds::TexParameterf cmd; 240 cmds::TexParameterf cmd;
241 cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 241 cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
242 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 242 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
243 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 243 EXPECT_EQ(GL_NO_ERROR, GetGLError());
244 } 244 }
245 245
246 TEST_F(GLES2DecoderTest2, TexParameterfInvalidArgs0_0) { 246 TEST_F(GLES2DecoderTest2, TexParameterfInvalidArgs0_0) {
247 EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0); 247 EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0);
248 SpecializedSetup<cmds::TexParameterf, 0>(false); 248 SpecializedSetup<cmds::TexParameterf, 0>(false);
249 cmds::TexParameterf cmd; 249 cmds::TexParameterf cmd;
250 cmd.Init(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 250 cmd.Init(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
251 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 251 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
252 EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); 252 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
253 } 253 }
254 254
255 TEST_F(GLES2DecoderTest2, TexParameterfInvalidArgs0_1) { 255 TEST_F(GLES2DecoderTest2, TexParameterfInvalidArgs0_1) {
256 EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0); 256 EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0);
257 SpecializedSetup<cmds::TexParameterf, 0>(false); 257 SpecializedSetup<cmds::TexParameterf, 0>(false);
258 cmds::TexParameterf cmd; 258 cmds::TexParameterf cmd;
259 cmd.Init(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 259 cmd.Init(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
260 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 260 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
261 EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); 261 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
262 } 262 }
263 263
264 TEST_F(GLES2DecoderTest2, TexParameterfInvalidArgs1_0) { 264 TEST_F(GLES2DecoderTest2, TexParameterfInvalidArgs1_0) {
265 EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0); 265 EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0);
266 SpecializedSetup<cmds::TexParameterf, 0>(false); 266 SpecializedSetup<cmds::TexParameterf, 0>(false);
267 cmds::TexParameterf cmd; 267 cmds::TexParameterf cmd;
268 cmd.Init(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_NEAREST); 268 cmd.Init(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_NEAREST);
269 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 269 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
270 EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); 270 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
271 } 271 }
272 272
273 TEST_F(GLES2DecoderTest2, TexParameterfvValidArgs) { 273 TEST_F(GLES2DecoderTest2, TexParameterfvValidArgs) {
274 SpecializedSetup<cmds::TexParameterfv, 0>(true); 274 SpecializedSetup<cmds::TexParameterfv, 0>(true);
275 cmds::TexParameterfv cmd; 275 cmds::TexParameterfv cmd;
276 cmd.Init(GL_TEXTURE_2D, 276 cmd.Init(GL_TEXTURE_2D,
277 GL_TEXTURE_MAG_FILTER, 277 GL_TEXTURE_MAG_FILTER,
278 shared_memory_id_, 278 shared_memory_id_,
279 shared_memory_offset_); 279 shared_memory_offset_);
280 GetSharedMemoryAs<GLfloat*>()[0] = GL_NEAREST; 280 GetSharedMemoryAs<GLfloat*>()[0] = GL_NEAREST;
281 EXPECT_CALL( 281 EXPECT_CALL(
282 *gl_, 282 *gl_,
283 TexParameteri(GL_TEXTURE_2D, 283 TexParameterf(GL_TEXTURE_2D,
284 GL_TEXTURE_MAG_FILTER, 284 GL_TEXTURE_MAG_FILTER,
285 *reinterpret_cast<const GLfloat*>(shared_memory_address_))); 285 *reinterpret_cast<const GLfloat*>(shared_memory_address_)));
286 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 286 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
287 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 287 EXPECT_EQ(GL_NO_ERROR, GetGLError());
288 } 288 }
289 289
290 TEST_F(GLES2DecoderTest2, TexParameterfvInvalidArgs0_0) { 290 TEST_F(GLES2DecoderTest2, TexParameterfvInvalidArgs0_0) {
291 EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0); 291 EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0);
292 SpecializedSetup<cmds::TexParameterfv, 0>(false); 292 SpecializedSetup<cmds::TexParameterfv, 0>(false);
293 cmds::TexParameterfv cmd; 293 cmds::TexParameterfv cmd;
294 cmd.Init(GL_TEXTURE_1D, 294 cmd.Init(GL_TEXTURE_1D,
295 GL_TEXTURE_MAG_FILTER, 295 GL_TEXTURE_MAG_FILTER,
296 shared_memory_id_, 296 shared_memory_id_,
297 shared_memory_offset_); 297 shared_memory_offset_);
298 GetSharedMemoryAs<GLfloat*>()[0] = GL_NEAREST; 298 GetSharedMemoryAs<GLfloat*>()[0] = GL_NEAREST;
299 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 299 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
300 EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); 300 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
301 } 301 }
302 302
303 TEST_F(GLES2DecoderTest2, TexParameterfvInvalidArgs0_1) { 303 TEST_F(GLES2DecoderTest2, TexParameterfvInvalidArgs0_1) {
304 EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0); 304 EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0);
305 SpecializedSetup<cmds::TexParameterfv, 0>(false); 305 SpecializedSetup<cmds::TexParameterfv, 0>(false);
306 cmds::TexParameterfv cmd; 306 cmds::TexParameterfv cmd;
307 cmd.Init(GL_TEXTURE_3D, 307 cmd.Init(GL_TEXTURE_3D,
308 GL_TEXTURE_MAG_FILTER, 308 GL_TEXTURE_MAG_FILTER,
309 shared_memory_id_, 309 shared_memory_id_,
310 shared_memory_offset_); 310 shared_memory_offset_);
311 GetSharedMemoryAs<GLfloat*>()[0] = GL_NEAREST; 311 GetSharedMemoryAs<GLfloat*>()[0] = GL_NEAREST;
312 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 312 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
313 EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); 313 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
314 } 314 }
315 315
316 TEST_F(GLES2DecoderTest2, TexParameterfvInvalidArgs1_0) { 316 TEST_F(GLES2DecoderTest2, TexParameterfvInvalidArgs1_0) {
317 EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0); 317 EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0);
318 SpecializedSetup<cmds::TexParameterfv, 0>(false); 318 SpecializedSetup<cmds::TexParameterfv, 0>(false);
319 cmds::TexParameterfv cmd; 319 cmds::TexParameterfv cmd;
320 cmd.Init(GL_TEXTURE_2D, 320 cmd.Init(GL_TEXTURE_2D,
321 GL_GENERATE_MIPMAP, 321 GL_GENERATE_MIPMAP,
322 shared_memory_id_, 322 shared_memory_id_,
323 shared_memory_offset_); 323 shared_memory_offset_);
324 GetSharedMemoryAs<GLfloat*>()[0] = GL_NEAREST; 324 GetSharedMemoryAs<GLfloat*>()[0] = GL_NEAREST;
325 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 325 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
326 EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); 326 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
327 } 327 }
328 328
329 TEST_F(GLES2DecoderTest2, TexParameterfvInvalidArgs2_0) { 329 TEST_F(GLES2DecoderTest2, TexParameterfvInvalidArgs2_0) {
330 EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0); 330 EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0);
331 SpecializedSetup<cmds::TexParameterfv, 0>(false); 331 SpecializedSetup<cmds::TexParameterfv, 0>(false);
332 cmds::TexParameterfv cmd; 332 cmds::TexParameterfv cmd;
333 cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, kInvalidSharedMemoryId, 0); 333 cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, kInvalidSharedMemoryId, 0);
334 GetSharedMemoryAs<GLfloat*>()[0] = GL_NEAREST; 334 GetSharedMemoryAs<GLfloat*>()[0] = GL_NEAREST;
335 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); 335 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
336 } 336 }
337 337
338 TEST_F(GLES2DecoderTest2, TexParameterfvInvalidArgs2_1) { 338 TEST_F(GLES2DecoderTest2, TexParameterfvInvalidArgs2_1) {
339 EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0); 339 EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0);
340 SpecializedSetup<cmds::TexParameterfv, 0>(false); 340 SpecializedSetup<cmds::TexParameterfv, 0>(false);
341 cmds::TexParameterfv cmd; 341 cmds::TexParameterfv cmd;
342 cmd.Init(GL_TEXTURE_2D, 342 cmd.Init(GL_TEXTURE_2D,
343 GL_TEXTURE_MAG_FILTER, 343 GL_TEXTURE_MAG_FILTER,
344 shared_memory_id_, 344 shared_memory_id_,
345 kInvalidSharedMemoryOffset); 345 kInvalidSharedMemoryOffset);
346 GetSharedMemoryAs<GLfloat*>()[0] = GL_NEAREST; 346 GetSharedMemoryAs<GLfloat*>()[0] = GL_NEAREST;
347 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); 347 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
348 } 348 }
349 349
350 TEST_F(GLES2DecoderTest2, TexParameterfvImmediateValidArgs) { 350 TEST_F(GLES2DecoderTest2, TexParameterfvImmediateValidArgs) {
351 cmds::TexParameterfvImmediate& cmd = 351 cmds::TexParameterfvImmediate& cmd =
352 *GetImmediateAs<cmds::TexParameterfvImmediate>(); 352 *GetImmediateAs<cmds::TexParameterfvImmediate>();
353 SpecializedSetup<cmds::TexParameterfvImmediate, 0>(true); 353 SpecializedSetup<cmds::TexParameterfvImmediate, 0>(true);
354 GLfloat temp[1] = {GL_NEAREST, }; 354 GLfloat temp[1] = {GL_NEAREST, };
355 cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, &temp[0]); 355 cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, &temp[0]);
356 EXPECT_CALL( 356 EXPECT_CALL(
357 *gl_, 357 *gl_,
358 TexParameteri(GL_TEXTURE_2D, 358 TexParameterf(GL_TEXTURE_2D,
359 GL_TEXTURE_MAG_FILTER, 359 GL_TEXTURE_MAG_FILTER,
360 *reinterpret_cast<GLfloat*>(ImmediateDataAddress(&cmd)))); 360 *reinterpret_cast<GLfloat*>(ImmediateDataAddress(&cmd))));
361 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); 361 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
362 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 362 EXPECT_EQ(GL_NO_ERROR, GetGLError());
363 } 363 }
364 364
365 TEST_F(GLES2DecoderTest2, TexParameterfvImmediateInvalidArgs0_0) { 365 TEST_F(GLES2DecoderTest2, TexParameterfvImmediateInvalidArgs0_0) {
366 cmds::TexParameterfvImmediate& cmd = 366 cmds::TexParameterfvImmediate& cmd =
367 *GetImmediateAs<cmds::TexParameterfvImmediate>(); 367 *GetImmediateAs<cmds::TexParameterfvImmediate>();
368 EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0); 368 EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0);
369 SpecializedSetup<cmds::TexParameterfvImmediate, 0>(false); 369 SpecializedSetup<cmds::TexParameterfvImmediate, 0>(false);
370 GLfloat temp[1] = {GL_NEAREST, }; 370 GLfloat temp[1] = {GL_NEAREST, };
371 cmd.Init(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, &temp[0]); 371 cmd.Init(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, &temp[0]);
372 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); 372 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
373 EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); 373 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
374 } 374 }
375 375
376 TEST_F(GLES2DecoderTest2, TexParameterfvImmediateInvalidArgs0_1) { 376 TEST_F(GLES2DecoderTest2, TexParameterfvImmediateInvalidArgs0_1) {
377 cmds::TexParameterfvImmediate& cmd = 377 cmds::TexParameterfvImmediate& cmd =
378 *GetImmediateAs<cmds::TexParameterfvImmediate>(); 378 *GetImmediateAs<cmds::TexParameterfvImmediate>();
379 EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0); 379 EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0);
380 SpecializedSetup<cmds::TexParameterfvImmediate, 0>(false); 380 SpecializedSetup<cmds::TexParameterfvImmediate, 0>(false);
381 GLfloat temp[1] = {GL_NEAREST, }; 381 GLfloat temp[1] = {GL_NEAREST, };
382 cmd.Init(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, &temp[0]); 382 cmd.Init(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, &temp[0]);
383 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); 383 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
384 EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); 384 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
385 } 385 }
386 386
387 TEST_F(GLES2DecoderTest2, TexParameterfvImmediateInvalidArgs1_0) { 387 TEST_F(GLES2DecoderTest2, TexParameterfvImmediateInvalidArgs1_0) {
388 cmds::TexParameterfvImmediate& cmd = 388 cmds::TexParameterfvImmediate& cmd =
389 *GetImmediateAs<cmds::TexParameterfvImmediate>(); 389 *GetImmediateAs<cmds::TexParameterfvImmediate>();
390 EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0); 390 EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0);
391 SpecializedSetup<cmds::TexParameterfvImmediate, 0>(false); 391 SpecializedSetup<cmds::TexParameterfvImmediate, 0>(false);
392 GLfloat temp[1] = {GL_NEAREST, }; 392 GLfloat temp[1] = {GL_NEAREST, };
393 cmd.Init(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, &temp[0]); 393 cmd.Init(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, &temp[0]);
394 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); 394 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
395 EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); 395 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
396 } 396 }
397 397
398 TEST_F(GLES2DecoderTest2, TexParameteriValidArgs) { 398 TEST_F(GLES2DecoderTest2, TexParameteriValidArgs) {
399 EXPECT_CALL(*gl_, 399 EXPECT_CALL(*gl_,
400 TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); 400 TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
(...skipping 1211 matching lines...) Expand 10 before | Expand all | Expand 10 after
1612 // TODO(gman): GenVertexArraysOESImmediate 1612 // TODO(gman): GenVertexArraysOESImmediate
1613 // TODO(gman): DeleteVertexArraysOES 1613 // TODO(gman): DeleteVertexArraysOES
1614 // TODO(gman): DeleteVertexArraysOESImmediate 1614 // TODO(gman): DeleteVertexArraysOESImmediate
1615 // TODO(gman): IsVertexArrayOES 1615 // TODO(gman): IsVertexArrayOES
1616 // TODO(gman): BindVertexArrayOES 1616 // TODO(gman): BindVertexArrayOES
1617 // TODO(gman): SwapBuffers 1617 // TODO(gman): SwapBuffers
1618 // TODO(gman): GetMaxValueInBufferCHROMIUM 1618 // TODO(gman): GetMaxValueInBufferCHROMIUM
1619 // TODO(gman): GenSharedIdsCHROMIUM 1619 // TODO(gman): GenSharedIdsCHROMIUM
1620 1620
1621 #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_ 1621 #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/gles2_cmd_decoder.cc ('k') | gpu/command_buffer/service/test_helper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698